IKEv2 Child SA - beware phase 2 DH on macOS/iOS



  • Hi,

    I have set up running IKEv2 cert based VPN that works on macOS, iOS and MSW.

    Pahse 1 DH20
    Pahse 2 DH20

    So i started to test rekeying.

    EDIT: logs are "newest on top".

    MSW

    Phase 1 lifetime 180 seconds
    Phase 2 lifetime 60 seconds

    Run for half a day (so hundreds of rekeyings), rekeying works as expected.

    macOS

    I use Apple Configurator which in GUI does not allow low values (and I did not want to search why, or edit config manually, so i went with it)

    Phase 1 lifetime 1200 seconds
    Phase 2 lifetime 600 seconds

    It connects.
    But on first child SA rekeying it drops with following stuff.

    
    Time	Process	PID	Message
    Mar 22 19:44:44    	charon    		15[CFG] <con1|11>lease 172.23.152.1 by 'ikemaster' went offline    
    Mar 22 19:44:44    	charon    		15[IKE] <con1|11>IKE_SA con1[11] state change: DELETING => DESTROYING    
    Mar 22 19:44:44    	charon    		15[NET] <con1|11>sending packet: from 192.168.10.100[4500] to 192.168.10.146[4500] (88 bytes)    
    Mar 22 19:44:44    	charon    		15[ENC] <con1|11>generating INFORMATIONAL response 11 [ ]    
    Mar 22 19:44:44    	charon    		15[IKE] <con1|11>IKE_SA deleted    
    Mar 22 19:44:44    	charon    		15[IKE] <con1|11>IKE_SA con1[11] state change: ESTABLISHED => DELETING    
    Mar 22 19:44:44    	charon    		15[IKE] <con1|11>deleting IKE_SA con1[11] between 192.168.10.100[route.warp.lv]...192.168.10.146[ikemaster]    
    Mar 22 19:44:44    	charon    		15[IKE] <con1|11>received DELETE for IKE_SA con1[11]    
    Mar 22 19:44:44    	charon    		15[ENC] <con1|11>parsed INFORMATIONAL request 11 [ D ]    
    Mar 22 19:44:44    	charon    		15[NET] <con1|11>received packet: from 192.168.10.146[4500] to 192.168.10.100[4500] (88 bytes)    
    Mar 22 19:44:44    	charon    		15[NET] <con1|11>sending packet: from 192.168.10.100[4500] to 192.168.10.146[4500] (88 bytes)    
    Mar 22 19:44:44    	charon    		15[ENC] <con1|11>generating CREATE_CHILD_SA response 10 [ N(NO_PROP) ]    
    Mar 22 19:44:44    	charon    		15[IKE] <con1|11>failed to establish CHILD_SA, keeping IKE_SA    
    Mar 22 19:44:44    	charon    		15[IKE] <con1|11>no acceptable proposal found    
    Mar 22 19:44:44    	charon    		15[CFG] <con1|11>configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ    
    Mar 22 19:44:44    	charon    		15[CFG] <con1|11>received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ    
    Mar 22 19:44:44    	charon    		15[CFG] <con1|11>no acceptable DIFFIE_HELLMAN_GROUP found    
    Mar 22 19:44:44    	charon    		15[CFG] <con1|11>selecting proposal:    
    Mar 22 19:44:44    	charon    		15[ENC] <con1|11>parsed CREATE_CHILD_SA request 10 [ N(REKEY_SA) SA No TSi TSr ]    
    Mar 22 19:44:44    	charon    		15[NET] <con1|11>received packet: from 192.168.10.146[4500] to 192.168.10.100[4500] (216 bytes)</con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11></con1|11> 
    

    The reason is clearly seen. macOS does not propse DH20 on child revocation.

    Lets check plist, it's there

    
    <key>ChildSecurityAssociationParameters</key>
     <dict><key>DiffieHellmanGroup</key>
      <integer>20</integer>
      <key>EncryptionAlgorithm</key>
      <string>AES-256</string>
      <key>IntegrityAlgorithm</key>
      <string>SHA2-256</string>
      <key>LifeTimeInMinutes</key>
      <integer>10</integer></dict> 
    
    

    Hmm, but I was able to connect and use VPN until first revocation. Is macOS sending for child SA proposal for ECP_384 only on connect, but not on revocation? Might be.

    Lets check connection logs.

    
    Mar 22 19:57:00    	charon    		12[ENC] <con1|13>generating IKE_AUTH response 9 [ AUTH CPRP(ADDR DNS SUBNET U_DEFDOM U_SPLITDNS) N(ESP_TFC_PAD_N) SA TSi TSr N(AUTH_LFT) N(MOBIKE_SUP) N(ADD_4_ADDR) N(ADD_4_ADDR) ]    
    Mar 22 19:57:00    	charon    		12[IKE] <con1|13>CHILD_SA con1{81} established with SPIs cbeb3942_i 0905f817_o and TS 0.0.0.0/0|/0 === 172.23.152.1/32|/0    
    Mar 22 19:57:00    	charon    		12[CHD] <con1|13>SPI 0x0905f817, src 192.168.10.100 dst 192.168.10.146    
    Mar 22 19:57:00    	charon    		12[CHD] <con1|13>adding outbound ESP SA    
    Mar 22 19:57:00    	charon    		12[CHD] <con1|13>SPI 0xcbeb3942, src 192.168.10.146 dst 192.168.10.100    
    Mar 22 19:57:00    	charon    		12[CHD] <con1|13>adding inbound ESP SA    
    Mar 22 19:57:00    	charon    		12[CHD] <con1|13>using HMAC_SHA2_256_128 for integrity    
    Mar 22 19:57:00    	charon    		12[CHD] <con1|13>using AES_CBC for encryption    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>config: 172.23.152.1/32|/0, received: ::/0|/0 => no match    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>config: 172.23.152.1/32|/0, received: 0.0.0.0/0|/0 => match: 172.23.152.1/32|/0    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>selecting traffic selectors for other:    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>config: 0.0.0.0/0|/0, received: ::/0|/0 => no match    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>config: 0.0.0.0/0|/0, received: 0.0.0.0/0|/0 => match: 0.0.0.0/0|/0    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>selecting traffic selectors for us:    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>proposal matches    
    Mar 22 19:57:00    	charon    		12[CFG] <con1|13>selecting proposal:</con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13></con1|13> 
    

    Whoa, it does not send ECP_384 also on connect! But i can connect!

    Should i file a bugreport for pfSense that it allows connection whithout matching proposals for phase2, but catches this fact only on first rekeying? Or am i missing something and this is expected behaviour that if
    configured: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ
    proposed by client: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
    it passes on connection, but will not pass on rekeying?

    Thinking that although logs say that on first connection macOS does not proposes ECP_384 but it reproposes it again in a way that it is not shown on logs seems faaaaaar stretched :) (and if so, then what happens on rekeying - macOS does not propse ECP_384 again but here also does not propose ECP_384 behind the scenes)?

    And i know that this is also Apple bug, that DH is not sent in phase 2 proposal both on connection and rekeying although it is configured in apple profile, but it is another topic. But if pfSense would have just not allowed to connect in the first place I could have catched this earlier.

    Current solution

    Meanwhile I just changed pfSense configuration that Phase 2 does not use DH group at all.
    Whatever I specify in apple configurator in Child CA does not matter as macOS will not send it anyways.
    And i reconfigured MSW to not use DH group in child CA.

    
    Set-VpnConnectionIPsecConfiguration -ConnectionName "myvpnname" -AuthenticationTransformConstants SHA256 -CipherTransformConstants AES256 -EncryptionMethod AES256 -IntegrityCheckMethod SHA384 -DHGroup ECP384 -PfsGroup None -PassThru -Force
    
    

    MSW works of course.

    macOS also works now. This is what I get on macOS connection now for phase 2 (server does not ask for DH and macOS does not supply, just as previously)

    Connection

    
    Mar 22 20:15:53    	charon    		15[CFG] <con1|14>selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ    
    Mar 22 20:15:53    	charon    		15[CFG] <con1|14>configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ    
    Mar 22 20:15:53    	charon    		15[CFG] <con1|14>received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ    
    Mar 22 20:15:53    	charon    		15[CFG] <con1|14>proposal matches    
    Mar 22 20:15:53    	charon    		15[CFG] <con1|14>selecting proposal:</con1|14></con1|14></con1|14></con1|14></con1|14> 
    

    Child SA (Phase 2) rekeying

    
    Mar 22 20:48:44	charon		10[CFG] <con1|16>selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
    Mar 22 20:48:44	charon		10[CFG] <con1|16>configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
    Mar 22 20:48:44	charon		10[CFG] <con1|16>received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
    Mar 22 20:48:44	charon		10[CFG] <con1|16>proposal matches
    Mar 22 20:48:44	charon		10[CFG] <con1|16>selecting proposal:</con1|16></con1|16></con1|16></con1|16></con1|16> 
    

    KE SA (Phase 1) rekeying

    
    Mar 22 20:55:22	charon		08[IKE] <con1|16>IKE_SA con1[16] state change: ESTABLISHED => REKEYED
    Mar 22 20:55:22	charon		08[IKE] <con1|16>rescheduling reauthentication in -450s after rekeying, lifetime reduced to 90s
    Mar 22 20:55:22	charon		08[IKE] <con1|16>IKE_SA con1[17] rekeyed between 192.168.10.100[route.warp.lv]...192.168.10.146[ikemaster]
    Mar 22 20:55:22	charon		08[IKE] <con1|16>maximum IKE_SA lifetime 1049s
    Mar 22 20:55:22	charon		08[IKE] <con1|16>scheduling reauthentication in 509s
    Mar 22 20:55:22	charon		08[IKE] <con1|16>IKE_SA con1[17] state change: CONNECTING => ESTABLISHED
    Mar 22 20:55:22	charon		08[CFG] <con1|16>selected proposal: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    Mar 22 20:55:22	charon		08[CFG] <con1|16>configured proposals: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    Mar 22 20:55:22	charon		08[CFG] <con1|16>received proposals: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    Mar 22 20:55:22	charon		08[CFG] <con1|16>proposal matches
    Mar 22 20:55:22	charon		08[CFG] <con1|16>selecting proposal:
    Mar 22 20:55:22	charon		08[IKE] <con1|16>IKE_SA con1[17] state change: CREATED => CONNECTING
    Mar 22 20:55:22	charon		08[IKE] <con1|16>192.168.10.146 is initiating an IKE_SA
    Mar 22 20:55:22	charon		08[ENC] <con1|16>parsed CREATE_CHILD_SA request 15 [ SA No KE ]
    Mar 22 20:55:22	charon		08[NET] <con1|16>received packet: from 192.168.10.146[4500] to 192.168.10.100[4500] (264 bytes)</con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16></con1|16> 
    

    BTW, Phase 1 (IKE SA) revocation worked on macOS always (as well as those hundres of MSW rekeyings), pfSense expects DH20, macOS proposes DH20 on both connection and rekeying, only child SA is affected.


  • Netgate

    The first IKEv2 "Phase 2" is derived from the initial IKE negotiation. The other values are not used until Rekey.

    There is one important aspect that affects IKEv2. The keys for the IPsec SA that's implicitly created with the IKE_AUTH exchange will always be derived from the IKE keys even if PFS is configured. So if the peers disagree on whether to use PFS or not it will not be known until the IPsec SA is first rekeyed (and fails). This is also the reason why you won't see a DH group in the status output of the daemon until the SA is first rekeyed. For IKEv1 that's different as each Quick Mode exchange uses the complete proposals, so already the first IPsec SA will use PFS according to the configuration.

    Short lifetimes have a whole set of problems on their own. That's probably why Apple (properly) disallows them.

    The value margin… + margin... * rekeyfuzz must not exceed the original limit. For example, specifying margintime = 30m in the default configuration is a bad idea as there is a chance that the rekey time equals zero and, thus, rekeying gets disabled.

    Both from: https://wiki.strongswan.org/projects/strongswan/wiki/ExpiryRekey



  • Forget about short lifetime, im debugging only proposals content, they will be usual 28800/3600.

    The first IKEv2 "Phase 2" is derived from the initial IKE negotiation.

    explains it all.

    Just checked that I can connect also with MSW while setting phase 2 DH on MSW to none

    Mar 22 22:30:14	charon		05[CFG] <con1|30> selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
    Mar 22 22:30:14	charon		05[CFG] <con1|30> configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ
    Mar 22 22:30:14	charon		05[CFG] <con1|30> received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ]
    Mar 22 22:30:14	charon		05[CFG] <con1|30> selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
    Mar 22 22:30:14	charon		05[CFG] <con1|30> configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ
    Mar 22 22:30:14	charon		05[CFG] <con1|30> received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ</con1|30></con1|30></con1|30></con1|30></con1|30></con1|30>
    

    and on first rekey it fails

    
    Mar 22 22:41:19	charon		12[ENC] <con1|30>generating CREATE_CHILD_SA response 10 [ N(NO_PROP) ]
    Mar 22 22:41:19	charon		12[IKE] <con1|30>failed to establish CHILD_SA, keeping IKE_SA
    Mar 22 22:41:19	charon		12[IKE] <con1|30>no acceptable proposal found
    Mar 22 22:41:19	charon		12[CFG] <con1|30>configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ
    Mar 22 22:41:19	charon		12[CFG] <con1|30>received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
    Mar 22 22:41:19	charon		12[CFG] <con1|30>no acceptable DIFFIE_HELLMAN_GROUP found
    Mar 22 22:41:19	charon		12[CFG] <con1|30>selecting proposal:</con1|30></con1|30></con1|30></con1|30></con1|30></con1|30></con1|30> 
    

    which is expected as per your explanation.

    So it is bug by Apple and only - not giving configured DH group (any actually, i tried HD14, DH2 for phase 2) on rekeying.

    Which I wanted to check befire filing bugreport here. Thanks you so much for making it clear!



  • Here is radar for macOS https://openradar.appspot.com/radar?id=4984460223184896
    And yes, I did file the same also for iOS.
    I borrowed @Derelict wording on why it connects :)
    maybe ranting was unnecessary. I have filed so many devbugs as well as opencl bugs, hard to count, one Foundation class breaking bug that I reported in 2009 and which affects one project that i maintain still stands.



  • Got answer for Apple (for iOS not macOS ticket, Q.E.D. :)).

    For IKEv2 on the iOS device to use the configured DH groups in Child Rekey, you will need to set the Enable Perfect Forward Secrecy option in the Apple Configurator application.

    Had not checked that, facepalm.

    For test have set Group 1 for 20 min rekeying, Group 2 for 10 min rekeying.

    On connect phase 1:

    charon		05[CFG] <31> selected proposal: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    charon		05[CFG] <31> configured proposals: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    charon		05[CFG] <31> received proposals: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    

    On connect phase 2:

    charon		11[CFG] <con1|37> selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ
    charon		11[CFG] <con1|37> configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ
    charon		11[CFG] <con1|37> received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/NO_EXT_SEQ</con1|37></con1|37></con1|37>
    

    On rekey phase 2:

    charon		10[CFG] <con1|32> selected proposal: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ
    charon		10[CFG] <con1|32> configured proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ
    charon		10[CFG] <con1|32> received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/ECP_384/NO_EXT_SEQ
    charon		10[CFG] <con1|32> proposal matches
    charon		10[CFG] <con1|32> selecting proposal:
    charon		10[ENC] <con1|32> parsed CREATE_CHILD_SA request 2 [ N(REKEY_SA) SA No KE TSi TSr ]</con1|32></con1|32></con1|32></con1|32></con1|32></con1|32>
    

    On rekey phase 1:

    
    charon		15[CFG] <con1|31> selected proposal: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    charon		15[CFG] <con1|31> configured proposals: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    charon		15[CFG] <con1|31> received proposals: IKE:AES_CBC_256/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/ECP_384
    charon		15[CFG] <con1|31> proposal matches
    charon		15[CFG] <con1|31> selecting proposal:
    charon		15[IKE] <con1|31> IKE_SA con1[32] state change: CREATED => CONNECTING
    charon		15[IKE] <con1|31> 192.168.10.146 is initiating an IKE_SA</con1|31></con1|31></con1|31></con1|31></con1|31></con1|31></con1|31>
    

    Seems to be rekeying now. ```
    ./iperf3 -c IPADDR -P 4 -f m -d -t 22 -O 2 -i 1

    
    However
    
    

    charon 10[CFG] <con1|37>lease 172.23.152.1 by 'ikemaster' went offline
    charon 10[IKE] <con1|37>IKE_SA con1[37] state change: DELETING => DESTROYING
    charon 10[IKE] <con1|37>IKE_SA deleted
    charon 10[ENC] <con1|37>parsed INFORMATIONAL response 2 [ ]
    charon 10[NET] <con1|37>received packet: from 192.168.10.146[4500] to 192.168.10.100[4500] (88 bytes)
    charon 10[NET] <con1|37>sending packet: from 192.168.10.100[4500] to 192.168.10.146[4500] (88 bytes)
    charon 10[ENC] <con1|37>generating INFORMATIONAL request 2 [ D ]
    charon 10[IKE] <con1|37>sending DELETE for IKE_SA con1[37]
    charon 10[IKE] <con1|37>IKE_SA con1[37] state change: ESTABLISHED => DELETING
    charon 10[IKE] <con1|37>deleting IKE_SA con1[37] between 192.168.10.100[XXXX]…192.168.10.146[ikemaster]
    charon 10[IKE] <con1|37>activating IKE_DELETE task
    charon 10[IKE] <con1|37>activating new tasks
    charon 10[IKE] <con1|37>queueing IKE_DELETE task</con1|37></con1|37></con1|37></con1|37></con1|37></con1|37></con1|37></con1|37></con1|37></con1|37></con1|37></con1|37></con1|37>

    
    it seems that pfSense itself queues and executes IKE_DELETE and it happens both on macOS and MSW.