-
Notifications
You must be signed in to change notification settings - Fork 18.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
Publishing ports explicitly to private networks should not be accessible from LAN hosts #45610
Comments
WorkaroundIn the meantime for those concerned, it can be prevented by:
For some scenarios, you may have alternative options that do not require port publishing. Or the upcoming IPVS NAT alternative may be suitable when paired with a firewall :) If anyone would like to pursue a PR, the moby/libnetwork/iptables/iptables.go Lines 196 to 200 in cf4df9d
Probably a bit more to it and I don't know for sure if that minor addition to exclude I'm not sure how the other adjustment could be approached 😅 (perhaps documentation would be easier) |
@polarathene Thanks for the high quality issue! I think this might be a duplicate (this is definitely well known with the existing network model), but I couldn't find it; in any case you've added enough of a detailed model here that we might want to use this issue as the reference going forward. Are you on the community Slack by any chance? If you could join there, I'd like to put you more directly in touch with the folks working on improving the networking stack. |
I am aware of two issues that are similar:
While this issue itself is about publishing only on If there was another issue tracking this same problem, nothing stood out to me when I did a quick search for existing issues 😅
I am now :) I sent you a DM there 👍 |
When fixed, the networking docs have a reference to this issue that can be dropped: docker/docs#17176 (comment) |
#14041 is what I had in mind -- nice find 😀 |
By default, published docker ports "bind" to all inbound addresses. We restrict to localhost to avoid exposing the site to the internet. Note that malicious same L2 participants can still reach the container due to: moby/moby#45610
Any updates or progress related to this issue? |
Description
With
docker run --rm -d -p 127.0.0.1:8081:80 traefik/whoami
, it is not expected that hosts on a common network could access the service, but they can due toiptables
rules managed by Docker:For example, on the docker host (
192.168.42.10
), the container could be reached at127.0.0.1:8081
or172.17.0.3:80
from a separate host at192.168.42.20
.Reproduce
Run the following commands:
Docker host (
192.168.42.10
):Technically only the 2nd container (
8081
) is relevant for reproduction:FORWARD
chain is set toACCEPT
)Neighbour host (
192.168.42.20
, same LAN):nmap
can be used to identify what ports are reachable at the docker host (only the published ports from Docker).Expected behavior
I did not expect hosts on the same network to be able to reach private subnets of a separate host like
127.0.0.1
or172.17.0.0/16
.Ports bound on
127.0.0.1
via services not running in containers were not reachable due to no equivalentiptables
rules permitting it AFAIK? Unclear if Docker could be more restrictive on that routing requirement.docker version
Click to view
Client: Docker Engine - Community Version: 24.0.1 API version: 1.43 Go version: go1.20.4 Git commit: 6802122 Built: Fri May 19 18:07:52 2023 OS/Arch: linux/amd64 Context: default Server: Docker Engine - Community Engine: Version: 24.0.1 API version: 1.43 (minimum version 1.12) Go version: go1.20.4 Git commit: 463850e Built: Fri May 19 18:06:17 2023 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.21 GitCommit: 3dce8eb055cbb6872793272b4f20ed16117344f8 runc: Version: 1.1.7 GitCommit: v1.1.7-0-g860f061 docker-init: Version: 0.19.0 GitCommit: de40ad0
docker info
Click to view
Additional Info
Reproduced with:
userland-proxy
enabled / disabled.docker
zone prevents bridge access)The scope is apparently limited to layer 2 network switching (not my area of expertise). Some other cloud providers like AWS aren't affected with their VPC by default, requiring opt-in config.
Cause and mitigation options
Docker changes (
sysctl net.ipv4.ip_forward=1
+iptables
chain rules forFORWARD
=>DOCKER
) to support the published ports, this is a side-effect.127.0.0.1
can be mitigated via additional constraint to thePREROUTING
NAT rule.172.16.0.0/12
(or similar docker networks) can at least be mitigated via Firewallddocker
zone.Related past vulnerability with
ip_forward=1
A related issue was reported in the past years ago and resolved. The vulnerability is present at a smaller scope (only access to containers via explicitly published ports, instead of all container ports), but may pose risk (indirect access to such containers on the docker hosts VPN network?).
This is presumably still a valid concern on untrusted networks (cafe / airport wifi), or trusted networks (home / corporate) if a LAN host were compromised.
You can find comments within existing issues from many years ago detailing how to perform this (a recent example (Nov 2021)), as well as other sources outside of the moby repo that discuss it. Thus the public report, as this had already been disclosed publicly?
Related past vulnerability from
route_localnet=1
elsewhereThis was initially for investigating when
userland-proxy: false
setssysctl net.ipv4.conf.docker0.route_localnet=1
. Which doesn't appear to be a risk (as detailed in point 3 here).I had seen a similar vulnerability in kubernetes which I wanted to verify (I had less familiarity with
route_localnet
at the time):That vulnerability although similar differs:
127.0.0.1
via the common LAN interface route, while the moby one is constrained to published ports only.moby
is only settingroute_localnet=1
for it's own bridge networks (not all interfaces withsysctl net.ipv4.conf.all.route_localnet=1
on the docker host - although narrowing that down to the common LAN interface would be sufficient).127.0.0.1
):INPUT
default policyDROP
)target: default
)The text was updated successfully, but these errors were encountered: