1. 程式人生 > >利用ssh與區域網內主機建立遠端連線實現區域網穿透

利用ssh與區域網內主機建立遠端連線實現區域網穿透

  公司新開發的專案,利用嵌入式linux系統,要求其中的軟體能夠支援遠端升級,個人感覺如果能實現遠端操作會更方便一些,於是在網上搜尋方法,當時的想法是希望能夠找到一種ssh代理服務,能夠實現兩臺不同區域網內電腦可以通過ssh代理伺服器建立遠端連線,可以保證資料的加密性。

  後來在網上找了很多資料,發現找不到這種代理服務,但是同時也發現了另一種解決辦法:ssh埠轉發,其實我感覺就類似於ssh代理服務了,而且利用這種方法還可以翻牆!不過這是另一篇文了,沒想到ssh這麼強大。。。

  下面簡述這種連線方式的工作流程,先做一些假設規定:

     1、我目前使用的公司區域網內電腦稱作電腦A。

     2、需要連線到的遠端嵌入式linux系統稱作電腦B,由於用的3G網路,所以IP地址是不固定的。

     3、ssh埠轉發伺服器,稱作電腦S,要有固定的外網IP地址,現在很多雲伺服器可以選擇,而且有很多免費

           的,你也可以申請個域名繫結上,省的記IP地址。。。

     4、我有伺服器S的某個使用者(稱作user)的私鑰,稱作user_rsa,沒有密碼的。

   正常情況下,我只要利用S_rsa,在A或者B的終端,輸入:ssh -o StrictHostKeyChecking=no -o TCPKeepAlive=yes -o ServerAliveInterval=300 -o ServerAliveCountMax=2 -i S_rsa [email protected]

就可以與伺服器S建立ssh連線,注意上面命令-o選項是為了實現第一次建立連線時避免人工互動,並且會定期傳送資料到伺服器以保持連線,檢測是否掉線,確保可以正常連線後,往下進行。。。

   下面直接給出本流程中需要用到的ssh命令,假設我要用公司電腦A連線遠端電腦B,

    那麼下面的命令就在B上執行:

     ssh -C -f -N -R listen_port:DST_Host:DST_port [email protected]_Host

    命令引數解釋:

     -R  將遠端主機(伺服器)的某個埠轉發到本地端指定機器的指定埠

    -C  壓縮資料傳輸

    -f   後臺認證使用者/密碼,通常和-N連用,不用登入到遠端主機

    listen_port:  遠端主機S上的某個埠

    DST_Host:  B的IP地址,一般是127.0.0.1

    DST_port:  B 的埠號,一般是22

    user:  伺服器S的使用者名稱

    Remote_Host:伺服器的IP地址或者域名

比如我在B電腦上執行:ssh -C -f -N -R 7001:127.0.0.1:22 [email protected]_Host

就是說,要伺服器S監聽埠7001,任何傳送這個埠的資料都會轉發到我的B電腦的22號埠上。

這樣,我只要在A電腦上通過ssh進入伺服器S,然後執行:ssh -p 7001 [email protected] 就可以操作B電腦了,要注意命令中root為B電腦的使用者名稱,localhost表明與自己的埠7001建立連線,因為7001已經對映到B電腦的22號埠上,所以就相當於直接用A電腦連線了B電腦。

結合上述,實際使用中可能是如下的命令:

 B電腦上執行:

ssh -o StrictHostKeyChecking=no -o TCPKeepAlive=yes -o \
ServerAliveInterval=300 -o ServerAliveCountMax=2 \
-i 祕鑰檔案 -C -f -N -R 7001:127.0.0.1:22 [email protected]Remote_Host

建立監聽。

A電腦上執行:

ssh -i 祕鑰檔案 [email protected]Remote_Host

連線伺服器S。

然後在S上執行:

ssh -i 祕鑰檔案 -p 7001 [email protected]

連線B電腦。

上面是實際使用時的流程,但是想要時刻能用A電腦連線B電腦,可能還要一些判斷B電腦掉線之類的指令碼,下面是我自己的指令碼,放到電腦B上,開機自動執行(之前沒用過shell指令碼,亂寫的):

#!/bin/sh

exit=1

while test $exit -eq 1
do
        if test $(ps | grep -c 'ssh.*-o StrictHostKeyChecking=no') -eq 1;then
                 /usr/local/bin/ssh -v -o StrictHostKeyChecking=no -o TCPKeepAlive=yes \
-o ServerAliveInterval=120 -o ServerAliveCountMax=2 \
-i /etc/init.d/joyo_rsa -C -f -N -R 10001:127.0.0.1:22 [email protected]
        fi
        sleep 60
done

實際測試時,有可能伺服器正在監聽某個埠,然後指令碼又執行一次,讓伺服器監聽同樣的埠,這種情況下還是會建立ssh連線,但是伺服器會返回監聽埠失敗,這時可以選擇性的結束伺服器上的ssh程序。

  2017.12.12更新:

   重新修改編譯了sshd服務端的原始碼,實現了可以選擇性的允許哪些客戶端建立連線,減小的伺服器端的壓力,詳情請見下面連線:http://www.xiezhaoxuan.top/blog/6/