Problem with an IPsec site-to-site VPN connection between OPNsense and FortiGate

Started by vpx, February 25, 2026, 03:11:18 PM

Previous topic - Next topic
Hi, I have a problem connecting our OPNsense with a FortiGate device.

Here is the IPsec log:

2026-02-25T15:00:59    Informational    charon    07[ENC] <353286> generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]   
2026-02-25T15:00:59    Informational    charon    07[CFG] <353286> no matching peer config found   
2026-02-25T15:00:59    Informational    charon    07[CFG] <353286> looking for peer configs matching 185.xxx.xx.xx[%any]...195.yyy.yyy.yyy[195.yyy.yyy.yyy]   
2026-02-25T15:00:59    Informational    charon    07[ENC] <353286> parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) AUTH N(MSG_ID_SYN_SUP) SA TSi TSr ]   
2026-02-25T15:00:59    Informational    charon    07[NET] <353286> received packet: from 195.yyy.yyy.yyy[500] to 185.xxx.xx.xx[500] (480 bytes)   
2026-02-25T15:00:59    Informational    charon    07[NET] <353286> sending packet: from 185.xxx.xx.xx[500] to 195.yyy.yyy.yyy[500] (456 bytes)   
2026-02-25T15:00:59    Informational    charon    07[ENC] <353286> generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(CHDLESS_SUP) N(MULT_AUTH) ]   
2026-02-25T15:00:59    Informational    charon    07[CFG] <353286> selected proposal: IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048   
2026-02-25T15:00:59    Informational    charon    07[IKE] <353286> 195.yyy.yyy.yyy is initiating an IKE_SA   
2026-02-25T15:00:59    Informational    charon    07[ENC] <353286> parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) ]   
2026-02-25T15:00:59    Informational    charon    07[NET] <353286> received packet: from 195.yyy.yyy.yyy[500] to 185.xxx.xx.xx[500] (672 bytes)   
2026-02-25T15:00:58    Informational    charon    09[NET] <353285> sending packet: from 185.xxx.xx.xx[500] to 195.yyy.yyy.yyy[500] (80 bytes)

IKE IDs are set on both sides and proposals are on default on both sides. Any suggestion?

There is already an old working IKEv1 connection to the same peer with a different firewall (Sophos Astaro) so there won't a be firewall issue.

But I wonder why the line with "looking for peer configs matching" says "[%any]" for the IKE ID when I specifically provided that. Could that prevent OPNsense from finding the Pre-Shared Key combination in the list?

I now added a screenshot which states "When left empty %any is chosen as default" yet it still shows "%any" in the log despite a defined local IP address, is this a bug?

Quote from: vpx on February 25, 2026, 03:11:18 PMIKE IDs are set on both sides and proposals are on default on both sides. Any suggestion?
I've read a recommendation to disable the default and specify certain proposal instead.

Quote from: vpx on February 25, 2026, 03:11:18 PMBut I wonder why the line with "looking for peer configs matching" says "[%any]" for the IKE ID when I specifically provided that.
Maybe it is complaining about the remote site's id. Possibly it's different from the IP address?

Quote from: viragomann on February 25, 2026, 05:35:49 PMI've read a recommendation to disable the default and specify certain proposal instead.
I doubt the proposals are the problem because as you can see in the log a cipher is already negotiated.

Quote from: viragomann on February 25, 2026, 05:35:49 PMMaybe it is complaining about the remote site's id. Possibly it's different from the IP address?
As you can see or can't see because I redacted the rest of the IP, the remote IP and remote ID are identical.

The FAQs of strongSwan have a section for the error message "no matching peer config found":

https://docs.strongswan.org/docs/5.9/support/faq.html#_no_matching_peer_config_found

So the problem can only be the ID or the proposals (which I already exluded as a cause).

The FAQ also mentions the allowed format for the ID: https://docs.strongswan.org/docs/5.9/config/identityParsing.html

I already tried to change the ID to the explicit <type>:<value> format under "VPN: IPsec: Connections: Local Authentication" to force the ID but it still shows "%any" in the log file.

I downloaded the swanctl.conf and it doesn't mention "%any" anwhere, this doesn't look right.

I also set the debugging level of "IKE_SA/ISAKMP SA" in "VPN: IPsec: Mobile & Advanced Settings: Syslog" to 2 ("More detailed debugging control flow") for some seconds, see also https://docs.strongswan.org/docs/latest/config/logging.html.

Here is the more detailed log, I don't think level 3 would make sense, it just shows hex data and "natd_chunk => 22 bytes @ 0x..." and similar messages.

2026-02-26T07:52:41    Informational    charon    10[ENC] <421129> generating IKE_AUTH response 1 [ N(AUTH_FAILED) ]   
2026-02-26T07:52:41    Informational    charon    10[CFG] <421129> no matching peer config found   
2026-02-26T07:52:41    Informational    charon    10[CFG] <421129> looking for peer configs matching 185.xxx.xx.xx[%any]...195.yyy.yyy.yyy[195.yyy.yyy.yyy]   
2026-02-26T07:52:41    Informational    charon    10[ENC] <421129> parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) AUTH N(MSG_ID_SYN_SUP) SA TSi TSr ]   
2026-02-26T07:52:41    Informational    charon    10[NET] <421129> received packet: from 195.yyy.yyy.yyy[500] to 185.xxx.xx.xx[500] (480 bytes)   
2026-02-26T07:52:41    Informational    charon    10[NET] <421129> sending packet: from 185.xxx.xx.xx[500] to 195.yyy.yyy.yyy[500] (456 bytes)   
2026-02-26T07:52:41    Informational    charon    10[ENC] <421129> generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(CHDLESS_SUP) N(MULT_AUTH) ]   
2026-02-26T07:52:41    Informational    charon    10[CFG] <421129> selected proposal: IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048   
2026-02-26T07:52:41    Informational    charon    10[IKE] <421129> IKE_SA (unnamed)[421129] state change: CREATED => CONNECTING   
2026-02-26T07:52:41    Informational    charon    10[IKE] <421129> 195.yyy.yyy.yyy is initiating an IKE_SA   
2026-02-26T07:52:41    Informational    charon    10[IKE] <421129> remote endpoint changed from 0.0.0.0 to 195.yyy.yyy.yyy[500]   
2026-02-26T07:52:41    Informational    charon    10[IKE] <421129> local endpoint changed from 0.0.0.0[500] to 185.xxx.xx.xx[500]   
2026-02-26T07:52:41    Informational    charon    10[ENC] <421129> parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) ]   
2026-02-26T07:52:41    Informational    charon    10[NET] <421129> received packet: from 195.yyy.yyy.yyy[500] to 185.xxx.xx.xx[500] (672 bytes)   
2026-02-26T07:52:40    Informational    charon    10[IKE] <421128> IKE_SA (unnamed)[421128] state change: CONNECTING => DESTROYING   
2026-02-26T07:52:40    Informational    charon    10[NET] <421128> sending packet: from 185.xxx.xx.xx[500] to 195.yyy.yyy.yyy[500] (80 bytes)
(By the way when did the logs change direction from down to up because I saw old posts where the log goes from up to down? :) )

Also how would I know the default proposals? Even the swanctl.conf just says "proposals = default" and "esp_proposals = default".

It would be nice if there was a place in the GUI where you can actually see them.

I actually found the default proposals by setting CFG ("Configuration management and plugins") to level 2, here they are:

2026-02-26T08:18:01 Informational charon 15[CFG] <422831> configured proposals: IKE:AES_CBC_128/AES_CBC_192/AES_CBC_256/AES_CTR_128/AES_CTR_192/AES_CTR_256/CAMELLIA_CBC_128/CAMELLIA_CBC_192/CAMELLIA_CBC_256/CAMELLIA_CTR_128/CAMELLIA_CTR_192/CAMELLIA_CTR_256/3DES_CBC/HMAC_SHA2_256_128/HMAC_SHA2_384_192/HMAC_SHA2_512_256/HMAC_SHA1_96/AES_XCBC_96/AES_CMAC_96/PRF_HMAC_SHA2_256/PRF_HMAC_SHA2_384/PRF_HMAC_SHA2_512/PRF_AES128_XCBC/PRF_AES128_CMAC/PRF_HMAC_SHA1/ECP_256/ECP_384/ECP_521/ECP_256_BP/ECP_384_BP/ECP_512_BP/CURVE_25519/CURVE_448/MODP_3072/MODP_4096/MODP_6144/MODP_8192/MODP_2048, IKE:AES_GCM_16_128/AES_GCM_16_192/AES_GCM_16_256/AES_CCM_16_128/AES_CCM_16_192/AES_CCM_16_256/CHACHA20_POLY1305/AES_GCM_12_128/AES_GCM_12_192/AES_GCM_12_256/AES_GCM_8_128/AES_GCM_8_192/AES_GCM_8_256/AES_CCM_12_128/AES_CCM_12_192/AES_CCM_12_256/AES_CCM_8_128/AES_CCM_8_192/AES_CCM_8_256/PRF_HMAC_SHA2_256/PRF_HMAC_SHA2_384/PRF_HMAC_SHA2_512/PRF_AES128_XCBC/PRF_AES128_CMAC/PRF_HMAC_SHA1/ECP_256/ECP_384/ECP_521/ECP_256_BP/ECP_384_BP/ECP_512_BP/CURVE_25519/CURVE_448/MODP_3072/MODP_4096/MODP_6144/MODP_8192/MODP_2048

I actually found the problem and I also have 3 possible solutions for anybody that encounters the same issue.

When I ramped up the debug level for CFG ("Configuration management and plugins") I found the culprit, the FortiGate device is sending a FQDN IKE ID.

2026-02-26T09:35:58 Informational charon 11[CFG] <428065> remote id match: 0 (ID_FQDN: 31:39:35:2e:79:79:79:2e:79:79:79:2e:79:79:79)
2026-02-26T09:35:58 Informational charon 11[CFG] <428065> local id match: 1 (ID_ANY: )

Searching this issue I found the following article from Fortinet: https://community.fortinet.com/t5/FortiGate/Troubleshooting-Tip-FortiGate-sends-local-id-in-FQDN-type-when/ta-p/224888

  • Solution 1: This is the easiest one, as the peer just has to remove the ID in the field "Local ID" in his Phase 1 settings, the FortiGate will then use the IP of the used interface (ID_IPV4_ADDR). That's the solution we now chose. Of course this only works if the IP equals the ID
  • Solution 2: On the FortiGate leave the IP address you used as the IKE ID and add the line "set localid-type address" to your IPsec config. Untested solution.
  • Solution 3: This could be handy if there is slow response on the FortiGate side, just copy the ID_FQDN from the verbose log into the OPNsense "Remote Authentication" secton. This is also untested.

But I still don't get why OPNsense/strongSwan always has the ID_ANY type for the local ID, despite setting a specific local ID.

Now there is only one weird observation left that I made when I had the CFG logs on verbose:

2026-02-26T09:27:20 Informational charon 07[CFG] vici client 490 disconnected
2026-02-26T09:27:20 Informational charon 01[CFG] updated vici connection: 3*******-a***-4***-9***-2***********
2026-02-26T09:27:20 Informational charon 01[CFG] id = 195.yyy.yyy.yyy
2026-02-26T09:27:20 Informational charon 01[CFG] remote:
2026-02-26T09:27:20 Informational charon 01[CFG] class = pre-shared key
2026-02-26T09:27:20 Informational charon 01[CFG] id = 49.56.53.46
2026-02-26T09:27:20 Informational charon 01[CFG] local:
2026-02-26T09:27:20 Informational charon 01[CFG] if_id_out = 0
2026-02-26T09:27:20 Informational charon 01[CFG] if_id = 0

Why the hell is there an IP from South Korea as our local ID (49.56.53.46)?

Is this just a random IP from cache because our type is ID_ANY? Can anybody else please raise their log level and check what IP is shown here?

Quote from: vpx on Today at 08:13:32 AM
QuoteMaybe it is complaining about the remote site's id. Possibly it's different from the IP address?
As you can see or can't see because I redacted the rest of the IP, the remote IP and remote ID are identical.
Yes, they seemed to be identical to me. I didn't doubt.

The log shows the remote IP and the expected IKE ID in square bracket.
My suspicion was, that the ID sent by the remote site (not shown in the log) differs from the expected one on your site, however. And obviously this was the issue in fact.^^