TCP packets with SYN=1 AND eg. FIN=1 or RST=1 will NOT be matched by your rule:
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j ACCEPT
Experimental test:
I wrote this example iptables rule set, where packets are only logged and not accepted or dropped.
doug@s19:~/iptables/misc$ cat tcp-new-and-flags
#!/bin/sh
FWVER=0.02
#
# tcp-new-and-flags Smythies 2023.10.05 Ver:0.02
# Change the script name, so it'll be easier to find in future.
#
# ask1488093 Smythies 2023.10.05 Ver:0.01
# See here:
# https://askubuntu.com/questions/1488093/iptables-tcp-new-state-vs-tcp-flags-in-ubuntu-22-04
# run as sudo
#
echo "Loading tcp-new-and-flags rule set version $FWVER..\n"
# The location of the iptables program
#
IPTABLES=/sbin/iptables
#Setting the EXTERNAL and INTERNAL interfaces and addresses for the network
#
# Smythies (for testing)
EXTIF="br0"
EXTIP="192.168.111.136"
NETWORK="192.168.111.0/24"
UNIVERSE="0.0.0.0/0"
#Clearing any previous configuration
#
echo " Clearing any existing rules and setting default policies.."
$IPTABLES -P INPUT ACCEPT
$IPTABLES -F INPUT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -F OUTPUT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -F FORWARD
# Delete user defined chains
$IPTABLES -X
# Reset all IPTABLES counters
$IPTABLES -Z
# loopback interfaces are valid.
#
$IPTABLES -A INPUT -i lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT
# Allow any related traffic coming back to the server in.
#
$IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -m state --state ESTABLISHED,RELATED -j ACCEPT
# A NEW TCP connection requires SYN bit set and FIN,RST,ACK reset.
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "NEW TCP no SYN:" --log-level info
# Just DROP invalid packets.
#
$IPTABLES -A INPUT -i $EXTIF -p tcp -m state --state INVALID -j LOG --log-prefix "INVALID:" --log-level info
# The main rules.
#
$IPTABLES -A INPUT -i $EXTIF -p tcp -m conntrack --ctstate NEW -j LOG --log-prefix "NEW C TCP:" --log-level info
$IPTABLES -A INPUT -i $EXTIF -p tcp -m state --state NEW -j LOG --log-prefix "NEW S TCP:" --log-level info
echo tcp-new-and-flags set version $FWVER done.
Then I used hping3
to send TCP packets with the desired test flags from another computer:
Test 1: SYN=1 and FIN=1:
doug@s15:~$ sudo /usr/sbin/hping3 -p 25565 --count 1 --syn --fin s19
HPING s19 (br0 192.168.111.136): SF set, 40 headers + 0 data bytes
len=46 ip=192.168.111.136 ttl=64 DF id=0 sport=25565 flags=RA seq=0 win=0 rtt=3.8 ms
--- s19 hping statistic ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 3.8/3.8/3.8 ms
And via tcpdump I got:
2023-10-05 12:09:43.079575 IP 192.168.111.1.1642 > 192.168.111.136.25565: Flags [FS], seq 1968173429, win 512, length 0
2023-10-05 12:09:43.079689 IP 192.168.111.136.25565 > 192.168.111.1.1642: Flags [R.], seq 0, ack 1968173431, win 0, length 0
And the iptables:
doug@s19:~/iptables/misc$ sudo iptables -xvnL
Chain INPUT (policy ACCEPT 21 packets, 1300 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
13 692 ACCEPT all -- br0 * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 LOG tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 state NEW LOG flags 0 level 6 prefix "NEW TCP no SYN:"
1 40 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 state INVALID LOG flags 0 level 6 prefix "INVALID:"
0 0 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 ctstate NEW LOG flags 0 level 6 prefix "NEW C TCP:"
0 0 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 state NEW LOG flags 0 level 6 prefix "NEW S TCP:"
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 12 packets, 1268 bytes)
pkts bytes target prot opt in out source destination
Observe, via the packet counters, the packet state was classified as INVALID.
Test 2: SYN=1 and RST=1:
doug@s15:~$ sudo /usr/sbin/hping3 -p 25565 --count 1 --syn --rst s19
HPING s19 (br0 192.168.111.136): RS set, 40 headers + 0 data bytes
--- s19 hping statistic ---
1 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
And via tcpdump I got:
2023-10-05 12:14:17.915848 IP 192.168.111.1.2976 > 192.168.111.136.25565: Flags [SR], seq 1102554713, win 512, length 0
And the iptables:
doug@s19:~/iptables/misc$ sudo iptables -xvnL
Chain INPUT (policy ACCEPT 72 packets, 4635 bytes)
pkts bytes target prot opt in out source destination
2 100 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
38 1994 ACCEPT all -- br0 * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 LOG tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 state NEW LOG flags 0 level 6 prefix "NEW TCP no SYN:"
2 80 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 state INVALID LOG flags 0 level 6 prefix "INVALID:"
0 0 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 ctstate NEW LOG flags 0 level 6 prefix "NEW C TCP:"
0 0 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 state NEW LOG flags 0 level 6 prefix "NEW S TCP:"
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 38 packets, 4800 bytes)
pkts bytes target prot opt in out source destination
Observe there has been another INVALID packet.
Test 2: SYN=0 and ACK=1:
doug@s15:~$ sudo /usr/sbin/hping3 -p 25565 --count 1 --ack s19
HPING s19 (br0 192.168.111.136): A set, 40 headers + 0 data bytes
len=46 ip=192.168.111.136 ttl=64 DF id=0 sport=25565 flags=R seq=0 win=0 rtt=7.8 ms
--- s19 hping statistic ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 7.8/7.8/7.8 ms
And via tcpdump I got:
2023-10-05 12:18:31.196161 IP 192.168.111.1.2342 > 192.168.111.136.25565: Flags [.], ack 1541434780, win 512, length 0
2023-10-05 12:18:31.196319 IP 192.168.111.136.25565 > 192.168.111.1.2342: Flags [R], seq 1541434780, win 0, length 0
And the iptables:
doug@s19:~/iptables/misc$ sudo iptables -xvnL
Chain INPUT (policy ACCEPT 109 packets, 7304 bytes)
pkts bytes target prot opt in out source destination
2 100 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
56 2837 ACCEPT all -- br0 * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
1 40 LOG tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 state NEW LOG flags 0 level 6 prefix "NEW TCP no SYN:"
2 80 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 state INVALID LOG flags 0 level 6 prefix "INVALID:"
1 40 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 ctstate NEW LOG flags 0 level 6 prefix "NEW C TCP:"
1 40 LOG tcp -- br0 * 0.0.0.0/0 0.0.0.0/0 state NEW LOG flags 0 level 6 prefix "NEW S TCP:"
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 60 packets, 8604 bytes)
pkts bytes target prot opt in out source destination
Observe the packet was classified as NEW, but was also caught by the NEW TCP no SYN
rule, where it would normally be dropped.
The /var/log/syslog
entries:
Oct 5 12:09:28 s19 kernel: [261594.730257] INVALID:IN=br0 OUT= MAC=deleted SRC=192.168.111.1 DST=192.168.111.136 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=45686 PROTO=TCP SPT=2608 DPT=25565 WINDOW=512 RES=0x00 SYN FIN URGP=0
Oct 5 12:09:43 s19 kernel: [261608.954625] INVALID:IN=br0 OUT= MAC=deleted SRC=192.168.111.1 DST=192.168.111.136 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=61927 PROTO=TCP SPT=1642 DPT=25565 WINDOW=512 RES=0x00 SYN FIN URGP=0
Oct 5 12:14:17 s19 kernel: [261883.796409] INVALID:IN=br0 OUT= MAC=deleted SRC=192.168.111.1 DST=192.168.111.136 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=56125 PROTO=TCP SPT=2976 DPT=25565 WINDOW=512 RES=0x00 RST SYN URGP=0
Oct 5 12:18:31 s19 kernel: [262137.081851] NEW TCP no SYN:IN=br0 OUT= MAC=deleted SRC=192.168.111.1 DST=192.168.111.136 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10150 PROTO=TCP SPT=2342 DPT=25565 WINDOW=512 RES=0x00 ACK URGP=0
Oct 5 12:18:31 s19 kernel: [262137.081889] NEW C TCP:IN=br0 OUT= MAC=deleted SRC=192.168.111.1 DST=192.168.111.136 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10150 PROTO=TCP SPT=2342 DPT=25565 WINDOW=512 RES=0x00 ACK URGP=0
Oct 5 12:18:31 s19 kernel: [262137.081915] NEW S TCP:IN=br0 OUT= MAC=deleted SRC=192.168.111.1 DST=192.168.111.136 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=10150 PROTO=TCP SPT=2342 DPT=25565 WINDOW=512 RES=0x00 ACK URGP=0
See also.