Basic VPS security with simple firewall rules
Firewalls for basic internet security
The internet is a hostile environment. In former times individual hackers might have tried to break into your system by manual attack for fame and glory. Nowadays automatic attack programs (robots) created by organized criminals scan random systems for vulnerabilities and occupy them if possible. Your system might not be of interest to criminals as a primary target, but they need your server to attack other servers an hide their identity or origin. If your server sends spam mails or attacks other servers in a denial-of-service attack than you will be held responsible. To protect your system against being 0wned and converted to a zombie under control of some criminal hacker you must configure some basic measures against attacks.
Problems with firewalls on VPS systems
The good news is: one of the most effective countermeasures is already at your hand if you use a linux server: every linux kernel contains the iptables firewall subsystem which is an industrial strength product used successfully in the majority of router products on the market. The linux firewall is know under the name 'iptables' and can be thought of a really huge and capable application running with kernel privileges (and therefore in the kernel itself). In dedicated linux root servers the iptables firewall is usable as a set of linux kernel modules that may be added to the kernel as an option if needed and consuming no memory if not needed / loaded.
VPS Systems are special in that all virtual systems share one linux kernel enhanced with VPS capablities. For security and stability reasons no virtual system is allowed to load any kernel modules. Therefore if iptables support is not compiled into the VPS kernel you cannot activate the iptables firewall yourself and you may stop reading here.
To check if your VPS kernel includes iptables, enter this command as user root:
# iptables --list
If the output equals
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
you are lucky because
- iptables support is active in your VPS kernel and
- iptables user space configuration tools are installed.
If the iptables command is not found you may try to install it with your distribution dependent software installation tool. But this only installs the configuration tools and not the firewall kernel modules. If your iptables command returns with an error message like 'modules not loaded' than your VPS providers has not enabled the firewall usage for your server.
But even if iptables is supported VPS systems impose some limits on firewall rules. First of all since you may not load kernel modules you are depend on the compiled in modules of your provider. These are basic ones and some of the more sophisticated may be missing - due to more cpu load for example. And even the basic ones are restricted further by the limits on the number of iptable entries you may define.
VPS limits on iptable entries
Enter the following command to see which limits are active on your VPS server:
# grep numiptent /proc/user_beancounters[uid resource held maxheld barrier limit failcnt]
numiptent 38 38 64 64 0
Numiptent is the abbreviation for number of iptable entries and is the limits the iptable rules you may use. Currently I use 38 of a possible maximum of 64 rules. But if you start you are in for a surprise: a firewall which does nothing - letting all network traffic through the filters - uses already 14 rules! There are only 50 left! On a Server4You system it's only a bit better, 10 rules used for no operation and up to 96 allowed.
In the past I used the firewall configuration script shoreline firewall (shorewall) so I configured as usual and started but I got not far: Shorewall generated 439 rules! There are other Firewall configuration tools like APF or the build-in firewall of your distribution like the SuSEFirewall integrated into Yast. But the number of rules is critical. Some firewall start scripts break because they want to load iptable kernel modules first. You may be successful by commenting out these lines and hope for the best.
Simple firewall rules for basic protection
If all else fails I'll continue with some handcrafted rules for basic protection which you should adjust to your needs. The idea is a whitelist of incoming port numbers effectivly forming a port filter. External clients may only connect to your system on port numbers the firewall allows, even if services / daemons run and listen on other ports. These are protected by the firewall. Additionally you are able to protect your system against some well known TCP attacks on the network protocol level. And some of the ICMP protocol are blocked and others allowed. Since some services need well known port number like HTTP on 80 and HTTPS on 443 these have to be open if you want to offer these services. But a SSH port for administration is not public and should be moved away from the well known port number of 22 to some (unused) port in the 10000-49000 range. This makes automatic attacks - beginning with a port scan - more difficult. You don't have to know every port number by heart, just use their alias from the file /etc/services.
These are the rules in the format for the Debian linux system version 4. If the server starts it'll run
/etc/init.d/iptables start
which in turn reads
/etc/iptables.conf
Here's my example
#!/usr/bin/env iptables-restore
*filter
# set default filter policies on forward, input and output
:FORWARD DROP [0:0]
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
# allow everything related to an already established input connection
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# allow all local connections
# necessary for example to connect to mysql via jdbc
-A INPUT -i lo -j ACCEPT
#
# allow selected protocols (whitelist)
# using protocol names from /etc/services for readability
#
# allow ssh on default ssh port
-A INPUT -p tcp --dport ssh -j ACCEPT
# allow ssh on a secret ssh port
#-A INPUT -p tcp --dport 12345 -j ACCEPT
# allow unsecure web requests
-A INPUT -p tcp --dport http -j ACCEPT
# allow secure web requests
#-A INPUT -p tcp --dport https -j ACCEPT
# allow incoming dns queries
-A INPUT -p udp --dport domain -j ACCEPT
# allow incoming unsecure email connection via smtp
-A INPUT -p tcp --dport smtp -j ACCEPT
# allow incoming secure email connection via smtp
-A INPUT -p tcp --dport smtps -j ACCEPT
# allow unsecure email download via pop3
-A INPUT -p tcp --dport pop3 -j ACCEPT
# allow unsecure email download via imap
-A INPUT -p tcp --dport imap -j ACCEPT
# allow secure email download via pop3
-A INPUT -p tcp --dport pop3s -j ACCEPT
# allow secure email download via imap
-A INPUT -p TCP --dport imaps -j ACCEPT
# allow subversion
-A INPUT -p TCP --dport svn -j ACCEPT
#
# secure against known TCP based attacks
#
-A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
-A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
-A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP
-A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
#
# allow only some ICMP types (ping)
#
-A INPUT -p icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp --icmp-type 3 -j ACCEPT
-A INPUT -p icmp --icmp-type 11 -j ACCEPT
-A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT
-A INPUT -p icmp -j DROP
#
# log attacks to syslog
# limit logging to protect against denial-of-service attacks
# look at attacks with command 'dmesg | less'
#
#-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
COMMIT
Uncomment and change the ssh ports if your ssh daemon runs on the different port. Please use a second terminal to test it first and stay logged in on the first terminal. Uncomment the last rule if you want to see your firewall in action and how many - previously invisible - attacks are launched against your server. I guess you'll be surprised.
A final word: I'm not a firewall expert and if you know better or have a proposition for an rule to add please leave a comment.
