How to configure iptables to use apt-get in a server
Source: serverfault.com
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.
I think I solved the problem.
$IPT -A INPUT –sport 80 -j ACCEPT and apt work correctly
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.
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.
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
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.
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
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
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
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