使用SSH代理在本地開發環境調試各種回調
前言背景
相信大家在支付寶、微信、釘釘等各種小程式或支付對接的開發中,經常會遇到服務端回調的問題,至少要求接收回調請求的伺服器有公網IP,以便能收到請求,微信的開發甚至要求回調接口必須是
https
,而本地開發環境往往都是内網環境,甚至連固定ip都沒有,難道每次測試回調内容隻能釋出到測試環境中去測試,有沒有簡單的方法呢?
當然有!答案就是使用SSH代理(或其他類似的proxy代理)。假定釋出應用給公網使用者,肯定得有一台固定ip的公網伺服器吧,甚至還有固定ip的測試環境,利用這台伺服器做ssh server實作代理(Linux伺服器自帶ssh server,windows環境可以安裝ssh server,這裡不贅述了)。
之前我寫過一篇利用SSH代理通路内網資源的文章,如果之前的文章對運維比較有用,那麼本篇的内容展現了ssh對開發的價值。之前的文章
-R
參數不是重點,那麼本篇則是詳解
-R
參數。
-L
參數代表在本地監聽端口,将請求轉發到遠端,而
-R
參數正好相反,在遠端監聽一個端口,将請求轉發到本地。
原理講解
本地必須有openssh client(Linux和Mac OS自帶,windows 10系統目前也自帶,windows低版本作業系統需要自己單獨下載下傳openssh client安裝),一台遠端伺服器,有公網ip,開啟ssh server,用作回調伺服器。
本地需要通過ssh連接配接遠端伺服器,在遠端伺服器上監聽一個端口,将此端口的資料轉發到本地的某個應用端口上,實作将遠端資料代理到本地的作用,大概的示意圖像這樣:
request ----> | remote server | <------------> | local client |
^
ssh通道
這樣的話本地用戶端不需要有固定ip,隻要能ssh連接配接到remote server,就可以讓remote server将request轉發過來,而openssh恰好就提供了這樣的功能,對應的是
-R
參數:
-R [bind_address:]port:host:hostport
-R [bind_address:]port:local_socket
-R remote_socket:host:hostport
-R remote_socket:local_socket
-R [bind_address:]port
按照官方man手冊的叙述,
-R
參數的作用是在遠端伺服器bind一個ip:port(或unix domain socket),監聽請求,并将請求轉發到本地的ip:port(或unix domain socket)上,本質上還是一個反向代理。
是以這個指令就非常容易寫出來(以下指令在本地執行):
ssh -R 9999:101.132.192.36:9999 user@remote
和常見的
ssh user@remote
這種直接連接配接ssh shell的指令相比,添加了一個
-R
參數,代表ssh連接配接成功之後,在遠端伺服器上監聽
101.132.192.36:9999
(注意省略bind_address代表bind環回口),将請求轉發到
101.132.192.36:9999
上(相對于本機的Ip),是以就等于通路了本機
101.132.192.36:9999
上監聽的應用程式。如果不想登入到遠端shell,可以追加
-N
參數,如果不想挂起在前台,可以追加
-f
參數,如果想啟用傳輸壓縮(gzip),還可以追加
-C
參數。更多有用的參數可以參見man手冊
需要注意下
-R
的幾個限制:
- 想bind權限端口(1024以内的端口号),必須以root身份連接配接,普通使用者無權限
-
參數設定為 ,表示随機監聽一個可用的端口port
-
預設為bind_address
,如果為localhost
或空
*
則表示bind所有可用ip,但是注意遠端伺服器的0.0.0.0
必須啟用sshd_config
選項才有權限這麼做GatewayPorts
- 由于ssh是
協定,是以這個代理也隻是TCP
四層反向代理,不能實作TCP
的反向代理UDP
配置
明白這個原理之後,我們就可以在實際應用中實作我們的需求了。由于微信、支付寶、釘釘等絕大多數回調請求都使用
HTTP
協定,這個協定本身是工作在
TCP
協定之上的,是以可以用ssh代理實作代理
HTTP
協定。
對于http請求,其實我們隻要在
sshd_config
啟用
GatewayPorts
選項,去bind
0.0.0.0
就可以将回調請求轉發到本地了,但是考慮到https反向代理,以及其他的一些http預處理需求,實際使用的時候建議前面放一個
Nginx
或其他http proxy server做反向代理,這樣的話就不需要配置
sshd_config
,隻bind 127.0.0.1就夠了。
以我們剛才的配置為例,監聽遠端伺服器的
101.132.192.36:9999
端口,是以很容易寫出Nginx的反向代理配置:
server {
listen 80;
server_name bieryun.com ; location / { proxy_pass http:// 101.132.192.36:9999 ; } }
把域名A記錄指向remote server就行了(比如bieryun.com),這樣回調請求到
http://bieryun.com/aliyunyouhuiquan
就會轉發到本地的
http://101.132.192.36:9999/aliyunyouhuiquan
,于是乎在本地開發環境就可以愉快的調試回調請求了,再也不用反複釋出到測試環境調試那麼麻煩了。
微信端回調要求https,那麼也簡單,使用免費的Let's encrypt證書,或者其他已有的安全證書,配置到Nginx就行了,使得
https://bieryun.com
可以使用就行了,這裡就不再贅述了。
ssh直接做可能會因為網絡閃斷導緻代理失效,如果希望ssh自動重連,可以使用autossh這個小工具,幫我們在ssh斷掉之後自動重連,維持代理隧道的穩定。
autossh的使用也十分簡單,基本相容絕大多數ssh參數,像ssh一樣用就行,比如:
autossh -M 0 -R 9999:192.168.1.10:9999 -C -N
更詳細的用法參考官方文檔或者man手冊即可。
原文位址
http://www.bieryun.com/3871.html