IPSec tunnel + L2TP/IPSec VPN - wrong PSK chosen by pfSense
1. IPSec, IKEv1 site to site tunnel, PSK, Main mode. FQDN identifier - talking to a Mac OS server (racoon)
2. L2TP/IPSec for mobile clients, PSK, Main mode.
1. The IPSec tunnel was set-up, all went well, tunnel established (no other VPN services yet)
2. The L2TP was set-up according to this guide [url]https://doc.pfsense.org/index.php/L2TP/IPsec[/url], however I needed to add "Any TCP flags" to my LAN and L2TP allow-all firewall rule to get connections to work (the floating rule for L2TP was not sufficient). L2TP Clients could connect.
All worked.... until the IPSec tunnel rekeyed a few hours later. Then impossible to reestablish the connection.
Debug logs showing that it was failing at the end of phase 1, hash not matching when I switched to aggressive mode, payload length incorrect in main mode. All DH shared secrets and auth data to hash were identical. This pointed to a PSK problem, yet the connection was established, so I knew my PSKs were correct.
After much head scratching, rebooting of servers, it turns out that the problem is that pfSense/strongSwan was selecting the wrong PSK.
cat /var/etc/ipsec/ipsec.secrets in the shell gives
%any : PSK 0s<base 64 encoded L2TP PSK> vpn.mycompany.com : PSK 0s<base 64 encoded tunnel PSK>
It would seem that the %any has priority over the identified entry, so the L2TP PSK is always selected - according to the L2TP doc, any user is needed to configure L2TP... which would explain why the tunnel came up to start with (no other PSK candidates).
As a workaround, I changed the tunnel PSK to be the same as the L2TP PSK and, bingo, the tunnel came up.
It would seem that the PSK values are checked in the order they are listed, no hierarchization of matching identifiers, so the %any entry enumerated first, matches and returns the PSK, which is wrong for the IPSec tunnel.
Checking the strongSwan sources (5.5.0)
enumerator_create_filter which stops on the first match, only owners within each line in ipsec.secrets have a best match applied via
shared_filter (line 454)
1. Within pfSense would be to order secrets in ipsec.secrets so that wildcard ids are at the end,
2. Correct strongSwan to choose the best match rather that enumerating the secrets in a linear manner.
#1 Updated by Janusz Baranek almost 4 years ago
ipsec.secrets (mistyped) should be:
%any @vpn.mycompany.com : PSK 0s<base 64 encoded tunnel PSK> %any : PSK 0s<base 64 encoded L2TP PSK>
(this was the contents of the file when the problem occurred)
As the shared keys are in reverse order in the list (mem_cred.c:534 -
%any rule would be enumerated first. So my suggested correction in pfSense should be:
1. Within pfSense would be to order secrets in ipsec.secrets so that wildcard ids are at the start,
#3 Updated by Jim Pingle over 3 years ago
- File psk-ordering.diff psk-ordering.diff added
- Status changed from New to Feedback
- Assignee changed from Jim Pingle to Janusz Baranek
I'm hesitant to commit changes to the ordering without lots of testing first, so can you try the attached patch to see if it resolves the problem for you? (use the System Patches package, path strip = 2)
The patch changes the ordering so any PSK with a wildcard local ID is places last in the secrets file. It would appear to help, but I'm not sure it goes far enough. If it's not sufficient it may need review by Renato or Luiz.
#4 Updated by Jim Pingle over 3 years ago
- Assignee deleted (
- Target version deleted (
No response from the OP, can't seem to reproduce it.
If someone can reproduce it and test a potential fix, please provide feedback. Potential impact of changing the affected code is fairly large so any fix needs testing before it can be committed.