Fork me on GitHub

ngrok实现内网穿透并设置开机启动,可以通过ssh远程控制主机,校外也能看论文。

在外的两大烦恼,一为无法免费下载论文,二为在国外受版权限制音乐都不能很愉快地欣赏,明明购买了音乐会员却一片灰色,即使使用阿里云服务器可以点亮却受限于少的可怜的1m带宽——连听首歌都会卡顿。
但因为IPv4地址数量有限,我们平时使用的宽带不会分配唯一的公网IP,即:正常情况下在互联网上无法定位我们,要建立通讯需要采取一些特殊的方法。
本篇博客采用ngrok实现穿透内网,使用shadowsocks搭建梯子建立连接。
注意:本博客仅供技术分享,请勿用此进行违法行为,一切后果概不负责!

ngrok原理

技术概括

内网穿透,即在茫茫网络中发现你的机器,通过外网也能访问你的本地应用。

内网主机可以是你的PC,也可以是实验室的服务器(请确保授权),甚至可以是你的树莓派等等等~

解决方案有多个,包括花生壳、nat123、ngrok、frp等。这些有些是收费的(并且一味依赖他人服务可能稳定性、安全性略有缺失),有些实现起来颇有难度,本篇采用ngrok方案实现内网穿透,如果你手头有可支配的云主机、域名那就非常方便。如果没有,也可以考虑租用购买一个便宜的,有些域名(如.site)八元就可以买一年(但需要注意部分廉价域名可能无法备案,在国内不能正常使用,如.tech听说不行),阿里云的学生计划也可以很便宜地租到服务器(阿里云服务器学生计划),由于不是本篇重点这里就不多谈了。

总体来说,我们需要在云服务器部署ngrok的服务端,在内网主机部署ngrok的客户端,将域名DNS解析到云服务器(后面细讲),最后在外网通过云服务器端口映射访问内网主机。(参照最上方的图解)

安装配置ngrok服务器端

这里我使用的是阿里云购买的域名,假设域名为example.com

我的云主机使用的是vultr旧金山节点的服务器(阿里云的也可以使用),下文将用ip_vultr代替我的服务器IP地址。

内网主机安装的是Ubuntu 16.04 server版本。

操作过程中如果遇到permission denied问题可以尝试在命令前加sudo(权限问题)

设置域名解析

需要设置两个A记录DNS解析,分别是:

  1. ngrok.example.com解析到ip_vultr
  2. *.ngrok.example.com解析到ip_vultr(泛域名解析)

注意:实际操作中只要域名前面部分就行,即ngrok*.ngrok,这个字符串可以修改,不过后面不能忘记。

安装依赖项

1
sudo apt-get install gcc golang

下载代码

1
git clone https://github.com/mamboer/ngrok.git

生成ssl证书

1
2
3
4
5
6
7
cd ngrok
domain="ngrok.example.com"
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$domain" -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=$domain" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000

复制证书到配置的目录中

1
2
3
cp rootCA.pem assets/client/tls/ngrokroot.crt -f
cp device.crt assets/server/tls/snakeoil.crt -f
cp device.key assets/server/tls/snakeoil.key -f

编译ngrok服务器端

1
make release-server

编译ngrok客户端

注:编译之前请先对照列表确认自己内网主机的系统参数:

1
2
3
4
5
6
7
8
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

我使用的是64位Ubuntu:

1
export GOOS="linux" GOARCH="amd64" && make release-client

编译完成后请将生成的客户端下载下来(在/ngrok/bin文件夹中,Linux是ngrok文件,Windows是在这个目录子文件夹中的ngrok.exe文件)

如果使用xshell连接云主机推荐使用lrzsz进行文件传输:

1
sudo apt-get install lrzsz

rz是上传文件到云服务器,sz file是下载文件到本地。

当然你也可以使用其他软件(如WinSCP)传输文件。

运行ngrok服务器端

1
/ngrok/bin/ngrokd -domain="ngrok.example.com" -httpAddr=":6060" -httpsAddr=":6061" -tunnelAddr=":6062"

注:ngrokd是生成的服务器端程序,如果反应找不到那可能是目录定位问题,可以cd到安装目录打开。

httpAddr以及httpsAddr分别是反向代理http以及https站点的端口。

tunnelAddrngrok客户端连接服务端的端口。(我们这次的重点,后面客户端还需要用到)

以上端口都可以更改,但请记住更改的端口号。

至此,我们的云服务器端就已经配置完成,下面是内网主机客户端。

内网主机ngrok客户端配置

编写配置文件

将之前从云服务器生成的ngrok客户端传到内网主机上(假设放到/home/ngrok目录下),在该目录创建一个ngrok.cfg文件,写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
server_addr: "ngrok.example.com:6062"
trust_host_root_certs: false
tunnels:
ss:
remote_port: 38383
proto:
tcp: 4321

ssh:
remote_port: 12345
proto:
tcp: 22

其中,第一行是我们和云服务器(ngrok服务器端)连接的方式:域名 + ngrok连接端口(请注意区分本篇博客的几个端口)

后面是我们的配置,

ss是 shadowsocks 的配置,将服务器端38383端口转发到本地的4321端口,即如果我们通过 shadowsocks 连接云服务器的38383端口,那么便会通过ngrok映射到内网主机的4321端口。

ssh是一个加密的网络传输壳协议,通过它我们可以远程连接控制主机。ssh的端口是22,这里将服务器端12345端口映射到客户端的22

这里其实还可以配置其他很多东西,比如HTTP(本地建站解决方案?)、xrdp(Linux图形界面)、mstsc(Windows远程桌面)等,有兴趣的可以自己研究一下~

小tip: 该文件格式不能使用Tab,否则会报错:
YAML error: line 1: found character that cannot start any token
请将Tab换成空格

运行ngrok客户端

使用如下命令启动客户端(再次提醒注意定位ngrok文件位置)

1
ngrok -log=ngrok.log -config=ngrok.cfg start ssh ss

运行后应该显示正在连接(connecting),直到绿色的online便是连接成功~

如果报错请先去掉最后的sh运行,或者先安装shadowsocks再运行。

安装使用shadowsocks(如果只需要内网穿透请忽略这一段)

为了防止大家概念混淆前面一直没有讲shadowsocks(对,我一开始看别人的教程就晕过qaq)

除了上面说过的服务器端客户端,shadowsocks(也就是常被用来搭建VPN的工具)将再引入一组服务器端客户端。

也就是说,安装shadowsocks,我们的内网主机(ngrok的客户端)将被作为shadowsocks的服务器端,在我们外网的机器上将安装shadowsocks的客户端,这样我们就可以通过shadowsocks将内网主机作为跳板访问内网资源了。

由于shadowsocks经常被人们拿来做不法用途,这里就不细讲了,感兴趣的可以上网搜索相关教程。这里推荐一个一键脚本。

服务器端可以使用下面的一键脚本安装:

1
git clone https://github.com/flyzy2005/ss-fly
1
2
3
4
Centos执行这个: yum -y install git
Ubuntu/Debian执行这个: apt-get update && apt-get -y install git

ss-fly/ss-fly.sh -i password 4321

这里password换成自己想要的shadowsocks的密码,4321是我们前面映射用到的端口号(需要一致)。

最后在外网的机器上安装shadowsocks客户端连接即可。(可以通过 GitHub shadowsocks 进行下载)

连接时的配置如下:

1
2
3
"server" : "ip_vultr",  // or: ngrok.example.com
"server_port" : 38383,
"password" : "password",

注意第一行可以是云服务器IP,也可以是自己解析过的域名。

第二行需要是云服务器上的端口(映射到内网主机上,仔细想想)

第三行就是刚才设置的shadowsocks密码啦~

设置内网主机ngrok开机自启

/home/ngrok目录下新建脚本ngrok.sh,内容如下:

1
2
cd /home/ngrok #此处更改为你自己的ngrok客户端的文件路径
./ngrok -config=./ngrok.cfg start ssh ss

接着我们来把ngrok启动脚本制作成系统服务。在 /etc/init.d目录下新建一个服务项目(其实就是新建一个名为“ngrok”的文件),代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/sh
#chkconfig:2345 70 30
#description:ngrok

ngrok_path=/home/ngrok #此处更改为你自己的启动脚本的文件路径
case "$1" in
start)
echo "start ngrok service.."
sh ${ngrok_path}/ngrok.sh
;;
*)
exit 1
;;
esac

保存上一步的文件,并赋予至少755的权限,shell命令如下:

1
sudo chmod 755 /etc/init.d/ngrok

接下来我们要注册ngrok的自启动服务,shell命令如下:

1
2
3
cd /etc/init.d
sudo update-rc.d ngrok defaults
sudo update-rc.d start 70 2 3 4 5

注:如果提示找不到程序,请使用sudo apt-get install sysv-rc-conf自行安装,安装前建议先更新系统,sudo apt-get update。

测试服务是否能启动成功,shell命令如下:

1
sudo service ngrok start

检查自启动的服务,shell命令如下:

1
sudo sysv-rc-conf

ngrok原理

如果叉叉和上图一致就没问题啦~

至此,我们的任务全部完成了,可以重启内网主机看看哦~

感兴趣可以做一个小作业:如何通过ngrok内网穿透远程登录桌面? 欢迎在评论区分享你的答案。

有问题欢迎留言或者私信/邮件,谢谢支持!

参考资料

使用ngrok+shadowsocks穿透内网校外也能畅快看论文

Windows&Linux下设置ngrok开机自启动

一分钟实现内网穿透(ngrok服务器搭建)

文章作者:Jinguo Dong (董金国)

最后更新:2019年01月16日 21:01:33

原始链接:http://blog.djinguo.com/2019-01-14/ngrokpenetrate/

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 3.0 许可协议,转载请注明出处!

0%