Good Ingredients

Firewall

Recipes > Core Recipes > .. > Firewall

It is very important to have a firewall, if for no other reason it is likely to discourage someone looking for an easy target. Firewalls are actually really easy to set up.

You can get the output of your current rules like this:

$ sudo iptables-save

If you want to start modifying your firewall rules it is a good idea to keep a copy of the current ones first.

$ sudo iptables-save > ~/iptables.current.rules

This saves the current firewall rules to a iptables.current.rules in your home directory. Copy this to /etc/iptables.rules:

$ sudo cp ~/iptables.current.rules /etc/iptables.rules

Now you can edit the /etc/iptables.rules file with your own rules. Here's mine which you can use as a basis:

# Generated by iptables-save v1.4.2 on Wed Jun 10 16:16:07 2009
*nat
:PREROUTING ACCEPT [6:774]
:POSTROUTING ACCEPT [43:3724]
:OUTPUT ACCEPT [42:3320]
COMMIT
# Completed on Wed Jun 10 16:16:07 2009
# Generated by iptables-save v1.4.2 on Wed Jun 10 16:16:07 2009
*mangle
:PREROUTING ACCEPT [686:69307]
:INPUT ACCEPT [438:37769]
:FORWARD ACCEPT [244:30990]
:OUTPUT ACCEPT [349:42626]
:POSTROUTING ACCEPT [593:73616]
COMMIT
# Completed on Wed Jun 10 16:16:07 2009
# Generated by iptables-save v1.4.2 on Wed Jun 10 16:16:07 2009
*filter
:INPUT ACCEPT [438:37769]

# Allow loopback traffic but drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT

# Allow all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow HTTP and HTTPS connections from anywhere
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Allow SSH connections (make sure --dport is the same as the one in your `/etc/ssh/sshd_config' file or you will not be able to SSH in)
-A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT

# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT

:FORWARD ACCEPT [244:30990]


:OUTPUT ACCEPT [349:42626]
# Allow all outbound traffic (modify to only allow certain traffic if you like)
-A OUTPUT -j ACCEPT

COMMIT
# Completed on Wed Jun 10 16:16:07 2009

In the :FORWARD ACCEPT section you might want to use this if you are not using OpenVZ:

# Reject all forwarded traffic
-A FORWARD -j REJECT

Tip

If you are using OpenVZ and have VEs on a private network 192.168.100.0/24 you might want to replace the *nat section with this to give them access to the internet via the HE. Replace 188.40.40.131 with the external IP address of the HE:

# Generated by iptables-save v1.4.2 on Wed Jun 10 16:16:07 2009
*nat
:PREROUTING ACCEPT [6:774]
:POSTROUTING ACCEPT [43:3724]
:OUTPUT ACCEPT [42:3320]
-A POSTROUTING -s 192.168.100.0/24 -o eth0 -j SNAT --to-source 188.40.40.131
COMMIT

You can apply rules from your configuration with:

$ sudo iptables-restore < /etc/iptables.rules

Again, test that you can still sign in using SSH before you exit the shell.

You can list all the filter rules like this:

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     0    --  anywhere             anywhere
REJECT     0    --  anywhere             loopback/8          reject-with icmp-port-unreachable
ACCEPT     0    --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:30000
ACCEPT     icmp --  anywhere             anywhere            icmp echo-request
LOG        0    --  anywhere             anywhere            limit: avg 5/min burst 5 LOG level debug prefix `iptables denied: '
REJECT     0    --  anywhere             anywhere            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     0    --  anywhere             anywhere            reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     0    --  anywhere             anywhere

At the moment, every time you reboot the rules will be lost.

TEST YOUR FIREWALL NOW, if there are any problems you can reboot to reset the rules.

Tip

If you want to clear all firewall rules, inlcuding the NAT ones you can use this:

$ sudo iptables -F
$ sudo iptables -X
$ sudo iptables -t nat -F
$ sudo iptables -t nat -X
$ sudo iptables -t mangle -F
$ sudo iptables -t mangle -X
$ sudo iptables -P INPUT ACCEPT
$ sudo iptables -P OUTPUT ACCEPT

Once you are happy you can make the rules permanant by editing /etc/network/interfaces and adding a pre-up linejust after iface lo inet loopback:

...
auto lo
iface lo inet loopback
pre-up iptables-restore < /etc/iptables.rules
...

This line will restore the iptables rules from the /etc/iptables.rules file every time the network is configured.

(view source)