Restricting Network Traffic Between Containers on the Default Bridge in Docker

By default, Docker containers on the bridge network can freely communicate. In this detailed guide, learn how to restrict inter-container communication using Docker’s icc setting, custom bridge networks, and advanced iptables rules to enhance network isolation and security

Restricting Network Traffic Between Containers on the Default Bridge in Docker
Photo by Alina Grubnyak / Unsplash

Introduction

By default, Docker containers attached to the bridge network can freely communicate with one another. While this behavior is convenient for development and testing, it poses a potential security risk in production environments. Containers on the same network should not always have unrestricted access to each other, especially when dealing with sensitive applications or microservices. In this detailed guide, you will learn how to restrict container-to-container network traffic on Docker's default bridge network, understand the challenges, and explore secure alternatives to isolate communication.

1. Understanding Docker's Default Bridge Network

Before diving into restricting inter-container communication, I recommend checking out my previous blog posts, "Understanding Docker’s Default Networking Modes", and "Creating Custom Docker Networks" where I cover Docker's networking fundamentals, including bridge networks and custom network setups.

When Docker is installed, it creates a default network called bridge. Containers attached to this network can:

  • Communicate with each other via their internal IP addresses.
  • Access the host machine and external networks.

To list Docker networks and identify the bridge network, use:

docker network ls

Output:

NETWORK ID     NAME       DRIVER    SCOPE
abcd12345678   bridge     bridge    local
efgh23456789   host       host      local
ijkl34567890   none       null      local

By default, all containers without a specific network configuration attach to the bridge network.

2. Demonstrating the Problem: Free Communication

To illustrate, let’s create two containers attached to the default bridge:

Step 1: Run Two Containers

Start two containers and attach them to the default bridge network:

docker run -dit --name container1 alpine sh  
docker run -dit --name container2 alpine sh  

Step 2: Verify Connectivity

Attach to container1 and ping container2's IP address:

Access container1 and ping container2:

docker exec -it container1 sh
ping 172.17.0.3

You’ll see successful pings, confirming that the containers can communicate freely.

Find the IP address of container2:

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container2

Example output: 172.17.0.3

3. Why Restrict Container-to-Container Communication?

Unrestricted communication between containers can lead to the following risks:

  • Unauthorized Access: Malicious containers can access sensitive services running on other containers.
  • Network Noise: Containers may send unnecessary traffic to each other.
  • Isolation Breach: Containers running different applications may unintentionally interact, compromising security.

To address this, you need to restrict container-to-container traffic on the default bridge network.

4. Configuring icc to Restrict Inter-Container Traffic

Docker provides the icc (Inter-Container Communication) option, which controls whether containers on the bridge network can communicate. By default, icc is set to true, allowing free communication.

Step 1: Edit the Docker Daemon Configuration

Open or create the Docker daemon configuration file /etc/docker/daemon.json:

sudo nano /etc/docker/daemon.json

Add or modify the following option to disable inter-container communication:

{
  "icc": false
}

Save the file and restart the Docker daemon to apply the changes:

sudo systemctl restart docker

Step 2: Verify icc Configuration

  1. Test Restricted Traffic: You will see that the ping now fails, demonstrating that inter-container communication has been disabled.
  2. Try pinging container2 from container1.
docker exec -it container1 sh
ping 172.17.0.3

Repeat the steps to create two containers:

docker run -dit --name container1 alpine sh
docker run -dit --name container2 alpine sh

Confirm the Docker daemon configuration with:

docker info | grep "icc"

Output:

Inter-Container Communication: false

5. Limitations of the icc Setting

While disabling icc restricts communication on the default bridge network, it does not provide fine-grained control over network traffic. Key limitations include:

  • Global Setting: The icc option affects all containers on the bridge network.
  • No Selective Rules: You cannot allow communication for specific containers or services.
  • Custom Networks Are Unaffected: This setting only impacts the default bridge network, not user-defined networks.

For more control, you can use user-defined bridge networks and Docker’s built-in firewall capabilities.

6. Using User-Defined Bridge Networks for Isolation

Docker allows you to create custom bridge networks that can isolate container communication. By default, containers on a user-defined network cannot communicate unless explicitly configured.

Step 1: Create a User-Defined Bridge Network

Run the following command to create a custom bridge network:

docker network create my_secure_network

Step 2: Run Containers in the Custom Network

Attach containers to the new network:

docker run -dit --name container1 --network my_secure_network alpine sh  
docker run -dit --name container2 --network my_secure_network alpine sh  

Step 3: Verify Isolation

  • Test Communication: Ping container2 from container1. By default, this will succeed.
  • Restrict Communication: Use Docker network policies or an external firewall like iptables to block traffic selectively.

7. Restrict Traffic Using iptables (Advanced)

For granular control, you can configure firewall rules with iptables to restrict communication between containers.

Docker automatically creates iptables rules when containers start. To view the rules:

sudo iptables -L -v -n

Step 2: Add Rules to Block Container Traffic

To block traffic between containers on the bridge network, add the following rule:

sudo iptables -I FORWARD -i docker0 -o docker0 -j DROP
  • docker0 is the default bridge interface.
  • This rule blocks traffic between containers on the bridge network.

Step 3: Test the Rule

  • Create two containers and verify they cannot ping each other.

To revert the rule, delete it:

sudo iptables -D FORWARD -i docker0 -o docker0 -j DROP

8. Best Practices for Restricting Container Communication

  1. Use Custom Bridge Networks: Replace the default bridge network with user-defined networks for better isolation.
  2. Disable icc: Set icc: false to globally disable inter-container communication on the default bridge.
  3. Implement Firewall Rules: Use iptables for advanced traffic restrictions.
  4. Network Segmentation: Place containers that require communication in the same network and isolate others.
  5. Audit and Monitor: Regularly audit network traffic to detect unauthorized communication.Conclusion

Restricting container-to-container communication on the default bridge network is a critical step toward improving Docker security. While disabling the icc setting offers a quick solution, user-defined networks and firewall rules provide more control and flexibility. By following the steps outlined in this guide, you can secure your Docker environment, reduce unnecessary network exposure, and mitigate potential risks.

Read next

Switching Docker to Rootless Mode: A Hands-On Guide

In this hands-on guide, I take you step-by-step through switching my local Docker server to rootless mode. From reconfiguring services to tackling real-world challenges, discover how to transform your Docker environment into a more secure and robust system, even on a home server. Let’s dive in!