SSH Port Forwarding / Agent Forwarding
Posted on Apr 26, 2018 in SSH 設定 by Amo Chen ‐ 3 min read
最近看了 The Black Magic Of SSH / SSH Can Do That? ,深覺對 SSH 的應用超級不熟悉,所以就筆記了一些對日常工作有幫助的用法,希望可以幫助自己也幫助別人。
大部份的人都利用 SSH 進行 UNIX-like 作業系統的遠端管理工具,不過 SSH 也常常用來建立加密連線通道(也就是俗稱的 Tunnel)。 The Black Magic Of SSH / SSH Can Do That? 就提到了幾種 Tunnel 的用法。
Local Port Forwarding
Local Port Forwarding 簡單來說就是可以讓 localhost 的 port 透過 SSH 連到遠端的伺服器,例如有台伺服器(secret.server)被限制只能由特定一台伺服器(remote.server)進行存取,這時候如果我們已經擁有可以透過 SSH 連線到 remote.server 的權限的話,就可以利用 SSH 建立與 remote.server 的 Tunnel,並請 remote.server 將連線要求轉至 secret.server ,這樣就能夠直接連到 secret.server 。
簡單的指令如下:
ssh -L 3306:secret.server:3306 [email protected]
Remote Port Forwarding
也就是俗稱的反向 SSH ,使用的情境通常是有一台伺服器(secret.server)從外網無法連線(例如被防火牆隔絕),但是可以連出外網的情況下,很像一般公司的內部網路配置,此時就可以透過反向 SSH 的方式,先將 secret.server 連線至外網的 remote.server 建立反向 SSH Tunnel ,然後其他人就可以透過 remote.server 連回 secret.server 。簡單來說就是透過雙方都可連線的中間伺服器來達到相連效果。
首先, secret.server 須使用指令連線到 remote.server ,指令如下:
ssh -NfR 2345:localhost:22 [email protected]
接下來只要其他人連線至 remote.server 後,就可以在 remote.server 使用以下指令突破防火牆連線至 secret.server :
ssh your.user.name@localhost
Dynamic Port Forwarding
除了 Tunnel 之外,還可以利用 SSH 架設 SOCKS Server 。通常在公共空間用瀏覽器上網時可以使用這種方式,如此一來連線就可以透過 SSH 加密後並由 remote.server 居中對外溝通,就不怕帳號密碼等機密資訊都被竊聽走。
利用 SSH 建立 SOCKS Server 的指令如下:
ssh -D 8080 [email protected]
接下來就只要到瀏覽器設定 SOCKS Server 就可以使用了。
Executing a command on remote server
最神奇的是透過 SSH 直接執行指令,就只要多加上 – 就可以直接執行後把結果回傳,並不需登入遠端 SSH 伺服器,方便我們把一些調查資料的日常作業寫成腳本。
以下範例是直接在遠端伺服器上執行 hostname
指令:
ssh [email protected] -- hostname
把日誌檔(log)從遠端伺服器 Pipe 回來的範例:
ssh [email protected] -- cat /var/log/apache2/error.log | grep error | tee remote.server.apache2.log
Agent Forwarding
Agent Forwarding 也就是 -A
參數,可以讓你使用本地伺服器的 SSH 金鑰(SSH Key),透過遠端的伺服器(remote.server)轉送,這樣就不需要把重要的金鑰再放一份到 remote.server 。好比說用本地伺服器的金鑰透過 remote.server 連線到 github.com :
ssh -A [email protected] -- ssh [email protected]
Agent Forwarding 可以應用在 ProxyCommand/Bastion Host ,例如連線到 customer.server 都必須透過 remote.server ,同時不把金鑰放在 remote.server 以確保安全:
your host ----SSH---> remote.server ---- SSH ----> customer.server
此外,可以利用設定檔設定 ProxyCommand :
vim ~/.ssh/config
Host customer
Hostname customer.server
User your.user.name.on.customer.server
ForwardAgent yes
Port 22
ProxyCommand ssh [email protected] -p 22 -W %h %p
這樣一來只要輸入以下指令就是直接透過 remote.server 連線到 customer.server 了!
ssh customer
後記:
-nNT
參數:上述的指令都會佔用一個 tty ,其實這是不必要的,如果只是要 Tunnel 功能,可以加上 -nNT
參數,讓 SSH 不要佔用一個 tty 。
範例:
ssh -nNT -L 9000:imgur.com:80 [email protected]
References
https://vimeo.com/54505525
http://tom.scogland.com/blog/2012/07/04/ssh-tricks/
https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Proxies_and_Jump_Hosts