Skip to content

Repository files navigation

Docker Firewall Operator

A declarative, label-based firewall for Docker containers.

Instead of fighting with Docker daemon over host iptables rules (which Docker frequently overwrites), this operator injects nftables rules directly into the isolated Network Namespace (netns) of each container. This ensures that your container network restrictions are persistent, secure, and independent of the host's firewall configuration.

Features

  • Declarative Configuration: Manage firewall rules directly via docker-compose.yaml labels.
  • True Isolation: Rules are applied inside the container's netns, making them completely immune to host Docker network reloads.
  • Dynamic DNS Resolution: Supports standard Docker service names (and Swarm tasks.*). IP addresses are resolved using Docker's internal DNS (127.0.0.11) and updated automatically on the fly.
  • High Performance: Uses Netlink and nftables Sets under the hood. Rules are updated instantly via diffing without dropping legitimate traffic or flushing the entire ruleset.

How to use

Deploymnet

The operator runs as a Docker container itself. However, to manipulate the network namespaces of other containers, it requires specific privileges.

services:
firewall-operator:
restart: unless-stoppedimage: ghcr.io/hit2hat/firewall-operator:latestpid: "host"# Required to discover processes and their netns on the hostcap_add:
- NET_ADMIN # Required to manage network namespaces and nftables
- SYS_ADMIN # Required to switch namespaces (setns)
- SYS_PTRACE # Required to inspect processescap_drop:
- ALL # Drop all other unneeded privileges for securityvolumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # Required to listen to Docker API

Available labels

You can control the firewall behavior for any container by adding the following labels:

LabelDescriptionExample
firewall.enabledEnables the firewall operator for this container.true or false
firewall.portsComma-separated list of ports exposed to the outside. All other ports are dropped at the very first filter.80,443,8080
firewall.in.enabledEnables filtering for incoming traffic.true or false
firewall.in.modeDefines the behavior for incoming traffic (whitelist or blacklist).whitelist
firewall.in.sourceComma-separated list of allowed/blocked incoming IP addresses/subnets.192.168.1.100,10.0.0.0/24
firewall.in.servicesComma-separated list of allowed/blocked internal Docker services.nginx,api-gateway
firewall.out.enabledEnables filtering for outgoing traffic.true or false
firewall.out.modeDefines the behavior for outgoing traffic (whitelist or blacklist).whitelist
firewall.out.sourceComma-separated list of allowed/blocked outgoing external IPs.8.8.8.8,1.1.1.1
firewall.out.servicesComma-separated list of allowed/blocked destination Docker services.postgres,redis

Example usage

Here is an example of two services. test2 is allowed to send traffic only to test1. Any other outgoing traffic from test2 will be dropped. test1 accepts incoming traffic only from test2 on port 80.

services:
test1:
image: nginx:alpinelabels:
- "firewall.enabled=true"
- "firewall.ports=80"
- "firewall.in.enabled=true"
- "firewall.in.mode=whitelist"
- "firewall.in.services=test2"test2:
image: curlimages/curl:latestcommand: ["sleep", "infinity"]labels:
- "firewall.enabled=true"
- "firewall.out.enabled=true"
- "firewall.out.mode=whitelist"
- "firewall.out.services=test1"

How to build

If you want to build the binary from source, ensure you have Go installed, then run:

For amd64:

GOOS=linux GOARCH=amd64 go build -o build/firewall_amd64 src/main.go

For arm64:

  • arm64: GOOS=linux GOARCH=arm64 go build -o build/firewall_arm64 src/main.go

License

MIT.

About

🐳 Docker Firewall Operator for declarative netns setup

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Packages

Contributors

Languages