Bug 140654 - ifup-ipsec attempts to set incorrect route
ifup-ipsec attempts to set incorrect route
Status: CLOSED RAWHIDE
Product: Fedora
Classification: Fedora
Component: initscripts (Show other bugs)
3
All Linux
medium Severity medium
: ---
: ---
Assigned To: Bill Nottingham
Brock Organ
:
: 128208 (view as bug list)
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2004-11-23 19:17 EST by Tyler Larson
Modified: 2014-03-16 22:50 EDT (History)
8 users (show)

See Also:
Fixed In Version: 8.06-1
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2005-03-28 15:52:16 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Patch to add/remove routes (1.75 KB, patch)
2005-03-28 15:51 EST, Bill Nottingham
no flags Details | Diff

  None (edit)
Description Tyler Larson 2004-11-23 19:17:27 EST
Description of problem:

lines 140 and 194 of ifup-ipsec contain the command:
'ip route add to $DSTNET via $DST' which is incorrect. Traffic routed
over the VPN needs to be routed through the address which serves
as the local (internal) endpoint to the VPN, rather than $DST, which
is the external address of the remote endpoint.

Version-Release number of selected component (if applicable):


How reproducible:
always

Steps to Reproduce:
1. ifup <your ipsec vpn>
  
Actual results:
route addition fails, VPN is usually non-functional.
Comment 1 Tyler Larson 2004-11-23 19:19:59 EST

I managed to make the script work correctly by replacing the offending
line with:
ip route add to $DSTNET via $SRCGW
where $SRCGW is a variable set by system-config-network, but
apparently unused by ifup and ifdown. This may not be the approprate
use of $SRCGW, since it isn't clear what that variable is actually
used for.



The following ASCII art should help explain what needs to be fixed:

  Net 1         Host1      Internet        Host 2      Net 2
-----------\  +------+  /--------------\  +------+  /-----------\
10.1.0.0/16 --=A    B=--    X.X.X.X     --=C    D=-- 10.2.0.0/16 |
-----------/  +------+  \--------------/  +------+  \-----------/
                  |                           |
                  +------- IPsec Tunnel ------+

Where Host 1 and Host 2 are IPsec tunnel endpoints which join Net 1
and Net 2 across the hostile Internet. Interface IPs are as follows:

A: 10.1.0.1
B: 1.2.3.4
C: 4.5.6.7
D: 10.2.0.1

The IPsec tunnel goes from 10.1.0.1 to 10.2.0.1. Therefore, Host 1
needs to route traffic going to 10.2.0.0/16 through 10.1.0.1.

The current scripts attempts to add the route:
10.2.0.0/16 via 4.5.6.7
when it should add the route
10.2.0.0/16 via 10.1.0.1

In fact, the script as it is causes the route addition to fail with
the response "RTNETLINK answers: Network is unreachable", since you
can't route through an IP that isn't on your broadcast network.

The solution I've used (using $SRCGW) seems suboptimal and
error-prone, as it requires the user to supply the required values. A
possible way to retrieve the needev value would be to parse the result
of the command:
ip route get $SRCNET

Comment 2 Bill Nottingham 2005-01-25 14:52:36 EST
*** Bug 146169 has been marked as a duplicate of this bug. ***
Comment 3 Douglas E. Warner 2005-02-25 14:46:02 EST
I seem to be suffering from the same problem. This seems similar to 
bug#126646, but from the comments it isn't clear how he worked his 
config out to bring the tunnel up. 
Comment 4 Bill Nottingham 2005-03-10 18:09:18 EST
Actually, looking at this again, I'm not convinced the route needs to
be set at all. If you just remove the 'ip route add...' does it work?
Comment 5 Bill Nottingham 2005-03-10 18:09:55 EST
*** Bug 128208 has been marked as a duplicate of this bug. ***
Comment 6 Tyler Larson 2005-03-10 19:28:03 EST
When I tested it before, it would not work without the route. The
reason for that was that it would try to send the packet the "normal"
way without using the IPSec tunnel. I.e., it would send the packet for
10.2.1.1 to my default gateway.

Admittedly, telling it to route through its local interface looks and
smells a lot like a hack--it shouldn't be necessary since the kernel
already has all the routing information it needs. Adding the route
seems to trigger it to follow the correct behavior.

It may have been fixed in more recent kernels, I don't know. All of my
IPSec endpoints are on production machines, so testing out theories is
out of the question where I work.

In order to test any theories properly, though, you need two IPSec
endpoints on different networks at least, I think.
Comment 7 Bill Nottingham 2005-03-10 19:43:47 EST
You wouldn't happen to have (or had):

net.ipv4.conf.default.rp_filter = 1

in /etc/sysctl.conf, would you?
Comment 8 Trevor Cordes 2005-03-10 21:28:38 EST
I do the same thing that the RH ipsec scripts do, but I do it
manually.   My setup needs the route or it doesn't work.  It makes
sense if the 2 networks you are VPN'ing are non-routable private IP
spaces (192.168.*, 10.*), doesn't it?

I just ip route del'd the routes on my 2 test boxes and instantly I
can no longer ping the other side's network.  Add the routes and
instantly it works again.

I remember that when I used to use freeswan, it too added its own
routes in order to function (but it did it automatically for you).
Comment 9 Bill Nottingham 2005-03-10 22:16:17 EST
The reason I asked is because I've tested without the route between
disparate networks, and it works for me; the key was turning off
rp_filter.
Comment 10 Trevor Cordes 2005-03-11 02:09:08 EST
echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter

on both systems and now, yes, it does work without the route present.

Now I'll have to go research what the heck rp_filter means and why it
was on by default and what it will mean if I have it off!  Perhaps
having an extra route in there isn't too bad a solution?

Yes, it was set to 1 in /etc/sysctl.conf, but I don't ever remember
changing it so it must be the RH default?
Comment 11 Bill Nottingham 2005-03-11 11:48:53 EST
rp_filter - BOOLEAN
        1 - do source validation by reversed path, as specified in RFC1812
            Recommended option for single homed hosts and stub network
            routers. Could cause troubles for complicated (not loop free)
            networks running a slow unreliable protocol (sort of RIP),
            or using static routes.

        0 - No source validation.

        conf/all/rp_filter must also be set to TRUE to do source
validation
        on the interface

        Default value is 0. Note that some distributions enable it
        in startup scripts.

...

Yes, it's set this way as RH default, because it's better for end-user
machines (much like ip_forward.)

I suppose it could be argued that tunnel mode should automatically
turn this (and ip_forwarding) on. I'll check with the networking gurus
which is preferred.
Comment 12 Trevor Cordes 2005-03-15 15:50:37 EST
Do you know what section of RFC1812 specifically talks about
rp_filter?  I've found lots of stuff in there about validation and rp
but nothing about an "rp filter" and the docs above seem opposite to
what the RFC describes (option value is inverted?).

Why does it work with no static route when rp_filter=1??  Doesn't it
make sense that rp_filter=1 would drop the packets and rp_filter=0
would let them through?  It seems reversed to me.

Do I lose or gain any useful security on my FC firewall/router by
[en|dis]abling rp_filter?
Comment 13 Bill Nottingham 2005-03-15 15:54:47 EST
Actually, what I would expect is that it would *require* rp_filter=0
to work.

But adding the routes is probably simpler.
Comment 14 Bill Nottingham 2005-03-15 15:58:32 EST
To clarify, I was asking if you had rp_filter=1, because in that case,
I would expect the route to be needed.
Comment 15 Trevor Cordes 2005-03-15 16:12:11 EST
OK, now I am completely lost.  I reread the entire bug and reran some
tests and now nothing makes sense.

On my test setup I tried changing all/rp_filter, default/rp_filter
*and* eth0/rp_filter and eth1/rp_filter on the fly first to all 0 then
to all 1.  I deleted my static route.

Now for all my tests the route seems unnecessary?!?  I can ping
network-to-network no matter what I set rp_filter to -- without any
static route?!?!

Does this make any sense?  I verified those values with cat and
verified the route was gone with ip route show.  Once you change these
values, do you have to reboot or ifdown/ifup to make them take effect?
Comment 16 Bill Nottingham 2005-03-15 16:40:09 EST
I saw the same behavior at one point; it didn't work, I turned
rp_filter off; it worked, I turned it back on, it *still* worked.

Comment 17 Trevor Cordes 2005-03-20 20:26:03 EST
Should that be opened as a separate bug?  If the kernel is not obeying rp_filter
settings on the fly, that may even be considered a security bug?

At the very least, it makes testing and diagnosing this bug's issue quite difficult!
Comment 18 Bill Nottingham 2005-03-28 15:49:26 EST
I'm adding the attached in CVS. As to the rp_filter issue, the network
maintainer says that's probably the route cache kicking in, and he suggests that
using routes, as opposed to messing with rp_filter, is the proper solution.
Comment 19 Bill Nottingham 2005-03-28 15:51:06 EST
Created attachment 112400 [details]
Patch to add/remove routes
Comment 20 Bill Nottingham 2005-03-28 15:52:16 EST
Should be in 8.06-1.

Note You need to log in before you can comment on or make changes to this bug.