I'm looking to use CouchDB with SSL and nodejs and I have just switched from self signed certificates (which were working for over a month) to a real SSL certificate and now I'm running into configuration issues. I've scattered a few questions along the way as there are quite a few pieces, but the main issue is that node and couch no longer talk.
I have nodejs running and I'm using the node-spdy extension (https://www.npmjs.org/package/spdy)
I have SSL certificates configured:
var options = {
key: fs.readFileSync(__dirname + '/keys/spdy-key.pem'),
cert: fs.readFileSync(__dirname + '/keys/spdy-cert.pem'),
ca: fs.readFileSync(__dirname + '/keys/spdy-ca.pem'),
};
First question: I now have an intermediate certificate, how do I tell nodejs this?Previously my cert was self-signed so I put the csr file in the ca spot (above) and that was working. Actually, trying it today, both the csr file and the intermediate certificate seem to work in that spot, but that can't be right, hence my question. So if it's the csr, then how do I properly configure the intermediate certificate? I've seen this thread: https://stackoverflow.com/questions/19104215/node-js-express-js-chain-certificate-not-working
Next, couchdb was working with SSL when I had self-signed cert. In order to get node and couch to play nice over SSL I had to set this flag in node:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
This stopped node from quitting on error of "self-signed" certificate. Now I want to remove that flag. (Originally I got that tip from here: https://github.com/mikeal/request/issues/418)
Now to to the main issue. In CouchDB, my local.ini has:
[httpd]
;port = 5984
;bind_address = 127.0.0.1
; Options for the MochiWeb HTTP server.
;server_options = [{backlog, 128}, {acceptor_pool_size, 16}]
; For more socket options, consult Erlang's module 'inet' man page.
;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}]
; Uncomment next line to trigger basic-auth popup on unauthorized requests.
WWW-Authenticate = Basic realm="administrator"
; Uncomment next line to set the configuration modification whitelist. Only
; whitelisted values may be changed via the /_config URLs. To allow the admin
; to change this value over HTTP, remember to include {httpd,config_whitelist}
; itself. Excluding it from the list would require editing this file to update
; the whitelist.
;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}]
[httpd_global_handlers]
;_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>}
[couch_httpd_auth]
; If you set this to true, you should also uncomment the WWW-Authenticate line
; above. If you don't configure a WWW-Authenticate header, CouchDB will send
; Basic realm="server" in order to prevent you getting logged out.
require_valid_user = true
[log]
;level = debug
[log_level_by_module]
; In this section you can specify any of the four log levels 'none', 'info',
; 'error' or 'debug' on a per-module basis. See src/*/*.erl for various
; modules.
;couch_httpd = error
[os_daemons]
; For any commands listed here, CouchDB will attempt to ensure that
; the process remains alive. Daemons should monitor their environment
; to know when to exit. This can most easily be accomplished by exiting
; when stdin is closed.
;foo = /path/to/command -with args
[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 = /srv/www/[appname]/keys/cert.pem
key_file = /srv/www/[appname]/keys/key.pem
;password = somepassword
; set to true to validate peer certificates
;verify_ssl_certificates = true
; Path to file containing PEM encoded CA certificates (trusted
; certificates used for verifying a peer certificate). May be omitted if
; you do not want to verify the peer.
; cacert_file = /srv/www/[appname]/keys/ca.pem
; The verification fun (optional) if not specified, the default
; verification fun will be used.
;verify_fun = {Module, VerifyFun}
; maximum peer certificate depth
ssl_certificate_max_depth = 1
Is this setup right? I followed (http://guide.couchdb.org/draft/security.html) and (http://wiki.apache.org/couchdb/How_to_enable_SSL)
However, when I connect, I get this in the node logs:
error { [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' }
This is usually an error when the other side of the connection ends early on nodejs. So couchDB is exiting. And when I run curl -k -v https://127.0.0.1:6984/
to check out what's up, I get:
* About to connect() to 127.0.0.1 port 6984 (#0)
* Trying 127.0.0.1...
* Adding handle: conn: 0x181eab0
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x181eab0) send_pipe: 1, recv_pipe: 0
* Connected to 127.0.0.1 (127.0.0.1) port 6984 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to 127.0.0.1:6984
* Closing connection 0
curl: (35) Unknown SSL protocol error in connection to 127.0.0.1:6984
This all happened after the new SSL files. I've heard that CouchDB doesn't like some of SSL configs? (See here: https://leap.se/code/issues/883#note-10)
Seems like a strange error to output if it's just permissions, but you can never be too sure. So, for the pem files - I have the permissions set to 700 on the /keys folder and 600 on the pem files. The user is a deploy user and couch runs on the couch user. So couch can't actually access these, correct? Is that the issue? If it is the solution, is the best course of action to add couchdb user to the deploy group? Is that the fix? I always like to make double sure when dealing with permissions.
Separately from that, no matter how I try, I can't seem to get couch to verify the SSL cert, so I've left that config as off. Is that a problem? I've heard that couch requires the certs to have a password for this setting to work. Is that true? (http://thinkinginsoftware.blogspot.ca/2012/12/couchdb-unknown-ssl-protocol-error-in.html) Do I even need this config to be on?
Lastly and separately, in couch.uri file it has both the http and https URLs. So it's starting up 2 instances. Can I safely remove the http URL from starting up now that I'm using SSL or does it need both?
Paul