VPS自搭建Ngrok内网穿透服务

原文链接: http://yangbingdong.com/2017/self-hosted-build-ngrok-server/

前言

Ngrok可以干嘛?我们经常会有 "把本机开发中的 web 项目给朋友看一下" 或 "测试一下支付宝、微信的支付功能" 这种临时需求,为此专门购买个域名然后在 VPS或云主机 上部署一遍就有点太浪费了。那么这时候,Ngrok就是个很好的东西,它可以实现我们的这种需求。而且 Ngrok 官网本身还提供了公共服务,只需要注册一个帐号,运行它的客户端,就可以快速把内网映射出去。不过这么好的服务,没多久就被了~幸好Ngrok是开源的,那么我们可以自己搭建一个Ngrok!

域名泛解析

因为内网穿透需要用到多级域名,这里,博主的这个域名是在Namesilo购买的,然后转到DNSPod解析:


如图所示,我搞买的域名是yangbingdong.com,将ngrok.yangbingdong.com通过A记录解析导VPS的ip地址,再将*.ngrok.yangbingdong.com通过CNAME解析导ngrok.yangbingdong.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/

生成自签名SSL证书,ngrok为ssl加密连接:

cd ngrok
NGROK_DOMAIN="ngrok.yangbingdong.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
GOOS=linux GOARCH=amd64
make clean
make release-server release-client

注意:上面的ngrok.yangbingdong.com换成自己的域名

  • 如果是32位系统,GOARCH=386; 如果是64为系统,GOARCH=amd64
  • 如果要编译linux,GOOS=linux;如果要编译window,GOOS=windows

启动server

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

ngrok.yangbingdong.com换成自己的域名。其他端口可自己配置。
顺利的话,可以正常编译,在bin下面可以看到「ngrokd」和「ngrok」,其中「ngrokd」是服务端执行程序,「ngrok」是客户端执行程序

后台运行:

cd /usr/local/src/ngrok/bin && nohup ./ngrokd -domain="ngrok.yangbingdong.com" -httpAddr=":8002" -httpsAddr=":8003" -tunnelAddr=":4000"  > /dev/null 2>&1 &
apt-get install screen
screen -S 任意名字(例如:keepngork)
然后运行ngrok启动命令
最后按快捷键
ctrl+A+D
既可以保持ngrok后台运行

设置开机启动

vim /etc/init.d/ngrok_start:
cd /usr/local/src/ngrok/bin
./ngrokd -domain="ngrok.yangbingdong.com" -httpAddr=":8002" -httpsAddr=":8003" -tunnelAddr=":4000"

chmod 755 /etc/init.d/ngrok_start

客户端使用

下载客户端

scp -P 26850 root@12.34.56.78:/usr/local/src/ngrok/bin/ngrok ~/

12.34.56.78换成自己的VPS ip

启动客户端

写一个简单的配置文件,随意命名如 ngrok.cfg:

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

然后启动:

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

其中ybd是自定义的域名前缀,ngrok.cfg是上面创建的配置文件,8080是本地需要映射到外网的端口。
没有意外的话访问ybd.ngrok.yangbingdong.com:8002就会映射到本机的8080端口了。

控制台:

就是上图的Web Interface,通过这个界面可以看到远端转发过来的 http 详情,包括完整的 request/response 信息,相当于附带了一个抓包工具。

另外,Ngrok支持多种协议,启动的时候可以指定通过-proto指定协议,例如:

http协议

./ngrok -subdomain ybd -config=ngrok.cfg -proto=http 8080

tcp协议

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

应该会看到:

ngrok                                               (Ctrl+C to quit)

Tunnel Status                 online
Version                       1.7/1.7
Forwarding                    tcp://ybd.ngrok.yangbingdong.com:8002-> 127.0.0.1:8080
Web Interface                 127.0.0.1:4040
# Conn                        0
Avg Conn Time                 0.00ms

Nginx添加server

虽然可以访问,但是带着端口就让人不舒服,80端口又被Nginx占用,那么可以用过Nginx反向代理Ngrok。
Nginx的配置一般在/etc/nginx/conf.d或者/usr/local/nginx/conf.d里面:

#ngrok.yangbingdong.com.conf
upstream ngrok {
    server 127.0.0.1:8002;
    keepalive 64;
}

server {
    listen 80;
    server_name *.ngrok.yangbingdong.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:

nginx -s reload 

维护脚本

在网上看到的某大神写的维护脚本:

wget https://gist.githubusercontent.com/IvanChou/1be8b15b1b41bf0ce2e9d939866bbfec/raw/1a2445599fe7fd706505a6e103a9dc60b4d3a0ed/ngrokd -O ngrokd

##修改 脚本中的配置
vi ngrokd

chomd +x ngrokd
sudo mv ngrokd /etc/init.d/ngrokd

常见错误

在ngrok目录下执行如下命令,编译ngrokd

$ make release-server

出现如下错误:
GOOS="" GOARCH="" go get github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=release \
        -debug=false \
        -o=src/ngrok/client/assets/assets_release.go \
        assets/client/…
make: bin/go-bindata: Command not found
make: *** [client-assets] Error 127
go-bindata被安装到了$GOBIN下了,go编译器找不到了。修正方法是将$GOBIN/go-bindata拷贝到当前ngrok/bin下。

$cp /home/ubuntu/.bin/go14/bin/go-bindata ./bin

遇到的问题:source与./

写了一个Ngrok的安装脚本,然后chmod +x ngrok-installation.sh赋权,再./ngrok-installation.sh执行。
但是遇到了一个奇怪的问题:在脚本里面设置了环境变量并source让其生效,然而出现的结果是由于没有加载到环境变量导致找不到命令,百思不得解,Google了一把,发现了原因:

source命令与shell scripts的区别是:
我们在test.sh设置了AA环境变量,它只在fork出来的这个子shell中生效,子shell只能继承父shell的环境变量,而不能修改父shell的环境变量,所以test.sh结束后,父进程的环境就覆盖回去。
source在当前bash环境下执行命令,而scripts是启动一个子shell来执行命令。这样如果把设置环境变量(或alias等等)的命令写进scripts中,就只会影响子shell,无法改变当前的BASH,所以通过文件(命令列)设置环境变量时,要用source 命令。

然后直接source ngrok-installation.sh,安装成功!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容