Bug 150862 - Overlapping subnets on IPSEC tunnel match local traffic to ipsec policies
Overlapping subnets on IPSEC tunnel match local traffic to ipsec policies
Status: CLOSED RAWHIDE
Product: Fedora
Classification: Fedora
Component: initscripts (Show other bugs)
rawhide
All Linux
medium Severity high
: ---
: ---
Assigned To: Bill Nottingham
Brock Organ
:
Depends On:
Blocks: FC5Target
  Show dependency treegraph
 
Reported: 2005-03-11 09:47 EST by Steve Hill
Modified: 2014-03-16 22:52 EDT (History)
6 users (show)

See Also:
Fixed In Version: 8.36-1
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2006-07-21 14:29:07 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
Adds an override policy for traffic staying in SRCNET (1.35 KB, patch)
2005-03-11 09:49 EST, Steve Hill
no flags Details | Diff
ifdown-ipsec patch to complement the above ifup-ipsec patch. (351 bytes, patch)
2005-03-11 09:50 EST, Steve Hill
no flags Details | Diff
Revised ifup-ipsec patch (1.80 KB, patch)
2005-03-11 11:55 EST, Steve Hill
no flags Details | Diff
Revised ifdown-ipsec script (798 bytes, patch)
2005-03-11 11:59 EST, Steve Hill
no flags Details | Diff
ifup-ipsec "let user have full control" approach (2.27 KB, patch)
2005-05-18 11:51 EDT, Aleksandar Milivojevic
no flags Details | Diff
ifdown-ipsec "let user have full control" approach (838 bytes, patch)
2005-05-18 11:52 EDT, Aleksandar Milivojevic
no flags Details | Diff
ifup-ipsec "let user have full control" approach (3.19 KB, patch)
2005-05-18 12:44 EDT, Aleksandar Milivojevic
no flags Details | Diff
ifdown-ipsec "let user have full control" approach (1.20 KB, patch)
2005-05-18 12:45 EDT, Aleksandar Milivojevic
no flags Details | Diff
fix routes for overlapped networks (5.18 KB, patch)
2005-05-18 15:14 EDT, Aleksandar Milivojevic
no flags Details | Diff
Exclude SRCNET<->SRCNET traffic if SRCNET is a subnet of DSTNET (4.00 KB, patch)
2006-05-17 12:48 EDT, Miloslav Trmač
no flags Details | Diff

  None (edit)
Description Steve Hill 2005-03-11 09:47:13 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5)
Gecko/20041111 Firefox/1.0

Description of problem:
If the subnet at the remote end of an IPSEC tunnel overlaps the local
subnet the IPSEC policy matches local traffic too.  (This prevents
access to the local address of the machine).

It also has the more serious side effect that when sending a large
packet through the tunnel with the DF flag set, the generation of an
ICMP: Frag Needed packet which matches the policy triggers a kernel
bug, causing the kernel to hard-lock (I am discussing this kernel bug
with the netdev mailing list at the moment).

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

How reproducible:
Always

Steps to Reproduce:
1. Set the LAN-facing address of the machine to 10.0.0.1/16
2. Set up an IPSEC tunnel with SRCNET=10.0.0.0/16 and DSTNET=10.0.0.0/8
3. Try to connect to 10.0.0.1 from a machine on SRCNET - this matches
the policy and will be dropped since it isn't encrypted.
4. Connect from 10.0.0.1 to a machine on SRCNET - again, this will be
dropped.
5. From a machine on the SRCNET, send a packet to the DSTNET with the
DF flag set that is close to the MTU size (i.e. it will exceed the MTU
when encrypted) - the kernel will lock up hard with no error message.

Actual Results:  For steps 3 and 4 the traffic was dropped as it
matched the policy, despite being traffic on the local network instead
of traffic going over the tunnel.

For step 5 the whole kernel locks up with no error message - SysRq has
no effect, caps/numlock lights don't toggle when hitting the keys.  I
am discussing this kernel bug on the netdev list and will file another
bug for this part.

Expected Results:  Traffic between machines on the local network (i.e.
not going over the tunnel) should be accepted.

Additional info:
Comment 1 Steve Hill 2005-03-11 09:49:41 EST
Created attachment 111886 [details]
Adds an override policy for traffic staying in SRCNET

This patch resolves the bug by adding a policy for traffic staying within
SRCNET to override the policies requiring encryption.
Comment 2 Steve Hill 2005-03-11 09:50:12 EST
Created attachment 111887 [details]
ifdown-ipsec patch to complement the above ifup-ipsec patch.
Comment 3 Steve Hill 2005-03-11 11:55:48 EST
Created attachment 111893 [details]
Revised ifup-ipsec patch

Now checks if the local subnet is smaller than the remote subnet before
applying the new policies (if the subnets are completely different it doesn't
matter either way)
Comment 4 Steve Hill 2005-03-11 11:59:28 EST
Created attachment 111895 [details]
Revised ifdown-ipsec script

Checks if the local subnet is smaller than the remote subnet before deleting
policies
Comment 5 Bill Nottingham 2005-03-28 16:15:30 EST
(Sorry about the delay.)

Why is the check for whether one subnet is bigger than the other really necessary?
(Yes, it prevents extraneous policies, but I'm not sure it's worth the
complication, and explanation of why the extraneous polices only occur in case X.)
Comment 6 Steve Hill 2005-03-29 02:33:02 EST
Ok, an example:  the endpoints of the tunnel are A and B with subnets like:

A: 10.0.0.1/16
B: 10.1.0.1/8

The normal policies for both ends requre traffic to be encrypted if it matches
either of:

From: 10.0.0.0/16  To: 10.0.0.0/8  (encrypted)
From: 10.0.0.0/8   To: 10.0.0.0/16 (encrypted)

So for machine A, talking to another machine on the local subnet (10.0.0.2), the
traffic matches the policy and is dropped since it's unencrypted.  To fix this
we add a policy to machine A based on the local subnet:

From: 10.0.0.0/16   To: 10.0.0.0/16 (unencrypted)

Because we're basing the policy on the local subnet, using the same code you
would end up adding to machine B:

From: 10.0.0.0/8    To: 10.0.0.0/8  (unencrypted)

This is obviously bad since it will override the encrypted policies completely.

The way around it is to simply check to see which subnet is bigger, which is
what I've done in the second pair of patches.

(Did that make sense? :)
Comment 7 Aleksandar Milivojevic 2005-05-17 13:07:09 EDT
I'm looking into the patches, and it seems it checks only what network has
bigger netmask, not if the networks actually overlap.

On an example...

machine-a:
SRCNET=192.168.1.0/24
DSTNET=192.168.0.0/16

machine-b:
SRCNET=192.168.0.0/16
DSTNET=192.168.1.0/24

This is where I'd probably want to have overrides in place.

On the other hand:
machine-a:
SRCNET=192.168.0.0/24
DSTNET=10.0.0.0/8

machine-b:
SRCNET=10.0.0.0/8
DSTNET=192.168.0.0/24

is a case where I probably don't want any overrides...
Comment 8 Steve Hill 2005-05-18 03:33:21 EDT
> it seems it checks only what network has bigger netmask, not if the networks
actually overlap.

Correct, but it shouldn't actually matter if you add the override for
non-overlapping networks...

(Actually, I think it might break if you have multiple VPNs on exactly the wrong
networks...)

Testing if networks overlap is reasonably non-trivial from a shell script though
I think.
Comment 9 Aleksandar Milivojevic 2005-05-18 11:49:21 EDT
It might be better to let user setup overrides in configuration file manually. 
system-config-network should than be patched to make best-guess configuration
when it detects overlaping networks (and even better, let user edit the
generated override list).

I'll attach two patches against vanila ifup-ipsec and ifdown-ipsec.  They use
$OVERRIDE variable from configuration file, which is of format:

OVERRIDE="1.2.3.0/24 4.5.6.0/24 7.8.9.0/24"

The above would set overrides for three networks.

Basically, list of networks that we don't want to have encrypted.  Usefull
feature even if there are no overlapping networks.

I'm not sure if all spd entries from the patch are needed or if they are
sufficient (just wrote the script, can't actually test it right now).  Steve
probably has much more experience with IPSec than I do, and can probably correct
any of my sillyness ;-)

The patches incorporate routefix patch too, as discussed in bug #146169.

The only thing...  This probably shouldn't be in per-interface configuration
file, but rather in /etc/sysconfig/network (and probably renamed to
$IPSEC_OVERRIDES).  It should probably be executed once from
/etc/init.d/network.  Opinions?

Patches follow...
Comment 10 Aleksandar Milivojevic 2005-05-18 11:51:47 EDT
Created attachment 114517 [details]
ifup-ipsec "let user have full control" approach

ifup-ipsec patch as discussed in comment #9
Comment 11 Aleksandar Milivojevic 2005-05-18 11:52:39 EDT
Created attachment 114518 [details]
ifdown-ipsec "let user have full control" approach

ifdown-ipsec patch as discussed in comment #9
Comment 12 Aleksandar Milivojevic 2005-05-18 12:44:55 EDT
Created attachment 114520 [details]
ifup-ipsec "let user have full control" approach

Fixed some syntax errors and added possibility to specify SRC/DST networks
directly.

OVERRIDE="1.2.3.0/24 2.3.4.0/24 5.6.7.0/24-6.7.8.0/24"

would override IPSec for networks 1.2.3.0/24 and 2.3.4.0/24, and between src
5.6.7.0/24 and dst 6.7.8.0/24.
Comment 13 Aleksandar Milivojevic 2005-05-18 12:45:58 EDT
Created attachment 114521 [details]
ifdown-ipsec "let user have full control" approach

companion to ifup-ipsec patch.
Comment 14 Aleksandar Milivojevic 2005-05-18 15:14:27 EDT
Created attachment 114528 [details]
fix routes for overlapped networks

This is combined patch.  I've tested the code, and it seems to give correct
results in my test environment.  It adds SPD entries, and also has bettern
handling of routing than original routefix patch from bug #146169.

Any and old comments and improvements more than welcome.  IPSec is something
new to me, so there might be some errors or omisions in this patch due to my
limited knowledge of the subject.
Comment 15 Bill Nottingham 2005-05-18 15:31:54 EDT
I don't like the idea of having to manually specify the overrides - this seems
like something that *could* be computed, or at least would be easy to mess up
when doing it manually.
Comment 16 Aleksandar Milivojevic 2005-05-18 16:31:44 EDT
The thing is, it is not trivial to correctly compute it for general case. 
Especially in a shell script that has limited knowledge of user's configuration.
 Even then, the user might want to add some additional overrides (script has no
way of knowing user's network topology).

That's why I suggested placing this information into configuration file, and
patching system-config-network instead to generate best-guess configuration (and
really, it would really be best-guess configuration, not necessary correct in
general case).  System-config-network can than present user with whatever it
computed are correct overrides, and allow user to change them if they are not
correct for user's environment (put a nasty warning if user attemptes to change
it, if it'll make you more comfortable).

Best of both worlds.  People with simple networks can use system-config-network
and simply accept default configuration.  People with non-trivial networks can
tweak configuration to match their needs.

An example of this is my test network that looks something like this (ASCII
graphics, make sure non-proportional font is used to view it):

   +----------+
   |  VPN1    |
   +----+-----+ 192.168.1.2/24
        |
   +----+-----+ 192.168.1.1/24
   + Router   +------------- many wires to the rest of 192.168.0.0/16
   +----+-----+ 192.168.2.1/24
        |
   +----+-----+ 192.168.2.2/24
   | Firewall |
   +----+-----+ 192.168.3.1/25
        |
   +----+-----+ 192.168.3.2/25
   | VPN2     |
   +----+-----+ 192.168.3.129/25
        |
   -----+----- wire for 192.168.3.128/25 network

Now, I want to be able to reach Firewall from 192.168.3.128/25 network and VPN2
machine with no IPSec.  The Firewall is not IPSec enabled at all.  External
interface on my VPN2 machine must be reachable from the rest of 192.168.0.0/16
without IPSec for administration (over SSH for example).  All traffic from
192.168.0.0/16 outside Firewall to 192.168.3.128/25 must be encrypted (using
IPSec tunnel between VPN1 and VPN2).  There is simply no way for script to guess
my network topology and compute correct configuration.

With the proposed patch, I could simply put this into config file on VPN2:

OVERRIDES="192.168.3.0/25 192.168.3.128/25 192.168.3.0/25-192.168.0.0/16"

and things work correctly.  All trafic that should be encrypted is encrypted,
all traffic that should not be encrypted is not encrypted (spent about half an
hour testing all cases I could think of, and than retested again).
Comment 17 Aleksandar Milivojevic 2005-12-05 12:47:35 EST
After a long time, rethinking about this problem (and Bill's comment that this
is something that should be completely automatic).

The underlying problem is difference between IPSec policies and IP routing.

IPSec policy says "encrypt everything that matches this source and that
destination".

What users usually want is to encrypt traffic that goes somewhere remote
(basically, leaving the particular interface).

In my own configurations, I was able to solve this discrepancy by using GRE
tunnel, and than just having a host-to-host policy.

To correctly autocompute everything (well, at least for most users), something
like this would need to be performed.  Add routes to remote network, so that
packets are leaving correct interface with correct source address (already part
of another bug report, I believe).  Then, check the output of "ip route show",
parse it, and generate policies that would reflect actuall routing.

Hm, example.  There's this remote VPN gateway.  There's two local networks
behind it.  192.168.0.0/24 and 192.168.1.0/24.  I want everything between this
two networks and the rest of 192.168.0.0/16 going through IPSec tunnel.  So the
IPSec policy might be something like encrypt everything between 192.168.0.0/23
and 192.168.0.0/16.  However, this policy would obviously match the local
traffic too (which is what this report is about).

So, what we can work with is something like this:

# ip addr show

1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 11:22:33:44:55:66 brd ff:ff:ff:ff:ff:ff
    inet 1.2.3.4/24 brd 200.50.2.47 scope global eth0
3: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 66:55:44:33:22:11 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 brd 192.168.253.255 scope global eth1

And the routing looks something like this (with IPSec routes already added):

1.2.3.4/24 dev eth0  proto kernel  scope link  src 1.2.3.4
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.2
192.168.0.0/24 via 192.168.1.1 dev eth1
192.168.0.0/16 via 1.2.3.1 dev eth0  src 192.168.1.2
default via 1.2.3.1 dev eth0

From the above, I need to add exception for anything that matches 192.168.0.0/16
but is not to be routed to eth0.  Repeat for all interfaces that are not eth0
(in this case only eth1).  I hope the "root" keyword does what I think it does ;-)

# ip route show root 192.168.0.0/16 dev eth1
192.168.1.0/24  proto kernel  scope link  src 192.168.1.2
192.168.0.0/24 via 192.168.1.1 dev eth1

Voila, there they are.  The correct list of local networks that I need overrides
for: 192.168.0.0/24 and 192.168.1.0/24.

Does anybody see any obvious holes in this logic?
Comment 18 Miloslav Trmač 2006-05-17 12:48:44 EDT
Created attachment 129336 [details]
Exclude SRCNET<->SRCNET traffic if SRCNET is a subnet of DSTNET

While ideally the IPsec policy rules should indeed match the relevant IP
routing
table, processing the routes would probably not be very reliable either:
- Adding IPsec rules to exclude routes found during ifup-ipsec won't handle
  routes added later
- In your example, the route "192.168.0.0/24 via 192.168.1.1 dev eth1" might be

  using IPsec, which could lead to "interesting" ordering-dependent results
  (either "ipsec" or "none" depending on which IPsec interface is activated
  first).  This is probably fixable, but more complicated than I'd like.

I'm inclined to just apply the attached patch which automatically solves the
basic case, and leave the other cases for manual scripting or something like
your $OVERRIDES.
Comment 19 Matthew Miller 2006-07-10 18:41:51 EDT
Fedora Core 3 is now maintained by the Fedora Legacy project for security
updates only. If this problem is a security issue, please reopen and
reassign to the Fedora Legacy product. If it is not a security issue and
hasn't been resolved in the current FC5 updates or in the FC6 test
release, reopen and change the version to match.

Thank you!
Comment 20 Bill Nottingham 2006-07-21 14:29:07 EDT
Fixed in 8.36-1.

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