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:
-
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
-
Select the CA or CAs used to verify the client certificate:
config authentication setting set user-cert-ca "CA_Cert_1" end
-
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
-
-
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
-
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
-
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:
-
In a web browser, access the VIP address. This example uses Chrome.
-
When prompted, select the client certificate, then click OK.
-
Click Certificate information to view details about the certificate.
-
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:
-
Repeat steps 1 to 6 of Example 1, using the common name on the certificate to verify the user.
-
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
-
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.
-
Enable WAD debug on all categories:
# diagnose wad debug enable category all
-
Set the WAD debug level to verbose:
# diagnose wad debug enable level verbose
-
Enable debug output:
# diagnose debug enable
-
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-----
-