みなさんさようなら.
仕事でも家でもAWSを使っていて,よくsshログインをしなければならない局面がある. で,高度に自動化されたAWSだと,Autoscaling Groupを使ってEC2インスタンスを自動で生み出したり,また自動で落としたりするよね. ECSを使っていても,裏側にはAutoscaling Groupを用意しておいて,インスタンスが足らなくなったら補充したりする.
で,そういうインスタンスに全てEIPを振ったり,固定のAレコードをつけたりしますか?
俺はめんどくさくてやってません(EIPはインスタンスに割り当てられてないと課金されるしね).
そうなると自然と,sshログインする際に「今どんなインスタンスが生きてるんだろー」って確認して,ターゲットのインスタンスのIPをコピーしてきてターミナルに貼り付けたりする.
めんどくさい.ああめんどくさい,めんどくさい.
この作業だけで,ブラウザを開く
-> AWSのコンソールにログインする
-> EC2インスタンスを探し出す
-> IPをコピーする
-> ターミナルに戻ってsshコマンドを組み上げる
というだけの作業をやらなきゃいけない.AWSアカウントに二段階認証をつけていたりすると,コンソールにログインするだけでめんどくさい.
pecoとかpercolを使ってなんとかする
この悩みはみんな当たるらしく,
みんな自作の関数を公開してくれている.
俺も今までこれらの例を参考に自分で関数を作っていた.
proxyを踏み台にしたい
管理するサーバ台数が多くなってくると,今度は個人ユーザを各サーバに配置するのがめんどくさくなる. セキュリティ的にも,いろんな人の公開鍵がアプリケーションサーバに埋め込まれてるのは嬉しくないし,会社だと人が辞めたり入ってきたりして,そのたびに全台のユーザ削除や追加を行わなければならない.
そうすると,自然とプロキシサーバみたいなものを作って,それを踏み台にしてアプリケーションサーバにログインする構造を作りたくなる.そうすれば,ユーザの管理はプロキシサーバでのみ行えばよくて,人が辞めたり入ってきた場合でもプロキシサーバでユーザ削除・追加を行えば十分になる.
となると,ログインする際にはプロキシを踏み台にする必要がある.
いろんな場所のIPが固定されているなら,~/.ssh/config
あたりに書けば良いが,プロキシサーバすらもchefで作ったりして,たまにインスタンスごと作りなおしたりする.
となると,先ほどの関数,プロキシ経由でも使いたいぞ.
zsh-ec2ssh
というわけで,作った.そしてそろそろプラグインにしてみた.
もちろん,プロキシを使わずに,単にリストアップしたEC2インスタンスにログインするだけの関数も提供している.
インストール方法はREADMEに書いているけど,zplugとか使うと楽だよ.
単にsshログインしたい
こんな~/.zshrc
を書く.
AWS_PROFILE_NAME=default AWS_DEFAULT_REGION=ap-northeast-1 SSH_USER=h3poteto SSH_PRIVATE_KEY_PATH=$HOME/.ssh/id_rsa function zsh-ec2ssh-default() { zsh-ec2ssh $AWS_PROFILE_NAME $AWS_DEFAULT_REGION $SSH_USER $SSH_PRIVATE_KEY_PATH } zle -N zsh-ec2ssh-default bindkey '^t' zsh-ec2ssh-default # Ctrl + t
proxyを踏み台にしてsshしたい
こっちはちょっと複雑.
AWS_PROFILE_NAME=production AWS_DEFAULT_REGION=ap-northeast-1 SSH_USER=h3poteto AWS_PROXY_PROFILE=proxy SSH_PROXY_USER=proxy-login-user SSH_PRIVATE_KEY_PATH=$HOME/.ssh/id_rsa function zsh-ec2ssh-production-proxy() { zsh-ec2ssh-with-proxy $AWS_PROFILE_NAME $AWS_DEFAULT_REGION $SSH_USER $AWS_PROXY_PROFILE $SSH_PROXY_USER $SSH_PRIVATE_KEY_PATH } zle -N zsh-ec2ssh-production-proxy bindkey '^p' zsh-ec2ssh-production-proxy # Ctrl + p
これを発動すると,まず,AWS_PROXY_PROFILE
で指定されたAWSアカウント内のインスタンスをリストアップする.この中から,踏み台にしたいサーバを選択する.
次に,AWS_PROFILE_NAME
で指定されたAWSアカウント内のインスタンスがリストアップされる.ここから,ログインしたいサーバを選択する.
profileを分けて指定させたのは,プロキシサーバを必ずしも同じAWSアカウント内に作っていないパターンがあったため(実体験,でもよくなかったとは思ってる).
このときのSSH_PRIVATE_KEY_PATH
はプロキシサーバへのログインに必要な秘密鍵の場所を指定する.
プロキシサーバ->アプリケーションサーバのログイン時の鍵指定には対応していない(けどこれって普通にプロキシサーバ作ったらだいたい$HOME/.ssh/id_rsa
とかでログインできるように作るんじゃないかな?という期待).
同じくSSH_PROXY_USER
はプロキシサーバへログインする際のユーザ名.
プロキシサーバ->アプリケーションサーバのログイン時のユーザはSSH_USER
で指定する.
あと,ちなみにこのへんの値は,だいたいデフォルトを環境変数から読むようになっていて,$AWS_DEFAULT_PROFILE
とか$AWS_DEFAULT_REGION
とか$USER
とかが設定されていると,そのへんをデフォルトとして使うようにしてある.
依存に入っているpecoはいいけどmyawsってなに?
友達が作っているコマンドラインツールで, A human friendly AWS Client written in Go
らしい.
awscliでもいいんだけど(というか昔はawscliを使っていた),これが出してくる情報が多すぎて,jq等を使ってフィルタリングしないといけない.これが結構めんどくさい上に,依存がひとつ増えてしまう. 対して,myawsの場合,出力するものを割と自由に指定できる(出力のfields指定ができる)のと,デフォルトのままで結構見やすい.その上goのバイナリなのでシングルバイナリになっている.
というわけで採用した.brewでインストールできるし!
StrictHostKeyChecking=noが気になる
はい,これは迷いどころで,askかyesにしたほうがいいというのもわかる. というかオプションで差し込めるようにしようかなーと思ったんだけど,まだ作ってない.どうしよう,やっぱり気になるかな.