Zero-trust outbound firewalling for Docker containers, powered by transparent DNS inspection.
Dockerwall is a security daemon that tightly controls outbound traffic from your Docker containers. Instead of manually maintaining brittle lists of IP addresses or configuring complex HTTP proxies, Dockerwall lets you specify allowed domains. It transparently intercepts container DNS queries, dynamically adds resolved IP addresses to an allowed ipset, and drops all other outbound traffic at the network level.
If your container gets compromised, the attacker cannot exfiltrate data to unauthorized servers, download external payloads, or pivot to unapproved external infrastructure.
In modern microservice architectures, containers often have unrestricted outbound internet access by default. This is a massive security risk. Traditional solutions fall short:
- Static IP Rules: IP addresses for services (like AWS, GitHub, or third-party APIs) change constantly. Static rules break production.
- HTTP Proxies (Squid/Envoy): Require modifying the container application to use proxy environments (
HTTP_PROXY), and they don't cover non-HTTP traffic.
Dockerwall's approach:
- Default-Deny: As soon as a Dockerwall network is created, all outbound traffic from that subnet is dropped.
- Transparent DNS Inspection: Dockerwall runs a local DNS proxy. Container DNS queries are seamlessly rerouted via
iptablesDNAT rules to the daemon. - Dynamic Network Access: When a container requests an allowed domain (e.g.,
api.github.com), Dockerwall resolves it, instantly injects the resulting IP addresses into the container'sipset, and allows the traffic through. - Protocol Agnostic: Because Dockerwall operates at the network layer (
iptables/ipset), it protects all traffic (TCP/UDP), not just HTTP.
Here is a full example of locking down a container so it can only communicate with example.com.
Start the Dockerwall daemon in the background. It will listen for IPC commands and manage the local DNS proxy.
sudo dockerwall daemon &Ask Dockerwall to create a secure Docker network named secure-net and restrict it strictly to *.example.com.
sudo dockerwall prepare-network secure-net "*.example.com"(Under the hood, Dockerwall creates the bridge network, establishes the iptables DROP/ACCEPT rules, creates the ipset, and sets up transparent DNS rerouting).
Attach any unmodified container to the network. It will transparently be secured.
Allowed Traffic:
docker run --rm --network secure-net curlimages/curl:latest -sS --max-time 5 http://example.com
# ✅ Success! The DNS was inspected and the IP was dynamically allowed.Blocked Traffic:
docker run --rm --network secure-net curlimages/curl:latest -sS --max-time 5 http://google.com
# ❌ Blocked! The connection will time out because it's dropped at the network layer.- Massive Scalability: Dockerwall uses high-performance
ipsetoperations. This ensures that even large cloud provider IP ranges can be managed with no impact on network latency. - Asynchronous & Non-Blocking: Built on the
tokioasync runtime, the transparent DNS proxy handles queries concurrently for maximum throughput. - Fairness & Isolation: Dockerwall is designed to be robust under heavy load. It implements per-IP concurrency limits and asynchronous backpressure, ensuring that no single container can monopolize resources or affect the DNS resolution of others.
- Secure Management: The control IPC interface is protected by strict Unix filesystem permissions (0600) and communication timeouts, ensuring a secure and reliable management plane.
- Zero Container Modification: No custom
--dnsflags or/etc/resolv.confchanges are required. Traffic enforcement is handled transparently at the network gateway.
Dockerwall tracks every DNS resolution attempt across your managed networks. This allows you to audit which domains your containers are accessing (or attempting to access).
To view the live statistics report:
sudo dockerwall statsExample Output:
Network: secure-net (172.30.113.0/28)
172.30.113.5 api.github.com 12✅ 5s ago
172.30.113.5 malicious.site 3❌ 1m ago
(✅ indicates an allowed resolution that updated the ipset; ❌ indicates a blocked domain query).
Stats are stored in-memory with a configurable TTL (default 24h), which can be adjusted via the --stats-ttl flag when starting the daemon.
Make sure you have Rust installed, then compile Dockerwall from source:
cargo build --release
sudo cp target/release/dockerwall /usr/local/bin/Note: Dockerwall requires root privileges to manage iptables, ipset, and Docker networks.