ngrok 实现内网穿透

作者: 老码农不上班 | 来源:发表于2018-02-13 03:08 被阅读117次

    最近新买了一台服务器放在家里跑各种杂七杂八的服务,需整一个内网穿透的服务通过外网也能远程登录服务器。很久之前就听闻 ngrok 能实现,于是乎自己也整了一遍。这篇文章记录服务端到客户端部署的全过程,备忘。

    首先得有一台外网能够访问的 vps 用以部署 ngrok 的服务端、及一个用以解析自搭建 ngrok 服务的域名。

    创建证书

    ngrok 的隧道采用 TSL 传输数据,如果使用默认证书的话任何人都可以连接你搭建的 ngrok 服务,在这里你可以去买,不过还是推荐自己生成证书。

    export NGROK_DOMAIN="ngrok.xxx.com"
    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
    

    执行上述文件会生成 6 个文件,server.key, server.crt, base.pem 这三个才是我们需要用到的,覆盖 ngrok 默认证书

    cp server.key assets/server/tls/snakeoil.key
    cp server.crt assets/server/tls/snakeoil.crt
    cp base.pem assets/client/tls/ngrokroot.crt
    

    编译 ngrok 服务端和客户端

    编译需要 Golang 环境,获取 ngrok 源码: git clone https://github.com/inconshreveable/ngrok.git

    ngrok 默认监听 IPv6 端口,我大清自有国情,我们需要源码两处

    • src/ngrok/server/tunnel.go 文件中 net.ListenTCP 后面的 tcp 改为 tcp4
    • src/ngrok/conn/conn.go 文件中 net.Listen 后面的 tcp 改为 tcp4

    接下来就是编译,我们需要查看将要部署 ngrok 服务的服务端和客户端 ARCH 信息以便进行跨平台编译,使用命令:

    // 这里是我机器的信息,你需要根据你机器得到的信息使用对用的编译指令
    dpkg --print-architecture
    amd64  // 将要部署 ngrok 服务端的 vps 服务器 arch 信息
    i386   // 将要部署 ngrok 客户端的内网服务器
    

    Go (Golang) GOOS and GOARCH

    cd 到 ngrok 源码的目录准备编译:

    // 服务端
    GOOS=linux GOARCH=amd64 make release-server
    
    // 客户端
    GOOS=linux GOARCH=386 make release-client
    

    编译得到的可执行文件在 bin 目录下,然后我们使用 scp 命令或 async 命令把编译后得到的文件拷贝到 vps 和内网服务器上:

    scp bin/linux_amd64/ngrokd {vps_server}
    scp bin/linux_386/ngrok {local_server}
    

    配置域名和 ngrok 客户端、服务端

    首先你需要在域名解析网站解析域名,后续你就可以通过域名远程连接内网服务器,这也是我们最终的目的哈。

    解析主机记录为 ngrock 和 *.ngrok.xxx.com 且全部为 A 记录类型,记录值填你的 vps 外网地址。
    

    服务端配置

    前面我们已经把 ngrokd 文件拷贝到 vps 的根目录,在这里我们把转移到这里:sudo mkdir /opt/ngrkd & sudo mv ngrokd /opt/ngrokd/

    然后使用 systemd 设置自启动服务,把如下内容保存在 /lib/systemd/system/ngrokd.service, 域名要改成你自己的。

    [Unit]
    Description=ngrok server
    After=network.target
    
    [Service]
    Type=simple
    ExecStart=/opt/ngrokd/ngrokd -domain ngrok.xxx.com -httpAddr "" -httpsAddr "" -tunnelAddr ":4443" -log "/var/log/ngrokd.log"
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    

    启动服务

    sudo systemctl enable ngrokd
    sudo systemctl start ngrokd
    sudo systemctl status ngrokd
    

    客户端配置

    登录到内网服务器, 同样把编译好的 ngrok 拷贝过来的 ngrok 客户端,然后同样客户端服务添加到 systemd 自启动服务中,保存下面内容到文件 /lib/systemd/system/ngrok.service

    [Unit]
    Description=ngrok client
    After=network.target
    
    [Service]
    Type=simple
    ExecStart=/opt/ngrok/ngrok -config "/opt/ngrok/ngrok.yml" -log "/var/log/ngrok.log" start transmission ssh
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    

    ExecStart 加载了配置文件 /opt/ngrok/ngrok.yml,其文件内容如下:

    server_addr: ngrok.xxx.com:4443
    trust_host_root_certs: false
    tunnels:
      transmission:
        remote_port: 9091
        proto:
          tcp: 9091
      ssh:
        remote_port: 23333
        proto:
          tcp: 22
    

    然后像启动 ngrok 服务端服务一样启动客户端服务

    在这里提醒一点,我踩到了一个坑,启动客户端服务时日志 (sudo tail -f /var/log/ngrok.log) 出现报错:

    [2018/02/13 01:41:28 CST] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [view] [term] Waiting for update
    [2018/02/13 01:41:28 CST] [EROR] (ngrok/log.Error:120) control recovering from failure dial tcp: lookup ngrok.xxx.com on 8.8.8.8:53: no such host
    

    后面我在内网服务器 ping ngrok.xxx.com 提示找不到 host, 应该是 dns 的问题,nslookup ngrok.xxx.com 看了一下,果不其然,我直接把域名和 IP 写到内服务器的 /etc/hosts 文件上。

    systemd 重启客户端服务之后就正常了。

    最后通过 ssh -p 23333 username@ngrok.xxx.com 即可远程登录局域网内的服务器。

    推荐及参考阅读

    内网穿透之ngrok [2017-10-13 UPDATED]

    相关文章

      网友评论

      • 0aae73191ccb:你好,我也遇到了lookup ngrok.xxx.com on 8.8.8.8:53: no such host问题。请问如何配置,谢谢

      本文标题:ngrok 实现内网穿透

      本文链接:https://www.haomeiwen.com/subject/dvtjtftx.html