前提
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