ZTNA
Sx11
Staff
Staff
Article Id 259247
Description

 

This article describes configuration steps used to implement ZTNA HTTP access proxy for Corporate Hosts attempting to access an internally protected Web Server.

In addition to Device verification through EMS, the user will be prompted to authenticate through SAML in order to access the internal Web page.

 

Scope

 

ZTNA, FortiGate, FortiAuthenticator, FortiEMS, SAML.

 

Solution

 

The environment used for this case:

 

ZTNAdiagram.png

 

ZTNA flow with SAML authentication:

 

  1. FortiClient connects to EMS in order to get configuration and register as an endpoint ( ZTNA telemetry).
  2. EMS issues the Device certificates to connect FortiClient endpoints and syncs to FortiGate in order to share Device certificates plus ZTNA Tags.
  3. The user uses the ZTNA Agent (FortiClient or Browser) to connect to FortiOS Access Proxy(FortiGate).
  4. FortiGate acting as an access proxy validates the Device Identity/posture and if these are successful it will then trigger User Authentication (SAML with FAC as IDP).
  5. When authentication is successful then a session is established in FortiOS which allows the user to access the Application or web resource.

Access to the application is granted only after:

 

  • Device verification (Certificates issued by EMS CA certificate ZTNA).
  • Posture check through Zero Trust tags.
  • User Authentication and Authorization.

 

Configuration:

 

The configuration is simplified by using only IP addresses to reference the Servers and Endpoints.

The scope of the article is to show the operation flow and relevant events that need to be checked when troubleshooting similar scenarios.

In a production environment, it is expected that customers to have proper Certificate Management and use FQDNs.

 

Step 1: Configure the Fabric Connection FGT <-> EMS.

 

a. EMS configuration.

Go to System Settings -> EMS settings:

 

EMSEMSconfig.png

Note:

 

Webserver Certificate - This is the server certificate identifying EMS for HTTPS access and Fabric connection.

EMS CA Certificate (ZTNA) - This is the CA certificate that EMS uses to Generate Client Certificates with FortiClient ID which are sent to FortiGate for Device verification.

 

b. FortiGate Config.

 

In FortiGate go to Security Fabric -> Fabric Connectors and add the EMS IP.

 

EMSconfig.png

 

The administrator will be prompted to Authorize the integration with EMS on FortiGate.

 

CLI config:

 

config endpoint-control fctems
    edit 1
        set status enable
        set name "EMSserver"
        set server "192.168.10.6"
        set serial-number "FCTEMS********"
        set capabilities fabric-auth silent-approval websocket websocket-malware push-ca-certs common-tags-api
        set ca-cn-info "OU = global.lab.net, CN = global.lab.netEMSserver.Domain1.local"
    next
end

 

Step 2 Configure ZTNA Tagging Rules in EMS.

 

a. Create Zero trust Tags.

Consider tagging the Corporate Hosts with a tag named 'Corporate_host'.

So once EMS detects a Windows Device is connected and communicating it will issue a Certificate to the FortiClient device and assign the matching TAG based on our rule.

 

This way, the hosts are identified as part of the corporate.

Additional rules can be added to make the rule more complex.

 

EMS_tag_creation.png

 

b. Verify the Zero trust Tag on the FortiClient endpoint.

In order to check what TAGs are the Endpoint matching it is necessary to enable the following option in EMS:

Go to Endpoint Profiles -> System Settings -> Edit the Default profile.

Enable 'Show Zero Trust Tag on FortiClient GUI'.

 

Zero_trust_TAG.png

 

Validate the host is matching the Corporate Host Tag by selecting the Username on the top left in FortiClient Dashboard:

Tag_on_forticlient.png

 

c. Validate Zero trust Tags are being synced in FortiGate.

Go to Policy & Objects -> ZTNA -> ZTNA Tags (The ZTNA feature must be enabled in System -> Feature Visibility in order to appear on the GUI).

 

ZTNAtags_fortigate_check.png

 

 

  • When the FortiGate establishes a connection with the FortiClient EMS server via the EMS Fabric connector, it pulls zero-trust tags containing device IP and MAC addresses and converts them to read-only dynamic address objects.
  • It also establishes a persistent WebSocket connection to monitor for changes in zero-trust tags, which keeps the device information current.

Synchronizing FortiClient ZTNA tags.

 

Step 3. Configure FortiAuthenticator as SAML IDP.

 

FortiAuthenticator is already integrated with an LDAP server where user 'jdoe' is imported and made part of groups: 'EU_Group' and 'Remote_LDAP'.

These two groups are used as filters for authentication.

Additionally, IDP and SP certificates have been created for both FortiAuthenticator(IDP) and FortiGate(SP) using a Local CA certificate.

The following documentation shows the certificate creation process: Certificate management.

 

a. Go to Authentication -> SAML IDP -> General.

Configure the relevant AD realm where the remote LDAP user is part of and filter for the groups.

Add the newly created IDP certificate.

 

FAC_IDP_cert.png

Leave other settings as default and save.

 

b. Go to Authentication -> SAML IDP -> Service Providers.

Complete the SAML SP configuration:

 

SPconfig1FAC.png

Add the following attributes to match user information that will be sent to the SP:

 

Assertion_attributeFAC.png

 

Leave other settings as default and save.

 

Step 4. FortiGate configuration.

 

a. Create the SAML SP entry in FortiGate.

 

Go to User & Authentication -> Single Sign-on -> Create new.

 

SP_config1FGT.png

 

In the Identity Provider configuration the 'REMOTE_Cert_3' is the imported FAC IDP certificate.

 

CLI config:

 

config user saml
    edit "SP2_test"
        set cert "FGT_SP_latest"
        set entity-id "http://10.10.10.1:8443/remote/saml/metadata/"
        set single-sign-on-url "https://10.10.10.1:8443/remote/saml/login"
        set single-logout-url "https://10.10.10.1:8443/remote/saml/login"
        set idp-entity-id "http://192.168.10.10:443/saml-idp/fortinet/metadata/"
        set idp-single-sign-on-url "https://192.168.10.10:443/saml-idp/fortinet/login/"
        set idp-single-logout-url "https://192.168.10.10:443/saml-idp/fortinet/logout/"
        set idp-cert "REMOTE_Cert_3"
        set user-name "username"
        set group-name "group"
        set digest-method sha1
    next

 

b. Create the SAML group in FortiGate.

Go to User & Authentication -> User Groups.

Create the group and add the newly created SAML instance as the Remote Server.

 

SAML_groupFGT.png

c. Create the Authentication Scheme, Rule, and authentication settings.

 

c.1. Go to Policy&Objects -> Authentication Rules and select Authentication Scheme on the top right:

Configure the Authentication Scheme by selecting the SAML method and referencing the SAML instance created previously.

 

Auth_Scheme.png

 

CLI configuration:

 

config authentication scheme
    edit "ZTNA_SAML"
        set method saml
        set saml-server "SP2_test"
    next
end

 

c.2. Configure the Authentication Rule:

Auth_Rule.png

 

 

CLI configuration:

 

config authentication rule
    edit "ZTNA_Rule"
        set srcintf "any"
        set srcaddr "all"
        set active-auth-method "ZTNA_SAML"
    next
end


c.3. Configure the captive portal:


config authentication setting
    set active-auth-scheme "ZTNA_SAML"
    set captive-portal-type IP
    set captive-portal-ip 10.10.10.1
    set captive-portal-port 9998
end

 

d. Configure the ZTNA Server and ZTNA rule.

Go to Policy&Objects -> ZTNA.

 

d.1. Create the ZTNA Server:

 

ZTNAServer.png

Add a Server/service mapping:

 

Serviceserver_mapping.png

CLI config:

 

config firewall access-proxy
    edit "WebServer"
        set vip "WebServer"
        set client-cert enable
            config api-gateway
                edit 1
                    set service HTTP
                        config realservers
                            edit 1
                                set ip 192.168.10.4
                                set port 80
                            next
                        end
                next
                edit 2
                    set service samlsp
                    set saml-server "SP2_test"
                next
            end
    next
end

 

d.2. Configure the ZTNA rule:

 

ZTNA_rule.png

 

Leave other settings as default.

 

CLI config:

 

config firewall proxy-policy

    edit 2
        set uuid e83fb0c6-0066-51ee-965e-7f0f97862e74
        set name "Web_Server_Access"
        set proxy access-proxy
        set access-proxy "WebServer"
        set srcintf "port3"
        set srcaddr "all"
        set dstaddr "all"
        set ztna-ems-tag "EMS1_ZTNA_Corporate_host"
        set ztna-tags-match-logic and
        set action accept
        set schedule "always"
        set logtraffic all
        set groups "Remote_SAML_FACIDP"
    next
end

 

Step 5 Validation and Debugging.

 

To troubleshoot similar cases, it is necessary to enable the below debugs in FortiGate CLI:

 

diag debug console timestamp enable
dia de app samld -1
dia de app fnbamd -1

diagnose wad debug enable category all
diag wad debug enable level verbose

diagnose debug enable

 

When trying to access the protected web page, it will initially be prompted by FortiGate to provide the client Certificate. This is the Certificate issued to the Device from the EMS ZTNA CA certificate.

It is necessary to select the certificate and then press ok.

ZTNA_certificate_check.png

 

At this point, FortiGate will perform a device identity check by validating the Client certificate and also performing a posture check (ZTNA tag matching).

Relevant events:

 

[p:229][s:5018004] wad_vs_ssl_access_proxy_on_clt_certs:11991 1:WebServer: cert cache cert(0x7f2ef4d80bf8) authi(0x
[p:229][s:5018004] wad_vs_ssl_access_proxy_on_clt_certs:11996 1:WebServer: vs, Found the cert, and issued by:ems
[p:229][s:5018004] wad_vs_ssl_access_proxy_on_clt_certs:12001 1:WebServer: hit the cached auth_result(7)
[p:229][s:5018004] wad_vs_ssl_access_proxy_on_clt_certs:12035 1:WebServer: Cert auth success. issued_by: ems

 

[V][p:229][s:11405486][r:51] wad_dev_addr_match :282 conf tag name:EMS1_ZTNA_Corporate_host(24) matched, id = 4, tag_index = 5!
[I][p:229][s:11405486][r:51] wad_auth_rule_match :1260 match auth rule succ: ZTNA_Rule
[I][p:229][s:11405486][r:51] wad_http_req_get_user :10437 process=229 auth-rule=ZTNA_Rule user=/0/0 ip-based/auth-cookie/transact=1/0/0 tp_proxy_auth=1 auth_req=(nil) auth_line=(nil)
[V][p:229][s:11405705][r:53] wad_dev_addr_match :282 conf tag name:EMS1_ZTNA_Corporate_host(24) matched, id = 4, tag_index = 5!
[I][p:229][s:11405705][r:53] wad_auth_rule_match :1260 match auth rule succ: ZTNA_Rule
[I][p:229][s:11405705][r:53] wad_http_req_get_user :10437 process=229 auth-rule=ZTNA_Rule user=/0/0 ip-based/auth-cookie/transact=1/0/0 tp_proxy_auth=1 auth_req=(nil) auth_line=(nil)

 

If this part is ok then FortiGate will redirect the client to the Fortiauthenticator IDP for authentication.

 

SAML_ZTNA_redirection.png

[[V][p:229] saml_ipc_on_read :268 Rcvd 12511 bytes from SAMLD: rc=0
[V][p:229] hauth_saml_aqueue_key_hash :2229 called
[V][p:229] hauth_saml_on_notify :1254 called
[V][p:229] hauth_saml_on_notify :1319 called
[V][p:229] hauth_saml_grpinfo_parse :1201 SAML RESP: attr 'group' = 'Remote_LDAP'
[I][p:229] hauth_saml_grpinfo_append :1183 Realloc grp inform size to 8192
[I][p:229] hauth_saml_grpinfo_append :1188 Append group info: 'Remote_LDAP'
[V][p:229] hauth_saml_grpinfo_parse :1201 SAML RESP: attr 'group' = 'EU_Group'
[I][p:229] hauth_saml_grpinfo_append :1188 Append group info: 'EU_Group'
[V][p:229] hauth_saml_grpinfo_parse :1201 SAML RESP: attr 'username' = 'jdoe'
[I][p:229] hauth_saml_grpinfo_append :1188 Append group info: 'jdoe'
[V][p:229] hauth_saml_resume_request :590 called
[V][p:229] hauth_saml_resume_request :683 called
[V][p:229] hauth_saml_process_usergrp :1659 called
[V][p:229] hauth_saml_activate_saml_user :962 called
[V][p:229] hauth_saml_activate_saml_user :964 Activate user 'jdoe' ses/vd: 0x7f2ef34c38b8/0x7f2ef37ce010
[V][p:229] hauth_saml_make_ms_from_grpinfo :913 server=SP2_test grp=EU_Group
[V][p:229] hauth_saml_make_ms_from_grpinfo :913 server=SP2_test grp=jdoe
[I][p:229] wad_http_auth_update_user_ext2 :2762 updating user. ip: 10.10.10.2, type:IP
[I][p:229] wad_auth_inc_user_count :1677 increased user count, quota:128000, n_shared_user:1, vd_used: 1, vd_max: 0, vd_gurantee: 0
[V][p:229] __wad_hauth_user_node_hold :2128 wad_hauth_user_node_alloc (1579): holding node 0x7f2ef35a3088
[V][p:229] __wad_hauth_user_node_hold :2128 wad_http_auth_use_user_node (2692): holding node 0x7f2ef35a3088
[V][p:229] __wad_hauth_user_node_put :2139 wad_http_auth_use_user_node (2693): putting node(ref=1) 0x7f2ef35a3088
mapping user_node:0x7f2ef35a3088, user_ip:0x7f2ef3581cf8(0), user:0x7f2ef351cc48(0)
[V][p:229] __wad_hauth_user_node_hold :2128 wad_http_auth_update_user_ext2 (2982): holding node 0x7f2ef35a3088
[V][p:229] hauth_saml_activate_saml_user :997 Update authenticated SAML user 'jdoe' cfg 'SP2_test' Success
[V][p:229] wad_inform_msg_hdr_get :580 msg=ReqAdd code=OK seq=6

 

Using the SAML tracer plugin, it is possible to double-check the expected Assertions sent in the SAML response from IDP to SP:

 

SAML_tracer_response.png

After successful authentication, the user will be redirected to the Web Server:

 

 

Web_server_Access.png

At this point, it is possible to check the endpoint and user information from FortiGate CLI:

 

a. Validate authenticated user:

 

firewall # dia wad user list | grep jdoe

ID: 11, VDOM: root, IPv4: 10.10.10.2
user name : jdoe
worker : 0
duration : 361
auth_type : IP
auth_method : SAML
pol_id : 2
g_id : 2
user_based : 0
expire : 366
LAN:
bytes_in=14278 bytes_out=3287
WAN:
bytes_in=1778 bytes_out=2457

 

b. Validate endpoint by IP:

 

firewall # diag endpoint record list 10.10.10.2
Record #1:
IP Address = 10.10.10.2
MAC Address = 00:70:6f:XX:XX:XX
MAC list =
VDOM = root (0)
EMS serial number: FCTEMS0000XXXXX
Client cert SN: FCA3XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Public IP address: Y:Y:Y:Y
Quarantined: no
Online status: online
Registration status: registered
On-net status: on-net
Gateway Interface: port3
FortiClient version: 7.0.7
AVDB version: 1.0
FortiClient app signature version: 0.0
FortiClient vulnerability scan engine version: 2.32
FortiClient UID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Host Name: Win10-Pro
OS Type: WIN64
OS Version: Microsoft Windows 10 Professional Edition, 64-bit (build 19041)
Host Description:
Domain: Domain1.local
Last Login User: jdoe
Owner:
Host Model: XXXXX
Host Manufacturer: XXXX
CPU Model: Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
Memory Size: 4095
AV Feature: 1
FW Feature: 0
WF Feature: 0
AS Feature: 0
VS Feature: 1
VN Feature: 1
Last vul message received time: Wed Jun 14 16:58:55 2023
Last vul scanned time: Thu Jan 1 01:59:59 1970
Last vul statistic: critical=8, high=13, medium=22, low=2, info=0
Avatar fingerprint: XXXXXXXXXXXXXXXXXXXX
Avatar source username: jdoe
Avatar source email:
Avatar source: OS
Phone number:
Number of Routes: (1)
Gateway Route #0:
- IP:10.10.10.2, MAC: 00:70:6f:XX:XX:XX, VPN: no
- Interface:port3, VFID:0, SN: XXXXXXXXXXXXX
online records: 1; offline records: 0; quarantined records: 0; out-of-sync records: 0

 

c. Display ZTNA logs:

 

firewall # execute log filter category 0

firewall # execute log filter field subtype ztna

firewall # execute log display
4 logs found.
4 logs returned.

.

.

.

4: date=XXXXXX time=XXXXX eventtime=XXXXX  tz="+XXX" logid="0005000024" type="traffic" subtype="ztna" level="notice" vd="root" srcip=10.10.10.2 srcname="Win10-Pro" srcport=58614 srcintf="port3" srcintfrole="lan" dstcountry="Reserved" srccountry="Reserved" dstip=192.168.10.4 dstport=80 dstintf="port2" dstintfrole="lan" sessionid=11373862 service="HTTP" proto=6 action="accept" policyid=2 policytype="proxy-policy" poluuid="e83fb0c6-0066-51ee-965e-7f0f97862e74" policyname="Web_Server_Access" duration=126 user="jdoe" group="Remote_SAML_FACIDP" authserver="SP2_test" gatewayid=1 vip="WebServer" accessproxy="WebServer" clientdeviceid="XXXXXXXXXXXXXXXXXXXXXXX" clientdevicetags="on-line/MAC_EMS1_ZTNA_OS_Compliant/EMS1_ZTNA_OS_Compliant/MAC_EMS1_ZTNA_Corporate_host/MAC_EMS1_ZTNA_all_registered_clients" wanin=1636 rcvdbyte=1636 wanout=1555 lanin=2261 sentbyte=2261 lanout=2276 fctuid="XXXXXXXXXXXXXXXXXXX" devtype="Computer" osname="Windows" srcswversion="10" unauthuser="jdoe" unauthusersource="forticlient" appcat="unscanned"

 

For testing purposes, other TAGs have been included to match this host in order to deny access when for specific TAGs.

In Log&Report -> ZTNA traffic, it is possible to check the matching Rules and actions:

 

ZTNA_traffic_logs.png

 

d. Corporate Host gets disconnected from ZTNA trust Telemetry:

 

In such cases, the Host will lose the Corporate Tag we previously assigned and it will be denied access to the protected resource.

Debug events for such cases would be the following:

 

[V][p:216] wad_informer_proc_dev_query :1636 Didn't find the record using dev_find, Forwarding request to EMS.
[V][p:216] wad_inform_dev_get_from_ems :1324 Request EMS to search with uid value XXXXXXXXX and sn value YYYYYYYYYYYYY.
[V][p:216] wad_inform_dev_create_intermediate_node:734 uid=XXXXXXXXX sn=YYYYYYYYYYYYY
[V][p:216] wad_inform_dev_query_req_open :706 dev 0x7f346b052048 has newly added query conn 0x7f346b1a2048.
[V][p:216] wad_informer_proc_dev_query :1669 hold request for further processing as no record found!.
[V][p:216] wad_inform_dev_query_expiry :818 No content returned for request 5.
[V][p:216] wad_inform_msg_hdr_get :580 msg=DevQueryResp code=NoEntry seq=5
[V][p:229] wad_authenticated_user_proc_msg_header:1447 msg=DevQueryResp code=NoEntry seq=5 data_len=0
[W][p:229] wad_dev_resp_proc :4311 dev resp is nok:1
[V][p:229] wad_dev_query_cb :4163 dev resp tid=0, rsp=(nil)
[W][p:229] wad_dev_query_cb :4169 vf_id=0,dev:cert:393532464533313141374435344231334241424641374538323732333939423200464354454d533030303031323030363700 is not found
[V][p:229] wad_fw_policy_match_dev_grp :4941 dev tag matching, info=(nil), tag_cnt=0, on_line=0,conf ems-tag size=1
[V][p:229] wad_fw_policy_match_dev :5012 pol_id = 2 matched = 0
[V][p:229][s:11314136][r:31] wad_http_req_policy_notify :9649 notify policy match: req=0x7f2ef382b5a8 status=1 pid=229.
[I][p:229][s:11314136][r:31] wad_http_req_policy_set :9435 match pid=229 policy-id=0 vd=0 in_if=5, out_if=4 10.10.10.2:58318 -> 192.168.10.4:80
[E][p:229][s:11314136][r:31] wad_http_req_proc_policy :9169 POLICY DENIED

 

ZTNA_restriction.png

Related documents for ZTNA deployments:

 

Deployment examples:

 

ZTNA access proxy with SAML and MFA using FortiAuthenticator

Using ZTNA to access protected TCP applications

 

Design documentation:

 

Design, concepts and considerations

 

 

  • ZTNA TCP forwarding access proxy is used for other applications, such as SSH, Remote Desktop Protocol (RDP), and others, whether hosted in the physical data center or cloud.
Contributors