Context and goal
See the About page for context of this post.
It is recommended to use a firewall no matter which kind of Linux installation we’re talking about wether it’s a laptop or a server. I collected here templates for those two most commonly used cases I have so that I can easily just copy from here. I’ll probably add these to the host-setup script at some point. If you want to actually learn something yourself about the firewall included in the Linux kernel commonly referenced as “iptables”, I’ve found these articles from Arch documentation to be very good:
Laptop (or desktop, why not)
This template for a laptop simply just:
- drops all incoming traffic and routing traffic that is not part of an already established connection,
- rejects udp, tcp and all other traffic properly (since on a laptop we don’t need to worry about a denial of service attacks) and
- accepts all outgoing traffic.
*filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate INVALID -j DROP -A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable -A INPUT -p tcp -j REJECT --reject-with tcp-reset -A INPUT -j REJECT --reject-with icmp-proto-unreachable COMMIT
My definition of a “web server” is a server that often enough needs to be connected via SSH for deployments or maintenance and which serves some sort of content via HTTP and HTTPS (hopefully forcing redirect to the latter) on the standard ports. This template does what the above template does with the following exceptions and additions:
- Drop all traffic without properly rejecting it to help in case of denial of service attacks,
- separate TCP and UDP connections to new chains for each for easier management
- and allow SSH, HTTP and HTTPS from anywhere.
Note: This template is usually paired with OpenSSH server setup that doesn’t allow root login or login with password which makes the significance of the open SSH port less risky. It is not a bad idea to modify the below template to only allow SSH from known addresses like a VPN or office network.
*filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :TCP - [0:0] :UDP - [0:0] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate INVALID -j DROP -A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT -A INPUT -p udp -m conntrack --ctstate NEW -j UDP -A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP -A TCP -p tcp --dport 22 -j ACCEPT -A TCP -p tcp --dport 80 -j ACCEPT -A TCP -p tcp --dport 443 -j ACCEPT COMMIT
Allowing SSH only from a certain address can be done by changing this
-A TCP -p tcp --dport 22 -j ACCEPT to this
-A TCP -p tcp --dport 22 -s <known-ip-address> -j ACCEPT.