こんにちは、サイオステクノロジー技術部 武井です。
今回はAzure上に構築したNGINXで、同じくAzure上に構築したADFS、Webアプリケーションプロキシへのリクエストを負荷分散してみたいと思います。
NGINXとは?
1日に数億リクエストを処理するような大規模サイトを中心に、ここ近年急速にシェアを伸ばしているオープンソース・ソフトウェア、それが「NGINX(エンジンエックス)」です。HTMLドキュメントや画像ファイルといった静的コンテンツを高速で配信します。消費するリソースも少なく、リバースプロキシやロードバランサーといった機能もある、今一番注目のWebサーバーです。
ADFS、Webアプリケーションプロキシとは?
Office365を始めとしたSAMLで認証するアプリケーションへのシングルサインオンを実現するソフトウェアです。
ADFS(Active Directory Federation System)を導入することにより、Active Directoryに参加した端末が、Office365を始めとしたSAMLに対応したアプリケーションへのシングルサイオンをできるようになります。ADFSは端末が保有するKerberos認証チケットをSAMLプロトコルに変換する役割を持ちます。
Webアプリケーションプロキシは、Active Directoryに参加できない端末が、Office365にログインするために、Active Directoryに認証情報を問い合わせる役割を持ちます。
今回の構成
今回の構成は以下のような感じです。
ADFS用、Webアプリケーションプロキシ用にそれぞれNGINXを構築します。ADFS、Webアプリケーションプロキシともに仕様上httpsのリクエストしか受け付けません。よって、今回構築するロードバランサーは、よくあるL7のレイヤー(リバースプロキシ)ではなく、L4のレイヤー(TCPによるロードバランス)で構築します。NGINXはTCPによるロードバランスをサポートしています。
構築方法
Azure上へのADFS、Webアプリケーションプロキシ構築方法については、以下の自習書を参考にして下さい。(横着してすみません・・・)
https://www.microsoft.com/ja-jp/download/details.aspx?id=43120
Virtual Machineの構築方法は、自習書に含まれる以下のドキュメントが参考になります。
microsoft_azure_virtual_machines_operation.pdf
ADFS、Webアプリケーションプロキシの構築方法は、同じく自習書に含まれる以下のドキュメントが参考になります。
AzureAD_Authentication_Eval_Guide_Jp.pdf
で、ADFS、WebアプリケーションプロキシがAzure上に構築出来ていることを前提として、それらへの負荷分散を行うNGINXを構築します。OSはCentOS7になります。
まず、Webアプリケーションプロキシへのリクエストを負荷分散するNGINXを構築します。NGINXのリポジトリをインストールします。
# yum install https://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
次に、NGINXをインストールします。
# yum install nginx
NGINXの設定ファイル(/etc/nginx/nginx.conf)に以下の内容を追加します。
stream { upstream adfsp { server 10.11.0.5:443; server 10.11.0.6:443; } server { listen 443; proxy_pass adfsp; } }
上記の内容は、443/tcpあてのリクエストが来たら、10.11.0.5(Webアプリケーションプロキシ1号機)、10.11.0.6(Webアプリケーション2号機)にラウンドロビンでそのまま流すことを意味します。
NGINXを再起動します。
# systemctl restart nginx
また、同様にADFSへのリクエストを負荷分散するためのNGINXを構築します。インストールまでは、Webアプリケーションプロキシ用のNGINXと同じです。違うのは設定ファイルになります。といってもほとんど同じです。
stream { upstream adfsp { server 10.11.0.7:443; server 10.11.0.8:443; } server { listen 443; proxy_pass adfsp; } }
upstream先のサーバーのIPアドレスが違うだけです。10.11.0.7(ADFS1号機)、10.11.0.8(ADFS2号機)になっています。
NGINXを再起動します。
# systemctl restart nginx
外向けDNS(インターネット上に公開されているDNS)に以下の内容のAレコードを登録して下さい。
- フェデレーションサービス名として指定したFQDN → Webアプリケーションプロキシ用NGINXにアクセスするためのグローバルIPアドレス
内向けDNS(社内などの閉じたネットワークからのみ参照されるDNS)に以下の内容のAレコードを登録して下さい。
- フェデレーションサービス名として指定したFQDN → ADFS用NGINXにアクセスするためのプライベートIPアドレス
以上で完了です。試しにOffice365にはアクセスしてみますと、まぁ、普通にアクセスできます。
効果を検証してみる
Office365にアクセスしただけでは、あまり効果を実感出来ません。そこで、パケットの中身を見てみることとします。今回は、Active Directoryに参加している端末がADFSにアクセスした時の、Active Directory参加端末⇔NGINX⇔ADFS間のパケットを見てみました。tcpdumpで取得し、Wiresharkで見ました。
ちっちゃくて見えないと思いますので、クリックして拡大してみて下さい。10.11.0.4はActive Directory参加端末です。10.11.0.9はNGINX、10.11.0.5はADFSです。ちゃんとNGINXがTCPのレイヤーでパケットをupstream先に渡しているのがわかります。
試しにADFS1号機を落としてみます。停止を押してみます。
停止しました。
この状態でOffice365にアクセスしてみて、パケットをキャプチャしてみます。
今度はちゃんとADFS2号機(10.11.0.6)にアクセスしているのがわかります。もちろん、Office365にも正常にアクセスできます。
効果を実感出来ました。
最後に
NGINXでここまで出来るのですから、高価なロードバランサーを入れなくてもよいと思います。
ところで、パケットを見ていて思ったのですが、送信元IPがロードバランサー(NGINX)になっています。これだと、ADFSやWebアプリケーションプロキシに記録されるのは、ロードバランサーのIPアドレスなので、ログを見ても、どのクライアントからアクセスしてきたのかわかりません。L7のロードバランサーだとx-forwarded-forヘッダに送信元IPアドレスを送ることができるのですが、今回のはL4ですので、それはできません。こんなときのためにNGINXはProxy Protocolでクライアント端末のIPを送出することができるのですが、それをADFSやWebアプリケーションプロキシでちゃんと取れるのかどうかは次回検証してみたいと思います。
nginx の詳細については下記をご覧ください!
https://sios.jp/products/oss-integration/service/oss_on_cloud/nginx.html