How to block outbound IPv4 TCP Fast Open

So I've hit:
https://bugzilla.redhat.com/show_bug.cgi?id=2252550
and would like to do something equivalent to:
iptables -t filter -A OUTPUT -p tcp --syn --tcp-option 34 -j DROP
(for both OUTPUT and FORWARD on the 464-xlat device)

The 'nft' equivalent is:

# iptables-translate -4 -t filter -A OUTPUT -p tcp --syn --tcp-option 34 -j DROP

nft 'add rule ip filter OUTPUT tcp option 34 exists tcp flags syn / fin,syn,rst,ack counter drop'

I've tried to set this up via the LUCI web UI, and got as far as
/etc/config/firewall:

config rule
        option name 'Disallow-TCP-FastOpen'
        option direction 'out'
        option device '464-xlat'
        option family 'ipv4'
        list proto 'tcp'
        option dest 'wan'
        option target 'DROP'
        option src '*'
        option enabled '0'

But now I'm stumped.

Do I need custom rules?
If so how/where?

I've come up with:

root@mf286a:~# cat /usr/share/nftables.d/table-post/disable-ipv4-fastopen.nft
        chain postrouting {
                type filter hook postrouting priority filter; policy accept;
                meta nfproto ipv4 oifname "464-xlat" tcp flags syn / fin,syn,rst,ack tcp option 34 exists counter drop comment "Drop Outbound IPv4 TCP FastOpen"
        }
root@mf286a:~# fw4 check
Automatically including '/usr/share/nftables.d/table-post/disable-ipv4-fastopen.nft'
Ruleset passes nftables check.

(the more logical chain-pre/postrouting directory doesn't appear to work)

That's not possible - systemd isn't used in OpenWrt by default so there can't be an issue with systemd-resolved's TCP fast open implementation. Can you better describe the issue you're having?

?

The Fast Open cookie found in in the TCP packet is generated by the server, not the client - yet you seem to be configuring an outbound firewall rule. TBH - it's not clear what you desire to accomplish.

systemd-resolved is on a machine behind the OpenWrt router, which is also the machine sending the SYN packets with TFO cookie. Note that sending SYN with TFO cookie does not imply it is generating the cookie. The cookie may indeed be generated by the server during a previous tcp connection, but is used to optimize this next tcp connection establishment.

I was worried you might say this. So to be clear, you're attempting to block a connection you already allow?

What you're describing may be an established connection, hence why your rules doesn't work. So it's still not clear what you wish to accomplish by stopping an ongoing connection.

Who's optimizing specifically, and why is this not desired?

If you mean the DST IP, there's nothing to fix, as the traffic already made the full trip.

EDIT:

Have you tried disabling TCP Fast Open on your client?

I have to block outbound TCP SYN with payload, because a NAT (464XLAT PLAT) I do not control run by my ISP is broken by it... And it's broken in such a way that it doesn't get detected as a fastopen blackhole, so fallback to non-fastopen mode doesn't trigger.

Dropping the outbound TCP SYN with payload would force a tcp fastopen blackhole and thus result in correct fallback.

I can't just outright disable tcp fastopen, because systemd-resolved is buggy and outright fails if tcp_fastopen sysctl is disabled (it no longer does any network traffic due to code bug in fallback path).

Anyway, turns out that the nft 'tcp option fastopen exists' logic is also broken... likely due to the mf286a device being big-endian instead of little endian. See https://lore.kernel.org/all/20231203131344.GB5972@breakpoint.cc/T/

I've come up with something that works for me

root@mf286a:~# cat /usr/share/nftables.d/chain-pre/mangle_postrouting/nop-out-tcp-fastopen.nft
meta nfproto ipv4 oifname "464-xlat" tcp flags syn / fin,syn,rst,ack tcp option @254,0,32 == 0xFE0CF989 counter drop comment "drop outbound IPv4 TCP Exp FastOpen";
meta nfproto ipv6 oifname "wwan0"    tcp flags syn / fin,syn,rst,ack tcp option @254,0,32 == 0xFE0CF989 counter drop comment "drop outbound IPv6 TCP Exp FastOpen";
meta nfproto ipv4 oifname "464-xlat" tcp flags syn / fin,syn,rst,ack tcp option fastopen length ge 2 reset tcp option fastopen counter comment "NOP out outbound IPv4 TCP FastOpen";
meta nfproto ipv6 oifname "wwan0"    tcp flags syn / fin,syn,rst,ack tcp option fastopen length ge 2 reset tcp option fastopen counter comment "NOP out outbound IPv6 TCP FastOpen"

(since along the way I discovered that native ipv6 is affected too, and that there are two different tcp fastopen options - the official one, and an old experimental one, and if the official one doesn't work, it seems to fallback to the experimental one)

though perhaps 'tcp option @254,16,16 == 0xF989' would be better still

EDIT: best yet solution:

meta nfproto ipv4 oifname "464-xlat" tcp flags syn / fin,syn,rst,ack tcp option @254,16,16 == 0xF989 reset tcp option 254 counter comment "drop outbound IPv4 TCP Exp FastOpen";
meta nfproto ipv6 oifname "wwan0"    tcp flags syn / fin,syn,rst,ack tcp option @254,16,16 == 0xF989 reset tcp option 254 counter comment "drop outbound IPv6 TCP Exp FastOpen";
meta nfproto ipv4 oifname "464-xlat" tcp flags syn / fin,syn,rst,ack tcp option fastopen length ge 2 reset tcp option fastopen counter comment "NOP out outbound IPv4 TCP FastOpen";
meta nfproto ipv6 oifname "wwan0"    tcp flags syn / fin,syn,rst,ack tcp option fastopen length ge 2 reset tcp option fastopen counter comment "NOP out outbound IPv6 TCP FastOpen"
1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.