筆者在工作中遇到此場景,如下兩條網絡限制下,總部如何訪問分公司內部web服務器?
- dmz服務器可以訪問總部外網服務器22端口,不可以訪問web服務器;
- web服務器不可訪問公網,但是到dmz網絡無限制。

初看需求,我們第一個想到的肯定是內網端口映射到公網,或者vpn,但是不修改網絡策略情況下很難實現。有沒有別的方法呢,我們繼續從純網絡角度分析現有條件。
網絡通信是雙向的,有請求,有回應,就是我們俗稱的“通”。dmz可以訪問外部22端口,代表請求,回包兩個通信通道都是通暢的,我們是否可以借助回包通道,從外部發起到內部的反向訪問呢?答案當然是有的,我們來試一試,需要ssh工具。
我們在dmz執行如下命令。
[root@dmz]# ssh -f -N -g -R 6606:10.1.1.1:80 [email protected]
-f:代表后臺運行程序
-N:表示使用遠程端口轉發創建ssh隧道
-g:監聽本機所有IP地址
-R,表示使用遠程端口轉發創建ssh隧道
命令結合起來什么意思呢,我們使用root用戶遠程連接到115.100.100.100,并且遠程主機監聽6606端口,當訪問此端口時,會跳轉到dmz的80端口。此過程會使用到ssh隧道。dmz運行之后,總部服務器的已經有了端口監聽。
[root@center]# netstat -tunlp | grep 6606
tcp 0 0 127.0.0.1:6606 0.0.0.0:* LISTEN 8616/sshd: root
我們在總部服務器嘗試端口提示拒絕,代表網絡已經打通了,但是dmz服務器并沒有監聽80端口,所以報端口拒絕。
[root@center]# telnet 127.0.0.1 6606
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
如法炮制,再把web服務器到dmz的網絡反向打通,dmz服務器訪問本地80端口時將跳轉到web服務器的80端口。
[root@web]# ssh -f -N -g -R 80:10.1.1.1:80 [email protected]
再次到總部服務器測試訪問就能通信了。
[root@center]# telnet 127.0.0.1 6606
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
我們最后從網絡角度來回顧數據包的的轉發過程。
從總部服務器看到如下信息。
#dmz服務器以115.100.100.101:29493作源,訪問本地22端口,建立了tcp連接。
[root@center]# ss | grep 115.
tcp ESTAB 0 0 172.16.1.1:22 115.100.100.101:29493
[root@center]# netstat -tpna | grep 115.
tcp 0 0 172.16.1.127:22 101.230.91.53:29493 ESTABLISHED 8555/sshd: root
#本地端口也對應到了進程號8616
[root@center]#netstat -tunlp | grep 6606
tcp 0 0 127.0.0.1:6606 0.0.0.0:* LISTEN 8616/sshd: root
[root@center]# ps -ef | grep 8616
root 8616 8555 0 Dec03 ? 00:01:04 sshd: root.
當總部服務器訪問127.0.0.1:6606時,網絡連接信息如下。
雙向通道已經建立
[root@center]# ss | grep 6606
tcp ESTAB 0 0 127.0.0.1:6606 127.0.0.1:51158
tcp ESTAB 0 0 127.0.0.1:51158 127.0.0.1:6606
我們最后用圖片來展示最終網絡轉發過程。

dmz發起ssh連接到總部服務器,并且遠程端口轉發。遠程服務器訪問轉發端口時,數據將封裝到回包通道,由于ssh本身加密,外部網絡無法知曉網絡交互邏輯,從而實現反向訪問。
原文鏈接:
https://zhuanlan.zhihu.com/p/444319023