猫と一緒にガジェットライフ♪ムチャ(@mutoj_rdm821)です。
あまりとりとめの無いシリーズになっていますが、自分用に調べたものの覚え書きという感じです。
前回はrubyのnet-sshを使ってシェルスクリプト(コマンド1発ではない)を実行する手順をご紹介しました。
今回は多段接続をする方法です。
多段接続とは
図のように、特定の閉じられたネットワークがあり、セキュリティポリシーにより外部からssh接続できるのは特定の1台のみという状況です。
目的のサーバーへ直接ssh接続することはできないので、踏み台となるサーバーへ一旦入ってから、さらにsshで接続する必要があります。
やり方!
とりあえずやり方です。前回と同じように、予め生成したキーペアの公開鍵は事前に踏み台およびターゲットサーバーに配置済みという前提です。
proxy = Net::SSH::Proxy::Command.new("ssh [proxy_host] -o stricthostkeychecking=no -W %h:%p -i ‘path/to/key_file’) opt = { keys: [‘path/to/key_file’], proxy: proxy, host_key_alias: 'Target Server', } Net::SSH.start([target_host], 'root', opt) do |ssh| ~
Net::SSH::Proxy::Commandというクラスがあるので、それを使います。
[proxy_host]には踏み台となるサーバー、[target_host]は目的のサーバーを指定(ホスト名またはIPアドレス)します。
%h、%pはそのままでOKです。ライブラリが置き換えてくれます。-Wというオプションは、%h:%pで指定したサーバー:ポートに対しての接続を中継する指定です。
あれ、-i [秘密鍵ファイル]は指定しなくても平気かもしれません・・・
opt(Hash)のproxyというキーにこのオブジェクトを入れて、通常通りNet::SSH.startを実行する際に引数に渡してやります。このときの接続先は最終的な目的のサーバーなので注意。
sshで接続する際には接続先のサーバー固有の値を確認する手順が入るのですが、stricthostkeychecking=noの指定でこれを無視します。本当は確認しないと、偽のサーバーにログインしてしまう可能性があるのですが、予め分かっている相手なら不要でしょうということで。指定しておかないと、初めてログインする際(~/.ssh/known_hostsに登録されていない)にエラーになってしまう気がしました(汗)。
Net::SSH::HostKeyMismatchエラーが出る場合
仮想環境で何度もサーバーを作り直している場合、同じIPアドレスやホスト名で異なるフィンガープリントが返ってくる場合があり得ます。
~/.ssh/known_hostsに登録されている情報と異なる場合、Net::SSH::HostKeyMismatchエラーが出ます。この場合はknown_hostsの情報を消してやればOKです。
上のコードで、HashにUserKnownHostsFileというキーでこのknown_hostsのファイル名を指定できるようなので、/dev/nullとかにしてやれば回避できそうです(未確認)。
-Wオプションについての余談
昔はncというコマンドで標準入出力を中継していたようです。これがOpenSSH5.4から標準機能として内蔵され、-Wオプションで使えるようになったとか。
ProxyCommandによるsshの多段接続について – ぺけみさお
まとめ
というわけで、net-sshでの多段接続の仕方でした。
自分用メモですが、お役に立てれば幸いです。
ちなみにnet-sshについては公式ドキュメントが結構しっかり書かれています(英語)。
それではみなさま良きガジェットライフを(´∀`)ノ