-
Notifications
You must be signed in to change notification settings - Fork 8
fix: preserve established connections on service restart #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.2.1
Are you sure you want to change the base?
fix: preserve established connections on service restart #53
Conversation
Add connection tracking rules to preserve established/related connections that already have a routing mark when the PBR service restarts. This prevents existing SSH sessions from being broken when routing rules are flushed and recreated, while ensuring new connections are properly routed. The fix adds rules that check for established/related connection state AND an existing routing mark before returning early, allowing those packets to continue using their existing routing table without interfering with new traffic that needs to be processed.
f81ac9b to
63db077
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR attempts to prevent established SSH sessions and other connections from being broken when the PBR (Policy-Based Routing) service restarts by adding connection tracking rules that preserve established/related connections.
Key Changes:
- Adds two nftables rules at the beginning of the prerouting and output chains to check for established/related connection state and return early if a routing mark is present
- These rules are inserted before the PBR guard rules that prevent re-marking of already marked packets
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Preserve established/related connections that already have a routing mark to prevent breaking existing sessions (e.g., SSH) | ||
| echo "add rule inet $nftTable ${nftPrefix}_prerouting ct state established,related meta mark & $fw_mask != 0 return" >> "$nftTempFile" | ||
| echo "add rule inet $nftTable ${nftPrefix}_output ct state established,related meta mark & $fw_mask != 0 return" >> "$nftTempFile" |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic of these rules may not work as intended. They check for meta mark & $fw_mask != 0, which verifies the packet mark, but packet marks are set by nftables rules on each packet and are not persistent across connections.
When the service restarts:
- Existing connections remain in conntrack with
established/relatedstate - However, packet marks are not saved to conntrack (no
ct mark setis used in this codebase) - The first packet from an established connection after restart won't have a mark yet (it's set by subsequent rules in the chain)
- Therefore, these rules won't match and won't preserve the connection's routing
To fix this, consider one of these approaches:
- Save marks to conntrack using
ct mark setwhen initially marking packets, then checkct mark & $fw_mask != 0here - Or simply check for
ct state established,relatedwithout requiring a mark, allowing established connections to continue with their existing routing - Or use
meta mark set ct markto restore marks from conntrack at the start of processing
| # Preserve established/related connections that already have a routing mark to prevent breaking existing sessions (e.g., SSH) | |
| echo "add rule inet $nftTable ${nftPrefix}_prerouting ct state established,related meta mark & $fw_mask != 0 return" >> "$nftTempFile" | |
| echo "add rule inet $nftTable ${nftPrefix}_output ct state established,related meta mark & $fw_mask != 0 return" >> "$nftTempFile" | |
| # Preserve established/related connections to prevent breaking existing sessions (e.g., SSH) | |
| echo "add rule inet $nftTable ${nftPrefix}_prerouting ct state established,related return" >> "$nftTempFile" | |
| echo "add rule inet $nftTable ${nftPrefix}_output ct state established,related return" >> "$nftTempFile" |
|
Thanks for your contribution @brauliobo. As the |
|
For my understanding is the problem you are encountering that existing SSH connections are broken and you have to login again after PBR (re)starts? The main chains already have a rule on top preserving related and established traffic, adding such a rule to the prerouting chain might have unwanted side effects but I am not an expert on nftables as I grew up with iptables and not with nftables |
|
Hi @stangri, yes I'm using SQM and nft sets with domain-based rules. I'm new to OpenWRT development and not able to test in detail. I have 3 WAN and 4 WG interfaces, so I'm testing rules to ping with each of them. I'm also using MWAN3, but I've set PBR a higher priority than it (lower @egc112 The SSH drop of connections is reproducible on every click of "Save & Apply", which triggers a PBR restart. It also happens with other services like a PostgreSQL connection via |
|
@egc112 I'd like to lean on your expertise here, I believe it's harmful to merge to dev branch and let people test it in the wild. What do you think? |
All the main chains (FORWARD, INPUT and OUTPUT) already have a rule on top which preserves RELATED and ESTABLISHED traffic. The PREROUTING chain does not have that , in the prerouting chain you want to reroute traffic and I can imaging also already existing traffic so adding such a rule to preserve already established traffic might have unwanted side effects. So I am hesitant to add it. Note: the OP is using MWAN3 which is also doing PBR and those two package might well be interfering which each other. |
|
@egc112 Thanks for your input Erik. @brauliobo I'm hesitant to add it to the package by default, but if it makes your life easier, I can move the nft-file header to a file on the OpenWrt filesystem instead of hard-coding it into the init script, so you could patch it yourself after install (rather than fixing the init script). Would that be useful for you, or do you have no problem patching the init-file? |
Add connection tracking rules to preserve established/related connections when the PBR service restarts. This prevents existing SSH sessions from being broken when routing rules are flushed and recreated.
The fix adds rules at the top of prerouting and output chains that check for established/related connection state and return early, allowing those packets to continue using their existing routing table.