Project

General

Profile

Bug #1375

If strongSwan is restarted at the time there is no route to destination peer then kernel traps are not installed and all traffic can exit in plain (with auto=route setting)

Added by Ansis Atteka over 4 years ago. Updated over 4 years ago.

Status:
Closed
Priority:
Normal
Category:
kernel-interface
Target version:
Start date:
31.03.2016
Due date:
Estimated time:
Affected version:
5.1.2
Resolution:
Fixed

Description

If there is no route to remote peer at the time strongSwan was started, then strongSwan does not install kernel traps. This causes strongSwan to send out traffic in plain that otherwise would have to be encrypted. This bug is reproducible 100% of the time by putting a "sleep 1" after "ipsec restart" as in this command:

root@ubuntu:/home/aatteka/Git# ifconfig eno16777736 0.0.0.0; ipsec restart; sleep 1; ifconfig eno16777736 192.168.71.136/24; ip route add default via 192.168.71.2; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka/Git# ifconfig eno16777736 0.0.0.0; ipsec restart; sleep 1; ifconfig eno16777736 192.168.71.136/24; ip route add default via 192.168.71.2; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka/Git# ifconfig eno16777736 0.0.0.0; ipsec restart; ifconfig eno16777736 192.168.71.136/24; ip route add default via 192.168.71.2; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Routed Connections:
sample-self-signed{1}:  ROUTED, TUNNEL, reqid 1 <----------- This is missing with sleep(1) after ipsec restart
sample-self-signed{1}:   192.168.71.136/32 === 192.168.0.2/32
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka/Git# ifconfig eno16777736 0.0.0.0; ipsec restart; ifconfig eno16777736 192.168.71.136/24; ip route add default via 192.168.71.2; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Routed Connections:
sample-self-signed{1}:  ROUTED, TUNNEL, reqid 1
sample-self-signed{1}:   192.168.71.136/32 === 192.168.0.2/32
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka/Git# ifconfig eno16777736 0.0.0.0; ipsec restart; sleep 1; ifconfig eno16777736 192.168.71.136/24; ip route add default via 192.168.71.2; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka/Git# ipsec status
Security Associations (0 up, 0 connecting):
  none

Since it is possible to fool strongSwan to let the traffic exit in plain, then this bug could also be leveraged as a potential security vulnerability in certain environments with combined attacks where attacker could figure out a creative way to make sure that strongSwan starts before host installed IP address and routes (e.g. by DoSing DHCP server so that strongSwan would start before the host got its IP address and routes on system restart).

Associated revisions

Revision 9c01e014 (diff)
Added by Tobias Brunner over 4 years ago

trap-manager: Allow local address to be unspecified

If there is currently no route to reach the other peer we just default
to left=%any. The local address is only really used to resolve
leftsubnet=%dynamic anyway (and perhaps for MIPv6 proxy transport mode).

Fixes #1375.

History

#1 Updated by Tobias Brunner over 4 years ago

  • Status changed from New to Feedback

If there is no route to remote peer at the time strongSwan was started, then strongSwan does not install kernel traps.

I can't reproduce this. Please check the log for the exact reason why the policies are not installed (one possibility is that the remote host couldn't get resolved if you configured a FQDN).

#2 Updated by Ansis Atteka over 4 years ago

Tobias Brunner wrote:

If there is no route to remote peer at the time strongSwan was started, then strongSwan does not install kernel traps.

I can't reproduce this. Please check the log for the exact reason why the policies are not installed (one possibility is that the remote host couldn't get resolved if you configured a FQDN).

Sorry, missed that you responded already .14 days ago. The notification somehow went into my Gmail Spam folder.

I am not using FQDNs and I am able to reproduce this consistently on fresh Ubuntu 15.10 with following configuration below. Note that the only difference between failed and successful test is "sleep 5 after "ipsec restart" command.

root@ubuntu:/home/aatteka# cat /usr/local/etc/ipsec.conf 
conn 192.168.71.2
      right=192.168.71.2
      auto=route
      mobike=yes
root@ubuntu:/home/aatteka# cat /usr/local/etc/ipsec.secrets 
: PSK "1234567890" 
root@ubuntu:/home/aatteka# ifconfig eno16777736 0.0.0.0; ipsec restart; sleep 5; ifconfig eno16777736 192.168.71.136/24; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka# ifconfig eno16777736 0.0.0.0; ipsec restart; sleep 5; ifconfig eno16777736 192.168.71.136/24; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka# ifconfig eno16777736 0.0.0.0; ipsec restart; sleep 0; ifconfig eno16777736 192.168.71.136/24; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Routed Connections:
192.168.71.2{1}:  ROUTED, TUNNEL, reqid 1
192.168.71.2{1}:   192.168.71.136/32 === 192.168.71.2/32
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka# ifconfig eno16777736 0.0.0.0; ipsec restart; sleep 0; ifconfig eno16777736 192.168.71.136/24; sleep 5; ipsec status
Stopping strongSwan IPsec...
Starting strongSwan 5.4.0 IPsec [starter]...
Routed Connections:
192.168.71.2{1}:  ROUTED, TUNNEL, reqid 1
192.168.71.2{1}:   192.168.71.136/32 === 192.168.71.2/32
Security Associations (0 up, 0 connecting):
  none
root@ubuntu:/home/aatteka# 

In case you are wondering what gets logged then here it is:
  1. In successful case:
    
    Apr 25 10:53:15 ubuntu ipsec_starter[30225]: Starting strongSwan 5.4.0 IPsec [starter]...
    Apr 25 10:53:15 ubuntu ipsec_starter[30248]: charon (30249) started after 40 ms
    Apr 25 10:53:15 ubuntu ipsec_starter[30248]: '192.168.71.2' routed
    Apr 25 10:53:15 ubuntu ipsec_starter[30248]: 
    Apr 25 10:53:16 ubuntu charon: 15[IKE] initiating IKE_SA 192.168.71.2[1] to 192.168.71.2
    
    
  1. In failed case:

Apr 25 10:54:32 ubuntu ipsec_starter[30283]: Starting strongSwan 5.4.0 IPsec [starter]...
Apr 25 10:54:32 ubuntu ipsec_starter[30306]: charon (30307) started after 20 ms
Apr 25 10:54:32 ubuntu ipsec_starter[30306]: routing '192.168.71.2' failed
Apr 25 10:54:32 ubuntu ipsec_starter[30306]: 

Let me know if you want me to bump up log level to debug and provide more information.

#3 Updated by Tobias Brunner over 4 years ago

In failed case:

Apr 25 10:54:32 ubuntu ipsec_starter[30283]: Starting strongSwan 5.4.0 IPsec [starter]...
Apr 25 10:54:32 ubuntu ipsec_starter[30306]: charon (30307) started after 20 ms
Apr 25 10:54:32 ubuntu ipsec_starter[30306]: routing '192.168.71.2' failed
Apr 25 10:54:32 ubuntu ipsec_starter[30306]: 

These are only the log messages logged by starter. There should be at least one error message by charon (level 1 in cfg) before the failure notice (a likely candidate would be installing trap failed, local address unknown).

Let me know if you want me to bump up log level to debug and provide more information.

Yes, please increase the log level for the knl and cfg log groups to 2.

#4 Updated by Ansis Atteka over 4 years ago

Tobias Brunner wrote:

In failed case:
[...]

These are only the log messages logged by starter. There should be at least one error message by charon (level 1 in cfg) before the failure notice (a likely candidate would be installing trap failed, local address unknown).

Let me know if you want me to bump up log level to debug and provide more information.

Yes, please increase the log level for the knl and cfg log groups to 2.

I increased everything to log level 2. This is for the failed case where IPsec tunnel never ended up being routed:

16[JOB] started worker thread 16
01[JOB] watcher going to poll() 5 fds
13[NET] waiting for data on sockets
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
01[JOB] watched FD 16 ready to read
01[JOB] watcher going to poll() 4 fds
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
06[CFG] received stroke: add connection '192.168.71.2'
06[CFG] conn 192.168.71.2
06[CFG]   left=%any
06[CFG]   right=192.168.71.2
06[CFG]   ike=aes128-sha256-modp3072
06[CFG]   esp=aes128-sha256
06[CFG]   dpddelay=30
06[CFG]   dpdtimeout=150
06[CFG]   mediation=no
06[KNL] 192.168.71.2 is not a local address or the interface is down
06[CFG] added configuration '192.168.71.2'
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
01[JOB] watched FD 16 ready to read
01[JOB] watcher going to poll() 4 fds
11[CFG] received stroke: route '192.168.71.2'
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
11[KNL] no address found to reach 192.168.71.2/32
11[CFG] installing trap failed, local address unknown
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
01[JOB] watched FD 15 ready to read
01[JOB] watcher going to poll() 4 fds
12[KNL] 192.168.71.136 appeared on eno16777736
14[JOB] next event in 99ms, waiting
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
01[JOB] watched FD 15 ready to read
01[JOB] watcher going to poll() 4 fds
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
01[JOB] watched FD 15 ready to read
01[JOB] watcher going to poll() 4 fds
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
01[JOB] watched FD 15 ready to read
01[JOB] watcher going to poll() 4 fds
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
01[JOB] watched FD 15 ready to read
01[JOB] watcher going to poll() 4 fds
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
14[JOB] got event, queuing job for execution
14[JOB] got event, queuing job for execution
14[JOB] no events, waiting
15[KNL] creating roam job due to address/link change
01[JOB] watched FD 16 ready to read
01[JOB] watcher going to poll() 4 fds
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds
01[JOB] watcher got notification, rebuilding
01[JOB] watcher going to poll() 5 fds

#5 Updated by Tobias Brunner over 4 years ago

  • Tracker changed from Issue to Bug
  • Target version set to 5.5.0
11[KNL] no address found to reach 192.168.71.2/32
11[CFG] installing trap failed, local address unknown

Yeah, that's what I thought. The problematic calls happen here: source:src/libcharon/sa/trap_manager.c#L193. Since you do not specify left it defaults to %any, which then triggers a source address lookup via routing table that fails if there are no routes and addresses at all. To be honest, I'm not entirely sure why a local address is enforced there. If leftsubnet is not configured it will just default to %dynamic and then get resolved to 0.0.0.0/0 if left is %any, but that does seem to be an issue and by changing leftsubnet you'd still have full control over the installed policies.

I pushed a fix for this to the 1375-trap-local-addr branch.

#6 Updated by Ansis Atteka over 4 years ago

Tobias Brunner wrote:

[...]

Yeah, that's what I thought. The problematic calls happen here: source:src/libcharon/sa/trap_manager.c#L193. Since you do not specify left it defaults to %any, which then triggers a source address lookup via routing table that fails if there are no routes and addresses at all. To be honest, I'm not entirely sure why a local address is enforced there. If leftsubnet is not configured it will just default to %dynamic and then get resolved to 0.0.0.0/0 if left is %any, but that does seem to be an issue and by changing leftsubnet you'd still have full control over the installed policies.

I pushed a fix for this to the 1375-trap-local-addr branch.

Thanks, I verified your fix and can confirm that it solves the issue I encountered.

#7 Updated by Tobias Brunner over 4 years ago

  • Category set to kernel-interface
  • Status changed from Feedback to Closed
  • Assignee set to Tobias Brunner
  • Resolution set to Fixed

Also available in: Atom PDF