Friday, October 21, 2011

Hardening CouchDB: A more secure distributed database

Here are the steps to follow in order to harden CouchDB. I am currently using candidate release 1.1.1 and these are instructions for a local environment. For a production environment you have to locate the non dev config files local.ini and default.ini (Just run "ps -ef | grep couchdb" and look for the path, in my case /usr/local/etc/couchdb/local.ini and /usr/local/etc/couchdb/default.ini).

  1. Install a primary key and generated pem certificate:
    $ export DOMAIN=couchdb.nestorurquiza.com
    $ openssl genrsa -des3 -out ${DOMAIN}.pem 1024
    $ openssl req -new -key ${DOMAIN}.pem -out ${DOMAIN}.csr
    $ openssl x509 -req -days 3650 -in ${DOMAIN}.csr -signkey ${DOMAIN}.pem -out ${DOMAIN}.cert.pem
    $ openssl rsa -in ${DOMAIN}.pem -out ${DOMAIN}.pem
    $ sudo mkdir -p /opt/couchdb/certs/
    $ sudo cp ${DOMAIN}.pem /opt/couchdb/certs/
    $ sudo cp ${DOMAIN}.cert.pem /opt/couchdb/certs/
    

  2. Configure couchDB for *SSL only* and restart the server
    $ vi /Users/nestor/Downloads/couchdb1.1.x/etc/couchdb/local.ini
    [admins]
    ;admin = mysecretpassword
    nestorurquizaadmin = secret1
    ...
    [daemons]
    ; enable SSL support by uncommenting the following line and supply the PEM's below.
    ; the default ssl port CouchDB listens on is 6984
    httpsd = {couch_httpd, start_link, [https]}
    ...
    [ssl]
    cert_file = /opt/couchdb/certs/couchdb.nestorurquiza.com.cert.pem
    key_file = /opt/couchdb/certs/couchdb.nestorurquiza.com.pem
    $ vi /Users/nestor/Downloads/couchdb1.1.x/etc/couchdb/default.ini
    [httpd]
    bind_address = 0.0.0.0 #Use no loopback address only if the server will be exposed to a different machine
    ...
    [daemons]
    ...
    ; httpd={couch_httpd, start_link, []}
    ...
    
  3. Restart
    sudo couchdb #local OSX
    sudo /usr/local/etc/init.d/couchdb restart #Ubuntu
    

  4. Now we can access the secured CouchDB instance
    HOST="https://nestorurquizaadmin:mysecret@127.0.0.1:6984"
    curl -k -X GET $HOST
    

Note that at this time to remove the insecure http you have to use /usr/local/etc/couchdb/default.ini which gets overwritten after any upgrade.

Of course we should sign our certificate with a Certificate Authority (CA) to make this really secure but you can also add some security if you play with firewall rules and allow access to the SSL port to certain IP only. I can do so because I do use a middle tear between CouchDB and the browser. If you directly hitting CouchDB from the wild you better use a CA.

1 comment:

Michael said...

Nice post. Thanks man. Just a quick note for googlers:

If you try to access SSL port in your browser (even with a username and password in the URL line), it won't work, even though it works fine from curl and the client libraries. So, don't be surprised.

Also: If you change the admin password in your local.ini *after* you have already created some database in the past, the database will reject the new password.

FYI =)

Followers