0%

搭建ngrok服务器并配合树莓派进行内网穿透

刚搬家,半个月前重新办理了联通宽带。联通宽带网速挺快的200Mbps,能跑到260兆。
但是有一个很严重的问题,就是没有公网ip!!!
由于本人懒的和联通扯皮,想到自己还有个服务器,就考虑自己弄个内网穿透进来用得了。
于是乎就有了这篇文章。

ngrok编译

go语言开发环境配置

本人服务器环境为阿里云轻量服务器。选用的是ubuntu 16.04系统。
一开始我是使用的apt install golang命令安装的go语言环境。但是系统自带的go语言版本太低了,无法编译ngrok项目。
于是乎要自行安装编译环境。好在go语言的编译环境很容易配置。

打开go语言官网下载链接https://golang.org/dl/
下载对应版本的压缩包,解压并解压压缩包。

1
2
3
wget https://dl.google.com/go/go1.12.1.linux-amd64.tar.gz
#如无法下载可使用国内源
tar -xzvf go1.12.1.linux-amd64.tar.gz -C /usr/local

配置环境变量

1
vi ~/.bashrc

文件结尾添加如下代码

1
2
3
4
5
6
export GOPATH=/opt/gopath
export GOROOT=/usr/lib/go
export GOARCH=386
export GOOS=linux
export GOTOOLS=$GOROOT/pkg/tool
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

使环境变量生效,并查看go语言开发环境是否可用

1
2
3
root@localhost:~# source ~/.bashrc 
root@localhost:~# go version
go version go1.12.1 linux/amd64

下载ngrok源码并设置域名参数

1
2
3
4
git clone https://github.com/inconshreveable/ngrok.git
export NGROK_DOMAIN="ipoi.bid"
#进入源码目录
cd ngrok

生成自签名证书

使用ngrok.com官方服务时,我们使用的是官方的SSL证书。自建ngrokd服务,我们需要生成自己的证书,并提供携带该证书的ngrok客户端。

1
2
3
4
5
6
7
8
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 device.key 2048
openssl req -new -key device.key -subj "/CN=$NGROK_DOMAIN" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key

编译ngrok服务端和客户端

编译ngrok服务端

设定服务端编译参数

1
GOOS=linux GOARCH=amd64

make服务端

1
make release-server

编译成功后,在当前目录的bin子目录下,应该生成了ngrokd文件
接下来测试一下服务端是否可用

1
2
#其中本博客已在使用80和443端口 故修改为10080 10443端口
bin/ngrokd -domain="ipoi.bid" -httpAddr=":10080" -httpsAddr=":10443" -tunnelAddr=":12345"

正常启动情况,屏幕会输出如下类似内容:

1
2
3
4
5
[03:05:48 CST 2019/03/30] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[03:05:48 CST 2019/03/30] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:10080
[03:05:48 CST 2019/03/30] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:10443
[03:05:48 CST 2019/03/30] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:12345
[03:05:48 CST 2019/03/30] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds

接下来Ctrl+C关闭服务端,进行客户端编译。

编译客户端

设定客户端编译参数,因为本客户端使用在树莓派上,故进行如下配置:

1
GOOS=linux GOARCH=arm

进行编译

1
make release-client

编译完成后,在bin/linux_arm目录下会生成ngrok文件。
ngrok文件传入树莓派即可。
接下来测试一下客户端,首先在ngrok相同目录下新建配置文件ngrok.cfg:

1
2
3
#其中端口号和服务端tunnelAddr相同
server_addr: "ipoi.bid:12345"
trust_host_root_certs: false

按照上文启动服务端,然后启动客户端:

1
./ngrok -config=./ngrok.cfg -subdomain=test 80

此时出现如下类似输出即可

1
2
3
4
5
6
7
8
9
ngrok                        (Ctrl+C to quit)

Tunnel Status online
Version 1.7/1.7
Forwarding http://test.ipoi.bid:10080 -> 127.0.0.1:80
Forwarding https://test.ipoi.bid:10080 -> 127.0.0.1:80
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms

服务端后台配置运行

在/etc/systemd/system/目录下创建服务ngrok.service,内容为

1
2
3
4
5
6
7
8
9
[Unit]
Description=ngrok
After=network.target

[Service]
ExecStart=/home/ngrok/ngrok/bin/ngrokd -domain="ipoi.bid" -httpAddr=":10080" -httpsAddr=":10443" -tunnelAddr=":12345"

[Install]
WantedBy=multi-user.target

然后使用命令启动服务即可

1
service ngrok start

客户端后台配置运行

因为本内网穿透主要是使用22端口,还对配置文件进行了一定修改

1
2
3
4
5
6
7
8
9
10
11
server_addr: "ipoi.bid:12345" 
trust_host_root_certs: false
tunnels:
ssh:
remote_port: 10022
proto:
tcp: 22
bak:
remote_port: 10023
proto:
tcp: 10023

设定远程端口10022映射到树莓派22端口,10023端口同理
备注:若同时搭建网站和ngrok服务,请自行研究加上一层nginx的反向代理

然后类似服务端进行服务配置即可 ngrokc.service文件

1
2
3
4
5
6
7
8
9
[Unit]
Description=ngrokc
After=network.target

[Service]
ExecStart=/home/ngrok/ngrok -config=/home/ngrok/ngrok.cfg start-all

[Install]
WantedBy=multi-user.target

然后使用service即可启动服务

1
service ngrokc start