ArcGIS Enterprise は HTTPS を使用しますが、そのためにはポータルで証明書を構成する必要があります。2017 年以降、Chrome インターネット ブラウザーは Subject Alternative Name (SAN) パラメーターを含むドメイン証明書のみを信頼するようになりました。このパラメーターは IIS Manager アプリケーション単独では構成できません。そのワークフローから作成された証明書は Chrome によって信頼されないという意味です。
ほとんどの場合は、IT 管理者が必要なドメイン証明書を提供してくれます。下のスクリプトは、SAN を含む証明書を作成し、それをポータルにインポートできる形式で IIS Manager からエクスポートしています。
証明書スクリプトの保存と実行
ドメイン証明書を作成するには、ドメインに認証機関が存在しており、コンピューターに IIS Manager がインストールされている必要があります。このワークフローには Windows PowerShell ISE 環境が望まれます。スクリプト ウィンドウとコマンド プロンプト ウィンドウの両方を使用できるからです。
ホスト名の証明書がコンピューター上にすでに存在する場合、スクリプトを実行すると、既存の証明書を上書きするかどうか確認するよう求められます。
- [管理者として実行] オプションを使用してコンピューター上に Windows PowerShell ISE アプリケーションを開き、スクリプトを作成します。
- 下に示すテキストをコピーして、アプリケーションのスクリプト ウィンドウに貼り付けます。
- スクリプトを *.ps1 ファイル (certificateScript.ps1 など) として保存します。
- ISE アプリケーションのコマンド プロンプト パネルで、スクリプトの保存場所にディレクトリを変更し、次のスクリプトを実行します。.\certificateScript.ps1
PowerShell で実行する証明書スクリプト
function New-CertificateRequest {
param ( [string]$hostname )
$CATemplate = "WebServer"
$CertificateINI = "cert.ini"
$CertificateREQ = "cert.req"
$CertificateRSP = "cert.rsp"
$CertificateCER = "cert.cer"
$Subject = 'Subject="CN=' + $hostname + '"'
$FriendlyName = 'FriendlyName=' + $hostname
$SAN = '_continue_ = "dns=' + $hostname + '&"'
### INI file generation
new-item -type file $CertificateINI -force
add-content $CertificateINI '[Version]'
add-content $CertificateINI 'Signature="$Windows NT$"'
add-content $CertificateINI ''
add-content $CertificateINI '[NewRequest]'
add-content $CertificateINI $Subject
add-content $CertificateINI 'Exportable=TRUE'
add-content $CertificateINI 'KeyLength=2048'
add-content $CertificateINI 'KeySpec=1'
add-content $CertificateINI 'KeyUsage=0xA0'
add-content $CertificateINI 'MachineKeySet=True'
add-content $CertificateINI 'ProviderName="Microsoft RSA SChannel Cryptographic Provider"'
add-content $CertificateINI 'ProviderType=12'
add-content $CertificateINI 'SMIME=FALSE'
add-content $CertificateINI 'RequestType=PKCS10'
add-content $CertificateINI $FriendlyName
add-content $CertificateINI '[Strings]'
add-content $CertificateINI 'szOID_ENHANCED_KEY_USAGE = "2.5.29.37"'
add-content $CertificateINI 'szOID_PKIX_KP_SERVER_AUTH = "1.3.6.1.5.5.7.3.1"'
add-content $CertificateINI 'szOID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2"'
add-content $CertificateINI 'szOID_SUBJECT_ALT_NAME2 = "2.5.29.17"'
add-content $CertificateINI '[Extensions]'
add-content $CertificateINI '2.5.29.17 = "{text}"'
add-content $CertificateINI $SAN
### Certificate request generation
if (test-path $CertificateREQ) {del $CertificateREQ}
certreq -new $CertificateINI $CertificateREQ
### Online certificate request and import
if ($OnlineCA) {
if (test-path $CertificateCER) {del $CertificateCER}
if (test-path $CertificateRSP) {del $CertificateRSP}
certreq -submit -attrib "CertificateTemplate:$CATemplate" -config $OnlineCA $CertificateREQ $CertificateCER
certreq -accept $CertificateCER
}
### Delete certificate request files
if (test-path $CertificateINI) {del $CertificateINI}
if (test-path $CertificateREQ) {del $CertificateREQ}
if (test-path $CertificateRSP) {del $CertificateRSP}
if (test-path $CertificateCER) {del $CertificateCER}
}
## Main
if ($args.length -ne 0) {$hostname = $args[0]}
else {$hostname = "$env:computername.$env:userdnsdomain".ToLower()}
# Check if a CA exists in the domain and if IIS is installed
if (@(certutil -dump | select-string "Config:")) {
$OnlineCA = (certutil -dump | select-string "Config:").Line.replace("``",'"').replace("'",'"').split('"')[1]
} else {
Write-Host "Unable to determine certificate authority (CA) for this domain"
Exit
}
if (-not @(Get-Service W3SVC -ErrorAction Ignore)) {
Write-Host "IIS is not installed on this machine"
Exit
}
# Check if a certificate already exists and prompt user to overwrite
if (@(Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" }).count -ne 0) {
Write-Host "A certificate for $hostname already exists"
$reply = Read-Host -Prompt "Overwrite existing certificate? (y/n)"
if ( $reply -notmatch "[yY]" ) { Exit }
Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Remove-Item
}
New-CertificateRequest -hostname $hostname > $null
Write-Host "`nCreated a new certificate for $hostname"
# Create https binding if necessary and add new cert to https binding
import-module WebAdministration
if (@(Get-WebBinding -name "Default Web Site" | Where-Object {$_.protocol -eq "https"}).count -eq 0) {
New-WebBinding -name "Default Web Site" -Protocol https -Port 443
Write-Host 'Created https binding for "Default Web Site"'
}
if (@(netsh http show sslcert ipport="0.0.0.0:443" | select-string -pattern "IP:port").count -ne 0) {
netsh http delete sslcert ipport="0.0.0.0:443" > $null
}
$cert = (Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Select-Object -First 1).Thumbprint
$guid = [guid]::NewGuid().ToString("B")
netsh http add sslcert ipport="0.0.0.0:443" certhash=$cert certstorename=MY appid="$guid" > $null
Write-Host "Updated https binding to use this certificate"
# Export certificate to .pfx (Windows 2012 and higher)
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
if ([Environment]::OSVersion.Version -ge (new-object 'Version' 6,2)) {
$pfxname = $hostname.Split(".")[0]
if ($pfxname -eq '*') {$pfxname = "wildcard"}
$pfxname = $pfxname + ".pfx"
Remove-Item $scriptPath\$pfxname -ErrorAction Ignore
$pfxpwd = ConvertTo-SecureString -String "certificate" -Force -AsPlainText
$cert = (Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Select-Object -First 1).Thumbprint
Get-ChildItem -Path cert:\localMachine\My\$cert | Export-PfxCertificate -FilePath $scriptPath\$pfxname -Password $pfxpwd -ChainOption EndEntityCertOnly > $null
Write-Host "Exported certificate in PFX format with password 'certificate' to"
Write-Host " $scriptPath\$pfxname"
}
# Export domain CA root certificate to domainRoot.cer
Remove-Item $scriptPath\domainRoot.cer -ErrorAction Ignore
certutil -config $OnlineCA '-ca.cert' $scriptPath\domainRoot.cer > $null
Write-Host "Exported domain root certificate to"
Write-Host " $scriptPath\domainRoot.cer"
メモ:
スクリプトを実行しようとしたときにセキュリティ例外のエラー メッセージが表示された場合は、実行ポリシーを調整する必要があります。スクリプトを実行できるように一時的に変更するには、次のコマンドを実行します。Set-ExecutionPolicy RemoteSigned -scope Process
既存の配置への新しい証明書のインポート
ArcGIS Enterprise 配置がすでに設定済みの場合は、以下の手順に従って新しい証明書を ArcGIS Enterprise ポータルとホスティング サーバーにインポートし、それを両方のコンポーネントのデフォルトの Web 証明書にします。
次の手順は、スクリプトによってエクスポートされる 2 つの証明書ファイル (*.cer 形式のドメイン ルート証明書と *.pfx 形式のサーバー証明書) をインポートする方法の概要です。この 2 つのファイルの場所は、スクリプトの保存場所である同じフォルダー内にする必要があります。これらはスクリプトの実行時にコマンド プロンプトの出力にも提示されます。
- https://sample.domain.com:7443/arcgis/portaladmin で ArcGIS Portal Administrator Directory にサイン インします。
- [Security] > [SSL Certificates] の順に参照して [Import Root or Intermediate Certificate] をクリックします。
- 証明書のエイリアスと、上記のスクリプトによってエクスポートされる domainRoot.cer ファイルへのファイル パスを指定します。[Do not restart the portal after import] オプションを選択して (ステップ 7 の操作でポータルが再起動します)、[Import] をクリックします。
- [SSL Certificates] に戻って、[Import Existing Server Certificate] をクリックします。
- 証明書のパスワード「certificate」と、ルート証明書に指定したエイリアスとは異なる証明書のエイリアスを入力して、コンピューター上で *.pfx ファイルを参照します。[インポート] をクリックします。
- [SSL Certificates] ページに戻って、[Update] をクリックします。
- [Web server SSL certificate] の値を、ステップ 5 でインポートした *.pfx 証明書のエイリアスに置き換えます。[更新] をクリックします。ポータルが再起動します。再起動には数分かかります。
- https://sample.domain.com:6443/arcgis/admin で ArcGIS Server Administrator Directory にサイン インします。
- [machines] > [<コンピューター名>] > [sslcertificates] の順に参照して、[importRootOrIntermediate] をクリックします。
- ステップ 3 と同様にエイリアスを入力して、domainRoot.cer ファイルの場所を参照します。[インポート] をクリックします。
- コンピューターのページに戻って、[importExistingServerCertificate] をクリックします。
- 再び「certificate」パスワードと、コンピューター上の *.pfx 証明書の場所を入力します。[送信] をクリックします。
- コンピューターのページに戻って、[edit] をクリックします。
- [Web server SSL certificate] の値を、新しいドメイン証明書のエイリアスに置き換えます。[編集の保存] をクリックします。サーバー コンピューターが再起動します。再起動には数分かかります。
ワークフローが完了すると、ArcGIS Enterprise ポータルとホスティング サーバーの新しい証明書がすべての Web ブラウザーによって信頼されるようになります。