LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Networking
User Name
Password
Linux - Networking This forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.

Notices


Reply
  Search this Thread
Old 05-08-2011, 03:40 PM   #1
Thireus
LQ Newbie
 
Registered: May 2011
Posts: 1

Rep: Reputation: 0
Question Route eth2 TCP packets to tun0 with IPTABLES & IP RULE/ROUTE


Hi everyone,

I have 3 network interfaces on my Linux Router :

Interface - Gateway - Type

Code:
br0 - 192.168.0.1 - Internet
eth2 - 192.168.1.1 - LAN
tun0 - 10.0.0.2 - VPN (via br0)
What I'd like to do is to route all TCP packets coming from eth2 to tun0 where a VPN client is running on 10.0.0.2.

If I delete all default routes and if I add a new route to tun0 like :

Code:
route del default
route add default gw 10.0.0.2
Everything is fine, and everyone on eth2 can reach the Internet using the VPN access.

----

Now the problem is that my VPN client does not allow any other protocols other than TCP. And I also want to allow VPN access only to eth2, no other LAN nor the router itself.

So the idea is to use iptables to filter any TCP packets and mark them, so they can be sent to tun0, while any other packets can reach the Internet via br0 (192.168.0.1).

I found on the Internet that we can mark packets before they get routed. Using the following commands :

Code:
iptables -t mangle -A PREROUTING -j MARK --set-mark 85 -i eth2 -p tcp --dport 80
ip route add table 300 default via 10.0.0.2 dev tun0
ip rule add fwmark 0x55 table 300
First of all, --dport 80 never work... :/ I wanted to filter TCP 80 packets coming from eth2, but none of them seems to be HTTP packets... oO (very strange...). Nevermind, I decided to forget about the --dport option.

I use the "iptables -L -v -t mangle" command to see how many packets are marked, and it is working fine, all TCP packets coming from eth2 are marked.

Now the problem is that none of them are routed to tun0 they are all respecting the "route -n" rules... and not the "table 300" rule I have created.

Can anyone help me on that point or tell me what's wrong with what I'm trying to achieve ?
 
Old 05-09-2011, 04:07 AM   #2
ambrop7
Member
 
Registered: May 2011
Distribution: Gentoo
Posts: 98

Rep: Reputation: 16
Considering your config, it has a problem that the your ip rule overrides the "main" routing table entirely, rather than only the default gateway - regardless, it should still work, given that "ip rule" by default inserts the rule after the "local" routing table (which is managed automatically).

I have also attempted to achieve the same thing, but with no success yet. It seems to be a bug in the "fwmark" match for "ip rule". Here's what I've put together so far:
Code:
# Select numbers for special routing tables. Append to /etc/iproute2/rt_tables:
256     tcp_tun2socks
257     real_default

# Remove default route from the main routing table.
route del default

# Add the default route which was removed to the real_default routing table.
# This will allow us to conditionally override the default route via "ip rule".
ip route add table real_default to default via 192.168.111.1

# Add the tun2socks default route to the tcp_tun2socks table.
ip route add table tcp_tun2socks to default via 10.0.0.2

# Set routing table decision rules: after consulting the main table (which now has no default route),
# consult table tcp_tun2socks if the packet is marked, else consult the real_default table which has
# the "default" default route.
ip rule add prio 40000 fwmark 0x100/0x100 lookup tcp_tun2socks
ip rule add prio 40001 lookup real_default

# At this point everything should work as before - only instead of having the default route in the
# main table, we have it in the real_default table, which is consulted after the main table. There is also
# a rule to consult the tcp_tun2socks table, but it has no effect since we haven't maked any packets with iptables.

# "ip rule list" output:
0:      from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 
40000:  from all fwmark 0x100/0x100 lookup tcp_tun2socks
40001:  from all lookup real_default

# "ip route show table main" should print the main routing table, which does not include any default route.

# "ip route show table tcp_tun2socks" output:
default via 10.0.0.2 dev tun0

# Mark TCP packets with iptables.
iptables -t mangle -A PREROUTING -p tcp -j MARK --or-mark 0x100

# This *should* work, but for some reason, on my system, the rule "prio 40000 fwmark 0x100/0x100 lookup tcp_tun2sock"
# is never matched, and the default route from the real_default table is used. This appears to be a problem with the
# fwmark match - if I do not include the fwmark match in the rule, the rule works and overrides the default route.
# I have also verified that the iptables rule is being matched. And it's not a problem that I'm or-ing the mask and checking
# a single bit later - setting and checking it in whole doesn't work too.
 
Old 05-09-2011, 08:32 AM   #3
afrorobot
LQ Newbie
 
Registered: Jun 2008
Distribution: Fedora 14
Posts: 10

Rep: Reputation: 0
Have you tried omitting the "dev" statement from "ip route add table 300 default via 10.0.0.2 dev tun0" and just give it the gateway IP?

- Tait
 
Old 05-09-2011, 08:54 AM   #4
ambrop7
Member
 
Registered: May 2011
Distribution: Gentoo
Posts: 98

Rep: Reputation: 16
Quote:
Originally Posted by ambrop7 View Post
I have also attempted to achieve the same thing, but with no success yet.
The above should in fact work fine, but for forwarded packets only. To work for local connections as well, the following can be done:

Code:
# Mark output packets too.
iptables -t mangle -A OUTPUT -p tcp -j MARK --or-mark 0x100
# Disable reverse path filter on tun0.
echo 2 > /proc/sys/net/ipv4/conf/tun0/rp_filter
 
Old 05-09-2011, 12:38 PM   #5
ambrop7
Member
 
Registered: May 2011
Distribution: Gentoo
Posts: 98

Rep: Reputation: 16
Quote:
Originally Posted by ambrop7 View Post
The above should in fact work fine, but for forwarded packets only.
Turns out that the reverse path filter needs to be turned off for forwarding to work too. So, the complete procedure could be as follows (tested for both fowarding and local traffic):

Code:
# Select numbers for special routing tables. Append to /etc/iproute2/rt_tables:
256     tcp_tun2socks
257     real_default

# Remove default route from the main routing table.
route del default

# Add the default route which was removed to the real_default routing table.
# This will allow us to conditionally override the default route via "ip rule".
ip route add table real_default to default via 192.168.111.1

# Add the tun2socks default route to the tcp_tun2socks table.
ip route add table tcp_tun2socks to default via 10.0.0.2

# Set routing table decision rules: after consulting the main table (which now has no default route),
# consult table tcp_tun2socks if the packet is marked, else consult the real_default table which has
# the "default" default route.
ip rule add prio 40000 fwmark 0x100/0x100 lookup tcp_tun2socks
ip rule add prio 40001 lookup real_default

# At this point everything should work as before - only instead of having the default route in the
# main table, we have it in the real_default table, which is consulted after the main table. There is also
# a rule to consult the tcp_tun2socks table, but it has no effect since we haven't maked any packets with iptables.

# "ip rule list" output:
0:      from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 
40000:  from all fwmark 0x100/0x100 lookup tcp_tun2socks
40001:  from all lookup real_default

# "ip route show table main" should print the main routing table, which does not include any default route.

# "ip route show table tcp_tun2socks" output:
default via 10.0.0.2 dev tun0

# "ip route show table real_default" output:
default via 192.168.111.1 dev eth0

# Mark TCP packets with iptables.
iptables -t mangle -A PREROUTING -p tcp -j MARK --or-mark 0x100

# Disable reverse packet filter for tun0.
# When a reply comes back from tun0 with source address S, the reverse packet filter checks "if I was to route a packet to address
# S, and it wouldn't go through tun0, I will drop the packet" - and because when doing this lookup there is no valid fwmark,
# it determines the route would be the usual default route, so it drops the packet.
echo 2 > /proc/sys/net/ipv4/conf/tun0/rp_filter

# If it is desired that local TCP goes through tun0 as well:
iptables -t mangle -A OUTPUT -p tcp -j MARK --or-mark 0x100
EDIT: added missing instructions

Last edited by ambrop7; 05-09-2011 at 12:47 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] IP Route UDP and TCP packets different interfaces howudodat Linux - Networking 2 09-22-2010 05:14 PM
How to set a route for Eth1 (DHCP clients) to reach Tun0 (openvpn server)? CentOS torontob Linux - Networking 2 09-22-2010 12:14 AM
[SOLVED] How do I route my internet traffic over tun0? FireRaven Linux - Networking 21 03-30-2010 04:38 PM
Route port 25 to interface eth2 ajaimes Linux - Networking 8 06-27-2007 02:39 AM
Route dialup modem packets back through dialup instead of default route cable modem jogress Linux - Networking 1 10-21-2003 03:48 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Networking

All times are GMT -5. The time now is 05:45 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration