我經營 homelab 已經幾年了。(之後可能再詳細介紹!)我常常需要 ssh 進入其中一台伺服器。

在家時,我可以直接使用類似這樣的網域名稱:

ssh ahoy.m.example.ca
ssh bread.m.example.ca

我在家裡使用 Split-Horizon DNS 搭配 DNSMasq 設定,因此這些網域只會在家裡解析。

當我外出時,我會使用一台「堡壘」伺服器來 ssh 進入,再跳轉到其他伺服器。它使用「秘密」連接埠。

為了讓 SSH 自動透過堡壘伺服器,我在 ~/.ssh/config 中加入以下設定:

Host *.m.example.ca
    ForwardAgent yes
    User evert
    ProxyCommand ssh -q -W %h:%p -l evert bastion.example.ca -p 6767

bastion.example.ca 會解析到真實 IP(我家裡的 IP)。這帶來的不便之處是,無論我在家裡還是外出,使用上述指令時都會經過堡壘伺服器。

我最近發現了 MatchProxyJump 指令,並拼湊出以下設定:

Match host *.m.example.ca exec "! getent hosts %h >/dev/null"
    ForwardAgent yes
    User evert
    ProxyJump [email protected]:6767

這與之前的設定效果相同,只是只有在 getent hosts %h 指令執行失敗時才會套用此規則。

ProxyJump 是比 ProxyCommand 更簡單的指令。我認為這個功能已經存在一段時間,但我過去十多年來一直從舊設定中複製 ProxyCommand

你可能沒有像我這樣的 DNS 設定,而是使用 .local 網域來存取本地伺服器。如果是這種情況,以下設定也適用,但請注意:

Match host *.local exec "! getent hosts %h >/dev/null"
    HostName %h
    ForwardAgent yes
    User evert
    ProxyJump bastion.example.ca:6767

每次執行時,你的電腦很可能會先在本地網路廣播,尋找該機器。.local / MDNS 在本地使用時也會稍慢一些,而且你已經付出這個代價。ForwardAgent 也可能讓這變得非常危險,因為有人可能偽裝成 target.local 並取得你整個 SSH 金鑰鏈的存取權。所以在這種情況下,也許永遠透過堡壘伺服器並不是最壞的選擇。如果你需要,這個設定適合你:

Host *.local
    HostName %h
    ForwardAgent yes
    User evert
    ProxyJump bastion.example.ca:6767

這會讓每一次對 .local 主機的 SSH 連線都經過堡壘伺服器。