6

I have a php / bash application on top of a Linux machine with 1 physical interface connecting to e.g., outbound webserver 123.123.123.123 :80. I do this via several openvpn providers. I have both tun and tap providers, but my favorite provider uses tun.

Actually I'm perfectly able to serially:

  1. open the vpn
  2. sudo route add 123.123.123.123 tun0
  3. send traffic to 123.123.123.123 :80
  4. close the vpn
  5. sudo route del 123.123.123.123

I use the "route-nopull" option inside the .ovpn config file in order to keep the Linux machine reachable and allow simultaneous openvpn connections.

Now I need to open several independent requests, always to outbound webserver 123.123.123.123 :80. But my actual flow is serial and I need to wait the first connection to close and clear itself before attempting a second connection.

I'm quite sure that I can achieve it mangling with "fake ports". Eg:

  • interfaces tun0, tun1, tun2
  • fake ports 9000, 9001, 9002
  • multiple routing tables rt0, rt1, rt2

So conceptually speaking:

  • 123.123.123.123:9000 -> mark for rt0 (tun0 is default gateway) -> rewrite as 123.123.123.123:80 -> rt0
  • 123.123.123.123:9001 -> mark for rt1 (tun1 is default gateway) -> rewrite as 123.123.123.123:80 -> rt1
  • 123.123.123.123:9002 -> mark for rt2 (tun2 is default gateway) -> rewrite as 123.123.123.123:80 -> rt2

I can only represent the concept because I have almost no skills on iptables. If you have different ways to achieve the result, they're welcome. Thank you for reading and helping.

5
  • Did you just try to perform (1) for different connections. I would expect to see tun0, tun1 etc. then and you can then use these for routing.
    – Harald
    Commented Oct 28, 2015 at 11:37
  • Do you mean if I -beyond the concepts- successfully established several connections, thus resulting in having simultaneously tun0 tun 1 tun2 etc etc active and running but not selectable (because of route-nopull)? Yes, I have them ready in place and can send traffic "one by one" following the 5 steps above.
    – fab
    Commented Oct 28, 2015 at 12:38
  • Uuuh, now I see: you really want to always reach the same target host. It was no accident that you always use 123.123.123.123 as the target. This may help:unix.stackexchange.com/q/21093/140503
    – Harald
    Commented Oct 28, 2015 at 13:50
  • Exactly (i edited my question). I found that answer you suggest first to ask here and it's quite close. But it's still a different situation and the buddy did some previous configs, so exact overall instructions are missing.
    – fab
    Commented Oct 28, 2015 at 15:03
  • I documented my progresses here unix.stackexchange.com/questions/240091/…
    – fab
    Commented Nov 1, 2015 at 14:04

1 Answer 1

9

I solved and documented it here: http://aftermanict.blogspot.it/2015/11/bash-iptables-iproute2-and-multiple.html

This will make the kernel permanently route packets, enables multiple routes and even for networks not attested on the machine:

nano /etc/sysctl.conf

net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
net.ipv4.ip_forward = 1

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 >| $f ; done

This will initialize iptables and in particular mangle and nat, which are needed for marking the traffic:

iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

add the alternative routes editing:

nano /etc/iproute2/rt_tables

Add (names are your references):

1 tunnel0
2 tunnel1

add routes and rules, we use tables IDs instead of names which are more immediate. As you can notice, the gateway is irrelevant, especially for tunnels which can have dynamic gateways:

ip route add 0.0.0.0/0 dev tun0 table 1
ip route add 0.0.0.0/0 dev tun1 table 2

add rules to mark traffic and bind to the corresponding table:

ip rule add from all fwmark 1 table 1
ip rule add from all fwmark 2 table 2
ip route flush cache

check if you like:

ip route show table 1
ip route show table 2
ip rule show

if you miss something, you can delete this way:

ip rule del table 1
ip route flush table 1

NOW THE MISSING PART: THIS WONT WORK:

iptables -A PREROUTING -t mangle -p tcp --dport 80 -j MARK --set-mark 1

THIS WILL:

iptables -A OUTPUT -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables-save

Do you need to select traffic and push it simultaneously in a device / tunnel? No problem, I solved this too:

iptables -A OUTPUT -t mangle -p tcp --dport 10001 -j MARK --set-mark 1
iptables -A OUTPUT -t mangle -p tcp --dport 10002 -j MARK --set-mark 2
iptables -t nat -A OUTPUT -p tcp --dport 10001 -j DNAT --to :80
iptables -t nat -A OUTPUT -p tcp --dport 10002 -j DNAT --to :80

NAT mandatory for reply

iptables -t nat -A POSTROUTING -o $DEV1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o $DEV2 -j MASQUERADE

iptables-save
2
  • 1
    Thanks for posting your answer but please don't post answers linking to external resources. Instead, include the information here as I did above.
    – terdon
    Commented Nov 7, 2015 at 18:18
  • This helped me in 2023. You are great! Commented Aug 21, 2023 at 3:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .