AWS Magaged Microsoft AD環境に作ったADFSサーバーを冗長化する

2019.10.09

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

注意事項
本記事では構築手順を解説していますがADFSの利用を推奨しているわけではありません。
本記事の内容は本番環境での利用を想定していませんので予めご了承ください。

しばたです。
前回はAWS Magaged Microsoft AD(以後Micorosft AD)環境にシングルのADFSサーバーとADFS WAPサーバーを構築しましたが、本記事ではより実践的な構成を目指しADFSサーバーを冗長化してみます。

検証環境

検証環境は下図の通りで、前回の構成にADFSサーバー1台と内部用ELBを追加しています。

通信要件はほとんど変わらないのですが、ELBのヘルスチェック(HTTPプローブ)のためにTCP 80(HTTP)の通信を許可しておく必要があります。 また、ADFSサーバー間での通信要件を見つけることが出来なかったのですが、これは全ての通信を許可しておけば問題ないでしょう。

その他詳細は以下。

ADFSサーバー

項目 設定値 備考
インスタンスタイプ t3.medium
OS 日本語版 Windows Server 2016 AMI : ami-0b26f62143241dc18
コンピューター名 ADFS02
ドメイン corp.shibata.tech に参加
Windows Firewall 無効に変更 通信制御はセキュリティグループで実施

ADFSサーバーは前回と同様です。

2台目のADFSサーバーの追加

前準備1 : gMSAの更新

ADFSサービスを動作させるユーザーであるグループ管理サービスアカウント(gMSA)は、前回の時点ではADFS01サーバーのみで利用可能な設定としていました。 このためADFSサーバーを増やす場合はこの設定を更新する必要があります。

Set-ADServiceAccountコマンドレットで-PrincipalsAllowedToRetrieveManagedPasswordパラメーターに利用可能サーバー名を$付きで指定してやります。

# ホスト名$ の形式で指定
Set-ADServiceAccount -Identity adfs-service -PrincipalsAllowedToRetrieveManagedPassword adfs01$, adfs02$

# 結果の確認
Get-ADServiceAccount -Identity adfs-service -Properties PrincipalsAllowedToRetrieveManagedPassword

前準備2 : 証明書のインポート

次に前回の記事で作成した証明書を新しいサーバーにインポートしておきます。

# エクスポートした証明書が C:\temp\adfs.pfx にある前提
$params = @{
    FilePath = 'C:\temp\adfs.pfx'
    CertStoreLocation = 'cert:\localMachine\my'
    Password = (ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force)
}
Import-PfxCertificate @params

1. 2台目のADFSサーバーの追加 (機能の追加)

ここからADFSサーバーの構築を開始します。

まずは前回同様にInstall-WindowsFeatureコマンドレットを使い「Active Directory Federation Services」の機能を追加します。

Install-WindowsFeature -Name 'ADFS-Federation' -IncludeManagementTools

2. 2台目のADFSサーバーの追加 (ADFSファームへのノード追加)

ここからADFSサーバーの設定に入り、Add-AdfsFarmNodeコマンドレットを使いADFSファームの2台目のノードを追加する形で設定を行います。

パラメーターは見れば大体わかるかと思いますが-PrimaryComputerNameパラメーターにADFS01を指定してやるのが重要です。

# 証明書情報を取得
$cert = Get-ChildItem Cert:\LocalMachine\My\ | Where-Object { $_.Subject -eq 'CN=sts.shibata.tech' }

# ADFSファームを構築する際のローカル管理者権限を持つユーザーの認証情報
$localAdminCred = Get-Credential 'corp\admin'

# 既存のファームへのノード追加
$params = @{
    CertificateThumbprint = $cert.Thumbprint
    GroupServiceAccountIdentifier = 'corp\adfs-service$'
    PrimaryComputerName = 'adfs01.corp.shibata.tech'
    Credential = $localAdminCred
    Verbose = $true
}
Test-AdfsFarmJoin @params
# インストール
# ※なぜか Test-AdfsFarmJoin にOverwriteConfigurationパラメーターが無いのでここで追加しておく
$params.OverwriteConfiguration = $true
Add-AdfsFarmNode @params

インストールに成功すると下図の様になります。

ADFS管理コンソールを開くとちゃんと2台目のサーバーとして登録されています。

ELB (Classic Load Balancer) の追加

続けてロードバランサーであるELBを追加します。

ADFSをロードバランシングにより冗長化する際の要件については以下に記載されています。

この要件から重要な点を抜き出すと、

  • ロードバランサーは SSL を終了できません。 ロードバランサーでの SSL の終了は、どのユースケースでもサポートされていません。
  • SNI をサポートするロードバランサーを使用することをお勧めします。
  • HTTP (HTTPS ではない) 正常性プローブエンドポイントを使用して、トラフィックをルーティングするロードバランサーの正常性チェックを実行することをお勧めします。

あたりでしょうか。

ADFSへはHTTPS通信をロードバランスできれば良いのですが、SSLを終端してはいけないためApplication Load Balancer(ALB)では上手く動作しませんでした。 手元の環境で試した限りではNetwork Load Balancer(NLB)かClassic Load Balancer(CLB)を選択しTCPでの通信設定をする必要がありました。 一応AWSのドキュメント上はELBによる負荷分散できるとあるのですが、ALB、NLB、CLBどれを使うべきかまでは記載されていませんでした。(恐らくはCLBなんだと思います...)

本記事ではCLBをマネジメントコンソールから作る想定で紹介します。 (一応NLBでも動作はしましたが本記事では割愛します)

まずロードバランサーの基本設定としてプロトコルをTCP 443にしてそのままインスタンスに分散させます。

  • ロードバランサーのプロトコル : TCP 443
  • インスタンスのプロトコル : TCP 443

サブネットは最初の図の通りプライベートサブネットを選択します。

セキュリティグループはADFS WAPからTCP 443を受信可能なものを選択します。

セキュリティ設定はスキップして、

ヘルスチェックはHTTPで行う必要があります。

  • pingプロトコル/ポート : HTTP 80
  • pingパス : /adfs/probe

この/adfs/probeがヘルスチェックのために用意されたパスで、ADFSサーバーが稼働していれば200を返す様になっています。

インスタンスにADFSサーバー2台を選択し、

あとはよしなに作成すればOKです。

これでELBの設定は完了です。

ADFS WAPサーバーの設定変更

ELBの追加が完了したらADFSサーバーのHOSTSファイルに設定しているsts.shibata.techの向き先をELBのIPアドレスに変更してやります。

<同一AZにあるELBのIP> sts.shibata.tech

これですべての設定が完了です。

最後に

ざっとこんな感じです。

ここまでご覧になった方は既に予測がついているかもしれませんが、次はADFS WAPサーバーを冗長化していきたいと思います。