Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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