如果你對NodeJs系列感興趣,歡迎關注微信公衆號:前端神盾局 或 github NodeJs系列文章
身爲一枚合格的搬磚工程師,筆者經常需要登錄服務器去查看日誌或者部署應用,ssh
也隨之成爲最常用的linux命令之一。本文主要是對SSH的概念和用法做一些簡單的梳理,大神請繞道。
什麼是SSH
SSH是一種加密的網絡傳輸協議,可在不安全的網絡中爲網絡服務提供相對安全的傳輸環境。任何網絡服務都可以通過SSH實現安全傳輸,但日常使用最多的還是遠程登錄服務器。
// 登錄一臺端口爲22,用戶名爲username,ip地址爲xx.xx.xx.xx的遠程主機
ssh -p 22 [email protected]
早先,互聯網通信基本是裸奔的(明文傳輸),這使得內容很容易被竊取或監聽。1995年,芬蘭學者Tatu Ylonen設計了SSH協議,將登錄信息全部加密,成爲互聯網安全的一個基本解決方案,迅速在全世界獲得推廣,目前已經成爲Linux系統的標準配置。
那SSH是如何實現加密的呢?整個過程如下:
- 遠程主機收到用戶的登錄請求,把自己的公鑰發給用戶;
- 用戶使用這個公鑰,將登錄密碼加密後,發送回來。
- 遠程主機用自己的私鑰,解密登錄密碼,如果密碼正確,就同意用戶登錄。
當然這個過程並不是萬無一失的,依舊存在“中間人攻擊”的風險,具體可參考阮一峯老師的文章:SSH原理與運用(一):遠程登錄
本地端口轉發
在實際項目中,筆者經常遇到這樣的一種情況:由於測試環境中數據庫和開發數據庫的沒有同步,導致筆者無法很好的復現bug。
那有同學問,爲什麼不直接連到測試服務器呢?原因很簡單,連不上。測試環境數據庫服務器並沒有對外開放。
所以剛開始的時候,筆者爲此相當苦惱,每次需要驗證數據的時候,都要先把測試環境中數據導出再導入到開發環境中,這樣一趟下來十幾分鍾過去了...
那有什麼方法可以連到測試數據庫呢?
有的,使用ssh本地端口轉發
先來描述一下場景,host1(106.xx.xxx.xx)是遠程主機,是可以對外訪問的;host2是內網主機(10.xx.xxx.x 安裝了mongo數據庫),只能通過host1訪問,無法連接外網。
我們需要兩個步驟實現本地端口轉發
- 創建本地服務器
const http = require('http');
const server = http.createServer(function(req,res){});
server.listen(5000);
這裏我們創建了一個端口爲5000的本地服務
- ssh轉發
ssh -L 5000:10.xx.xxx.x:27017 [email protected]
命令中的L參數一共接受三個值,分別是"本地端口:目標主機:目標主機端口",它們之間用冒號分隔。這條命令的意思,就是指定SSH綁定本地端口5000,然後指定host1將所有的數據,轉發到目標主機host2的27017端口。
運行命令,隨後我們在瀏覽器中打開http://localhost:5000
,可以看到頁面顯示如下:
It looks like you are trying to access MongoDB over HTTP on the native driver port.
這表示我們連接成功~
ssh
命令挺長的,還有各種ip地址...有沒有簡化版呢?
好吧~我們可以使用tunnel-ssh改造一下
const tunnel = require('tunnel-ssh');
const server = tunnel({
keepAlive: true,
// host1
host: '106.xx.xxx.xx',
username: 'superTerrorist',
password: 'xxxx',
port: 22,
// 內網主機 host2
dstHost: '10.xx.xxx.x',
dstPort: 27017,
// 本地端口
localPort: 5000,
},async function(error,server){
if(error){
console.log(error);
return;
}
console.log('ssh tunnel connected');
});
這裏我們使用了第三方包tunnel-ssh實現了本地轉發的功能,每次我們只要使用node script.js
即可,這比使用ssh
清爽多了。如果各位同學還有更好的方法,歡迎在此留言討論
參考