トップ 最新 追記

2011-06-01 [長年日記]

_ 秘密鍵を本体内からUSBメモリに移動した

職場の環境が変わったのでこれを機に以前から気になっていたことを試してみた。それは

秘密鍵を本体内に残さない

こと。

Zebedeeはそのまま移動するだけでよかった

トンネルを Zebedee で掘ってるんだけど、Zebedee に関しては

  • 実行バイナリが本体内
  • 設定ファイル、鍵などは USB メモリ

という組み合わせで普通に動いた。起動して detach してしまえば鍵や設定を入れた USB メモリは抜いてしまってもまったく問題ない。

OpenSSHはpermissionがキモ

もともと USB メモリに ssh の秘密鍵は入れてあった。しかしそれは

  • FAT でフォーマットしてある
  • 基本的に緊急時用のもので iniファイル版の putty と putty 用の鍵を用意
  • OpenSSH 用のものも入ってたけど入ってるだけ

という状態だった。今回はここにすでにある OpenSSH の秘密鍵を普段から利用するようにして本体内の秘密鍵は削除してしまおうという作戦。しかし、知ってたけど OpenSSH は鍵の permission をチェックしてくれるので、FAT 上の鍵は使えない。

MSのfilesystemは結局全滅
  • NTFS
  • exFAT *1
  • FAT32

を試したが、どれも OpenSSH の要求する permission を実現することができなかった。まぁ FAT がダメなのは予想通りなんだけど、NTFS もダメなんだね。

どうしたかというと、結局パーティションを分割して

  1. FAT で Windows 用のツールと鍵のパーティション
  2. ext で OpenSSH 鍵のパーティション

を用意した。

あ、Linux で使う気がないなら別に ext パーティションじゃなくて HFS+ でも UFS でもいいような気がするけど、たぶんそんな人いないよね?

MacFUSE + fuse-ext2でextパーティションを作る

ホストが Mac なのでそのままでは ext パーティションは作れない。そこで

の二つを利用して Mac 上で ext を読み書きできるようにした。

fuse-ext2の注意点

(OS や MacFUSE を含めた)バージョンの問題なのかもしれないけど、MacFUSE + fuse-ext2 の組み合わせでは

ext パーティションを自動で mount すると read only になってしまう

ようだ。今回は目的が OpenSSH の鍵を置くだけなので、普段は read only でまったく問題ない。

手作業でrwでmountする

とは言っても実際に鍵を置く作業をする際には read only では困る。そういうときには fuse-ext2 コマンドを mount コマンドに見立てて

$ fuse-ext2 -o rw+ device mountpoint

で mount してあれげば ok. めっちゃ EXPERIMENTAL って man には書いてあるけど。

MacFUSEの注意点

google code にある official version は 32bit で build されているので 64bit で動かしている場合は使えない。有志による 64bit build があるのでそちらを使う。

残念ながら unofficial version の置き場所は定まってないようなので、あっちこっちの blog などからたどって落として来る形になっているようだ。ちょっと怪しげな感じがするけど仕方ないのかなぁ。

なんでこんなことしたのか

もし秘密鍵を奪われた場合、ローカルでブルートフォースできまくるので、公開鍵暗号方式の接続もまったく安全とは言えなくなってしまう。

ということで銃と弾丸を別管理するように、本体と秘密鍵も別管理にできると良いと思い、やってみた。今のところ職場内のモラルやスキル的にこんな措置は必要ないんだけど、これを応用して、

  • 私物ノートの安全性向上
  • 共用アカウントの安全な運用

などを計っていきたいと思っている。

[2012-10-07 追記] もしLAN内の複数の端末で相互にログイン、認証したいので鍵をあちこちに置いておく必要がある、ということがあるなら「使い方を考え」た方がよいだろうし、それでもどうしても秘密鍵をどこかの端末に置いておく必要があるなら「エージェント転送(-A)」や「netcat mode」などが利用できる。

期待はしていなかったが、「netcat mode」では本来ログインできないはずの端末からログインできるようになる。エージェント転送はエージェント情報が途中の端末に残るので秘密鍵を残すのとどちらが危険か判断が必要になる。

Tags: Security OSX

*1 10.6で対応しててパーティションの作成もできた


2011-06-02 [長年日記]

_ keychainでssh-agentと鍵を管理することにした

鍵を本体外に出したので、ssh 接続のたびに鍵ファイルを指定するのがだるくなってしまった。面倒なのはいけない。そこで ssh-agent を使うことにした。

ssh-agentをなんとなく避けていた

ssh-agent は今までなんとなく避けていた。というのも

ssh-agentってメモリ内にパスフレーズそのまま保存してるんじゃないの?

と思っていたから。ということはハイバネート状態のノートからは生のパスフレーズが抜き取れるよね、という話にたどり着いて、そんなあぶないもの使いたくないとか思っていたんだけど、そもそも

PC本体内に秘密鍵があるので本体奪われたらagent使っていようがいまいが一緒

という状態に目をつぶって頑なにagentを拒否していても意味がない。

ということで颯爽とポリシーを変更した。

本当は秘密鍵を抜き取ったことだし、今まで通り ssh-agent を使わない運用ならだいぶ安全になると思うんだけど、逆に接続のたびに USB メモリが必要だと結局 USB メモリ刺しっぱなしになりそうで、それだとまったく意味がない。分離した意味を持たせたうえで面倒なく運用するにはやはり agent を使った方がよさそうだ。

ssh-agentってしっくりこないんです!

  • ssh-agent は秘密鍵とパスフレーズを保持してくれる
  • ssh-agent とのやりとりは ssh-agent 自身ではサポートしてくれない
  • SSH_AUTH_SOCK と SSH_AGENT_PID を使った古典的な方法で、そのままでは shell が変わったら使えない
  • ssh-agent の多重起動も簡単に起きてしまう
ちなみにいちばん簡単な使い方は
  1. eval `ssh-agent` で起動する
    • ssh-agent は起動すると自身の管理に使える環境変数(のセット方法)を出力して daemon 化する。ここでこの出力を eval すると変数がセットされて、その shell 内では ssh-agent とやりとりできるようになる。
  2. ssh-add で鍵を教える
    • このとき必要ならパスフレーズを入力する

の2アクションを行えば、以降の ssh 接続では何もする必要がなくなる。

とは言え shell が変わったら使えなくなるのはきつすぎる。screen 起こしたらアウトだもの。

OSX標準のkeychainってしっくりこないんです!

OSX には 10.5 辺りから ssh 接続のときに GUI でダイアログが出てパスフレーズを記憶しようとしてくれる keychain さんがいる*1。ssh-agent を使いたくなかったのでこれも ~/.zshrc で

unset SSH_AUTH_SOCK

して殺していた。この記述を外して使ってやればいいじゃんと思ったりもしたが、

  • ssh 接続を hook して起きてくるので、接続しようとするまで ssh-agent は起きていない
  • ということは本体外に追い出してしまった鍵ファイルの場所を教える方法がない*2
  • パスフレーズをシステムのキーチェーンに保存したいわけじゃない

ということでやっぱり黙っていてもらうことにした。

別途keychainをインストールする

Mac のキーチェーンじゃなくてこれ。

Keychain - Funtoo Linux

MacPorts でも Homebrew でもインストールできる。

ここで言う keychain の目的の一つは上で挙げた ssh-agent の shell をまたげないという問題を回避する方法を提供することで、もう一つは ssh-agent の多重起動も防止すること。何度呼び出しても ssh-agent は増えない。つまり、

  1. ssh-agent を起動してSSH_AUTH_SOCK と SSH_AGENT_PID をファイルに吐き出す
  2. ssh-agent を管理する

上の機能を提供してくれる。

実際に keychain を活用するには keychain をインストールして起動するだけではやっぱりダメで、自分の使っている shell の rc ファイルに上の 1 で吐き出されたファイルの存在チェックと、存在した場合の読み込み処理を追記してやる必要がある。

何を書けばよいかは man を読めば分かる。

OSX 標準のものを殺しつつkeychainを利用する

どこでもいいんだけど man にある通り ~/.keychain に agent 関係のファイルを保存することにしたので、

if [ ! -f $HOME/.keychain/$HOSTNAME-sh ] ; then
    unset SSH_AUTH_SOCK
fi

こんな感じで

  1. 自分で起こした keychain の使うファイルがあれば SSH_AUTH_SOCK はそのまま使う
    • でないと ssh-agent とやりとりできない
  2. 存在しない場合は OSX 標準の keychain を呼ぼうとしてうざいので SSH_AUTH_SOCK は消しちゃう

ということにした。それ以外にも hostname を screen さんやいろんな人が利用していたりして結構面倒なことになっていたが、ようやく整理できた。

使い方

今はどうしているかというと、

  1. USBメモリを刺す
  2. eval `keychain --eval`
  3. ssh-add /Volumes/PATH/TO/KEY
  4. パスフレーズを入力
  5. USBメモリを抜いて片付ける

で、快適生活してます*3

長時間席を外すときには

keychain -k all

しておくと安心。

Tags: Security

*1 どうやら SSHKeychain と言うらしく、/usr/sbin/systemkeychain が正体かな? そこから /usr/bin/ssh-agent -l を起動する。

*2 と思ったけど ssh -i で教えられるな…。忘れてた。

*3 ssh-add を keychain でやることもできる