ngork是提供内网穿透的一个工具。要使用这个的原因大致是因为装着Gentoo的那台电脑太重了,不方便带到宿舍外去,但是在宿舍外又想配置刚弄好的系统…所以我至少需要连接到出于宿舍Wi-Fi里的Gentoo上。

ngrok原本是又一个官方的网站,即默认走官方的路线,用个客户端即可的。但是出于众所周知的原因,原本的ngrok官网不能使用了。国内虽然有替代的网站,但是好像或多或少都有一点盈利方面的倾向,感觉用得不会很愉快。

ngrok这个东西服务器和客户端都是开源的,因而觉得自己搭就可以。

首先当然得有一个VPS,我的VPS是在腾讯云上的Ubuntu。

下载ngrok源码

1
2
git clone https://github.com/inconshreveable/ngrok.git
cd ngrok

准备自签名证书

如果是使用官方服务,则不需要进行这个过程了。

在此时,你需要给你的服务一个域名,比如ciaran.cn,把它称作“NGROK_BASE_DOMAIN”。

1
export NGROK_BASE_DOMAIN=ciaran.cn

注意:若你想访问的服务的地址为xxxxx.ciaran.cn,那么你的NGROK_BASE_DOMAIN就为ciaran.cn。如果你想访问的服务地址为xxxxxx.tunnel.ciaran.cn,那么你的NGROK_BASE_DOMAIN为tunnel.ciaran.cn

接下来生成对应的证书

1
2
3
4
5
openssl genrsa -out ngrok.key 2048
openssl req -x509 -new -nodes -key ngrok.key -subj "/CN=$NGROK_BASE_DMOAIN" -days 5000 -out ngrok.pem
openssel genrsa -out snakeoil.key 2048
openssl req -new -key snakeoil.key -subj "/CN=$NGROK_BASE_DMOAIN" -out snakeoil.csr
openssl x509 -req -in snakeoil.csr -CA ngrok.pem -CAkey ngrok.key -CAcreateserial -out snakeoil.crt -days 5000

这会生成6个新文件其中我们需要的有

  • ngrok.pem
  • snakeoil.crt
  • snakeoil.key

要将它们替换原本文件中的证书:

1
2
3
cp ngrok.pem assets/client/tls/ngrok.pem
cp snakeoil.crt assets/server/tls/snakeoil.crt
cp snakeoil.key assets/server/tls/snakeoil.key

Golang安装

1
sudo apt install golang

需要正确设置go的环境变量。(实际上在安装的时候,就默认的就可以了。

编译ngrok

编译服务器:

1
make release-server

编译相应的客户端:

  • 编译在Linux上的客户端(因为本身是在Linux上)

    1
    make release-client
  • 编译在64位Win上的客户端

    1
    GOOS=windows GOARCH=amd64 make release-client
  • 编译在64位Mac上的客户端

    1
    GOOS=darwin GOARCH=adm64 make release-client
  • 编译树莓派上的客户端

    1
    GOOS=linux GOARCH=arm make release-client

这个客户端将交给使用ngrok来进行端口映射的本地机。

这两个过程会在当前文件夹的bin文件夹下产生ngrok和ngrokd两个文件

将ngrok移到/usr/bin/下后,就能直接使用他们了。

配置

启动ngrok服务器

1
sudo nohup ngrokd -domain=$NGROK_BASE_DOMAIN -httpAddr=":8080" -httpsAddr=":8081" -tunnelAddr=":443" &

在这里,可以ps aux | grep看看有否启动成功。

在需要端口映射的机子上创建并编辑文件”ngrok.cfg

1
2
server_addr: "ciaran.cn:443"
trust_host_root_certs: false

这时通过配置文件启动文件:

1
sudo ngrok -config=ngrok.cfg -subdomain="test" -log "ngrok.log" 8000

这句话会做的事情是将本身的8000端口映射到test.ciaran.cn的某个端口(8080),将输出写入到ngrok.log

如果没有什么问题的话,应该会出现类似这样的一个画面:

1
2
3
4
5
6
7
Tunnel Status online
Version 1.7/1.7
Forwarding http://test.ciaran.cn:8080 -> 127.0.0.1:8000
Forwarding https://test.ciaran.cn:8080 -> 127.0.0.1:8000
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms

不过如果你的状态是Tunnel Status reconnecting,那请参照ngrok.log改正你的网络或其它的配置。

多数情况下会是DNS配置错误,查看你的nslookup test.ciaran.cn是否指向的是你的VPS。

server_addr后的值要求必须与NGROK_BASE_DOMAIN的值一样,否则服务器端会出现Bad certificate的错误。

如果一切正常,那么当你访问test.ciaran.cn:8080时,它会返回本地机子上8000端口的响应。

测试的方式可以用python -m http.server

配置ssh的端口映射

ssh的端口映射是使用tcp连接的,即如果要映射22端口的话,需要这样:

1
sudo ngrok -config=ngrok.cfg -subdomain="test" -log "ngrok.log" -proto=tcp 22

然后它的输出应该会类似这样:

1
2
3
...
Forwarding http://test.ciaran.cn:24067 -> 127.0.0.1:22
...

注意它的端口不是1080了。你需要这样访问这个ssh服务器的映射

1
ssh <username>@test.ciaran.cn -p 24067

后台运行

新建一个start_ngrok.sh的文件:

1
sudo ngrok -config=ngrok.cfg -subdomain="test" -log "ngrok.log" -proto=tcp 22

然后我们可以通过使用pm2的方式使ngrok运行:

1
pm2 start start_ngrok.sh --interpreter=bash

对于我们希望让进程在后台默默地运行的情况,这样打印在屏幕上的方式显示端口恐怕会显得比较难受。那么我们可以通过查看它的日志(无论是在服务器方还是)


参考此处