Riak2.0セキュリティ機能の強化内容について調査しました

みんなでやるRiak Advent Calendar 2013 クリスマスイブのネタとして投稿します。

次期バージョンのRiak(Riak2.x)では、CRDT、Strong Consistency、Yokozuna Searchなど、様々な機能強化が予定されています。今回の投稿では、Riak2.0で拡張が予定されているセキュリティ機能についてまとめます。

情報源

出来ること

  • Authentication
    • IPv4ソースアドレス(CIDR)による認証
    • Password認証
    • PAM認証
    • LDAP認証
      • PAM認証が出来ればLDAP認証は出来るので、無くても何とかなる
  • Authorization
    • ユーザ単位でput,getをどのbucketで許可するかを設定できる

分かったこと

  • まだ色々と実装が完了していない
    • riak-admin security delete-source が無いなど

使い方の例

securityの設定方法は、riak-adminコマンドのsecond level command に "security"が増えたので、こちらを用いることで設定できます。

  • ユーザ名'testuser'を追加し、全ユーザからの127.0.0.1/32 からのアクセスを許可する
$ dev/dev1/bin/riak-admin security add-user testuser
$ dev/dev1/bin/riak-admin security add-source all 127.0.0.1/32 trust
  • ユーザ名'sean'を追加し、パスワード'justopenasocket'でのアクセスを許可する
$ dev/dev1/bin/riak-admin security add-user sean password=justopenasocket
$ dev/dev1/bin/riak-admin security add-source sean 0.0.0.0/0 password
  • PAM認証を許可する
$ dev/dev1/bin/riak-admin security add-source all 192.168.1.0/24 trust
$ dev/dev1/bin/riak-admin security add-source all 0.0.0.0/0 pam service=riak
  • Usage of security second level command
sogabe@sherco:~/src-github/riak$ dev/dev1/bin/riak-admin security
Usage: riak-admin security <command>

The following commands modify users and security ACLs for Riak:

    add-user <username> [options]
    add-source all|<users> <CIDR> <source> [options]
    grant <permissions> ON ANY|<type> [bucket] TO <users>
    revoke <permissions> ON ANY|<type> [bucket] FROM <users>
    print-users
    print-sources
    print-user <user>
  • ユーザ'testuser'に バケット名'mybucket'に対して get のアクセス権を与える
$ dev/dev1/bin/riak-admin security grant riak_kv.get ON mybucket TO testuser
  • ユーザ'sean'にバケット名'mybucket'に対して get,put のアクセス権を与える
$ dev/dev1/bin/riak-admin security grant riak_kv.get,riak_kv.put ON mybucket TO sean
$ dev/dev1/bin/riak-admin security grant riak_kv.put ON myapp_* to testuser
(現時点では未だ動作せず)
  • security 設定情報の一覧を表示する(print)
sogabe@sherco:~/src-github/riak$ dev/dev1/bin/riak-admin security print-users
+--------------------+--------------------+----------------------------------------+------------------------------+
|      username      |       roles        |                password                |           options            |
+--------------------+--------------------+----------------------------------------+------------------------------+
|        sean        |                    |c57e004ee67d6260863b1050e58d93405f5900fd|              []              |
|      testuser      |                    |                                        |              []              |
+--------------------+--------------------+----------------------------------------+------------------------------+
sogabe@sherco:~/src-github/riak$ dev/dev1/bin/riak-admin security print-sources
+--------------------+--------------+----------+--------------------+
|       users        |     cidr     |  source  |      options       |
+--------------------+--------------+----------+--------------------+
|        all         | 127.0.0.1/32 |  trust   |         []         |
|        all         |192.168.1.0/24|  trust   |         []         |
|        sean        |  0.0.0.0/0   | password |         []         |
|        all         |  0.0.0.0/0   |   pam    |[{"service","riak"}]|
+--------------------+--------------+----------+--------------------+
  • security ユーザ毎の設定情報を表示する(print-user)
sogabe@sherco:~/src-github/riak$ dev/dev1/bin/riak-admin security print-user testuser

Inherited permissions

+--------------------+----------+----------+----------------------------------------+
|        role        |   type   |  bucket  |                 grants                 |
+--------------------+----------+----------+----------------------------------------+

Applied permissions

+----------+----------+----------------------------------------+
|   type   |  bucket  |                 grants                 |
+----------+----------+----------------------------------------+
| mybucket |    *     |              riak_kv.get               |
+----------+----------+----------------------------------------+
sogabe@sherco:~/src-github/riak$ dev/dev1/bin/riak-admin security print-user sean

Inherited permissions

+--------------------+----------+----------+----------------------------------------+
|        role        |   type   |  bucket  |                 grants                 |
+--------------------+----------+----------+----------------------------------------+

Applied permissions

+----------+----------+----------------------------------------+
|   type   |  bucket  |                 grants                 |
+----------+----------+----------------------------------------+
| mybucket |    *     |        riak_kv.put, riak_kv.get        |
+----------+----------+----------------------------------------+

試してみる

2013年12月現在、riak2.0は開発中なので github の developブランチを用いてテストをします。

riakのソースコードをダウンロードし、ビルドする
$ git clone https://github.com/basho/riak
$ cd riak
$ make stagedevrel
riak securityの設定

2013年12月現在、developブランチでは security機能を有効にするためのコードが入っていないので、手動でコードを修正してテストをします。
下記の例では、riak.conf に "security = on"と記述することでsecurity機能を有効にできるようになります。
尚、riak2.0からはコンフィグファイルが Erlang由来のものではなく cuttlefish と呼ばれるパーサを使うことになったので、下記のように cuttlefish 用の schemaファイルに必要な設定を追加します。

$ vi deps/riak_core/priv/riak_core.schema
(下記を追加)
%%
%% XXX security
%%
{mapping, "security", "riak_core.security", [
  {default, off},
  {datatype, {enum, [on, off]}}
]}.
{ translation,
  "riak_core.security",
  fun(Conf) ->
    Setting = cuttlefish:conf_get("security", Conf),
    case Setting of
      on -> true;
      off -> false;
      _Default -> false
    end
  end
}.

$ make stagedevrel
 (ビルドする)

$ vi dev/dev1/etc/riak.conf
...
(SSLの cert, key を設定する)
## Default cert location for https can be overridden
## with the ssl config variable, for example:
ssl.certfile = ./etc/cert.pem

## Default key location for https can be overridden
## with the ssl config variable, for example:
ssl.keyfile = ./etc/key.pem

...
(https を有効にして、代わりにhttpを無効にする)
listener.https.internal = 127.0.0.1:10018
...
#listener.http.internal = 127.0.0.1:10018

...
(セキュリティ機能を有効にする)
security = on

$ ulimit -n 4096
$ dev/dev1/bin/riak start
curlを用いた Authentication / Authorizationのテスト
$ curl -k -i https://localhost:10018/riak/test/doc
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Riak"
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:08:15 GMT
Content-Type: text/html
Content-Length: 159

<html><head><title>401 Unauthorized</title></head><body><h1>Unauthorized</h1>Unauthorized<p><hr><address>mochiweb+webmachine web server</address></body></html>

$ curl -k -i --user andrew:foo https://localhost:10018/riak/test/doc
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Riak"
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:08:15 GMT
Content-Type: text/html
Content-Length: 159

<html><head><title>401 Unauthorized</title></head><body><h1>Unauthorized</h1>Unauthorized<p><hr><address>mochiweb+webmachine web server</address></body></html>

$ dev/dev1/bin/riak-admin security add-user andrew
$ curl -k -i --user andrew:foo https://localhost:10018/riak/test/doc
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Riak"
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:09:51 GMT
Content-Type: text/html
Content-Length: 159

<html><head><title>401 Unauthorized</title></head><body><h1>Unauthorized</h1>Unauthorized<p><hr><address>mochiweb+webmachine web server</address></body></html>

$ dev/dev1/bin/riak-admin security add-source andrew 127.0.0.1/32 trust
$ curl -k -i --user andrew:foo https://localhost:10018/riak/test/doc
HTTP/1.1 403 Forbidden
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:11:03 GMT
Content-Type: text/plain
Content-Length: 154

Permission denied: User 'andrew' does not have'riak_kv.get' on {<<"default">>,
                                                                <<"test">>}
$ dev/dev1/bin/riak-admin security grant riak_kv.get ON default test TO andrew
$ curl -k -i --user andrew:foo https://localhost:10018/riak/test/doc
HTTP/1.1 404 Object Not Found
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:12:17 GMT
Content-Type: text/plain
Content-Length: 10

not found

$ curl -k -i --user andrew:foo https://localhost:10018/riak/test2/doc
HTTP/1.1 403 Forbidden
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:13:04 GMT
Content-Type: text/plain
Content-Length: 155

Permission denied: User 'andrew' does not have'riak_kv.get' on {<<"default">>,
                                                                <<"test2">>}

$ curl -k -i --user andrew:foo https://localhost:10018/riak/test/doc -d "hello world"
HTTP/1.1 403 Forbidden
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:13:54 GMT
Content-Type: text/plain
Content-Length: 154

Permission denied: User 'andrew' does not have'riak_kv.put' on {<<"default">>,
                                                                <<"test">>}

$ dev/dev1/bin/riak-admin security grant riak_kv.put ON default test TO andrew
$ curl -k -i --user andrew:foo https://localhost:10018/riak/test/doc -d "hello world"
HTTP/1.1 204 No Content
Vary: Accept-Encoding
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:14:56 GMT
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

$ curl -k -i --user andrew:foo https://localhost:10018/riak/test2/doc -d "hello world"
HTTP/1.1 403 Forbidden
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:15:49 GMT
Content-Type: text/plain
Content-Length: 155

Permission denied: User 'andrew' does not have'riak_kv.put' on {<<"default">>,
                                                                <<"test2">>}
$ curl -k -i --user andrew:foo https://localhost:10018/riak/test/doc
HTTP/1.1 200 OK
X-Riak-Vclock: a85hYGBgzGDKBVIcR4M2cgetf/4qgymRMY+V4UOpyhm+LAA=
Vary: Accept-Encoding
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Link: </riak/test>; rel="up"
Last-Modified: Tue, 17 Dec 2013 07:14:56 GMT
ETag: "59NlprW7hUCSUVKznH6VKM"
Date: Tue, 17 Dec 2013 07:16:29 GMT
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

hello world

$ dev/dev1/bin/riak-admin security revoke riak_kv.get,riak_kv.put ON default test FROM andrew
$ curl -k -i --user andrew:foo https://localhost:10018/riak/test/doc
HTTP/1.1 403 Forbidden
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:19:20 GMT
Content-Type: text/plain
Content-Length: 154

Permission denied: User 'andrew' does not have'riak_kv.get' on {<<"default">>,
                                                                <<"test">>}

$ curl -k -i --user andrew:foo -XPUT https://localhost:10018/riak/test/doc -d "hello world"
HTTP/1.1 403 Forbidden
Server: MochiWeb/1.1 WebMachine/1.10.5 (jokes are better explained)
Date: Tue, 17 Dec 2013 07:18:52 GMT
Content-Type: text/plain
Content-Length: 154

Permission denied: User 'andrew' does not have'riak_kv.put' on {<<"default">>,
                                                                <<"test">>}