IPTables Example Configuration

from here

IPTables is a very powerful firewall that allows you to protect your Linux servers. I have been looking for some best practices to protect a server from the Internet and after collecting some examples here and there I came up with the following rules. This will block all the bad stuff, allow inbound SSH and also allows outgoing traffic from the server itself.

Don’t just copy and paste this script as there is always a change to block some legitimate traffic, look at the example and then decide for yourself what you want to use. Having said that, let’s take a look:

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# ACCEPT LOOPBACK
-A INPUT -i lo -j ACCEPT
# FIRST PACKET HAS TO BE TCP SYN
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# DROP FRAGMENTS
-A INPUT -f -j DROP

# DROP XMAS PACKETS
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# DROP NULL PACKETS
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# DROP EXCESSIVE TCP RST PACKETS
-A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

# DROP ALL INVALID PACKETS
-A INPUT -m state --state INVALID -j DROP
-A FORWARD -m state --state INVALID -j DROP
-A OUTPUT -m state --state INVALID -j DROP

# DROP RFC1918 PACKETS
-A INPUT -s 10.0.0.0/8 -j DROP
-A INPUT -s 172.16.0.0/12 -j DROP
-A INPUT -s 192.168.0.0/16 -j DROP

# DROP SPOOFED PACKETS
-A INPUT -s 169.254.0.0/16 -j DROP
-A INPUT -s 127.0.0.0/8 -j DROP
-A INPUT -s 224.0.0.0/4 -j DROP
-A INPUT -d 224.0.0.0/4 -j DROP
-A INPUT -s 240.0.0.0/5 -j DROP
-A INPUT -d 240.0.0.0/5 -j DROP
-A INPUT -s 0.0.0.0/8 -j DROP
-A INPUT -d 0.0.0.0/8 -j DROP
-A INPUT -d 239.255.255.0/24 -j DROP
-A INPUT -d 255.255.255.255 -j DROP

# ICMP SMURF ATTACKS + RATE LIMIT THE REST
-A INPUT -p icmp --icmp-type address-mask-request -j DROP
-A INPUT -p icmp --icmp-type timestamp-request -j DROP
-A INPUT -p icmp --icmp-type router-solicitation -j DROP
-A INPUT -p icmp -m limit --limit 2/second -j ACCEPT

# ACCEPT SSH
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# DROP SYN-FLOOD PACKETS
-A INPUT -p tcp -m state --state NEW -m limit --limit 50/second --limit-burst 50 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -j DROP

# ALLOW ESTABLISHED CONNECTIONS
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

COMMIT

Explanation of Rules

Accept Loopback Traffic

-A INPUT -i lo -j ACCEPT

We should permit local traffic on the server.

First TCP segment requires SYN bit

-A INPUT -p tcp ! --syn -m state --state NEW -j DROP

When TCP establishes a connection it will perform a 3 way handshake. The first TCP packet always has the SYN bit set. If it doesn’t have this, we will drop the traffic.

No Fragments allowed

-A INPUT -f -j DROP

We don’t allow fragmented IP Packets.

XMAS Packets

-A INPUT -p tcp --tcp-flags ALL ALL -j DROP

A TCP packet that has all the flags set is called a XMAS packet and should never be accepted.

Null Packets

-A INPUT -p tcp --tcp-flags ALL NONE -j DROP

A Null packet is a TCP packet without any flags. This is never used in legitimate traffic so it should be dropped.

Excessive TCP RST Packets

-A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT

The TCP RST (Reset) is used to abort a TCP connection so we shouldn’t see many of these at the same time. They are accepted but limited to 2 per second with a burst of 2.

Invalid Packets

-A INPUT -m state --state INVALID -j DROP
-A FORWARD -m state --state INVALID -j DROP
-A OUTPUT -m state --state INVALID -j DROP

When using stateful packet inspection, a packet can be new, established or related. When it’s not one of these, it is considered invalid and should be dropped.

RFC 1918 Packets

-A INPUT -s 10.0.0.0/8 -j DROP
-A INPUT -s 172.16.0.0/12 -j DROP
-A INPUT -s 192.168.0.0/16 -j DROP

On the Internet we should never see IP packets from private IP addresses so we’ll drop them.

Spoofed Packets

-A INPUT -s 169.254.0.0/16 -j DROP
-A INPUT -s 127.0.0.0/8 -j DROP
-A INPUT -s 224.0.0.0/4 -j DROP
-A INPUT -d 224.0.0.0/4 -j DROP
-A INPUT -s 240.0.0.0/5 -j DROP
-A INPUT -d 240.0.0.0/5 -j DROP
-A INPUT -s 0.0.0.0/8 -j DROP
-A INPUT -d 0.0.0.0/8 -j DROP
-A INPUT -d 239.255.255.0/24 -j DROP
-A INPUT -d 255.255.255.255 -j DROP

We shouldn’t see the ranges above so when we do, they are considered as spoofed and dropped.

ICMP Smurf Attack and Rate Limit

-A INPUT -p icmp --icmp-type address-mask-request -j DROP
-A INPUT -p icmp --icmp-type timestamp-request -j DROP
-A INPUT -p icmp --icmp-type router-solicitation -j DROP
-A INPUT -p icmp -m limit --limit 2/second -j ACCEPT

We allow most ICMP traffic but it is rate-limited.

SSH Connections

-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

SSH is allowed for remote access.

SYN Flood Protection

-A INPUT -p tcp -m state --state NEW -m limit --limit 50/second --limit-burst 50 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -j DROP

A SYN flood is a DOS attack where the attacker sends a lot of SYN packets but never completes the 3 way handshake. As a result the server will have a lot of “half open” connections and might not be able to serve new connections. Be careful with this setting as this is a global limit.

Established Connections

-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Packets with the “new” state are checked with our first rule, we drop “invalid” packets so at the end we can accept all “related” and “established” packets.

Hopefully this iptables example gives you a template to work on. If you want to protect your device even more you might want to consider looking at the hashlimit module. This allows you to rate-limit traffic based on IP addresses and port numbers, which might be helpful to combat some DOS attacks.

How to check current linux connections

quante tipi di connessioni da un dato ip
netstat -nat | grep 146.0.191.49 | awk ‘{print $6}’ | sort | uniq -c | sort -n

quante porte usate da un dato ip
netstat -nat | grep 146.0.191.49 | awk ‘{print $4}’ | sort | uniq -c | sort -n

numero di connessioni presenti per indirizzo ip
netstat -atun | awk ‘{print $5}’ | cut -d: -f1 | sed -e ‘/^$/d’ |sort | uniq -c | sort -n

numero totale di connessioni
netstat -nat | awk ‘{ print $5}’ | cut -d: -f1 | sed -e ‘/^$/d’ | uniq | wc -l

numero porte utilizzate
netstat -nat | awk ‘{print $4}’| cut -d: -f2 | sort | uniq -c | sort -n



lsof -ni | egrep -i “10\.0\.8|193\.170”

Subnet mask values and figure out what they mean

Here are the charts, followed by some explanations of what they mean.

CIDR SUBNET MASK WILDCARD MASK # OF IP ADDRESSES # OF USABLE IP ADDRESSES
/32 255.255.255.255 0.0.0.0 1 1
/31 255.255.255.254 0.0.0.1 2 2*
/30 255.255.255.252 0.0.0.3 4 2
/29 255.255.255.248 0.0.0.7 8 6
/28 255.255.255.240 0.0.0.15 16 14
/27 255.255.255.224 0.0.0.31 32 30
/26 255.255.255.192 0.0.0.63 64 62
/25 255.255.255.128 0.0.0.127 128 126
/24 255.255.255.0 0.0.0.255 256 254
/23 255.255.254.0 0.0.1.255 512 510
/22 255.255.252.0 0.0.3.255 1,024 1,022
/21 255.255.248.0 0.0.7.255 2,048 2,046
/20 255.255.240.0 0.0.15.255 4,096 4,094
/19 255.255.224.0 0.0.31.255 8,192 8,190
/18 255.255.192.0 0.0.63.255 16,384 16,382
/17 255.255.128.0 0.0.127.255 32,768 32,766
/16 255.255.0.0 0.0.255.255 65,536 65,534
/15 255.254.0.0 0.1.255.255 131,072 131,070
/14 255.252.0.0 0.3.255.255 262,144 262,142
/13 255.248.0.0 0.7.255.255 524,288 524,286
/12 255.240.0.0 0.15.255.255 1,048,576 1,048,574
/11 255.224.0.0 0.31.255.255 2,097,152 2,097,150
/10 255.192.0.0 0.63.255.255 4,194,304 4,194,302
/9 255.128.0.0 0.127.255.255 8,388,608 8,388,606
/8 255.0.0.0 0.255.255.255 16,777,216 16,777,214
/7 254.0.0.0 1.255.255.255 33,554,432 33,554,430
/6 252.0.0.0 3.255.255.255 67,108,864 67,108,862
/5 248.0.0.0 7.255.255.255 134,217,728 134,217,726
/4 240.0.0.0 15.255.255.255 268,435,456 268,435,454
/3 224.0.0.0 31.255.255.255 536,870,912 536,870,910
/2 192.0.0.0 63.255.255.255 1,073,741,824 1,073,741,822
/1 128.0.0.0 127.255.255.255 2,147,483,648 2,147,483,646
/0 0.0.0.0 255.255.255.255 4,294,967,296 4,294,967,294

* /31 is a special case detailed in RFC 3021 where networks with this type of subnet mask can assign two IP addresses as a point-to-point link.

And here’s a table of the decimal to binary conversions for subnet mask and wildcard octets:

SUBNET MASK WILDCARD
0 00000000 255 11111111
128 10000000 127 01111111
192 11000000 63 00111111
224 11100000 31 00011111
240 11110000 15 00001111
248 11111000 7 00000111
252 11111100 3 00000011
254 11111110 1 00000001
255 11111111 0 00000000

Note that the wildcard is just the inverse of the subnet mask.

 

here the original article

Apache command connection check

The netstat command has been deprecated and replaced by the ss command in most of the Linux distributions.

It reads various ‘/proc’ files to gather information. It would take more time when there are lots of connections to display.

1) Checking the number of concurrent Apache connections

Run following ss command to find the total number of concurrent connections to Apache:

# ss -ant | grep -E ':80|:443' | wc -l
500

Alternatively, you can get Apache concurrent connection using netstat command as shown below:

# netstat -ant | grep -E ':80|:443' | wc -l
430

2) Checking concurrent connections of Apache in detail

Run the below ss command to see detailed information of Apache connections instead of counting it.

It shows the active internet connections on the server on port 80 & 443:

# ss -ant | grep -E ':80|:443'

 LISTEN     0      128    10.10.6.160:80                       :                  
106.222.112.160:12650              
 TIME-WAIT  0      0      94.237.76.92:443                114.119.135.42:2366               
 TIME-WAIT  0      0      94.237.76.92:443                114.119.135.42:2406               
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38400              
 ESTAB      0      0      127.0.0.1:38454              94.237.76.92:443                     
 ESTAB      0      0      94.237.76.92:443                117.249.205.234:64685              
 ESTAB      0      0      94.237.76.92:443                192.99.9.25:33132              
 ESTAB      0      0      94.237.76.92:443                66.249.71.82:49611              
 ESTAB      0      0      94.237.76.92:443                106.222.112.160:12648              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38412              
 ESTAB      0      0      127.0.0.1:38402              94.237.76.92:443                
 TIME-WAIT  0      0      94.237.76.92:443                157.46.105.172:45656              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38340              
 ESTAB      0      151496 94.237.76.92:443                106.222.112.160:12656              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38332              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38396              
 ESTAB      0      0      127.0.0.1:38460              94.237.76.92:443                
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38374              
 ESTAB      0      0      94.237.76.92:80                 5.9.61.232:51082              
 ESTAB      0      0      94.237.76.92:443                60.8.123.152:64476              
 ESTAB      0      0      94.237.76.92:443                167.114.209.104:35758              
 ESTAB      0      0      94.237.76.92:80                 106.222.112.160:12643              
 ESTAB      0      0      94.237.76.92:443                167.114.158.215:53270                          
 ESTAB      0      0      94.237.76.92:443                66.249.71.147:56912              
 ESTAB      0      0      94.237.76.92:443                127.0.0.1:38454              
 ESTAB      0      0      94.237.76.92:443                127.0.0.1:38468                         
 ESTAB      0      0      94.237.76.92:443                127.0.0.1:38402              
 TIME-WAIT  0      0      94.237.76.92:443                127.0.0.1:38366

Check the same information using the netstat command as shown below:

# netstat -ant | grep -E ':80|:443'

3) Listing Apache connections sort by IP

To count the number of connections currently active in Apache from each IP address and to sort them, use the following command:

# ss -ant |grep -E ':80|:443'|grep ESTAB| awk '{print $5}' | cut -d":" -f1 | sort | uniq -c | sort -nr

       8 94.237.76.92
       8 127.0.0.1
       2 5.9.61.232
       2 106.222.112.160
       1 98.236.14.66
       1 66.249.72.22
       1 66.249.71.48
       1 192.99.9.25
       1 167.114.209.104
       1 167.114.158.215

Similarly, you can find the same information using netstat command as shown below:

# netstat -ant |grep -E ':80|:443'|grep ESTAB | awk '{print $5}' | cut -d":" -f1 | sort | uniq -c | sort -nr

      6 162.158.155.70
      5 127.0.0.1
      2 172.68.51.180
      2 172.68.215.98
      2 172.68.215.86
      2 172.68.215.77
      2 172.68.215.75
      2 172.68.215.113
      2 172.68.215.111
      2 172.68.215.109
      2 172.68.215.101
      2 172.68.215.100
      2 162.158.150.128
      2 162.158.150.120
      2 162.158.118.154
      2 141.101.96.253
      2 141.101.96.243
      2 141.101.76.234
      2 141.101.105.254
	  .
	  .

Bonus Tips: 1) Counting running Apache processes in Linux

ps command is used to display all running processes in Linux system. Use the following format, if you would like to count the running Apache processes in Linux:

# ps -auxw | grep httpd | grep -v grep | wc -l
12

1.a) Listing Apache processes with ps

Use the following command to see the running httpd processes in Linux:

# ps auxw | grep httpd | grep -v grep
nobody    7988  0.0  0.5 253280 23252 ?        S    14:32   0:00 /usr/sbin/httpd -k start
nobody    8050  0.0  0.6 253412 24276 ?        S    14:33   0:00 /usr/sbin/httpd -k start
nobody    8054  0.0  0.6 253280 23288 ?        S    14:33   0:00 /usr/sbin/httpd -k start
nobody    8158  0.0  0.6 253280 23296 ?        S    14:33   0:00 /usr/sbin/httpd -k start
nobody    8159  0.0  0.5 253280 23176 ?        S    14:33   0:00 /usr/sbin/httpd -k start
daygeek   8202  0.0  0.6 253416 23304 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8203  0.0  0.5 253280 23052 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8207  0.0  0.5 253280 23044 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8213  0.0  0.6 253280 23300 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8216  0.0  0.5 253280 23052 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8218  0.0  0.6 253416 23304 ?        S    14:34   0:00 /usr/sbin/httpd -k start
nobody    8266  0.0  0.5 253148 23052 ?        S    14:35   0:00 /usr/sbin/httpd -k start
nobody    8267  0.0  0.5 253144 22800 ?        S    14:35   0:00 /usr/sbin/httpd -k start
nobody    8391  0.3  0.5 253144 22800 ?        S    14:35   0:00 /usr/sbin/httpd -k start
nobody    8393  0.5  0.5 253012 21776 ?        S    14:35   0:00 /usr/sbin/httpd -k start
nobody    8394  1.0  0.5 253144 22800 ?        S    14:35   0:00 /usr/sbin/httpd -k start
root     30500  0.0  0.0 227356  3584 ?        Ss   Jul25   2:33 /usr/sbin/httpd -k start

Let’s quickly look at the parameters

  • Serverlimit – Maximum number of Apache processes
  • StartServers – Number of processes to start when you start running Apache
  • MinSpareThreads/MaxSpareThreads – Number of threads to keep idle without being killed
  • ThreadsPerChild – Number of threads per process
  • MaxRequestWorkers – Number of concurrent connections to be supported. This is the main directive that you need to change to increase max connections in Apache
  • MaxConnectionsPerChild – Number of connections to be handled by each child before it is killed