前提
local, remote1.com, remote2.com があるとする。remote2.com は remote1.com からのみログインできる。経路の SSH は全て公開鍵認証を行う。
SSH config で済む場合
SSH config ~/.ssh/config に書けるならそれが一番楽。経路の認証に使う鍵が接続元である local に全て存在している場合はこれでよい。
Host remote2
HostName remote2.com
User remote2user
IdentityFile /path/remote2key
ProxyCommand ssh -l remote1user -i /path/remote1key remote1.com -W %h:%p
これで
local:~$ ssh remote2
local:~$ scp src remote2:/path/dest
local:~$ rsync src remote2:/path/dest
で済み、emacs (tramp) もこれを読むので C-x C-f ssh:remote2 で接続できる。
config に書けない場合、ヘルパースクリプトを用意
表題のコマンド群は、バックエンドの SSH コマンドでどれを使うかを指定できる。
つまり、config で対応できないケース、例えば 3段目に使う鍵を接続元に持ってこれないとか、途中で sudo ssh をしたいとか、そういう場合であるが、ssh をラップしたスクリプトを ssh コマンドの代わりに使うことができる。
想定環境
remote2.com に接続するには remote1.com 上で sudo -u user2 ssh しなければならない。remote1.com 上の鍵は local に持ってきてはいけない。
用意するスクリプト
ssh -t -l remote1user -i /path/remote1key remote1.com "sudo -u user2 ssh $@"
chmod +x /path/ssh_helper で実行可能にしておく。
通常の ssh ログインができるか確認。
local:~$ /path/ssh_helper remote2.com
で user2 として remote2.com に入れればOK。
scp の場合
-S オプションで接続に使うプログラムを指定できる。
local:~$ scp -S /path/ssh_helper srcfile remote2.com:/destpath/file
git の場合
GIT_SSH 環境変数で接続に使うプログラムを指定できる。
local:~$ GIT_SSH=/path/ssh_helper git clone user2@remote2.com:/repos/repo.git
rsync の場合
-e オプションで接続に使うプログラムを指定できる。
local:~$ rsync -e '/path/ssh_helper' ./srcdir remote2.com:/dest/dir
emacs の場合
ヘルパースクリプトは使えない。先ほどと同等のことを | でつなげて実現できる。sudo が絡むとちょっとややこしい。
C-x C-f /ssh:remote1.com|sudo:user2@remote1.com|ssh:remote2.com:/path/to/file
remote1.com に ssh し、remote1.com 上の user2 として、remote2.com に ssh してファイルを開く、という流れ。
ssh config の補足
ProxyCommand 内に書くホストも config 内で定義してしまうことでより簡潔に書くことができる。3段、4段と増えてくる場合はワンライナーではキツイのでそれぞれのホストを Host で定義するのがよい。
ssh がデフォルトで読む ~/.ssh/config に書いているなら特に難しいことはないが、そうでない別の場所の config を -F で読み込んでいる場合は、最初の ssh で読んだ config がずっと使われるわけではないことに注意。ProxyCommand 内の ssh はあくまで別のコマンド実行である。
Host remote2
HostName remote2.com
User remote2user
IdentityFile /path/remote2key
ProxyCommand ssh -F /path/myconf remote1 -W %h:%p
# ProxyCommand 内の ssh でも config ファイルを明示すればよい
Host remote1
HostName remote1.com
User remote1user
IdentityFile /path/remote1key