Server (VPS, openvz) Firewall Script - iptables

T

his tutorial works for CentOS only. For your specific OS tutorial use the tags or serach function in the sidebar area.

It is crucial that you have configure the firewall for to not only avoid security holes but also any sort of brute-force attempts or DDoS attacks. On linux machines default firewall is controlled by system iptables package. Iptables rules are difficult to maintain newborn sys admin like you therefore custom script comes in handy. Of course there are some packages like CSF but as RAM usage is important to all VPS owners - I stick with default iptables.

To check what Linux distributrion or CentOS version you have run: cat /etc/*-release

[root@vps ~]# cat /etc/*-release
CentOS release 6.4 (Final)
CentOS release 6.4 (Final)
CentOS release 6.4 (Final)
[root@vps ~]#
 

Here come the script itself. You can take a look:

 

Now, since we're setting up a new VPS system what we gonna do is download the script, make it executable, move to services for a ease of use and start it.

In console type: 

  1. wget sh.beadmin.2tl.eu/firewall.sh
    that will download the script from be.admin sources
  2. chmod +x firewall.sh
    set the executable flag on the script
  3. ls -l
    lists directory, checks 'if everything is ok' is good anywhere ;)
  4. mv firewall.sh /etc/init.d/firewall
    move to the services scripts directory
[root@vps ~]# wget http://sh.beadmin.2tl.eu/firewall.sh
--2013-07-02 07:54:51-- http://sh.beadmin.2tl.eu/firewall.sh
Resolving sh.beadmin.2tl.eu... 188.116.52.25
Connecting to sh.beadmin.2tl.eu|188.116.52.25|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5839 (5.7K) [application/x-sh]
Saving to: `firewall.sh'

100%[====================================================================>] 5,839 --.-K/s in 0s

2013-07-02 07:54:51 (458 MB/s) - `firewall.sh' saved [5839/5839]

[root@vps ~]# chmod x firewall.sh
[root@vps ~]# ls -l
total 8
-rwxr-xr-x 1 root root 5839 Jul 2 04:48 firewall.sh
[root@vps ~]# mv firewall.sh /etc/init.d/firewall
[root@vps ~]#
 

​We can now check our active iptables rules using the script:

Command: service firewall status

[root@vps ~]# service firewall status
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
[root@vps ~]#
 
 
As this is a fresh VPS installation, no rules are present. At this very time we can start our firewall but remeber:

SSH Port Warning

The tutorial assumes the SSH is on port 22 - since it's New VPS installation. If it's NOT make changes to the firewall script (lines 51-52)

To start firewall script simply enter: service firewall start

Now verify the rules are working: service firewall status

[root@vps ~]# service firewall start
[root@vps ~]# service firewall status
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 127.0.0.0/8
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:22
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp spt:22 flags:!0x17/0x02
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:53
ACCEPT udp -- 0.0.0.0/0 xxx.xxx.xxx.xxx udp dpt:53
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp spt:53 dpts:1024:65535 flags:!0x17/0x02
ACCEPT udp -- 0.0.0.0/0 xxx.xxx.xxx.xxx udp spt:53 dpts:1024:65535
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:25
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp spt:25 dpts:1024:65535 flags:!0x17/0x02
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp spts:1024:65535 dpt:113
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp spt:113 dpts:1024:65535 flags:!0x17/0x02
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:110
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:995
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:143
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:993
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:587
ACCEPT icmp -- 0.0.0.0/0 xxx.xxx.xxx.xxx icmp type 0
ACCEPT icmp -- 0.0.0.0/0 xxx.xxx.xxx.xxx icmp type 3
ACCEPT icmp -- 0.0.0.0/0 xxx.xxx.xxx.xxx icmp type 8
ACCEPT icmp -- 0.0.0.0/0 xxx.xxx.xxx.xxx icmp type 11
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:80
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:443
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:20
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp spt:20 dpts:1024:65535 flags:!0x17/0x02
ACCEPT udp -- 0.0.0.0/0 xxx.xxx.xxx.xxx udp dpt:20
ACCEPT udp -- 0.0.0.0/0 xxx.xxx.xxx.xxx udp spt:20 dpts:1024:65535
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp dpt:21
ACCEPT tcp -- 0.0.0.0/0 xxx.xxx.xxx.xxx tcp spt:21 dpts:1024:65535 flags:!0x17/0x02
ACCEPT udp -- 0.0.0.0/0 xxx.xxx.xxx.xxx udp dpt:21
ACCEPT udp -- 0.0.0.0/0 xxx.xxx.xxx.xxx udp spt:21 dpts:1024:65535
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:1024:65535 flags:!0x16/0x02
ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpts:1024:65535
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:35000:35999

Chain FORWARD (policy DROP)
target prot opt source destination

Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 127.0.0.0/8 0.0.0.0/0
ACCEPT all -- xxx.xxx.xxx.xxx 0.0.0.0/0
[root@vps ~]#
 
You should see something like above, but in place of xxx.xxx.xxx.xxx ther will be your VPS external IP(s). If everything's alright you can add firewall script to the autostart
by entering: chkconfig firewall on

And verify: chkconfig firewall --list

You should see something like this: 

[root@vps ~]# chkconfig firewall on
[root@vps ~]# chkconfig firewall --list
firewall 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@vps ~]#
 

How to edit the script?

We can use a system text editor. Simply enter: vi /etc/init.d/firewall , next press 'Insert' key, and make the changes but be very carefull, you must know what you're doing.
 
For example, block an IP:
  1. Navigate near line 124 , #manual deny section
  2. and type '${FWIN} -s xxx.xxx.xxx.xxx ${NO}' without the brackets and in new line, where the xxx.xxx.xxx.xxx is the IP to be blocked
For example, open a port 2222 in firewall:
  1. Navigate near line 119 and paste the code
 
for OURIP in ${SERVER_IPS}; do
${FWIN} -p tcp -d ${OURIP} --dport 2222 ${OK}
done
 
After making changes, for Save & Exit press 'Esc' key and type ':wq' and hit 'Enter'
 
After making any changes you have to restart firewall.
 
To do this simply enter: service firewall restart
 

Firewall Policy

Default firewall script policy is to DROP everything thay you don't allow. That's the most secure solution. If you i.e. install a service on specific port - you have to open that port in firewall as described above.

Additional security Rules

After #manual deny section ADD

#Disabling IP Spoofing attacks.
echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter

#Don't respond to broadcast pings
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

#Enable forwarding
echo 1 >/proc/sys/net/ipv4/ip_forward

#Block source routing
echo 0 >/proc/sys/net/ipv4/conf/all/accept_source_route

#Enable SYN Cookies
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

#Kill redirects
echo 0 >/proc/sys/net/ipv4/conf/all/accept_redirects

#Enable bad error message protection
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
 
After

"We allow access to our SMTP server, as well as answers
        # to our SMTP connections and, temporarily, identd stuff:
for OURIP in ${SERVER_IPS}; do"

ADD:

${FWIN} -p tcp --dport 25 --syn -m limit --limit 1 --limit-burst 10 ${OK}
${FWIN} -p tcp --dport 25 --syn ${NO}
 
 
Before: #manual deny ADD:
 
#tootledoodle iptables rule will help prevent DoS attack
${FWIN} -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 ${OK}
 
and you don't serve IRC
 
#Drop irc packets
$IPTABLES -A OUTPUT -p tcp --destination-port 6660:6669 -j DROP
$IPTABLES -A OUTPUT -p tcp --destination-port 7000 -j DROP