ngrok 應用在.net core 實作 === ###### tags: `課程教案` ## ngrok online ## 說明 ### 自建ngrok服務支援https訪問 :::info 前言 ::: 最近從事第三方平臺代小程式實現業務開發,很多業務互動請求需要https,本地除錯開發實現不了,不可能把部署到生產伺服器除錯,那又很不方便。我參考網上很多教程,很多不完整,不繫統。我於是整理出完整教程當備用。 :::info 專業術語 ::: 內網穿透,又叫NAT穿透,是計算機用語,翻譯過來就是 你的電腦可以直接被你朋友訪問。 通常我們的電腦是無法自己被訪問的。因為我們的電腦缺少自己的獨立的ip地址。現在ip稀缺,電信運營商已經不會隨便分配固定ip給個人。 通常實現內網穿透,是通過路由器上埠對映來實現的。但是路由器通常不是每個人都有許可權可以訪問和設定,而且可能存在多級路由器較為複雜的網路結構。埠對映也無法實現。這就需要ngrok來實現了。 :::info 原理 ::: ngrok 建立一個隧道,將主機A的http請求 傳遞給 主機B,從而實現內網穿透。 ngrok分為client端(ngrok)和服務端(ngrokd), ![](https://i.imgur.com/RZTrCmz.png) 實際使用中的部署如下: ![](https://i.imgur.com/6mCbZly.png) 圖中內網主機上安裝客戶端。 公網主機 安裝服務端。 client public 則代表 訪問你電腦的使用者或者朋友。 現在都雲時代,各種服務都能找到提供商。內網穿透也是如此。ngrok服務端相當麻煩,如果你只是簡單的穿透,又不是什麼敏感資訊,可以找到很多 服務提供商。例如 https://ngrok.com/ 下載客戶端根據你的個人電腦系統下載匹配的客戶端。下載地址: https://ngrok.com/download ![](https://i.imgur.com/2XkCQUr.png) :::info 啟動 ::: > 如果 http://localhosts:4040 -> 代理成 https://xx.xxx.ngrok.com/ ``` ngrok http 4040 ``` > 如果 https://xx.xxx.ngrok.com/ -> https://xx.maxaiot.ngrok.com/ 要付錢 20US/Month = 20*30*12 = 7200元/年 ### Linux Client 版安裝程式 ``` cd ~/ wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz tar -C /usr/lib -xzf ngrok-v3-stable-linux-amd64.tgz /usr/lib/ngrok config add-authtoken 2Dylrflb3y4PQxlIYNOiWodujZf_ua5E63cRYsTaXMDtJU1r ``` ## Ngrok Server 建置 :::warning 以下失敗文件參考就好 ::: 實ngrok 可以自己架說, 但我架了半天, 失敗。 github 說的了, github 上面是ngrok 1.x 不在維護有很多bug , 難怪建不起來,唉..跟openalpr opensource 一樣狀況。 :::info 說明 ::: 從外部要訪問內網部署的服務。大概步驟也比較簡單(6步): 1. LXC(TWS,GCP...提供Public IP 並可以設定services port的雲端簡稱) 。 2. dns server 將domain 指到此LXC(Public IP); 3. LXC ngrok原始碼(ngrokd 服務) 4. 生成證書; 5. 編譯生成主機服務(最終生成二進位制檔案ngrokd,啟動跑在LXC主機上); 6. 編譯生成客戶端服務(最終生成二進位制檔案ngrok,要從LXC主機複製到內網真正提供服務的主機上,並啟動)。ngrok伺服器,實現內網穿透的本質,就是部署在公網端的ngrokd服務和部署在客戶端的ngrok服務相互通訊轉發指令和資料。 我的公網伺服器端和客戶端都是Ubuntu系統,以下有公網IP域名的稱為服務端,內網稱為客戶端。 ### 安裝 ngrok V2 apt install gccgo-go wget https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz tar -C /usr/lib -zxvf go1.8.linux-amd64.tar.gz rm go1.8.linux-amd64.tar.gz sudo vi /etc/profile sudo echo export GOROOT=/usr/lib/go >> /etc/profile sudo echo export GOPATH=$GOROOT/bin >> /etc/profile sudo echo export PATH=$PATH:$GOPATH >> /etc/profile source /etc/profile sudo apt install snapd -y sudo snap install ngrok wget htps://coding.net/u/sfantree/p/self_use_OSS/git/raw/master/source/ngrok.tar.gz tar -C /usr/lib -zxvf ngrok.tar.gz cd ngrok ### 參數說明 * **GOROOT** GoLang 程式的路徑 * **GOPATH** GoLang 應用程式的路徑 ### 安裝 ngrok V1 沒成功 ``` echo ---------------------------------安裝環境應用程式 cd ~/ sudo apt-get update && sudo apt-get upgrade -y sudo apt-get install openssh-server ssh openssl git curl mercurial make binutils bison gcc build-essential -y echo ---------------------------------安裝 golang sudo add-apt-repository ppa:longsleep/golang-backports sudo apt update -y sudo apt install golang-go -y wget -c https://go.dev/dl/go1.19.linux-amd64.tar.gz rm -rf /usr/lib/go tar -C /usr/lib -xzf go1.19.linux-amd64.tar.gz rm go1.19.linux-amd64.tar.gz echo export GOROOT=/usr/lib/go >>~/.bashrc echo export GOPATH=/usr/lib/go/bin >>~/.bashrc echo export PATH=$GOPATH:$PATH >>~/.bashrc echo 記得將ngrok.maxaiot.com 改成計劃要用的domain哦 echo export NGROK_DOMAIN="ngrok.maxaiot.com" >>~/.bashrc source ~/.bashrc cd /usr/lib/go/src GOOS=linux GOARCH=amd64 CGO_ENABLED=0 ./make.bash cp /usr/lib/go/bin/go /usr/bin sudo sed -i "s/RANDFILE/#RANDFILE/g" /etc/ssl/openssl.cnf ``` 要重開ssl 目前只有重開機才行, 沒找到法 ``` echo --------------------------------安裝ngrok cd /usr/lib git clone https://github.com/inconshreveable/ngrok.git cd ngrok echo --------------------------------生成證書: openssl genrsa -out rootCA.key 2048 openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -out rootCA.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 rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 5000 cp rootCA.pem assets/client/tls/ngrokroot.crt cp server.crt assets/server/tls/snakeoil.crt cp server.key assets/server/tls/snakeoil.key GOOS=linux GOARCH=amd64 make release-server release-client ``` ### 移除golang ### Error1 ``` GOOS="" GOARCH="" go get github.com/jteeuwen/go-bindata/go-bindata ../go1.4/src/sync/pool.go:8:2: C source files not allowed when not using cgo or SWIG: atomic_amd64x.c defs.c float.c heapdump.c lfstack.c malloc.c mcache.c mcentral.c mem_linux.c mfixalloc.c mgc0.c mheap.c msize.c os_linux.c panic.c parfor.c proc.c runtime.c signal.c signal_amd64x.c signal_unix.c stack.c string.c sys_x86.c vdso_linux_amd64.c Makefile:22: recipe for target 'bin/go-bindata' failed make: *** [bin/go-bindata] Error 1 ``` #### 問題1:server.pem 沒有完成 go-bindata被安装到了$GOBIN下了,go编译器找不到了。修正方法是将$GOBIN/go-bindata拷贝到当前ngrok/bin下。 cp /home/ubuntu/.bin/go14/bin/go-bindata ./bin cp /usr/lib/ngrok/src/github.com/jteeuwen/go-bindata /usr/lib/ngrok/bin ### go build 環境變數怎麼設定 在執行 go build . 的時候,會讀取讀 GO 的環境變數 GOOS 和 GOARCH 來決定要產生什麼樣平台的執行檔案。 如下圖所示,我執行 go env 來查看環境變數, 可以看到 GOARCH=amd64,GOOS=windows,這表示我執行 go build . 的時候會產生 windows 64位元 作業系統的執行檔案。 >go env ![](https://i.imgur.com/TP1CWfR.png) ### Error2 : golang有問題 >go env 不會出現資訊 ``` GOOS="" GOARCH="" go get github.com/jteeuwen/go-bindata/go-bindata /bin/sh: 1: go: not found Makefile:22: recipe for target 'bin/go-bindata' failed make: *** [bin/go-bindata] Error 127 ``` ### Error3 : 使用 1.11.4 版本的 golang 然後就可以了 >如果编译报以下错,安装最新的go和配置GOPATH ``` package github.com/rivo/uniseg: found packages uniseg (doc.go) and main (gen_breaktest.go) in /usr/lib/ngrok/src/github.com/rivo/uniseg github.com/gorilla/websocket (download) Makefile:8: recipe for target 'deps' failed make: *** [deps] Error 1 ``` ## 接下來就可以編譯了: GOOS=Windows GOARCH=amd64 make release-server release-client 編譯完成之後這只是linux的版本,如果要在windows下使用,需要交叉編譯: > cd /root/.gvm/gos/go1.4/src GOOS=windows GOARCH=amd64 CGO_ENABLED=0 ./make.bash > 編譯windows版本的ngrok > cd ~/ngrok GOOS=windows GOARCH=amd64 make release-server release-client cd /usr/local/ git clone https://github.com/inconshreveable/ngrok.git export GOPATH=/usr/local/ngrok/ export NGROK_DOMAIN="ngrok.maxaiot.com" cd ngrok openssl genrsa -out rootCA.key 2048 openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -out rootCA.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 rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 5000 cp rootCA.pem assets/client/tls/ngrokroot.crt cp server.crt assets/server/tls/snakeoil.crt cp server.key assets/server/tls/snakeoil.key vi /usr/local/ngrok/src/ngrok/log/logger.go curl -s -S -L https://gist.github.com/bradw2k/e776d26df44f59adfe44#file-install-go1-4-amd64-sh > install-go1-4-amd64.sh ## 更改ngrok 域名 ``` export GOPATH=/usr/local/ngrok export NGROK_DOMAIN="ngrok.maxaito.com" ``` ## 域名生成証書 ``` openssl genrsa -out rootCA.key 2048 openssl req x-x509 -new -key rootCA.key -subj "/CN=#NGROK_DOMAIN" openssl grenrsa -out server.kye 2048 opoenssl req -new -key server.key -sub "/CN=$NGROK_DOMAIN" -out server.csr openssl x509 -req in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 5000 ``` ## 複制cert到指定位置 ``` cp rootCA.pem assets/client/tls/ngrokroot.crt cp server.crt assets/server/tls/snakeoil.crt cp server.key assets/server/tls/snkeoil.key ``` ## 編譯 ``` make release-server release client GOOS=windows GOARCH=amd64 make release-client ``` ## 運用行Server ``` ./ngrokd -tlskey="../assets/server/tls/snakeoil.key" -tlsCrt="assets/server/tls/snakeoil.key" -tlsCrt="../assets/server/tls/sankeoil.crt" -domain="ngrok.maxaiot.com" ``` ## 運行用戶端 ``` server_addr: "ngrok.maxaiot.com" trust_host_root_certs:false ngrok -subdoman ngrok.maxaiot.com -config=ngrok.cfg port ``` ## golang 手動安裝 1.7.4 比較舊的版本 ``` wget -c https://storage.googleapis.com/golang/go1.7.4.linux-amd64.tar.gz tar -C /usr/local -zxvf go1.7.4.linux-amd64.tar.gz ``` ### golang 1.4 ``` wget -c https://go.dev/dl/go1.4.linux-amd64.tar.gz && tar -C /usr/lib -zxvf go1.4.linux-amd64.tar.gz && rm go1.4.linux-amd64.tar.gz cd /usr/lib mv go go1.4 echo export GOROOT=/usr/lib/go1.4 >>~/.bashrc echo export GOPATH=$HOME/go >>~/.bashrc echo export PATH=$GOPATH/bin:$GOROOT/bin:$PATH >>~/.bashrc source ~/.bashrc cd /usr/lib/go1.4/src ``` ### golang 1.10.2 安裝 ``` sudo add-apt-repository ppa:longsleep/golang-backports sudo apt update -y sudo apt install golang-go -y ```