Access SMB file shares over ZTNA with Kerberos KDC Proxy
Configure a Windows Server KDC Proxy and FortiGate ZTNA TCP forwarding so remote AD users can obtain a Kerberos ticket and access file shares by FQDN.
Demo guide — not a tested configuration
On this page
Before you begin
Confirm each prerequisite before planning changes. Checklist progress is kept for this visit and resets when you reload.
Overview
Configure remote access to an AD file share through FortiGate ZTNA while obtaining fresh Kerberos tickets through a Windows KDC Proxy. FortiClient forwards the file server connection on TCP 445 and the KDC Proxy HTTPS connection on TCP 443 through the existing ZTNA gateway. File authorization remains with Active Directory, share permissions and NTFS.
Scope: AD-joined or hybrid AD-joined Windows clients initially signing in with AD passwords. Windows Hello, smart-card and Entra-only authentication require a separately verified identity design. Existing ZTNA gateway, EMS enrollment, endpoint certificates, trust and device-tag enforcement are prerequisites; this guide adds the two application destinations.
Example environment
Replace or reuse these values throughout:
| Component | Example |
|---|---|
| AD DNS domain | corp.example.com |
| AD NetBIOS domain | CORP |
| Domain controller/DNS | dc01.corp.example.com — 10.10.10.10 |
| File server | fs01.corp.example.com — 10.10.20.10 |
| Share | \\fs01.corp.example.com\Data |
| KDC Proxy server | kdc01.corp.example.com — 10.10.20.20 |
| FortiGate ZTNA gateway | ztna.example.com:9443 |
| FortiGate source toward servers | 10.10.20.1 |
10.10.20.1 represents the source address the backend servers actually see. If you use a dedicated ZTNA SNAT pool, substitute that address.
There are two separate connections:
| Connection | Purpose |
|---|---|
| Client → ZTNA → kdc01:443 | Obtain Kerberos tickets |
| Client → ZTNA → fs01:445 | Authenticate to SMB and access files |
The client presents the Kerberos ticket directly to the file server. Neither FortiGate nor the KDC Proxy needs Kerberos constrained delegation for this flow.
Prepare the Windows KDC Proxy server
Execution context
Use a fully patched Windows Server 2022 member server with a static address and AD DNS.
Run Windows PowerShell as Administrator.
If it is a fresh server, configure its DNS using its actual interface alias:
Get-NetAdapter
Set-DnsClientServerAddress `
-InterfaceAlias "Ethernet" `
-ServerAddresses "10.10.10.10"Rename it, then restart:
Rename-Computer -NewName "KDC01" -RestartJoin the domain after restarting:
Add-Computer `
-DomainName "corp.example.com" `
-Credential (Get-Credential "CORP\DOMAIN_JOIN_ACCOUNT") `
-RestartAfter the domain join, verify:
Test-ComputerSecureChannel -Verbose
Resolve-DnsName `
-Type SRV `
"_kerberos._tcp.corp.example.com"
Test-NetConnection dc01.corp.example.com -Port 88
Get-Service KpsSvcThe secure channel and DNS must work. The KDC Proxy service proxies Kerberos messages to domain controllers.
On a standard Server 2022 installation, check for the built-in KpsSvc before adding roles. This setup uses that service and HTTP.sys; an IIS website is not part of the configuration.
Install the KDC Proxy HTTPS certificate
You need a certificate with:
- SAN: kdc01.corp.example.com
- Enhanced Key Usage: Server Authentication
- A private key
- A chain trusted by the Windows clients
- Certificate revocation/AIA locations reachable by those clients
An internal AD CS certificate is suitable if the clients trust your CA and can reach its required certificate URLs. Fortinet explicitly calls out client access to CRL/AIA URLs.
To request it through AD CS:
- Run certlm.msc on KDC01.
- Open Personal → Certificates.
- Right-click → All Tasks → Request New Certificate.
- Select your approved server authentication template.
- If the template requires supplied names, enter kdc01.corp.example.com as a DNS SAN.
- Complete enrollment.
Alternatively, import an existing PFX:
$pfxPassword = Read-Host "PFX password" -AsSecureString
Import-PfxCertificate `
-FilePath "C:\Temp\kdc01.pfx" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-Password $pfxPasswordList the installed certificates:
Get-ChildItem Cert:\LocalMachine\My |
Select-Object Subject, Thumbprint, HasPrivateKey, NotAfter,
DnsNameList, EnhancedKeyUsageList |
Format-ListCopy the correct certificate thumbprint.
The KDC Proxy certificate is separate from the FortiGate ZTNA gateway certificate. Windows validates the KDC Proxy HTTPS certificate inside the forwarded connection.
Configure HTTPS and the KDC Proxy service
Existing bindings and password-authentication scope
First inspect existing HTTP.sys configuration:
netsh http show sslcert
netsh http show urlacl
Get-NetTCPConnection -LocalPort 443 -State Listen `
-ErrorAction SilentlyContinueUse a dedicated server with TCP/443 available. If an HTTPS binding already exists, inspect it before changing anything.
Set the certificate thumbprint:
$thumbprint = "REPLACE_WITH_CERTIFICATE_THUMBPRINT" -replace "\s", ""
$certificate = Get-Item "Cert:\LocalMachine\My\$thumbprint"
$certificate |
Format-List Subject, HasPrivateKey, NotAfter, DnsNameListCreate the HTTPS URL reservation. Resolve the well-known Network Service account SID below to its localized account name. S-1-5-20 is the Network Service account SID, not the KpsSvc service SID:
$networkService = (
[System.Security.Principal.SecurityIdentifier]"S-1-5-20"
).Translate(
[System.Security.Principal.NTAccount]
).Value
netsh http add urlacl `
"url=https://+:443/KdcProxy" `
"user=$networkService"Bind the certificate to TCP/443:
$appId = "{$([guid]::NewGuid())}"
netsh http add sslcert `
"ipport=0.0.0.0:443" `
"certhash=$thumbprint" `
"appid=$appId" `
"certstorename=MY"These are HTTP.sys URL reservation and TLS binding operations; Microsoft documents the binding syntax in netsh http.
For the AD password authentication scenario, configure:
$settings = "HKLM:\SYSTEM\CurrentControlSet\Services\KPSSVC\Settings"
New-Item -Path $settings -Force | Out-Null
New-ItemProperty `
-Path $settings `
-Name "HttpsClientAuth" `
-PropertyType DWord `
-Value 0 `
-Force
New-ItemProperty `
-Path $settings `
-Name "DisallowUnprotectedPasswordAuth" `
-PropertyType DWord `
-Value 0 `
-ForceThese settings allow the password-based Kerberos scenario documented by Fortinet. The HTTPS connection still protects the traffic; this does not enable plaintext SMB authentication.
Start the service:
Set-Service -Name KpsSvc -StartupType Automatic
Start-Service -Name KpsSvcIf it was already running when you changed its settings:
Restart-Service -Name KpsSvcConfigure Windows Firewall and internal connectivity
Allow the FortiGate’s backend source to reach KDC01 on TCP/443:
New-NetFirewallRule `
-DisplayName "ZTNA - KDC Proxy HTTPS" `
-Direction Inbound `
-Action Allow `
-Protocol TCP `
-LocalPort 443 `
-RemoteAddress "10.10.20.1" `
-Profile DomainThe KDC Proxy server must retain normal domain member connectivity to AD DNS and domain controllers, including Kerberos TCP/88. It does not need an inbound internet connection outside the ZTNA path.
Verify the service and binding:
Get-Service KpsSvc
Get-ItemProperty `
"HKLM:\SYSTEM\CurrentControlSet\Services\KPSSVC\Settings"
netsh http show sslcert ipport=0.0.0.0:443
netsh http show servicestate
Get-NetTCPConnection -LocalPort 443 -State ListenA listener owned by System/PID 4 is normal for HTTP.sys.
Validate the HTTPS endpoint internally
From an internal Windows computer that trusts the CA:
Test-NetConnection kdc01.corp.example.com -Port 443Then:
curl.exe -v https://kdc01.corp.example.com/KdcProxyCheck that:
- TCP/443 connects.
- TLS certificate validation succeeds.
- The certificate matches kdc01.corp.example.com.
A normal browser or curl GET is not a Kerberos request, so an HTTP error response can be expected. It proves neither successful ticket issuance nor a working KDC Proxy by itself.
Do not use -k for certificate validation testing.
Configure FortiGate TCP forwarding
Configuration context: on your FortiGate, locate the existing ZTNA TCP forwarding/access-proxy server and its proxy policy (commonly Policy & Objects > ZTNA or in CLI). Names/screens vary by FortiOS release. Add the two destination mappings below to that existing design; backend address objects, gateway certificate, listener and policy IDs are environment-specific prerequisites and are not invented here.
Add these backend destinations to your ZTNA TCP forwarding configuration:
| Name | Backend address | Port |
|---|---|---|
| ZTNA-SMB-FS01 | 10.10.20.10 | TCP/445 |
| ZTNA-KDC01 | 10.10.20.20 | TCP/443 |
CLI Context:
config firewall address
edit "ZTNA-SMB-FS01"
set subnet 10.10.20.10 255.255.255.255
next
edit "ZTNA-KDC01"
set subnet 10.10.20.20 255.255.255.255
next
end
config firewall access-proxy
edit "<EXISTING-ZTNA-ACCESS-PROXY>"
config api-gateway
edit <TCP-FORWARDING-GATEWAY-ID>
set service tcp-forwarding
config realservers
edit 0
set address "ZTNA-SMB-FS01"
set mappedport 445
next
edit 0
set address "ZTNA-KDC01"
set mappedport 443
next
end
next
end
next
endFor each destination:
- Add it to the applicable traffic forwarding/access proxy configuration.
- Permit it in the ZTNA proxy policy.
- Apply user/group/tag restrictions if your existing design uses them.
- Enable traffic logging.
If the servers are behind another FortiGate, the intervening policies must permit the ZTNA gateway’s backend traffic to those servers.
On FS01, permit TCP/445 from the actual FortiGate SNAT source:
New-NetFirewallRule `
-DisplayName "ZTNA - SMB" `
-Direction Inbound `
-Action Allow `
-Protocol TCP `
-LocalPort 445 `
-RemoteAddress "10.10.20.1" `
-Profile DomainKeep the existing share and NTFS permissions for the required AD users/groups.
Configure EMS destinations
Configuration context: in EMS Endpoint Profiles, edit the assigned profile and its ZTNA Destinations/TCP forwarding settings. The exact profile-page label depends on EMS/FortiClient release. Confirm the saved profile reaches the pilot before testing; the destination rules refer to internal FQDNs, not the public gateway name as a backend.
In the endpoint profile’s ZTNA destinations add your applciations synced from Fortigate or add them manually: NOTE: Ensure that your client or Fortigate can resolve internal FQDNs as to forward traffic correctly.
| Destination | Port | Gateway |
|---|---|---|
| fs01.corp.example.com | 445 | ztna.example.com:9443 |
| kdc01.corp.example.com | 443 | ztna.example.com:9443 |
Push the profile and confirm both rules appear on the endpoint.
Use TCP forwarding for KDC01’s HTTPS connection, so Windows communicates with its KDC Proxy endpoint through FortiClient.
Both names must resolve appropriately on the remote endpoint. For a first test, static hosts entries can remove DNS as a variable.
Configure Windows clients to use the KDC Proxy
Create a computer GPO linked to your devices.
Navigate to:
Computer Configuration
Policies
Administrative Templates
System
Kerberos
Specify KDC proxy servers for Kerberos clientsSet Enabled → Show:
| Value name | Value |
|---|---|
| corp.example.com | <https kdc01.corp.example.com:443:KdcProxy /> |
The value uses special Windows policy syntax: preserve the spaces and angle brackets.
The mapping applies to the AD DNS domain, which may differ from users’ email/UPN suffix. Windows uses this proxy mapping when it cannot locate a DC directly.
On the client:
gpupdate /forceRestart the client.
Confirm the effective settings:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos" /sLeave “Disable revocation checking for the SSL certificate of KDC proxy servers” unconfigured. Fix certificate trust and CRL reachability instead of disabling validation.
Policy-source distinction
Check the file server’s Kerberos identity
Start with its actual AD hostname:
\\fs01.corp.example.com\DataFrom a computer with the AD tools:
setspn -L CORP\FS01Check for the server’s normal HOST registrations:
HOST/fs01
HOST/fs01.corp.example.comWindows can use these registrations for CIFS. Do not add an explicit CIFS SPN merely because one is absent.
If you use an alias, cluster name or NAS, ensure that name belongs to the AD account that actually serves SMB. Incorrect or duplicate SPNs can cause Kerberos failure.
Test Kerberos from outside
Pilot-session disruption
Use a domain joined workstation on an external connection, with VPN disconnected and FortiClient’s ZTNA destinations loaded.
Sign in using the user’s AD password for this initial test.
Close File Explorer windows using the share and remove the test mapping, if present:
net use Z: /deleteOn the client, clear that user session’s tickets:
klist purgeThis clears the current session’s Kerberos tickets and can temporarily affect other authenticated resources, so use a test session.
Now request the SMB service ticket:
klist get cifs/fs01.corp.example.comCheck the cache:
klistLook for:
krbtgt/CORP.EXAMPLE.COM
cifs/fs01.corp.example.comklist get requests a ticket for the specified SPN; klist displays the tickets in the current logon session. Run these commands in the same user context as File Explorer.
Map the share:
net use Z: \\fs01.corp.example.com\Data /persistent:yesCheck that the user can read/write according to the existing permissions.
Finally, restart the workstation while still outside the office and repeat the test. This checks that it can acquire fresh tickets remotely.
Confirm the actual SMB logon used Kerberos
On FS01, inspect the corresponding successful Security event 4624:
Logon Type: 3
Authentication Package: KerberosEnsure successful Logon auditing is enabled if these events are missing.
Also check FortiGate’s traffic forwarding logs for both:
- KDC01 TCP/443 during ticket acquisition.
- FS01 TCP/445 during file access.
A successful drive mapping alone is insufficient evidence: Windows may have used NTLM fallback.
Troubleshooting
| Symptom | Check |
|---|---|
| KDC01 TCP/443 fails | EMS rule, FortiGate policy, backend routing, SNAT source, Windows Firewall |
| TLS certificate error | SAN, expiry, client CA trust, CRL/AIA access |
| HTTPS connects but no ticket | KpsSvc, effective GPO mapping, AD DNS, KDC01 → DC connectivity |
| Ticket request says principal unknown | Exact server name and SPN ownership |
| KRB_AP_ERR_MODIFIED | SPN on the wrong account, duplicate SPN, or server account/key issue |
| Ticket exists but SMB fails | TCP/445 path, SMB service, share permissions and NTFS permissions |
| Share opens using NTLM | Existing SMB session, credentials, requested hostname and Kerberos ticket acquisition |
| Works until reboot | Cached tickets masking a KDC Proxy/client configuration problem |
For FortiGate packet visibility, substitute the real backend addresses:
diagnose sniffer packet any 'host 10.10.20.20 and tcp port 443' 4 0 ldiagnose sniffer packet any 'host 10.10.20.10 and tcp port 445' 4 0 lFor production, include the KDC Proxy certificate binding in your renewal procedure: when the certificate thumbprint changes, the HTTP.sys binding must reference the replacement certificate.
This gives you Kerberos for SMB without giving remote clients general network access to domain controllers. The client obtains tickets through the KDC Proxy, while file authorization remains with AD, share permissions and NTFS.
Certificate renewal
References and review notes
Primary input is the owner-supplied Windows Server 2022/SMB/KDC Proxy procedure. Official references were used to check the proxy/service settings, policy mapping, HTTP.sys syntax, SPN behavior and verification commands. The Microsoft SMB-over-QUIC page is used only for its Windows KDC Proxy setup; this guide continues to use SMB TCP 445 through Fortinet ZTNA, not QUIC.
Fortinet — KDC Proxy and ZTNA access to shared drives ↗
Fortinet — SMB drive mapping/reboot caveat, FortiOS 7.4.8 release notes ↗
Microsoft — netsh http certificate bindings and URL reservations ↗
Microsoft — KDC Proxy setup and realm-mapping example (transport context: SMB over QUIC) ↗
Microsoft — Kerberos KDC Proxy Group Policy and revocation settings ↗
Microsoft — setspn and HOST service-class substitution ↗
Microsoft — klist ticket request, display and purge ↗
Microsoft — successful logon event 4624 ↗
Microsoft protocol specification — HTTPS KDC proxy transport ↗
Verify the result
Use observed results to decide whether the intended outcome has been achieved.
Expected result
If it isn’t working
Use the symptom/check table in Troubleshooting, correlating KDC01 service/TLS and effective GPO state with FortiGate forwarding logs, the client ticket cache and FS01 event 4624. A successful HTTPS GET or drive mapping alone is insufficient. Record actual firmware/client versions and review certificate renewal bindings before publication.
Change one variable at a time
Video walkthrough
The written guide stands on its own. A companion video can be added after the guide is validated.