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 が使える権限を付与する必要があります。
また、今回はパスワード認証を行わないのでChallengeResponseAuthentication
はno
にしておきましょう。
最初に秘密鍵・公開鍵ペアの作成し秘密鍵を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 BackendsやAudit Backendsの設定が必要です。