How to forward UDP packets from Docker container to host 127.0.0.1?

6,639

If anybody cares, I have solved the problem with

sysctl -w net.ipv4.conf.docker0.route_localnet=1
Share:
6,639

Related videos on Youtube

Futurama1
Author by

Futurama1

Updated on September 18, 2022

Comments

  • Futurama1
    Futurama1 over 1 year

    I have a host (A) with a StatsD daemon listening at 127.0.0.1:8125:

    root@A# netstat -uln
    Proto Recv-Q Send-Q Local Address           Foreign Address         State      
    udp        0      0 127.0.0.1:8125          0.0.0.0:*                          
    

    And a docker container (B) started on host A, with bridge network:

    root@A# docker network inspect bridge
    [
        {
            "Name": "bridge",
            "Id": "02b013615710b375744975ff74bdd0b5dcc8c25debba4fa23ad8f53da2c684e3",
            "Created": "2017-04-21T08:13:04.389253904Z",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": [
                    {
                        "Subnet": "172.17.0.0/16",
                        "Gateway": "172.17.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Containers": {
                "e1fde895c871504f64627c88531a380269ee9fe8a9fa5237a98c81500fa47a7a": {
                    "Name": "B",
                    "EndpointID": "4e4a8758e811bb48cecec67d339c182c60e1d955126506cddb7d451e818c5535",
                    "MacAddress": "02:42:ac:11:00:02",
                    "IPv4Address": "172.17.0.2/16",
                    "IPv6Address": ""
                }
            },
            "Options": {
                "com.docker.network.bridge.default_bridge": "true",
                "com.docker.network.bridge.enable_icc": "true",
                "com.docker.network.bridge.enable_ip_masquerade": "true",
                "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
                "com.docker.network.bridge.name": "docker0",
                "com.docker.network.driver.mtu": "1500"
            },
            "Labels": {}
        }
    ]
    

    My network interfaces:

    root@A# ip addr show
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
        link/ether 02:42:60:00:2c:63 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.1/16 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:60ff:fe00:2c63/64 scope link 
           valid_lft forever preferred_lft forever
    

    Now I want to send UDP packets with metrics from container B to StatsD on A (127.0.0.1:8125), something like this:

    root@B# echo "metric.name:1|c" | nc -w 1 -u 172.17.0.1 8125
    

    What should I do next to forward UDP packets from 172.17.0.1:8125 to 127.0.0.1:8125?

    I have tried to add iptables rule:

    root@A# iptables -t nat -A PREROUTING -p udp -i docker0 -d 172.17.0.1 --dport 8125 -j DNAT --to-destination 127.0.0.1:8125
    

    But I still do not see my UDP packets on StatsD.

    iptables nat:

    root@A# iptables -t nat -L -n -v
    Chain PREROUTING (policy ACCEPT 736 packets, 53956 bytes)
     pkts bytes target     prot opt in     out     source               destination         
     211K   13M DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
        3   116 DNAT       udp  --  docker0 *       0.0.0.0/0            172.17.0.1           udp dpt:8125 to:127.0.0.1:8125
    
    Chain INPUT (policy ACCEPT 724 packets, 53227 bytes)
     pkts bytes target     prot opt in     out     source               destination         
    
    Chain OUTPUT (policy ACCEPT 838 packets, 57674 bytes)
     pkts bytes target     prot opt in     out     source               destination         
       20  1186 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
    
    Chain POSTROUTING (policy ACCEPT 1407 packets, 91792 bytes)
     pkts bytes target     prot opt in     out     source               destination         
    84593 5296K MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
        0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:8080
    
    Chain DOCKER (2 references)
     pkts bytes target     prot opt in     out     source               destination         
     1285 77084 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
      933 55820 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.2:8080
    

    iptables filter:

    root@A# iptables -t filter -L -n -v
    Chain INPUT (policy ACCEPT 33641 packets, 5895K bytes)
     pkts bytes target     prot opt in     out     source               destination         
    
    Chain FORWARD (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
    2298K 1931M DOCKER-ISOLATION  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    1165K  662M DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
     602K  560M ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    1133K 1269M ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
        0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           
    
    Chain OUTPUT (policy ACCEPT 27954 packets, 14M bytes)
     pkts bytes target     prot opt in     out     source               destination         
    
    Chain DOCKER (1 references)
     pkts bytes target     prot opt in     out     source               destination         
     8285  685K ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:8080
    
    Chain DOCKER-ISOLATION (1 references)
     pkts bytes target     prot opt in     out     source               destination         
    2298K 1931M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    

    What is wrong?

    Important:

    1. I must use statsd only at A's 127.0.0.1:8125 (can't just set it to listen on 172.17.0.1:8125)
    2. Docker network is "bridge" only (can't use "host")
    • Futurama1
      Futurama1 almost 7 years
      @Aaron I have solved the problem with net.ipv4.conf.docker0.route_localnet=1
    • Aaron
      Aaron almost 7 years
      Happy to help. Just keep in mind that method blurs the line between the security zone of the loopback network with your docker network. You would have to decide if that is a risk and take precautions to protect the higher security zone.
  • Nishant Jani
    Nishant Jani almost 5 years
    Any explanation what this does?
  • Paul
    Paul about 3 years
    This did not work for me and seems to require some explanation (as this command is also referenced in 'security issue') github.com/kubernetes/kubernetes/issues/90259