#+TITLE: Setting Firewalls with IPTables #+AUTHOR: Howard Abrams #+EMAIL: howard.abrams@gmail.com #+DATE: 2015 Apr 12 #+TAGS: linux technical #+DESCRIPTION: Tangle-able notes on setting up IPTables that can install a nifty script #+PROPERTY: results drawer #+PROPERTY: eval no-export #+PROPERTY: comments org #+PROPERTY: tangle /ssh:troll.howardabrams.com:bin/setup-iptables.sh #+PROPERTY: dir /ssh:troll.howardabrams.com: According to this [[https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-iptables-on-ubuntu-14-04][tutorial from DigitalOcean]] (and this [[https://www.digitalocean.com/community/tutorials/how-to-setup-a-basic-ip-tables-configuration-on-centos-6][perfect tutorial]]), I need to do the following in order to configure a “default” firewall configuration. In this case, I am only allowing SSH and Web. * Initial Analysis View the current rules: #+BEGIN_SRC sh :tangle no sudo iptables --list #+END_SRC #+RESULTS: :RESULTS: Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination :END: Or we can get a more succinct view of our rules: #+BEGIN_SRC sh :tangle no sudo iptables -S #+END_SRC If executing the above command looks like the following, then we are in trouble, as we have everything wide open: #+BEGIN_EXAMPLE -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT #+END_EXAMPLE * Close All the Ports Flushing the firewall rules, erases them all: #+BEGIN_SRC sh iptables -F #+END_SRC We can't really count on iptables alone to protect us from a full-scale DDOS or similar, but we can at least put off the usual network scanning bots that will eventually find our VPS and start looking for security holes to exploit. First, we start with blocking null packets. #+BEGIN_SRC sh iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP #+END_SRC We told the firewall to take all incoming packets with tcp flags NONE and just DROP them. Null packets are, simply said, recon packets. The attack patterns use these to try and see how we configured the VPS and find out weaknesses. The next pattern to reject is a syn-flood attack. #+BEGIN_SRC sh iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP #+END_SRC Syn-flood attack means that the attackers open a new connection, but do not state what they want (ie. SYN, ACK, whatever). They just want to take up our servers' resources. We won't accept such packages. Now we move on to one more common pattern: XMAS packets, also a recon packet. #+BEGIN_SRC sh iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP #+END_SRC We have ruled out at least some of the usual patterns that find vulnerabilities in our VPS. * Open Some Ports Now we can start adding selected services to our firewall filter. The first such thing is a localhost interface: #+BEGIN_SRC sh iptables -A INPUT -i lo -j ACCEPT #+END_SRC ** HTTP We tell iptables to add (-A) a rule to the incoming (INPUT) filter table any trafic that comes to localhost interface (-i lo) and to accept (-j ACCEPT) it. Localhost is often used for, ie. your website or email server communicating with a database locally installed. That way our VPS can use the database, but the database is closed to exploits from the internet. Now we can allow web server traffic: #+BEGIN_SRC sh iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT #+END_SRC ** SSH We should also allow SSH traffic, so we can connect to the VPS remotely. The simple way to do it would be with this command: #+BEGIN_SRC sh iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT #+END_SRC ** Tomcat We should also allow SSH traffic, so we can connect to the VPS remotely. The simple way to do it would be with this command: #+BEGIN_SRC sh iptables -A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT #+END_SRC * Other Projects Other services will need exceptions to the above. ** Minecraft The following should expose the Minecraft port on 25565: #+BEGIN_SRC sh :tangle no iptables -A INPUT -p tcp -m tcp --dport 25565 -j ACCEPT #+END_SRC * Final Results View the results of executing the previous commands, but only display the network addresses, not the hostnames: #+BEGIN_SRC sh sudo iptables --list -n --line-numbers #+END_SRC #+RESULTS: :RESULTS: Chain INPUT (policy ACCEPT) num target prot opt source destination 1 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x00 2 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 state NEW 3 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x3F 4 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 7 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 8 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:25565 Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination :END: If all looks good, then we need to make it permanent. On a CentOS or other RedHat system, we’d write the results out to the start up scripts file: #+BEGIN_SRC sh :tangle no iptables-save | sudo tee /etc/sysconfig/iptables #+END_SRC However, on Ubuntu, it has a special persistent storage package: #+BEGIN_SRC sh :tangle no sudo apt-get update sudo apt-get install iptables-persistent #+END_SRC