# [solved] Redirect traffic from one interface to another

## Yuu

Hi,

i would like to have this setup : http://img521.imageshack.us/img521/1738/networkf.png. But i'm not a system adminstrator, just an standard IT student.

So, my server1 is reachable from : his own IP, and from vpn1, depending on the port. For this, I'm using iptables's set-mark to redirect force some services to go through VPN1.

At the moment, users are connected to vpn2 and are accessing internet from server1. I want my users to be connected to internet through vpn1, but by using vpn2. So, I want a kind of bridge between vpn1 and vpn2, on server1.

From server's side : eth0 is the interface directly connected to internet

tun0 is the interface to go through vpn1 : 10.16.3.0/24

tun1 is the interface used by vpn2's users : 10.8.0.0/24

The iptables rules for vpn2 are : 

```
iptables -D INPUT -p tcp --dport 444 -j ACCEPT        # opening port to allow users to connect to the vpn

iptables -D INPUT -i tun1 -j ACCEPT        # accepting connections to tun1 (vpn2)

iptables -D FORWARD -i tun1 -j ACCEPT        # accepting forwarding from, and to tun1 (vpn2)

iptables -D FORWARD -o tun1 -j ACCEPT

echo 0 > /proc/sys/net/ipv4/ip_forward        # enabling kernel forwarding

iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE        # re-routing all packets from 10.8.0.0/24 to get redirected to eth0
```

But with this, vpn2 users' are directly connected to the internet from server1, and are not using vpn1 ip.

I've tried changing POSTROUTING rule like : 

```
iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o tun0 -j MASQUERADE
```

To force packets going directly on vpn1, but it doens't seems to work.

I've also tried marking packets to force them using vpn1's route, but unsuccessfully : 

```
iptables -t mangle -D OUTPUT -p tcp --dport 80 -j MARK --set-mark 0x07

iptables -t nat -D POSTROUTING -o tun1 -j SNAT --to 10.16.3.12

iptables -t mangle -D OUTPUT -s 10.8.0.0/24  -j MARK --set-mark 0x07
```

Where 0x07 marked packets usually follow the vpn1's route (thanks to "ip rule add fwmark..etc"), and 10.16.3.12 is the obtained IP from vpn1.

I think it is possible with good iptable rules, but the level is too high for me. Also, I don't want to use br* interfaces, as I don't want to recompile my kernel just for that. Also, "user1, user2 and user3" doesn't exists from vpn2's point of view, so that's not possible with a bridge.

PS : sorry for my bad english, that's not my native language.

Any help would be greatly appreciated, thank you :]

----------

## truc

I don't exactly get what's your VPN1 but anyway... probably less messy than play with iptables for that, you could do some source routing

quick example:

```
ip route add default add defaull_gw_on_VPN1 table 200

ip rule add  from 10.8.0.0/24 table 200
```

You may also need to SNAT/MASQUERADE those packets, but  you should be able to figure this out.

The big question being do you know which IP you can use as being your derfault gw on VPN1?

----------

## Yuu

Thank you for you fast reply.

VPN1 is just a standard VPN used by my server1. From server1's side, some services are directly accessing internet, and some of them are going through the VPN1 tunnel. For this, I'm using my hand-made ugly initscript. Please don't make fun of it. I'm not a initscript expert : it's working and that's all I need.

I don't added this : 

```
ip route add default add defaull_gw_on_VPN1 table 200 
```

because I already have this :

```
ip route add default dev tun0 table 200
```

and I'm not using the vpn1's default gateway in this "ip route" line because I don't know how easly to get it (maybe on openvpn's log?).

But, yeah, it is working fine now ! Thank you truc, you're the best  :Very Happy:  !

Here are the commands to do this, if it can helps somebody : 

```
iptables -A INPUT -p tcp --dport 109 -j ACCEPT

iptables -A INPUT -i tun1 -j ACCEPT

iptables -A FORWARD -i tun1 -j ACCEPT

iptables -A FORWARD -o tun1 -j ACCEPT

echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

ip route add default dev tun0 table 200

ip rule add from 10.8.0.0/24 table 200
```

Thank you  :Smile: 

And as it seems to work fine, I'm adding the [solved] tag.

----------

## truc

Two things:

I tend to forgot the first one although I've already been bitten by it, set a priority to your rules:

for example, change this line:

```
ip rule add from 10.8.0.0/24 table 200
```

to this one:

```
ip rule add priority 100 from 10.8.0.0/24 table 200
```

Don't do routing per interface, this is just wrong, you'll certainly improve the tunnel overall performance by not doing it.

I don't know if you you can also modify you the VPN1 openvpn server, but if you do, you can use ccd (--client-config-dir)  so that your your server1 always get the same IP.

This way you could do proper routing as well as replace MASQUERADE in iptables'rules with a nice SNAT --to-source a.b.c.d rule

If you cannot modify the openvpn server, then parsing the log once should not be of an issue, but monitoring it for change in order to modify iptables rules is starting off becoming one   :Confused:  

----------

## Yuu

Thank you for your quick reply.

By folowing your good advices, I've added the priority to my route. How to set good priorities to my rules ? I mean, before, it was :  *Quote:*   

> # ip rule show
> 
> 0:	from all lookup local 
> 
> 32766:	from all lookup main 
> ...

 

And now, it is :  *Quote:*   

> # ip rule show
> 
> 0:	from all lookup local 
> 
> 100:	from 10.8.0.0/24 lookup VPN 
> ...

 

So, I have different priorities to my last two ip rules. But how should I know which rule should have a lower or better priority ?

 Okay, I'll try to route by ip instead of using dev <interface> but, at the moment, I'm still thiking about a better solution than monitoring openvpn's log. I just hope that this solution exists. Maybe I'll find a good and reliable solution someday.

For the SNAT thing instead of MASQUERADE, I'll use it. Also, I'll change my SNAT --to a.b.c.d to SNAT --to-source a.b.c.d, which seems to be a proper way (cf. my ugly initscript). By the way, iptables' manual is just showing "--to-source", and not "--to" for the SNAT target; so It must be it.

Oh, and I don't actually own VPN1 (so bad), so I can't modify VPN1's configuration.

----------

## truc

Are you sure you still need the rule from all fwmark 0x07 lookup VPN ? I don't think so

Also here is an example of why the priority can be important:

The behaviour with the following rules

```
ip rule show

0: from all lookup local

100: from 10.8.0.0/24 lookup VPN1

101: from all fwmark 0x07 lookup VPN2

32766: from all lookup main

32767: from all lookup default
```

can differ from these rules

```
ip rule show

0: from all lookup local

100: from all fwmark 0x07 lookup VPN2

101: from 10.8.0.0/24 lookup VPN1

32766: from all lookup main

32767: from all lookup default
```

HTH:)

----------

