#没时间整理 error!!
编译分两块:
服务端
配套客户端
客户端是需要和服务端匹配的,在编译的时候是要指定域名证书的,所以不用担心别人用其他的客户端去连你的服务端。
编译准备
一个vps,阿里云或者其他,linux系统即可,这里我推荐debian或ubuntu.
一个域名,将域名泛解析到你的服务器上。
为服务器安装git和go
我就直接在我的博客服务器上编译了,我准备使用
ngrok.ekan001.com
作为动态域名的根,记得泛解析。
首先我们需要在服务器上安装go环境,我建议下载最新版的go包,直接解压到服务器(也可以直接apt-get install)
/usr/local/go
即可,然后将
/usr/local/go/bin/*
复制到
/usr/bin/
。
go的下载地址:http://www.golangtc.com/download 下载和你服务器系统对应的版本即可,这里我是linux 64位的,就选择下载
go1.4.2.linux-amd64.tar.gz
即可。
接着,下载ngrok源码:
cd /usr/local/src/
git clone https://github.com/inconshreveable/ngrok.git
export GOPATH=/usr/local/src/ngrok/
export NGROK_DOMAIN=”ngrok.ekan001.com”
cd ngrok
(我是下好ngrok_master放到/home/lym/goproj/src目录下的
然后cd ~/goproj/src/ngrok_master)
开始编译
首先为根域名生成证书
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
编译服务端
服务端比较容易,先指定一下我的环境变量,然后再make:
GOOS=linux GOARCH=amd64
#如果是32位系统,这里 GOARCH=386
然后make
make release-server
按理讲,应该就可以编译成功了,但是我发现,编译的时候很多依赖包是需要自动下载的,有一个包
log4go
是在 code.google 上的,我们天朝服务器是无法访问google的,大家懂,所以我这里是这么处理的:修改源码,将该包改为 github 上的地址:
找到
/usr/local/src/ngrok/src/ngrok/log/logger.go
,第五行import中的 log 包,改为:
log “github.com/keepeye/log4go”
。
然后重新
make release-server
。
接下来可能还会遇到一个问题,编译时在
go get gopkg.in/yaml.v1
步骤时候卡住,这是因为git版本太低,请将服务器git版本升级到1.7.9.5以上。
或许:
install hg(sudo apt-get install mercurial)
编译成功后,应该可以在
/usr/local/src/ngrok/bin
下生成了一个
ngrokd
可执行文件,这就是我们的服务端了,现在启动服务端试试:
bin/ngrokd -domain=”$NGROK_DOMAIN” -httpAddr=”:8000”
如果没有报错的话,会出现以下输出:
[10:05:48 CST 2015/04/17] [INFO] (ngrok/log.(PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[10:05:48 CST 2015/04/17] [INFO] (ngrok/log.(PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
[10:05:48 CST 2015/04/17] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:8000
[10:05:48 CST 2015/04/17] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:443
[10:05:48 CST 2015/04/17] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
现在先
ctrl+c
退出,我们还需要编译客户端呢。
编译客户端
我的本机系统是 mac osx ,64位,对应的 GOOS 和 GOARCH 是这样的:
GOOS=darwin GOARCH=amd64
然后我直接编译:
make release-client
编译是成功了,但是我发现编译出来的东西是
bin/ngrok
,它还是linux平台的包,我mac上无法执行。原因是我们没有为go生成交叉编译环境,需要补充下面的一个步骤:
前文说到,我们的 go 安装在
/usr/local/go
,现在我们执行下面的命令:
cd /usr/local/go/src
GOOS=darwin GOARCH=amd64 ./make.bash
然后回去ngrok目录,接着编译:
cd -
GOOS=darwin GOARCH=amd64 make release-client
完了以后可以在
/usr/local/src/ngrok/bin/darwin_amd64/
下发现
ngrok
文件,将它拷贝到我的mac上。
如果是windows下的客户端,是这样的:
cd /usr/local/go/src
GOOS=windows GOARCH=amd64 ./make.bash
cd -
GOOS=windows GOARCH=amd64 make release-client
#同理,这里的amd64是64位系统,32位改成386
#应该会在 bin/windows_amd64 目录下生成ngrok客户端程序
到这里,编译就完成了,现在让我们把应用跑起来:
按之前的方式启动服务端ngrokd,有以下提示:
Listening for public http connections on [::]:8000
Listening for control and proxy connections on [::]:4443
记住这两个端口 8000 和 4443 。
现在我们来到自己电脑上,准备启动客户端。在启动之前,我们需要为客户端编写一个配置文件 ngrok.cfg :
server_addr: “ngrok.ekan001.com:4443”
trust_host_root_certs: false
注意,配置文件中用的是4443端口。
然后启动客户端,假设我们要分配一个域名
test.ngrok.ekan001.com
执行以下命令:
./ngrok -config=./ngrok.cfg -subdomain=test 80
如果是用来做ss转发的话加上 -proto=tcp
解释一下参数:
-config 就是上面配置文件ngrok.cfg的路径
-subdomain 就是需要分配域名的前缀部分
80 就是本机websever的端口,比如apache监听的端口,一会ngrok会将请求映射到该端口上。
如果没错误,应该会出现以下的输出:
Tunnel Status online
Version 1.7/1.7
Forwarding http://test.ngrok.ekan001.com:8000 -> 127.0.0.1:80
Forwarding https://test.ngrok.ekan001.com:8000 -> 127.0.0.1:80
Web Interface 127.0.0.1:4040
Conn 0
Avg Conn Time 0.00ms
现在,访问
test.ngrok.ekan001.com:8000
,ngrok服务端就会讲请求转发到我们本地客户端,再由客户端转发给我们的webserver 80端口。所以,我们只需要配置apache或nginx,添加虚拟主机,绑定域名
test.ngrok.ekan001.com
即可。
事情还没有结束!
我们前面提到,微信开发中的api地址,是不认80以外的端口的,所以如果我们将
test.ngrok.ekan001.com:8000
作为接口域名,得到的只能是 非法地址 或 配置失败 这个提示。
为什么在启动服务端的时候,端口不指定为80呢?就像下面:
bin/ngrokd -domain=”$NGROK_DOMAIN” -httpAddr=”:80”
很遗憾,因为这台vps不是只用来做ngrok服务的,我博客还在上面呢,80端口已经被nginx占用了。
那怎么办?
不得不提nginx是个牛逼的软件,我们可以在nginx中配置一个server,就绑定
test.ngrok.ekan001.com
域名,然后将所有请求转发到后端
:8000
端口上,这就是反向代理。我发一下自己的nginx配置:
#ngrok.ekan001.com.conf
upstream nodejs {
server 127.0.0.1:8000;
keepalive 64;
}
server {
listen 80;
server_name *.ngrok.ekan001.com;
access_log /home/wwwlogs/ngrok.ekan001.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host:8000;
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Connection “”;
proxy_pass http://nodejs;
}
}
总结:
生命在于折腾,enjoy it!
前言
最近想要在校园网内搭建一个VPN服务,但是因为校园网,所以没有公网IP,只好做内网穿透了,之前做了一些n2n以及ssh隧道的尝试,这次使用ngrok反向代理尝试一下:
由于最初没有安装go环境,以及下载go环境的一些不方便,曾打算使用ngrok-c,但是尝试以后,发现貌似仅支持openwrt。。。可能是我学艺不精吧,如果可以请私信我。
搭建环境:
局域网外(公网)
- 阿里云的ECS服务器
- Ubuntu 16.04 64位 系统
- 用户:root
局域网内
- 树莓派
- Ubuntu 系统
-公网服务器端
安装go环境
别人的博客:
#wget https://golangtc.com/static/go/1.8.3/go1.8.3.linux-amd64.tar.gz
wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz
tar zxvf go1.8.3.linux-amd64.tar.gz
mv go /usr/local/
emmmm,反正我是两个都下载失败了的,也是我一开始放弃go的原因.
直到,我使用了以下操作…
apt-get install golang
其他博客里的环境变量配置,我于是也没去弄了,其实是弄崩了一次bash。。
ngrok的配置
1.下载ngrok源码
方法一
git clone https://github.com/inconshreveable/ngrok.git
export GOPATH=~/ngrok
cd ngrok
方法二
wget htps://coding.net/u/sfantree/p/self_use_OSS/git/raw/master/source/ngrok.tar.gz
tar zxvf ngrok.tar.gz
export GOPATH=~/ngrok
cd ngrok
2.生成签名证书
使用ngrok.com官方服务时,我们使用的是官方的SSL证书。自建ngrokd服务,我们需要生成自己的证书,并提供携带该证书的ngrok客户端。
证书生成过程需要一个NGROK_BASE_DOMAIN。如果你要提供服务的地址为”temple.com”,那NGROK_BASE_DOMAIN就应该 是”temple.com”。就假设我的服务域名是temple.com。
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj “/CN=temple.com” -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj “/CN=temple.com” -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000
执行完以上命令,在ngrok目录下会生成6个新的文件
device.crt device.csr device.key
rootCA.key rootCA.pem rootCA.srl
3.替换证书
ngrok通过bindata将ngrok源码目录下的assets目录(资源文件)打包到可执行文件(ngrokd和ngrok)中 去,assets/client/tls和assets/server/tls下分别存放着用于ngrok和ngrokd的默认证书文件,我们需要将它们替换成我们自己生成的:(因此这一步务必放在编译可执行文件之前)
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key
4.编译ngrokd(服务端)和ngrok(客户端)
在ngrok目录下执行如下命令,编译ngrokd:
GOOS=linux GOARCH=amd64 make release-server
go支持交叉编译的平台非常多,详见 GO中文文档
#64位linux server
make release-server GOOS=linux GOARCH=amd64
#32位linux server
make release-server GOOS=linux GOARCH=386
emmm,据说别的博客一般会出现两种错误,但遗憾的是我并没有遇到。
同样,在ngrok目录下编译ngrok:
我的客户端是运行在树莓派上,所以执行
GOOS=linux GOARCH=arm make release-client
编译完成过后~/ngrok/bin/ngrokd即为服务端运行文件
编译完成过后~/ngrok/bin/linux_arm/ngrok即为树莓派客户端运行文件
至此,文件编译已经完成,可以进行调试了。
调试
1.启动ngrokd(服务器)
cp ~/ngrok/bin/ngrokd /usr/bin/
ngrokd -domain=”temple.com” -httpAddr=”:6000”
若弹出The program ‘ngrokd’ is currently not installed. You can install it by typing: apt install ngrok-server
不要使用它提供的语句,可以使用 find / -name ngrokd 找到在/root/ngrok/bin/ngrokd目录,于是
cd /root/ngrok/bin
./ngrokd -domain=”temple.com” -httpAddr=”:6000”
然后,正常的服务日志就出来了
[17:28:09 CST 2017/11/06] [INFO] (ngrok/log.(PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[17:28:09 CST 2017/11/06] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:6000
[17:28:09 CST 2017/11/06] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
[17:28:09 CST 2017/11/06] [INFO] (ngrok/log.(PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
客户端的使用
在树莓派上用scp root@temple.com:ngrok/bin/linux_arm/ngrok /home/pi/ngrok将bin文件夹下载到树莓派上。
cd ~/ngrok/bin
cat > ngrok.conf <<EOF
#必须是 域名:隧道端口 的格式
server_addr: “temple.com:4443”
#自行编译无需验证ngrok官网证书
trust_host_root_certs: false
tunnels:
http:
remote_port: 26321
proto:
tcp: 80
EOF
其中26321为服务器端口,不要与其他冲突即可,我这里随便打的。
80为本地转发端口,主要决定于你想将哪个端口转发出去。
4443我没有修改,使用的是默认值。
客户端启动
./ngrok -config=ngrok.conf start http
或者说将文件放入/usr/bin 中就不需要再加入路径。
cp /home/pi/ngrok/ngrok /usr/bin
cp /home/pi/ngrok/ngrok.conf /usr/bin
ngrok -config=ngrok.conf start http
完成
ngrok
Tunnel Status online
Version 1.7/1.7
Forwarding tcp://temple.com:26321 -> 127.0.0.1:80
Web Interface 127.0.0.1:4040
Conn 0
Avg Conn Time 0.00ms
多端口转发
可以进行多端口转发,方法如下:
文件ngrok.conf 内容如下设置
cd ~/ngrok/bin
cat > ngrok.conf <<EOF
#必须是 域名:隧道端口 的格式
server_addr: “temple.com:4443”
#自行编译无需验证ngrok官网证书
trust_host_root_certs: false
tunnels:
http1:
remote_port: 26321
proto:
tcp: 80
http2:
remote_port: 23422
proto:
tcp: 2313
EOF
运行
ngrok -config=ngrok.conf start http1 http2即可