Enhancing Netfilter with Layer 7 Protocol Filtering: A Comprehensive Guide

1: Iptables – Layer7

By default, iptables filters OSI layers 2, 3, and 4, including source MAC address filtering. For a specific application: xunlei, kugou, qq, msn, flv, p2p, httpd, smtp, etc., filtering is done directly based on the protocol. Netfilter does not have these functions by default. If we need to use layer 7 application protocol filtering, we must patch netfilter. Netfilter is just a framework by default. The actual filtering rules are implemented by iptables, but whether these rules are effective requires the framework provided by netfilter. At the same time, iptables must support layer 7 syntax. Therefore, we need to patch both netfilter and iptables. The official website for layer7: http://l7-filter.sourceforge.net/

  • 1: Review of Iptables

Iptables is just a management tool for the Linux firewall, located at /sbin/iptables. The actual implementation of firewall functionality is netfilter, which is the internal structure in the Linux kernel that implements packet filtering.

[root@linux-node1 ~]# vim /boot/config-2.6.32-573.el6.x86_64 # Core Netfilter Configuration#CONFIG_NETFILTER_NETLINK=mCONFIG_NETFILTER_NETLINK_QUEUE=mCONFIG_NETFILTER_NETLINK_LOG=mCONFIG_NF_CONNTRACK=mCONFIG_NF_CONNTRACK_MARK=y
  • 2: Iptables Four Tables and Five Chains

Four tables: filter, nat, mangle, raw. The default table is filter (if no table is specified, it is the filter table). Table processing priority: raw > mangle > nat > filter. filter: General filtering functions nat: Used for NAT functions (port mapping, address mapping, etc.) mangle: Used for modifying specific packets raw: Highest priority, setting raw is generally to prevent iptables from performing connection tracking on packets, improving performance. Five chains: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING. INPUT: Destination is the local machine after passing through the routing table OUTPUT: Generated by the local machine, forwarded outwards POSTROUTING: Before sending to the network card interface.

  • 3: Iptables Relationship Diagram
--> PREROUTING --> [ROUTE] --> FORWARD --> POSTROUTING -->             MANGLE       |     MANGLE          ^ MANGLE           NAT            |      NAT            | NAT                      ∨                 |                 INPUT                    OUTPUT                  |                         |   MANGLE                  |                         |   NAT                  ∨    -->  LOCAL    -->    ^   FILTER
  • 4: Common Parameters
-t  Specify table-A  Specify chain-I  Insert a rule at the top-D  Delete a rule-F  Flush all rules-L  List all rules-N  Define a custom chain (can be used after -j)-P  Set default policy-Z  Zero packet and byte counters-s  Match a specific source IP address-d  Match a specific destination IP address-p  Specify protocol, tcp, udp, icmp-i  Specify incoming network card, e.g., -e eth0-o  Specify outgoing interface-j  Action, DROP, REJECT, ACCEPT, LOG-n  Do not resolve, display numeric values-v  Verbose output--line-numbers  Number each rule
  • 5: SSH Enhanced Configuration
[root@linux-node1 ~]# iptables -t filter -A INPUT -i lo -j ACCEPT[root@linux-node1 ~]# iptables -t filter -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT[root@linux-node1 ~]# iptables -t filter -P INPUT DROP[root@linux-node1 ~]# iptables -L INPUT -nv        +----------------------------------------------------------------------------------------------------+        | Chain INPUT (policy DROP 15 packets, 1321 bytes)                                                   |        | pkts bytes target     prot opt in     out     source               destination                     |        |    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0                       |        |  123  9128 ACCEPT     tcp  --  *      *       192.168.1.0/24       0.0.0.0/0           tcp dpt:22  |        +----------------------------------------------------------------------------------------------------+[root@linux-node1 ~]# iptables -L INPUT -nv --line-number        +--------------------------------------------------------------------------------------------------------+        | Chain INPUT (policy DROP 25 packets, 2720 bytes)                                                       |        | num   pkts bytes target     prot opt in     out     source               destination                   |        | 1        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0                     |        | 2      155 11432 ACCEPT     tcp  --  *      *       192.168.1.0/24       0.0.0.0/0           tcp dpt:22|        +--------------------------------------------------------------------------------------------------------+
  • 6: Extended Match -m
[root@linux-node1 ~]# iptables -t filter -P INPUT ACCEPT
  • 6.1: Deny Others from Pinging You

But you can ping others. There are two methods here.

  • 6.1.1 Modify Kernel Parameters
[root@linux-node1 ~]# cat /proc/sys/net/ipv4/icmp_echo_ignore_all         +--+        | 0|        +--+[root@linux-node1 ~]# echo 1 > !$    Test: In Windows cmdC:\Users\Thinkpad>ping 192.168.1.11        +----------------------------------------------------------+        |                                                          |        |Pinging 192.168.1.11 with 32 bytes of data:               |        |Request timed out.                                        |        |Request timed out.                                        |        |Request timed out.                                        |        |Request timed out.                                        |        |                                                          |        |Ping statistics for 192.168.1.11:                         |        |    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),|        +----------------------------------------------------------+    Note: If your host is configured with this, no matter how you stop, you can always ping through, but you are not actually pinging the server.
  • 6.1.2 Iptables Control
[root@linux-node1 ~]# echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all    --icmp-type echo-request indicates a request, outgoing            echo-reply indicates a reply, incoming[root@linux-node1 ~]# iptables -t filter -A INPUT -s 192.168.1.0/24 -p icmp -m icmp --icmp-type echo-reply -j DROP        In this case, the return is denied, so it actually pings out, but cannot get a reply, you cannot ping out[root@linux-node1 ~]# ping 192.168.1.13        +----------------------------------------------------------------+        |PING 192.168.1.13 (192.168.1.13) 56(84) bytes of data.          |        |^C                                                              |        |--- 192.168.1.13 ping statistics ---                            |        |3 packets transmitted, 0 received, 100% packet loss, time 2243ms|        +----------------------------------------------------------------+[root@linux-node1 ~]# iptables -t filter -D INPUT -s 192.168.1.0/24 -p icmp -m icmp --icmp-type echo-reply -j DROP[root@linux-node1 ~]# iptables -t filter -A INPUT -s 192.168.1.0/24 -p icmp -m icmp --icmp-type echo-request -j DROP        You can ping others, but others cannot ping you
  • 6.2: Limit Connection Count
-m connlimit --connlimit-above 2 Maximum number of connections per client does not exceed two[root@linux-node1 ~]# iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -m connlimit -h        Help retrieval[root@linux-node1 ~]# iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j DROP
  • 6.3: Limit FTP Download Speed
[root@linux-node1 ~]# iptables -D INPUT -s 192.168.1.0/24 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j DROP    -m limit --limit Match speed [--burst Buffer count][root@linux-node1 ~]# iptables -A INPUT -d 192.168.1.11 -m limit --limit 1/s -j ACCEPT[root@linux-node1 ~]# iptables -A INPUT -d 192.168.1.11 -j DROP[root@linux-node1 ~]# rpm -ivh /media/Packages/vsftpd-2.2.2-14.el6.x86_64.rpm && /etc/init.d/vsftpd restart[root@linux-node1 ~]# dd if=/dev/zero of=/var/ftp/a.txt bs=100M count=1    Test:[root@linux-node2 ~]# yum install -y lftp[root@linux-node2 ~]# lftp 192.168.1.11    lftp 192.168.1.11:~> ls        +--------------------------------------------------------------+        |-rw-r--r--    1 0        0        104857600 Jul 09 10:32 a.txt|        |drwxr-xr-x    2 0        0            4096 Mar 06  2015 pub   |        +--------------------------------------------------------------+    lftp 192.168.1.11:/> get a.txt        +--------------------------------------------------------+        |`a.txt' at 158088 (0%) 3.8K/s eta:7h8m [Receiving data] |        +--------------------------------------------------------+
  • 6.3: ICMP Flood Attack
By using many hosts' ping packets to saturate the bandwidth of the attacked host.     ping -i  Specify interval     Example: 0.001 seconds, send a ping packet [root@linux-node1 ~]# iptables -F[root@linux-node2 ~]# ping -i 0.001 192.168.1.11Solution:[root@linux-node1 ~]# iptables -t filter -A INPUT -p icmp -m icmp --icmp-type echo-request -m limit --limit 2/s -j ACCEPT[root@linux-node1 ~]# iptables -t filter -A INPUT -p icmp -m icmp --icmp-type echo-request -j DROPTest:[root@linux-node2 ~]# ping -i 0.001 192.168.1.11Speed significantly slows downIntermittent ping[root@linux-node1 ~]# iptables -F[root@linux-node1 ~]# iptables -A INPUT -p icmp -m icmp --icmp-type echo-request -m limit --limit 6/min --limit-burst 2 -j ACCEPT[root@linux-node1 ~]# iptables -A INPUT -p icmp -m icmp --icmp-type echo-request -j DROP    Test:C:\Users\Thinkpad>ping 192.168.1.111 -t        +--------------------------------------------------+        |Pinging 192.168.1.111 with 32 bytes of data:      |        |Reply from 192.168.1.111: bytes=32 time<1ms TTL=64|        |Reply from 192.168.1.111: bytes=32 time<1ms TTL=64|        |Request timed out.                                |        |Request timed out.                                |        |Reply from 192.168.1.111: bytes=32 time=2ms TTL=64|        |Request timed out.                                |        |Request timed out.                                |        |Reply from 192.168.1.111: bytes=32 time=3ms TTL=64|        |Request timed out.                                |        |Request timed out.                                |        |Reply from 192.168.1.111: bytes=32 time<1ms TTL=64|        +--------------------------------------------------+
  • 6.4: Multiport Usage
Just an example, consider carefully in production[root@linux-node1 ~]# iptables -F[root@linux-node1 ~]# iptables -A FORWARD -s 192.168.1.111 -p tcp -m multiport --sport 80,23,22 -j ACCEPT[root@linux-node1 ~]# iptables -A FORWARD -s 192.168.1.111 -j DROP[root@linux-node1 ~]# iptables -A FORWARD -s 192.168.1.111 -p tcp -d 192.168.1.111 -m multiport --dport 80,22,23 -j ACCEPT[root@linux-node1 ~]# iptables -A FORWARD -s 192.168.1.111 -p tcp -d 192.168.1.111 -j DROP[root@linux-node1 ~]# iptables -F
  • 6.5: State Rules
-m  stat  State-based firewall rules:     tcp: Three-way handshake, only the first packet SYN, state is: NEW. Others are: ESTABLISHED     ftp: RELATED  FTP Active Mode: Active mode diagram            In step 1, the client's command port establishes a connection with the FTP server's command port and sends the command "PORT 1027".            In step 2, the FTP server returns an "ACK" to the client's command port.             In step 3, the FTP server initiates a connection from its own data port (20) to the client's previously specified data port (1027).             In step 4, an "ACK" is returned to the server.             The main problem with active FTP is actually on the client side. The FTP client does not actually establish a connection to the server's data port; it simply tells the server the port number it is listening on, and the server connects back to this specified port on the client. For the client's firewall, this is a connection from an external system to the internal client, which is usually blocked. Passive Mode: FTP pasv Passive mode diagram            In step 1, the client's command port establishes a connection with the server's command port and sends the command "PASV".             In step 2, the server returns the command "PORT 2024", telling the client (server) which port to listen on for the data connection.             In step 3, the client initializes a data connection from its own data port to the server-specified data port.             Finally, in step 4, the server returns an "ACK" response to the client's data port. Configure Passive Mode FTP Server: [root@linux-node1 ~]# vim /etc/vsftpd/vsftpd.conf         listen_port=21        pasv_enable=YES        pasv_min_port=9900        pasv_max_port=9999            Note: pasv_min_port and pasv_max_port specify the open port numbers [root@linux-node1 ~]# /etc/init.d/vsftpd restart[root@linux-node1 ~]# netstat -antup | grep 99*            No ports are found; passive mode requires data transfer to generate ports[root@linux-node2 ~]# lftp 192.168.1.11        lftp 192.168.1.11:~> ls[root@linux-node1 ~]# netstat -antup | grep 99*            +------------------------------------------------------------------------------------------+            |tcp        0      0 192.168.1.111:9925          192.168.1.13:46841          TIME_WAIT   - |            +------------------------------------------------------------------------------------------+Passive Mode FTP Firewall Rule Configuration:             FTP, unlike most other TCP applications, uses two TCP connections between the client process and the server process.             The first is the control connection, which lasts until the session between the client process and the server process is complete.             The other is the data connection, which can be created and destroyed as needed. Whenever a file is transferred, a data connection is created. The control connection is called the main connection, and the data connection is called the sub-connection.             The data connection is a sub-connection, and its connection state is identified as RELATED, not New, at the beginning of the connection. [root@linux-node1 ~]# iptables -t filter -A INPUT -i lo -j ACCEPT[root@linux-node1 ~]# iptables -t filter -A INPUT -s 0.0.0.0 -p tcp --dport 21 -j ACCEPT[root@linux-node1 ~]# iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT[root@linux-node1 ~]# iptables -P INPUT DROP[root@linux-node1 ~]# lsmod | grep nat_ftp[root@linux-node1 ~]# modprobe ip_nat_ftp[root@linux-node1 ~]# lsmod | grep nat_ftp            +------------------------------------------------------------------------------------+            |nf_nat_ftp              3443  0                                                     |            |nf_nat                 22676  1 nf_nat_ftp                                          |            |nf_conntrack_ftp       11953  1 nf_nat_ftp                                          |            |nf_conntrack           79206  4 nf_nat_ftp,nf_nat,nf_conntrack_ipv4,nf_conntrack_ftp|            +------------------------------------------------------------------------------------+[root@linux-node1 ~]# iptables -L INPUT -nv        +------------------------------------------------------------------------------------------------------------------+        |Chain INPUT (policy DROP 8 packets, 624 bytes)                                                                    |        | pkts bytes target     prot opt in     out     source               destination                                   |        |    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0                                     |        |    0     0 ACCEPT     tcp  --  *      *       0.0.0.0              0.0.0.0/0           tcp dpt:21                |        |  112  8288 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED |        +------------------------------------------------------------------------------------------------------------------+
  • 6.6: Mark Functionality

Use iptables mangle to mark, then use mark to match

[root@linux-node1 ~]# iptables -t mangle -A PREROUTING -m ttl --ttl-eq 64 -j MARK --set-mark 1    [root@linux-node1 ~]# iptables -t mangle -A PREROUTING -m ttl --ttl-eq 128 -j MARK --set-mark 2    [root@linux-node1 ~]# iptables -t filter -A FORWARD -m mark --mark 1 -j ACCEPT    [root@linux-node1 ~]# iptables -t filter -A FORWARD -m mark --mark 2 -j DROP    [root@linux-node1 ~]# iptables -t mangle -L -n    +------------------------------------------------------------------------------------------------+    |Chain PREROUTING (policy ACCEPT)                                                                |    |target     prot opt source               destination                                            |    |MARK       all  --  0.0.0.0/0            0.0.0.0/0           TTL match TTL == 64 MARK set 0x1   |    |MARK       all  --  0.0.0.0/0            0.0.0.0/0           TTL match TTL == 128 MARK set 0x2  |    +------------------------------------------------------------------------------------------------+    [root@linux-node1 ~]# iptables -t filter -L -nv    +--------------------------------------------------------------------------------------------------------+    |Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)                                                        |    | pkts bytes target     prot opt in     out     source               destination                         |    |    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           mark match 0x1  |    |    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           mark match 0x2  |    +--------------------------------------------------------------------------------------------------------+
  • 7: Server Iptables Operations
[root@mail netfilter]# iptables -t filter -F [root@mail netfilter]# iptables -t nat -F [root@mail netfilter]# iptables -t mangle -F [root@mail netfilter]#iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT [root@mail netfilter]# iptables -t filter -A INPUT -i lo -j ACCEPT [root@mail netfilter]# iptables -t filter -A INPUT -p icmp -m icmp --icmp-type echo-request -m limit --limit 2/second -j ACCEPT [root@mail netfilter]# iptabels -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT [root@mail netfilter]# iptables -t filter -A INPUT -m state --state INVALID -j DROP [root@mail netfilter]# iptables -t filter -P INPUT DROP FTP:    There is a difference between active and passive modes (the following is passive mode): [root@stu12 ~]# modprobe ip_nat_ftp [root@stu12 ~]# iptables -t filter -A INPUT -p tcp --dport 21 -j ACCEPT [root@stu12 ~]# iptabels -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT    DNS:[root@stu12 ~]# iptables -t filter -A INPUT -p tcp -d 1.1.1.1 --dport 53 -j ACCEPT [root@stu12 ~]# iptables -t filter -A INPUT -p udp -d 1.1.1.1 --dport 53 -j ACCEPT    NFS:    NFS service ports are fixed at 111 and 2049.     However, rquotad, nlockmgr, and mountd service ports are random. Since the ports are random, it makes it impossible to set up a firewall. At this time, you need to configure /etc/sysconfig/nfs to fix the ports for rquotad, nlockmgr, and mountd. [root@stu12 ~]#vim /etc/sysconfig/nfs          #Modify the corresponding line content    13:RQUOTAD_PORT=10003     20:LOCKD_TCPPORT=10000     22:LOCKD_UDPPORT=10000     57:MOUNTD_PORT=10001 [root@stu12 ~]# service nfs restart[root@stu12 ~]# iptables -t filter -A INPUT -p tcp --dport 111 -j ACCEPT [root@stu12 ~]# iptables -t filter -A INPUT -p udp --dport 111 -j ACCEPT [root@stu12 ~]# iptables -t filter -A INPUT -p tcp --dport 2049 -j ACCEPT [root@stu12 ~]# iptables -t filter -A INPUT -p udp --dport 2049 -j ACCEPT [root@stu12 ~]# iptables -t filter -A INPUT -s 192.168.1.0/24 -p udp -m multiport --dports 111,2049,10000,10001,10003 -j ACCEPT[root@stu12 ~]# iptables -t filter -A INPUT -s 192.168.1.0/24 -p tcp -m multiport  --dports 111,2049,10000,10001,10003 -j ACCEPT 

Summary: 1. samba tcp 139/445 udp 137/138 2. ftp ip_nat_ftp module + RELATED state 3. HTTP 80/443 4. SMTP 25 POP3 110 IMAP 143 POP3S 995 IMAPS 993 5. tftp 69

  • 8: Log Management

1. rsyslog service records logs. 2. Application-generated logs (apache, mysql) 3. ELK rsyslog advantages: 1. You can specify the log storage location through /etc/rsyslog.conf (can be local or remote) undefined 2. You can use logrorate to truncate logs. Log storage path: /var/log

  • 8.1: Last Related Logs
last #Used to display user login status. [root@linux-node1 ~]# ls /var/log/wtmp  #last reads this log file [root@linux-node1 ~]# last       #A lot of information output[root@linux-node1 ~]# > /var/log/wtmp [root@linux-node1 ~]# last       #No information output after clearing
  • 8.2: Lastb Related Logs

lastb is used to view accounts that failed to log in via ssh. Command: lastb, corresponding log /var/log/btmp. Generally speaking, if this file is large, consider whether there is a brute force attack. A habitual action of an operations personnel: After logging in: w command grep bash /etc/passwd #Check if there are any extra users /tmp #Check if there are any extremely default files, the system is set to clear them regularly. Extension: tmpwatch, delete files in the tmp directory that have not been used for a long time.

[root@linux-node1 ~]# rpm -ivh /media/Packages/tmpwatch-2.9.16-4.el6.x86_64.rpm         [root@linux-node1 ~]# tmpwatch -h            -a|-all     Delete any type of file            -m|-mtime   Based on file modification time            -c|-ctime   Based on file status change time            -f|-force   Force delete files or directories, similar to rm -f            -U|-exclude-user=USER|UID   Exclude files of a certain user            -x|-exclude=PATH        Exclude a certain path            -v|-verbose Output detailed process            -u|-atime   Based on access time

Linux Timestamps: ctime, mtime, atime ctime: File change time (mainly refers to file attributes) mtime: Modification time (mainly refers to file content) atime: Access time The main difference between change and modification is changing a component’s label, mtime is changing the content. Delete files in /tmp that are older than 5 days root@linux-node1 ~#tmpwatch -afv 5d /tmp/ tmpwatch scheduled cleanup task:

[root@linux-node1 ~]# vim /etc/cron.daily/tmpwatch             #! /bin/sh            flags=-umc            /usr/sbin/tmpwatch "$flags" -x /tmp/.X11-unix -x /tmp/.XIM-unix \                    -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \                    -X '/tmp/hsperfdata_*' 10d /tmp            /usr/sbin/tmpwatch "$flags" 30d /var/tmp            for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do                if [ -d "$d" ]; then                    /usr/sbin/tmpwatch "$flags" -f 30d "$d"                fi            done        This is a scheduled task to clear the /tmp directory every 30 days    Kill illegal login connections, first check which terminal is currently logged in[root@linux-node1 ~]# ps -aux | grep pts            +------------------------------------------------------------------------------------+            |Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ       |            |root       2776  0.0  0.9  98384  4472 ?        Ss   18:37   0:02 sshd: root@pts/2  |            |root       2778  0.0  0.3 108304  1940 pts/2    Ss   18:38   0:00 -bash             |            |root       3360  0.0  0.2 110232  1176 pts/2    R+   21:11   0:00 ps -aux           |            |root       3361  0.0  0.1 103308   896 pts/2    S+   21:11   0:00 grep pts          |            +------------------------------------------------------------------------------------+[root@linux-node1 ~]#kill -9 2776      #If found illegal, kill it directly
  • 8.3: Log Backup

Log backup: Situation 1: Manage logs with rsyslog, remote log backup can be performed. Situation 2: For application-managed logs, regular scp or rsync is required to back up logs to a remote host. Log truncation: The idea is to back up first, then clear, without deleting.

[root@linux-node1 ~]# cp /var/log/secure  data.sec  [root@linux-node1 ~]# > /var/log/secure