利用VPS搭建Ngrok内网穿透服务

/ 0评 / 0

Preface

由于之前自费提供花生壳内网穿透服务给公司测试服务器测试外网回调的上司离职了, 开发环境下的微信支付宝测试面临难关. 而我, 作为公司目前唯一的一个后端(sigh..), 自然是避免不了踩一踩坑.

有想过的解决方案:

  1. 找公司再开一台阿里云ECS, 重新搭一套服务. 然而耗时, 耗钱, pass.

  2. 去找花生壳开个免费版的个人内网穿透服务. 但是听说免费版限制多不稳定, 而且, 我单纯不喜欢花生壳这个名字, 故pass.

  3. 网上的ngrok, natapp共享服务器, 不稳定+不安全, pass again.

想了想, 还是自己用vps搭一个ngrok服务. 目前手里vps服务器的压力不大, 搭好了以后也可以自用. 而且最近莫名地很想学习新知识, 所以不多废话了.

整个搭建过程的思路参考了这篇文章.

域名解析

由于域名解析生效需要时间, 所以就先把域名解析好.

域名是在Namesilo购买的, 综合性价比和服务, 应该是最值得推荐的域名服务商之一.

域名解析的nameserver我选择迁移到了cloudflare, 原因可能是操作比较熟, 界面比较好看吧

步骤很简单, 解析两条A记录到VPS的ip地址就好, 分别是*.ngrok.jimmytinsley.comngrok.jimmytinsley.com

服务部署

Go语言环境

apt-get update
apt-get -y install build-essential mercurial git
wget https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.8.1.linux-amd64.tar.gz
mkdir $HOME/go
echo 'export GOROOT=/usr/local/go' >> /etc/profile.d/go.sh
echo 'export GOPATH=$HOME/go' >> /etc/profile.d/go.sh
echo 'export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' >> /etc/profile.d/go.sh
source /etc/profile.d/go.sh

Ngrok安装

安装目录可以自己选, 我是直接照搬的原文章

cd /usr/local/src/
git clone https://github.com/tutumcloud/ngrok.git ngrok
export GOPATH=/usr/local/src/ngrok/

接下来有个重点, 就是Ngrok的ssl证书. 由于Ngrok的可执行文件(客户端和服务端)是在ssl证书生成之后再编译完成的. 我当时先编译了一遍, 把客户端可执行文件拷到本地服务器之后, 不小心操作失误所以需要重新生成ssl证书编译服务端. 结果连接时, 服务端一直报bad certificate错误, 研究了很久才找到错误原因.

Ngrok的ssl证书生成和可执行文件编译

cd ngrok
### 这里NGROK_DOMAIN=""填自己的域名
NGROK_DOMAIN="ngrok.jimmytinsley.com"
### 给域名生成ssl证书
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
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000
### 把证书复制tls目录
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key
### 设定编译环境, 我是64位linux所以这样写
### 32位系统为GOARCH=386
### Windows平台为GOOS=windows
GOOS=linux GOARCH=amd64
### 编译客户端和服务端
make release-server release-client

启动Ngrok服务端

-domain填写自己的域名, 一定要是ngrok.xxx.xxx 即上面解析的没有通配符的那个域名. 端口号可以随便填, 注意占用情况就好

### -domain=填写自己的域名
cd /usr/local/src/ngrok/bin && ./ngrokd -domain="ngrok.jimmytinsley.com" -httpAddr=":8002" -httpsAddr=":8003" -tunnelAddr=":4000"

为了方便一点, 也可以写到 ~/.bash_profile

alias runngork='cd /usr/local/src/ngrok/bin && ./ngrokd -domain="ngrok.jimmytinsley.com" -httpAddr=":8002" -httpsAddr=":8003" -tunnelAddr=":4000"'

然后别忘记source一下

source ~/.bash_profile

启动完成之后, 可以看到下图

blob.jpg

这样就是启动成功了

启动客户端

先用scp命令或者xftp等工具把 /usr/local/src/ngrok/bin/ngrok 可执行文件传输到需要开启内网穿透的服务器上一个目录, 比如 ~/ngrok/ngrok, 然后需要手动创建一个客户端的配置文件.

比如说

vi ~/ngrok/ngrok.cfg

内容为

server_addr: ngrok.jimmytinley.com:4000
trust_host_root_certs: false

注意这里的 server_addr 一定要填写启动服务端时 -domain= 内填写的域名和端口

保存退出后, 如果ngrok可执行文件和ngrok.cfg配置文件处在同一目录的话, 可以直接运行以下代码, 否则要指定完整的配置文件路径. 这里 -subdomain 可以任意填, 端口号是本地映射到外网的端口, 也可以任意指定.

./ngrok -subdomain hello -config=ngrok.cfg 80

运行完, 如果看到这个画面

blob.jpg

那应该就可以通过 hello.ngrok.jimmytinsley.com:8002 来访问本地的80端口了.

Nginx反向代理

比较难办的是, 虽然服务可以正常访问, 而且我也成功收到了支付宝的付款结果回调, 但是有个新的问题, 微信支付的回调地址似乎只支持80端口, 而我这台VPS的80端口被挂博客的Apache给占用了.

如果我想直接通过域名访问博客网站, 那80端口肯定是留出来, 不能让Ngrok占用了, 所以这个时候就要用上Nginx了.

那么就先解决Apache要使用80端口的问题.

首先把Apache服务器的端口切换到8080, 然后换Nginx来监听80端口.

修改Nginx配置文件的server部分, 将直接访问 jimmytinsley.comwww.jimmytinsley.com 的请求全部转发给8080端口的Apache.

location / {
    proxy_pass http://127.0.0.1:8080;
}

同时在Nginx目录的conf.d文件夹内新建apache.conf, 写入如下配置:

#apache.conf
upstream apache {
    server 127.0.0.1:8080;
    keepalive 64;
}

server {
    listen 80;
    server_name jimmytinsley.com www.jimmytinsley.com;
    access_log /var/log/nginx/apache_access.log;
    proxy_set_header "Host" $host:8080;
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host:8080;
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_pass  http://apache;

    }
    access_log off;
    log_not_found off;
}

接着解决Ngrok需要使用80端口的问题. 同样在conf.d文件夹内新建ngrok.conf, 写入如下内容:

upstream ngrok {
    server 127.0.0.1:8002;
    keepalive 64;
}

server {
    #监听访问 *.ngrok.jimmytinsley.com 80 端口的请求
    #并转发到8002端口的ngrok服务上
    listen 80;
    server_name *.ngrok.jimmytinsley.com;
    access_log /var/log/nginx/ngrok_access.log;
    proxy_set_header "Host" $host:8002;
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host:8002;
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_pass  http://ngrok;

    }
    access_log off;
    log_not_found off;
}

然后重启一下Nginx服务就好啦

service nginx restart

现在可以通过域名 hello.ngrok.jimmytinsley.com80端口访问在本地测试服务器的服务了. VPS搭建在 Vultr 的 LA 机房, 通过内网穿透调试接口, 平均的响应时间多了大概360ms, 考虑到直接ping VPS的延迟也有160-170ms左右, Ngrok的速度已经比较让人满意了.

发表评论

电子邮件地址不会被公开。 必填项已用*标注