# gre-panel:managed=1 # # The panel's port forwarding ruleset, rendered from the database. Every change # rewrites this file in full and applies it with a single nft transaction, so the # kernel never holds a partial ruleset. # # Everything the panel installs lives in the one table below. Replacing that table # replaces the panel's rules and touches nothing else on this host: rules belonging # to Docker, firewalld or anything else live in their own tables and are never read, # flushed or reordered from here. # # Every rule carries the comment grep:, which is what lets a rule read # back from the kernel be matched to the database row that generated it. # Declaring the table before flushing it makes this file work on a host that has # never seen it; flushing a table that does not exist is an error. table inet gre_panel flush table inet gre_panel table inet gre_panel { # Named counter objects, one pair per rule. Byte accounting reads these, # never the nat chains: a nat hook only ever sees the first packet of a # connection, so counting there would report connections as if they were # bytes and under-report traffic by orders of magnitude. counter route_1_rx { } counter route_1_tx { } chain prerouting { type nat hook prerouting priority dstnat; policy accept; # Destination NAT: traffic arriving for a rule is redirected to its destination. # route 1 "Web relay": tcp 203.0.113.10:2044 -> 198.51.100.20:2044 [nat none] ip daddr 203.0.113.10 tcp dport 2044 dnat ip to 198.51.100.20:2044 comment "grep:1" } chain output { type nat hook output priority -100; policy accept; # The prerouting hook never sees traffic this host generates itself, so a rule # that should also serve local processes is repeated here. # route 1 "Web relay": tcp 203.0.113.10:2044 -> 198.51.100.20:2044 [nat none] ip daddr 203.0.113.10 tcp dport 2044 dnat ip to 198.51.100.20:2044 comment "grep:1" } chain forward { type filter hook forward priority filter; policy accept; # Forward permission. The established/related rule covers the return direction, # so no reverse rule matching on source port is emitted: conntrack expresses the # intent exactly, and matching on the far end's source port would accept traffic # that belongs to no flow this server ever started. ct state established,related accept comment "gre-panel:structural" # route 1 "Web relay": tcp 203.0.113.10:2044 -> 198.51.100.20:2044 [nat none] ip daddr 198.51.100.20 tcp dport 2044 accept comment "grep:1" } chain accounting { type filter hook forward priority filter - 10; policy accept; # Accounting. These rules carry no verdict, so they count and fall through # without influencing policy, and they sit at their own priority so they see # traffic whatever the forward chain decides. # route 1 "Web relay": tcp 203.0.113.10:2044 -> 198.51.100.20:2044 [nat none] ip daddr 198.51.100.20 tcp dport 2044 counter name "route_1_tx" comment "grep:1" ip saddr 198.51.100.20 tcp sport 2044 counter name "route_1_rx" comment "grep:1" } chain local_out_accounting { type filter hook output priority filter - 10; policy accept; # Accounting for traffic this server originates itself, which the forward hook # never sees. It references the same counters as the chain above, so a rule's # total is its whole total rather than the forwarded half of it. # route 1 "Web relay": tcp 203.0.113.10:2044 -> 198.51.100.20:2044 [nat none] ip daddr 198.51.100.20 tcp dport 2044 counter name "route_1_tx" comment "grep:1" } chain local_in_accounting { type filter hook input priority filter - 10; policy accept; # The return direction of the same traffic. Replies to a locally-originated # connection are delivered to a socket on this host, so they arrive at input # rather than being forwarded. # route 1 "Web relay": tcp 203.0.113.10:2044 -> 198.51.100.20:2044 [nat none] ip saddr 198.51.100.20 tcp sport 2044 counter name "route_1_rx" comment "grep:1" } }