在代管式 Microsoft AD 网域上部署 AD FS

本指南介绍如何在 Managed Service for Microsoft Active Directory 网域中部署适用于 Windows Server 2019 的 Microsoft Active Directory Federation Services (AD FS)。

下图演示了该部署:

架构

用户与使用 Google 管理的证书HTTPS 负载均衡器通信,以终止 SSL 连接。该负载均衡器会将连接转发到运行适用于 Windows Server 2019 的 Microsoft AD FS 并且加入 Managed Microsoft AD 网域的虚拟机实例。负载均衡器和虚拟机实例之间的通信使用自签名 SSL 证书进行保护。

该部署使用单个 AD FS 实例和 Windows 内部数据库,因此适用于小型环境。对于可靠性或安全性要求更高的环境,请考虑在服务器场配置中部署多个 AD FS 实例并部署联合代理

准备工作

准备项目和网络

您需要准备 Google Cloud 项目和 VPC 网络,才能部署 AD FS。

创建虚拟机实例

创建服务帐号和虚拟机实例以运行 AD FS:

  1. Google Cloud 控制台中,打开 Cloud Shell

    激活 Cloud Shell

  2. 设置默认项目 ID

    gcloud config set project PROJECT_ID
    

    PROJECT_ID 替换为您的 Google Cloud 项目的 ID。

  3. 设置默认地区和区域:

    gcloud config set compute/region REGION
    gcloud config set compute/zone ZONE
    

    替换以下内容:

    • REGION:要在其中进行部署的区域的 ID。
    • ZONE:要在其中进行部署的地区的 ID。
  4. 创建服务账号:

    gcloud iam service-accounts create SA_NAME
    

    SA_NAME 替换为服务账号的名称。

  5. 创建一个运行 Windows Server 2019 并使用专用脚本自动安装 AD FS 服务器角色的虚拟机实例:

    gcloud compute instances create VM_NAME \
      --machine-type n2-standard-8 \
      --image-family windows-2019 \
      --image-project windows-cloud \
      --boot-disk-size 50 \
      --boot-disk-type pd-ssd \
      --subnet SUBNET_NAME \
      --service-account SA_NAME@$(gcloud config get-value core/project).iam.gserviceaccount.com \
      --metadata sysprep-specialize-script-ps1="Add-WindowsFeature ADFS-Federation -IncludeManagementTools;Add-WindowsFeature RSAT-AD-PowerShell;Add-WindowsFeature RSAT-ADDS-Tools"
    

    替换以下内容:

    • VM_NAME:虚拟机实例的名称。
    • SUBNET_NAME:要在其中部署 AD FS 的子网的名称。
    • SA_NAME:服务账号的名称。

    如需配置虚拟机实例并将其加入您的 Active Directory 网域,请完成以下步骤:

    1. 通过查看虚拟机的串行端口输出来监控其初始化过程:

      gcloud compute instances tail-serial-port-output VM_NAME
      

      等待大约 3 分钟,直到您看到输出 Instance setup finished,然后按 Ctrl+C。此时,该虚拟机实例已准备就绪,可以使用了。

    2. 为虚拟机实例创建用户名和密码

    3. 使用远程桌面连接到虚拟机,然后使用上一步中创建的用户名和密码登录。

    4. 右键点击开始按钮(或者按 Win+X),然后点击 Windows PowerShell(管理员)

    5. 点击以确认提升权限提示。

    6. 将该计算机加入您的 Active Directory 网域,然后重启:

      Add-Computer -Domain DOMAIN -Restart
      

      DOMAIN 替换为您的 Active Directory 网域的 DNS 名称。

      等待重启过程完成,大约需要 1 分钟。

创建负载均衡器

您需要创建一个负载均衡器,允许用户使用单个虚拟 IP 地址访问 AD FS。

如需将运行 AD FS 的虚拟机实例与负载均衡器相关联,请先创建一个非托管实例组,然后将此实例组分配给负载均衡器:

  1. 返回到现有的 Cloud Shell 会话。
  2. 创建非托管实例组:

    gcloud compute instance-groups unmanaged create INSTANCE_GROUP_NAME &&
    gcloud compute instance-groups set-named-ports INSTANCE_GROUP_NAME --named-ports=http:443
    

    INSTANCE_GROUP_NAME 替换为您要创建的实例组的名称。

  3. 将现有虚拟机实例添加到该实例组:

    gcloud compute instance-groups unmanaged add-instances INSTANCE_GROUP_NAME --instances VM_NAME
    
  4. 创建健康检查以探测 AD FS 的 HTTPS 端口:

    gcloud compute health-checks create tcp HEALTH_CHECK_NAME --port 443
    

    HEALTH_CHECK_NAME 替换为健康检查的名称。

  5. 创建一个负载均衡器后端服务,该服务使用您之前创建的 HTTPS 健康检查和实例组:

    gcloud compute backend-services create BACKEND_SERVICE_NAME \
      --health-checks HEALTH_CHECK_NAME \
      --port-name http \
      --protocol HTTPS \
      --global && \
    gcloud compute backend-services add-backend BACKEND_SERVICE_NAME \
      --instance-group INSTANCE_GROUP_NAME \
      --global \
      --instance-group-zone $(gcloud config get-value compute/zone)
    

    BACKEND_SERVICE_NAME 替换为后端服务的名称。

  6. 为负载均衡器预留静态外部 IP 地址

    gcloud compute addresses create ADDRESS_NAME --global
    

    ADDRESS_NAME 替换为您想要与该地址关联的名称。

  7. 为负载均衡器创建托管式 SSL 证书

    gcloud compute ssl-certificates create CERTIFICATE_NAME \
      --domains PUBLIC_FQDN \
      --global
    

    替换以下内容:

    • CERTIFICATE_NAME:代管式 SSL 证书的名称。
    • PUBLIC_FQDN:要用于 AD FS 的公共完全限定域名 (FQDN)。例如 login.example.com
  8. 创建使用外部 IP 地址并将流量转发到后端服务的负载均衡器前端:

    gcloud compute url-maps create URL_MAP_NAME \
      --default-service BACKEND_SERVICE_NAME && \
    gcloud compute target-https-proxies create PROXY_NAME \
      --ssl-certificates CERTIFICATE_NAME \
      --url-map URL_MAP_NAME && \
    gcloud compute forwarding-rules create FORWARDING_RULE_NAME \
      --global \
      --address ADDRESS_NAME \
      --target-https-proxy PROXY_NAME \
      --ports 443
    

    替换以下内容:

    • URL_MAP_NAME:负载均衡器的网址映射的名称。
    • PROXY_NAME:负载均衡器的目标代理的名称。
    • FORWARDING_RULE_NAME:负载均衡器转发规则的名称。
  9. 创建防火墙规则,允许来自负载均衡器的数据流量访问运行 AD FS 的虚拟机实例:

    gcloud compute firewall-rules create FIREWALL_RULE_NAME \
      --allow tcp:443 \
      --network VPC_NAME \
      --source-ranges 130.211.0.0/22,35.191.0.0/16 \
      --target-service-accounts SA_NAME@$(gcloud config get-value core/project).iam.gserviceaccount.com
    

    替换以下内容:

    • FIREWALL_RULE_NAME:防火墙规则的名称。
    • VPC_NAME:您的 VPC 网络的名称。
    • SA_NAME:服务账号的名称。

    来源范围是内部负载均衡器的 IP 地址范围。如需了解详情,请参阅配置防火墙规则

  10. 查找负载均衡器的 IP 地址:

    gcloud compute addresses describe ADDRESS_NAME \
       --global \
       --format=value\(address\)
    
  11. 在您的公共 DNS 区域中创建指向负载均衡器的 IP 地址的 DNS A 记录。DNS 记录的完全限定名称必须与您用于 SSL 证书的名称一致。

部署 AD FS

您需要在虚拟机实例上部署 AD FS 服务器角色。由于您在代管式 Microsoft AD 网域中没有 Domain Admins 权限,因此无法使用服务器管理器执行安装,而必须改用 PowerShell。

创建服务用户

您需要在 Active Directory 中为 AD FS 服务创建用户帐号:

  1. 使用远程桌面连接到虚拟机实例,然后使用委派的管理员凭据登录。
  2. 右键点击开始按钮(或者按 Win+X),然后点击 Windows PowerShell(管理员)
  3. 为 AD FS 服务帐号设置随机密码:

    $AdfsCredential = Get-Credential -UserName USER -Message 'PASSWORD'
    

    替换以下内容:

    • USER:Active Directory 用户的名称。
    • PASSWORD:Active Directory 用户的密码。
  4. 创建 Active Directory 用户:

    $CloudOuPath = "OU=Cloud," + (Get-ADDomain).DistinguishedName
    $AdfsUser = New-ADuser `
      -Name USER `
      -DisplayName 'AD FS service account' `
      -AccountPassword $AdfsCredential.Password `
      -Path "$CloudOuPath" `
      -PasswordNeverExpires $True `
      -PassThru | Enable-ADAccount -PassThru
    
  5. 将用户添加到本地管理员群组:

    Add-LocalGroupMember `
     -Group "Administrators" `
     -Member "$env:userdomain\USER"
    
  6. 指定服务主体名称:

    setspn -a http/PUBLIC_FQDN USER
    

    PUBLIC_FQDN 替换为 AD FS 的公共完全限定域名。

  7. 在 Active Directory 中创建空容器。您稍后在安装 AD FS 时需要使用此容器:

    New-ADObject `
      -Type Container `
      -Name "ADFS Data" `
      -Path $CloudOuPath
    
  8. 向 AD FS 用户授予对容器的完全控制权:

    dsacls.exe "CN=ADFS Data,$CloudOuPath" /G $env:userdomain\USER:GA /I:T
    

安装 AD FS

您可以在该虚拟机实例上安装 AD FS:

  1. 以 ADFS 用户的身份启动 PowerShell 会话:

    runas /u:$env:userdomain\USER powershell
    

    新的 PowerShell 会话以 AD FS 用户的身份运行,但没有提升的权限。

  2. 在新的 PowerShell 会话中,启动第二个提升权限的 PowerShell 会话:

    Start-Process PowerShell -Verb RunAs
    

    您必须在这个提升权限的这个新 PowerShell 会话中运行所有后续步骤。

  3. 创建一个使用 RSA 2048 位密钥的自签名 SSL 证书,并将其存储在计算机证书存储区中:

    $DnsName="PUBLIC_FQDN"
    $Certificate = New-SelfSignedCertificate `
      -Subject $DnsName `
      -KeyAlgorithm RSA `
      -KeyLength 2048 `
      -KeyExportPolicy NonExportable `
      -KeyUsage DigitalSignature, KeyEncipherment `
      -Provider 'Microsoft Platform Crypto Provider' `
      -NotAfter (Get-Date).AddDays(365) `
      -Type SSLServerAuthentication `
      -CertStoreLocation 'Cert:\LocalMachine\My' `
      -DnsName $DnsName
    

    PUBLIC_FQDN 替换为 AD FS 的公共完全限定域名。

  4. 创建另一个 AD FS 用作令牌签名证书的 RSA 2048 位证书:

    $SigningCertificate = New-SelfSignedCertificate `
      -Subject "ADFS Signing" `
      -KeyAlgorithm RSA `
      -KeyLength 2048 `
      -KeyExportPolicy NonExportable `
      -KeyUsage DigitalSignature, KeyEncipherment `
      -Provider 'Microsoft RSA SChannel Cryptographic Provider' `
      -NotAfter (Get-Date).AddDays(365) `
      -DnsName $DnsName `
      -CertStoreLocation 'Cert:\LocalMachine\My'
    
  5. 创建分布式密钥管理器 (DKM) 容器:

    $CloudOuPath = "OU=Cloud," + (Get-ADDomain).DistinguishedName
    $DkmContainer = New-ADObject `
      -Name ((New-Guid).Guid) `
      -Type Container `
      -Path "CN=ADFS Data,$CloudOuPath" `
      -PassThru
    
  6. 重新输入之前设置的 AD FS 用户的凭据:

    $AdfsCredential = Get-Credential -UserName "$env:userdomain\USER" -Message 'PASSWORD'
    
  7. 使用您之前创建的证书和 DKM 容器安装 AD FS:

    Install-ADFSFarm `
      -CertificateThumbprint $Certificate.Thumbprint `
      -SigningCertificateThumbprint $SigningCertificate.Thumbprint `
      -DecryptionCertificateThumbprint $SigningCertificate.Thumbprint `
      -FederationServiceName $DnsName `
      -ServiceAccountCredential $AdfsCredential `
      -OverwriteConfiguration `
      -AdminConfiguration @{"DKMContainerDn"=$DkmContainer.DistinguishedName}
    

    该命令可能会显示以下警告消息:

    WARNING: A machine restart is required to complete ADFS service configuration. For more information, see:
    https://go.microsoft.com/fwlink/?LinkId=798725
    
    WARNING: The SSL certificate subject alternative names do not support host name 'PUBLIC_FQDN'.
    Configuring certificate authentication binding on port '49443' and hostname 'PUBLIC_FQDN'.
    
    WARNING: An error occurred during an attempt to set the SPN for the specified service account. Set the SPN for the
    service account manually.  For more information about setting the SPN of the service account manually, see the AD FS
    Deployment Guide.  Error message: An error occurred during an attempt to set the SPN for the specified service account.
    You do not have sufficient privileges in the domain to set the SPN.
    
    WARNING: The SSL certificate does not contain all UPN suffix values that exist in the enterprise.  Users with UPN
    suffix values not represented in the certificate will not be able to Workplace-Join their devices.  For more
    information, see http://go.microsoft.com/fwlink/?LinkId=311954.
    

    您可以忽略这些警告,因为您已设置 SPN,且未使用基于证书的身份验证。

  8. 如果您打算使用集成式 Windows 身份验证 (IWA) 来向 AD FS 进行身份验证,请运行以下命令以停用令牌绑定:

    Set-ADFSProperties -ExtendedProtectionTokenCheck None
    Restart-Service -Name adfssrv
    

    必须停用令牌绑定,因为您是在负载均衡器后面部署 AD FS,而负载均衡器会终止 TLS 连接。

如果您在执行上述步骤时遇到任何权限相关问题,请与 Google Cloud 支持团队联系。

配置 TLS

与后端建立连接时,HTTPS 负载均衡器不使用服务器名称指示 (SNI) 扩展程序。若要让 AD FS 接受没有 SNI 的连接,您必须配置证书回退:

  1. 在 PowerShell 中,查看 AD FS 的 SSL 服务器证书绑定:

    netsh http show sslcert hostnameport=PUBLIC_FQDN:443
    

    PUBLIC_FQDN 替换为 AD FS 的公共完全限定域名。

  2. 为绑定配置回退证书:

    netsh http add sslcert ipport=0.0.0.0:443 certhash=CERTIFICATE_HASH "appid=APP_ID" "certstorename=MY"
    

    替换以下内容:

    • CERTIFICATE_HASH:上一个命令中显示的证书哈希值。
    • APP_ID:上一个命令中显示的应用 ID(包含大括号)。
  3. 重启计算机以完成安装:

    Restart-Computer
    

    等待重启过程完成,大约需要 1 分钟。

测试 AD FS

AD FS 服务已部署,但您仍必须验证是否可以使用 HTTPS 负载均衡器访问该服务:

  1. 返回到 Cloud Shell 会话。
  2. 验证 SSL 证书是否处于 ACTIVE 状态:

    gcloud compute ssl-certificates describe CERTIFICATE_NAME \
        --global \
        --format="get(managed.status)"
    

    如果证书处于 PROVISIONING 状态,则您为 AD FS 创建的 DNS 记录可能需要更多时间来传播。如需了解详情,请参阅对 Google 管理的证书进行问题排查

  3. 在本地计算机上,打开浏览器并转到以下网址:

    https://PUBLIC_FQDN/adfs/ls?wa=wsignout1.0
    

    PUBLIC_FQDN 替换为 AD FS 的公共完全限定域名

    验证您是否看到指示 AD FS 已成功部署的消息 You have successfully signed out

如果您打算使用集成式 Windows 身份验证 (IWA),请验证您是否可以获得 AD FS 的 Kerberos 票据:

  1. 使用远程桌面连接到虚拟机实例或其他已加入网域的虚拟机,然后使用网域凭据登录。
  2. 右键点击开始按钮(或者按 Win+X),然后点击 Windows PowerShell
  3. 使用 klist 命令请求 AD FS 的服务票证:

    klist get http/PUBLIC_FQDN
    

    验证输出是否包含 AD FS 的票据:

    #1>     Client: USER @ DOMAIN
            Server: http/PUBLIC_FQDN @ DOMAIN
            KerbTicket Encryption Type: ...
    

AD FS 已准备就绪,可供使用。如需详细了解如何使用和配置该服务,请参阅 AD FS 操作