如何让Riak 2.0安全功能与riak-python-client一起工作?

1 投票
2 回答
843 浏览
提问于 2025-04-18 08:03

Riak 2.0 安装在 Ubuntu 14.04 上,使用的是默认设置。

Riak 的 Python 客户端来自开发分支:https://github.com/basho/riak-python-client/tree/feature/bch/security

我做的步骤:

1. 启用安全性:

> riak-admin security enable

2. 检查状态:

> riak-admin security status
> Enabled

3. 添加示例用户、组,并应用一些基本权限。

4. 整体看起来如下:

用户:

riak-admin security print-users

+----------+---------------+----------------------------------------+------------------------------+
| username |   member of   |                password                |           options            |
+----------+---------------+----------------------------------------+------------------------------+
| user_sec |   group_sec   |ce055fe0a2d621a650c293a56996ee504054ea1d|              []              |
+----------+---------------+----------------------------------------+------------------------------+

用户的权限:

riak-admin security print-grants user_sec
Inherited permissions (user/user_sec)

+--------------------+----------+----------+----------------------------------------+
|       group        |   type   |  bucket  |                 grants                 |
+--------------------+----------+----------+----------------------------------------+
|     group_sec      | default  |    *     |              riak_kv.get               |
|     group_sec      |bucket_sec|    *     |              riak_kv.get               |
+--------------------+----------+----------+----------------------------------------+

Cumulative permissions (user/user_sec)

+----------+----------+----------------------------------------+
|   type   |  bucket  |                 grants                 |
+----------+----------+----------------------------------------+
| default  |    *     |              riak_kv.get               |
|bucket_sec|    *     |              riak_kv.get               |
+----------+----------+----------------------------------------+

认证来源:

riak-admin security print-sources

+--------------------+------------+----------+----------+
|       users        |    cidr    |  source  | options  |
+--------------------+------------+----------+----------+
|      user_sec      | 0.0.0.0/32 | password |    []    |
|      user_sec      |127.0.0.1/32|  trust   |    []    |
+--------------------+------------+----------+----------+

我尝试运行的简单 Python 脚本(在 Riak 运行的同一主机上):

import riak
from riak.security import SecurityCreds
pbc_port = 8002
riak_host = "127.0.0.1"
creds = riak.security.SecurityCreds('user_sec', 'secure_password')
riak_client = riak.RiakClient(pb_port=pbc_port, host=riak_host, protocol='pbc', security_creds=creds)
bucket = riak_client.bucket('test')
data = bucket.get("42")
print data.data

我遇到的堆栈跟踪: python riak_test.py

Traceback (most recent call last):
  File "riak_test.py", line 8, in <module>
    data = bucket.get("42")
  File "/usr/local/lib/python2.7/dist-packages/riak/bucket.py", line 214, in get
    return obj.reload(r=r, pr=pr, timeout=timeout)
  File "/usr/local/lib/python2.7/dist-packages/riak/riak_object.py", line 307, in reload
    self.client.get(self, r=r, pr=pr, timeout=timeout)
  File "/usr/local/lib/python2.7/dist-packages/riak/client/transport.py", line 184, in wrapper
    return self._with_retries(pool, thunk)
  File "/usr/local/lib/python2.7/dist-packages/riak/client/transport.py", line 126, in _with_retries
    return fn(transport)
  File "/usr/local/lib/python2.7/dist-packages/riak/client/transport.py", line 182, in thunk
    return fn(self, transport, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/riak/client/operations.py", line 382, in get
    return transport.get(robj, r=r, pr=pr, timeout=timeout)
  File "/usr/local/lib/python2.7/dist-packages/riak/transports/pbc/transport.py", line 148, in get
    if self.quorum_controls() and pr:
  File "/usr/local/lib/python2.7/dist-packages/riak/transports/feature_detect.py", line 102, in quorum_controls
    return self.server_version >= versions[1]
  File "/usr/local/lib/python2.7/dist-packages/riak/util.py", line 148, in __get__
    value = self.fget(obj)
  File "/usr/local/lib/python2.7/dist-packages/riak/transports/feature_detect.py", line 189, in server_version
    return LooseVersion(self._server_version())
  File "/usr/local/lib/python2.7/dist-packages/riak/transports/pbc/transport.py", line 101, in _server_version
    return self.get_server_info()['server_version']
  File "/usr/local/lib/python2.7/dist-packages/riak/transports/pbc/transport.py", line 119, in get_server_info
    expect=MSG_CODE_GET_SERVER_INFO_RESP)
  File "/usr/local/lib/python2.7/dist-packages/riak/transports/pbc/connection.py", line 51, in _request
    return self._recv_msg(expect)
  File "/usr/local/lib/python2.7/dist-packages/riak/transports/pbc/connection.py", line 137, in _recv_msg
    raise RiakError(err.errmsg)
riak.RiakError: 'Security is enabled, please STARTTLS first'

当安全性被禁用时,同样的脚本运行得很好:

python riak_test.py
{u'question': u"what's the sense of universe?"}

我还尝试使用这个工具生成示例证书:https://github.com/basho-labs/riak-ruby-ca,并在 riak.conf 中设置它们:

grep ssl /etc/riak/riak.conf
## with the ssl config variable, for example:
ssl.certfile = $(platform_etc_dir)/server.crt
## Default key location for https can be overridden with the ssl
ssl.keyfile = $(platform_etc_dir)/server.key
## with the ssl config variable, for example:
ssl.cacertfile = $(platform_etc_dir)/ca.crt

并在 Python 脚本中使用 ca.crt:

creds = riak.security.SecurityCreds('user_sec', 'secure_password', 'ca.crt')

这没有改变任何东西。我仍然遇到相同的异常。我想这个问题可能很简单,但现在我没有任何头绪。

更新:

我使用了错误的参数名称。几次提交之前,它叫做:security_creds,现在叫做:credentials。 当我在脚本中修正这个问题后,SSL 握手被初始化了。接下来出现的异常是由于 SecurityCreds 初始化错误。构造函数使用命名参数,所以应该是:

creds = riak.security.SecurityCreds(username='user_sec', password='secure_password', cacert_file='ca.crt')

握手已初始化,但在这个命令上失败:

ssl_socket.do_handshake()

来自 riak/transport/pbc/connection.py(第 134 行)

我随机遇到这两个错误:

    File "/home/gta/riak-python-client/riak/transports/pbc/connection.py", line 77, in _init_security
    self._ssl_handshake()
  File "/home/gta/riak-python-client/riak/transports/pbc/connection.py", line 145, in _ssl_handshake
    raise e
OpenSSL.SSL.SysCallError: (104, 'ECONNRESET')


    File "/home/gta/riak-python-client/riak/transports/pbc/connection.py", line 77, in _init_security
    self._ssl_handshake()
  File "/home/gta/riak-python-client/riak/transports/pbc/connection.py", line 145, in _ssl_handshake
    raise e
OpenSSL.SSL.SysCallError: (-1, 'Unexpected EOF')

我还在 Riak 的日志中观察到错误(/var/log/riak/error.log):

2014-06-02 15:09:33.954 [error] <0.1995.1> gen_fsm <0.1995.1> in state wait_for_tls terminated with reason: {error,{startls_failed,{certfile,badarg}}}
2014-06-02 15:09:33.955 [error] <0.1995.1> CRASH REPORT Process <0.1995.1> with 0 neighbours exited with reason: {error,{startls_failed,{certfile,badarg}}} in gen_fsm:terminate/7 line 622
2014-06-02 15:09:33.955 [error] <0.28750.0> Supervisor riak_api_pb_sup had child undefined started with {riak_api_pb_server,start_link,undefined} at <0.1995.1> exit with reason {error,{startls_failed,{certfile,badarg}}} in context child_terminated

这种情况在两种方法中都会发生:cacert(ca.crt)和客户端证书(client.crt)/密钥(client.key)。我尝试了各种密钥组合:

  • 来自 tests/resource 的密钥

  • 使用 riak-ruby-ca 脚本生成的密钥

  • 在 tests/resource 中使用 make 生成的密钥

  • 使用 pyOpenSSL 的辅助脚本生成的密钥

  • ...这些都对我不起作用

我使用的是 riak_2.0.0beta1-1_amd64.deb

2 个回答

1

感谢你热情的测试!你拉取的这个分支是一个还没有经过审核的正在进行中的工作,我今天也做了一些更新。

我建议你再试试最新的2.0.0测试版和这个分支上做的更改。在riak/tests/resources里有一些测试证书,可以帮助你开始测试你的配置。

现在你需要给你的cacert参数命名,因为添加了几个其他选项。

基本设置看起来不错。试试最新的版本,告诉我效果如何。

1

我终于搞定了。以下是我需要做的事情:

  1. 把Erlang升级到16版本(我从源代码编译的)
  2. 下载最新的Riak源代码
  3. 从源代码编译Riak
  4. 再仔细读一遍这个段落:http://docs.basho.com/riak/2.0.0beta1/ops/running/security-sources/#Certificate-based-Authentication
  5. 设置用户(记住:如果你想用Brett的证书来测试,那么你可能需要添加一个叫'certuser'的用户)
  6. 在riak.config中设置证书(我用的是Brett在/tests/resources中的示例证书)

看起来在Beta1版本中,安全功能并没有完全支持。

撰写回答