近來,在為公司客戶部署相關DNS系統服務,用于資源排程服務,但是客戶出口缺少公網ip位址,不能友善的去管理這台伺服器,開始想到使用teamviewer做中轉,穿透内網,但是在Centos環境下,照teamviewer官方給出的手冊嘗試安裝多次,未果,始終未能擷取ID号,甚至最後都安裝了圖形gnome環境,嘗試在圖形環境下安裝teamviewer,網絡始終是notReady,最後,隻能放棄使用teamviewer,在公司找了台有公網ip的機器,用ssh反向主動連接配接,也就是常說的端口轉發。
這種方式跟最早網上流行的反彈式遠端控制工具原理類似,像灰鴿子,任我行,Pcshare等等,包括現在很多黑客使用的遠端控制木馬程式都是這種主動連接配接反彈式木馬,“堡壘總是從内部突破容易的多”。
回歸正題,先來實操,最後上原理。
系統環境:
公司主機:extrahost(代指主機名和ip,具有公網ip),使用者名:root ssh端口:2200
客戶伺服器:Intrahost(代指主機名和ip,私網ip做了NAT),使用者名:root ssh端口:2211
ssh用到的參數:
-N:不執行何指令
-f:背景執行
-R:建立反向 tunnel
在客戶的系統中輸入如下指令:
----------------------------------------------------------------------------------------------------------
[root@Intrahost ]# ssh -NfR 2233:localhost:2211 root@extrahost -p 2200
輸入密碼即可
//port2233指綁定遠端主機extrahost端口2233
-------------------------------------------------------------------
在公司管理裝置檢視端口2233是否在監聽狀态,netstat -ant,
如果未成功監聽,請檢查管理裝置防火牆 和sshd是否有相關通路控制
在公司管理主機extrahost輸入如下指令和密碼,登陸到客戶系統intrahost
--------------------------------------------------------------------
[root@extrahost]#ssh [email protected] -p 2233
//即可連接配接到客戶的伺服器上
------------------------------------------------------------------
問題
一.連接配接穩定問題
由于是反向主動連接配接,在會話異常中斷,無法由控制端發起連接配接,我們可以借助幾個工具來幫我們保持會話。
1.使用autossh工具
安裝方法 autossh工具不在linux源中,需要從第三方源下載下傳
位址:http://pkgs.repoforge.org/autossh/ 安裝包有32位和64位,下載下傳根據作業系統去選擇。
使用方法 跟ssh類似,差別autossh需要不斷去檢測ssh連接配接狀态,需要我們使用 -M參數,來指定autossh監聽端口:
---------------------------------------------------------------------------------------
[root@Intrahost]autossh -M 1100 -NfR 2233:localhost:2211 root@extrahost -p 2200
----------------------------------------------------------------------------------------
2.使用nohup指令,截斷挂起信号
用法:Usage: nohup COMMAND [ARG]...
or: nohup OPTION
示例:
------------------------------------------------------------------------------------
[root@Intrahost]nohup ssh -NfR 2233:localhost:2211 root@extrahost -p 2200
來中斷對ssh的挂起信号。
---------------------------------------------------------------------------
3.建議大家使用nohup指令,這種方法可靠性很高,原因稍後闡述,現在我們來編寫腳本使用crond定時任何計劃來保持ssh會話,腳本内容如下。
#!/bin/bash
createTunnel() {
/usr/bin/ssh -NfR 2233:localhost:2211 root@extrahost -p 2200
if [[ $? -eq 0 ]]; then
echo Tunnel to jumpbox created successfully
else
echo An error occurred creating a tunnel to jumpbox. RC was $?
fi
}
/bin/pidof ssh
if [[ $? -ne 0 ]]; then
echo Creating new tunnel connection
createTunnel
fi
添加定時任務計劃,重複執行腳本來判斷通信隧道的建立
-----------------------------------------------------
指令:crontab -e
*/1 * * * * /root/ReverseSsh.sh > tunnel.log 2>&1
别忘了将腳本賦予執行權限
----------------------------------------------------
chmod u+x /root/ReverseSsh.sh
-----------------------------------------------------
鄙人能看到和想到的維持會話的方法,就在這了,歡迎大家分享自己的創新方法。
二、安全性問題
雖然我們坦然的建立了這條tunnel,可是大家忽略了一個東西,就是建立反向連接配接的tunnel時,我們需要輸入對方裝置的密碼,假設我們的裝置因為我們人品的關系,導緻了重新開機,這時,無論再好的保持會話的工具和指令,都沒辦法替你輸入密碼,除非,公司的客戶是你的好朋友或者至少是你信任的人,讓他幫你輸入密碼,很不幸,事情往往超乎我們的想象。
是以,我們需要建立一個腳本,來替我們輸入密碼,并且對腳本進行加密,來防止客戶肆意窺探我們管理裝置的密碼。也有,拿密鑰做認證來免密碼登陸,不建議大家這麼做,這樣雖然友善管理,但同樣意味着客戶可以使用該裝置随意進入我們的管理裝置,這是我們不願意發生的事情,雖然我們的客戶很可愛而且善良和藹可親。
腳本内容如下,我們需要借助自動化工具expect,至于expect是怎樣的套件和工具,具體使用方法,大家可以去查資料學習,這個是我們自動化運維較常用的互動工具,建議大家掌握。
except安裝方法,建議使用yum安裝:
----------------------------------------------
yum -y install expect*
#!/bin/sh
# description:The script file for keepalive ssh session
# Founder broadband interconnection.DE created by John.zhang
# update 20151104
passwd=********
expect -c "
/usr/bin/ssh -NfR 2233:localhost:2211 root@extrahost -p 2200
set timeout 5
expect \"password:\"
send \"${passwd}\r\"
expect eof
"
腳本内容功能實作簡單,大家可以盡情發揮,然後我們對該腳本檔案進行加密,較常用的有三四種,我們這裡推薦大家使用SHC工具,友善安全容易。
詳細的安裝方法大家去網上檢索,這裡簡單飄過,我們隻說使用方法。
下載下傳位址:wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.9b.tgz
下載下傳後,我們進行解包,
tar -xvf shc-3.8.9b.tgz
這個包下到的不是源代碼,是預編譯好的檔案,直接安裝即可make install
使用示例:[root@Intrahost]#shc -r -f ~/ReverseSsh_pass.sh
運作後會生成兩個檔案,ReverseSsh_pass.x 和 ReverseSsh_pass.x.c. 其中sReverseSsh_pass.x是加密後的可執行的二進制程式;用./ReverseSsh_pass.x即可運作,ReverseSsh_pass.x.c是生成ReverseSsh_pass.x的原檔案,建議大家拷貝到自己電腦,從伺服器上删除。并且對該程式添加執行權限,添加到開機啟動。
[root@Intrahost]# vi /etc/rc3.d/S99local
在該檔案下邊寫入我們加密腳本後的程式 /root/ReverseSsh_pass.x,用于開機自啟動。注意這裡是指令行方式,注意啟動級别。
三、原理闡述,大神可忽略。
1.SSH reverse tunnel
如圖,為ssh服務的正向和反向兩種會話連接配接示意圖,正常情況下(正向),我們由用戶端發起會話請求到服務端,使用ssh協定為我們建立起一條連接配接通訊,我們可以将這條連接配接看做是條隧道(tunnel),這樣我就可以使用終端工具來遠端管理我們的伺服器,注意,這裡我們并不是真正意思上打開了終端,而是我們在網絡層上,通過建立起來的隧道來連接配接到終端,是以我們把像使用putty,Securecrt這類工具,建立起連接配接呈現的終端也叫仿真終端。
既然我們建立起這樣一條隧道,那必然每條隧道都有相同的端點,起始端和結束端,而這兩端的端點正是我們的用戶端和服務端,不同的是,正向連接配接是聲明要連接配接的對端ip和端口,而反向連接配接則是由服務端聲明可以連接配接到本機的對端ip和通訊端口。
這裡提醒大家的是,正向連接配接和反向連接配接,建立起隧道的方向是一緻的,都是由用戶端作為起始端建立的通訊隧道,所謂的正向連接配接和反向連接配接取決于服務端在建立隧道的行為,正向連接配接,是被動接受來自用戶端的請求,建立連接配接;而反向連接配接則是由服務端主動請求連接配接,但建立會話連接配接的起始端始終是用戶端。
同樣,弄懂原理後,那麼像Telnet,FTP,甚至是我們用來連接配接windows桌面的RDP,也可以實作反向連接配接,大家可以在網上搜搜具體方法。
2.nohup
剛才我們提到了nohup這個指令,這個了解其實很容易,從字面不難了解禁止挂斷,官方手冊解釋也很簡單,ignoring hangup signals,忽略挂斷信号,個人認為把它解釋為截斷挂斷信号,更好點,nohup實作原理像一個守護程序,但它工作的機制是信号量級的,當我們所運作的程序在異常中斷,或者逾時的時候,會産生中斷信号,來結束該程序,節約資源開銷,nohup原理就是當收到來自針對該程序的中斷信号時,會阻止該信号的發送,進而保持程序的運作不會因為異常情況而中斷。
使用這個指令的優勢很明顯,autossh保持會話的工作原理基本和我們編寫的腳本類似,而nohup工作機制直接是信号量級的,不需要通過執行另外的程式産生信号結果回報,linux的信号機制起源于Unix系統,信号量由軟體産生,程序之間的通訊均由信号完成,是以nohup執行效率和穩定性相比autossh很高,或者說兩個沒有可比性,因為它們實作的方式不一樣。