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
Related videos on Youtube
Author by
Futurama1
Updated on September 18, 2022Comments
-
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:
- 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)
- Docker network is "bridge" only (can't use "host")
-
Futurama1 almost 7 years@Aaron I have solved the problem with
net.ipv4.conf.docker0.route_localnet=1
-
Aaron almost 7 yearsHappy 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 almost 5 yearsAny explanation what this does?
-
Paul about 3 yearsThis 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