Project

General

Profile

Issue #3170

Source IP in route table is incorrect when use static virtual ip and multiple local_ts

Added by Yanzhe Lee 9 days ago. Updated 9 days ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Category:
configuration
Affected version:
5.8.1
Resolution:

Description

In Virtual IP documentation[[https://wiki.strongswan.org/projects/strongswan/wiki/VirtualIP]], it says that

To use a specific and static virtual IP (i.e. without exchanging any configuration payloads) it may simply be added to any local interface (even lo) and referenced in the client's local traffic selector (local_ts in swanctl.conf or leftsubnet in ipsec.conf). Configuring such an IP as in the example above will not have the intended effect because the IP won't get installed on the system unless the server actually assigns that IP to the client with a configuration payload.

On client side, I manually add a static virtual ip to enp0s31f6 by ip addr add 10.10.6.1 dev enp0s31f6 and my local swanctl.conf is

connections {
    nnc {
        local {
            auth = eap-mschapv2
            eap_id = ABC
            id = NETNET_CLIENT
        }
        remote_addrs = abc.example.com
        remote {
            id = abc.example.com
        }
        children {
            nnc-ch {
                local_ts = 10.10.6.0/24,10.224.0.0/11,172.25.0.0/16,172.26.0.0/16,222.194.15.1/32
                remote_ts = 10.10.0.0/16
            }
        }
    }
}

After the connection is successfully established, the source ip in route table is incorrect.
root@test# ip route show table 220
10.10.0.0/16 via 10.245.146.1 dev enp0s31f6 proto static src 172.25.0.1  # The source ip in this entry should be 10.10.6.1. 172.25.0.1 is the ip of another interface (e.g. docker bridge).
10.200.0.0/22 dev docker0 proto static src 10.200.1.1 linkdown 
10.200.131.0/24 dev br-98707a03469a proto static src 10.200.131.1 
10.200.140.0/24 dev docker_gwbridge proto static src 10.200.140.1 
10.245.146.0/24 dev enp0s31f6 proto static src 10.245.146.40 
172.17.0.0/16 dev br-636e2a6d963e proto static src 172.17.0.1 linkdown 
172.25.0.0/16 dev br-4a108130f9eb proto static src 172.25.0.1 
172.29.0.0/16 dev br-ac60a654dca4 proto static src 172.29.0.1 
192.168.16.0/20 dev br-af004f6bbc55 proto static src 192.168.16.1 
192.168.32.0/20 dev br-2c914de58881 proto static src 192.168.32.1 
192.168.122.0/24 dev virbr0 proto static src 192.168.122.1 linkdown

If I change to local_ts = 10.10.6.0/24, which contains the only subnet that includes my static virtual ip, then the source ip in route table has the correct value 10.10.6.1

root@test# ip route show table 220
10.10.0.0/16 via 10.245.146.1 dev enp0s31f6 proto static src 10.10.6.1    # This source ip is correct.
10.200.0.0/22 dev docker0 proto static src 10.200.1.1 linkdown 
10.200.131.0/24 dev br-98707a03469a proto static src 10.200.131.1 
10.200.140.0/24 dev docker_gwbridge proto static src 10.200.140.1 
10.245.146.0/24 dev enp0s31f6 proto static src 10.245.146.40 
172.17.0.0/16 dev br-636e2a6d963e proto static src 172.17.0.1 linkdown 
172.25.0.0/16 dev br-4a108130f9eb proto static src 172.25.0.1 
172.29.0.0/16 dev br-ac60a654dca4 proto static src 172.29.0.1 
192.168.16.0/20 dev br-af004f6bbc55 proto static src 192.168.16.1 
192.168.32.0/20 dev br-2c914de58881 proto static src 192.168.32.1 
192.168.122.0/24 dev virbr0 proto static src 192.168.122.1 linkdown

So I think that strongswan cannot determine with ip to use since the local_ts has multiple ip range, which matches multiple static ip in my interfaces.
Then I tried to specify the interface used in child by setting interface = enp0s31f6 in children section:
        children {
            nnc-ch {
                local_ts = 10.10.6.0/24,10.224.0.0/11,172.25.0.0/16,172.26.0.0/16,222.194.15.1/32
                remote_ts = 10.10.0.0/16
                interface = enp0s31f6
            }
        }

But it doesn't help. The source ip in route table is still the same wrong value 172.25.0.1.

So, it seems that if there are multiple static ip matches local_ts, strongswan will pick one of it regardless the interface and then install it to route table?
How can I specify which static ip to use?

History

#1 Updated by Yanzhe Lee 9 days ago

BTW, I'm using ignore-lan plugin.

#2 Updated by Tobias Brunner 9 days ago

  • Category changed from charon-systemd to configuration
  • Status changed from New to Feedback
  • Priority changed from High to Normal

On client side, I manually add a static virtual ip to enp0s31f6 by ip addr add 10.10.6.1 dev enp0s31f6 and my local swanctl.conf is

But you have obviously also a local IP address in 172.25.0.0/16.

After the connection is successfully established, the source ip in route table is incorrect.

Maybe for you, strongSwan has no reason to assume it is anything but correct.

So I think that strongswan cannot determine with ip to use since the local_ts has multiple ip range, which matches multiple static ip in my interfaces.

For each pair of local and remote traffic selectors (i.e. for each outbound policy) a local IP address in the local TS is searched and, if found, a route to the remote TS with that IP address as source is installed. With multiple local IP addresses in local traffic selectors and one remote traffic selector a single route is installed and later replaced for each match. So first there will be a route with 10.10.6.1 as source but it gets replaced with a route that has 172.25.0.1 as source when the policy for the local traffic selector 172.25.0.0/16 is installed.

Then I tried to specify the interface used in child by setting interface = enp0s31f6 in children section:
[...]
But it doesn't help.

No, that setting has a different purpose.

So, it seems that if there are multiple static ip matches local_ts, strongswan will pick one of it regardless the interface and then install it to route table?

As explained above.

How can I specify which static ip to use?

You may try to reorder your local TS so the one with the intended source IP is the last. Or just don't let the daemon install any routes by disabling charon.install_routes.

#3 Updated by Yanzhe Lee 9 days ago

I tried
local_ts = 10.224.0.0/11,172.25.0.0/16,172.26.0.0/16,222.194.15.1/32,10.10.6.0/24, and local_ts = 10.224.0.0/11,10.10.6.0/24,172.25.0.0/16,172.26.0.0/16,222.194.15.1/32, the result route table is

10.10.0.0/16 via 10.245.146.1 dev enp0s31f6 proto static src 172.25.0.1        # Source ip doesn't change, regardless the order of local_ts
10.200.0.0/22 dev docker0 proto static src 10.200.1.1 linkdown 
10.200.131.0/24 dev br-98707a03469a proto static src 10.200.131.1 
10.200.140.0/24 dev docker_gwbridge proto static src 10.200.140.1 
10.245.146.0/24 dev enp0s31f6 proto static src 10.245.146.40 
172.25.0.0/16 dev br-4a108130f9eb proto static src 172.25.0.1 
172.29.0.0/16 dev br-ac60a654dca4 proto static src 172.29.0.1 
192.168.16.0/20 dev br-af004f6bbc55 proto static src 192.168.16.1 
192.168.32.0/20 dev br-2c914de58881 proto static src 192.168.32.1 
192.168.122.0/24 dev virbr0 proto static src 192.168.122.1 linkdown

and local_ts = 10.224.0.0/11,172.25.0.0/16,10.10.6.0/24,172.26.0.0/16,222.194.15.1/32, the result route table is

10.10.0.0/16 via 10.245.146.1 dev enp0s31f6 proto static src 172.25.0.1     # Source ip doesn't change, regardless the order of local_ts
10.10.6.1 via 10.10.6.1 dev enp0s31f6 proto static src 10.10.6.1            # I just changed the order of local_ts, why this entry is installed? So strange...
10.200.0.0/22 dev docker0 proto static src 10.200.1.1 linkdown 
10.200.131.0/24 dev br-98707a03469a proto static src 10.200.131.1 
10.200.140.0/24 dev docker_gwbridge proto static src 10.200.140.1 
10.245.146.0/24 dev enp0s31f6 proto static src 10.245.146.40 
172.25.0.0/16 dev br-4a108130f9eb proto static src 172.25.0.1 
172.29.0.0/16 dev br-ac60a654dca4 proto static src 172.29.0.1 
192.168.16.0/20 dev br-af004f6bbc55 proto static src 192.168.16.1 
192.168.32.0/20 dev br-2c914de58881 proto static src 192.168.32.1 
192.168.122.0/24 dev virbr0 proto static src 192.168.122.1 linkdown

It seems that the order of local_ts matters, but in an unexpected way....

All my interfaces address(inet6 omitted) are

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP group default qlen 1000
    link/ether 18:31:bf:4d:da:fc brd ff:ff:ff:ff:ff:ff
    inet 10.245.146.40/24 brd 10.245.146.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet 10.10.6.1/32 scope global enp0s31f6
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:b1:d5:ba brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:b1:d5:ba brd ff:ff:ff:ff:ff:ff
5: br-98707a03469a: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:47:7c:b5:a3 brd ff:ff:ff:ff:ff:ff
    inet 10.200.131.1/24 brd 10.200.131.255 scope global br-98707a03469a
       valid_lft forever preferred_lft forever
6: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:47:10:8d:2e brd ff:ff:ff:ff:ff:ff
    inet 10.200.1.1/22 brd 10.200.3.255 scope global docker0
       valid_lft forever preferred_lft forever
7: br-ac60a654dca4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:36:2a:cc:0d brd ff:ff:ff:ff:ff:ff
    inet 172.29.0.1/16 brd 172.29.255.255 scope global br-ac60a654dca4
       valid_lft forever preferred_lft forever
8: br-af004f6bbc55: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:5e:2c:59:cb brd ff:ff:ff:ff:ff:ff
    inet 192.168.16.1/20 brd 192.168.31.255 scope global br-af004f6bbc55
       valid_lft forever preferred_lft forever
9: docker_gwbridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:46:d6:d5:26 brd ff:ff:ff:ff:ff:ff
    inet 10.200.140.1/24 brd 10.200.140.255 scope global docker_gwbridge
       valid_lft forever preferred_lft forever
10: br-2c914de58881: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:16:a4:d5:98 brd ff:ff:ff:ff:ff:ff
    inet 192.168.32.1/20 brd 192.168.47.255 scope global br-2c914de58881
       valid_lft forever preferred_lft forever
11: br-4a108130f9eb: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:54:96:83:4e brd ff:ff:ff:ff:ff:ff
    inet 172.25.0.1/16 brd 172.25.255.255 scope global br-4a108130f9eb
       valid_lft forever preferred_lft forever

#4 Updated by Tobias Brunner 9 days ago

It seems that the order of local_ts matters, but in an unexpected way....

You should check the log for the other in which policies are installed (if you increase knl to level 2 you also get more details about the route installation).

And again, if you don't like the routes installed by the daemon, disable that and install them yourself.

Also available in: Atom PDF