Vault 0.3がリリースされたときにSSHに関する機能が実装されたと言うのを見て気になっていたのですが、なかなか試せずにいたのですが、先日HashiCode#2に参加したので、その勢いで試してみました。

Vault の SSH Secret Backend はもの凄く大ざっぱに言うとVaultがSSHのパスワードや公開鍵の管理を行ってくれる機能です。

使うもの

  • Vault 0.3以上
  • OpenSSH
  • vault-ssh-helper
  • CentOS 7.0
    • ディストリはGentooでも何でも

SSH Secret Backend

まずは Vault について理解を深めるためにGetting Startedを行ってみるとよいと思います。

$ vault server -dev

このように-devを付けて起動すると何も考えずに各種機能を試せます。 この dev モードはメモリだけで動作するので、終了すると設定した内容はすべて消えてしまいます。 また、データの seal もされてないので、プロダクション環境では使わないようにしましょう。

vault-ssh-helper のインストール

Vault の操作の前に vault-ssh-helper をインストールする必要があります。

$ git clone https://github.com/hashicorp/vault-ssh-helper
$ cd vault-ssh-helper
$ make bootstrap
$ make
$ make install

次に設定ファイルを作ります。

$ sudo vi /etc/vault-ssh-helper.d/config.hcl
vault_addr="http://127.0.0.1:8200"
ssh_mount_point="ssh"

PAMの設定を変更します。

$ sudo vi /etc/pam.d/sshd
- auth       substack     password-auth
+ auth requisite pam_exec.so quiet expose_authtok log=/tmp/vaultssh.log /usr/local/bin/vault-ssh-helper -config-file=/etc/vault-ssh-helper.d/config.hcl
+ auth optional pam_unix.so no_set_pass use_first_pass nodelay

最後に /etc/ssh/sshd_config の以下の3つを変更しておきます。

ChallengeResponseAuthentication yes
UsePAM yes
PasswordAuthentication no

One Time Password Type

それでは dev mode でOTPを試してみます。

$ export VAULT_ADDR='http://127.0.0.1:8200'
$ vault mount ssh
Successfully mounted 'ssh' at 'ssh'!
$ vault write ssh/roles/otp_key_role \
    key_type=otp \
    default_user=centos \
    cidr_list=127.0.0.0/8,192.168.11.0/24
Success! Data written to: ssh/roles/otp_key_role

以上がOTPの設定です。 One-Time-Tokenを作ってみます。

$ vault write ssh/creds/otp_key_role ip=127.0.0.1
Key             Value
lease_id        ssh/creds/otp_key_role/ab69a54e-f845-d29a-0627-a3971cacb7b7
lease_duration  2592000
lease_renewable false
key             0c9e7c24-64bb-8c71-3aa4-fdff88b31fde
key_type        otp
port            22
username        centos
ip              127.0.0.1

ここで指定する ip は前述のcidr_listの範囲であれば何でも良いです。 出力結果のkeyがOTPです。

試してみます。

$ ssh centos@localhost 
Password: 0c9e7c24-64bb-8c71-3aa4-fdff88b31fde
[centos@localhost ~]$ exit
$ ssh centos@localhost
Password: 0c9e7c24-64bb-8c71-3aa4-fdff88b31fde
Password: 
Password: 
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,keyboard-interactive).

このように一度使ってしまったOTPは再度利用できません。

次に他のユーザでログインできるOTP作ってみます。

$ vault write ssh/creds/otp_key_role ip=127.0.0.1 username=vagrant                                                                                                                                                                           
Key             Value
lease_id        ssh/creds/otp_key_role/f49cfd4e-907d-5cf7-1d80-c9fc932b5ad9
lease_duration  2592000
lease_renewable false
key_type        otp
port            22
username        vagrant
ip              127.0.0.1
key             21a90e3b-fe47-4766-af2e-fcb0093c1864
$ ssh vagrant@localhost
Password: 21a90e3b-fe47-4766-af2e-fcb0093c1864
[vagrant@localhost ~]$ 

毎回 vault write コマンドでOTPを作るのはめんどくさいという方は vault ssh と言うコマンドが用意されています。

$ vault ssh -role otp_key_role centos@localhost
OTP for the session is 28535dc6-7b50-af74-b37f-4b6ebedcf50c
[Note: Install 'sshpass' to automate typing in OTP]
Password: 28535dc6-7b50-af74-b37f-4b6ebedcf50c
Last login: Thu Oct 22 23:55:06 2015 from localhost
[centos@localhost ~]$

書いてある通り sshpass を入れておけばOTPの入力を省略できます。

$ sudo yum install -y epel-release
$ sudo yum install -y sshpass
$ vault ssh -role otp_key_role centos@localhost
Last login: Thu Oct 22 23:59:23 2015 from localhost
[centos@localhost ~]$

Dynamic Type

Dynamic Typeは公開鍵を使用して認証として利用する方式です。 仕組みとしては、Vault サーバがログイン先のサーバ・ユーザの authorized_keys に一時的に生成した公開鍵をインジェクトするというものです。

インジェクトするためにSSHを利用するので、あらかじめVaultに追加した秘密鍵で生成した公開鍵を各サーバに登録しておく必要があります。 また、Vault Serverがインジェクトに使用するユーザが sudo が使える権限を付与する必要があります。

また、今回はパスワード認証を行わないのでChallengeResponseAuthenticationnoにしておきましょう。

最初に秘密鍵・公開鍵ペアの作成し秘密鍵をVaultに登録します。

[vagrant@localhost ~]$ openssl genrsa -out shared_key.pem 2048                                                                                                                                                                                                                 
Generating RSA private key, 2048 bit long modulus
............................................................+++
.........................+++
e is 65537 (0x10001)
[vagrant@localhost ~]$ vault write ssh/keys/dev_key key=@shared_key.pem
Success! Data written to: ssh/keys/dev_key

各サーバの sudoers に以下の設定を入れます。 Vault Serverがログインに利用するユーザは vaultadmin とします。

[vagrant@localhost ~]$ ssh-keygen -f shared_key.pem -y | sudo tee -a /home/vaultadmin/.ssh/authorized_keys
[vagrant@localhost ~]$ visudo
vaultadmin   ALL=(ALL)NOPASSWD: ALL

最後にDynamic Key Roleを有効化します。 admin_user は Vault serverがログインに使用するユーザである vaultadmin を指定します。

[vagrant@localhost ~]$ vault write ssh/roles/dynamic_key_role \
    key_type=dynamic \
    key=dev_key \
    admin_user=vaultadmin \
    default_user=centos \
    cidr_list=127.0.0.0/8,192.168.33.0/24
Success! Data written to: ssh/roles/dynamic_key_role

では、キーペアを作成してみます。

[vagrant@localhost ~]$ vault write ssh/creds/dynamic_key_role ip=127.0.0.1
Key             Value
lease_id        ssh/creds/dynamic_key_role/657543b6-26ee-370c-d67c-bf0965171afd
lease_duration  2592000
lease_renewable true
ip              127.0.0.1
key             -----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC1fPQ1wA0eThBxPCu3WwCBWontKrrYaiOXJkjGkPl+fFSBwIP3
7WUzfVrI9oYEeFisRvbsi1NjMeAFpHwC5vGbqGWd8UGUZW5PDyfoPOnj9jsbUd5U
kPz1nZfxKke73WpXShyqtO3nIiF3BU6XbBSJuOuvDCC/P5ZCL/vSYHCjcQIDAQAB
AoGBAKgUVDtfZQbW92VXe4kxL3Oc/TX3p9l72wBGBYpYg6f/z2fnepDnfB1GkAik
P5PuPPk4M8D4e77XVwkCv5MUfVbC52fQjpVktKsdvt4TMx9r3RrIm/xEkxRNJSr1
vYIXcfBzh49s3CwPrMAOXugE0/1lx2dVjovS8BZbv9wBm9vBAkEAzj4j4PWcSMIn
5MPqyQ8cvWAPdOAKIDXStzTBZ3drHTnE1s2AlSVuBMTnDAvIBXHGpy8lTsysHGqk
OxDWhVseGQJBAOFF7jsSdaU9nhoUk+9wmK/iXrTbjJgzRegmBPnVRaZQNurxcv9p
wQqqMTynP0rIBWuun32wyxQJiS4y9jbwqxkCQQDC7rrMqnhv0IsSTxa/uHfqijux
tPv9G8IxBTzzxUxJkEt61zt8PKdy/ISAvzXr53Dinc3+X7chGK5nYW/RFaEpAkB8
2shd/y4rJkqRQ+R2Kd7GZN1+ucxjss9FCoVpfpX6xqyZbLcC7rcqVQezCTMgHFo8
w2zsOedkNKDOdTpXWu5JAkBWsUq1pLv3B7L5ZgGzE3lIzCNJAsrzoyB+VCp3LsxR
XQ4i1krzcUCyh3g58CdN7mS82kkrQ9iGkTkbu7B6JmVZ
-----END RSA PRIVATE KEY-----
key_type        dynamic
port            22
username        centos

keyが生成された秘密鍵です。ファイルに保存します。

[vagrant@localhost ~]$ vi dynkey.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC1fPQ1wA0eThBxPCu3WwCBWontKrrYaiOXJkjGkPl+fFSBwIP3
7WUzfVrI9oYEeFisRvbsi1NjMeAFpHwC5vGbqGWd8UGUZW5PDyfoPOnj9jsbUd5U
kPz1nZfxKke73WpXShyqtO3nIiF3BU6XbBSJuOuvDCC/P5ZCL/vSYHCjcQIDAQAB
AoGBAKgUVDtfZQbW92VXe4kxL3Oc/TX3p9l72wBGBYpYg6f/z2fnepDnfB1GkAik
P5PuPPk4M8D4e77XVwkCv5MUfVbC52fQjpVktKsdvt4TMx9r3RrIm/xEkxRNJSr1
vYIXcfBzh49s3CwPrMAOXugE0/1lx2dVjovS8BZbv9wBm9vBAkEAzj4j4PWcSMIn
5MPqyQ8cvWAPdOAKIDXStzTBZ3drHTnE1s2AlSVuBMTnDAvIBXHGpy8lTsysHGqk
OxDWhVseGQJBAOFF7jsSdaU9nhoUk+9wmK/iXrTbjJgzRegmBPnVRaZQNurxcv9p
wQqqMTynP0rIBWuun32wyxQJiS4y9jbwqxkCQQDC7rrMqnhv0IsSTxa/uHfqijux
tPv9G8IxBTzzxUxJkEt61zt8PKdy/ISAvzXr53Dinc3+X7chGK5nYW/RFaEpAkB8
2shd/y4rJkqRQ+R2Kd7GZN1+ucxjss9FCoVpfpX6xqyZbLcC7rcqVQezCTMgHFo8
w2zsOedkNKDOdTpXWu5JAkBWsUq1pLv3B7L5ZgGzE3lIzCNJAsrzoyB+VCp3LsxR
XQ4i1krzcUCyh3g58CdN7mS82kkrQ9iGkTkbu7B6JmVZ
-----END RSA PRIVATE KEY-----
[vagrant@localhost ~]$ chmod 400 dynkey.pem

保存した鍵を利用し、ログインしてみます。

[vagrant@localhost ~]$ ssh -i dynkey.pem centos@localhost
[centos@localhost ~]$ exit

こちらはRevokeするか、lease_durationが経過するまで鍵を使用することが出来ます。 Revokeは次のように行います。

[vagrant@localhost ~]$ vault revoke ssh/creds/dynamic_key_role/657543b6-26ee-370c-d67c-bf0965171afd
Key revoked with ID 'ssh/creds/dynamic_key_role/594ac177-f4b2-b840-31ab-4cea0b15e18a'.
[vagrant@localhost ~]$ ssh -i dynkey.pem centos@localhost
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

まとめ

Vaultを利用することでSSHの鍵の管理をVaultに任せてしまうことができるので、各サーバに鍵の展開を行う必要はなくなりそうです。 今回は使ってみることを優先してみましたが、実際に利用する際はAuth BackendsAudit Backendsの設定が必要です。

参考文献