Tuesday, November 10, 2009

How to install CouchDB + nginx + basic authentication on EC2, including a Ruby client

Please note that if want to more secure installation, SSL should also be installed following these instructions (I used these instructions and another web blog to create the following abbreviated instructions). For my purposes, basic HTTP authentication is good enough. I assume that you are used to using nginx and CouchDB and either installed them from source or using apt-get. I am using Ubuntu, so you might have to modify these instructions slightly. On my laptop, I created a simple crypt program because OS X does not include one:
#!/usr/bin/perl
print crypt($ARGV[0],$ARGV[0])."\n";
After giving this script execute permissions, I created an encrypted password:
crypt my12398pass61
You should save the output because on your EC2 instance you need to, as root or sudo, edit the file /etc/nginx/htpasswd adding a line:
couchclient:myEKNgP2ivVVo
where myEKNgP2ivVVo was the output from crypt for the plain text password my12398pass61. Then edit nginx.conf file adding something like:
    server {
listen 9001;
server_name example123.com; # not a real domain name
location / {
auth_basic "Please login to use CouchDB";
auth_basic_user_file /etc/nginx/htpasswd;
proxy_pass http://localhost:5984;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If you restart nginx, then you should be able to access
http://example123.com:9001/_utils
You will have to enter couchclient as the user name and my12398pass61 as the password. I allowed my browser to set an authentication cookie so I would not have to keep logging in. (Obviously, you should use a different user name and password with crypt and setting up your /etc/nginx/htpasswd file.)

For a ruby client, do a "gem install couchrest" and try this:
require 'rubygems'
require 'couchrest'

db = CouchRest.database!("http://couchclient:my12398pass61@example123.com:9001/testdb")
response = db.save_doc({:key => 'value', 'another key' => 'another value'})
doc = db.get(response['id'])
puts doc.inspect
You should be good to go writing Ruby applications that use your remote CouchDB service.

This installation is not very secure and should probably not be used on a production server containing sensitive data. I am not a security expert; if you are then I would appreciate your comments on this blog entry.

- - -

PS. an hour after writing this blog, I found a simpler solution of using a SSH tunnel. Check this out on the Disco Blog. You set a tunnel like:
ssh -i ~/.ssh/id_rsa-gsg-keypair  -L 5984:localhost:5984 root@ec2-31-111-149-100.compute-1.amazonaws.com
If you use an Elastic IP address so your server always has the same IP address, then this ssh command can be aliased, for fast temporary connections to CouchDB and other services that are confgured for only localhost client connections.

No comments: