雲服務器通過內網穿透的方式ssh訪問內網服務器
背景
買了一台雲服務器,了解到可以通過外部服務器連接到公司內部服務器。
為了加快辦公的效率,配置了一下。
以Ubuntu為例。
原文(有刪改):https://www.cnblogs.com/kwongtai/p/6903420.html
描述一下目前的機器狀況
機器 | OS | IP | ssh端口號 | 用戶名 | 備注 |
---|---|---|---|---|---|
A | Ubuntu 18.04 | 192.168.168.1 | 22(默認是22) | inuser | 目標服務器,處於內網 |
B | Ubuntu 16.04 | 123.45.67.890 | 22(默認是22) | outuser | 外網服務器,相當於橋梁的作用 |
處於內網 A 機器能夠訪問到 處於外網的B機器。我們現在要實現:處於內網 A 機器能夠被 處於外網的B機器訪問到
做法
通俗地說:就是在機器A上做到B機器的反向代理;然后在B機器上做正向的代理實現本地端口的轉發
安裝ssh、autossh
每台都要安裝ssh的客戶端。
sudo apt-get install -y openssh-server autossh
使用到的ssh參數
反向代理
ssh -fCNR
正向代理
ssh -fCNL
-f 后台執行ssh指令
-C 允許壓縮數據
-N 不執行遠程指令
-R 將遠程主機(服務器)的某個端口轉發到本地端指定機器的指定端口
-L 將本地機(客戶機)的某個端口轉發到遠端指定機器的指定端口
-p 指定遠程主機的端口
在內網設備中建立反向代理
首先在A(內)上面操作:
建立A機器到B機器的反向代理,具體指令為:
ssh -fCNR [B機器IP或省略]:[B機器端口]:[A機器的IP]:[A機器端口] [登錄B機器的用戶名@服務器IP]
在這里我使用了雲服務器的6666端口,以及內網機器的22端口,按照上面的指令就是這樣子的操作:
## 內網的ssh端口
INSIDE_PORT=22
## 外網的ssh端口
OUTSIDE_PORT=22
## 公共轉發端口
COMMON_MATCH=6666
## 公共監聽端口
COMMON_LISTEN=6667
## 外網賬號
OUTSIDE_USER=outuser
## 外網IP
OUTSIDE_ADDR=123.45.67.890
## 代表內網的端口(轉發端口)
INSIDE_REPORT=1234
## 內網賬號
INSIDE_USER=inuser
ssh -p ${OUTSIDE_PORT} -fCNR ${COMMON_MATCH}:localhost:${INSIDE_PORT} ${OUTSIDE_USER}@${OUTSIDE_ADDR}
檢驗是否已經啟動了可以使用ps aux | grep ssh
指令來查看:
$ ps -aux | grep ssh
xx 41476 0.0 0.0 50216 4300 ? Ss 14:05 0:00 ssh -p 22 -fCNR 6666:localhost:22 outuser@123.45.67.890
在外網設備中建立正向代理
建立B機器的正向代理,用來做轉發,具體指令為
ssh -fCNL [A機器IP或省略]:[A機器端口]:[B機器的IP]:[B機器端口] [登錄B機器的用戶名@B機器的IP]
按照第3那里輸入的指令,這里的B機器的端口和上面的B機器的端口是一致的,端口1234的也是B機器的。
## 內網的ssh端口
INSIDE_PORT=22
## 外網的ssh端口
OUTSIDE_PORT=22
## 公共轉發端口
COMMON_MATCH=6666
## 公共監聽端口
COMMON_LISTEN=6667
## 外網賬號
OUTSIDE_USER=outuser
## 外網IP
OUTSIDE_ADDR=123.45.67.890
## 代表內網的端口(轉發端口)
INSIDE_REPORT=1234
## 內網賬號
INSIDE_USER=inuser
ssh -p ${OUTSIDE_PORT} -fCNL "*:${INSIDE_REPORT}:localhost:${COMMON_MATCH}" localhost
檢驗是否已經啟動了可以使用ps aux | grep ssh
指令來查看:
$ ps -aux | grep ssh
xxx 7828 0.0 0.1 47772 2576 ? Ss 14:08 0:00 ssh -p 22 -fCNL *:1234:localhost:6666 localhost
在此1234端口為本地轉發端口,負責和外網進行通信,並將數據轉發的7280這個端口,實現了可以從其他機器訪問的功能。
同時,*號表示可以接受任何IP的訪問。
正常登錄
至此我們都配置好了AB機器,那么我們就可以從一部外網的電腦登錄到內網里面去啦。
鑒於我目前的電腦在內網,而服務器都是外網的(也就是配置的B機器),所以可以通過B機器連接到我內網的A中,具體指令為:
## 內網的ssh端口
INSIDE_PORT=22
## 外網的ssh端口
OUTSIDE_PORT=22
## 公共轉發端口
COMMON_MATCH=6666
## 公共監聽端口
COMMON_LISTEN=6667
## 外網賬號
OUTSIDE_USER=outuser
## 外網IP
OUTSIDE_ADDR=123.45.67.890
## 代表內網的端口(轉發端口)
INSIDE_REPORT=1234
## 內網賬號
INSIDE_USER=inuser
ssh -p ${INSIDE_REPORT} ${INSIDE_USER}@${OUTSIDE_ADDR}
我們在上面指定了1234端口為轉發端口,故用1234端口登錄,然后inuser是內網A機器的用戶名,例如:
ssh -p 1234 inuser@123.45.67.890
增強穩定性
不幸的是,單單通過ssh實現的反向鏈接會因為超時而關閉,如果關閉了那從外網連通內網的通道就無法維持了,為此我們需要另外的方法來提供穩定的ssh反向代理隧道。
設置彼此免密碼登錄
內網免登陸到外網
ssh-geygen
$ ssh-keygen # 外加三個回車使用默認設置
Generating public/private rsa key pair.
Enter file in which to save the key (~/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ~/.ssh/id_rsa.
Your public key has been saved in ~/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:yozmNhbF3+pQ1OYn9TFzl8pCEKBOSEbIMo9oudlH6Fw schips@canton
The key's randomart image is:
+---[RSA 2048]----+
|. o+ ..o. |
|ooo . . .. .|
|o+...+ . o.. +.o|
|oo..oEo. o.....=.|
|. * oo .S.o..o. |
| o +.= o. .o. |
| +.= . |
| o+ .. |
| o.. .. |
+----[SHA256]-----+
將公鑰復制到外網機器
在內網的機器A上面執行:
## 內網的ssh端口
INSIDE_PORT=22
## 外網的ssh端口
OUTSIDE_PORT=22
## 公共轉發端口
COMMON_MATCH=6666
## 公共監聽端口
COMMON_LISTEN=6667
## 外網賬號
OUTSIDE_USER=outuser
## 外網IP
OUTSIDE_ADDR=123.45.67.890
## 代表內網的端口(轉發端口)
INSIDE_REPORT=1234
## 內網賬號
INSIDE_USER=inuser
ssh-copy-id -p ${OUTSIDE_PORT} ${OUTSIDE_USER}@${OUTSIDE_ADDR}
按照之前我設定的端口,這個指令就是如下
ssh-copy-id outuser@123.45.67.890
例如:
$ ssh-copy-id -p 22 outuser@123.45.67.890
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/inuser/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
outuser@123.45.67.890's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -p '22' 'outuser@123.45.67.890'"
and check to make sure that only the key(s) you wanted were added.
外網免登陸到內網
ssh-geygen
$ ssh-keygen # 外加三個回車使用默認設置
Generating public/private rsa key pair.
Enter file in which to save the key (~/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ~/.ssh/id_rsa.
Your public key has been saved in ~/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:yozmNhbF3+pQ1OYn9TFzl8pCEKBOSEbIMo9oudlH6Fw schips@canton
The key's randomart image is:
+---[RSA 2048]----+
|. o+ ..o. |
|ooo . . .. .|
|o+...+ . o.. +.o|
|oo..oEo. o.....=.|
|. * oo .S.o..o. |
| o +.= o. .o. |
| +.= . |
| o+ .. |
| o.. .. |
+----[SHA256]-----+
將公鑰復制到內網機器
根據正常登錄的命令,參考ssh-copy-id
即可
上文中使用到的是:
ssh -p 1234 inuser@123.45.67.890
那么,結合內網穿透的實現
## 內網的ssh端口
INSIDE_PORT=22
## 外網的ssh端口
OUTSIDE_PORT=22
## 公共轉發端口
COMMON_MATCH=6666
## 公共監聽端口
COMMON_LISTEN=6667
## 外網賬號
OUTSIDE_USER=outuser
## 外網IP
OUTSIDE_ADDR=123.45.67.890
## 代表內網的端口(轉發端口)
INSIDE_REPORT=1234
## 內網賬號
INSIDE_USER=inuser
# ssh -p ${INSIDE_REPORT} ${INSIDE_USER}@${OUTSIDE_ADDR}
ssh-copy-id -i .ssh/id_rsa.pub -p ${INSIDE_REPORT} ${INSIDE_USER}@${OUTSIDE_ADDR}
實際上就是:
ssh-copy-id -i .ssh/id_rsa.pub -p 1234 inuser@123.45.67.890
用autossh為內網建立穩定隧道到外網
來看看具體的autossh的指令為
## 內網的ssh端口
INSIDE_PORT=22
## 外網的ssh端口
OUTSIDE_PORT=22
## 公共轉發端口
COMMON_MATCH=6666
## 公共監聽端口
COMMON_LISTEN=6667
## 外網賬號
OUTSIDE_USER=outuser
## 外網IP
OUTSIDE_ADDR=123.45.67.890
## 代表內網的端口(轉發端口)
INSIDE_REPORT=1234
## 內網賬號
INSIDE_USER=inuser
autossh -M ${COMMON_LISTEN} -p ${OUTSIDE_PORT} -fCNR ${COMMON_MATCH}:localhost:${INSIDE_PORT} ${OUTSIDE_USER}@${OUTSIDE_ADDR}
autossh
的參數與ssh的參數是一致的,但是不同的是,在隧道斷開的時候,autossh會自動重新連接而ssh不會。
另外不同的是我們需要指出的-M參數,這個參數指定一個端口,這個端口是外網的B機器用來接收內網A機器的信息,如果隧道不正常而返回給A機器讓他實現重新連接。
autossh -M 6667 -fCNR 6666:localhost:22 outuser@123.45.67.890
# 相當於
ssh -fCNR 6666:localhost:22 outuser@123.45.67.890
注,如果想殺死autossh
,那么使用kill -9
命令。
配置autossh開機自啟動
略,參考:ubuntu 18.04 設置開機自啟
只要把下列的內容添加到一個能夠開機啟動的腳本即可,注意添加執行權限chmod +x
:
#!/bin/sh
## 內網的ssh端口
INSIDE_PORT=22
## 外網的ssh端口
OUTSIDE_PORT=22
## 公共轉發端口
COMMON_MATCH=6666
## 公共監聽端口
COMMON_LISTEN=6667
## 外網賬號
OUTSIDE_USER=outuser
## 外網IP
OUTSIDE_ADDR=123.45.67.890
## 代表內網的端口(轉發端口)
INSIDE_REPORT=1234
## 內網賬號
INSIDE_USER=inuser
killall -9 autossh >/dev/null 2>&1
autossh -M ${COMMON_LISTEN} -p ${OUTSIDE_PORT} -fCNR ${COMMON_MATCH}:localhost:${INSIDE_PORT} ${OUTSIDE_USER}@${OUTSIDE_ADDR}