在外的两大烦恼,一为无法免费下载论文,二为在国外受版权限制音乐都不能很愉快地欣赏,明明购买了音乐会员却一片灰色,即使使用阿里云服务器可以点亮却受限于少的可怜的1m带宽——连听首歌都会卡顿。
但因为IPv4地址数量有限,我们平时使用的宽带不会分配唯一的公网IP,即:正常情况下在互联网上无法定位我们,要建立通讯需要采取一些特殊的方法。
本篇博客采用ngrok实现穿透内网,使用shadowsocks搭建梯子建立连接。
注意:本博客仅供技术分享,请勿用此进行违法行为,一切后果概不负责!
技术概括
内网穿透,即在茫茫网络中发现你的机器,通过外网也能访问你的本地应用。
内网主机可以是你的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解析,分别是:
- 将
ngrok.example.com
解析到ip_vultr
- 将
*.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 | cd ngrok |
复制证书到配置的目录中
1 | cp rootCA.pem assets/client/tls/ngrokroot.crt -f |
编译ngrok服务器端
1 | make release-server |
编译ngrok客户端
注:编译之前请先对照列表确认自己内网主机的系统参数:
1 | Linux 平台 32 位系统:GOOS=linux GOARCH=386 |
我使用的是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
站点的端口。
而tunnelAddr
是ngrok
客户端连接服务端的端口。(我们这次的重点,后面客户端还需要用到)
以上端口都可以更改,但请记住更改的端口号。
至此,我们的云服务器端就已经配置完成,下面是内网主机客户端。
内网主机ngrok客户端配置
编写配置文件
将之前从云服务器生成的ngrok客户端传到内网主机上(假设放到/home/ngrok
目录下),在该目录创建一个ngrok.cfg
文件,写入以下内容:
1 | server_addr: "ngrok.example.com:6062" |
其中,第一行是我们和云服务器(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 | Centos执行这个: yum -y install git |
这里password换成自己想要的shadowsocks的密码,4321
是我们前面映射用到的端口号(需要一致)。
最后在外网的机器上安装shadowsocks客户端连接即可。(可以通过 GitHub shadowsocks 进行下载)
连接时的配置如下:
1 | "server" : "ip_vultr", // or: ngrok.example.com |
注意第一行可以是云服务器IP,也可以是自己解析过的域名。
第二行需要是云服务器上的端口(映射到内网主机上,仔细想想)
第三行就是刚才设置的shadowsocks密码啦~
设置内网主机ngrok开机自启
在/home/ngrok
目录下新建脚本ngrok.sh
,内容如下:
1 | cd /home/ngrok #此处更改为你自己的ngrok客户端的文件路径 |
接着我们来把ngrok启动脚本制作成系统服务。在 /etc/init.d目录下新建一个服务项目(其实就是新建一个名为“ngrok”的文件),代码如下:
1 | !/bin/sh |
保存上一步的文件,并赋予至少755的权限,shell命令如下:
1 | sudo chmod 755 /etc/init.d/ngrok |
接下来我们要注册ngrok的自启动服务,shell命令如下:
1 | cd /etc/init.d |
注:如果提示找不到程序,请使用sudo apt-get install sysv-rc-conf自行安装,安装前建议先更新系统,sudo apt-get update。
测试服务是否能启动成功,shell命令如下:
1 | sudo service ngrok start |
检查自启动的服务,shell命令如下:
1 | sudo sysv-rc-conf |
如果叉叉和上图一致就没问题啦~
至此,我们的任务全部完成了,可以重启内网主机看看哦~
感兴趣可以做一个小作业:如何通过ngrok内网穿透远程登录桌面? 欢迎在评论区分享你的答案。
有问题欢迎留言或者私信/邮件,谢谢支持!