Azure AD Application Proxy ( 後簡稱 AppProxy ) 是我真心覺得微軟非常棒的一個 Azure 服務,IT 管理者可以簡單完成串接企業內部應用程式,使用者在無 VPN 的環境下就能從 Internet 直接存取到內部系統,並且搭配 Azure AD 及 Conditional Access 提供企業強大及完整的安全防護。
一般在佈建 AppProxy 服務時,IT 管理者為方便後期快速部署,大都會使用萬用字元憑證 ( Wildcard SSL Certificate ) 進行設定。但如果遇到萬用字元憑證快到期時,已經大量部署的 AppProxy 應該沒人想一個個手動更換憑證,老闆又不是請你來做工讀生的工作 (但可能給工讀生的薪水!?),這時可以利用後述的指令進行大量更換。
本篇指令主要參考國外分享,然後將其拆分成兩段做小部改寫,因為我認為任何的直接快速大量修改都是有風險的,必須要測試及確認後才能進行變更,甚至有機會做還原動作。
開始前,請準備好
1. Azure AD PowerShell
2. 預備更新的萬用字元憑證帶私鑰 ( Private Key ) 的檔案。PFX 檔案格式,如果檔案小於 4 KB ,一般我會懷疑該檔案完全沒有含私鑰。
3. 預備更新的憑證匯入密碼
兩段的 PowerShell 程式如下,並已放在 GitHub 提供下載使用
GitHub - AskaSu - Bulk update Certificate for AAD AppProxy
第一段,產生與指定網域名稱有關的 AppProxy 資訊 CSV 報表。
藉此瞭解現有相關設定外,同時可以工人模式檢視哪些 App Proxy 真的需要進行憑證更換。
[提醒]
a. 預設產生的報表指定放入 C:\Temp 目錄中,如有其他需求請自行修改。
b. 假設這個報表主要作為憑證更新使用,可以參考程式碼中 ExternalUrl -nolike 那段進行編修,對子網域直接做過濾。主要是一般萬用字元憑證並不支援子網域 ,除非買的是 Multi-Domain 等級的憑證,不過那價格應該不是一般企業會採購的了。
執行語法範例
1 | .\AAD_Create_AppProxy_Checking_List.ps1 -CustomDomain 網域名稱 |
完整指令碼
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | Param ( [ Parameter ( Mandatory = $true )] [string] $CustomDomain ) $QueryDomain = "*" + $CustomDomain + "/*" #Connect to AzureAD Write-Host 'Connecting to AzureAD' -ForegroundColor Yellow Connect-AzureAD #ExportFile $AADName = @((@(( Get-AzureADDomain | Where-Object { $_ .Name -like "*.onmicrosoft.com" }).Name )[0]).Split( "." ))[0] $ExportFilePath = "C:\Temp\" + $AADName + "_AADAppProxy_Checking_list_" + "$((Get-Date -format yyyy-MMdd).ToString()).csv" #Get all Azure AD App Proxy Proxy Applications checking the ObjectID of all apps. Write-Host 'Obtaining Azure AD App Proxy Applications for your Domain' -ForegroundColor Yellow $ProxyApps = foreach ( $a in ( Get-AzureADApplication -All : $true | Sort-Object DisplayName)) { try { $p = Get-AzureADApplicationProxyApplication -ObjectId $a .ObjectId [pscustomobject] @{DisplayName= $a .DisplayName; ObjectID= $a .ObjectId; ExternalUrl= $p .ExternalUrl; InternalUrl= $p .InternalUrl; AuthenticationType= $p .ExternalAuthenticationType; ServerTimeout= $p .ApplicationServerTimeout; CertSubjectName = $p .VerifiedCustomDomainCertificatesMetadata.SubjectName; CertThumbprint = $p .VerifiedCustomDomainCertificatesMetadata.Thumbprint; CertExpiryDate = $p .VerifiedCustomDomainCertificatesMetadata.ExpiryDate ; CertificateInfo= $p .VerifiedCustomDomainCertificatesMetadata} } catch { continue } } #Filter the proxy applications with the ExternalURL of your domain to askacloud.com only, and not including Jira site series, rd.askacloud.com and iot.askacloud.com etc. $AppsOnCustomDomain = $ProxyApps | Where-Object { $_ .ExternalUrl -like $QueryDomain ` -and $_ .ExternalUrl -notlike "*.jira*" ` -and $_ .ExternalUrl -notlike "*rd.askacloud.com*" ` -and $_ .ExternalUrl -notlike "*iot.askacloud.com*" ` } | Sort-Object DisPlayName Write-Host 'The following applications need to been reviewed for Certificate Update' -ForegroundColor Yellow $AppsOnCustomDomain | Out-Host #Export list for checking again and updating $AppsOnCustomDomain | Export-Csv -NoTypeInformation -Encoding UTF8 -Path $ExportFilePath |
第二段,依據前面的列表作為大量更換的依據,接著進行憑證更新。
可以嘗試先將列表清單修改到僅剩下一兩項,也就是前面提到的先進行測試,確認後再進行大量部署。
[提醒]
a.本段語法假設已透過 PowerShell 完成連接 Azure AD,並且預備更新的 AppProxy 清單檔案,儲存在執行前段指令當天所產生的位置裡。
b. 執行過程如下圖會需要輸入匯入密碼,請先準備。
執行語法範例
1 | .\AAD_Update_Cert_to_AppProxy.ps1 -PFXLocation 檔名及完整路徑 |
完整指令碼
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | Param ( [ Parameter ( Mandatory = $True )] [String] $PFXLocation ) #Connect to AzureAD #Write-Host 'Connecting to AzureAD' -ForegroundColor Yellow #Connect-AzureAD # $PFXLocation = "C:\Temp\wildcard_askacloud_com.pfx" #Enter the PFX password Write-Host 'Enter the password for PFX file' -ForegroundColor Yellow $PFXPassword = Read-Host -AsSecureString $AADName = @((@(( Get-AzureADDomain | Where-Object { $_ .Name -like "*.onmicrosoft.com" }).Name )[0]).Split( "." ))[0] $ImportFilePath = "C:\Temp\" + $AADName + "_AADAppProxy_Checking_list_" + "$((Get-Date -format yyyy-MMdd).ToString()).csv" $AppsOnCustomDomain = Import-CSV -path $ImportFilePath Write-Host 'Are you sure you wish to change certificate on the above applications? (Y/N)' -ForegroundColor Yellow $Answer = Read-Host If ( $Answer -eq 'Y' ){ #Loop through the custom domain apps and upload new TLS certificate foreach ( $CustomDomainApp in $AppsOnCustomDomain ) { Write-Host "Setting Certificate on Application" $CustomDomainApp .DisplayName -ForegroundColor Green Set-AzureADApplicationProxyApplicationCustomDomainCertificate -ObjectId $CustomDomainApp .ObjectID -PfxFilePath $PFXLocation -Password $PFXPassword } } else { Write-Host 'Apps not approved for change' -ForegroundColor Red } |
另外,我觀察測試及確認
1. 一旦完成更新與這個網域有關的憑證後,再新增加與該網域有關的 AppProxy,就會自動使用這張最新更換的。
2. 憑證匯入密碼打錯,不會做任何動作,只是會跳錯誤訊息而已。
3. 更新過程會去檢查憑證是否有對應到使用的網域名稱,如果沒有對應到,就會報錯,但不會影響該 App Proxy 的原始憑證設定,也就是不會被搞到壞掉。
舉例來說,下圖報錯的項目「AppProxy - POC - Graylog」,實際的 FQDN 為 log.app.askacloud.com 是在子網域中 ,也就是前面提及的狀況,一般萬用字元憑證無法使用到再下一層的子網域,所以報錯無法更新是正常情形,而且,錯誤訊息也很明顯地告知:
" Set-AzureADApplicationProxyApplicationCustomDomainCertificate : Error occurred while executing SetApplicationProxyApplication
Code: InvalidCertificate_HostNameMismatch
Message: Bad Certificate Request "
資料參考
Declan Turley Tech Blog - Azure AD App Proxy: Bulk Update TLS Certificate for a Custom Domain
MS Docs - Get all Azure Active Directory Application Proxy applications published with the identical certificate and replace it
發佈留言