部署自己的Ngrok内网穿透服务

### 说明

其实这就是让外网用户访问内网的服务,要求就是自己需要一个公网服务端。优点是方便,缺点就是有点脱了裤子(都有公网服务器了,还需要在内网做什么?不过确实还是有提供服务的,方便网友。你说懒得上传服务器,那好吧,这算是个优点。)

我已完成搭建,域名http://?.n.scwy.net,有需要的网友可以申请,做一些小量的测试使用还是可以的。比如我就用在Raspberry Pi上,安装一些服务之类的。

### 编译安装ngrok
#### 安装GO环境

ngrok是使用GO进行开发的,所以首先需要安装GO环境,在CentOS中非常方便,直接使用 yum install golang -y 进行安装,安装完成之后在命令行中执行 go version 命令,如果出现版本号即表示安装成功。可以通过 go env 命令查看GO的环境信息。

#### 下载ngrok

ngrok项目的官方地址是:https://github.com/inconshreveable/ngrok,可以通过 git clone https://github.com/tutumcloud/ngrok.git ngrok 进行安装,但发现在服务器上下载非常慢,也可以直接下载其源码的zip包,命令行如下(以安装到/usr/local/ngrok目录为例):

wget https://github.com/inconshreveable/ngrok/archive/master.zip -O /usr/local/ngrok.zip
unzip /usr/local/ngrok.zip -d /usr/local/
mv /usr/local/ngrok-master/ /usr/local/ngrok/
export GOPATH=/usr/local/ngrok/


### 生成自签名证书

因为单独安装自己的ngrok,所以需要使用openssl生成自签名的SSL证书,使用下面的命令(需要将NGROK_DOMAIN替换成自己的域名):

cd /usr/local/ngrok
NGROK_DOMAIN="ngrok.example.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 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

最后的复制命令是将生成的证书分别替换到 assets/client/tls和assets/server/tls 目录中,这两个目录分别存放着ngrok和ngrokd的默认证书。

最后的复制命令是将生成的证书分别替换到 assets/client/tls和assets/server/tls 目录中,这两个目录分别存放着ngrok和ngrokd的默认证书。

### 编译并启动服务端

ngrokd 为服务端的执行文件,ngrok为客户端的执行文件,我们先来编译ngrok的服务端程序,在ngrok目录下面执行下面的命令:

make release-server

首次编译的时候需要从远程下载一些依赖文件,所以时间有一些长。需要注意的是,第一次不能执行 make clean 命令,否则会出现错误,对GO不是很熟悉,有一些资料说是跟使用yum方式安装GO有关。

编译成功之后会在项目目录的bin目录下面生成一个 ngrokd 的文件,使用下面的命令启动服务:

bin/ngrokd -domain="ngrok.example.com" -httpAddr=":8088" -httpsAddr=":8089" -tunnelAddr=":4000"

上面的参数中,domain表示服务的域名,httpAddr和httpsAddr分别表示HTTP和HTTPS的端口,tunnelAddr用来设置通道的端口,在客户端和服务端建立连接的端口,需要在防火墙中开放次端口(默认为4443)。

可以将命令加入到 /etc/rc.local 中使其开机启动,命令如下:

/usr/local/ngrok/bin/ngrokd -domain="ngrok.example.com" -httpAddr=":8088" -httpsAddr=":8089" -tunnelAddr=":4000" > /dev/null 2>&1 &

其中 /usr/local/ngrok 是ngrok的安装目录,最后不显示运行的日志,并且在后台运行。

### 使用客户端调用
编译客户端

接下来要编译专用的客户端,首先进入项目的根目录,使用下面的命令编译专用的客户端文件:

GOOS=windows GOARCH=386 make release-client

其中GOOS用乱设置操作系统,GOARCH用来设置对应的架构(386,amd64或arm),其含义如下:

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

上面的命令表示编译windows下使用的32位的客户端程序,编译好的文件在bin目录下对应平台的目录下面。

### 启动客户端

接下来就可以使用客户端了,首先创建一个ngrok的配置文件ngrok.cfg:

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

域名后面的端口是设置的通道端口。

接下来使用下面的命令运行客户端:

./ngrok -subdomain jet -config=ngrok.cfg 8080

其中jet是自定义的域名前缀,ngrok.cfg是上面的配置文件,8080是映射的本地到外网的端口,这样就可以使用 http://jet.ngrok.example.com:8088 访问本地8080的端口了。

另外,还可以使用 -proto 来指定协议的类型(默认是http协议),支持http、tcp等多种协议:

./ngrok -subdomain jet -config=ngrok.cfg -proto=tcp 8080


### 使用Nginx反向代理到80端口

上面通过子域名访问的时候不是默认的80端口,可以使用Nginx进行反向代理,配置信息如下:
```
upstream tdt_99tone_ngrok_server {
    server 127.0.0.1:8088 weight=1 max_fails=3 fail_timeout=30s;
    keepalive 64;
}

server {
    listen 80;
    server_name *.ngrok.example.com ngrok.example.com;
    charset utf-8;

    location / {
        proxy_next_upstream http_502 http_504 error timeout invalid_header;
            proxy_set_header Host  $host:8088;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://tdt_99tone_ngrok_server;
            proxy_redirect off;
    }

    access_log off;
    log_not_found off;
}

```

外网访问内网ssh
ngrok -config=./ngrok.cfg -proto=tcp 22


这里还介绍了为自己的服务器添加一个简单认证,免得随便谁都来使用。--> https://ask.csdn.net/questions/688161
实际是修改了 ngrok/src/ngrok/server/control.go文件
```
func NewControl(ctlConn conn.Conn, authMsg *msg.Auth) {
     //省略
     //读取文件方法
     readLine := func(token string, filename string) (bool, error) {

        if token == "" {
            return false, nil;
        }
        f, err := os.Open(filename)
        if err != nil {
            return false, err
        }
        buf := bufio.NewReader(f)
        for {
            line, err := buf.ReadString('\n')
            line = strings.TrimSpace(line)
            if line == token {
                return true, nil
            }
            if err != nil {
                if err == io.EOF {
                    return false, nil
                }
                return false, err
            }
        }
        return false, nil
}
    //省略
    //调用验证
    authd, err := readLine(authMsg.User, "authtokens.txt")

    if authd != true {
        failAuth(fmt.Errorf("authtoken %s invalid", "is"));
        return
}
     //省略
 }

```
当然你随意添加还是会有点错误提示,比如库没有引入,failAuth没定义之类的。会golang的自会处理。
重新编译服务端 , 在执行文件同目录建立一个 用户文件,"authtokens.txt"
在客户端使用的时候-authtoken "xxxxxxx" 对应txt中的其中一行即可:
ngrok -subdomain=b -config=./ngrok.cfg -authtoken=abcdefg 8181
或者修改配置文件,例如:
```
server_addr: ngrok.testdomain.com:4443
trust_host_root_certs: true/false
auth_token: username:password
tunnels:
  b:
    subdomain: b
    proto:
      http: "80"
      https: "8080"
```
然后启动.\ngrok.exe -log ngrok.log -config ngrok.cfg start b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值