Skip to content

libnetwork: Remove iptables nat rule when hairpin is disabled#44803

Merged
neersighted merged 1 commit intomoby:masterfrom
akerouanton:fix-44721
Jan 12, 2023
Merged

libnetwork: Remove iptables nat rule when hairpin is disabled#44803
neersighted merged 1 commit intomoby:masterfrom
akerouanton:fix-44721

Conversation

@akerouanton
Copy link
Copy Markdown
Member

When userland-proxy is turned off and on again, the iptables nat rule
doing hairpinning isn't properly removed. This fix makes sure this nat
rule is removed whenever the bridge is torn down or hairpinning is
disabled (through setting userland-proxy to true).

Unlike for ip masquerading and ICC, the programChainRule() call
setting up the "MASQ LOCAL HOST" rule has to be called unconditionally
because the hairpin parameter isn't restored from the driver store, but
always comes from the driver config.

For the "SKIP DNAT" rule, things are a bit different: this rule is
always deleted by removeIPChains() when the bridge driver is
initialized.

Fixes #44721.

Side note: I'm not super happy with this fix. It does its job but there're now 3 ways iptables rules created by setupIPTablesInternal are torn down. There might be a better way to do that, but this probably won't be possible until libnetwork got cleaned up and iptables rules are managed in a better way.

- How to verify it

Turning userland-proxy off and on again, and then running iptables -t nat -nvL. There should be no rule looking like -A POSTROUTING -o docker0 -m addrtype --src-type LOCAL -j MASQUERADE.

When userland-proxy is turned off and on again, the iptables nat rule
doing hairpinning isn't properly removed. This fix makes sure this nat
rule is removed whenever the bridge is torn down or hairpinning is
disabled (through setting userland-proxy to true).

Unlike for ip masquerading and ICC, the `programChainRule()` call
setting up the "MASQ LOCAL HOST" rule has to be called unconditionally
because the hairpin parameter isn't restored from the driver store, but
always comes from the driver config.

For the "SKIP DNAT" rule, things are a bit different: this rule is
always deleted by `removeIPChains()` when the bridge driver is
initialized.

Fixes moby#44721.

Signed-off-by: Albin Kerouanton <[email protected]>
Copy link
Copy Markdown
Member

@neersighted neersighted left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM. This is definitely messy, but not as bad as I feared in #44721 (comment), and the one-line change makes it a lot more palatable.

Overall I think this is the lesser evil until the rules logic gets cleaned up in its entirety.

Comment thread docs/contributing/debug.md
@neersighted
Copy link
Copy Markdown
Member

Eyeing this for 23.0.y; I think it's fine to omit from 20.10.

@neersighted neersighted requested a review from corhere January 12, 2023 15:07
Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops, I kicked CI earlier, thought I LGTM'd

backporting sounds okay to me

@neersighted
Copy link
Copy Markdown
Member

Test failure is known flake/unrelated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

userland-proxy: false does not clean-up NAT rule when switching to userland-proxy: true

4 participants