Incorrect source address, per-process routing

Linux Advanced Routing and Traffic Control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello, please excuse the length of my question, and I hope that this is
an appropriate place to ask.

I have a workstation that has two interfaces connected to two private
networks, 192.168.0.0/24 and 192.168.1.0/24, each of which has a
separate masquerading gateway to the internet, something like as follows:

            +-----------> to internet
            |
         router0
       192.168.0.1
            |
            |
      192.168.0.100
    +-----<eth0>----+
    |               |
    |  Workstation  |
    |               |
    +-----<eth1>----+
      192.168.1.100
            |
            |
       192.168.1.1
         router1
            |
            +-----------> to internet


I want to control which traffic to/from processes running on the
workstation uses which interface (i.e. outbound path to internet) on a
process-by-process basis, without the cooperation of the program (i.e.
rather than having the program bind to a particular local interface,
when I start a program I want to be able to choose one or the other
interface, and have all of that process's traffic get routed through
that interface).

My idea of how to accomplish this (I'm open to alternate suggestions) is
to set up a default route via one gateway, e.g. router0, then a
designated group-ID via the iptables 'owner' match module to mark
packets from processes owned by a user in that group, and use the
iproute2 tables to route those packets via the other gateway (router1). 
(it seems that ipt_ROUTE is frowned upon and I've never been able to get
it to work anyhow.)  So, after each interface is up on its sub-net and
the default route is set, my commands are like this:

iptables --table mangle --append OUTPUT --match owner --gid-owner
alt-route-group -j MARK --set-mark 1
ip rule add fwmark 1 pref 10001 table 100
ip route add default via router1 table 100

It's not a very elegant solution, but it seems like it should work; yet
I have a problem: when I run a program sudo'd to the designated
user/group, its traffic does indeed get matched, marked, and exits via
the "alternate" interface (eth1), bound for the alternate gateway
(router1), but when I examine by sniffing the interface, I find that the
packets' source IP address is that of the default interface (eth0,
192.168.0.100).  Of course this prevents proper routing of any return
packets.

I tried forcing the source-address in the routing table entry with 'src':
    ip route add default via router1 dev eth1 src 192.168.1.100 table 100
But it still showed the source as 192.168.0.100 (eth0's address), even
though the packet exited via eth1, and I verified that their destination
ethernet address is bound for router1.

So I wonder if anyone knows what's wrong?  I would also be interested in
other suggestions for how to do per-process routing (but I'd like to get
this approach working even if I abandon it).  Any help is greatly
appreciated.

My tables:

    ~ # iptables --table mangle --list OUTPUT
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    MARK       all  --  anywhere             anywhere            OWNER
GID match alt-route-group MARK set 0x1

    ~ # ip rule show
    0:      from all lookup local
    10001:  from all fwmark 0x1 lookup 100
    32766:  from all lookup main
    32767:  from all lookup default

    ~ # ip route show table main
    192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.100
    192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.100
    169.254.0.0/16 dev eth0  scope link
    default via 192.168.0.1 dev eth0

    ~ # ip route show table 100
    default via 192.168.1.1 dev eth1  src 192.168.1.100


The command:
    ~ # sudo -u alt-route-user ping google.com
    PING google.com (64.233.187.99) 56(84) bytes of data.

    --- google.com ping statistics ---
    4 packets transmitted, 0 received, 100% packet loss, time 3010ms
    /tmp #


Produces the trace:
    ~ # tshark -n -i eth1 icmp
    Capturing on eth1
      0.000000 192.168.0.100 -> 64.233.187.99 ICMP Echo (ping) request
      1.009611 192.168.0.100 -> 64.233.187.99 ICMP Echo (ping) request
      2.009777 192.168.0.100 -> 64.233.187.99 ICMP Echo (ping) request
      3.013895 192.168.0.100 -> 64.233.187.99 ICMP Echo (ping) request
    4 packets captured
    ~ #

Thanks in advance,
David

_______________________________________________
LARTC mailing list
LARTC@xxxxxxxxxxxxxxx
http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc

[Index of Archives]     [LARTC Home Page]     [Netfilter]     [Netfilter Development]     [Network Development]     [Bugtraq]     [GCC Help]     [Yosemite News]     [Linux Kernel]     [Fedora Users]
  Powered by Linux