0

My problem:

I used the following iptables command:

iptables -t nat -A PREROUTING -p udp -i eth0 --dport 52220 -j DNAT --to-destination 192.168.19.40

192.168.19.40 is the IP address of a virtual machine, which is pingable:

root@Helium ~ # ip route get 192.168.19.40
192.168.19.40 dev untrusted-vm-br  src 192.168.19.1 
    cache 
root@Helium ~ # ping 192.168.19.40
PING 192.168.19.40 (192.168.19.40) 56(84) bytes of data.
64 bytes from 192.168.19.40: icmp_seq=1 ttl=64 time=0.181 ms

However, UDP packets incoming from eth0 are not forwarded:

root@Helium ~ # tcpdump -i eth0 udp port 52220
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
20:36:15.425602 IP <reverse_hostname_of_my_home>.19834 > Helium.52220: UDP, length 160
20:36:23.621066 IP <reverse_hostname_of_my_home>.19834 > Helium.52220: UDP, length 160
^C
2 packets captured
2 packets received by filter
0 packets dropped by kernel
root@Helium ~ # tcpdump -i untrusted-vm-br udp port 52220
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on untrusted-vm-br, link-type EN10MB (Ethernet), capture size 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

I have similar port redirections for TCP ports, which all work as expected.

What am I doing wrong? Is there something specific to UDP I missed?


Additional debugging information:

IPv4 forwarding is enabled:

root@Helium ~ # cat /proc/sys/net/ipv4/ip_forward
1

Using iptables -v shows that no packet matched my iptable rule:

root@Helium ~ # iptables -L -v -t nat
Chain PREROUTING (policy ACCEPT 9680 packets, 612K bytes)
 pkts bytes target     prot opt in     out     source               destination         
[...]
    0     0 DNAT       udp  --  eth0   any     anywhere             anywhere             udp dpt:52220 to:192.168.19.40

I tried using iptables -j LOG:

iptables -t nat -A PREROUTING -p udp -j LOG --log-prefix "[iptables log udp]"

Which gives:

Aug 10 17:01:33 Helium kernel: [1824208.192607] [iptables log udp]IN=eth0 OUT= MAC=<mac_address_of_my_eth0> SRC=<ip_address_of_my_home> DST=<ip_address_of_eth0> LEN=188 TOS=0x00 PREC=0x00 TTL=51 ID=1476 DF PROTO=UDP SPT=19834 DPT=

Linux/iptables version:

root@Helium ~ # uname -a
Linux Helium 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u3 (2016-07-02) x86_64 GNU/Linux
root@Helium ~ # iptables --version
iptables v1.4.21
Valentin Lorentz
  • 197
  • 2
  • 14
  • I don't really know, but have you tried adding a port to you --to-destination? Also, do you have an allow rule for the specific original destination, port and udp in your FORWARD table? – madeddie Aug 11 '16 at 00:07
  • @madeddie 1. No. But it started working after a few hours, without touching anything… so I guess that was not the issue. 2. yes, ACCEPT by default for all chains. – Valentin Lorentz Aug 11 '16 at 07:15
  • hmm, problems that fix themselves after some time without specific reason are annoyingly hard to debug. – madeddie Aug 11 '16 at 07:18

1 Answers1

3

After spending a several hours trying to fix this, I put the machine sending the UDP packets to sleep for the night.

When I woke up I started the process again, and packets were going to the VM as expected. I already tried to restart the sending process before, so it's not just that. Maybe the pausing the packets for a long time…

So, magic, I guess.

Valentin Lorentz
  • 197
  • 2
  • 14