Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm a ubuntu/iptables noob and am running my first Linode to serve a rails app. While things are starting to come together and I'm feeling pretty good about my INPUT chain, the OUTPUT so much. :)

Obviously my rules should reflect my personal needs and there will always be variation from person to person, but for a basic ubuntu server, what should I generally be conscious of? Are there any best practices for outbound chains? Right now outbound is set to ACCEPT basically everything, but i'd rather deny and whitelist things as necessary.

Given that and excluding the rules which could be figured out based on one's input chain, anyone have suggestions as to what outbound rules one should generally allow on a ubuntu box? (e.g.,for package updates, time syncing, etc.). I don't want to miss something and unknowingly prevent a background task from running properly.


Edit: Thanks for the helpful replies, everyone! My account is brand new and I unfortunately don't have the minimum reputation to vote things up at this time, but I appreciate you all helping me very much. I've gone ahead and accepted an answer.

share|improve this question
If I were you, I'd just let the OUTPUT defaults to ACCEPT. – pepoluan Mar 30 '11 at 13:36
Thanks for sharing your opinion. That's how it has been set up thus far. While it would probably make things much easier to maintain if kept that way, my primary concern is should my box become compromised in some manner, I'd rather have additional preventative measures in place to hopefully minimize undesirable outgoing connections until I can catch and resolve the issue(s). That said, if my box is compromised I'll be in trouble regardless, but it just seems like one more little proactive thing I can implement. :) – StrandedPanda Mar 30 '11 at 20:56
I understand your concern. If your box is compromised, though, there's no stopping the infil from changing the iptables rules. So I'd rather open up the OUTPUT chain, thus saving the box from the additional (albeit very small) processing of outgoing packets. Rather than spending efforts there, I'd dedicate more effort on hardening strategies. A couple of weeks back I started a 'Community Wiki' titled "iptables Tips & Tricks". I strongly suggest you take a peek there; lots of interesting uses. – pepoluan Mar 31 '11 at 1:30
In addition, do dedicate some time to learn about Linux general hardening, e.g., SELinux, AppArmor, GrSecurity, PaX, etc. – pepoluan Mar 31 '11 at 1:34
I'll definitely bookmark your iptables Tips & Tricks 'Community Wiki.' I've previously been exploring SELinux and AppArmor and will also check out your other recommendations. In regard to the worth of filtering output at all, I thank you for the clarification in regard to why you recommend against it. It certainly doesn't seem as cut and dry as I initially thought & getting all these viewpoints on what is worth my time, what isn't, etc. has been extremely valuable. – StrandedPanda Mar 31 '11 at 2:07
up vote 1 down vote accepted

Since you're probably not going to be using this server to do anything other than obtaining data from your configured repos in /etc/apt/sources.listyou should probably just allow those by FQDN and port.

I would use conntrack and stateful inspection rather than specifying an input since it's more secure. A specially crafted packet with it's source port set to 80 will get through the rules that Jonathan Ross mentioned.

#set policy on chains to drop
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

#allows already established/related connections
iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -p tcp -j ACCEPT
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -p tcp -j ACCEPT

#allow incoming to www
iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT

#allow outgoing to my sources.list repo
iptables -A OUTPUT -o eth0 -d -p tcp --dport 80 -j ACCEPT

#add upd/123 for NTP
iptables -A OUTPUT -o eth0 -d -p udp --dport 123 -j ACCEPT
share|improve this answer
You'll want to consider adding a rule to allow a small range of ISP address into SSH (for your access) and maybe a rule to allow DNS lookups to your DNS server as well (for any reverse lookups apache may want to do). – Sean C. Mar 30 '11 at 10:37
This has been most helpful, Sean. Thank you for the examples and recommendations. – StrandedPanda Mar 30 '11 at 21:01

When I was learning IPtables the first rule of thumb was "default deny". That is only allow through what you want and deny everything else instead of just hardening services you are using. It makes a big difference to security.

  • Default deny

iptables -P INPUT DROP

iptables -P OUTPUT DROP

iptables -P FORWARD DROP

  • I like having pings enabled:

iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

iptables -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT

iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT

iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT

  • Apt is necessary, usually as you mentioned

iptables -A OUTPUT -p tcp --dport 80 -m -j ACCEPT

iptables -A INPUT -p tcp --sport 80 -j ACCEPT

iptables -A OUTPUT -p tcp --dport 80 --sport 32768:61000 -j ACCEPT

share|improve this answer
I would encourage you to have a close look at this rule: iptables -A INPUT -p tcp --sport 80 -j ACCEPT. This rule allows me to craft a packet with source port 80 and hit any destination port on your server. – Sean C. Mar 30 '11 at 10:30
Thanks very much ! I'll take a closer look. – Jonathan Ross Mar 30 '11 at 10:59
Adding -m state --state ESTABLISHED,RELATED before -j ACCEPTto that line means it only allows traffic that's part of a connection through. – Jonathan Ross Mar 30 '11 at 11:15
You should add the stateful inspection as its own entry at the top of the chain. That way, already established connections will pass through the chains immediately. Refer to the rules I wrote above. – Sean C. Mar 30 '11 at 11:58
Okay, thanks very much. – Jonathan Ross Mar 30 '11 at 12:44

May be it is worth writing OUTPUT rules symmetrical to INPUT? I mean swapping destination and source addresses, adding NEW state for state-sensetive rules, etc.

Package downloading (as already mentioned) is done over standard HTTP or FTP. FTP variant is a bit more complex because of active/passive FTP mode.

NTP uses tcp port 123. I think it is worth also limiting the address of your NTP server (if you are not using world-wide pool).

share|improve this answer
NTP is udp/123 -- but, good idea. Time sync is nice. – Sean C. Mar 30 '11 at 10:15
Thanks, HUB! Yeah, I definitely plan to refer to my input rules when crafting the output side. The clarification in regard to how packages are download is most useful. I'll also investigate my NTP's settings to ensure that I allow the right address. – StrandedPanda Mar 30 '11 at 21:04
Sean C - thanks for clarifying the NTP's protocol of udp. – StrandedPanda Mar 30 '11 at 21:07

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.