Setting up Linux firewall for make more safe web server

Server works in network with opened every ports — sounds not very safety. Let’s protect it by using netfilter firewall which delivered together with Linux. Netfilter, in turn, managed by iptables utility. So, iptables is what we need.

Warning: if you don’t have physical access to real server (working with it remotely e. g. by SSH) first you need find anybody (e. g. supportguy from hosting provider) who could restore SSH access to you or do something else if you accidentally, suddenly or not specially will block yourself.

So, iptables. I should warn you iptables doesn’t save self settings and after server restart, iptables settings will restored to default. Therefore it is possible to use iptables-persistent program which can save iptables settings when you ask about it. Let’s install it:

sudo apt install iptables-persistent

Setup program will ask you would you want to save present rules. Why not? Of course you want to save present rules because you will change it in next steps. Later on you can save your rules anytime by using next command:

sudo dpkg-reconfigure iptables-persistent

The next what you should know that netfilter will process rules in reverse order. If you block packet in some rule it won’t go to rule above last.

Every iptables command neccessary enter into the console. I added comments to every command for you know what it do.

sudo -i # Working with root privileges
iptables -L -n # Will show list of current rules in system
iptables -F # Will delete all current rules 
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP # Will block null-packets
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP # Will drop XMAS packets
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP # Will protect from Syn-flood
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT # Don't forget allow access to SSH oneself (change 22 port if your SSH working on another port)
iptables -A INPUT -i lo -j ACCEPT # Will allow access to local interface. It is neccessary for database, mail, etc.
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # Will allow 80 port for access to sites by HTTP
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # It will allow 443 port for access to sites by HTTPS (if you have)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # Allow ping our server (if you block it external services will think that our server doesn't work)
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # It is neccessary for server updates
iptables -P OUTPUT ACCEPT # Allow output traffic from our server
iptables -P INPUT DROP # It will close left ports
iptables -L -n # Check set rules

Now you need to exit from ssh connection and relogin it again. Check it. It’s ok? Now check how work sites on 80 or 443 port. Also check disallowed ports e. g. 2525:

telnet your_server_IP 2525

Warning: if you got «Connected» it is mean something wrong.

If all is good save your rules:

sudo dpkg-reconfigure iptables-persistent
 281   2019