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

しておくと安心。

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

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

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

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm