Fortinet Document Library

Version:

Version:

Version:

Version:


Table of Contents

Administration Guide

Download PDF
Copy Link

mTLS client certificate authentication

FortiGate supports client certificate authentication used in mutual Transport Layer Security (mTLS) communication between a client and server. Clients are issued certificates by the CA, and an access proxy configured on the FortiGate uses the new certificate method in the authentication scheme to identify and approve the certificate provided by the client when they try to connect to the access proxy. The FortiGate can also add the HTTP header X-Forwarded-Client-Cert to forward the certificate information to the server.

Examples

In these examples, the access proxy VIP IP address is 10.1.100.200.

Example 1

In this example, clients are issued unique client certificates from your CA. The FortiGate authenticates the clients by their user certificate before allowing them to connect to the access proxy. The access server acts as a reverse proxy for the web server that is behind the FortiGate.

This example assumes that you have already obtained the public CA certificate from your CA, the root CA of the client certificate has been imported (CA_Cert_1), and the client certificate has been distributed to the endpoints.

To configure the FortiGate:
  1. Configure user authentication. Both an authentication scheme and rule must be configured, as the authentication is applied on the access proxy:

    config authentication scheme
        edit "mtls"
            set method cert
            set user-cert enable
        next
    end
    config authentication rule
        edit "mtls"
            set srcintf "port2"
            set srcaddr "all"
            set dstaddr "all"
            set active-auth-method "mtls"
        next
    end
  2. Select the CA or CAs used to verify the client certificate:

    config authentication setting
        set user-cert-ca "CA_Cert_1"
    end
  3. Configure the users. Users can be matched based on either the common-name on the certificate or the trusted issuer.

    • Verify the user based on the common name on the certificate:

      config user certificate
          edit "single-certificate"
              set type single-certificate
              set common-name "client.fortinet.com"
          next
      end
    • Verify the user based on the CA issuer:

      config user certificate
          edit "trusted-issuer"
              set type trusted-issuer
              set issuer "CA_Cert_1"
          next
      end
  4. Configure the access proxy VIP. The SSL certificate is the server certificate that is presented to the user as they connect:

    config firewall vip
        edit "mTLS"
            set type access-proxy
            set extip 10.1.100.200
            set extintf "port2"
            set server-type https
            set extport 443
            set ssl-certificate "Fortinet_CA_SSL"
        next
    end
  5. Configure the access proxy policy, including the real server to be mapped. To request the client certificate for authentication, client-cert is enabled:

    config firewall access-proxy
        edit "mTLS-access-proxy"
            set vip "mTLS"
            set client-cert enable
            set empty-cert-action accept
            config api-gateway
                edit 1
                    config realservers
                        edit 1
                            set ip 172.16.200.44
                        next
                    end
                next
            end
        next
    end
  6. Configure the firewall policy to allow the client to connect to the access proxy:

    config firewall policy
        edit 1
            set srcintf "port2"
            set dstintf "any"
            set action accept
            set srcaddr "all"
            set dstaddr "mTLS"
            set schedule "always"
            set service "ALL"
            set inspection-mode proxy
            set logtraffic all
            set nat enable
        next
    end
  7. Configure the proxy policy to apply authentication and the security profile, selecting the appropriate user object depending on the user type:

    config firewall proxy-policy
        edit 3
            set proxy access-proxy
            set access-proxy "mTLS-access-proxy"
            set srcintf "port2"
            set srcaddr "all"
            set dstaddr "all"
            set action accept
            set schedule "always"
            set users {"single-certificate" | "trusted-issuer"}
            set utm-status enable
            set ssl-ssh-profile "deep-inspection-clone"
            set av-profile "av"
        next
    end
To verify the results:
  1. In a web browser, access the VIP address. This example uses Chrome.

  2. When prompted, select the client certificate, then click OK.

  3. Click Certificate information to view details about the certificate.

  4. On the FortiGate, check the traffic logs.

    • If client certificate authentication passes:

      1: date=2021-06-03 time=15:48:36 eventtime=1622760516866635697 tz="-0700" logid="0000000010" type="traffic" subtype="forward" level="notice" vd="vdom1" srcip=10.1.100.11 srcport=45532 srcintf="port2" srcintfrole="undefined" dstcountry="Reserved" srccountry="Reserved" dstip=172.16.200.44 dstport=443 dstintf="vdom1" dstintfrole="undefined" sessionid=154900 service="HTTPS" wanoptapptype="web-proxy" proto=6 action="accept" policyid=3 policytype="proxy-policy" poluuid="af5e2df2-c321-51eb-7d5d-42fa58868dcb" duration=0 user="single-certificate" wanin=2550 rcvdbyte=2550 wanout=627 lanin=4113 sentbyte=4113 lanout=2310 appcat="unscanned"
    • If the CA issuer is used to verify the client:

      1: date=2021-06-03 time=15:43:02 eventtime=1622760182384776037 tz="-0700" logid="0000000010" type="traffic" subtype="forward" level="notice" vd="vdom1" srcip=10.1.100.11 srcport=45514 srcintf="port2" srcintfrole="undefined" dstcountry="Reserved" srccountry="Reserved" dstip=10.1.100.200 dstport=443 dstintf="vdom1" dstintfrole="undefined" sessionid=153884 service="HTTPS" wanoptapptype="web-proxy" proto=6 action="accept" policyid=3 policytype="proxy-policy" poluuid="af5e2df2-c321-51eb-7d5d-42fa58868dcb" duration=0 user="trusted-issuer" wanin=0 rcvdbyte=0 wanout=0 lanin=4089 sentbyte=4089 lanout=7517 appcat="unscanned" utmaction="block" countweb=1 crscore=30 craction=8 utmref=65535-0
    • If the client certificate authentication fails, and the traffic is blocked:

      1: date=2021-06-03 time=15:45:53 eventtime=1622760353789703671 tz="-0700" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="vdom1" srcip=10.1.100.11 srcport=45518 srcintf="port2" srcintfrole="undefined" dstip=172.16.200.44 dstport=443 dstintf="vdom1" dstintfrole="undefined" srccountry="Reserved" dstcountry="Reserved" sessionid=154431 proto=6 action="deny" policyid=0 policytype="proxy-policy" user="single-certificate" service="HTTPS" trandisp="noop" url="https://10.1.100.200/" agent="curl/7.68.0" duration=0 sentbyte=0 rcvdbyte=0 sentpkt=0 rcvdpkt=0 appcat="unscanned" crscore=30 craction=131072 crlevel="high" msg="Traffic denied because of explicit proxy policy"

Example 2

In this example, the same configuration as in Example 1 is used, with a web proxy profile added to enable adding the client certificate to the HTTP header X-Forwarded-Client-Cert. The header is then forwarded to the server.

To configure the FortiGate:
  1. Repeat steps 1 to 6 of Example 1, using the common name on the certificate to verify the user.

  2. Configure a web proxy profile that adds the HTTP x-forwarded-client-cert header in forwarded requests:

    config web-proxy profile
        edit "mtls"
            set header-x-forwarded-client-cert add
        next
    end
  3. Configure the proxy policy to apply authentication, the security profile, and web proxy profile:

    config firewall proxy-policy
        edit 3
            set uuid af5e2df2-c321-51eb-7d5d-42fa58868dcb
            set proxy access-proxy
            set access-proxy "mTLS-access-proxy"
            set srcintf "port2"
            set srcaddr "all"
            set dstaddr "all"
            set action accept
            set schedule "always"
            set logtraffic all
            set users "single-certificate"
            set webproxy-profile "mtls"
            set utm-status enable
            set ssl-ssh-profile "deep-inspection-clone"
            set av-profile "av"
        next
    end
To verify the results:

The WAD debug shows that the FortiGate adds the client certificate information to the HTTP header. The added header cannot be checked using the sniffer, because the FortiGate encrypts the HTTP header to forward it to the server.

  1. Enable WAD debug on all categories:

    # diagnose wad debug enable category all
  2. Set the WAD debug level to verbose:

    # diagnose wad debug enable level verbose
  3. Enable debug output:

    # diagnose debug enable
  4. Check the debug output.

    • When the FortiGate receives the client HTTP request:

      [0x7fc8d4bc4910] Received request from client: 10.1.100.11:45544
      
      GET / HTTP/1.1
      Host: 10.1.100.200
      User-Agent: curl/7.68.0
      Accept: */*
    • When the FortiGate adds the client certificate in to the HTTP header and forwards the client HTTP request:

      [0x7fc8d4bc4910] Forward request to server:
      GET / HTTP/1.1
      Host: 172.16.200.44
      User-Agent: curl/7.68.0
      Accept: */*
      X-Forwarded-Client-Cert: -----BEGIN CERTIFICATE-----
      MIIFXzCCA0egAwI...aCFHDHlR+wb39s=
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      MIIFpTCCA42gAwI...OtDtetkNoFLbvb
      -----END CERTIFICATE-----

mTLS client certificate authentication

FortiGate supports client certificate authentication used in mutual Transport Layer Security (mTLS) communication between a client and server. Clients are issued certificates by the CA, and an access proxy configured on the FortiGate uses the new certificate method in the authentication scheme to identify and approve the certificate provided by the client when they try to connect to the access proxy. The FortiGate can also add the HTTP header X-Forwarded-Client-Cert to forward the certificate information to the server.

Examples

In these examples, the access proxy VIP IP address is 10.1.100.200.

Example 1

In this example, clients are issued unique client certificates from your CA. The FortiGate authenticates the clients by their user certificate before allowing them to connect to the access proxy. The access server acts as a reverse proxy for the web server that is behind the FortiGate.

This example assumes that you have already obtained the public CA certificate from your CA, the root CA of the client certificate has been imported (CA_Cert_1), and the client certificate has been distributed to the endpoints.

To configure the FortiGate:
  1. Configure user authentication. Both an authentication scheme and rule must be configured, as the authentication is applied on the access proxy:

    config authentication scheme
        edit "mtls"
            set method cert
            set user-cert enable
        next
    end
    config authentication rule
        edit "mtls"
            set srcintf "port2"
            set srcaddr "all"
            set dstaddr "all"
            set active-auth-method "mtls"
        next
    end
  2. Select the CA or CAs used to verify the client certificate:

    config authentication setting
        set user-cert-ca "CA_Cert_1"
    end
  3. Configure the users. Users can be matched based on either the common-name on the certificate or the trusted issuer.

    • Verify the user based on the common name on the certificate:

      config user certificate
          edit "single-certificate"
              set type single-certificate
              set common-name "client.fortinet.com"
          next
      end
    • Verify the user based on the CA issuer:

      config user certificate
          edit "trusted-issuer"
              set type trusted-issuer
              set issuer "CA_Cert_1"
          next
      end
  4. Configure the access proxy VIP. The SSL certificate is the server certificate that is presented to the user as they connect:

    config firewall vip
        edit "mTLS"
            set type access-proxy
            set extip 10.1.100.200
            set extintf "port2"
            set server-type https
            set extport 443
            set ssl-certificate "Fortinet_CA_SSL"
        next
    end
  5. Configure the access proxy policy, including the real server to be mapped. To request the client certificate for authentication, client-cert is enabled:

    config firewall access-proxy
        edit "mTLS-access-proxy"
            set vip "mTLS"
            set client-cert enable
            set empty-cert-action accept
            config api-gateway
                edit 1
                    config realservers
                        edit 1
                            set ip 172.16.200.44
                        next
                    end
                next
            end
        next
    end
  6. Configure the firewall policy to allow the client to connect to the access proxy:

    config firewall policy
        edit 1
            set srcintf "port2"
            set dstintf "any"
            set action accept
            set srcaddr "all"
            set dstaddr "mTLS"
            set schedule "always"
            set service "ALL"
            set inspection-mode proxy
            set logtraffic all
            set nat enable
        next
    end
  7. Configure the proxy policy to apply authentication and the security profile, selecting the appropriate user object depending on the user type:

    config firewall proxy-policy
        edit 3
            set proxy access-proxy
            set access-proxy "mTLS-access-proxy"
            set srcintf "port2"
            set srcaddr "all"
            set dstaddr "all"
            set action accept
            set schedule "always"
            set users {"single-certificate" | "trusted-issuer"}
            set utm-status enable
            set ssl-ssh-profile "deep-inspection-clone"
            set av-profile "av"
        next
    end
To verify the results:
  1. In a web browser, access the VIP address. This example uses Chrome.

  2. When prompted, select the client certificate, then click OK.

  3. Click Certificate information to view details about the certificate.

  4. On the FortiGate, check the traffic logs.

    • If client certificate authentication passes:

      1: date=2021-06-03 time=15:48:36 eventtime=1622760516866635697 tz="-0700" logid="0000000010" type="traffic" subtype="forward" level="notice" vd="vdom1" srcip=10.1.100.11 srcport=45532 srcintf="port2" srcintfrole="undefined" dstcountry="Reserved" srccountry="Reserved" dstip=172.16.200.44 dstport=443 dstintf="vdom1" dstintfrole="undefined" sessionid=154900 service="HTTPS" wanoptapptype="web-proxy" proto=6 action="accept" policyid=3 policytype="proxy-policy" poluuid="af5e2df2-c321-51eb-7d5d-42fa58868dcb" duration=0 user="single-certificate" wanin=2550 rcvdbyte=2550 wanout=627 lanin=4113 sentbyte=4113 lanout=2310 appcat="unscanned"
    • If the CA issuer is used to verify the client:

      1: date=2021-06-03 time=15:43:02 eventtime=1622760182384776037 tz="-0700" logid="0000000010" type="traffic" subtype="forward" level="notice" vd="vdom1" srcip=10.1.100.11 srcport=45514 srcintf="port2" srcintfrole="undefined" dstcountry="Reserved" srccountry="Reserved" dstip=10.1.100.200 dstport=443 dstintf="vdom1" dstintfrole="undefined" sessionid=153884 service="HTTPS" wanoptapptype="web-proxy" proto=6 action="accept" policyid=3 policytype="proxy-policy" poluuid="af5e2df2-c321-51eb-7d5d-42fa58868dcb" duration=0 user="trusted-issuer" wanin=0 rcvdbyte=0 wanout=0 lanin=4089 sentbyte=4089 lanout=7517 appcat="unscanned" utmaction="block" countweb=1 crscore=30 craction=8 utmref=65535-0
    • If the client certificate authentication fails, and the traffic is blocked:

      1: date=2021-06-03 time=15:45:53 eventtime=1622760353789703671 tz="-0700" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="vdom1" srcip=10.1.100.11 srcport=45518 srcintf="port2" srcintfrole="undefined" dstip=172.16.200.44 dstport=443 dstintf="vdom1" dstintfrole="undefined" srccountry="Reserved" dstcountry="Reserved" sessionid=154431 proto=6 action="deny" policyid=0 policytype="proxy-policy" user="single-certificate" service="HTTPS" trandisp="noop" url="https://10.1.100.200/" agent="curl/7.68.0" duration=0 sentbyte=0 rcvdbyte=0 sentpkt=0 rcvdpkt=0 appcat="unscanned" crscore=30 craction=131072 crlevel="high" msg="Traffic denied because of explicit proxy policy"

Example 2

In this example, the same configuration as in Example 1 is used, with a web proxy profile added to enable adding the client certificate to the HTTP header X-Forwarded-Client-Cert. The header is then forwarded to the server.

To configure the FortiGate:
  1. Repeat steps 1 to 6 of Example 1, using the common name on the certificate to verify the user.

  2. Configure a web proxy profile that adds the HTTP x-forwarded-client-cert header in forwarded requests:

    config web-proxy profile
        edit "mtls"
            set header-x-forwarded-client-cert add
        next
    end
  3. Configure the proxy policy to apply authentication, the security profile, and web proxy profile:

    config firewall proxy-policy
        edit 3
            set uuid af5e2df2-c321-51eb-7d5d-42fa58868dcb
            set proxy access-proxy
            set access-proxy "mTLS-access-proxy"
            set srcintf "port2"
            set srcaddr "all"
            set dstaddr "all"
            set action accept
            set schedule "always"
            set logtraffic all
            set users "single-certificate"
            set webproxy-profile "mtls"
            set utm-status enable
            set ssl-ssh-profile "deep-inspection-clone"
            set av-profile "av"
        next
    end
To verify the results:

The WAD debug shows that the FortiGate adds the client certificate information to the HTTP header. The added header cannot be checked using the sniffer, because the FortiGate encrypts the HTTP header to forward it to the server.

  1. Enable WAD debug on all categories:

    # diagnose wad debug enable category all
  2. Set the WAD debug level to verbose:

    # diagnose wad debug enable level verbose
  3. Enable debug output:

    # diagnose debug enable
  4. Check the debug output.

    • When the FortiGate receives the client HTTP request:

      [0x7fc8d4bc4910] Received request from client: 10.1.100.11:45544
      
      GET / HTTP/1.1
      Host: 10.1.100.200
      User-Agent: curl/7.68.0
      Accept: */*
    • When the FortiGate adds the client certificate in to the HTTP header and forwards the client HTTP request:

      [0x7fc8d4bc4910] Forward request to server:
      GET / HTTP/1.1
      Host: 172.16.200.44
      User-Agent: curl/7.68.0
      Accept: */*
      X-Forwarded-Client-Cert: -----BEGIN CERTIFICATE-----
      MIIFXzCCA0egAwI...aCFHDHlR+wb39s=
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      MIIFpTCCA42gAwI...OtDtetkNoFLbvb
      -----END CERTIFICATE-----