How to get Riak 2.0 security working with riak-python-client?
Question: Riak 2.0 is installed on Ubuntu 14.04 with default settings

Riak python client is taken from dev branch: <https://github.com/basho/riak-
python-client/tree/feature/bch/security>

**Steps I made:**

1.Enable security:

    
    
    > riak-admin security enable
    

2.Check status:

    
    
    > riak-admin security status
    > Enabled
    

3.Add example user, group and apply some basic permissions

4.Overall it looks like following:

**user:**

    
    
    riak-admin security print-users
    
    +----------+---------------+----------------------------------------+------------------------------+
    | username |   member of   |                password                |           options            |
    +----------+---------------+----------------------------------------+------------------------------+
    | user_sec |   group_sec   |ce055fe0a2d621a650c293a56996ee504054ea1d|              []              |
    +----------+---------------+----------------------------------------+------------------------------+
    

**user's grants:**

    
    
    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               |
    +----------+----------+----------------------------------------+
    

**auth sources:**

    
    
    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   |    []    |
    +--------------------+------------+----------+----------+
    

**simple python script I'm trying to run (on the same host where Riak is
running):**

    
    
    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
    

stack trace I'm getting: 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'
    

When security is disabled the same script works perfectly fine:

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

I also tried to generate example certificates using this tool:
<https://github.com/basho-labs/riak-ruby-ca> and set them in 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
    

and use ca.crt in python script:

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

It didn't change anything. I'm still getting the same exception. I guess this
problem might be trivial, but I don't have any clue for now.

**Update:**

I was using wrong param name. Few commits ago it was: **security_creds** , now
it's called: **credentials**. When I fixed this in my script, SSL handshake
was initialized. Then next exceptions were caused by wrong SecurityCreds
initialization. Constructor is using named params, so it should be:

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

handshake is initialized, but it's failing on this command:

    
    
    ssl_socket.do_handshake()
    

from riak/transport/pbc/connection.py (line 134)

I'm getting these 2 errors (randomly):

    
    
        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')
    

I'm also observing errors in Riak's logs (/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
    

This situation happens with both approaches: cacert (ca.crt) and client cert
(client.crt)/key (client.key). I tried various combinations of keys:

  * keys from tests/resource

  * keys generated with riak-ruby-ca script

  * keys generated with `make` in tests/resource

  * keys generated with helper script from pyOpenSSL

  * ...none of them work for me

I'm using **riak_2.0.0beta1-1_amd64.deb**


Answer: Thanks for the enthusiastic testing! The branch you pulled is an unreviewed
work in progress and I've added some updates today.

I would try again with both the very latest 2.0.0 beta and the changes made to
this branch. There are some test certs in `riak/tests/resources` which would
be useful to get started testing your configuration.

You'll need to name your **cacert** parameter, now, too since several other
options have been added.

The basic setup looks pretty good. Try the latest and let me know how it works
for you.

