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 chain...eh...not 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.

  • 1
    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. :) 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. Mar 31 '11 at 2:07

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 mirrors.kernel.org -p tcp --dport 80 -j ACCEPT

#add upd/123 for NTP
iptables -A OUTPUT -o eth0 -d tock.usask.ca -p udp --dport 123 -j ACCEPT
  • 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. 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

  • 1
    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
  • Adding -m state --state ESTABLISHED,RELATED before -j ACCEPTto that line means it only allows traffic that's part of a connection through. 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
  • Jonathan, thank you for the helpful suggestions. Default deny was definitely drilled into my head based on all the iptables reading I've done thus far. It's nice to hear that the approach is recommended from real world users as well. Mar 30 '11 at 21:11

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).

  • 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. Mar 30 '11 at 21:04
  • Sean C - thanks for clarifying the NTP's protocol of udp. Mar 30 '11 at 21:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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