Skip to content
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

Add --random-fully to SNAT IP Table Rules #6544

Closed
Scoobed opened this issue Jul 24, 2024 · 5 comments · Fixed by #6602
Closed

Add --random-fully to SNAT IP Table Rules #6544

Scoobed opened this issue Jul 24, 2024 · 5 comments · Fixed by #6602
Assignees
Labels
kind/feature Categorizes issue or PR as related to a new feature. lifecycle/active Indicates that an issue or PR is actively being worked on by a contributor. reported-by/end-user Issues reported by end users.

Comments

@Scoobed
Copy link

Scoobed commented Jul 24, 2024

Describe the problem/challenge you have
Default SNAT behavior is to preserve the source whenever possible. We are seeing a precentage of traffic using SNATs traffic fail due to TCP Port Numbers being reused too quickly. As the referenced in a-reason-for-unexplained-connection-timeouts-on-kubernetes-docker below where there is latency in the insert into the conntrack table which can cause the same Source Port to be given to multiple pods.

Thus we are seeing in the TCP Dump output, there are multiple [TCP Port Numbers reused] on POD.

Describe the solution you'd like
Expose an option to randomize the Source Pods Ports to use --random / --random-fully in iptables

Anything else you would like to add?

See the Netfilter NAT & Conntrack kernel modules section on the following link.
Note the following link is Kubernetes / Docker, but looks like it would hold true with Kubernetes/Containerd level

a-reason-for-unexplained-connection-timeouts-on-kubernetes-docker
time-wait article
Cilium SNAT issue

@Scoobed Scoobed added the kind/feature Categorizes issue or PR as related to a new feature. label Jul 24, 2024
@antoninbas
Copy link
Contributor

I personally support adding this as a configuration parameter for the antrea-agent, as I don't think there is any drawback (we would keep the current behavior as the default) and it could potentially help in some situations.

@Scoobed for your specific issue, there may be better ways to address it on the client side (we discussed this on Slack).
Regarding the links you shared: if memory served me right, the primary concern was race conditions in iptables / netfilter which impacted UDP specifically and therefore impacted DNS queries in K8s clusters. I am not sure TCP connections were affected. See https://quentin.machu.dev/2018/06/24/5-15s-dns-lookups-on-kubernetes/. In your case (based on our Slack conversation), there is no race condition as the implementation behaves correctly, but some network device in the path is not happy about rapid port reuse.

By the way, this may be a "good first issue" if you (or someone else) are interested in taking a stab at it. The only thing to look out for AFAIK is that some older kernel versions may not support --random-fully and that a check may be desired in the antrea-agent when the configuration parameter is set.

@antoninbas
Copy link
Contributor

While this is not mentioned explicitly in the original post, I believe that @Scoobed experienced the issue in the context of Egress SNAT, given that the Slack post mentioned "SNAT IP per namespace".

However, the ability for users to configure --random-fully could apply both to Egress SNAT and to Node SNAT.

Node SNAT (masquerade):

if !c.noSNAT {
writeLine(iptablesData, []string{
"-A", antreaPostRoutingChain,
"-m", "comment", "--comment", `"Antrea: masquerade Pod to external packets"`,
"-s", podCIDR.String(), "-m", "set", "!", "--match-set", podIPSet, "dst",
"!", "-o", c.nodeConfig.GatewayConfig.Name,
"-j", iptables.MasqueradeTarget,
}...)
}

Egress SNAT:

for snatMark, snatIP := range snatMarkToIP {
// Cannot reuse snatRuleSpec to generate the rule as it doesn't have "`" in the comment.
writeLine(iptablesData, []string{
"-A", antreaPostRoutingChain,
"-m", "comment", "--comment", `"Antrea: SNAT Pod to external packets"`,
"!", "-o", c.nodeConfig.GatewayConfig.Name,
"-m", "mark", "--mark", fmt.Sprintf("%#08x/%#08x", snatMark, types.SNATIPMarkMask),
"-j", iptables.SNATTarget, "--to", snatIP.String(),
}...)
}

It is not completely clear to me whether we would want 2 separate configuration parameters or a unified one. I would personally prefer the latter.

@Scoobed
Copy link
Author

Scoobed commented Jul 25, 2024

I would prefer two settings if possible as we might want the one but not the other one. if I was going to do the pull request is there directions on how this tested and thos requirements

@antoninbas
Copy link
Contributor

I would prefer two settings if possible as we might want the one but not the other one

Do you mean that you would want source port selection to be random for Egress SNAT but not for Node SNAT (or the reverse)? Could you provide more information as to why?

@Scoobed
Copy link
Author

Scoobed commented Jul 25, 2024

I mean I would just like to control them independent of each other. Like only enable with Egress and not the node. Sorry if that came off confusing as I don't have a good reason other than flexibility.

@antoninbas antoninbas added the reported-by/end-user Issues reported by end users. label Jul 25, 2024
@antoninbas antoninbas self-assigned this Aug 7, 2024
@antoninbas antoninbas added this to the Antrea v2.2 release milestone Aug 7, 2024
@antoninbas antoninbas added the lifecycle/active Indicates that an issue or PR is actively being worked on by a contributor. label Aug 7, 2024
antoninbas added a commit to antoninbas/antrea that referenced this issue Aug 8, 2024
We expose 2 new configuration parameters for the Agent:
snatFullyRandomPorts and egress.snatFullyRandomPorts. When the first one
is set to true, the MASQUERADE iptables rules used to implement "local"
Node SNAT will use randomized source port mappings. When the second one
is set to true, the SNAT iptables rules used to implement Egress SNAT
will use randomized source port mappings. This is achieved with the
`--random-fully` iptables flag.

These new configuration parameters are only supported on Linux
Nodes. They require iptables >= 1.6.2, which is not a problem with the
standard antrea-agent container images. They also require Linux kernel
>= 3.13 and >= 3.14 respectively, but these are very old releases so we
can ignore this requirment, which is consistent with the K8s
implementation.

The 2 parameters are set to false by default, but we may change the
default value to true in the future.

Fixes antrea-io#6544

Signed-off-by: Antonin Bas <[email protected]>
antoninbas added a commit to antoninbas/antrea that referenced this issue Aug 19, 2024
We expose 2 new configuration parameters for the Agent:
snatFullyRandomPorts and egress.snatFullyRandomPorts. When the first one
is set to true, the MASQUERADE iptables rules used to implement "local"
Node SNAT will use randomized source port mappings. When the second one
is set to true, the SNAT iptables rules used to implement Egress SNAT
will use randomized source port mappings. This is achieved with the
`--random-fully` iptables flag.

These new configuration parameters are only supported on Linux
Nodes. They require iptables >= 1.6.2, which is not a problem with the
standard antrea-agent container images. They also require Linux kernel
>= 3.13 and >= 3.14 respectively, but these are very old releases so we
can ignore this requirment, which is consistent with the K8s
implementation.

The 2 parameters are set to false by default, but we may change the
default value to true in the future.

Fixes antrea-io#6544

Signed-off-by: Antonin Bas <[email protected]>
antoninbas added a commit to antoninbas/antrea that referenced this issue Aug 22, 2024
We expose 2 new configuration parameters for the Agent:
snatFullyRandomPorts and egress.snatFullyRandomPorts. When the first one
is set to true, the MASQUERADE iptables rules used to implement "local"
Node SNAT will use randomized source port mappings. When the second one
is set to true, the SNAT iptables rules used to implement Egress SNAT
will use randomized source port mappings. This is achieved with the
`--random-fully` iptables flag.

These new configuration parameters are only supported on Linux
Nodes. They require iptables >= 1.6.2, which is not a problem with the
standard antrea-agent container images. They also require Linux kernel
>= 3.13 and >= 3.14 respectively, but these are very old releases so we
can ignore this requirment, which is consistent with the K8s
implementation.

snatFullyRandomPorts is set to false by default (this may change in the
future). egress.snatFullyRandomPorts is set to null (empty) by default,
which means that unless the parameter is explicitly set, we will use the
top-level snatFullyRandomPorts value.

Fixes antrea-io#6544

Signed-off-by: Antonin Bas <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. lifecycle/active Indicates that an issue or PR is actively being worked on by a contributor. reported-by/end-user Issues reported by end users.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants