ブログ | NGINX

NGINX Plus と NGINX を使用して LDAP でアプリケーション ユーザーを認証する

NGINX-F5 水平黒タイプ RGB の一部
オーウェン・ギャレット サムネイル
オーウェン・ギャレット
2015 年 6 月 22 日公開

保護されたリソースやアプリケーションを、それを要求するユーザーを認証することで保護するために、NGINX Plus と NGINX をどのように使用すればよいのか、という質問をお客様からよく受けます。 本日、私たちはそのような認証システムのリファレンス実装を発表し、 GitHubの NGINX, Inc. リポジトリで公開します。 この投稿では、実装の仕組み、インストール方法、独自の認証システムのモデルとして使用する方法について説明します。

このソリューションは、NGINX Plus および NGINX のngx_http_auth_request_moduleモジュールを利用して、認証リクエストを外部サービスに転送します。 リファレンス実装では、そのサービスはldap‑authと呼ばれるデーモンです。 これは Python で記述されており、Lightweight Directory Access Protocol (LDAP) 認証サーバー (デフォルトではOpenLDAP)と通信しますが、Microsoft® Windows® Server Active Directory (2003 バージョンと 2012 バージョンの両方) のデフォルト構成に対しても ldap‑auth デーモンをテストしました。

ldap‑auth デーモンは、独自の「コネクタ」アプリのモデルとして機能します。このアプリは、他の言語で作成したり、異なる認証システムで展開したり、またはその両方を行うことができます。 NGINXプロフェッショナル サービスチームが、このような適応を支援します。

注:

  • リファレンス実装は、実稼働環境での使用を目的としたものではなく、独自の実装のモデルとしてのみ使用されます。
  • 読みやすくするために、この記事の残りの部分では NGINX Plus について言及していますが、リファレンス実装は NGINX Open Source でも動作します。 前提条件となる http_auth_request モジュールは、NGINX Plus パッケージビルド済みの NGINX バイナリの両方に含まれています。

リファレンス実装における認証の仕組み

認証を実行するために、http_auth_request モジュールは ldap‑auth デーモンに HTTP サブリクエストを送信します。ldap‑auth デーモンは仲介役として機能し、LDAP サーバーのサブリクエストを解釈します。NGINX Plus との通信には HTTP を使用し、LDAP サーバーとの通信には適切な API を使用します。

リファレンス実装に興味がある場合は、認証を要求することで保護するアプリケーションやその他のリソースがすでにあると想定しています。 ただし、リファレンス実装のテストを容易にするために、ポート 9000 でリッスンする、Python で記述されたサンプル バックエンド デーモンを提供しています。 ユーザーの資格情報を要求し、それに基づいて Cookie を作成することで、テスト中に実際の HTTP アプリケーションの代わりに使用できます。

LDAP認証用のNGINX Plusリファレンス実装には、ldap-authデーモンとサンプルバックエンドデーモンが含まれています。

ここでは、リファレンス実装における認証プロセスを段階的に説明します。 詳細は、 nginx-ldap-auth.conf構成ファイルの設定によって決まります。以下の「リファレンス実装の構成」を参照してください。 手順の下のフローチャートはプロセスを要約したものです。

  1. クライアントは、NGINX Plus がリバース プロキシとして機能しているサーバー上でホストされている保護されたリソースに対して HTTP リクエストを送信します。

  2. NGINX Plus(具体的にはhttp_auth_requestモジュール)はリクエストをldap-authデーモンに転送し、ldap-authデーモンはHTTPコードで応答します。401資格情報が提供されなかったためです。

  3. NGINX Plus は、バックエンドデーモンに対応するhttp://backend/loginにリクエストを転送します。 転送されたリクエストのX-Targetヘッダーに元のリクエスト URI を書き込みます。

  4. バックエンド デーモンはクライアントにログイン フォームを送信します (フォームはデーモンの Python コードで定義されます)。 error_pageディレクティブで設定されているように、NGINXはログインフォームのHTTPコードを次のように設定します。200

  5. ユーザーはフォームのユーザー名とパスワードのフィールドに入力し、「ログイン」ボタンをクリックします。 フォーム内のコードに従って、クライアントは/login宛ての HTTP POSTリクエストを生成し、NGINX Plus はそれをバックエンド デーモンに転送します。

  6. バックエンド デーモンは、 username : passwordという形式の文字列を作成し、Base64 エンコードを適用し、エンコードされた文字列に値を設定したnginxauthという Cookie を生成し、その Cookie をクライアントに送信します。 JavaScript を使用して Cookie を読み取ったり操作したりすることを防ぐために、 httponlyフラグを設定します (クロスサイト スクリプティング [XSS] の脆弱性から保護します)。

  7. クライアントは元のリクエスト (ステップ 1 から) を再送信しますが、今回は HTTP ヘッダーのCookieフィールドに Cookie を含めます。 NGINX Plus はリクエストを ldap-auth デーモンに転送します (手順 2 を参照)。

  8. ldap-auth デーモンは Cookie をデコードし、認証要求でユーザー名とパスワードを LDAP サーバーに送信します。

  9. 次のアクションは、LDAP サーバーがユーザーを正常に認証したかどうかによって異なります。

    • 認証が成功すると、ldap-authデーモンはHTTPコードを送信する。200 NGINX Plus へ。 NGINX Plus はバックエンド デーモンからリソースを要求します。 リファレンス実装では、バックエンド デーモンは次のテキストを返します。

         こんにちは世界! 要求された URL: メールアドレス
      

      nginx-ldap-auth.confファイルには、認証試行の結果をキャッシュするためのディレクティブが含まれています。キャッシュを無効にするには、以下の「キャッシュ」を参照してください。

    • 認証に失敗した場合、ldap-authデーモンはHTTPコードを送信する。401 NGINX Plus へ。 NGINX Plus はリクエストをバックエンド デーモンに再度転送し (手順 3 を参照)、プロセスが繰り返されます。

NGINX PlusのLDAP認証リファレンス実装では、ldap-authデーモンがNGINX PlusとLDAPサーバー間の仲介役となります。

コンポーネントのインストール

リファレンス実装で配布される NGINX Plus 構成ファイルnginx-ldap-auth.confは、LDAP サーバー以外のすべてのコンポーネント (つまり、NGINX Plus、クライアント、ldap-auth デーモン、およびバックエンド デーモン) が同じホスト上で実行されるように構成します。これはテスト目的には十分です。 テスト中は、LDAP サーバーをそのホスト上で実行することもできます。

実際の展開では、バックエンド アプリケーションと認証サーバーは通常、それぞれ別のホストで実行され、NGINX Plus は 3 番目のホストで実行されます。 ldap-auth デーモンはほとんどの場合多くのリソースを消費しないため、NGINX Plus ホストまたは任意の別のホストで実行できます。

  1. GitHub リポジトリのクローンを作成します。

  2. NGINX Plus がまだ実行されていない場合は、オペレーティング システムの手順に従ってインストールします。

  3. LDAP サーバーがまだ実行されていない場合は、インストールして構成します。 デフォルトでは、ldap‑auth デーモンは OpenLDAP と通信しますが、Microsoft Windows Active Directory 2003 および 2012 もサポートされています。

    リファレンス実装をテストするためだけに LDAP サーバーを使用している場合は、GitHub で入手できるOpenLDAP サーバー Docker イメージを使用することも、 「Ubuntu 16.04 に OpenLDAP と phpLDAPadmin をインストールして構成する方法」などの手順に従ってサーバーをセットアップすることもできます。

    ベース DN、バインド DN、バインド パスワードに設定した値をメモします。 これらは、「リファレンス実装の構成」の NGINX 構成ファイルに記載されます。

  4. ldap‑auth デーモンを実行するホストに、次の追加ソフトウェアをインストールします。 オープン ソース リポジトリからソフトウェアをダウンロードするのではなく、オペレーティング システムとともに配布されるバージョンを使用することをお勧めします。

    • Python バージョン 2。 バージョン 3 はサポートされていません。
    • Python LDAP モジュール、 python‑ldap ( python-ldap.orgオープン ソース プロジェクトによって作成)。
  5. リポジトリ クローンから次のファイルを指定されたホストにコピーします。

    • nginx-ldap-auth.conf – リファレンス実装をテストするための最小限のディレクティブ セットを含む NGINX Plus 構成ファイル。 NGINX Plus ホストにインストールします (従来の構成スキームを使用する場合は、 /etc/nginx/conf.dディレクトリにインストールします)。 設定の競合を避けるため、NGINX Plus とともにインストールされたデフォルトの設定ファイルを移動するか、名前を変更することを忘れないでください。
    • nginx-ldap-auth-daemon.py – ldap‑auth デーモンの Python コード。 選択したホストにインストールします。
    • nginx-ldap-auth-daemon-ctl.sh – デーモンを起動および停止するためのサンプル シェル スクリプト。 ldap-auth デーモンと同じホストにインストールします。
    • backend-sample-app.py – テスト中にバックエンド アプリケーション サーバーの代わりになるデーモンの Python コード。 選択したホストにインストールします。
  6. 以下の「リファレンス実装の構成」の説明に従って、NGINX Plus 構成ファイルを変更します。 変更を加えた後、 nginx -tコマンドを実行して、ファイルが構文的に有効であることを確認します。

    root# nginx -t nginx: 設定ファイル /etc/nginx/nginx.conf の構文は正常です nginx: 設定ファイル /etc/nginx/nginx.conf のテストは成功しました
    
  7. NGINX Plusを起動します。 NGINX Plus がすでに実行されている場合は、次のコマンドを実行して設定ファイルを再読み込みします。

    ルート# nginx -s リロード
    
  8. 適切なホストで次のコマンドを実行して、ldap‑auth デーモンとバックエンド デーモンを起動します。

    root# nginx-ldap-auth-daemon-ctl.sh を開始root# python backend-sample-app.py
    
  9. Web ブラウザを使用してhttp:// nginx-server-address :8081にアクセスします。 ブラウザに認証フォームが表示されていることを確認します。 フォームに入力して送信した後、サーバーが有効な資格情報に対して期待どおりの応答を返すことを確認します。 前述のように、バックエンド デーモンは次のテキストを返します。

       こんにちは世界! 要求された URL: メールアドレス
    

リファレンス実装の構成

nginx-ldap-auth.confファイルに次の変更を加えます。 示されているように、一部は必須で、一部はオプションです。

LDAP サーバー設定

nginx-ldap-auth-daemon.pyに実装されているように、 ldap‑auth デーモンは OpenLDAP サーバーと通信し、認証するユーザー アカウントを指定するためのパラメーターを渡します。 Python コードを変更する必要性をなくすために、 nginx-ldap-auth.confファイルには、パラメータの設定に使用される HTTP ヘッダーの値を設定するproxy_set_headerディレクティブが含まれています。 次の表は、パラメータとヘッダーのマッピングを示しています。

LDAPパラメータ HTTP ヘッダー
ベース X-LDAP ベース DN
バインド X-Ldap-BindDN
バインドパスワード X-Ldap-BindPass
クッキー名 X-Cookie名
領域 X-Ldap-レルム
テンプレート X-Ldap テンプレート
URL X-LDAP-URL
  • (必須) 次のディレクティブで、太字の値を LDAP サーバー展開の正しい値に置き換えます。 特に、 nginx-ldap-auth.confファイルは LDAPS の既知のポート 636 を使用することに注意してください。 ポートを 389 (LDAP の既知のポート) または別の LDAP ポートに変更する場合は、プロトコル名もldapsからldapに変更することを忘れないでください。

    # LDAP サーバーに接続するための URL とポート proxy_set_header X-Ldap-URL " ldaps :// example.com :636 "; # ベース DN proxy_set_header X-Ldap-BaseDN " cn=Users,dc=test,dc=local "; # バインド DN proxy_set_header X-Ldap-BindDN " cn=root,dc=test,dc=local "; # バインド パスワード proxy_set_header X-Ldap-BindPass " secret ";
    
  • (OpenLDAP ではなく Active Directory を使用する場合は必須) 次のディレクティブを次のようにコメント解除します。

    proxy_set_header X-Ldap-Template "(SAMAccountName=%(username)s)";
    
  • (オプション) リファレンス実装では、Cookie ベースの認証が使用されます。 代わりに HTTP 基本認証を使用している場合は、次のディレクティブを次のようにコメント アウトします。

    # proxy_set_header X-CookieName "nginxauth"; # proxy_set_header Cookie nginxauth=$cookie_nginxauth;
    
  • (オプション) ldap‑auth デーモンがデフォルトで OpenLDAP サーバーに渡すテンプレートパラメーターの値を変更する場合は、次のディレクティブを次のようにコメント解除し、値を変更します。

    proxy_set_header X-Ldap-Template " (cn=%(username)s) ";
    
  • (オプション) レルム名をデフォルト値 ( Restricted ) から変更する場合は、次のディレクティブのコメントを解除して変更します。

    proxy_set_header X-Ldap-Realm "制限";
    

バックエンドデーモンの IP アドレス

バックエンド デーモンが NGINX Plus と同じホスト上で実行されていない場合は、アップストリーム構成ブロックでその IP アドレスを変更します。

アップストリームバックエンド{サーバー127.0.0.1:9000; }

ldap‑auth デーモンの IP アドレス

ldap‑auth デーモンが NGINX Plus と同じホスト上で実行されていない場合は、次のproxy_passディレクティブの IP アドレスを変更します。

場所 = /auth-proxy { proxy_pass http://127.0.0.1 :8888; # ... }

NGINX が listen する IP アドレスとポート

クライアントが NGINX Plus と同じホスト上で実行されていない場合は、このlistenディレクティブの IP アドレスを変更します (または、アドレスを完全に削除して、すべてのクライアントからのトラフィックを受け入れるようにします)。 必要に応じて、NGINX が listen するポートを 8081 から変更することもできます。

サーバー{ listen127.0.0.1 :8081 ; # ... }

キャッシング

nginx-ldap-auth.confファイルにより、データと資格情報の両方のキャッシュが可能になります。 必要に応じて、次の設定を変更できます。

  • http構成ブロックのproxy_cache_pathディレクティブは、 cacheと呼ばれるローカル ディスク ディレクトリを作成し、メタデータが保存されるauth_cacheと呼ばれるゾーンに 10 MB の共有メモリを割り当てます。

    proxy_cache_pathキャッシュ/ keys_zone= auth_cache : 10m ;
    

    共有メモリ ゾーンの名前を変更する場合は、 proxy_cacheディレクティブ (ldap-auth デーモンにトラフィックを送信するlocationブロック内) でも名前を変更する必要があります。

    場所 = /auth-proxy { proxy_cache auth_cache ; # ... }
    
  • proxy_cache_validディレクティブ( proxy_cacheと同じロケーションブロック内)は、HTTPコードでマークされたキャッシュされたレスポンスを指定します。200または403有効期間は10分です。

    場所 = /auth-proxy { proxy_cache_valid 200 403 10m ; # ... }
    

キャッシュを無効にするには、これら 3 つのディレクティブとproxy_cache_keyディレクティブをコメント アウトします。

認証システムのカスタマイズ

前述のように、ldap‑auth デーモンを、http_auth_request モジュールからの要求を受け入れる独自のアプリケーションのモデルとして使用できます。 Python でアプリを作成して、異なる (LDAP 以外の) タイプの認証サーバーと通信する場合は、 nginx-ldap-auth-daemon.pyスクリプトのLDAPAuthHandler を置き換える新しい認証ハンドラー クラスを作成します。

セキュリティに関する注意事項

バックエンド デーモンは、Cookie 内のユーザー名とパスワードに Base64 エンコードを使用します。 Base64 は非常に弱い形式のスクランブルであり、資格情報が抽出され、悪用される危険性があります。 認証を実際の目的に役立てるには、バックエンド アプリケーションでより高度な暗号化を使用する必要があります。


「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"