HashiCorp Vault + LDAP で MySQL のアカウント管理
ようやくはてなブログに移りました。 ということでその最初の記事を書く。
LinuxのアカウントはLDAP(やらIPA Server)とか使えば統合管理できるのだけど、MySQLのアカウント管理を一箇所で統合的に管理しようと思うと、その権限なども含めるとなんかよいソリューションがないように思える。 イヤ、こういうのあるよってあれば教えてください。
そこで、HashiCorpのVaultとLDAPを組み合わせると、ちょっとそれらしくMySQLのアカウント管理できるのではないかと思ってそれを試してみた。
Vault 起動
今回は、おおよそこういうことができる、ということを確認することが目的なので、Vault自体の可用性とかまで考えない。
dev モードで起動する。
$ vault server -dev
表示される root Token を使って、root として Vault にログインする。以下のような感じ。
$ vault auth 4a1eea82-facd-c7d3-e9c7-c0bb4b04e81f
MySQL Secret Backend の設定
Vaultには機密情報(Secret)を保持したり生成したりするコンポーネントである Secret Backends というのがあり、そのうちの1つに MySQL のアカウントを生成しその権限も設定してくれる MySQL Secret Backend というのがある。
今回の目的のためにこの MySQL Secret Backend を利用する。
複数のデータベースを想定して(ここでは1つしか設定しないが)、db1 というパスにマウントする。
$ vault mount -path=db1 mysql Successfully mounted 'mysql' at 'db1'!
db1に対応するデータベースへの接続情報を登録する。GRANT OPTION権限をもつユーザを登録する必要がある。
$ vault write db1/config/connection value="admin:adminpass@tcp(db1.example.com:3306)/" Success! Data written to: db1/config/connection
このMySQL Secret Backedが払い出してくれるアカウントとパスワードの有効期限を設定する。
$ vault write db1/config/lease lease=10m lease_max=1h Success! Data written to: db1/config/lease
Roleを登録。以下では、"readonly" という Role を登録している。権限は任意のDBに対するSELECT だけ。
$ vault write db1/roles/readonly sql="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';" Success! Data written to: db1/roles/readonly
強い権限をもつアカウントが必要であれば、さらに別の Role を作ればよい。
LDAP Auth Backendの設定
認証し、ユーザにVaultのポリシーを割り当てる Auth Backends というのがある。そのうちの1つにLDAPを使って認証し、LDAPのグループとポリシーを対応づけてくれる LDAP Auth Backend というのがある。
自分の環境では IPA Server が稼働しており、こことつなぐためにこの LDAP Auth Backends を使う。
下記のコマンドで有効にする。
$ vault auth-enable ldap Successfully enabled 'ldap' at 'ldap'!
$ vault write auth/ldap/config url="ldap://ipa.example.com" \ userattr=uid \ userdn="cn=users,cn=accounts,dc=example,dc=com" \ groupdn="dc=example,dc=com" \ upndomain="EXAPMPLE.COM" \ insecure_tls=true \ starttls=true Success! Data written to: auth/ldap/config
ポリシー
db1 に Role "readonly" としてアクセスする情報を読むことができる Policy を作成。 readonly.hcl として下記内容のファイルを用意。
path "db1/creds/readonly" { policy = "read" }
このポリシーをポリシー名 "readonly" として登録。
$ vault policy-write readonly readonly.hcl Policy 'readonly' written.
IPA Server(LDAP)のグループ: "readers" に "readonly" ポリシーを割り当てる。
$ vault write auth/ldap/groups/readers policies=readonly Success! Data written to: auth/ldap/groups/readers
動作確認
以上の設定により、IPA Serverのグループ:"readers"に所属するユーザで、Vault にログインすると、db1/creds/readonly を読むことができ、その結果 SELECT のみが許可されるユーザ・パスワードが払い出される。
Vault にログインする。
$ vault auth -method=ldap username=kikumoto Password (will be hidden): <IPA Serverのユーザ kikumoto に対するパスワード> Successfully authenticated! The policies that are associated with this token are listed below: readonly, readonly
このように、readonly というポリシーが関連づけれらたことがわかる。
引き続き、DBアクセス情報の取得。
$ vault read db1/creds/readonly Key Value lease_id db1/creds/readonly/3bc89d58-fe04-8e2e-0ab4-419cacc618eb lease_duration 600 lease_renewable true password 8c0f7f32-1739-1911-41e5-c9565af7289a username ldap-kikum-c8129
この username / password を用いて db1.example.com の MySQL にアクセスできる。
$ mysql -u ldap-kikum-c8129 -h db1.example.com -p Enter password: > create database mydb; ERROR 1044 (42000): Access denied for user 'ldap-kikum-c8129'@'%' to database 'mydb'
という感じで、CREATE はできない。
そして10分ほど経過すると、Vault のログに下記のような表示されて、アクセス情報が廃止されたことがわかる。
2015/09/06 21:22:53 [INFO] expire: revoked 'db1/creds/readonly/3bc89d58-fe04-8e2e-0ab4-419cacc618eb'
そして、MySQL にはアクセスできなくなる。
$ mysql -u ldap-kikum-c8129 -h db1.example.com -p Enter password: ERROR 1045 (28000): Access denied for user 'ldap-kikum-c8129'@'localhost' (using password: YES)
課題
ポリシーに正規表現が使えないので、対象DBノード数が増えると、その分だけポリシーファイル内のエントリーが増える。 これは Consul Template で解決できればまだ助かるかなぁ。でも、正規表現欲しい。
Vaultがダウンしていたりとかすると DB にゴミユーザが残る気もするので、このあたりどこまで面倒見てくれるのかもう少し確認が必要そう。それでもゴミが残るケースはあると思うので、適宜ゴミ掃除をする仕組みがいるかも。
まとめ
Vault + LDAP を使うと MySQL のアカウント・権限を一元管理的なことができそうなことを試した。
そこそこいけそうな感じではあるが、まだまだ確認しなければいけないことはある。
あとは、Vaultについて詳しいかたと話してみたい。
また、進展があればエントリーを書こうと思う。
いじょう -