-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Add an opt-out for iptables 'raw' rules #49621
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
Conversation
|
Perhaps something we should add to the Not sure how easy it would be to punch through this option all the way from the daemon config, but if that's not trivial (likely isn't?) we could add the same check for the env-var somewhere in the |
Sure, how does this look? ... could add some words about the implications, but that could get a bit too wordy? (Maybe worth noting, I think this will go-away once we've switched to native nftables.) |
Probably fine; if we need more, we could of course add a (Having it in |
daemon/info_unix.go
Outdated
| } | ||
| // Env-var belonging to the bridge driver, disables use of the iptables "raw" table. | ||
| if os.Getenv("DOCKER_INSECURE_NO_IPTABLES_RAW") == "1" { | ||
| v.Warnings = append(v.Warnings, "WARNING: DOCKER_INSECURE_NO_IPTABLES_RAW=1") |
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.
If we do want to add some words around it, perhaps something like;
| v.Warnings = append(v.Warnings, "WARNING: DOCKER_INSECURE_NO_IPTABLES_RAW=1") | |
| v.Warnings = append(v.Warnings, "WARNING: DOCKER_INSECURE_NO_IPTABLES_RAW is set") |
| v.Warnings = append(v.Warnings, "WARNING: DOCKER_INSECURE_NO_IPTABLES_RAW=1") | |
| v.Warnings = append(v.Warnings, "WARNING: raw iptables rules are skipped because DOCKER_INSECURE_NO_IPTABLES_RAW is set") |
The 'DOCKER_INSECURE_NO_IPTABLES_RAW is set` may be slightly nicer to indicate what's the case, but not sure about the "raw iptable rules are skipped", not sure if that's providing much context on its own.
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.
Ok, yes - I'll change it to "is set".
| "gotest.tools/v3/golden" | ||
|
|
||
| containertypes "github.com/docker/docker/api/types/container" |
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.
Micro-nit (if you'll be pushing again); looks like this one ended up separate from the other imports below
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.
Doh! Thank you ... something in my GoLand setup does that, maybe gofumpt. It's very annoying, but haven't tracked it down yet.
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.
Yeah, possibly it's using a different convention (which we possibly should adopt) where imports are in 3 blocks instead of 2;
[go stdlib imports]
[external imports]
[local imports]
That's kinda ok, but I see it also more often result in accidental splitting up blocks even more. I think there's a linter for that though (still to look into)
For kernels that don't have CONFIG_IP_NF_RAW, if the env var DOCKER_INSECURE_NO_IPTABLES_RAW is set to "1", don't try to create raw rules. This means direct routing to published ports is possible from other hosts on the local network, even if the port is published to a loopback address. Signed-off-by: Rob Murray <[email protected]>
|
|
||
| func rawRulesDisabled(ctx context.Context) bool { | ||
| if os.Getenv("DOCKER_INSECURE_NO_IPTABLES_RAW") == "1" { | ||
| log.G(ctx).Debug("DOCKER_INSECURE_NO_IPTABLES_RAW=1 - skipping raw rules") |
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.
Is this logged once, or for every container? If it's once, then Warn would be fine as well
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.
Every container, on create and delete ... I figured it'd be better to repeat it, so it's there in any log snippets we get.
thaJeztah
left a comment
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 LGTM
I'll leave it to @akerouanton for the networking side of things 🤗
|
WDYT about changelog: Add environment variable `DOCKER_INSECURE_NO_IPTABLES_RAW=1` to allow Docker to run on systems where the Linux kernel can't provide `CONFIG_IP_NF_RAW` support. When enabled, Docker will not create rules in the iptables `raw` table. Warning: This is not recommended for production environments as it reduces security by allowing other hosts on the local network to route to ports published to host addresses, even when they are published to `127.0.0.1.` This option bypasses some of the security hardening introduced in Docker Engine 28.0.0. |
- What I did
For kernels that don't have
CONFIG_IP_NF_RAW, if the env varDOCKER_INSECURE_NO_IPTABLES_RAWis set to"1", don't try to create raw rules.Warning: When the environment variable is set, direct routing to published ports is possible from other hosts on the local network, even if the port is published to a loopback address. It un-does some of the security hardening described at https://www.docker.com/blog/docker-engine-28-hardening-container-networking-by-default/
- How I did it
The env var is
DOCKER_INSECURE_NO_IPTABLES_RAW... because that's why the workaround is needed. Alternatively, it could be called something likeDOCKER_INSECURE_ALLOW_DIRECT_ROUTING... because that's currently the effect. Then it'd need to do the same thing for an nftables/firewalld implementation.If we want to add a more "feature-y" way to allow direct routing at some point - it should be via a new "gateway mode" with well defined semantics, something less drastic than
nat-unprotected(allowing access from remote hosts, but only to published ports, and maybe not to ports published to127.0.0.1). That'd work per network rather than globally, and it'd need some different regression testing and more documentation.So, I went for this simple workaround for kernels without the required module.
- How to verify it
New integration test.
Also, checked a container with host port mapping started on a host without
CONFIG_IP_NF_RAW...In docker's log ...
(And, no rules created in the iptables/ip6tables
rawtable.)- Human readable description for the release notes