Fix for IKEv2 VPN on Fortigate (bug in 5.0.0 MPPE support)

The Duo Auth Proxy 5.0.0 is now able to re-encrypt MPPE keys as associated with RADIUS-encapsulated EAP messages e.g. EAP-MSCHAPv2 as commonly used to authenticate IKEv2 VPNs, awesome! However in 5.0.0 there is a bug whereby the Message-Authenticator attribute is copied rather than being re-generated.

After pointing my Fortigate to a Duo Auth Proxy between it and FreeRADIUS, PAP authentication works fine (e.g. SSL VPN) but IKEv2 is unhappy.

Enable debugging on the Fortigate

diagnose debug application ike -1
diagnose debug application fnbamd -1
diagnose debug enable

And note the smoking gun

[1763] fnbamd_radius_auth_validate_pkt-Invalid digest
[1364] fnbamd_auth_handle_radius_result-Error validating radius rsp
[2708] handle_auth_rsp-Error (5) for req 2087461305

A packet capture on the Duo Auth Proxy server shows that the Message-Authenticator attribute is just being copied. Time to dig into the source.


    def create_accept_packet(
        # If there are any MPPE attributes in the radius_attrs, they will have
        # been decrypted for us by the radius client module. Re-encrypt them
        # with the authenticator and secret shared between the server module
        # and the appliance
        if any(a in base.MS_MPPE_RESPONSE_ATTRS for a in radius_attrs):
            send_key = radius_attrs["MS-MPPE-Send-Key"][0]
            recv_key = radius_attrs["MS-MPPE-Recv-Key"][0]

            # _create_response_packet put the unencrypted keys on the packet
            # since it copies over all radius_attrs. Remove them and add the
            # encrypted values
            del response_packet["MS-MPPE-Send-Key"]
            del response_packet["MS-MPPE-Recv-Key"]

        return response_packet

Hmm, this looks relevant. What if I try to re-generate the Message-Authenticator attribute after Duo’s finished mangling the message.

            del response_packet["Message-Authenticator"]

        return response_packet

Voila! Now the proxied RADIUS message can be authenticated by the Fortigate and IKEv2 VPNs work regardless of which auth method is used.

Hopefully this can be incorporated into 5.0.1 and released soon :slight_smile:


Please update to v5.0.1 to see if the Message-Authenticator fix resolves your issue.

(No, we didn’t create a v5.0.1 release overnight after your post. :slight_smile: )

v5.0.1 works, thanks!

I think I’ve encountered another MPPE handling bug, where the “server” RADIUS secret is used instead of the “client” secret to decrypt the MPPE keys. The workaround is to use the same secret for both sides, as I had been doing earlier.

I traced the source of the mixed-up secret as far as self.response.secret in lib/ and gave up once I had a workaround…

It may be worth adding check to decrypt_and_extract_mppe_key in lib/ along the lines of

if (key_length + 1) > len(decrypted_key):
    print("Something not quite right here...")

This issue still appears to exist in 5.1.0 when using different client/server secrets.

Hi @ryanm!

Thanks for your updates on this thread. The Duo Community isn’t the best place to report bugs or issues with the software, as our development teams may need additional information to investigate or resolve issues that shouldn’t be shared in a public forum.

If you haven’t already, please contact Duo Support to open an actual case for this.

Fixed in 5.1.1 after providing logs, configs, packet captures etc to support.