Transparently forward local port to remote server
I have StatsD daemon running on a remote server (x.x.x.x
) at 8125
. I would like to forward 127.0.0.1:8125
to x.x.x.x:8125
.
I have already tried running the following on localhost
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p udp --dport 8125 -j DNAT --to x.x.x.x:8125
iptables -t nat -A OUTPUT -p udp --dport 8125 -j DNAT --to-destination x.x.x.x:8125
iptables -t nat -A POSTROUTING -d x.x.x.x -j MASQUERADE
But it is not forwarding correctly.
echo "test.test.test:1|c" | nc -w 1 -u localhost 8125
Fails with error nc: Write error: Connection refused
echo "test.test.test:1|c" | nc -w 1 -u 127.0.0.1 8125
Fails without any error
echo "test.test.test:1|c" | nc -w 1 -u x.x.x.x 8125
Works correctly
Also, will such a port forwarding cause any security issues?
Solution 1:
That's not possible.
Packets generated by local processes are not involved in the forwarding plan.
As a consequence you won't be able to use PREROUTING
and FORWARD
chains in the tables locally generated packets will go through, but only OUTPUT
(in raw/mangle/nat/filter
tables) and POSTROUTING
(in mangle/nat
tables) chains while the routing decision is already made and you can't change it.
In fact with your current iptables setup your rules will do the following considering your use case :
- First rule : unreached.
- Second rule : DNAT locally generated packets to
x.x.x.x
on the loopback interface. - Third rule : Masquerade packets going trough your loopback interface with the IP address of your loopback interface.
So the result is : local packets will try to reach x.x.x.x:8125
on your loopback interface.
This netfilter diagram can help you understand the location of locally generated packets in the global flow.