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)
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
History
#1 Updated by Tobias Brunner over 6 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 6 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:
- 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
- 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 6 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 6 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 6 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 6 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 6 years ago
- Category set to kernel-interface
- Status changed from Feedback to Closed
- Assignee set to Tobias Brunner
- Resolution set to Fixed
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.