Creating a network which allows communication between containers but no internet access

745 views Asked by At

How can I create a docker network using testcontainers which:

  • allows for all containers in the network to communicate with each
  • allows for containers to map ports to the host
  • but does not allow containers to have access to the internet

I have tried to do this using an internal network:

private Network generateInternalNetwork() {
     // Consumer which operates on the final CreateNetworkCmd which will be run to
     // make sure the 'internal' flag is set.
     Consumer<CreateNetworkCmd> cmdModifier = (createNetworkCmd) -> {
         createNetworkCmd.withInternal(true);
     };

     return Network.builder()
             .createNetworkCmdModifier(cmdModifier)
             .build();
}

However, when I run this I cannot have my port mapped. An exception is thrown:

Caused by: java.lang.IllegalArgumentException: Requested port (8024) is not mapped

If I run it without withInternal(true) it works fine but of course the containers have internet access.

2

There are 2 answers

0
vab2048 On BEST ANSWER

After spending a few days trying different things I have come up with a hack of a solution that kind-of works:

    /**
     * Set an invalid DNS for the given container.
     * This is done as a workaround so that the container cannot access
     * the internet.
     */
    void setInvalidDns() {
        GenericContainer<?> container = getContainer();
        Consumer<CreateContainerCmd> modifier = (cmd) -> {
                // Amend the config with the garbage DNS.
                String invalidDns = "255.255.255.255";
                HostConfig hostConfig = cmd.getHostConfig();
                hostConfig.withDns(invalidDns);
                cmd.withHostConfig(hostConfig);
        };

        container.withCreateContainerCmdModifier(modifier);
    }

This sets the container's DNS to an invalid IP and then when you try to make a HTTP request in the container it will throw a java.net.ConnectException.

2
larsks On

I think you can get what you want by (a) creating normal networks, and then (b) adding a DROP rule to your DOCKER-USER firewall chain:

iptables -I DOCKER-USER -j DROP

In my quick experiment just now, this let me map ports from containers, but prevented the containers from accessing the internet (because this chain is called from the FORWARD chain, to it prevents containers from forwarding traffic through the host to the outide internet).