-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
Proposal for changes to NAT. #279629
Proposal for changes to NAT. #279629
Conversation
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/3697 |
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/3751 |
Does #277016 fix one of these surprising behaviours when using iptables? |
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.
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.
Were all three points addressed? |
Oh, sorry for missing your comment! Yes, 2. and 3. were resolved. No 1. turns out to be "only" a problem if the attacker has L2 access to any of the NAT-enabled machine interfaces, which I'd argue is still a problem. Thankfully, #277016 appears to deny unrestricted forwarding, but only when using iptables instead of nftables. I've tested it, and couldn't find any hole. @JustTNE According to your knowledge, is the current iptables implementation tight against L2-enabled attacks? |
Could you please take a look at the NixOS test introduced in #277016, specifically this part: Lines 250 to 251 in 956c52b
Does this explain why No 1. was only addressed for iptables? Is there a way to fix this? Feel free to also audit the rest of the test script and see if anything is missing. |
As far as I can see, #277016 did not address No. 1. It did add a new chain To address No. 1, we could:
|
I do admit it's been quite a while since I've thought about this since the PR is unfortunately so old.
AND
The text explaining this is present in the
To my knowledge, I was simply not familiar with a way to run an equivalent command to
This is correct. Due to the already rampant scope creep, that was definitely out of scope for my PR. This is the configuration necessary that is mentioned in:
This is an excellent idea and should be implemented. This would be a good first time pull request for someone here who is interested. It should be about a 3 line change in
I agree this is a good idea, but it should probably be a separate pull request because it is bound to affect at least one existing setup that may rely on this being off by default. |
Background
Recently I've been testing NixOS' NAT feature extensively, and found three surprising quirks to its behavior, one of which I find concerning.
I submit a draft of changes to the NAT integration test to cover those quirks, and check against behavior I find unreasonable. If maintainers agree with this proposal, I will proceed to implement changes to the actual NAT module to make this new test pass.
1. NAT affects all interfaces.
As currently implemented, turning on NAT enables indiscriminate traffic forwarding between all interfaces on the nat-enabled machine in all directions. In particular this allows to:
The new test checks against those in many places, see line 177.
2. DNAT overrides source IP address.
The rules to capture packets intended for
loopbackIPs
are so wide they capture "normal" traffic from theexternalInterface
indented for DNAT. In the end, the packets get routed to the correct destination, but because the source IP is being set toexternalIP
, the listening service cannot identify what is coming from where, which is oftentimes useful for i.e. blacklisting.See new check
client.succeed("check-last-clients-ip ${serverIp}")
.A side question: why does the
loopbackIP
option even exist -- as in why aren't all forwards loopbacked by default? Is there any reasonable use case for routing traffic from the outside differently than from the inside... but only the forwarded ports?3. DNAT captures traffic on all IPs even if
externalIP
was specified.networking.nat.externalIP option allows to specify the exact external address to be used for NAT. This is particularly useful, if there are multiple IP addresses associated with one
networking.nat.externalInterface
.However, as currently implmented, even if
externalIP
was set, packets destined for other IP addresses on theexternalInterface
would still be captured, making it impossible to host services bound to IP addresses not meant for NAT.See new check
server.succeed('[[ 'curl http://${routerAlternativeExternalIp}:8080' == "router" ]]')
.There was a pull request about this #254025, it was closed for... unrelated reasons.
The question was if this isn't too obscure to warrant changes to the configuration semantics. I think if we agree on the points above, this question becomes irrelevant.
I'm looking forward to a feedback.
@samhug @mkg20001 @duament @wegank