Tonghua
Tonghua

Reputation: 309

How to use docker container as a router for other containers in the same network

I want to use docker-compose to setup one container (C1) works as a router/gateway, C1 forwards the tcp data from container (C2) to internet. But C2 cannot access internet at all, traceroute shows packets reached C1 then no more further actions

with this similar setup using virtual machines, it works fine. Why is that?

C2(set C1 as default router) -> C1 -> internet

C1: alpine image, with iptables installed, ip: 1.1 . ping or traceroute works here

iptables -A FORWARD -o eth0 -j ACCEPT;

C2: alpine image, use ip route to replace default router, ip: 1.3

ip route replace default via 172.28.1.1

version: '3'
services:
    C1:
        build: ./projects/C1
        container_name: C1
        privileged: true
        cap_add:
            - NET_ADMIN
            - SYS_MODULE
        sysctls:
            # - net.ipv4.conf.all.src_valid_mark=1
            - net.ipv4.ip_forward=1
        networks:
            testing_net:
                ipv4_address: 172.28.1.1

    C2:
        build: ./projects/C2
        container_name: C2
        cap_add:
            - NET_ADMIN
            - SYS_MODULE
        privileged: true
        # sysctls:
            # - net.ipv4.conf.all.src_valid_mark=1
            # - net.ipv4.ip_forward=1
        networks:
            testing_net:
                ipv4_address: 172.28.1.3
                
networks:
    testing_net:
        ipam:
            driver: default
            config:
                - subnet: 172.28.0.0/16

Upvotes: 5

Views: 8128

Answers (2)

Kamil Kozioł
Kamil Kozioł

Reputation: 194

I have found that this IP tables command solved my issues. I have tried everything that you proposed but this fixed it

iptables -t nat -A POSTROUTING --out-interface eth0 -j MASQUERADE

Upvotes: 1

Tonghua
Tonghua

Reputation: 309

From wireshark, I can see C1/C2 is sending out SYN packet, but website no response. According to this https://serverfault.com/a/496548/565903, I have to set tcp timestamp 0 so in docker-compose.yml file, C1 section, add tcp_timestamps = 0 then I can access public internet from C2.

        sysctls:
            - net.ipv4.ip_forward=1
            - net.ipv4.tcp_timestamps=0

Upvotes: 4

Related Questions