Cozy Camp owu.se Mountain(´∀`)

Docker Networking Nightmare and UFW can't help you ;-;

Guys, Docker just fuck me up real hard ;-;

Realizing that my docker-based application has been open-naked to the public for months is fucked up dude.

Here is the breakdown of what happen and why and how to fix this.

7 Jul, I was casually browsing on shodan.io and tried one of my server IP addresses and it turned out that I have port 4040 opened. I even set my UFW rule to deny all that’s not whitelisted.

So, I reviewed all my docker-based service, and it turned out that all my docker services are reachable by the internet UNRESTRICTED

Panic Docker banner

What Wrong?

we’re talking about Docker Compose here’s what docker-compose.yml usually looks like:

services:
  app:
    image: xxx
    ports:
      - "4040:4040"
    volumes:
      - .:/app

this configuration will expose ports to the internet through 0.0.0.0:4040and nothing like UFW can prevent it from exposing to the internet. because Docker is directly making changes on the Iptables level.

This is pretty serious in that it might unintentionally expose sensitive services that should not be exposed to the internet, exposed to the internet. without restriction.

Why?

referring to Docker Docs, traffic from/to containers is routed before INPUT/OUTPUT rules apply. This bypass all rules "effectively ignoring your firewall configuration."

How to fix

There are multiple ways to prevent Docker from exposing ports to the internet.

by editing /etc/docker/daemon.json to disable it by:

{
  "iptables" : false 
}

I’ve tried this method and sadly doesn’t work. also, Docker Docs Recommend against this method quote "It is likely to break container networking for the Docker Engine"

2. Next up, “User-defined networks”.

You just need to create a network driver and use this network driver to communicate with another Docker Container.

Tho, this is recommended if you are just going to use your docker container internally or between docker containers.

Excerpt from Archivebox Docker-compose.yml here’s what User-defined networks looks like:

# using network driver name "dns" and set dns address to "172.20.0.53" for the "main" the container
services:
  archivebox:
        image: archivebox/archivebox:latest
        ports:
            - 8000:8000
        networks:
         - dns
        dns:
         - 172.20.0.53

# Setup IPv4 address for pi-hole container
  pihole:
        image: pihole/pihole:latest
        networks:
        dns:
          ipv4_address: 172.20.0.53

# Network driver setup
networks:
    # network just used for pihole container to offer :53 dns resolving on fixed ip for archivebox container
    # Learn more : https://docs.docker.com/compose/networking/
    dns:
        ipam:
            driver: default
            config:
                - subnet: 172.20.0.0/24 # Here is subnet for internal Docker Network ip address

3. Publish port cautiously on specified network Interfaces

This method is the easiest way, you just have to specify your network interfaces when config your docker-compose.yml

for example, you need to forward port 4040 of your host to 8080 on the docker host:

    ports:
    - "127.0.0.1:4040:8080"

This will exposing your docker container on port 8080 to 127.0.0.1:4000 on your local network, NOT THE INTERNET!

What I Learned from the incident

First, internet scanners like shodan/censys are very useful for detecting an accidental expose.

Second, Never trust certain software too much! this is really important in this case i trusted UFW’s ability to block traffic so much that I didn’t even ever check for port leaks. So, this simple issue remain under radar for years!

Aside from that don’t forget to check your docker-compose.yml file when hosting new software for potential port leaks, because most docker-focused projects would always(if not mostly) expose their service to the internet via something like 4040:4040 in their default docker-compose.yml file.

Panic Yuru Camp banner, stolen from tenor

And now your service should be safe from an unwanted attention!

References:

Note: this is the longest article I have written in years, if anyone has a comment please leave one! via My E-Mail or GitHub issue!

#blog #docker #security