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.
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
*** Bug 146169 has been marked as a duplicate of this bug. ***
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.
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?
*** Bug 128208 has been marked as a duplicate of this bug. ***
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.
You wouldn't happen to have (or had): net.ipv4.conf.default.rp_filter = 1 in /etc/sysctl.conf, would you?
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).
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.
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?
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.
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?
Actually, what I would expect is that it would *require* rp_filter=0 to work. But adding the routes is probably simpler.
To clarify, I was asking if you had rp_filter=1, because in that case, I would expect the route to be needed.
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?
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.
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!
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.
Created attachment 112400 [details] Patch to add/remove routes
Should be in 8.06-1.