centos下ngrok服务器搭建及ngrok客户端使用

ngrok 简介及作用

ngrok 是一款用 go 语言开发的开源软件,它是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道.ngrok 可以做 TCP 端口转发,对于 Linux 可以将其映射到 22 端口进行 SSH 连接,Windows 的远程桌面可以将其映射到 3389 端口来实现.同理,如果要做 MySQL 的远程连接,只需映射 3306 端口即可. 最重要的是可以本地调试微信开发,极其方便

开发前注意事项

  1. 防火墙设置:服务器和客户端都要关闭对应端口的防火墙,否则无法通过连接使用.ngrok默认端口是4443.

  2. 编译客户端及服务器时要注意系统是32位和64位,不能编译错了,否则将无法使用.

安装前的准备

除了ngrok是需要git下来安装 其他都通过yum安装(方便管理)

域名设置

假设你的域名是xxx.com,服务器地址是123.123.123.123则你需要解析2条A记录值到服务器

  1. 第一条是 @.xxx.com 第二条是 *.xxx.com

  2. 这样就可以任意二级域名就是作为你ngrok客户端的地址了

如果想使用二级域名则解析以下2个A记录值到服务器,假设你想使用的二级域名是ngrok.xxx.com

  1. 第一条是 ngrok.xxx.com 第二条是 *.ngrok.xxx.com

  2. 这样 子域名.ngrok.xx.com的三级域名就是作为你ngrok客户端的地址了

  3. 说明:

  4. 主机记录就是域名前缀,常见用法有:

  5. www:解析后的域名为www.aliyun.com。

  6. @:直接解析主域名 aliyun.com。

  7. *:泛解析,匹配其他所有域名 *.aliyun.com。

  8. mail:将域名解析为mail.aliyun.com,通常用于解析邮箱服务器。

  9. 二级域名:如:abc.aliyun.com,填写abc。

  10. 手机网站:如:m.aliyun.com,填写m。

  11. 显性URL:不支持泛解析(泛解析:将所有子域名解析到同一地址)

我使用的是二级域名解析 也就是ngrok.xxx.com

未分类

下载常用依赖库

yum -y install zlib-devel openssl-devel perl hg cpio expat-devel gettext-devel curl curl-devel perl-ExtUtils-MakeMaker hg wget gcc gcc-c++

安装go和git

yum -y install go git

我的是centos7.2 yum安装下来的git版本是1.8.3.1 go版本是1.8.3

要注意git版本必须大于1.7.9,go版本必须大于1.4,否则可能有意想不到的错误

开始安装ngrok

下载ngrok源码

个人习惯安装到/usr/local/目录下 如果你想安装到其他目录 则进入你想安装的目录

cd /usr/local/
git clone https://github.com/inconshreveable/ngrok.git ngrok

cd ngrok #进入ngrok目录,后面操作都是在ngrok目录下完成!

生成域名证书(确保在ngrok目录下)

#生成并替换源码里默认的证书,注意域名要修改为你自己的,这里是一个虚拟的测试域名
NGROK_DOMAIN="ngrok.xxx.com"

#测试一下有没有设置成功
echo $NGROK_DOMAIN #输出ngrok.xxx.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

之后会在 ngrok 目录下生成 root,device 等六个文件。 然后需要拷贝到配置的目录中,在编译的时候会使用这些文件。

cp -r rootCA.pem assets/client/tls/ngrokroot.crt
cp -r device.crt assets/server/tls/snakeoil.crt
cp -r device.key assets/server/tls/snakeoil.key

到这个地方,证书生成已经复制的准备工作就已经完成了。

生成服务器的ngrokd

make release-server

这样就会在bin目录下生成ngrokd 这个文件,就是我们ngrok的服务器程序

编译客户端ngrok(不同系统不同的命令如下)

  • 32位linux客户端: GOOS=linux GOARCH=386 make release-client

  • 64位linux客户端: GOOS=linux GOARCH=amd64 make release-client

  • 32位windows客户端: GOOS=windows GOARCH=386 make release-client

  • 64位windows客户端: GOOS=windows GOARCH=amd64 make release-client

  • 32位mac平台客户端:GOOS=darwin GOARCH=386 make release-client

  • 64位mac平台客户端:GOOS=darwin GOARCH=amd64 make release-client

  • ARM平台linux客户端: GOOS=linux GOARCH=arm make release-client

我这里是64位linux和64位windows客户端编译

GOOS=linux GOARCH=amd64 make release-client
GOOS=windows GOARCH=amd64 make release-client

依次执行这2个命令之后就会在bin目录里面生成所有的客户端文件,客户端平台是文件夹的名字,客户端放在对应的目录下,当前Linux平台客户端就直接在bin目录下一个ngrok的程序

配置启动服务器

  • httpAddr 是访问普通的http使用的端口号,用后面用 子域名.ngrok.xxx.com 来访问服务

  • httpsAddr 是访问的https使用的端口号,同上,只不过是需要https的服务访问才用这个端口(一般用不上)

  • tunnelAddr 是ngrok通道的端口号,这个端口是Ngrok用来通信的,所以这个端口在服务器上和客户端上设置必须要对应才可以正常的链接,默认端口是4443

完整命令

bin/ngrokd -domain="$NGROK_DOMAIN" -httpAddr=":80" -httpsAddr=":443" -tunnelAddr=":4443"

我使用的

bin/ngrokd -domain="$NGROK_DOMAIN" -httpAddr=":80"

其中NGROK_DOMAIN对应的就是一开始设置过的域名地址。

要注意我这里使用的是80端口。要确保服务器上没有apache或nginx占用80端口,后面会介绍使用其他端口的方式

配置windows客户端

首先先把bin目录下windows_amd64文件夹ftp或者sftp传到windows下并进入

然后新建一个 ngrok.cfg,在里面填写以下内容

server_addr: "ngrok.xxx.com:4443"
trust_host_root_certs: false

server_addr地址和服务器设置的 NGROK_DOMAIN=”ngrok.xxx.com” 中的地址保持一致,如果你服务器启动的时候设置了tunnelAddr端口则把4443也改成你设置的端口

启动客户端

完整命令

ngrok.exe -log=ngrok_log.txt -subdomain=test -config="ngrok.cfg" 80

我的命令

ngrok.exe -subdomain=test -config="ngrok.cfg" 80
  • 日志: -log=ngrok_log.txt 是记录ngrok的日志,如果前期调试的时候加上这个参数,如果不能访问就可以查看到底是什么问题

  • 子域名: -subdomain=test 是定义访问的时候的子域名,现在访问 test.ngrok.xxx.com 就可以访问到这一台机器上80端口的服务

ngrok

Tunnel Status online
Version 1.7/1.7
Forwarding https://test.ngrok.xxx.com -> 127.0.0.1:80
Forwarding http://test.ngrok.xxx.com -> 127.0.0.1:80
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms

online是绿色的 表示连接成功!

到这里不出意外的话就会启动成功了,访问test.ngrok.xxx.com的时候就是你本地的ip了.你可以通过apache或nginx配置test.ngrok.xxx.com域名指定你的目录开始使用啦~

你可以访问127.0.0.1:4040来看到所有对test.ngrok.xxx.com的请求~

用啥ngrok,用ssh解决大局域网反向端口转发问题

自从家里换了联通光纤后,联通就在我家宽带出口前搭了一个路由器,我家也彻底沦为192.168.1.0/24段的局域网了,带来的问题就是在外网无法访问家里的路由器。这对于刷了LEDE,有时候需要从外网直接管理使用路由器的我,觉得难受极了。周末有空,干脆解决这个问题。

在这之前,了解过一个ngrok项目,用于将局域网内的某一个地址的端口,映射到公网。但是研究了一下该软件,发现其在LEDE的源中,并不包含,我又是个懒的去编译的程序员,因此想看看有没有其他办法。

研究一下,发现其实程序员必备的SSH就有这个功能。SSH一共支持三种端口转发:

  • 本地端口转发:就是客户端方的某个端口和服务器某个端口相连,这样访问客户端该端口,就相当于访问服务器端某个端口

  • 远程端口转发:还是把客户端方的某个端口和服务器某个端口相连,只不过反向的,访问服务器端某个端口,就相当于访问到了客户端该端口

  • 动态转发:SOCKS5代理模式,不多说了

更具体一些,可以参见这篇文章:https://blog.twofei.com/528/

回到我的需求,我是希望访问VPS的某个端口,就相当于访问路由器的指定端口。比如我访问VPS的2222,就相当于访问路由器的22端口。所以是第二种:远程端口转发

SSH做起来非常简单,首先,修改VPS端/etc/ssh/sshd_config加入GatewayPorts yes。据说,不这样外网无法访问转发的端口,未验证。然后路由器一条命令搞定:

ssh -f -NR "*:2222:localhost:22" user@vps  

这样子,访问VPS的2222端口,就直接访问到了路由器

进化一:持久

用ssh命令有个问题,因为各种因素,它可能会莫名挂掉,网络不好啦,网络干扰啦,网络xxx啦,总归都是网络问题。因此,我们得祭出神奇autossh。在LEDE的包中,默认就有,安装之,爱死LEDE。在这之前,自己搞定SSH的密钥登录哦,否则autossh起来,也会卡在输入密码。 autossh在LEDE的配置文件是/etc/config/autossh,配置一下

config autossh 'ssh'  
    option gatetime '0'
    option monitorport '20000'
    option poll '600'
    option ssh '-p 22 -NR *:2222:localhost:22 user@vps'

然后开启autossh

进化二:隐藏

在我家的运营商,我发现了一个问题,如果你ssh启动一段时间后,到目的地址的网络丢包就开始大量出现。思来想去,把ssh塞到ssr-tunnel中不就完事了。

先建立一个到VPS的22端口的ssr-tunnel隧道

ssr-tunnel -c /var/etc/shadowsocksr.json -l 2222 -L VPS:22 -f /tmp/ssr-tunnel.pid >> /tmp/ssr-tunnel.log  

这样,访问本机的2222端口,就相当于走ssr流量访问远端的22端口。把autossh的配置稍微改一下,让其访问本机2222端口

config autossh 'ssh'  
    option gatetime '0'
    option monitorport '20000'
    option poll '600'
    option ssh '-p 2222 -NR *:2222:localhost:22 vpsuser@localhost'

为了让ssr-tunnel隧道保持运行,需要搞个监控。不需要很复杂,放到crontab里就可以了

ps | grep [s]sr-tunnel || `ssr-tunnel -c /var/etc/shadowsocksr.json -l 2222 -L vps:22 -f /tmp/ssr-tunnel.pid >> /tmp/ssr-tunnel.log`  

进化三:多射

映射了第一个端口,你就想再来一个。什么aria2映射出来,就可以做外网离线下载。其实也蛮简单的,因为autossh支持多端口映射

config autossh 'ssh'  
    option gatetime '0'
    option monitorport '20000'
    option poll '600'
    option ssh '-p 2222 -NR *:2222:localhost:22 -NR *:6800:localhost:6800 vpsuser@localhost'

这样就把aria2的6800也映射出来了

就这样,结束了.

related post: http://briteming.blogspot.com/2016/04/ngrok.html

SSH的三种端口转发(Port forwarding)/ 隧道协议概要

用SSH有一段时间了,自认为对ssh的操作还是有一定的了解。而今天我要介绍的是ssh的三种端口转发(隧道协议、Tunnel、Port forwarding)功能的使用与它们的使用场合。

为什么要用ssh的端口转发功能,我想大家一定明白(不明白也无所谓,既然来到了这里,你肯定是想把它弄明白的!)。一来是为了安全(数据加密传输);二来是为了突破(穿越)某些防火墙对某些主机的访问限制。

据我所知,SSH一共提供了 3 种端口转发,分别是本地转发(-L参数)、远程转发(-R参数)和动态转发(-D参数)。接下来我就一一介绍这几种不同的转发方式的使用。我尽量简明扼要地叙述主题重点,让人一看就学会(回忆起)该如何操作。

本文用到的一些“术语”和约定

既然提到转发,就应该明白:这是三台主机之间要合作干的事。不然为何不两台主机直连,而要通过第三者转发?
本地主机:形式为IP或域名,你当前正在使用的这台机器;
远程主机:形式与本地主机一样。这里的“远程”并不是指实际的距离有多远,准确地说是“另一台”;

本地转发

本地转发,顾名思义(有点)就是把本地主机端口通过待登录主机端口转发到远程主机端口上去。

本地转发通过参数 -L 指定,格式:-L [本地主机:]本地主机端口:远程主机:远程主机端口。加上ssh待登录主机,这里就有了三台主机。

举例:ssh -L 50000:www.google.com:80 user@host。例中本地主机、远程主机和待登录主机分别用颜色红绿蓝标识。

当成功执行上面的命令之后,访问本地的50000端口,就等同于访问 www.google.com 的 80 端口。但和直接访问有着本质的区别:这次是通过登录主机来安全转发数据的,没有人知道你和远程主机之间传输了何种数据。就算你不能和远程主机建立连接(而登录主机能访问),那就能突破(绕过)(防火墙的)限制。

但本例其实举得不够好。就算你能访问 www.google.com,你却依然不能其它主机,甚至是 google域 的另一台主机,比如 plus.google.com。想要更全面的端口转发功能,还需动态转发。

远程转发

远程转发是指把登录主机端口通过本地主机端口转发到远程主机。
远程转发通过参数 -R 指定,格式:-R [登录主机:]登录主机端口:远程主机:远程主机端口。

举例:ssh -R 0.0.0.0:8080:localhost:80 user@host。

当成功执行上面的命令之后,访问登录主机的 8080 端口就相当于访问 localhost:80!

不要小看这个例子,它可是有相当有用。我书读得多,不会骗你 ????
设想这样一种情况(其实这种情况太普遍了):你在本机开发了一个web应用,想拿给别人测试,但现在你却处在内网,外网是无法直接访问内网的主机的,怎么办!?很多人可能会说,找台有公网IP的主机,重新部署一下就行了。这样可行,但太麻烦。然而自从你了解了ssh的远程转发之后,一切都变得简单了。只需在本地主机上执行一下上面例子的命令即可实现外网访问内网的web应用,相信我,我经常就这样干,屡试不爽。这简直是太好了,awesome! 让你从此对ssh爱不释手。

动态转发

相对于本地转发和远程转发的单一端口转发模式而言,动态转发有点更加强劲的端口转发功能,即是无需固定指定被访问目标主机的端口号。这个端口号需要在本地通过协议指定,该协议就是简单、安全、实用的 SOCKS 协议。FQ(你懂的)就靠她了!

动态转发通过参数 -D 指定,格式:-D [本地主机:]本地主机端口。相对于前两个来说,动态转发无需再指定远程主机及其端口。它们由通过 SOCKS协议 连接到本地主机端口的那个主机(peer,比如最常见的浏览器)指定(此属协议内容,无需深究)。

举例:ssh -D 50000 user@host。

当成功执行上面这个命令后。通过协议告诉你要访问的远程主机及端口,然后你与目标主机之间的数据就通过登录主机安全地传输了。

最常见的用途:FQ(大家都懂的)。在浏览器中设置代理类型为 SOCKS(5),主机及端口:127.0.0.1:50000。然后 gg/ytb/tt/fb 等就一丝不挂地摆在眼前了!

CentOS 7 搭建ngrok服务器

IE8和IE9在实现跨域请求的时候使用XDomainRequest自己实现了一套,所以即使是使用jquery1.9.1版本也无法直接兼容IE8,IE9的跨域请求。

一、前提条件

需要一台云服务器和一个域名解析到该IP

二、环境安装

1、安装 gcc

yum install gcc

2、安装 git

yum install git

3、安装 go 语言环境

到网站https://golang.org/dl/查找最新的版本链接

下载

wget https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz

解压安装:

tar -C /usr/local/ -zxvf go1.8.linux-amd64.tar.gz

添加环境变量,编辑:vi /etc/profile,在最后添加:

#go lang
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin

使环境变量生效

source /etc/profile

检查是否安装成功:

go version

输出:go version go1.8 linux/amd64表示安装成功

三、在服务器搭建 ngrok 服务

1、下载 ngrok 源码

cd /usr/local/src
git clone https://github.com/inconshreveable/ngrok.git

2、生成证书

在自生成证书时需要一个解析到服务器上的主域名,现在以”dogjun.com”为例:

cd ngrok
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=dogjun.com" -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=dogjun.com" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000

将新生成的证书,替换掉assets/client/tls下的证书

yes|cp rootCA.pem assets/client/tls/ngrokroot.crt
yes|cp device.crt assets/server/tls/snakeoil.crt
yes|cp device.key assets/server/tls/snakeoil.key

3、编译生成ngrokd(服务端)

#这里是交叉编译,linux系统GOOS=linux,64位系统GOARCH=amd64,32位系统GOARCH=386
#当前系统可用go env查看
GOOS=linux GOARCH=amd64 make release-server

编译成功后在当前目录的bin目录下可找到ngrokd文件

启动服务端(/usr/local/src/ngrok目录下)

./bin/ngrokd -tlsKey="assets/server/tls/snakeoil.key" -tlsCrt="assets/server/tls/snakeoil.crt" -domain="uboff.com"  -httpAddr=":80" -httpsAddr=":8081" -tunnelAddr=":4443"

后台运行

nohup ./bin/ngrokd -tlsKey="assets/server/tls/snakeoil.key" -tlsCrt="assets/server/tls/snakeoil.crt" -domain="ngrok.dogjun.com"  -httpAddr=":80" -httpsAddr=":8082" -tunnelAddr=":4443" &

出现下面信息,启动成功

[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:80
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:8081
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds

4、编译生成ngrok(客户端)

这里生成windows下的客户端:

GOOS=windows GOARCH=amd64 make release-client

成功会在bin目录下看到windows_amd64文件夹,复制到windows电脑上即可启动

在windows_amd64目录下新建一个ngrok.cfg文件,内容如下:

server_addr: "ngrok.dogjun.com:4443"
trust_host_root_certs: false

然后就可以启动客户端,我已经把windows_amd64文件夹下载到E盘下,打开CMD输入:

ngrok -subdomain hwj -config=ngrok.cfg 80

看到下面信息则启动成功:

Tunnel Status                 online
Version                       1.7/1.7
Forwarding                    http://hwj.ngrok.dogjun.com -> 127.0.0.1:80
Forwarding                    https://hwj.ngrok.dogjun.com -> 127.0.0.1:80
Web Interface                 127.0.0.1:4040
# Conn                        1
Avg Conn Time                 0.00ms

搭建自己的ngrok服务器-debian版

作为一个Web开发者,我们有时候会需要临时地将一个本地的Web网站部署到外网,以供他人体验评价或协助调试等等,通常我们会这么做:

  1. 找到一台运行于外网的Web服务器。
  2. 服务器上有网站所需要的环境,否则自行搭建
  3. 将网站部署到服务器上
  4. 调试结束后,再将网站从服务器上删除

只不过是想向朋友展示一下网站而已,要不要这么麻烦,累感不爱。

安装go lang环境

wget http://www.golangtc.com/static/go/1.7.3/go1.7.3.linux-amd64.tar.gz

常见的不同版本根据下方来匹配(可以到这里下载):

mac: darwin-amd64
ubuntu: linux-amd64
centos: linux-386

或者使用命令安装:

apt-get install golang-go

安装git

apt-get install git

git clone ngrok源码,编译

ngrok源码:https://github.com/inconshreveable/ngrok.git

进入/usr/local目录

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

引入临时的全局环境变量,此次登录有效

# 这个等会编译的时候要用
export GOPATH=/usr/local/ngrok/
# 这个是你自己的域名,可以是二级或三级域名
# 注意,这边ngrok.gabin.top和它的所有子域名都必须指向中转服务器,我最开始就是没有注意这点,导致各种没报错,但是就是不能用
export NGROK_DOMAIN="atecher.net"

替换域名证书,注意到了吗,NGROK_DOMAIN这个环境变量是我们刚刚设置的。

#生成证书
cd /usr/local/ngrok
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
#替换证书
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp server.crt assets/server/tls/snakeoil.crt
cp server.key assets/server/tls/snakeoil.key

开始生成服务端执行文件

# 自己注意下,不同操作系统“GOARCH”是不一样的参数,上面也有写到了
GOOS=linux GOARCH=amd64 make release-server

成功之后在/usr/local/ngrok/bin目录下会生成一个ngrokd的文件,这就是服务端的启动执行文件了

生成客户端可执行文件

#--mac
cd /usr/local/ngrok
GOOS=darwin GOARCH=amd64 make release-client
#--window
cd /usr/local/ngrok
GOOS=windows GOARCH=amd64 make release-client
#成功之后在/usr/local/ngrok/bin目录下会生成对应的目录,一般是darwin_amd64和window_64,前一个是mac的,后一个是window的

替换掉引用(国内被墙了,没法用)

vim /usr/local/ngrok/src/ngrok/log/logger.go
# 替换掉import中log的引用,记得删除旧的,别注释了,会报错哈哈
log "github.com/keepeye/log4go"

调试

  • 启动服务端,这边使用的是80端口。一般都需要用这个,原本想用反向代理,发现好像是不行。如果有发现可以的朋友,可以分享一下。

如果需要在后台执行的话,参考nohup命令

# 由于NGROK_DOMAIN是临时的环境变量,所以如果要重复使用的话,这个变量最好保存起来,否则下次登录就失效了。
/usr/local/ngrok/bin/ngrokd -domain="$NGROK_DOMAIN" -httpAddr=":80"
  • 启动客户端

先设置好配置文件:同目录下创建一个ngrok.cfg

server_addr: "blog.atecher.net:4443"
trust_host_root_certs: false
# 通过配置文件启动,这边的端口代表的是自己本地调试程序启用的端口,一般是8080
./ngrok -config=./ngrok.cfg -subdomain=blog 80

好了,可以用了。访问以下 blog.atecher.net

PS:

  1. 其实主要就是装好go环境,如果想学习新的程序语言,可以考虑下这个最近正火的语言
  2. 需要知晓基础的一些知识:环境变量、证书、make(虽然我也不是很懂,总之做多了会有点感觉,就感觉这么做是对的…)
  3. 如果没有测试环境可以用的话,可以购买特价的国际域名,一般一年不要十几二十块的,然后申请个像是华为企业云的服务器(本人就申请了一个1块钱15天的试用服务),就可以自己动手尝试了
  4. 其实自己没有服务器资源的可以使用国人分享出来的,百度搜索一下,最近看着还蛮多的