42
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ぼくのかんがえたさいきょうの(?)SSH鍵運用管理方法

Last updated at Posted at 2015-07-15

サーバーへ接続する際のSSH鍵ってどうしてますか?

AWSでEC2インスタンスを立てるときに生成するSSH鍵(keypair)を開発者間で持ち回って運用・管理しているというところも結構あるのではないでしょうか。ただ、開発者が部署異動する場合や退職する場合を考えるとセキュリティ上のリスクがあります。

開発者個別に自身のSSH公開鍵を提出してもらってそれで認証するのもいいんですが、なにぶんサーバー数やユーザー数が多くなるとその管理が大変になってきます。

そんな悩みどころをまとめると次の2点になります。

  • 要求①: サーバー数が多くなっても自動的に全サーバーに反映したい
  • 要求②: ユーザー個別にどのサーバーにアクセス可能か管理したい

そこで以下の方式を考えてみました。

cron pull方式

信頼と実績のcronとリポジトリpull機能を使った方式です。

サーバー数が多くなっても自動的に全サーバーに反映させる

要点は以下です。

  • .ssh/authorized_keysに相当するファイルをリポジトリ管理する
  • 各サーバーではcronで定期的に.ssh配下にリポジトリ内容をpullする

リポジトリ内のファイル構成(各サーバーの.sshフォルダ配下の構成)は下記のようにします。肝はauthorized_keysをシンボリックリンクにしておくこと。この構成をcronで定期的にpullしてくるようにします。

REPO_ROOT
  ├ authorized_keys # ← シンボリックリンク。リポジトリ管理外
  ├ config          # ← リポジトリ管理外
  ├ known_hosts     # ← リポジトリ管理外
  ├ rc
  └ sources
    ├ authorized_keys-Service1-PRD-root # 本番環境へアクセスできるユーザーのSSH鍵集
    ├ authorized_keys-Service1-PRD-ref  # 本番環境へ参照のみできるユーザーのSSH鍵集
    ├ authorized_keys-Service1-STG-root # ステージング環境へアクセスできるユーザーのSSH鍵集
    ├ authorized_keys-Service1-DEV-root # 開発環境へアクセスできるユーザーのSSH鍵集
    ├ authorized_keys-Service2-PRD-root
    ├ authorized_keys-Service2-STG-root
    ├ authorized_keys-Service2-DEV-root
      ……

上記では仮に「authorized_keys-<サーバー名>-<ステージ>-<Unixユーザー名>」としています。

ユーザー個別にどのサーバーにアクセス可能か管理する

前述までの仕組みで要求①が実現できました。次は要求②です。

ユーザーとアクセス可能なサーバーをスプレッドシートで管理し、CSV出力したものをスクリプトに食わせてauthorized_keys_XXXファイルを出力させます。

timestamp user_name ssh_key servers options memo
2015/07/15 12:34:56 hanako ssh-rsa AAAB3z(中略)FlqFz hanako@example.com Server1-PRD-root, Server2-PRD-root なし 管理者
2015/07/15 14:56:12 tarou ssh-rsa AAAB3x(中略)DzsBa tarou@example.com Server1-DEV-root なし 開発者
2015/07/15 16:23:46 jirou ssh-rsa AAAB3y(中略)AhrJk jirou@example.com Server1-PRD-ref no-pty,no-X11-forwarding,no-agent-forwarding DB参照者

optionsは、authorized_keys内で指定するオプションです。DB参照者のようにログインはせずポートフォワーディングだけしたい場合は「no-pty,no-X11-forwarding,no-agent-forwarding」を指定するなどしておくとよいと思います。

スプレッドシートはGoogle Driveのフォームなどを使うと、GitHubやBitbucketのSSH鍵登録フォームのような感じになり、ユーザーも管理者も幸せになれそうな気がします。

スクリーンショット 2015-07-15 21.37.11.png

おまけ

authorized_keysには小粋な機能があって、接続してきたSSH鍵それぞれに対して個別に環境変数を設定することなどができます。

参考: authorized_keys ファイルについて調べてみたら楽しかった. - それマグで!

なので、以下の様なauthorized_keys_XXXを生成するようにしておき、.ssh/rcにシェルスクリプトを仕込んでおくとログインしてきたユーザー名&接続元IPをログに記録することができます。

environment="SSH_LOGIN_NAME=hanako" ssh-rsa AAAB3z(中略)FlqFz hanako@example.com
.ssh/rc
if [ "$SSH_LOGIN_NAME" != "" ]; then
    logger -t SSH "$SSH_LOGIN_NAME on $USER accessing now! (from $SSH_CLIENT)"
fi

メリット・デメリット

  • 持ち回り方式
    • メリット:
      • サーバー側の運用・管理が楽。何もしなくてイイ
    • デメリット:
      • 開発者の部署移動や退職時に個人別に権限を剥奪することができない
  • cron pull方式
    • メリット:
      • 開発者の部署移動や退職時に個人別に権限を剥奪することができる
    • デメリット:
      • pullが失敗するとログインできないサーバーになってしまう
        • それでも最後にpull成功していた状態は保たれると思われる

おわりに

chefとか使ったらもっとスマートにできるのかもしれませんが、使ったことなくてわかってないです。
もっと簡単にできるよという方法をご存知のかた、ぜひとも教えて下さい。

42
36
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?