本文へスキップ
hdknr blog

ProxyJump による多段 SSH

踏み台(bastion)経由の SSH を ProxyJump と -J で短く書き、Match host でプライベート IP 帯にまとめて適用し、ControlMaster で接続を多重化する。ssh -G で解決結果を確かめる

概要

VPC のプライベートサブネットにあるサーバーへ踏み台経由で SSH する設定は、ProxyCommand ssh -W %h:%p bastion や踏み台上の nc を使う古い書き方より、OpenSSH 7.3 で入った ProxyJump(コマンドラインでは -J)で短く書ける。Match host でアドレス帯にまとめて適用すれば、IP が変わる EC2 でも設定を書き換えずに済む。

詳細

完成形

Host bastion
    Hostname 203.0.113.10
    User ec2-user
    # 次の 3 行は Windows ネイティブの OpenSSH では使えない
    ControlMaster auto
    ControlPath ~/.ssh/cp-%C
    ControlPersist 10m

Host app1
    Hostname 172.16.1.10
    User ubuntu

# 接続先エントリより後ろに書く
Match host 172.16.*,!172.16.0.5
    ProxyJump bastion

これで ssh app1 でも ssh 172.16.1.20 でも bastion 経由になる。

ProxyJump と -J

Host ではなく Match host を使う理由

Host はコマンドラインで指定した名前(app1)とだけ照合し、Match host は先に読んだ Hostname で置き換えた後の名前(172.16.1.10)と照合する。

書き方と位置ssh -G app1ssh -G 172.16.1.10
Host 172.16.*ProxyJump なしproxyjump bastion
Match host 172.16.*(接続先エントリより後)proxyjump bastionproxyjump bastion
Match host 172.16.*(接続先エントリより前)ProxyJump なしproxyjump bastion
Match final host 172.16.*(前)proxyjump bastion—

ssh は設定を上から読むので、Match host の行に来た時点で Hostname がまだ読まれていないと app1 のまま照合されて外れる。共通設定を上に書きたいなら、設定をもう一度読み直させる Match final host を使う。

ControlMaster で接続を多重化する

設定意味
ControlMaster auto既存の接続があれば使い回し、なければ新しく張る
ControlPath共有する Unix ドメインソケットのパス。%r@%h:%p だとファイル名に接続先が出るので、見せたくなければハッシュの %C
ControlPersist 10m最後のセッションを閉じても 10 分は接続を保持

2 回目以降は TCP 確立と認証を省けて速くなり、踏み台の TCP 接続本数も減る。Windows ネイティブの OpenSSH は Unix ドメインソケット非対応で使えないが、WSL2 の中なら使える。

ハマりどころ

設定は ssh -G で確かめる

ssh -G app1 | grep -i '^proxyjump'

ssh -G は設定を解決して表示するだけで接続しない。ssh_config は記載順序と照合する名前で結果が変わるので、変えたら接続する前にこれで見る。

関連ページ

ソース記事