tags:

views:

3483

answers:

6

Is it possible to change the destination port of a UDP packet using iptables?

I'm trying to get an SNMP agent to send out traps on 1620 instead of 162. Unfortunately so far I've only managed to change the source port:

iptables -t nat -A POSTROUTING -p udp --dport 162 -j SNAT --to :1620

+1  A: 

Instead of making SNAT, try with DNAT. The source port gets changed because SNAT means SourceNAT, so DNAT will work for you.

azkotoki
to get DNAT to work you would need to specify an ip-address as --to-destination
PiedPiper
That wouldn't be much of a problem in this case, but a DNAT rule doesn't seem to work either. The rule isn't hit and the packets sent out are not modified.
Kristof Provost
You cannot use DNAT on a POSTROUTING chain. http://iptables-tutorial.frozentux.net/iptables-tutorial.html#DNATTARGET
borodimer
Thanks for the advice @borodimer. The rule must be placed in PREROUTING if the packets come from the outside, and in OUTPUT if they are generated locally.
azkotoki
A: 

@PiedPiper was right. With DNAT you must specify an ip address, but we only want to do port redirection, so -j REDIRECT may work in this case.

See http://www.netfilter.org/documentation/HOWTO//NAT-HOWTO-6.html#ss6.2

azkotoki
If I read that right redirect will send the packet to port 1620 on the local machine. I want it to go to the destination listed in the packet, but on port 1620 instead of 162.
Kristof Provost
Yes, I didn't read that on the first time. Sorry.
azkotoki
A: 

Assuming you know which machine you are sending to:

iptables -t nat -A OUTPUT -p udp --dport 162 -j DNAT --to-destination <dest-ip>:1620
PiedPiper
This causes my iptables to complain: "iptables: Invalid argument"
Kristof Provost
It works for me. You are replacing <dest-ip> with a real ip address?
PiedPiper
borodimer
I have kernel 2.6.10 and iptables v1.3.3
Kristof Provost
I have kernel 2.6.26 and iptables 1.4.1 but it should work with older versions.
PiedPiper
A: 

You could set up a divert rule and then re-inject the packet with the modified port.

I've done this a while back on Mac OS X but it's the same principle on Linux: http://blog.dv8.ro/2006/08/using-divert-sockets-on-mac-os-x.html

You basically need to create a very simple transparent proxy.

diciu
+1  A: 

This usage is apparently not supported. Taken from http://www.netfilter.org/documentation/HOWTO/NAT-HOWTO.txt:

6.3.7. Altering the Destination of Locally-Generated Connections

The NAT code allows you to insert DNAT rules in the OUTPUT chain, but
this is not fully supported in 2.4 (it can be, but it requires a new
configuration option, some testing, and a fair bit of coding, so unless someone contracts Rusty to write it, I wouldn't expect it soon).

The current limitation is that you can only change the destination to
the local machine (e.g. `j DNAT --to 127.0.0.1'), not to any other machine, otherwise the replies won't be translated correctly.

Adam Liss
Doesn't that redirect to port 1620 on the local machine? This seems to be the same recommendation as askotoki gave.
Kristof Provost
You're right ... I dug a bit deeper and found the above info.
Adam Liss
A: 

you could redirect 162 to 1620

iptables -t nat -A PREROUTING -p UDP --dport 162 -j REDIRECT --to-port 1620