ngrok是一个可用于内网穿透的软件,在我们做网站调试或者需要访问内网的资源,而内网又没有外网IP的情况下具有非常好的效果。做内网穿透之前我们需要具备的条件如下:

  • 一台具有外网IP的服务器(vps、云服务器等)
  • 域名

域名解析

建立两条A记录,把域名解析到vps上,用来关联ngrok服务。假设你的域名是example.com(文章接下来的部分均假设你的域名为example.com,请根据自己的域名做修改),那么建立ngrok.example.com和*.ngrok.example.com解析到vps服务器上。如下图所示:

安装ngrok

安装依赖

git, go,编译环境等。。

下载源代码

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

生成自签名证书

cd ngrok
domain="ngrok.example.com"
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$domain" -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=$domain" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 500

替换证书


\cp rootCA.pem assets/client/tls/ngrokroot.crt -f
\cp device.crt assets/server/tls/snakeoil.crt  -f
\cp device.key assets/server/tls/snakeoil.key -f

编译服务器软件ngrokd

make release-server

生成的服务软件在bin/ngrokd

编译各平台的客户端

export GOOS="windows" GOARCH="amd64" && make release-client
export GOOS="linux" GOARCH="amd64" && make release-client
export GOOS="linux" GOARCH="arm" && make release-client

不同平台对应的参数如下:

Linux 平台 32 位系统:GOOS=linux GOARCH=386 Linux 平台 64 位系统:GOOS=linux GOARCH=amd64

Windows 平台 32 位系统:GOOS=windows GOARCH=386 Windows 平台 64 位系统:GOOS=windows GOARCH=amd64

MAC 平台 32 位系统:GOOS=darwin GOARCH=386 MAC 平台 64 位系统:GOOS=darwin GOARCH=amd64

ARM 平台:GOOS=linux GOARCH=arm

安装服务端

复制ngrokd到/usr/local/bin/进行安装(go生成的客户端就是只有一个文件)

下载编译好的客户端到本地电脑

可以使用sftp下载。

测试

服务端启动

/usr/local/bin/ngrokd -domain=ngrok.example.com -httpAddr=:6060 -httpsAddr=:6061 -tunnelAddr=:6062

记得打开防火墙对应的端口

本地客户端

建立ngrok.cfg配置文件:

server_addr: "ngrok.example.com:6062"
trust_host_root_certs: false

运行客户端,暴露本地80端口

ngrok.exe -subdomain demo -config=ngrok.cfg 80

可以下载一个NGINX,然后在本地运行,用浏览器访问demo.ngrok.example.com:6060

写入配置文件

刚才测试的时候使用的是命令行,而在我们使用的时候往往希望是以服务在运行。

服务器

使用systemd来启动与关闭服务,建立文件/etc/systemd/system/ngrokd.service

[Unit]
Description=Share local port(s) with ngrokd
After=syslog.target network.target

[Service]
PrivateTmp=true
Type=simple
Restart=always
RestartSec=1min
StandardOutput=null
StandardError=null
ExecStart=/usr/local/bin/ngrokd -domain=ngrok.example.com -httpAddr=:6060 -httpsAddr=:6061 -tunnelAddr=:6062
ExecStop=/usr/bin/killall ngrokd

[Install]
WantedBy=multi-user.target

还应当给ngrok.service文件增加可行性权限:

chmod +x ngrok.service

本地

ngrok.cfg(多个映射端口同时启用):

server_addr: "ngrok.example.com:6062"
trust_host_root_certs: false
tunnels:
    ss:
        subdomain: "ss"
        remote_port: 33333
        proto:
            tcp: 127.0.0.1:1081

    ssh:
        subdomain: "ssh"
        remote_port: 5000
        proto:
            tcp: 127.0.0.1:22

    # 内网穿透访问内网的网址
    yjk:
        subdomain: "yjk"
        remote_port: 8273
        proto:
            tcp: 172.168.1.20:8273

    demo:
        subdomain: "demo"
        proto:
            http: 127.0.0.1:80

    demo1:
        subdomain: "demo1"
        proto:
            http: 127.0.0.1:8080

启动方式

ngrok.exe -config=ngrok.cfg start ss ssh demo demo1