NGINX PlusによるMicrosoft Active Directory Federation Servicesの高可用性

NGINX | 2018年10月16日

Microsoft Active Directory Federation Services(AD FS)を使用すると、Windows Server上でアプリケーションをホストする組織は、エクストラネットを介して、信頼できるビジネスパートナーの従業員にもシングルサインオン(SSO)アクセスを拡張できます。ビジネスパートナー間でのID情報の共有は「フェデレーション」と呼ばれます。

実際、AD FSを使用すると、フェデレーションに参加する企業の従業員は、自社の環境にログインするだけで済みます。信頼関係にあるビジネスパートナーのWebアプリケーションにアクセスすると、ローカルのAD FSサーバーが、セキュリティトークンの形式で従業員のID情報をパートナーのAD FSサーバーに渡します。このトークンは複数のクレームで構成されます。クレームとは、ローカルのActive Directoryに保存されている従業員の個別属性(ユーザー名、業務上の役割、従業員IDなど)です。パートナーのAD FSサーバーは、トークン内のクレームをパートナーのアプリケーションが認識できるクレームにマッピングし、要求された種類のアクセスが従業員に許可されているかどうかを判断します。

AD FS 2.0以降では、高可用性(HA)を有効にすることで、アプリケーションの認証サービスのレジリエンスと拡張性を高めることができます。AD FS HAクラスター(AD FS ファームとも呼ばれます)では、複数のAD FSサーバーを単一のデータセンター内に配置するか、複数のデータセンターに分散して配置します。全系稼働型HAとして構成されたクラスターでは、AD FSサーバー間でトラフィックを均等に分散するためにロードバランサーが必要です。アクティブ/パッシブ型HA構成では、プライマリAD FSサーバーに障害が発生した際に、ロードバランサーによってバックアップAD FSサーバーへフェイルオーバーできます。

この記事では、AD FS 3.0とAD FS 4.0をそれぞれWindows Server 2012 R2とWindows Server 2016で実行する環境において、HAを実現するためのNGINX Plusの構成方法について説明します。

AD FSの標準HAトポロジ

本記事では、説明のために標準的なAD FSファームトポロジを使用します。これは推奨を目的としたものではなく、考えられるすべての導入シナリオを網羅するものでもありません。オンプレミス環境では、標準的なファームは、企業イントラネット上の1台以上のAD FSサーバーと、その前段に配置された1台以上のWeb Application Proxy(WAP)サーバーで構成されます。WAPサーバーはDMZネットワーク上に配置され、リバースプロキシとして機能することで、外部ユーザーが企業イントラネット上でホストされているWebアプリケーションにアクセスできるようにします。

ただし、WAPにはサーバークラスターを構成したり、HAをサポートしたりする機能が組み込まれていないため、WAPサーバーの前段にロードバランサーを導入する必要があります。また、AD FSのHAを実現するため、DMZとイントラネットの境界にもロードバランサーを配置します。標準的なAD FSファームでは、Windows Server 2012および2016のネットワーク負荷分散(NLB)機能がロードバランサーとして動作します。最後に、通常はロードバランサーの外部IPアドレスの前段と、ネットワークゾーン間にファイアウォールを実装します。

図1. NLBを使用した標準的なオンプレミスAD FSファーム

標準HAトポロジでのNGINX Plusの使用

前述のとおり、NLBはAD FSファームの負荷分散を実行できます。ただし、その機能は非常に基本的なものに限られます(基本的なヘルスチェックと限定的な監視機能のみ)。NGINX Plusは軽量でありながら、本番環境のAD FSでHAを実現するために不可欠な機能を数多く備えています。

ここで説明する標準トポロジの導入では、NGINX PlusがNLBに代わり、すべてのWAPファームとAD FSファームのトラフィックを負荷分散します。ただし、AD FSが正しく動作するには、WAPサーバーからの実際のSSL証明書をAD FSサーバーが確認できる必要があるため、NGINX PlusではAD FSサーバーへのSSL接続を終端しません(詳細については、こちらの「Microsoft TechNetの記事」を参照してください)。

本番環境では、NGINX Plus自体にもHAを実装することを推奨しますが、ここでは示していません。手順については、NGINX Plus Admin Guideの「オンプレミス環境への導入におけるNGINX Plusの高可用性サポート」を参照してください。

図2. NGINX Plusを使用した標準的なオンプレミスAD FSファーム

AD FSサーバーを負荷分散するためのNGINX Plusの設定

AD FSサーバーを負荷分散するためのNGINX Plusの設定は簡単です。前述のとおり、AD FSサーバーはWAPサーバーからの実際のSSL証明書を確認する必要があります。そのため、DMZとイントラネットの境界にあるNGINX Plusインスタンスを、SSL暗号化トラフィックを終端したりその他の処理を行ったりせずにAD FSサーバーへ転送するよう設定します。

必須のディレクティブに加えて、次のディレクティブを設定に含めます。

  • zone は、すべてのNGINX Plusワーカープロセスがアップストリームグループ内のサーバーに関する構成情報と実行時の状態情報にアクセスできるよう、共有メモリ内に領域を割り当てます。
  • hashは、送信元IPアドレス(クライアントのIPアドレス)に基づいて、クライアントとAD FSサーバー間のセッション永続性を確立します。クライアントはAD FSサーバーとのTCP接続を1つだけ確立しますが、セッション永続性が有効になっていない場合、特定の条件下では一部のアプリケーションでログインのリダイレクトが複数回発生する可能性があるため、この設定が必要です。
  • status_zoneは、NGINX Plus APIがこのサーバーのメトリクスを収集することを意味します。収集したメトリクスは、組み込みのライブアクティビティ監視ダッシュボードに表示できます(APIとダッシュボードは個別に設定します)。
stream {    upstream adfs_ssl {
        zone adfs_ssl 64k;
        server 10.11.0.5:443; # AD FS server 1
        server 10.11.0.6:443; # AD FS server 2
        hash $remote_addr;
    }

    server {
        status_zone adfs_ssl;
        listen 10.0.5.15:443;
        proxy_pass adfs_ssl;
    }
}


WAPサーバーからのトラフィックがNGINX Plusを経由してAD FSサーバーに到達するようにするには、フェデレーションサービス名(この例ではfs.example.com)を、NGINX PlusがリッスンしているIPアドレスにマッピングする必要もあります。本番環境では、DMZにDNSホストAレコードを追加します。テスト環境では、各WAPサーバーのhostsファイルにエントリを作成すれば十分です。ここでは、fs.example.comをhostsファイル内で10.0.5.15に関連付けます。

図3. hostsファイルでのNGINX Plusサーバーのマッピング

WAPサーバーからのトラフィックがAD FSサーバーに到達することをテストするため、まずipconfig /flushdnsコマンドを実行してDNSキャッシュをフラッシュします。次に、ブラウザーでSSOページからAD FSにログインします。https://fs.example.com/adfs/ls/idpinitiatedsignon.htm:

図4. AD FSへのログイン

WAPサーバーを負荷分散するためのNGINX Plusの設定

次に、外部クライアントからWAPサーバーへのHTTPS接続を負荷分散するようにNGINX Plusを構成します。ベストプラクティスでは、AD FSサーバーに到達する時点でもトラフィックをSSL暗号化しておく必要があります。そのため、NGINX PlusがHTTPSトラフィックをWAPサーバーに転送するように、SSLパススルーまたはSSL再暗号化のいずれかの方法で構成します。

SSLパススルーの設定

より簡単な構成では、SSLで暗号化されたTCPトラフィックをNGINX PlusからWAPサーバーへ変更せずに転送します。そのため、streamコンテキストに、前述のAD FSサーバーの負荷分散用仮想サーバーと同様の仮想サーバーを構成します。

ここでは、NGINX Plusは別の一意のIPアドレス10.0.5.100で外部トラフィックをリッスンします。本番環境では、公開アプリケーションの外部FQDNが、パブリックゾーンのDNSホストAレコードとしてこのアドレスを指すようにする必要があります。テストでは、クライアントマシンのhostsファイルにエントリを追加するだけで十分です。

注:このサーバーと同じIPアドレスでリッスンする追加のHTTPSサービスをstreamコンテキストで構成する場合は、トラフィックを異なるアップストリームに正しくルーティングするために、ssl_prereadディレクティブとmapを使用してServer Name Indication(SNI)を有効にする必要があります。この内容は本ブログの範囲外ですが、NGINXのリファレンスドキュメントに例が掲載されています。

stream {    upstream wap {
        zone wap 64k;
        server 10.11.0.5:443; #WAP server 1
        server 10.11.0.6:443; #WAP server 2
        least_time connect;
    }
  
    server {
        status_zone wap_adfs;
        listen 10.0.5.100:443;
        proxy_pass wap;
    }
}

HTTPS再暗号化の設定

SSLパススルーの代わりに、httpコンテキストでHTTPSトラフィックを受け入れるように仮想サーバーを構成することで、NGINX Plusのレイヤー7機能を最大限に活用できます。NGINX PlusはクライアントからのHTTPS接続を終端し、WAPサーバーへの新しいHTTPS接続を確立します。

証明書ファイルと秘密鍵ファイルである「example.com.crt」と「example.com.key」では、公開されたアプリケーションの外部FQDNが、コモンネーム(CN)またはサブジェクト代替名(SAN)プロパティに含まれています。この例のFQDNは「fs.example.com」です。

The proxy_ssl_server_nameディレクティブとproxy_ssl_nameディレクティブは、SSL Client Helloで送信するリモートホスト名を指定し、必要なServer Name Indication(SNI)ヘッダーを有効にします。このヘッダーは、公開されたアプリケーションの外部FQDNと一致する必要があります。この例では、fs.example.comです。

関連情報をWAPサーバーに渡し、ログにも記録できるように、proxy_set_headerディレクティブを使用します。

  • The X-Real-IPヘッダーには、$remote_addr変数で取得された送信元(クライアント)のIPアドレスが格納されます。
  • The X-Forwarded-Forヘッダーは、クライアントリクエストの同名ヘッダーにクライアントのIPアドレスを追加して転送します(クライアントリクエストに同名ヘッダーがない場合は、そのIPアドレスのみを転送します)。
  • The x-ms-proxyヘッダーは、ユーザーがプロキシサーバー経由でルーティングされたことを示し、そのサーバーがNGINX Plusインスタンスであることを識別します。

ここで示したディレクティブに加えて、NGINXとNGINX Plusには、SSL/TLSのパフォーマンスとセキュリティの向上に役立つさまざまな機能があります。詳しくは、F5の「ブログ」をご覧ください。

http {    upstream wap {
        zone wap 64k;
        server 10.0.5.11:443;
        server 10.0.5.10:443;
        least_time header;
    }

    server {
        listen 10.0.5.100:443 ssl;
        status_zone fs.example.com;
        server_name fs.example.com;
        ssl_certificate     	/etc/ssl/example.com/example.com.crt;
        ssl_certificate_key 	/etc/ssl/example.com/example.com.key;

        location / {
            proxy_pass https://wap; # 'https' enables reencrypt 
            proxy_ssl_server_name on;
            proxy_ssl_name $host;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header x-ms-proxy $server_name;
        }
    }
}

WAPサーバーを使用しないトポロジでのNGINX Plusの構成

外部クライアントからAD FSサーバーへのアクセスを有効にする場合は、DMZと社内イントラネットの境界で外部トラフィックを終端し、さらにx-ms-proxyヘッダーを挿入して外部からの認証試行を識別することがベストプラクティスです。WAPサーバーはこれら両方の機能を実行しますが、前のセクションで構成したNGINX Plusも同様に実行します。

一部のユースケースでは、WAPサーバーは必要ありません。たとえば、IPネットワークや信頼レベルなどの高度な要求規則を使用しない場合です。このような場合、WAPサーバーを廃止し、DMZとイントラネットの境界にNGINX Plusを配置して、内部のAD FSサーバーへのリクエストを認証できます。これにより、ハードウェア、ソフトウェア、運用のコストを削減できます。

図5. WAPサーバーを使用しないAD FSファーム

この構成は、標準HAトポロジの構成に代わるものです。WAPサーバーを負荷分散するためのHTTPS再暗号化構成とほぼ同じですが、この構成では、NGINX Plusが外部リクエストを内部ネットワークのAD FSサーバーに直接負荷分散します。

upstream adfs {    zone adfs 64k;
    server 192.168.5.5:443; # AD FS Server 1
    server 192.168.5.6:443; # AD FS Server 2
    least_time header;
 }

server {
    listen 10.0.5.110:443 ssl;
    status_zone adfs_proxy;
    server_name fs.example.com;
    ssl_certificate         /etc/ssl/example.com/example.com.crt;
    ssl_certificate_key     /etc/ssl/example.com/example.com.key;
  
    location / {
        proxy_pass https://adfs;
        proxy_ssl_server_name on;
        proxy_ssl_name $host;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header x-ms-proxy $server_name;
    }
 }

AD FS環境でNGINX Plusをお試しください。今すぐ30日間の無料トライアルを開始するか、お問い合わせのうえ、ユースケースについてご相談ください。


共有

関連するブログ記事

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
NGINX | 2024/01/18

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する

OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
NGINX | 2023/05/31

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正

Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
NGINX | 2023/02/09

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法

Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINX | 2022/05/24

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング

NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
NGINX | 2018/08/17

SELinuxでNGINXおよびNGINX Plusを使用する

Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。

NGINX PlusによるAWS Auto Scalingグループの負荷分散
NGINX | 2017/03/06

NGINX PlusによるAWS Auto Scalingグループの負荷分散

新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります