Flowminder / FlowKit

FlowKit: Flowminder CDR analytics toolkit
https://flowminder.github.io/FlowKit/
Mozilla Public License 2.0
86 stars 20 forks source link

Consider taking a stricter stance on Docker container port publishing in the provided FlowKit examples #2813

Open chrisjbrooks opened 4 years ago

chrisjbrooks commented 4 years ago

Is your feature request related to a problem? Please describe. We should assist end users as best we can to align with Docker security best practises, particularly for scenarios where FlowKit might be installed on a host (be it a prod server or a dev laptop) that is exposed to external source IPs and/or the Internet. From the Docker networking documentation:

By default, all external source IPs are allowed to connect to the Docker host.

The consequence of this is that if you publish something using docker run, e.g.

docker run -p 5435:5432 ...

or as part of a compose file service configuration, e.g.

...
- ports
    - "5435:5432"
...

then the published port will bind to 0.0.0.0:5435 i.e. reachable via "all IPv4 addresses on the local machine" from all external source IPs. For docker swarm deployments, it is published on the ingress network by default, and thus it is public. To publish to the host rather than the ingress network, you can use the ports expanded syntax in the Compose file:

- ports:
    - mode: host
       target: 5435
       published: 5432

However, this will still bind to 0.0.0.0:5435 on each host. It is currently not possible to deploy a service with an IP address specified i.e. you can't bind to 127.0.0.1 on a swarm deploy. See existing issues here and here.

Describe the solution you'd like

  1. Remove host port publishing to the external world from all example Compose yaml files (or similar) for all services except those that actually need it i.e. FlowAPI, and possibly FlowETL's Airflow UI/API.
  2. Take a secure-by-default stance when publishing any port. Ensure examples that expose http services demonstrate serving over https by default i.e. FlowAPI and FlowETL's Airflow UI/API.
  3. Consider adding a reverse proxy service to the examples to demonstrate how to reduce the attack surface.
  4. For docker CLI or docker-compose examples, ensure that published ports for backend services like FlowDB are bound to 127.0.0.1 by default e.g. docker run -p 127.0.0.1:5435:5432 ...
  5. For docker swarm examples, since you can't bind to the loopback (localhost) 127.0.0.1, remove all unnecessary port publishing, and ensure any that are implemented in a secure-by-default manner.
  6. Review current deployment examples and content of associated documentation against best practise e.g. CIS Docker Benchmark v1.2.0.

Describe alternatives you've considered

  1. Consider adding example iptables rules (Linux) e.g. to restrict connections to the host. Investigate docker+firewall best practise for dev environments e.g. on macOS.

Additional context Part of the documentation for Developers/Administrators should include Docker Security best practise tips, with clear examples related to FlowKit dev and prod deployment scenarios.

chrisjbrooks commented 3 years ago

In addition, secure-by-default should also apply when adding a private registry to a FlowKit swarm e.g. for hosts with no internet access.

greenape commented 3 years ago

Yeah. This we should a. cut down the number of ports published, and b. sort out publish-externally-by-default. I think what we actually want is a 'proper' deploy example, which includes our solutions for those.