-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
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
nixos/nat: Match iptables behavior with nftables, add externalIP check #277016
Conversation
The user that originally implemented nat reflection seems to have deleted their GitHub account or it's inaccessible for another reason. That's unfortunate. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/prs-ready-for-review/3032/3789 |
What about the nftables implementation at |
@Luflosi We do not use nftables in production (I believe we tried to in the past), so I can't speak for how well the nftables code works (and I do not have any experience with nftables either) About writing tests, it doesn't seem like there are nat reflection tests as is and I am not sure how to write some as of right now either. One would have to emulate a network environment where an "outside" and "inside" network exists I suppose? |
Is there still any interest in getting this pull request merged? |
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.
Code looks good to me. The nftables implementation looks like its has the same issue. We have to fix the nftables implementation for feature parity since both use the same options. Having a test for this would be awesome.
I think #279629 is relevant. |
Oh yes! I would be willing to port that test to this pull request and try my luck at implementing it for nftables as well. Excellent! |
That would be awesome! |
So... Trying to write these tests has me a little stuck with some unexpected behavior. I wrote up a minimal test case where two machines in separate networks seem to be able to talk to each other completely without any iptables statements allowing them to do so. This assumes a disabled firewall, but to me, it seems rather odd that the Linux kernel just goes "yeah that checks out" Test file here: |
I was able to replicate this with the firewall enabled on the router as well: This means a device from outside the network is indeed able to access any other network connected to the router it seems, unless I'm missing something?? I would appreciate some pointers for sure. For now, for the purposes of this pull request, I'm going to solve the one issue this pull request is supposed to solve and put solving the other issues on the to-do list... Edit: |
4cc52c6
to
4955a9a
Compare
This PR has been majorly updated with all the changes necessary to make this work. Iptables's behavior now matches the behavior of nftables in the new tests, iptables can now be configured for forward default drop and externalIP actually matters for port forwarding now. This should also address all the concerns @gray-heron had in #279629 in general. @Luflosi @fpletz @stalkerhumanoid @ofborg test nat |
I've rebased this pull request to fix the merge conflicts it had. It would be great if the reviewers could review this pull request again so that we can finally get this merged! (Thanks for the help by the way!) I've decided against implementing @TRPB request number 1 because this neither works on nftables nor iptables as of right now as far as I can tell, so it should be a separate PR I'd say. I've made some progress on implementing that, however I don't plan on finishing it. A diff is attached to this comment: @stalkerhumanoid @fpletz (mentioning previous reviewers) |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/prs-ready-for-review/3032/4648 |
Great job! Thank you very much for picking this up. I would suggest adding a note to Other than that, I have checked the new behavior extensively and I found the issues preventing me from using the NixOS NAT resolved. I hope this gets reviewed and merged soon. |
dc41e81
to
7452818
Compare
Rebased and addressed the review concerns! Thank you for the review and extensive testing. I've been running this in production since day 1 of this pull request existing, but the extra eyes and extra testing gives me some extra peace of mind for sure! @ofborg test nat |
7452818
to
4c3c348
Compare
Rebased to fix the merge conflict in the docs. |
May I ask anyone with write access what could be done to unblock this pull request? This PR has been open since 2023 after all, and the 24.11 breaking changes freeze is coming up very soon according to #339153. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/prs-ready-for-review/3032/4705 |
4c3c348
to
f3a9edf
Compare
…tables rule is in effect. This allows feature parity with the nftables "filterForward" firewall option when adding a ip forwarding default drop iptables rule.
This code is mostly from NixOS#279629, the uninvoled client checks were removed (since they are the same as the direct connection to the client test) and the tests were adjusted to work as intended as well as bugs fixed. In some cases, some tests are skipped when they do not make sense for the specific configuration that is being tested.
f3a9edf
to
12f0948
Compare
Rebased and release notes updated to 25.05! I'd still really like to get this merged some time! It's been almost a full year now! |
@ofborg test nat |
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.
Unless there are any objections I'll merge this tomorrow.
Description of changes
Previously, the behavior of the iptables and nftables NAT implementations had some differences. This PR addresses these differences by matching iptable nat's functionality with that of nftables. Additionally, this PR implements updated tests based on #279629. Finally, a relatively minor change mentioned in #279629 section 3 was implemented as well.
1. Previously, all requests arriving from outside NAT would still have their "source address" adjusted on iptables.
The following diagram describes the setup I've experienced the issue in:
1.2.3.4 - Example client
101.101.101.101 - Server's public address
10.0.0.5 - nixos nspawn container (via containers.*) address behind NAT
If we introduce this example configuration:
Any request previously targeted at 10.0.0.5, even from outside the NAT (outside of where NAT reflection is supposed to act), would have its source address rewritten to 101.101.101.101.
An application, like nginx, behind this NAT would then see the following:
The changes in this PR prevent the outside client's IP address from being overwritten by limiting the source address change to behind the NAT, matching the behavior with nftables. Test
2. NAT now supports default forward drop iptables rules.
Behaviors allowed by the NAT are now explicitly whitelisted in the forward ruleset on iptables, which allows behavior similar to nftables with the firewall filterForward setting enabled. Test
3. Only connections made to the nat.externalIP will be port forwarded
This is the one new addition to both nftables and iptables. This means that an interface that has multiple IP addresses can now correctly use only one of those IP addresses as the IP address used for NAT port forwarding, allowing the rest of the IP addresses on the interface to be used however else desired without interference. Test
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)@ofborg test nat
Add a 👍 reaction to pull requests you find important.