3

I’m currently working on a docker-compose setup that can be used to deploy a cluster of CouchDB 2 nodes. I’ve finally got the nodes working and the data syncing across nodes, but unless I am mistaken, it appears that CouchDB does not sync user sessions.

My setup has 3 nodes and uses an haproxy setup almost identical to haproxy.cfg. As per my configuration, haproxy routes incoming traffic on port 5984 to port 5984 on all 3 nodes.

Assume an admin username of root and password of password.

I first log in with:

curl -vX POST http://localhost:5984/_session -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=root&password=password'

Note the returned AuthSession is used below as AUTHSESSION.

Then, I issue the following:

curl -X PUT http://localhost:5984/mydb --cookie AuthSession=AUTHSESSION -H "X-CouchDB-WWW-Authenticate: Cookie" -H "Content-Type: application/x-www-form-urlencoded"

This usually fails with “You are not a server admin.” I can continue to issue the same PUT and it will eventually succeed as I assume that haproxy eventually routes the request to the single node with which I am authenticated. As haproxy is using round robin there is a 1 in 3 chance that I will hit the target node.

I would think that CouchDB 2 could handle syncing user sessions across nodes. Am I making a silly assumption here?

(Please see run cluster via docker-compose to replicate my setup)

Update with specific solution for my docker-compose setup

As per @lossleader, you need to set the secret in the [couch_httpd_auth] section so that it is identical across nodes. Moreover, you need to set the same admin username and password in the [admins] section. The detail I missed here is that all nodes must have the exact same password hash in the .ini file. Having the same cleartext password is not enough, as otherwise, each node will generate its own salt and generate a different hash.

See run cluster via docker-compose for my complete setup.

4

2 回答 2

7

简短的回答:是的。

长答案:

正如其他人评论的那样,couchdb 不知道它创建的会话,所以确实没有同步会话本身的机制,但是在一个节点上创建会话 cookie 之前,您需要同步两个非会话的东西集群将在任何其他上有效。

[couch_httpd_auth] secret = foo

这是用于签署会话 cookie 的秘密值。如果在请求会话 cookie 时不存在,则将其设置为随机值。集群的每个节点自然会产生不同的值。

因此,在启动之前,请将此值设置为一个较大的随机值,但在集群的所有节点上都相同。

[admins] foo = -pbkdf2-2cbae77dc3d2dadb43ad477d312931c617e2a726,cd135ad4d6eb4d2f916cba75935c3ce7,10

本节包含每个管理员用户的加盐密码哈希。盐包含在会话 cookie 的签名中。更改密码时,盐会重新随机化,因此包含盐的效果是它会使密码更改之前的会话 cookie 无效。

您还需要此部分在所有节点上都相同。每个节点在对管理员密码进行哈希处理时都会生成一个随机盐。

作为节点配置自动化的一部分,最好在外部生成此部分。

我希望这能让你开始。我们希望在未来的版本中改善这种情况,它显然反映了 couchdb 的预集群版本。

于 2017-05-14T17:02:38.183 回答
4

CouchDB 会话令牌只是用户密码盐、服务器密码和时间的 HMAC 哈希。会话根本不存储在 CouchDB 中,即使在单节点系统上也是如此。所以没有什么可以同步的。

您可以并且很多人都可以完全以编程方式在 CouchDB 外部生成会话。

于 2017-05-14T07:39:02.973 回答