Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

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 redirect all local connections with destination matchs port 22 to specified tunnel using iptables MARK, but, something is going wrong. my public address tunnel public address my local tunnel address

Here the configs:

# ip rule show 
1:      from all fwmark 0x14 lookup 20 

# ip route show table 20 
default via dev tun0

And I have created following rules on iptables:

iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 20 
iptables -t mangle -A OUTPUT -s -j MARK --set-mark 20

And when I try to ssh some server(dreamhost in this case) I get:

tcp      6 299 ESTABLISHED src= dst= sport=37152 dport=22 packets=4 bytes=221 src= dst= sport=22 dport=37152 packets=2 bytes=133 [ASSURED] mark=0 secmark=0 use=2

Packet is not getting marked and going out through default route, which is

I don't know what I'm doing wrong..

Anyone have any idea??

share|improve this question

mangle's PREROUTING is for altering incoming packets before routing and OUTPUT for altering locally-generated packets before routing. Hence PREROUTING is needless (for local connections). But OUTPUT should have worked, though. You don't need to specify source address in firewall rules usually, since it would be "locally-generated packets" anyway.

And another thing to remember is no-one gonna change source IP just due to you've marked the packet and it would be routed with another route table — you'd need to use NAT explicitly for that. In terms of Linux' iptables it has to be SNAT. And "This target is only valid in the nat table, in the POSTROUTING chain", as the man says. Although I personally prefer its subspecies MASQUERADE which is more handy for that, cause you don't have to bother with IP-addresses hard coding.

share|improve this answer
I've tryed -A OUTPUT -p tcp --dport 22 -j MARK --set-mark 20 and now I got timed out. Looks like I really need SNAT, but I don't understand cleary why! – user158720 Feb 13 '13 at 11:07
Since the difference is GRE adding a Header to each packet who leaves through this interface. And in fact, source address is the and destination another edge) and inside the GRE packet we have the original source and destination. So why these marks are not working? – user158720 Feb 13 '13 at 11:14
It has nothing to do with GRE in particular and encapsulation in general. It's just another route set, and that's it. SNAT has to be used due to IP packet had been already filled up and TCP/IP stack didn't use any policy routing when doing that. – poige Feb 13 '13 at 21:02

Your Answer


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

Not the answer you're looking for? Browse other questions tagged or ask your own question.