FortiGate
FortiGate Next Generation Firewall utilizes purpose-built security processors and threat intelligence security services from FortiGuard labs to deliver top-rated protection and high performance, including encrypted traffic.
pkavin
Staff
Staff
Article Id 207606
Description This article describes SSL-VPN Authentication using User Certificates as 1st Factor and LDAP/Radius for Username and Password as 2nd factor of authentication.
Scope FortiGate.
Solution

SSL-VPN Authentication with User Certificates 'ONLY' is given in the following document:

 

SSL VPN with LDAP-integrated certificate authentication.

 

But the following document covers how to use Username and Password as a 2nd factor which is configured on the remote authentication servers like LDAP/Radius along with User Certificates and User Certificate being the 1st factor.

 

This feature is implemented in 6.2.2 and 6.4.0 onwards.

 

SSL-VPN Authentication using User Certificates as 1st Factor and LDAP Username and Password as 2nd Factor.

 

Configuration on CLI:

 

  1. LDAP configuration.

 

config user ldap

    edit "LDAP"

        set server "20.20.20.3"

        set cnid "cn"

        set dn "dc=example,dc=com"

        set type regular

        set username "example\\Administrator"

        set password ENC #######

    next

end

 

It is also possible to use, set cnid=“sAMAccountName".

 

  1. PKI User.

 

config user peer

    edit "testuser"

        set ca "CA_Cert_1"

        set ldap-server "LDAP"

        set ldap-mode principal-name

    next

end

 

Note.

The 'CA_Cert_1' is the CA Certificate of the CA who signed the certificate for the user.

After the CA certificate is imported into the FortiGate then it will show up under the # set ca, command.

 

It is possible to use any Certificate Authority to sign the user’s certificate, provided that FortiGate trusts that CA.

For FortiGate to trust that CA, it should be either imported into the FortiGate, or it should be a well-known CA present in the FortiGate’s factory certificate bundle.

 

  1. User group.

     

    config user group

        edit "LDAP-SSLVPN"

            set member "LDAP"

        next

  2. SSL-VPN configuration.

 

config vpn ssl setting#

    set servercert "SSLVPN"

    set tunnel-ip-pools "SSLVPN_TUNNEL_ADDR1"

    set tunnel-ipv6-pools "SSLVPN_TUNNEL_IPv6_ADDR1"

    set source-interface "port2"

    set source-address "all"

    set source-address6 "all"

    set default-portal "full-access"

        config authentication-rule

            edit 1

                set groups "LDAP-SSLVPN"

                set portal "full-access"

                set client-cert enable

                set user-peer "testuser"

            next 

        end

end

 

  1. Firewall Policies.

 

config firewall policy

       edit 2

        set name "SSLVPN to Internet"

        set srcintf "ssl.root"

        set dstintf "port1"

        set srcaddr "SSLVPN_TUNNEL_ADDR1"     

        set dstaddr "all"

        set action accept

        set schedule "always"

        set service "ALL"

        set groups "LDAP-SSLVPN"

        set nat enable

    next

end

 

Topic 2: Authentication flow and Debugs for Topic no. 1.

 

Note.

Below are the filtered debugs which will explain the overview of the authentication flow.

 

  1. Session allocated by the SSL-VPN daemon:

 

[1639:root:cb]allocSSLConn:297 sconn 0x7f7cd7923100 (0:root)

 

  1. Fetch the user/group list from the Policy

     

    [1639:root:cd]sslvpn_auth_check_usrgroup:2610 forming user/group list from policy.

    [1639:root:cd]sslvpn_auth_check_usrgroup:2648 got user (0) group (1:0).

  2. Check the SSL-VPN Authentication rules to list the groups from those rules.


    1639:root:cd]sslvpn_validate_user_group_list:1800 validating with SSL-VPN authentication rules (1), realm ()[1639:root:cd]sslvpn_validate_user_group_list:1881 checking rule 1 cipher.

    [1639:root:cd]sslvpn_validate_user_group_list:1889 checking rule 1 realm.

    [1639:root:cd]sslvpn_validate_user_group_list:1900 checking rule 1 source intf.

    [1639:root:cd]sslvpn_validate_user_group_list:1939 checking rule 1 vd source intf.

    [1639:root:cd]sslvpn_validate_user_group_list:2185 rule 1 done, got user (0:0) group (1:1) peer group (0).[1639:root:cd]sslvpn_validate_user_group_list:2513 got user (0:0), group (1:1) peer group (0).

  3. Do certificate check, and for Certificate check send the request to FNBAM daemon.
    [1639:root:cd]fam_cert_send_req:1107 do certificate peer check first(2).
    [1639:root:cd]fam_cert_send_req:1179 doing certificate checking for 1 peer(s).

  4. FNBAM receives the request to do Certificate checking.

    [2395] handle_req-Rcvd auth_cert req id=1033441082, len=1106, opt=0

  5. Chain Validation is done by FNBAM.

    [103] __cert_chg_st- 'Init'

    [139] fnbamd_cert_load_certs_from_req-1 cert(s) in req.

    [99] __cert_chg_st- 'Init' -> 'Chain-Build'

    [712] __cert_build_chain-req_id=1033441082

    [199] fnbamd_chain_build-Chain discovery, opt 0x17, cur total 1

    [215] fnbamd_chain_build-Following depth 0

    [276] fnbamd_chain_build-Extend chain by system trust store. (good: 'CA_Cert_1')

    [215] fnbamd_chain_build-Following depth 1

    [229] fnbamd_chain_build-Self-sign detected.

    [99] __cert_chg_st- 'Chain-Build' -> 'Validation'

    [771] __cert_verify-req_id=1033441082

    [772] __cert_verify-Chain is complete.

  6. Check the Subject Name of the User Certificate. Configured Subject Name has not been configured in FortiGate’s PKI configuration (config user peer) so this check will pass automatically.

    [689] fnbamd_cert_check_group_list-checking group with name 'testuser'

    [503] __check_add_peer-check 'testuser'
    [383] peer_subject_cn_check-Cert subject 'CN = testuser'
    [419] peer_subject_cn_check-Subject is good.

  7. Fetch the LDAP server associated with the PKI user and prepare the LDAP search filter after fetching the UPN name field which is a part of the SAN field in the User Certificate.

    The LDAP search filter is the UPN name.

    [77] fnbamd_peer_ldap_push-Check LDAP setting of peer user 'testuser'
    [511] __check_add_peer-'testuser' check ret:pending
    [722] fnbamd_cert_check_group_list-LDAP servers
    [728] fnbamd_cert_check_group_list-    'LDAP', (Principle-Name), ref=2
    [193] __get_default_ocsp_ctx-def_ocsp_ctx=(nil), no_ocsp_query=0, ocsp_enabled=0
    [751] fnbamd_cert_check_group_list-Peer users
    [757] fnbamd_cert_check_group_list-    'testuser' ('LDAP','N/A')
    [808] __cert_verify_do_next-req_id=1033441082
    [99] __cert_chg_st- 'Validation' -> 'Status-Query'
    [641] __cert_status_query-req_id=1033441082
    [443] __cert_ldap_query-req_id=1033441082
    [450] __cert_ldap_query-LDAP query, idx 0
    [1713] fnbamd_ldap_init-search filter is: (&(userPrincipalName=testuser@example.com)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))
    [1722] fnbamd_ldap_init-search base is: dc=example,dc=com
    [1146] __fnbamd_ldap_dns_cb-Resolved LDAP:20.20.20.3 to 20.20.20.3, cur stack size:1
    [919] __fnbamd_ldap_get_next_addr-
    [1152] __fnbamd_ldap_dns_cb-Connection starts LDAP:20.20.20.3, addr 20.20.20.3
    [874] __fnbamd_ldap_start_conn-Still connecting 20.20.20.3.

  8. Admin Binding to the LDAP server.

    [981] __ldap_rxtx-state 3(Admin Binding)
    [363] __ldap_build_bind_req-Binding to 'example\Administrator'
    [1084] fnbamd_ldap_send-sending 47 bytes to 20.20.20.3
    [1096] fnbamd_ldap_send-Request is sent. ID 1
    [981] __ldap_rxtx-state 4(Admin Bind resp)
    [1127] __fnbamd_ldap_read-Read 8
    [1233] fnbamd_ldap_recv-Leftover 2
    [1127] __fnbamd_ldap_read-Read 14
    [1307] fnbamd_ldap_recv-Response len: 16, svr: 20.20.20.3
    [988] fnbamd_ldap_parse_response-Got one MESSAGE. ID:1, type:bind
    [1023] fnbamd_ldap_parse_response-ret=0

  9. After successful Admin Bind, search for the DN of the user using the filter which was prepared earlier. If the DN is returned successfully that means that the user is existing in the LDAP server’s database.

    [1048] __ldap_rxtx-Change state to 'DN search'
    [751] fnbamd_ldap_build_dn_search_req-base:'dc=example,dc=com' filter:(&(userPrincipalName=testuser@example.com)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))

    [1096] fnbamd_ldap_send-Request is sent. ID 2
    [1023] fnbamd_ldap_parse_response-ret=0
    [1220] __fnbamd_ldap_dn_entry-Get DN 'CN=testuser,CN=Users,DC=example,DC=com'

  10. If DN is returned means the user exists and the Certificate authentication is completed.

    [621] __ldap_membership_next-Auth accepted
    [1048] __ldap_rxtx-Change state to 'Done'

    [981] __ldap_rxtx-state 23(Done)
    [1084] fnbamd_ldap_send-sending 7 bytes to 20.20.20.3
    [1096] fnbamd_ldap_send-Request is sent. ID 3
    [785] __ldap_done-svr 'LDAP'
    [755] __ldap_destroy-
    [725] __ldap_stop-Conn with 20.20.20.3 destroyed.
    [402] __cert_ldap_query_cb-LDAP ret=0, server='LDAP', req_id=1033441082
    [413] __cert_ldap_query_cb-Matched peer 'testuser'
    [99] __cert_chg_st- 'Status-Query' -> 'Done'
    [853] __cert_done-req_id=1033441082

    [1671] __auth_cert_session_done-id=1033441082

  11. FNBAM sends the Certificate Authentication results back to SSL-VPN daemon.

    [217] fnbamd_comm_send_result-Sending result 0 (nid 672) for req 1033441082, len=2066
    [1639:root:cd]__auth_cert_cb:912 certificate check OK, matched peer [testuser].

  12. SSL-VPN now sends the LDAP group to FNBAM for Username and Password authentication.

    [1639:root:cd][fam_auth_send_req_internal:424] Groups sent to FNBAM:
    [1639:root:cd]group_desc[0].grpname = LDAP-SSLVPN

  13. FNBAM handles this new request from the SSL-VPN daemon. As the auth req ID is +1 of the previous request ID (1033441082), thus user and password authentication follows after certificate authentication.

    [1937] handle_req-Rcvd auth req 1033441083 for testuser in  opt=00200421 prot=11
    [429] __compose_group_list_from_req-Group 'LDAP-SSLVPN', type 1
    [1083] __fnbamd_cfg_get_ldap_list_by_group-Loaded LDAP server 'LDAP' for usergroup 'LDAP-SSLVPN' (2)
    [1713] fnbamd_ldap_init-search filter is: cn=testuser
    [1722] fnbamd_ldap_init-search base is: dc=example,dc=com
    [1103] __ldap_connect-tcps_connect(20.20.20.3) is established.

  14. Admin Bind to the LDAP server again. Once the LDAP bind is successful then DN search starts.

    [981] __ldap_rxtx-state 3(Admin Binding)
    [363] __ldap_build_bind_req-Binding to 'example\Administrator'
    [1023] fnbamd_ldap_parse_response-ret=0

  15. DN Search. The filter used is cn=testuser and not the UPN name this time.[1048] __ldap_rxtx-Change state to 'DN search'

    [751] fnbamd_ldap_build_dn_search_req-base:'dc=example,dc=com' filter:cn=testuser
    [981] __ldap_rxtx-state 12(DN search resp)
    [1023] fnbamd_ldap_parse_response-ret=0
    [1220] __fnbamd_ldap_dn_entry-Get DN 'CN=testuser,CN=Users,DC=example,DC=com'
    [988] fnbamd_ldap_parse_response-Got one MESSAGE. ID:2, type:search-result
    [1023] fnbamd_ldap_parse_response-ret=0

  16. Starts User Bind on the DN returned.


    [1048] __ldap_rxtx-Change state to 'User Binding'
    [981] __ldap_rxtx-state 5(User Binding)
    [596] fnbamd_ldap_build_userbind_req-Trying DN 'CN=testuser,CN=Users,DC=example,DC=com'
    [1023] fnbamd_ldap_parse_response-ret=0

  17. Attribute query to fetch the group membership information once User bind is completed.

    [1048] __ldap_rxtx-Change state to 'Attr query'
    [649] fnbamd_ldap_build_attr_search_req-Adding attr 'memberOf'
    [661] fnbamd_ldap_build_attr_search_req-base:'CN=testuser,CN=Users,DC=example,DC=com' filter:cn=*
    [981] __ldap_rxtx-state 8(Attr query resp)
    [1023] fnbamd_ldap_parse_response-ret=0
    [556] __get_member_of_groups-Get the memberOf groups.
    [522] __retrieve_group_values-Get the memberOf groups.

    [527] __retrieve_group_values-attr='memberOf' - found 0 values
    [1300] __fnbamd_ldap_attr_next-Entering CHKPRIMARYGRP state
    [1023] fnbamd_ldap_parse_response-ret=0
    [472] __get_one_group-group: CN=Domain Users,CN=Users,DC=example,DC=com
    [785] __ldap_done-svr 'LDAP'
    [2770] fnbamd_ldap_result-Result for ldap svr 20.20.20.3 is SUCCESS
    [401] ldap_copy_grp_list-copied CN=Domain Users,CN=Users,DC=example,DC=com
    [2781] fnbamd_ldap_result-Passed group matching
    [1064] find_matched_usr_grps-Group 'LDAP-SSLVPN' passed group matching[1065] find_matched_usr_grps-Add matched group 'LDAP-SSLVPN'(2)

  18. FNBAM sends the result to the SSL-VPN daemon.

    [217] fnbamd_comm_send_result-Sending result 0 (nid 0) for req 1033441083, len=2104
    [1639:root:cd]fam_auth_proc_resp:1264 fnbam_auth_update_result return: 0
    [1639:root:cd]fam_do_cb:665 fnbamd return auth success.[1639:root:cd]SSL VPN login matched rule (1).

  19. SSL-VPN connects.


[1639:root:ce]Will add auth policy for policy 2 for user testuser:LDAP-SSLVPN
[1639:root:ce]Add auth logon for user testuser:LDAP-SSLVPN, matched group number 1
[1639:root:ce]fsv_associate_fd_to_ipaddr:1664 associate 10.212.134.200 to tun (ssl.root:35)
[1639:root:cd]sslvpn_read_request_common,656, ret=-1 error=-1, sconn=0x7f7cd7923100.

 

Topic 3: SSL-VPN Authentication using User Certificates as 1st Factor and Radius Username and Password as 2nd Factor.

 

The flow for this is more or less the same.

It is necessary to add a Radius group that references a Radius server in the SSL-VPN configuration and in the Firewall policies.

 

1st factor of authentication using User Certificates will happen using the LDAP server ONLY. The 2nd factor of authentication using username and password will happen using the Radius server.

 

Configuration on CLI:

 

  1. LDAP configuration: Same as above.
  2. PKI user: Same as above.
  3. User groups.

    config user group
        edit "Radius-SSLVPN"
            set member "Radius"
        next
    end

  4. SSL-VPN configuration.

    config vpn ssl setting
        set servercert "SSLVPN"
        set tunnel-ip-pools "SSLVPN_TUNNEL_ADDR1"
        set tunnel-ipv6-pools "SSLVPN_TUNNEL_IPv6_ADDR1"
        set source-interface "port2"
        set source-address "all"
        set source-address6 "all"
        set default-portal "full-access"
            config authentication-rule
                edit 1
                    set groups "Radius-SSLVPN"
                    set portal "full-access"
                    set client-cert enable
                    set user-peer "testuser"
                next
            end
    end
  5. Firewall policies.

config firewall policy

    edit 2

        set name "SSLVPN to Internet"

        set uuid 72ba630e-4bfa-51ec-27f9-d1445c0282ed

        set srcintf "ssl.root"

        set dstintf "port1"

        set srcaddr "SSLVPN_TUNNEL_ADDR1"

        set dstaddr "all"

        set action accept

        set schedule "always"

        set service "ALL"

        set groups "Radius-SSLVPN"

        set nat enable

    next

end

 

Topic 4: Authentication flow and Debugs for Topic no. 3.

 

The first part of authentication by 1st factor i.e. by using the User Certificate is exactly the same as the Authentication flow discussed in Topic 2).

Below is are the debugs for the 2nd part i.e. Username and Password authentication using Radius.

 

  1. Groups sent by SSL-VPN daemon to FNBAM.

[1639:root:d2][fam_auth_send_req_internal:424] Groups sent to FNBAM:

[1639:root:d2]group_desc[0].grpname = Radius-SSLVPN

 

  1. Contacting the Radius server and sending Radius Access-Request and got Radius Access-Accept (response code 2) packet. FNBAM sends result to SSL-VPNdaemon.

 

[569] __fnbamd_cfg_get_radius_list_by_group-Loading RADIUS server 'Radius' for usergroup 'Radius-SSLVPN' (4)

[1391] fnbamd_radius_auth_send-Compose RADIUS request

[1329] __fnbamd_rad_send-Sent radius req to server 'Radius': fd=13, IP=20.20.20.3(20.20.20.3:1812) code=1 id=10 len=127 user="testuser" using PAP

 [1797] fnbamd_radius_auth_validate_pkt-RADIUS resp code 2

[1414] fnbamd_auth_handle_radius_result-->Result for radius svr 'Radius' 20.20.20.3(1) is 0

[1338] fnbamd_radius_group_match-Passed group matching

[1064] find_matched_usr_grps-Group 'Radius-SSLVPN' passed group matching

[1065] find_matched_usr_grps-Add matched group 'Radius-SSLVPN'(4)

[217] fnbamd_comm_send_result-Sending result 0 (nid 0) for req 1033441085, len=2105

[1639:root:d2]Auth successful for user testuser in group Radius-SSLVPN

[1639:root:d2]Auth successful for group [Radius-SSLVPN] with matched user-peer [testuser]

 

3. SSL-VPN Connects.

[1639:root:d3]Will add auth policy for policy 2 for user testuser:Radius-SSL-VPN
[1639:root:d3]Add auth logon for user testuser:Radius-SSLVPN, matched group number 1
[1639:root:d3]tunnel2_enter:1108 Framed IP is set to 10.212.134.200
[1639:root:d3]fsv_associate_fd_to_ipaddr:1664 associate 10.212.134.200 to tun (ssl.root:35)
[1639:root:d2]sslvpn_read_request_common,656, ret=-1 error=-1, sconn=0x7f7cd7920900. <\ol>

 

 

Related article:

Technical Tip: Combining remote user authentication and client certificates in SSL VPN.