ApacheをReverse Proxyにすると、SSL化や認証についてApacheに関する情報がそのまま流用できて便利だよね、と思い認証ハンドラを作成しました。 とりあえず自分が使うのに必要なものを作って、一般化するために最低限の機能だけを加えています。
CouchDB Wikiにある Apache_As_a_Reverse_Proxyの手順でも似たようなことはできますが、null_authentication_handlerを使う事で、localhostのユーザは無制限にadmin権限を手に入れることができてしまいます。
これはReverse Proxy ServerとCouchDBを別のサーバで動かす場合に、気をつけなければならない点です。
この認証ハンドラは強固なセキュリティを提供するものではありませんが、いくらかリスクを軽減する事ができるはずです。
最終的に仕上げたCouchDB 1.0.1用のパッチは、新しいハンドラを追加しただけで、既存の機能は変更していないので、内部的な変更がなければ基本的には他のバージョンでも動くはずです。
- 20101127.1.couchdb101.webproxy.diff(sha1sum: b53b6621d84f5ca63570060da7eac7c9d82eee7f)
- 20101127.1.couchdb101.webproxy.diff.gz(sha1sum: 7bfbd1a03bc36b53c30fa16a8fab1dc1984f521f)
この認証ハンドラは AlexにDebian lennyを入れた環境で試しています。 Erlang-R14BとCouchDB-1.0.1は手動でコンパイルしました。
セットアップ手順
~/20101127.1.couchdb101.webproxy.diffを準備して、CouchDB-1.0.1をコンパイルしたディレクトリに移動します。
$ cd apache-couchdb-1.0.1 $ patch -p1 < ~/20101127.1.couchdb101.webproxy.diff $ cd src/couchdb $ make $ sudo cp couch_httpd_auth.beam /usr/local/lib/couchdb/erlang/lib/couch-1.0.1/ebin/
local.iniなどのiniファイルで認証にwebproxy_authentication_handlerを使用するようにします。
[httpd]
authentication_handlers = {couch_httpd_auth, webproxy_authentication_handler}
この認証ハンドラは2つのオプションを取ります。
- require_authentication_db_entry (default: true) - trueの場合、authentication_dbにユーザ名に対応したエントリがない場合、認証に失敗します
- webproxy_use_secret (default:false) - trueの場合、Reverse Proxyが適切なX-Auth-CouchDB-Tokenヘッダを付与しない場合、認証に失敗します
これらを加えた一般的なこの認証ハンドラを使う場合の設定は次のようになります。
[httpd]
WWW-Authenticate = Basic realm="administrator"
authentication_handlers = {couch_httpd_auth, webproxy_authentication_handler}
[couch_httpd_auth]
require_valid_user = true
require_authentication_db_entry = true
webproxy_use_secret = false
secret = 329435e5e66be809a656af105f42401e
Reverse Proxy側の設定 (Apache)
Debianでは/etc/apache2/sites-enabledディレクトリに置いた設定ファイルをhttpdが認識します。 まずは/etc/apache2/sites-enabledにファイルを作成します。
<VirtualHost couch.example.org:80>
ServerAdmin webmaster@example.org
DocumentRoot /var/www/
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
ErrorLog /var/log/apache2/error.log
LogLevel warn
CustomLog /var/log/apache2/access.log combined
<IfModule mod_alias.c>
Redirect permanent / https://couch.example.org/
</IfModule>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost couch.example.org:443>
ServerAdmin webmaster@example.org
DocumentRoot /var/www/
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
ErrorLog /var/log/apache2/error.log
LogLevel warn
CustomLog /var/log/apache2/ssl_access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-couch.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-key-couch.pem
BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
<Location />
AuthType Digest
AuthName "CouchDB"
AuthDigestDomain /
AuthDigestProvider file
AuthUserFile /etc/apache2/htdigest.db
Require valid-user
</Location>
<IfModule mod_proxy.c>
ProxyPass / http://127.0.0.1:5984/
ProxyPassReverse / http://127.0.0.1:5984/
</IfModule>
</VirtualHost>
</IfModule>
サーバ名やファイル名など、具体的には次の内容が適切か確認してください。
- VirtualHost couch.example.org:80
- Redirect permanent / https://couch.example.org/
- VirtualHost couch.example.org:443
- SSLCertificateFile /etc/ssl/certs/ssl-cert-couch.pem
- SSLCertificateKeyFile /etc/ssl/private/ssl-key-couch.pem
- AuthUserFile /etc/apache2/htdigest.db
ファイル名を指定して、a2ensiteコマンドで設定を有効にします。
$ sudo a2ensite couch $ sudo a2ensite couch-ssl $ sudo /etc/init.d/apache2 restart
CouchDB側の設定
設定自体は冒頭に説明しましたが、その内容について解説します。
require_authentication_db_entryについて
trueの場合、authenticate_db(default: '_users')にユーザ名(example: username)に対応する文書(example: /_users/org.couchdb.user:username)がない場合、認証に失敗します。
require_authentication_db_entryを"false"にすると対応する文書がなくてもアクセス可能となります。 その場合は文書があればroleが設定され、なければroleは空"[]"になります。
webproxy_use_secretについて
trueの場合、HTTP Request Headerに適切なX-Auth-CouchDB-Token行がない場合、認証に失敗します。
<IfModule mod_proxy.c>
<IfModule mod_headers.c>
RequestHeader add X-Auth-CouchDB-Token "c21ec459f6a650dcf6907f2b52e611a069a7aeee"
</IfModule>
ProxyPass / http://127.0.0.1:5984/
ProxyPassReverse / http://127.0.0.1:5984/
</IfModule>
X-Auth-CouchDB-Tokenに指定する値はSHA1のHMACで、計算方法は 以前に投稿したように、salt = 329435e5e66be809a656af105f42401e
として次の手順で行ないます。
$ erl -pa /usr/local/lib/couchdb/erlang/lib/couch-1.0.1/ebin 1> nl(couch_util). 2> nl(crypto). 3> crypto:start(). 4> Secret = <<"329435e5e66be809a656af105f42401e">>. 5> couch_util:to_hex(crypto:sha_mac(Secret,Secret)). "c21ec459f6a650dcf6907f2b52e611a069a7aeee"
webproxy_use_secretがデフォルトのままfalseの場合、ローカルユーザがdummyのAuthorization行を追加した場合に、認証に成功してしまいます。
$ curl -H 'Authorization: Digest username="admin"' http://localhost:5984/_session
セキュリティの観点から設定をお勧めしますが、設定が少し難しいので、デフォルトの値をfalseとしています。
CouchDBは使えるのが基本ですからね。
couchdbをリスタートして設定を反映させます。
$ sudo /etc/init.d/couchdb restart
稼働確認
SSLに自己認証CA局を使っている場合は、そのcacert.pemファイルを指定して他のホストから次のようなリクエストを投げてみます。
$ curl --digest --cacert cacert.pem -u admin:xxxxxx https://couch.example.org/_session
0 件のコメント:
コメントを投稿