ngrok實現(xiàn)內網穿透,讓家里的筆記本也能做服務器

背景

家里淘汰了一臺筆記本,windows系統(tǒng)裝起來很卡,于是裝了個linux系統(tǒng)。這臺筆記本有2G內存,奔騰雙核處理器,配置比我在阿里云上買的ECS高多了,于是想著給它利用起來。研究了一下,發(fā)現(xiàn)ngrok內網穿透能實現(xiàn)這個功能,剛好我也有外網服務器和域名,那就直接開干。

安裝gcc、git和go語言

yum install gcc -y  
yum install git -y
yum install golang -y

源碼編譯

下載源碼

此處從git下載,選擇的是tutumcloud修改過的源碼,解決了部分包無法獲取的問題。也可以在window下下載zip包,然后再上傳至服務器,解壓即可。

git clone https://github.com/tutumcloud/ngrok.git ngrok

生成自簽名證書

我們采用自己的服務器自建ngrokd服務,需要生成自己的自簽名證書,并用該證書編譯一個ngrok客戶端。
生成證書需要配置一個環(huán)境變量NGROK_BASE_DOMAIN,直接在命令行里定義即可,這個域名是一個基礎域名,后面ngrok提供http服務的時候,可以在這個域名前面再加前綴。以ngrok.com的官方服務為例,它提供的服務地址為xxx.ngrok.com,那么它這個NGROK_BASE_DOMAIN變量就為,“ngrok.com”。此處,我用自己的二級域名“ngrok.shawnan.xyz”,后續(xù)提供http服務時,域名為“xxx.ngrok.shawnan.xyz”。
生成簽名的代碼如下,在ngrok目錄執(zhí)行。

cd ngrok
NGROK_DOMAIN="ngrok.shawnan.xyz"
openssl genrsa -out base.key 2048
openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.pem
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr
openssl x509 -req -in server.csr -CA base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt

替換證書

生成完成后需要替換證書,就在當前目錄把編譯要用到的證書替換掉。

cp base.pem assets/client/tls/ngrokroot.crt

編譯

編譯,編譯一個服務端和一個客戶端,如果是在window下使用,就編譯windows的客戶端。

make release-server release-client

// 編譯windows客戶端
GOOS=windows GOARCH=amd64 make release-client  

編譯后會在bin目錄下生成ngrokd和ngrok文件,ngrokd和ngrok文件分別是ngrok的服務端程序和linux平臺下的客戶端程序。如果編譯了windows客戶端,則會生成一個ngrok.exe,是windows下的客戶端程序。
到此處編譯工作就完成了,下面開始啟動服務。

啟動服務

準備工作

準備工作之一就是首先要確定幾個端口,分別是ngrok用來轉發(fā)http、https服務的端口,還有轉發(fā)ssh、ftp等服務的端口,此處我用到了3個,分別是http的8088、https的8443、ssh的8022。此處要記得在linux的防火墻開啟這幾個端口,如果是云服務器,則要配置相應的規(guī)則,否則外網的設備如何也連不進你部署的ngrokd服務。
我們可以在windows下采用telnet命令測試服務器的端口是否已經打開:

telnet xx.xx.xxx.xx 222
// 如果返回類似“SSH-2.0-OpenSSH_7.4”的結果,則222端口就打開了,如果一直是connecting,則該端口就沒打開

此處假設端口已經可用了,下面開始啟動ngrok服務。

啟動ngrokd服務

通過命令行啟動ngrokd服務很簡單,只需要配置幾個參數(shù)即可,httpAddr、httpsAddr分別是ngrok用來轉發(fā)http、https服務的端口,可以自由配置,domain就是你的外網域名。ngrokd 還會開一個4443 端口用來跟客戶端通訊,這個端口也可通過 -tunnelAddr=”:xxx” 指定。

./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="ngrok.shawnan.xyz" -httpAddr=":8088" -httpsAddr=":8443"

nginx映射

服務端啟動完畢之后,還要配置nginx代理。在服務器上面的nginx的配置文件里面增加如下一段:

server {
    listen 80;
    server_name ngrok.shawnan.xyz *.ngrok.shawnan.xyz;

    location / {
        proxy_pass http://127.0.0.1:8088;
        proxy_redirect off;
        proxy_set_header Host $http_host:8088;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Nginx-Proxy true;
        proxy_set_header Connection "";
        proxy_connect_timeout 90;
        proxy_send_timeout 120;
        proxy_read_timeout 120;
    }
}

此處就把ngrok.shawnan.xyz和*.ngrok.shawnan.xyz上的請求都轉發(fā)到了8088上,實現(xiàn)客戶端可以通過xxx.ngrok.shawnan.xyz域名訪問。

啟動客戶端

http服務

linux在ngrok文件(windows在ngrok.exe)的同級目錄新建配置文件,ngrok.config,輸入以下內容(域名改成自己的):

server_addr: "ngrok.shawnan.xyz:4443"  
trust_host_root_certs: false  

然后利用以下命令啟動:

ngrok -config=ngrok.config -subdomain=local 8080

Tunnel Status                 online
Version                       1.7/1.7
Forwarding                    http://local.ngrok.shawnan.xyz:8888 -> 127.0.0.1:8080
Forwarding                    https://local.ngrok.shawnan.xyz:8888 -> 127.0.0.1:8080
Web Interface                 127.0.0.1:4040
# Conn                        0
Avg Conn Time                 0.00ms

啟動后如果正常連接,Tunnel Status會顯示online,這樣就把local.ngrok.shawnan.xyz映射到了你本地的8080端口。
如果連接不上會顯示connecting,超時之后還會顯示reconnecting。

tcp服務

除了http服務,ngrok還可以對tcp服務進行轉發(fā),這樣我們就可以通過轉發(fā)22端口利用SSH把局域網內的linux服務器共享到局域網外面去遠程連接了。
比如把本機的22端口轉發(fā)到外網,還是使用剛才的配置文件,使用如下命令:

ngrok -config=ngrok.config -proto=tcp 22

如果配置文件里面沒有配置端口,ngrok會隨機選擇一個端口進行tcp轉發(fā)。比如將本地的22端口轉發(fā)到了ngrok.shawnan.xyz的34538。

Tunnel Status                 online
Version                       1.7/1.7
Forwarding                    tcp://ngrok.shawnan.xyz:34538 -> 127.0.0.1:22
Web Interface                 127.0.0.1:4040
# Conn                        0
Avg Conn Time                 0.00ms

此時就可以使用域名和端口遠程連接局域網內的linux機器了。

ssh xxx@ngrok.shawnan.xyz -p 34358

完善配置文件

前面ngrok隨機選擇了一個端口對22端口進行轉發(fā),很不方便,每次還需要先看一下端口才能遠程ssh連接。此處如果想自定義tcp轉發(fā)的端口,則需要完善ngrok的配置文件,通過完善配置文件,可以大大簡化運行命令。配置文件前面兩行不變,仍舊是配置服務器地址和禁用TLS加密協(xié)議的證書信任。下面配置管道,可以同時配置多種管道,比如ssh、http、https等。

server_addr: ngrok.moonwalker.me:4443
trust_host_root_certs: false
tunnels:
 ssh:
  remote_port: 1122
  proto:
   tcp: 22
 ftp:
  remote_port: 20
  proto:
   tcp: 20
 ftp2:
  remote_port: 21
  proto:
   tcp: 21
 http:
  subdomain: www
  proto:
   http: 80
   https: 443

配置完成后,可以直接啟動指定的管道或者啟動全部管道。

./ngrok -config ngrok.cfg start ssh
./ngrok -config ngrok.cfg start-all

配置成為服務并設置自啟動

服務端和客戶端都配置完了,但是我們不想每次都輸入這么長的命令,那么就可以借助systemctl來將我們的服務配置成為系統(tǒng)服務并設置自動啟動。此處以Centos7為例,CentOS7的服務systemctl腳本存放在:/usr/lib/systemd/system,在此文件夾下建立ngrok.service文件,內容如下:

[Unit]
Description=ngrok
After=network.target

[Service]
ExecStart=/usr/local/ngrok/bin/ngrokd -tlsKey=/usr/local/ngrok/server.key -tlsCrt=/usr/local/ngrok/server.crt -domain=ngrok.shawnan.xyz -httpAddr=:8088 -httpsAddr=:8443

[Install]
WantedBy=multi-user.target

[Unit]部分主要是對這個服務的說明,內容包括Description和After,Description用于描述服務,After用于描述服務類別。[Service]部分是服務具體運行參數(shù)的設置,此處ExecStart即為服務啟動的命令,[Install]部分是服務安裝的相關設置,可設置為多用戶的。
配置完畢后,使用如下命令分別啟動服務,停止服務,查看狀態(tài)。

systemctl start ngrok.service // 啟動
systemctl stop ngrok.service // 停止
systemctl status ngrok.service // 查看狀態(tài)

使用enable指令可以配置該服務為開機自啟動,這條命令實際上是創(chuàng)建了一個該文件的軟連接到/etc/systemd/system/multi-user.target.wants/ngrok.service。放在/etc/systemd/system下的service都是會開機自啟動的,但是比較規(guī)范的做法是放到/usr/lib/systemd/system,然后再使用systemctl enable設置開機啟動。

systemctl enable ngrok.service

至此,借助ngrok,家里的筆記本也可以作為服務器對外提供服務了。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容