Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to accomplish the following: I have a box with a service listening on a dummy interface (say, udp port 5555. Now what I'd like to do is to take packets that arrive on interfaces eth0 ( and eth1 ( and forward them to the service on the dummy interface, and have replies go back to clients out the same physical interface they came in. Clients must think they're talking to or I think I need a mix of iptables rules and packet marking, plus some iproute rules (if it's possible at all). What I tried is to catch packets coming in from eth0 and eth1, udp port 5555, and mark them with 1 and 2 respectively, and --save-mark in the connmark. Then I used a DNAT to The service seems to be getting the packets. Now I'm not sure how to do the reverse. It seems that for packets originating from the box, you can't do anything before the routing decision, but that would be the place to restore the marks, and thus make a routing decision based on those. Here's what I have so far:

iptables -t mangle -A PREROUTING -d -p udp --port 5555 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -d -p udp --port 5555 -j MARK --set-mark 2

iptables -t mangle -A PREROUTING -d -p udp --port 5555 -j CONNMARK --save-mark
iptables -t mangle -A PREROUTING -d -p udp --port 5555 -j CONNMARK --save-mark

iptables -t nat -A PREROUTING -m mark --mark 1 -j DNAT --to-destination
iptables -t nat -A PREROUTING -m mark --mark 2 -j DNAT --to-destination

# What next?

As I said, I'm not even sure it can be done. To give a bit of background, it's an old OpenVPN installation that cannot be upgraded (otherwise I'd install a recent version that supports multihoming natively).

Thanks for any help.

share|improve this question

Have you tried just using straight NAT (via the REDIRECT target) to do this? Conntrack should take care of the return packets, no need for manual marking.

share|improve this answer

I think I kind of got it working, here's what I did in case it might be useful to somebody else in the future:

iptables -t mangle -A PREROUTING -i eth0 -d -p udp --dport 5555 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth1 -d -p udp --dport 5555 -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i eth0 -p udp --dport 5555 -j CONNMARK --save-mark
iptables -t mangle -A PREROUTING -i eth1 -p udp --dport 5555 -j CONNMARK --save-mark

# nat PREROUTING comes after mangle PREROUTING
iptables -t nat -A PREROUTING -m mark --mark 1 -j DNAT --to-destination
iptables -t nat -A PREROUTING -m mark --mark 2 -j DNAT --to-destination

# restore mark from packets originating from, as it triggers a new routing decision
iptables -t mangle -A OUTPUT -s -p udp --sport 5555 -j CONNMARK --restore-mark

ip rule add prio 20 fwmark 1 lookup upstream0
ip rule add prio 21 fwmark 2 lookup upstream1

OpenVPN is bound to only (assigned to interface dummy0), and gets all traffic that clients send to or

share|improve this answer

I don't see how that could help:

It redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface

Incoming packets are already addressed to the address of the incoming interface (ie or Or maybe I didn't understand what you mean, apologies in that case.

I forgot to add, if that solution seems overkill, it's because I tried the simpler one first, ie having the service listen on and using packet marking, but again I don't see where to restore the marking for locally-generated UDP packets.

If I switch to TCP everything works correctly even without the need of marking (not sure why exactly); I still need source-base routing rules of course, but then it "just works". I'll probably switch to TCP if I'm not able to make it work using UDP (although TCP has worst performance). My guess about why TCP works and UDP doesn't is because UDP/IP packets do not have a source address set when hitting the routing decision, so the address is "filled in" after the routing, which will select either the default route, or a random route in a multipath group, and that won't match the original incoming interface (or it will, but only by accident). On the other hand, TCP/IP packets already have a source address (and it is the right one) when they reach the routing phase, so source-based routing rules can be used. This is just a guess, if somebody spots some mistake I'm more than happy to stand corrected.

Thank you.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.