2

I'm starting using iptables (newbie) to protect a linux server (specifically Debian 5.0). Before I configure the iptables settings, I can use apt-get without a problem. But after I configure the iptables, the apt-get stop working. For example I use this script in iptables:

#!/bin/sh
IPT=/sbin/iptables

## FLUSH
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X

$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP

$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

$IPT -A INPUT -p tcp --dport 22 -j ACCEPT
$IPT -A OUTPUT -p tcp --sport 22 -j ACCEPT

$IPT -A INPUT -p tcp --dport 80 -j ACCEPT
$IPT -A OUTPUT -p tcp --sport 80 -j ACCEPT
$IPT -A INPUT -p tcp --dport 443 -j ACCEPT
$IPT -A OUTPUT -p tcp --sport 443 -j ACCEPT

# Allow FTP connections @ port 21
$IPT -A INPUT  -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT

# Allow Active FTP Connections
$IPT -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT 

# Allow Passive FTP Connections
$IPT -A INPUT -p tcp --sport 1024: --dport 1024:  -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p tcp --sport 1024: --dport 1024:  -m state --state ESTABLISHED,RELATED -j ACCEPT 

#DNS
$IPT -A OUTPUT -p udp --dport 53 --sport 1024:65535 -j ACCEPT

$IPT -A INPUT -p tcp --dport 1:1024
$IPT -A INPUT -p udp --dport 1:1024

$IPT -A INPUT -p tcp --dport 3306 -j DROP
$IPT -A INPUT -p tcp --dport 10000 -j DROP
$IPT -A INPUT -p udp --dport 10000 -j DROP

then when I run apt-get I obtain:

core:~# apt-get update
0% [Connecting to ftp.us.debian.org] [Connecting to security.debian.org] [Conne

and it stalls. What rules I need to configure to make it works.

Thanks

Addendum:

After some attempts, I find that the problem is in the INPUT policy, and not in the OUTPUT one, if a modify the $IPT -P OUTPUT to $IPT -P OUTPUT ACCEPT the problem remains. But if I change the $IPT -P INPUT to $IPT -P INPUT ACCEPT then it start to work.

10 Answers 10

8

You need to allow the first packet to open a HTTP connection OUT, then allow answers back in.

Try:

$IPT -A OUTPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
2
  • I change the order of the rules, but the problem persist.
    – user25704
    Mar 16, 2010 at 16:11
  • You will likely need to duplicate these rules for port 443 for HTTPS access too.
    – timbo
    May 26, 2016 at 23:48
5

To solve this problem you need to add next rules in your IPT:

# Apt-Get without problem
$IPT -A OUTPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
3

Perhaps Apt is unable to resolve hostnames with DNS. Try adding this line in your DNS section of your ruleset:

$IPT -A INPUT -p udp --sport 53 --dport 1024:65535 -j ACCEPT
2

Two ports are necessary for a default Debian install to get updates:

  • HTTP (tcp port 80)
  • DNS (udp port 53)

Solution with -m state:

$IPT -A OUTPUT -p tcp --dport 80 --sport 32768:61000 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p tcp --sport 80 --dport 32768:61000 -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p udp --dport 53 --sport 32768:61000 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p udp --sport 53 --dport 32768:61000 -m state --state ESTABLISHED -j ACCEPT

or with -m conntrack:

$IPT -A OUTPUT -p tcp --dport 80 --sport 32768:61000 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p tcp --sport 80 --dport 32768:61000 -m conntrack --ctstate ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p udp --dport 53 --sport 32768:61000 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p udp --sport 53 --dport 32768:61000 -m conntrack --ctstate ESTABLISHED -j ACCEPT
1

Apt usually uses good old port 80, but you should check apt.conf to see what it is set as, since it can use any of several. Also check /etc/apt/sources.list

1

I believe you would need an output rules where high source ports allowed. When apt connects to http, Linux will give it a random high source port (Higher than whatever is in /proc/sys/net/ipv4/ip_local_port_range). (Might not be random, can't remember). ftp has passive and actives modes as well, I would recommend http sources in your sources.list in this case.

So if you change your sources to http, and set output rule for all your ephemeral ports. You will be all set. If you use ftp, you need to find out if it is active or passive and then add the rules accordingly. See this link for an explanation of the active/passive modes. I see you have those currently listed, but they seem to be from the perspective of the box being a server, not a client. With apt you are the client.

So for http source ports:

$ cat /proc/sys/net/ipv4/ip_local_port_range
32768   61000
$IPT -A OUTPUT -p tcp --dport 80 --sport 32768:61000 -j ACCEPT

Lastly, you can log dropped packets as a general iptables troubleshooting tool. See this link.

2
  • To test it, I change the OUTPUT policy to ACCEPT, and the problem persist.
    – user25704
    Mar 15, 2010 at 22:10
  • Jonathan has is right. His input rule will allow HTTP replies because it will track the connection and open up wholes for the replies in the INPUT chain. That is what the state module does, same as ip inspect on routers. Mar 15, 2010 at 22:31
0

Using DROP as the default policy for the OUTPUT chain sounds somewhat excessive to me.

I'd recommend changing the default OUTPUT policy to ACCEPT and then monitor traffic and filter specific ports if needed. Otherwise, it's way too much trouble to keep track of all the outgoing connections and allow each one of them through your firewall.

After all, the trick is not to let anyone in, not keep them from going out.

1
  • I try to change the OUTPUT policy to ACCEPT, but the problem persist. Only if I change the INPUT policy to ACCEPT, apt-get starts to work properly.
    – user25704
    Mar 15, 2010 at 22:09
0

I know this is probably a bit late but this thread kept coming up in my google searches so I'm posting what worked for me:

iptables -A OUTPUT -p tcp --dport 80 --sport 32786:61000 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 --sport 32786:61000 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 32786:61000 --sport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 32786:61000 --sport 80 -j ACCEPT
0

I got close issue. I'm using CSF and configured the cc_allow_filter key with BR value thinking this is for SSH and after reading the docs i discovery this is for all connections in the server. Mine is blocking because the mirrors that i use for apt-get is from another country, and CSF was blocking. After removing the country blocking everything star working normaly again.

-1

I think I solved the problem.

$IPT -A INPUT --sport 80 -j ACCEPT and apt work correctly

Not the answer you're looking for? Browse other questions tagged .