Puppet 3.6から使えるpurge_ssh_keysでauthorized_keysをきちんと管理する

#puppet

Puppet 3.6でuserリソースにpurge_ssh_keysが追加され、Puppetで管理されていないauthorized_keysを削除できるようになった。

ssh_authorized_keyおさらい

前に、Puppetのssh_authorized_keyリソースを使ってauthorized_keysを管理する方法を書いた1

使い方は以下の通りだ。ユーザ、鍵、鍵のタイプを指定する。

ssh_authorized_key { 'vagrant insecure public key':
  user => 'testuser',
  key  => 'AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==',
  type => 'ssh-rsa',
}

このmanifestsを適応すると、/home/testuser/.ssh/authorized_keysへ以下のように公開鍵が登録される。

[testuser@localhost ~]$ cat .ssh/authorized_keys
# HEADER: This file was autogenerated at Mon Dec 29 18:27:52 +0900 2014
# HEADER: by puppet.  While it can still be managed manually, it
# HEADER: is definitely not recommended.
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key

Puppet以外で追加した鍵の管理(削除)が難しかった

しかし、ssh_authorized_keyリソースには、Puppetで管理していない公開鍵を削除出来ない難点があった。 例えば以下のように、任意の公開鍵を登録してしまうと、Puppetからは削除出来なかったのだ。

[testuser@localhost ~]$ cat .ssh/authorized_keys
# HEADER: This file was autogenerated at Mon Dec 29 18:27:52 +0900 2014
# HEADER: by puppet.  While it can still be managed manually, it
# HEADER: is definitely not recommended.
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA89gn23YAVYUUSsJQ25qjJabKDHIuEWUifhHfXJCvM5mHR/1jUaS3Yf4k1X8MItmyOWldPNJ+u49wluL/NKbsGnaxaihVrjS8B5WnKrauWxIsNN19UOJ2gwiMOGr4BvdtR2TuToylU0jKvZX60JsMEF+3KI8kT2ISRl3UqfVNutH1jeCdj1ba6kfFPsJAsfBuvn7eE0d+T+zWZp5jRZwnzt6cfgv1gAY+FPwz06TBw5Hag+Q++evqJ6r5eb8QJWGasUyu/+6mhjHuiKv9BTdnwkHT6qUm9Whgxb1TifmHCBvqklkw94N8VlKczKhBn8NRwhKu/0hn/RUt8/kFgqayow== vagrant@localhost.localdomain

ちょっとした用事から公開鍵をサーバに登録して接続を試みることは割とあるが、いつ誰が追加したかを記録するのは難しい。

閑話休題: CMTの削除苦手問題について

このような「削除が苦手」というのはChef/PuppetのようなConfiguration Management Toolsに共通する問題で、Rebuild 24回でもmizzyさんが言及している。

「一時的に必要で入れたものを、後に必要がなくなったから削除する」のが難しいという話で、この問題はPuppet側も認識しているのか、purgeする機能はちょこちょこ実装されている。

Puppet 3.6でuserリソースにpurge_ssh_keys属性が追加された

さて、このauthorized_keysの削除問題を解決する機能がPuppet 3.6で導入された。

purge_ssh_keys属性をuserリソースに指定することで、そのユーザのauthorized_keysをより精確に管理することが出来るようになった。

user { 'testuser':
  ensure         => present,
  purge_ssh_keys => true,
}

このmanifestsを適応すると、Notice ... Ssh_authorized_key[vagrant@localhost.localdomain]/ensure: removedとある通り、Puppetで管理していない公開鍵vagrant@localhost.localdomainがauthorized_keysから削除された。

$ vagrant provision
==> default: Running provisioner: puppet...
==> default: Running Puppet with default.pp...
==> default: Notice: Compiled catalog for localhost in environment production in 0.73 seconds
==> default: Notice: /Stage[main]/Main/Ssh_authorized_key[vagrant@localhost.localdomain]/ensure: removed
==> default: Notice: Finished catalog run in 0.09 seconds

ちなみにautorequireが効いているので、require属性を指定する必要も無い。 便利だ。

Autorequires: If Puppet is managing the user account in which this SSH key should be installed, the ssh_authorized_key resource will autorequire that user.

https://docs.puppetlabs.com/references/latest/type.html#ssh_authorized_key-description

Puppet 3.6.0から使えるらしいけど…

リリースノートにある通り、この機能はバージョン3.6.0から利用可能となっている。

Feature: Purging Unmanaged SSH Authorized Keys
Purging unmanaged ssh_authorized_key resources has been on the most-wanted features list for a very long time, and we haven’t been able to make the resources meta-type accommodate it.

https://docs.puppetlabs.com/puppet/3.6/reference/release_notes.html#feature-purging-unmanaged-ssh-authorized-keys

ところで、以下のバグレポートを見ると、Puppec 3.6系では特定条件のauthorized_keysが上手く削除できない問題が在るようだ。

この課題はPuppet 3.7.0で解消されているので、purge_ssh_keysを利用する場合はPuppet 3.7系が良さそうだ。

まとめ

Puppet 3.6からは便利な機能な大量に追加されている。

ssh_authorized_keyリソースを使って鍵管理するのであれば、userリソースにもpurge_ssh_keys属性を指定することで、より厳密なauthorized_keysの管理が実現出来る。

サーバの管理台数が増えるとauthorized_keysの管理は難しくなりがちなので、できれば両方を指定した方がいいだろう。