GeekFactory

int128.hatenablog.com

nginxでLDAP認証を使う

Webアプリや共有フォルダなどの認証を必要とする場面が増えてくると、ユーザ管理のコストが無視できなくなります。Active DirectoryLDAPでIDを統合すると、運用者はユーザ管理が楽になり、利用者シングルサインオンで快適になります。たとえ自分しか使わない環境であっても、一括でパスワード変更できたり、簡単に認証を設定できるメリットは大きいでしょう。多くのアプリがLDAP認証に対応しています。

この記事ではnginxでLDAP認証を使う方法を説明します。.htpasswdによる認証とは異なり、IDとパスワードはWebサーバでは管理しません。LDAPサーバのリポジトリで管理します。

今回は以下のミドルウェアを使いました。

LDAPを準備する

OpenLDAPを構築します。今回は以下のツリーを想定します。

  • dc=example,dc=com
    • ou=users
      • uid=hoge (Webブラウザの認証に使うアカウント)
    • ou=services
      • cn=nginx (nginxがLDAPサーバに接続する時のアカウント)

LDAPリポジトリのメンテナンスツールは Apache Directory Studio が便利です。ldapaddコマンドとか知らなくても大丈夫。

SRPMを準備する

nginxはApache httpdとは違って動的にモジュールを追加できません。したがって、新しいモジュールを追加するには再ビルドが必要になります。ここではExtra Packages for Enterprise Linux (EPEL) リポジトリを使います。

(4/12追記) Amazon Linuxリポジトリにnginxが追加されました。以下と同様にSRPMを修正することでモジュールを組み込めます。ただし、SRPMを修正するとサポートを受けられなくなると思います。

nginxのSRPMhttp://dl.fedoraproject.org/pub/epel/6/SRPMS/repoview/nginx.html から取得できます。一般ユーザでインストールするとホームディレクトリにインストールされます*1

wget http://dl.fedoraproject.org/pub/epel/6/SRPMS/nginx-1.0.12-1.el6.src.rpm
rpm -ivh nginx-1.0.12-1.el6.src.rpm 

必須ではありませんが、SRPMからビルドしたRPMで動作確認しておきましょう。問題が起きた時に切り分けしやすくなると思います。

# ビルド
cd ~/rpm/SPECS/
rpmbuild -bb nginx.spec 
# インストール
cd ~/rpm/RPMS/
sudo yum install nginx-1.0.12-1.amzn1.x86_64.rpm

nginx-auth-ldapモジュールを組み込んでビルドする

specファイルを修正します。

  • EPELオリジナルの配布物と区別するため、リリースバージョンを変更します。
  • openldap-develなどに依存します。本来はspecファイルに依存関係を書くべきですが、今回は書いてません。
  • ビルドスクリプトに以下を追加します:
    • nginx-auth-ldapモジュールのソースコードをgit cloneします。
    • configureの引数に --add-module を渡します。

オリジナルとの差分は以下になります。

--- nginx.spec.dist     2012-03-17 17:31:49.320143008 +0900
+++ nginx.spec  2012-03-17 19:50:51.158143267 +0900
@@ -9,7 +9,7 @@
 
 Name:           nginx
 Version:        1.0.12
-Release:        1%{?dist}
+Release:        1.20120317%{?dist}
 Summary:        Robust, small and high performance HTTP and reverse proxy server
 Group:          System Environment/Daemons
 
@@ -59,6 +59,8 @@
 %patch0 -p0
 
 %build
+# retrieve LDAP authentication module
+git clone 'https://code.google.com/p/nginx-auth-ldap/'
 # nginx does not utilize a standard configure script.  It has its own
 # and the standard configure options cause the nginx configure script
 # to error out.  This is is also the reason for the DESTDIR environment
@@ -80,6 +82,7 @@
     --http-scgi-temp-path=%{nginx_home_tmp}/scgi \
     --pid-path=%{_localstatedir}/run/%{name}.pid \
     --lock-path=%{_localstatedir}/lock/subsys/%{name} \
+    --add-module=./nginx-auth-ldap/ \
     --with-http_ssl_module \
     --with-http_realip_module \
     --with-http_addition_module \

SRPMをビルドし、生成されたRPMをインストールします。

# ビルド
cd ~/rpm/SPECS/
rpmbuild -bb nginx.spec 
# インストール
cd ~/rpm/RPMS/
sudo yum install nginx-1.0.12-1.20120317.amzn1.x86_64.rpm
# libldapに依存していればおk
ldd /usr/sbin/nginx

LDAP認証を有効にする

設定例にしたがって、LDAP認証を有効化します。例えばこんな感じです:

http {
    # (中略)

    # LDAPサーバとバインドアカウント
    auth_ldap_url ldap://localhost/ou=users,dc=example,dc=com?uid?sub;
    auth_ldap_binddn cn=nginx,ou=services,dc=example,dc=com;
    auth_ldap_binddn_passwd 'some_password';

    server {
        listen 80;
        server_name private.example.com;

        location / {
            root   /var/www/html;
            index  index.html;

            # ユーザhogeのみアクセスを許可する
            auth_ldap 'Authentication Required';
            auth_ldap_require user 'uid=hoge,ou=users,dc=example,dc=com';
        }
    }
}

auth_ldap_requireにはユーザだけでなくグループも指定できます。

auth_ldap_urlに指定するURLは http://www.ipa.go.jp/security/rfc/RFC2255JA.html を参考にしてください。上記では "ou=users,dc=example,dc=com" のサブツリーから "uid=(クライアントから受け取ったユーザ名)" に合致するエントリを検索するように設定しています。

設定を変更したらリロードします。構文エラーがある場合は表示されます。

sudo service nginx reload

動作確認

Webブラウザから保護対象URLにアクセスし、認証ダイアログが表示されることを確認します。また、わざとパスワードを間違えて拒否されることを確認します。うまく動かない場合はnginxのログをチェックしましょう。

*1:~/.rpmmacrosでSRPMの配置先を設定しておく必要があります。