A reverse proxy server as a front-end of couchdb seems to be useful for authentication and SSL because there are many examples, such as Apache_As_a_Reverse_Proxy.
According to the couchdb reference, however, it suggests to use the null_authentication_handler and the user=%{LA-U:REMOTE_USER} rewrite rule, it means that an local user will get the admin privilege.
A new authentication handler was developed working with an authentication_db to solve this issue.
If the reverse proxy server and couchdb are placed at different servers, this kind of handler might be useful.
The following patch is for the couchdb-1.0.1, but just added new codes. I think that it should work with another version.
- 20101127.1.couchdb101.webproxy.diff(sha1sum: b53b6621d84f5ca63570060da7eac7c9d82eee7f)
- 20101127.1.couchdb101.webproxy.diff.gz(sha1sum: 7bfbd1a03bc36b53c30fa16a8fab1dc1984f521f)
This authentication handler was tested on alix with debian lenny. Some stuffs, especially erlang-R14B and couchdb-1.0.1, were manually compiled.
Setup Procedures
The diff file, 20101127.1.couchdb101.webproxy.diff, are placed at ~/, then move to the couchdb directory and apply it.
$ 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/
To use this handler, please modify the local.ini file as following;
[httpd]
authentication_handlers = {couch_httpd_auth, webproxy_authentication_handler}
This handler will take two options;
- require_authentication_db_entry (default: true) - if it's true and the authenticated user name is not on the authentication_db, then the authorization at couchdb will be failed.
- webproxy_use_secret (default:false) - if it's true and there is no proper X-Auth-CouchDB-Token header, then the access will be denied.
The authentication_db entry is just used to get the user's role. It means just user, type and roles entries are reqruied to each document.
To enable the authentication, you need more configurations usually. Following is an typical example of the local.ini file.
[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
Set up Apache as A Reverse Proxy
These configurations are just an example. Please modify for your environment.
To setup apache on debian lenny, we need to create setup files on /etc/apache2/sites-enabled directory.
<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>
To use above settings, please change that following values and files for your environment.
- 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
To enable changes, create symbolic-links and restart apache.
$ sudo a2ensite couch $ sudo a2ensite couch-ssl $ sudo /etc/init.d/apache2 restart
Set up CouchDB
Possible parameters and settings are explained at the top of this document. This section explains much more details.
require_authentication_db_entry
If it's true, the authenticated username should be described on the authentication_db, such as /_users/org.couchdb.user:username.
If it's the default value, false, the authenticated user can access to the couchdb without an authentication_db entry. In this case, the role of the user set to empty, []. To enable the role, user's authentication_db entry is essential.
webproxy_use_secret
If it's true and there is no X-Auth-CouchDB-Token line at the http request header, then the authorization will be failed.
To add the X-Auth-CouchDB-Token to the request header, the following settings are required.
<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>
The value of X-Auth-CouchDB-Token can be calculated by SHA1 HMAC as following;
$ 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"
The value of 'Secret' is the value of the secret key on the .ini file.
Security considerations
The default value of the webproxy_use_secret is false.
In this case, if an user connects to couchdb's port directly, such as curl http://127.0.0.1:5984/, with a dummy header, like 'Authorization: Digest username="admin"', then the user will get the admin user's priviledge.
$ curl -H 'Authorization: Digest username="admin"' http://localhost:5984/_session
Please consider the webproxy_use_secret to be enable, but it's a little bit difficult, I guess. So that the default value is false to relax.
Example of a curl command line
If the ssl cert file was confirmed by the self-signed CA, then the cacert.pem file should be append to the curl command line.
$ curl --digest --cacert cacert.pem -u admin:xxxxxx https://couch.example.org/_session
Enjoy!
0 件のコメント:
コメントを投稿