NAT Table UDP Timeout for NTP Packets

Hi,
I'm running a NTP server behind my OpenWRT Router and was wondering if there is a possibility to reduce the UDP timeout for NTP Packets only?

Currently I have the following configured in /etc/sysctl.conf

net.netfilter.nf_conntrack_udp_timeout=10
net.netfilter.nf_conntrack_udp_timeout_stream=20

I believe the default values are

net.netfilter.nf_conntrack_udp_timeout=60
net.netfilter.nf_conntrack_udp_timeout_stream=120

The issue with the default values are that i'm handling to much NTP requests and the NAT Table is getting a little bit to full for my liking (~90% of 64k).

So I set it down for the moment but I would like to only handle NTP Packets with the lower timeout. I've read that some people increase the max. amount of connections but I don't really want to go there.

Did anyone had a similar issue before? Would really appreciate some help on this one.
Thx

If you visit pool.ntp.org guidelines you need to treat NTP notrack.

1 Like

Where and how would I need to configure this?

/etc/nftables.d/whatever.nft

chain ntp_prerouting {
        type filter hook prerouting priority raw - 1; policy accept;
        udp sport . udp dport { 0-65535 . 123, 123 . 0-65535 } jump ntp_mark_i
}

chain ntp_mark_i {
        meta mark set meta mark or 0x1000
        counter notrack
}

chain input {
## this should be equivalent to existing input chain 
        type filter hook input priority filter; policy drop;
        meta mark and 0x1000 ne 0x0 counter accept
}

chain output {
## idem
        type filter hook output priority filter; policy accept;
        udp sport . udp dport { 0-65535 . 123, 123 . 0-65535 } jump ntp_mark_o
}

chain ntp_mark_o {
        meta mark set meta mark or 0x2000
        counter accept
}

chain ntp_output {
        type filter hook output priority raw; policy accept;
        meta mark and 0x2000 ne 0x0 counter notrack
}

EDIT: oopsie

__set%d tst 87 size 2
__set%d tst 0
        element 00000000 00007b00  - 0000ffff 00007b00  : 0 [end]       element 00007b00 00000000  - 00007b00 0000ffff  : 0 [end]
inet tst output
  [ meta load l4proto => reg 1 ]
  [ cmp eq reg 1 0x00000006 ]
  [ payload load 2b @ transport header + 0 => reg 1 ]
  [ payload load 2b @ transport header + 2 => reg 9 ]
  [ lookup reg 1 set __set%d ]
  [ immediate reg 0 jump -> ntp_mark_o ]

inet tst ntp_mark_o
  [ meta load mark => reg 1 ]
  [ bitwise reg 1 = ( reg 1 & 0xffffdfff ) ^ 0x00002000 ]
  [ meta set mark with reg 1 ]

inet tst ntp_mark_o
  [ counter pkts 0 bytes 0 ]
  [ immediate reg 0 accept ]

inet tst ntp_output
  [ meta load mark => reg 1 ]
  [ bitwise reg 1 = ( reg 1 & 0x00002000 ) ^ 0x00000000 ] <---- we avoid second multiport inspection
  [ cmp neq reg 1 0x00000000 ]
  [ counter pkts 0 bytes 0 ]
  [ notrack ]

I really appreciate the help, but this is like reading Chinese to me.
What exactly does what in the custom nftables entry?
Do I need my port forward after I configured this?

This rules is for NTP server. Like with gps and atomic pulses.

You mean configure on the NTP Server?

Yes, I understood NTP server is OpenWRT?

I'm afraid not. The NTP Server runs on a raspi and is connected to the OpenWRT Router.

[NTP Server]-->[OpenWRT]<--[Internet]

I have configured a port forward on the OpenWRT

You need to inject custom timeout in masquerade section via same include place
https://wiki.nftables.org/wiki-nftables/index.php/Ct_timeout
i.e meta nfproto ipv4 l4proto udp udp dport 123 ct set udp timeout 1s

and run 'fw4 check' when changing that table.

How do I do that?
I'm sorry, I have absolutely no clue of this stuff.

You run
nft list ruleset | less
identify points where you want to attach short timeout
Then add side-rule that sets shorter tc timeout.

I'cant figure it out. :frowning_face:

I think the two chains are needed?

chain dstnat_wan {
		meta nfproto ipv4 udp dport 123 counter packets 32946 bytes 2503940 dnat ip to 192.168.123.2:123 comment "!fw4: NTP Incoming"
}

chain accept_from_ntp {
		iifname "br-lan.4" counter packets 0 bytes 0 accept comment "!fw4: accept ntp IPv4/IPv6 traffic"
	}

Here is the whole output

table inet fw4 {
	chain input {
		type filter hook input priority filter; policy drop;
		iifname "lo" accept comment "!fw4: Accept traffic from loopback"
		ct state established,related accept comment "!fw4: Allow inbound established and related flows"
		ct state invalid drop comment "!fw4: Drop flows with invalid conntrack state"
		tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
		iifname "br-lan.5" jump input_to_gwa comment "!fw4: Handle to_gwa IPv4/IPv6 input traffic"
		iifname "br-lan.4" jump input_ntp comment "!fw4: Handle ntp IPv4/IPv6 input traffic"
		iifname "wan" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
		ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
		ct state invalid drop comment "!fw4: Drop flows with invalid conntrack state"
		iifname "br-lan.5" jump forward_to_gwa comment "!fw4: Handle to_gwa IPv4/IPv6 forward traffic"
		iifname "br-lan.4" jump forward_ntp comment "!fw4: Handle ntp IPv4/IPv6 forward traffic"
		iifname "wan" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
	}

	chain output {
		type filter hook output priority filter; policy drop;
		oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
		ct state established,related accept comment "!fw4: Allow outbound established and related flows"
		ct state invalid drop comment "!fw4: Drop flows with invalid conntrack state"
		oifname "br-lan.5" jump output_to_gwa comment "!fw4: Handle to_gwa IPv4/IPv6 output traffic"
		oifname "br-lan.4" jump output_ntp comment "!fw4: Handle ntp IPv4/IPv6 output traffic"
		oifname "wan" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
	}

	chain prerouting {
		type filter hook prerouting priority filter; policy accept;
		iifname "br-lan.5" jump helper_to_gwa comment "!fw4: Handle to_gwa IPv4/IPv6 helper assignment"
		iifname "br-lan.4" jump helper_ntp comment "!fw4: Handle ntp IPv4/IPv6 helper assignment"
	}

	chain handle_reject {
		meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic"
		reject comment "!fw4: Reject any other traffic"
	}

	chain syn_flood {
		limit rate 25/second burst 50 packets return comment "!fw4: Accept SYN packets below rate-limit"
		drop comment "!fw4: Drop excess packets"
	}

	chain input_to_gwa {
		jump accept_from_to_gwa
	}

	chain output_to_gwa {
		jump accept_to_to_gwa
	}

	chain forward_to_gwa {
		jump accept_to_ntp comment "!fw4: Accept to_gwa to ntp forwarding"
		jump accept_to_to_gwa
		log prefix "drop to_gwa forward: "
	}

	chain helper_to_gwa {
	}

	chain accept_from_to_gwa {
		iifname "br-lan.5" counter packets 27 bytes 1728 accept comment "!fw4: accept to_gwa IPv4/IPv6 traffic"
	}

	chain accept_to_to_gwa {
		oifname "br-lan.5" counter packets 159 bytes 10253 accept comment "!fw4: accept to_gwa IPv4/IPv6 traffic"
	}

	chain input_ntp {
		jump accept_from_ntp
	}

	chain output_ntp {
		jump accept_to_ntp
	}

	chain forward_ntp {
		jump accept_to_wan comment "!fw4: Accept ntp to wan forwarding"
		jump accept_to_to_gwa comment "!fw4: Accept ntp to to_gwa forwarding"
		jump accept_to_ntp
		log prefix "drop ntp forward: "
	}

	chain helper_ntp {
	}

	chain accept_from_ntp {
		iifname "br-lan.4" counter packets 0 bytes 0 accept comment "!fw4: accept ntp IPv4/IPv6 traffic"
	}

	chain accept_to_ntp {
		oifname "br-lan.4" counter packets 5 bytes 380 accept comment "!fw4: accept ntp IPv4/IPv6 traffic"
	}

	chain input_wan {
		ct status dnat accept comment "!fw4: Accept port redirections"
		jump drop_from_wan
	}

	chain output_wan {
		jump accept_to_wan
	}

	chain forward_wan {
		ct status dnat accept comment "!fw4: Accept port forwards"
		jump drop_to_wan
	}

	chain accept_to_wan {
		meta nfproto ipv4 oifname "wan" ct state invalid counter packets 0 bytes 0 drop comment "!fw4: Prevent NAT leakage"
		oifname "wan" counter packets 217 bytes 16108 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
	}

	chain drop_from_wan {
		iifname "wan" counter packets 10220 bytes 718348 drop comment "!fw4: drop wan IPv4/IPv6 traffic"
	}

	chain drop_to_wan {
		oifname "wan" counter packets 0 bytes 0 drop comment "!fw4: drop wan IPv4/IPv6 traffic"
	}

	chain dstnat {
		type nat hook prerouting priority dstnat; policy accept;
		iifname "wan" jump dstnat_wan comment "!fw4: Handle wan IPv4/IPv6 dstnat traffic"
	}

	chain srcnat {
		type nat hook postrouting priority srcnat; policy accept;
		oifname "wan" jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
	}

	chain dstnat_wan {
		meta nfproto ipv4 udp dport 123 counter packets 1386812 bytes 105413749 dnat ip to 192.168.123.2:123 comment "!fw4: NTP Incoming"
	}

	chain srcnat_wan {
		meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 wan traffic"
	}

	chain raw_prerouting {
		type filter hook prerouting priority raw; policy accept;
	}

	chain raw_output {
		type filter hook output priority raw; policy accept;
	}

	chain mangle_prerouting {
		type filter hook prerouting priority mangle; policy accept;
	}

	chain mangle_postrouting {
		type filter hook postrouting priority mangle; policy accept;
	}

	chain mangle_input {
		type filter hook input priority mangle; policy accept;
	}

	chain mangle_output {
		type route hook output priority mangle; policy accept;
	}

	chain mangle_forward {
		type filter hook forward priority mangle; policy accept;
		iifname "wan" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
		oifname "wan" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
	}
}

chain srcnat_wan {
    meta proto ipv4 udp port 123 jump ntp_shortcut
}

chain ntp_shortcut {
   ct set timeout udp 1s
   masquerade random
}

You need to read documentation for it, nat adds too much jitter and asymmetric delay to consider nated ntp a time source.
(im sure it syntax is wrong, but it is to hook in that place before total NAT rule)