Not sure if the question should rather be on ServerFault?
I have a couchDB setup on my server using Apache credentials (but I can switch that off if it is an distraction).
I have local instances on various laptops. Now I want to setup secure (continuous) replication. From my understanding I could use username/password, SSL certificates or OAuth. I found bits and pieces of information:
- SSL Question on serverFault
- the WIKI entry on replication
- how to on replication in the wiki
- the gist on 1.2 replication
- the replication algorythm
All this documents added a hunch, but also confusion (I'm just a simple mind).
What I'm looking for is a step by step instruction:
- Pro and con for OAuth or SSL certificates (optional discussion)
- Steps to setup the SSL components Clarification: I'm not looking for SSL transport security - that's not really complicated and documented well for both Apache HTTP and CouchDB. What I'm looking for is authentication using certificates, similar to what you can do in SSH. The potential problem I see with OAuth: a admin has full access to the credentials (?). With a certificate approach (s)he can't impersonate the user since the private key is not under admin control.
- Steps to setup OAuth
- Sample replication documents for the each user uses a local replica with some documents and share one oneline
Where could I find that?
Secure transfer of user credentials is a very delicate question.
If we wouldn't look on third-party, in most cases, SSL is better way to start from since it has wide support by every tool you might used. SSL certificate, provides not only encryption (even self-signed ones), but insurance that user had requested right resource. Last option also worth to be highlighted if you're care about server security. The main drawback of SSL usage is performance degradation (vary on used algorithm) since server have to decrypt data and client need to validate certificate in additional to common communication routines. Also you have to pay some money for trusted certificate (not always true).
Using OAuth allows to not disclose real user credentials and easily maintain their access control from server side. Also, you need some library that handle OAuth 1.0 specification properly and if your platform miss such - you have to implement it by your own. In additional OAuth provides transfer data signing, so it aims to be safe for MiTM case. That's actually all that he does.
As you note, SSL and OAuth are about two different things: SSL helps to encrypt data on transport level (TLS) while OAuth take care about credentials disclosure in non secure environment. They are not replacement for each other, but each of them may stand as good additional to other.
To setup SSL support for CouchDB just follow the documentation guide. It's quite simple and easy to do. Note, that if there is some proxy server in front of CouchDB, it might be wise to setup SSL for him and proxy data to local CouchDB instance via regular HTTP protocol.
To setup OAuth there need to make next steps:
0. Ensure that {couch_httpd_oauth, oauth_authentication_handler}
handler is exists for authentication_handlers
option of [httpd]
section for default.ini
config file:
[httpd]
authentication_handlers = {couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
After that you need to edit your local.ini
file in next way:
- Setup consumer secret:
[oauth_consumer_secrets]
example.org = sekr1t
- Setup token secrets:
[oauth_token_secrets]
token1 = tokensekr1t
- Map tokens to existed CouchDB user:
[oauth_token_users]
token1 = joe
That's all! If you have CouchDB version 1.2 or higher, you may also define OAuth credentials within user document inside _users
database:
{
"_id": "org.couchdb.user:joe",
"type": "user",
"name": "joe",
"password_sha": "fe95df1ca59a9b567bdca5cbaf8412abd6e06121",
"salt": "4e170ffeb6f34daecfd814dfb4001a73"
"roles": ["foo", "bar"],
"oauth": {
"consumer_keys": {
"example.org": "sekr1t",
"consumerKey2": "key2Secret"
},
"tokens": {
"token1": "tokensekr1t",
"token2": "token2Secret"
}
}
}
Now, when we'd setup OAuth credentials for our user joe, let's start our replication. To let CouchDB use OAuth credentials, we need to extend source
or target
fields, depending on which side will authorize our user:
{
"source": "mailbox",
"target": {
"url": "https://secure.example.org/mailbox",
"auth": {
"oauth": {
"consumer_secret": "sekr1t",
"consumer_key": "example.org",
"token_secret": "tokensekr1t",
"token": "token1"
}
}
}
}
and POST
this data to _replicate
resource or create document for _replicator
database. Replication will start from local server to remote secure.example.org
using SSL protocol encryption and all operations will goes for remote user with login joe
.
Summarizing: combination of SSL and OAuth allows you not only protect transfered data (not only user credentials) and insure that target server was not faked, but also protects real user login name and password from accidental disclosure, control consumer sources (e.g. if example.org
will be compromised, we can only remove his consumer token, but not force user to change his password) and signing requests for additional protection against MiTM attacks.
UPDATE: For your case regular SSL certificate routines are ok: you will need to create personal certificates signed by your own and let clients to setup for further work with your CouchDB. The only thing required from CouchDB side is to validate certificates before process the connection. But note, that custom personal SSL certificate installation may be not trivial especially for mobile clients.
Speaking for OAuth side, CouchDB may use RSA-SHA1 auth method that uses some kind of personal certificate for secret. However, you need to patch sources first to unlock this method - it's disabled by default.