SSHのRemoteCommandでも踏み台っぽく扱う

TL;DR

ProxyCommandもいいけど、厄介な事情ならRemoteCommandでもできそうですよという記事。

以下のような場合。

  • PC: bastion(user:foo) へ繋ぐ
  • bastion(user:foo): bastion(user:bar)にユーザを切り替え
  • bastion(user:bar): vagrant ssh server-1 で繋ぐ
  • また、ポートフォワードで、PCのlocalhost:54321にアクセスすると、server-1のlocalhost:54321につながるようにしたい

~/.ssh/configにはこんな感じに書く。

Host server-1
  User foo
  HostName bastion
  LocalForward 54321 localhost:54321
  RemoteCommand sudo -i -u bar -- vagrant ssh server-1 -- -L 54321:localhost:54321
  RequestTTY yes

RequestTTY yesがミソでこれが欠けると応答が返ってこなくなる。正直よくわかっていない。 あとはコマンド通りという感じ。

ただ、ProxyCommandのように秘密鍵を手元だけで管理できないし、LocalFowardの数珠繋ぎ感が辛い。ケースバイケースでしょう。

以下、やったこととか

背景

PC→bastion(user:foo)→bastion(user:bar)→vagrant ssh server-1

というちょっと変わったSSH構成がある。

繋ぐだけなら簡単で、以下のようにすればよい。

PC

ssh foo@bastion

bastion(user:foo)

# sudo 権限があるものとする

sudo su - bar
vagrant ssh server-1

# もしくは一発で
sudo -i -u bar vagrant ssh server-1

ここまでは簡単なんだけど、これを1発でやりたい、LocalForwardしたい、となるとすぐ出てこなかった。 単純なsshサーバであれば、ProxyCommandを数珠繋ぎになるようにすればいける。が、そうでない場合はどうすればよいかわからなかった。

整理

  • bastionのfooユーザにしかログインできない(sudo権限はある)
  • bastionのbarユーザが持ってるVagrantfileを使う必要がある
  • vagrant ssh server-1する必要がある

sshコマンドで使えるようにするためにvagrant ssh-configで書き出す方法もあるが、鍵ファイルがfooが読めるとは限らないので今回は却下。 まぁvagrant秘密鍵なんてだいたい飾りなのでコピーしても良いかもしれない。

で、最初はProxyCommandで出来るでしょうって思って色々試したが全然できなくて、2時間ぐらいハマる。 ProxyCommandを完全に理解したあたりから「これ、ProxyCommandじゃなくて、ログインした後にsudoとvagrant sshさせないといけないのでは」とまた調べて、RemoteCommandをどう使うか調べてたらserverfaultでそのまま使えばよさそうという事に気づいて解決した。

serverfault.com