Search

Thursday, September 1, 2016

Centos 7 Network Hardening: How to Protect Your Server from Basic Network Attacks using IPTABLES Firewall

Linux iptables, included in Centos 7 distribution, provides a mechanism to block basic network attacks. This is a guide to set up basic iptables firewall rules to protect your server from some of the most common and simplest network attacks.



Since you are here reading this, I assume you already have iptables installed and running, i.e. the command systemctl status iptables produces an output similar to this:

iptables.service - IPv4 firewall with iptables
   Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
   Active: active (exited) since Mon 2016-08-22 23:37:19 UTC; 1 weeks 2 days ago
 Main PID: 598 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/iptables.service

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.

Also disable the Centos 7 firewalld daemon. It attempts to provide an interface to manipulating iptables which I do not want and do not use at all.

# systemctl stop firewalld
# systemctl disable firewalld

The first step now is to examine your existing rules with line numbers.

# iptables -nL --line-numbers

If you have no rules defined, you will see empty lists:

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

Otherwise, if some rules are defined, you will see them with line numbers, as in the following example of what I see. Note: I use fail2ban and custom blocklist scripts; the following example includes the resulting rules.

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 110,995,143,993,587,465,4190 match-set f2b-dovecot src reject-with icmp-port-unreachable
2    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587,220,993,110,995 match-set f2b-postfix-sasl src reject-with icmp-port-unreachable
3    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-postfix src reject-with icmp-port-unreachable
4    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-sendmail-reject src reject-with icmp-port-unreachable
5    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-postfix-rbl src reject-with icmp-port-unreachable
6    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 587,465,25 match-set f2b-sendmail-auth src reject-with icmp-port-unreachable
7    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 8080 match-set f2b-squid src reject-with icmp-port-unreachable
8    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22 match-set f2b-sshd-ddos src reject-with icmp-port-unreachable
9    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22 match-set f2b-sshd src reject-with icmp-port-unreachable
10   ACCEPT     all  --  64.137.248.161       0.0.0.0/0
11   DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set blacklist src
12   DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set blacklistnet src
13   IP4BOGONS  all  --  0.0.0.0/0            0.0.0.0/0
14   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 110,995,143,993,587,465,4190 match-set f2b-dovecot src reject-with icmp-port-unreachable
15   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-sendmail-reject src reject-with icmp-port-unreachable
16   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587,220,993,110,995 match-set f2b-postfix-sasl src reject-with icmp-port-unreachable
17   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 587,465,25 match-set f2b-sendmail-auth src reject-with icmp-port-unreachable
18   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-postfix-rbl src reject-with icmp-port-unreachable
19   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 8080 match-set f2b-squid src reject-with icmp-port-unreachable
20   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-postfix src reject-with icmp-port-unreachable
21   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22 match-set f2b-sshd-ddos src reject-with icmp-port-unreachable
22   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22 match-set f2b-sshd src reject-with icmp-port-unreachable
23   ACCEPT     all  --  64.137.248.161       0.0.0.0/0
24   DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set block src
25   DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:!0x17/0x02 state NEW
26   DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x3F
27   DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x00
28   DROP       all  -f  0.0.0.0/0            0.0.0.0/0
29   ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
30   ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
31   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
32   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:23
33   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:25
34   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:53
35   ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53
36   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:80
37   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:110
38   ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:123
39   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:143
40   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:443
41   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:465
42   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:587
43   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:993
44   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:995
45   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:4190
46   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:8080
47   ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:65514
48   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:65515
49   REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination
1    REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain IP4BOGONS (1 references)
num  target     prot opt source               destination
1    RETURN     all  --  10.0.0.0/8           0.0.0.0/0
2    RETURN     all  --  172.16.0.0/12        0.0.0.0/0
3    RETURN     all  --  192.168.0.0/16       0.0.0.0/0
4    DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set fullbogons-ipv4 src

In any case, we start by inserting a rule at the top of, i.e. line number 1, the ACCEPT list to drop fragmented packets. This blocks IP fragmentation exploits like IP fragment overlapped (teardrop), IP fragmentation buffer full, IP fragment overrun, IP fragment too many data-grams, IP fragment incomplete, IP Fragment Too Small and similar attacks. We use the -I switch with iptables to insert a rule at a position 1.

# iptables -I INPUT 1 -f -j DROP

Next, we stop Null Scans, which are basically a bunch of TCP packets with sequence number 0 and no flags set. Such packets are not used in proper network communications, and are used to find open ports or holes by hackers. The following command will insert the rule at the top of the ACCEPT table, pushing the existing rules down by one line.

# iptables -I INPUT 1 -p tcp --tcp-flags ALL NONE -j DROP

We next stop TCP "Christmas Tree" packets - unusual packets that have all flags set. These packets are used by hackers to explore the security and features of servers, and often provide clues to the underlying operating system because operating systems react differently to such packets. Again we insert this rule at the top (line number 1), pushing existing rules down.

# iptables -I INPUT 1 -p tcp --tcp-flags ALL ALL -j DROP

Finally we attempt to check TCP SYN Flood attacks by inserting a rule at the top.

# iptables -I INPUT 1 -p tcp ! --syn -m state --state NEW -j DROP

After executing these four commands, the first four rules in the ACCEPT change should show the resulting iptables firewall rules, followed by whatever other rules existed before.

# iptables -nL --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:!0x16/0x02 state NEW
2    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x3F/0x3F
3    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x3F/0x00
4    DROP       all  -f  0.0.0.0/0            0.0.0.0/0
...
...
...

Making it permanent

We need to make the changes permanent, i.e. persistent across system restarts and reboots. On my server, iptables starts up on reboot using the default rules file /etc/sysconfig/iptables and then eventually other applications add what they need later on (e.g. a script I run to block of malware / attack sources based on publicly available blocklists, fail2ban jails created by fail2ban, etc.).

Therefore, I just saved the four rules in the default iptables system configuration file /etc/sysconfig/iptables


Finally, please make sure your /etc/sysctl.conf file has some server hardening parameters, including for securing your network. Here is mine.





Starter /etc/sysconfig/iptables

You can use the following iptables as the starting point. Simply copy and put it into /etc/sysconfig/iptables and then adjust the ports that it opens up for the services your server provides.

No comments:

Post a Comment

Recommended Products from Amazon