• 编译搭建ngrok服务实现内网穿透


    搭建ngrok服务实现内网穿透

    日期: 2019-05-09

    环境说明:

    	编译环境:
    	       名称:CentOS7 
    	       系统:CentOS7 1810 64位
    	       GO版本:1.11 和 1.13 均测试编译通过,1.18不行
    	公网主机:
    	       名称:cloud7
    	       系统:CentOS7 minimal 1804 64位
    	本地主机:
    	       名称:yl_deep_local
    	       系统:Ubuntu 18.04 64位
    	本次需要做内网穿透,实现再其他地方能连接本地主机yl_deep_local。注意文中的 tunnel.MYDOMAIN.COM 请替换为自己实际用的域名。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1 编译程序

    1.0 准备工作

    编译环境的主机最好配置国内的yum源,还需要配置epel源。配置epel后能方便的使用yum安装go语言编译环境。

    1.1 下载源码包

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

    可以使用git下载,也可以直接下载zip包(我这里直接下载zip包,解压并上传到系统中)
    我将源码放置于/opt/src/ngrok-src,如下图
    ngrok-src

    1.2 生成证书

    注意替换为自己的域名

    mkdir ~/tmp
    cd ~/tmp
    export NGROK_DOMAIN="tunnel.MYDOMAIN.COM"
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    完成后生成如下证书(位于~/tmp目录):
    证书
    替换证书

    cd /opt/src/ngrok-src
    cp ~/tmp/rootCA.pem assets/client/tls/ngrokroot.crt
    cp ~/tmp/server.crt assets/server/tls/snakeoil.crt
    cp ~/tmp/server.key assets/server/tls/snakeoil.key
    
    • 1
    • 2
    • 3
    • 4

    1.3 安装go语言编译环境

    (需配置epel源)

    yum install golang
    
    • 1

    使用root账号运行,安装了如下包
    golang

    1.4 编译程序

    客户端版本说明

    • 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
    cd /opt/src/ngrok-src
    export GOPATH=$(pwd)    # 设置go目标目录
    GOOS=windows GOARCH=amd64 make release-client    # 编译windows 64客户端
    GOOS=windows GOARCH=amd64 make release-server    # 编译windows 64服务端
    GOOS=linux GOARCH=amd64 make release-client    # 编译linux 64客户端
    GOOS=linux GOARCH=amd64 make release-server    # 编译linux 64服务端
    GOOS=darwin GOARCH=amd64 make release-client    # 编译MAC 64客户端
    GOOS=darwin GOARCH=amd64 make release-server    # 编译MAC 64服务端
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    完成编译后bin目录下有以下文件(各平台都编译了,以后备用)
    bins

    2 配置服务端

    2.1 配置域名解析到公网主机ip

    这样 *.tunnel.MYDOMAIN.COM 和 tunnel.MYDOMAIN.COM 都解析到了公网主机 cloud7
    dns

    2.2 配置服务端并启动服务

    将ngrokd(linux amd64版)上传到公网主机的/opt/ngrok/目录下,然后添加执行权限

    chmod +x /opt/ngrok/ngrokd    # 后来由于方便起见放到 /usr/bin 目录下
    
    • 1

    后来由于方便起见放到 /usr/bin 目录下,以便可以使用命令直接运行

    ngrokd -domain=tunnel.MYDOMAIN.COM -httpAddr=:5442 -httpsAddr=:5443 -tunnelAddr=:4443
    
    • 1

    效果如下图:
    ngrokd
    看情况,后台启动添加 nohup,日志重定向到日志文件或/dev/null

    2.3 开启防火墙端口

    我这里只用4443

    firewall-cmd --zone=public --add-port=4443/tcp --permanent
    firewall-cmd --reload
    
    • 1
    • 2

    3 配置客户端

    3.1 配置客户端

    将ngrok(linux amd64版)上传到本地主机的/opt/ngrok/目录下,然后添加执行权限

    chmod +x /opt/ngrok/ngrok
    
    • 1

    新建配置文件(这里使用配置文件的方式启动ngrok,另一种方式是直接命令中指定相关配置选项)

    cd /opt/ngrok/
    vi /opt/ngrok/ngrok-config
    
    • 1
    • 2

    内容如下

    server_addr: "tunnel.MYDOMAIN.COM:4443"
    trust_host_root_certs: false
    tunnels:
      web:
        proto:
          http: 80
        subdomain: web
      webs:
        proto:
          https: 443
        hostname: webs.tunnel.MYDOMAIN.COM
      ssh:
        proto:
          tcp: 10022
        remote_port: 10022
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这里配置了3条转发,这里测试用10022作为ssh端口,默认端口为22。

    3.2 启动客户端

    前面配置了3条,这里只启动ssh

    ./ngrok -config=ngrok-config start ssh
    
    • 1

    效果如下
    ngrok-client-ssh如果需同时启动其他规则,命令start后添加其他规则名称即可,如启动web和webs

    ./ngrok -config=ngrok-config start web webs
    
    • 1

    ngrok-client-web如果想一次启动所有,可以使用命令

    ./ngrok -config=ngrok-config start-all
    
    • 1

    3.3 效果测试

    xshell的ssh配置,主机中填写域名
    xshell-session
    使用xshell连接
    xshell-window
    连接成功,试了几个小时,没有掉线情况。之前使用ssh转发,经常掉,现在终于解决问题了。

    4 配置为服务自启动

    将程序配置为服务项,开机启动

    4.1 配置服务端

    服务端为CentOS7

    vi /usr/lib/systemd/system/ngrokd.service
    
    • 1

    内容如下,注意Exec命令中不要有双引号,会导致失败(找了好久问题)

    [Unit]
    Description=ngrokd
    After=network.target
    
    [Service]
    TimeoutStartSec=30
    ExecStart=/usr/bin/ngrokd -domain=tunnel.MYDOMAIN.COM -httpAddr=:5442 -httpsAddr=:5443 -tunnelAddr=:4443 -log-level=INFO 
    ExecStop=/bin/kill -SIGINT $MAINPID
    ExecReload=/bin/kill -SIGHUP $MAINPID
    Restart=on-failure
    #NotifyAccess=main
    #WatchdogSec=30
    
    [Install]
    WantedBy=multi-user.target
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    启动设置及相关命令

    systemctl daemon-reload  # 载入配置服务
    systemctl enable ngrokd  # 设置开机启动
    systemctl start ngrokd   # 开启ngrok
    systemctl status ngrokd  # 查看状态
    systemctl stop ngrokd    # 停止
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.2 配置客户端

    客户端为Ubuntu 18.04

    vim /lib/systemd/system/ngrok-ssh.service
    
    • 1

    内容如下

    [Unit]
    Description=ngrok-ssh.service
    
    [Service]
    #Type=forking
    #PIDFile=/run/test.pid
    #EnvironmentFile=/etc/systemd/test.conf
    ExecStart=/usr/bin/nohup /usr/bin/ngrok  -log=stdout -log-level=INFO -config=/opt/ngrok/ngrok-config start ssh
    ExecReload=/bin/kill -SIGHUP $MAINPID
    ExecStop=/bin/kill -SIGINT $MAINPID
    Restart=on-failure
    #NotifyAccess=main
    #WatchdogSec=30
    
    [Install]
    WantedBy=multi-user.target
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    相关命令

    systemctl daemon-reload    # 载入配置服务
    systemctl enable ngrok-ssh  # 设置开机启动
    systemctl start ngrok-ssh    # 启动服务
    systemctl status ngrok-ssh    # 查看状态
    systemctl stop ngrok-ssh    # 停止服务
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ngrok-ssh-service

    5 后续补充

    2022-10-19重新编译,有几个坑:

    1. go 新版不行,后使用ubuntu 20.04(go 1.13)成功编译;
    2. 依赖 uniseg 最高支持 uniseg-0.2.0 版本的,试出来的;
    3. 由于网络问题可能无法下载依赖的,可以通过手动下载,然后放置到src下对应的目录,如提示go get -tags 'release' -d -v ngrok/... github.com/nsf/termbox-go (download) 时,可以到github下载源代码,然后放到src/github.com/nsf/termbox-go即可,如图:
      termbox
  • 相关阅读:
    小程序引入隐私政策
    go语言实现LeetCode59 螺旋矩阵Ⅱ
    网易企业邮箱斩获双料奖项!产品实力与客户口碑双丰收!【公司邮箱怎么申请】
    js作用域
    Python 教程之将网页内容专为语音mp3
    解决提示CUDA内存不够,但 GPU显示还有足够的空间
    【iOS】iphone 短信标记未读 bug/ 永远清不干净的红点未读提示 /总结四大解决方案,总有N个适合你
    Java-字符编码-roadmap
    GoLang反射
    每日五道java面试题之springMVC篇(一)
  • 原文地址:https://blog.csdn.net/ylhlly/article/details/127391856