Which INPUT rules do I need to add to iptables so apt (apt-get, aptitude) can work (update, upgrade, search, install)?
I need to use aptitude to update and install software but it fails. It says...
0% [Connecting to archive.ubuntu.com]
...and halts. I need to type CTRL-C
to move out. I'm using Ubuntu Server 10.04 LTS (Lucid Lynx).
This is happening due to my iptables rules. If I restore iptables to its defaults (by removing rules and setting policies to ACCEPT), then aptitude works as expected. No errors anymore.
But, hey, I want to use my iptables rules... I just need to know: what exactly I need to keep open to make apt work?
My rules are quite simple. OUTPUT policy is ACCEPT. FORWARD policy is ACCEPT. And I have no rules for OUTPUT and FORWARD. INPUT policy is DROP. So, the problem is in the INPUT chain! I have 11 INPUT rules to open specific TCP ports that I need to run services like FTP, SSH, HTTP, etc. An additional rule to accept ICMP (ping), and other to accept all localhost input. And this is all:
iptables -F
iptables -A INPUT -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 587 -j ACCEPT
iptables -A INPUT -p tcp --dport 995 -j ACCEPT
iptables -A INPUT -p tcp --dport 1008 -j ACCEPT
iptables -A INPUT -p tcp --dport 2812 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
iptables -P INPUT DROP
I tried lots of rules trying to make aptitude work. Of course a simple iptables -P INPUT ACCEPT
makes it work, but I don't want to accept everything. I want to open only what is needed for aptitude to do its job.
It sounds strange to me that the INPUT chain is the issue... but it is.
Another issue is that I have no access to iptables logs... I have just found there is a bug in the kernel I am using (see https://serverfault.com/questions/159818/iptables-logging-not-working)... so, don't ask me for the log contents, because I am unable to have them.
Thank you!
When you send a HTTP request to the other server, you're using TCP. First, a SYN packet go outside to the other server from a random high port, then you'll receive a ACK response. Finally you send SYN/ACK to the server and the server responds with the requested document (in multiple packets). Your rules do not allow the ACK packet to be received and therefore the connection cannot be established. Add a rule like:
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
You don't get iptables logs for free. Your rules should look like:
# if no rule matched, the input should be dropped
-P INPUT DROP
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# etc
# the limit prevents your logs from being flooded if there are a lot packets being captured
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied" --log-level debug
Note that I've omitted iptables
before the commands, I recommend using iptables-restore
(or iptables-apply
for testing) to avoid locking yourself out if a rule fails to apply. The file to be passed to the command looks like:
*FILTER
# your rules here, for example:
-P INPUT DROP
-P INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
COMMIT
A newline after the COMMIT
line is mandatory.
By default, the entries go to /var/log/kern.log
. Not good if you want to differentiate between kernel and iptables messages, so create a filter for rsyslog in /etc/rsyslog.d/iptables.conf
containing:
:msg,contains,"iptables denied" /var/log/iptables.log
& ~
This will filter iptables errors and send those to /var/log/iptables.log
.