Netfilter
Linux Netfilter firewall is often configured via one of the following tools
iptables/ip6tables — administration tool for IPv4/IPv6 packet filtering and NAT
nft - Administration tool of the nftables framework for packet filtering and classification
firewall-cmd - firewalld command line client
Default policy
Allowing everything and denying a few ports you don’t need and who may be dangerous is not a good idea. For an effective network filtering, it’s far better to deny everything by default and allow what is needed. Each server and computer should have an active firewall to filter network traffic. This deny policy should be applied to incoming traffic and routed traffic but also to outgoing traffic.
Lateral movement refers to the techniques that cyber attackers, or threat actors, use to progressively move through a network as they search for the key data and assets that are ultimately the target of their attack campaigns. If each server and computer filter not only the incoming traffic but also the outgoing traffic, attackers will have less ways to move through your servers.
TCP MSS
The TCP protocol includes a mechanism for both ends of a connection to advertise the Maximum Segment Size (MSS) to be used by its peer when the connection is created. Each end uses the OPTIONS field in the TCP header to advertise a proposed MSS. If one endpoint does not provide its MSS, then 536 bytes is assumed for IPv4. Small MSS are bad for performance.
Technically, the MSS can be lower than 536. Some of the packets generated by nmap while doing OS fingerprinting are using such values.
84/* 8 options:
85 * 0~5: six options for SEQ/OPS/WIN/T1 probes.
86 * 6: ECN probe.
87 * 7-12: T2~T7 probes.
88 *
89 * option 0: WScale (10), Nop, MSS (1460), Timestamp, SackP
90 * option 1: MSS (1400), WScale (0), SackP, T(0xFFFFFFFF,0x0), EOL
91 * option 2: T(0xFFFFFFFF, 0x0), Nop, Nop, WScale (5), Nop, MSS (640)
92 * option 3: SackP, T(0xFFFFFFFF,0x0), WScale (10), EOL
93 * option 4: MSS (536), SackP, T(0xFFFFFFFF,0x0), WScale (10), EOL
94 * option 5: MSS (265), SackP, T(0xFFFFFFFF,0x0)
95 * option 6: WScale (10), Nop, MSS (1460), SackP, Nop, Nop
96 * option 7-11: WScale (10), Nop, MSS (265), T(0xFFFFFFFF,0x0), SackP
97 * option 12: WScale (15), Nop, MSS (265), T(0xFFFFFFFF,0x0), SackP
I have chosen to drop packets with a MSS lower than 536.
iptables
iptables and ip6tables are used to set up, maintain, and inspect the tables of IPv4 and IPv6 packet filter rules in the Linux kernel. Several different tables may be defined. Each table contains a number of built-in chains and may also contain user-defined chains.
On AlmaLinux 9, iptables-nft package brings nftables compatibility for iptables, arptables and ebtables.
A good policy is to deny everything by default.
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
Remember that filtering the OUTPUT traffic limits lateral movement.
To filter anomalous traffic early, instead of doing it in INPUT and FORWARD from table filter, it’s possible to do it in PREROUTING from table mangle.
In this example, the external interface is eth7.
iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
iptables -t mangle -A PREROUTING -p tcp ! --tcp-flags ALL SYN -m conntrack --ctstate NEW,RELATED -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN -m tcpmss ! --mss 536:65535 -j DROP
iptables -t mangle -A PREROUTING -p tcp --sport 0 -j DROP
iptables -t mangle -A PREROUTING -p udp --sport 0 -j DROP
iptables -t mangle -A PREROUTING -m set -i eth7 --set blocklist src -j DROP
These rules are dropping
INVALIDpacketsNEW(orRELATED) tcp packets withoutSYNflag. AFAIK, there should be noSYN+URGand noSYN+PSH.tcp packets containing a
SYNand noRSTwith a MSS lower than 536.tcp and udp packets with source port 0
packets from the blocklist ipset but only on the external interface.
# iptables -nvL PREROUTING -t mangle
Chain PREROUTING (policy ACCEPT 3655M packets, 9547G bytes)
pkts bytes target prot opt in out source destination
986K 48M DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
48868 6843K DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x3F/0x02 ctstate NEW
7108K 284M DROP tcp -- eth7 * 0.0.0.0/0 0.0.0.0/0 ctstate NEW,RELATED tcpmss match !536:65535
4 192 DROP udp -- eth7 * 0.0.0.0/0 0.0.0.0/0 udp spt:0
6 336 DROP tcp -- eth7 * 0.0.0.0/0 0.0.0.0/0 tcp spt:0
2584 1285K DROP all -- eth7 * 0.0.0.0/0 0.0.0.0/0 match-set blocklist src
To prevent mapping of internal network topology, I drop packets with a Time-to-Live (TTL) lower than 5.
Note that dropping INVALID packets, new TCP connexion without SYN and TCP SYN packet without the MSS option isn’t necessary if its done in the PREROUTING rules.
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state NEW,RELATED -p tcp ! --tcp-flags ALL SYN -j DROP
iptables -A FORWARD -m state --state NEW,RELATED -p tcp ! --tcp-option 2 -j DROP
iptables -A FORWARD -i eth7 -m ttl --ttl-lt 5 -m limit --limit 4/s -j LOG --log-prefix "TTL too short "
iptables -A FORWARD -i eth7 -m ttl --ttl-lt 5 -j DROP
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -nvL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
...
15871 991K LOG all -- eth7 * 0.0.0.0/0 0.0.0.0/0 TTL match TTL < 5 limit: avg 4/sec burst 5 LOG flags 0 level 4 prefix `TTL too short '
17856 1101K DROP all -- eth7 * 0.0.0.0/0 0.0.0.0/0 TTL match TTL < 5
3529M 9533G ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Similar rules can be created for INPUT.
iptables -P INPUT DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp ! --tcp-flags ALL SYN -m state --state NEW -m limit --limit 4/s -j LOG --log-prefix "TCP INPUT without SYN "
iptables -A INPUT -p tcp ! --tcp-flags ALL SYN -m state --state NEW -j DROP
...
iptables -A INPUT -m limit --limit 4/s -j LOG --log-prefix "INPUT bad "
iptables -A INPUT -j DROP
It’s good practice to filter outgoing packets from your servers too.