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

Docker not blocked by macOS firewall #729

Open
oleborup opened this issue Sep 30, 2016 · 22 comments
Open

Docker not blocked by macOS firewall #729

oleborup opened this issue Sep 30, 2016 · 22 comments

Comments

@oleborup
Copy link

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

  1. Enable macOS firewall
  2. Run nginx mapping to port 8080: docker run --rm -p 8080:80 -v /tmp:/usr/share/nginx/html:ro nginx
  3. Try to connect from other machine on same network using curl: curl http://<ip-of-mac-running-nginx>:8080
@ijc
Copy link
Contributor

ijc commented Nov 15, 2016

@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.

@iBobik
Copy link

iBobik commented Jan 9, 2017

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.

@djs55
Copy link
Contributor

djs55 commented Jan 10, 2017

(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:

screen shot 2017-01-10 at 10 41 38

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?

@atombender
Copy link

@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?

@atombender
Copy link

Ah, found it: Drag /Applications/Docker.app/Contents/Resources/bin/vpnkit into the list.

@atombender
Copy link

This issue has been open for 1 year and 7 months. Can it please get some attention?

@YRM64
Copy link

YRM64 commented May 15, 2018

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).

@atombender
Copy link

atombender commented May 15, 2018

@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.

@SRautila
Copy link

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"

@pjialin
Copy link

pjialin commented Sep 18, 2018

@SRautila Thanks for your answer, It's a great solution.

@docker-robott
Copy link
Collaborator

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

@atombender
Copy link

/remove-lifecycle stale

@docker-robott
Copy link
Collaborator

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

@orymate
Copy link

orymate commented Mar 17, 2019

/remove-lifecycle stale
This is a security issue.

@docker-robott
Copy link
Collaborator

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

@atombender
Copy link

/remove-lifecycle stale

@thaJeztah
Copy link
Member

/lifecycle frozen

@thaJeztah
Copy link
Member

@djs55 was there any progress to report on this?

@bolt-juri-gavshin
Copy link

Is there a way to force local Kubernetes to bind only to 127.0.0.1?

@bolt-juri-gavshin
Copy link

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).

@vsisl
Copy link

vsisl commented Nov 29, 2023

What is the status of this? I find this to be quite a serious security issue.

@Creative-Difficulty
Copy link

@atombender

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

No branches or pull requests