Open oleborup opened 8 years ago
@oleborup thanks for the report and sorry for the tardiness of the response. I can confirm your observations and also that this behaviour is independent of the state of the "Automatically allow signed software to receive incoming connections".
I'm going to escalate this to an internal ticket.
How is it going?
It is potential security issue because developers travels around public WiFis and they usually does not know all their containers are accessible to their neighbours.
(sorry for the confused update -- I got mixed up between this ticket and an almost-identical internal duplicate.)
In the System Preferences -> Firewall -> Firewall options I see a checkbox:
Automatically allow downloaded signed software to receive incoming connections
This is checked by default on my system and is what -- I believe -- lets docker run -p 8080
work silently.
I believe there is a caching effect too -- I had to uncheck the box, then remove com.docker.slirp
from the application list and then restart Docker.app
. Then when I run docker run -p 8080
it pops up a dialog box asking me to allow or deny incoming connections to com.docker.slirp
and then remembers it here:
It's probably associated the choice with the specific application binary + signature-- you would probably get asked again over an upgrade.
Personally I think this behaviour is not ideal -- once the user has authorised the application this is cached and is independent of the Wifi network, which as @iBobik points out may not be what you want. It appears to be standard on the Mac though. I authorised my com.docker.slirp
and then switched to the guest network and there was no additional prompt.
However there is a partial work-around if you want to treat networks differently: you can restrict docker's ability to bind to external IP addresses via a database key (there is no UI yet-- the feature isn't really finished) e.g.
cd ~/Library/Containers/com.docker.docker/Data/database/com.docker.driver.amd64-linux
git reset --hard
echo "127.0.0.1,1.2.3.4" > allowed-bind-address
git add allowed-bind-address
git commit -m 'restrict bind addresses'
A log line will show it has taken effect, in syslog -k Sender Docker
Jan 10 10:51:43 Davids-MBP-2 Docker[20119] <Notice>: allowing binds to 1.2.3.4, 127.0.0.1
and then attempts to bind other addresses (NB 0.0.0.0
is the default) will fail:
docker run --rm -p 8080:80 -v /tmp:/usr/share/nginx/html:ro nginx
docker: Error response from daemon: driver failed programming external connectivity on endpoint gallant_goldwasser (5e1c04bf3a6a588e055a6c889f6e153b89710234f61b144afff20ef993f5f923): Error starting userland proxy: Bind for 0.0.0.0:8080 failed: permission denied.
I think we should at least add some notes about this to the networking section of the manual. Perhaps we should refine this feature into one which allows whitelisting of trusted networks?
@djs55: My Edge install doesn't have a binary named com.docker.slirp
anywhere, and it's not in the firewall list. Which binary should one add?
Ah, found it: Drag /Applications/Docker.app/Contents/Resources/bin/vpnkit
into the list.
This issue has been open for 1 year and 7 months. Can it please get some attention?
Alexander, I think what your addressing is an inherent design dilemma built into the MacOs firewall application. I don't want to refer to as a design 'flaw', however, it does pose a significant inconvenience for developers seeking to block certain ports that the docker/MacOs firewall allows through.
I don't think there's been an update to this issue since March 2016. If I'm wrong, I stand corrected. Perhaps djs55 can comment for us on the timeframe, and the amount of time it will take to come up with an acceptable solution. I've conducted a little research on the subject matter, and the following is what I ascertained. Developers feel free to jump in here if your research has taken you in a different direction.
First, you must have an OSX v. 10.5.1 or later version to configure the firewall to your own personal specification using the advanced settings feature. To allow certain protocols/applications through the MacOs firewall:
1) Open System apreferences 2) Click on Security or Security and Privacy icon 3) Click on the Firewall Tab 4) Click the lock icon in the Preference Pane, then Enter an Administrative Name and Password 5) Select the Firewall's Option Button 6) Click on Add Application (+) Button; to Remove an Application Listed, Remove Application using the (-) symbol What most developers don't realize is that apps signed by Apple and Ipfw automatically come through the firewall, this is a design element built into the MacOs firewall. Apps signed by Apple are deemed authorized, and are therefore allowed through. And, ipfw rules supersede any firewall rules. In other words, if ipfw blocks an incoming packet, the MacOs firewall ignores it.
Furthermore, the Mac firewall works with internet protocols utilized by apps TCP and UDP. Firewall settings don't affect for example, Apple Talk Connections. To reiterate, The firewall can't override ipfw rule setting technology. I suspect, but I could be wrong, this is a possible reason you aren't prompted to disclose whether you want to allow or disallow a certain application through the firewall. Perhaps djs55 can provide further comment on this particular issue.
One healthful/helpful piece of advice I can contribute to the discussion is to encourage developers to enable Stealth Mode which prevents the computer from responding to probing requests. Unexpected requests are ignored (such as ping).
@YRM64 The easiest workaround would be for DfM to stop binding to external interfaces. I'm not sure what kind of workflow other developers use, but to me there's no utility to binding external interfaces, since localhost is entirely sufficient for local development and testing. For any testing that requires incoming connections I use (and recommend) ngrok.
DfM could also easily work around the Automatically allow downloaded signed software to receive incoming connections setting by adding a custom firewall rule that overrides it.
For the user to manually configure the firewall setting just to achieve security is nonsensical, but it is also not future-proof. Case in point: Back in February I added /Applications/Docker.app/Contents/Resources/bin/vpnkit
to the list of blocked apps. But in some subsequent DfM upgrade, they changed the binary to .../bin/com.docker.vpnkit
, and so my rule got knocked out without me realizing it.
My workaround for this is to only expose the ports to 127.0.0.1 for local development.
E.g.
ports:
- "127.0.0.1:8000:8000"
@SRautila Thanks for your answer, It's a great solution.
Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale
comment.
Stale issues will be closed after an additional 30d of inactivity.
Prevent issues from auto-closing with an /lifecycle frozen
comment.
If this issue is safe to close now please do so.
Send feedback to Docker Community Slack channels #docker-for-mac or #docker-for-windows. /lifecycle stale
/remove-lifecycle stale
Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale
comment.
Stale issues will be closed after an additional 30d of inactivity.
Prevent issues from auto-closing with an /lifecycle frozen
comment.
If this issue is safe to close now please do so.
Send feedback to Docker Community Slack channels #docker-for-mac or #docker-for-windows. /lifecycle stale
/remove-lifecycle stale This is a security issue.
Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale
comment.
Stale issues will be closed after an additional 30d of inactivity.
Prevent issues from auto-closing with an /lifecycle frozen
comment.
If this issue is safe to close now please do so.
Send feedback to Docker Community Slack channels #docker-for-mac or #docker-for-windows. /lifecycle stale
/remove-lifecycle stale
/lifecycle frozen
@djs55 was there any progress to report on this?
Is there a way to force local Kubernetes to bind only to 127.0.0.1?
It could be a setting in Docker UI, to list IPs the Kubernetes (or the entire Docker) is allowed to bind to.
Yet another possibility is to start supporting loadBalancerIP
in Service with type "LoadBalancer", this way one can create a LoadBalancer, that is bound to "127.0.0.1", for example. I think the latter option is more flexible. However, NodePort must also become unavailable on other inerfaces (otherwise services are still vulnerable).
What is the status of this? I find this to be quite a serious security issue.
@atombender
Expected behavior
When mapping a container port to a host port it is expected that external access to the port is blocked by the macOS firewall, if enabled, and it is expected that the user should be prompted to allow docker to open the port in the firewall.
Actual behavior
Mapped ports are accessible externally even if the firewall is enabled. Only enabling "Block all incoming connections" will prevent access, but not an option is cases where some ports needs to be accessible.
Information
Docker for Mac: version: 1.12.1-beta26.1 (12c3e63) OS X: version 10.12 (build: 16A323) logs: /tmp/5EEDAAC2-A4C2-4562-86DF-C033FDB4739C/20160930-104203.tar.gz [OK] docker-cli [OK] virtualization kern.hv_support [OK] menubar [OK] moby-syslog [OK] dns [OK] disk [OK] system [OK] app [OK] osxfs [OK] virtualization VT-X [OK] db [OK] slirp [OK] logs [OK] env [OK] vmnetd [OK] moby-console [OK] moby [OK] driver.amd64-linux
Steps to reproduce the behavior
docker run --rm -p 8080:80 -v /tmp:/usr/share/nginx/html:ro nginx
curl http://<ip-of-mac-running-nginx>:8080