共计 2240 个字符,预计需要花费 6 分钟才能阅读完成。
需求:利用具有公网 ip 的服务器让处在不同局域网的客户端能够相互通信。比如,学校某机房的电脑能通过自建的网站直接上传文件到自己的手机上,或者从手机上下载文件,访问手机内网搭建的网站等(手机上用 termux 作为内网穿透工具)。当然,处在不同局域网的电脑之间也能通过同样的配置达到互相通信的效果。(注意,此处不是简单的文件上传到服务器然后再在服务器上下载文件,而是利用 nginx 转发请求到局域网的另一台机器,后者实用性远高于前者)
互联网上实现该需求的软件有很多,比如向日葵,ngrok,frp 等,小编也尝试过一些,但毕竟是通过别人的服务器代理,安全性是不如自己的私有服务器的。于是小编经过一番研究和踩坑,终于发现了如下实现方法,亲测有效。
公网服务端:需要一台具有公网 ip 的服务器,这个是必须的,大家没有的话可以去阿里云或者 vultr 这些服务器提供商买一台,没钱的话参考小编的这篇文章领两台永久免费的:注册甲骨云使用永久免费套餐搭建个人博客
局域网服务端:安卓手机一台(或者具有 ssh 环境的其他客户端也行),型号不限,但要搭建好 termux 的 ssh 环境,不会使用 termux 的同志可以看看我这两篇文章:安卓神器 termux 入门教程,玩转 termux
在终端(此处为 termux)中输入:
ssh -o ServerAliveInterval=60 -fNR 6666:1.1.1.1:8080 root@1.2.3.4
这句命令的意思是将访问服务器的 6666 端口的请求转发到内网(termux)的 8080 端口上。需要将 1.1.1.1 修改成你的内网 ip,可通过 ifconfig 命令查看内网 ip,或者直接使用本地环回地址 127.0.0.1 也行。本地 8080 端口也可以修改成你打开了 web 服务的相应端口。root 是服务器的默认用户名,不是 root 请自行更改。1.2.3.4 是服务器公网 ip 地址,可在服务器上通过命令 curl ifconfig.me 获取。
-o ServerAliveInterval=60 的意思是在隧道无通信后的 60 秒发送一个请求给服务器,就是为了保持隧道的连接,避免长时间无请求导致隧道断开链接。- f 选项是后台认证,不用登录服务器,仅在需要输入服务器密码时弹出认证。- N 选项是不执行远程命令,这里只进行端口转发。- R 选项是指将远程端口映射到本地端口。如果服务器使用了密钥登录,该命令不会有任何输出。
这样,局域网服务端就搭建好了,记得打开 termux 的端口服务方可正常使用。
公网服务端请登录云服务器,编辑 nginx 配置文件,在你的网站的 server 模块加入以下内容:
location ^~ /test/ {
proxy_redirect off;
proxy_pass http://127.0.0.1:6666/; # 将请求转发到本地 6666 端口,进而转发到内网相应的端口
client_max_body_size 1024M; # 允许上传大文件
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
NGINX
重启 nginx 使设置生效:
nginx -s reload
随后访问你的网站域名加路径 test 即可访问到你的内网端口提供的页面,如小编搭建的就是访问 https://www.sfnote.com/test。
最后需要注意的是此处通过域名访问内网资源时,内网文件中的超链接必须使用相对路径,如果是绝对路径,将以域名的根路径为根路径,比如:假设你的内网 php 文件中 css 链接为”/css/basic.css”,那么服务器将处理为 sfnote.com/css/basic.css,而服务器上这个文件根本不存在,就会导致无法正常加载 css,此时将超链接改为”./css/basic.css”即可,js 和图像等资源的超链接也是如此。如果超链接指向目录,则结尾必须加上斜杠,例如”./web/apps/”而不能是”./web/apps”,其中 apps 为一个目录,不然也会以域名为根路径导致出现 404 页面。如果大家发现能在 nginx 配置文件中解决此问题的方法,请在评论区告知,感激不尽。
termux 中想要搭建上传文件到 termux 服务的话,需要增加 php 配置,因为默认 php 只允许上传 2m 以内的文件,在 termux 中输入以下命令完成配置:
echo -e "upload_max_filesize = 1024M;\npost_max_size = 1024M;\nmax_excution_time = 30000;\nmax_input_time = 600;\nmemory_limit = 1024M;" >> /data/data/com.termux/files/usr/lib/php.ini
pkill php-fpm; php-fpm
同时 termux 中的 nginx 部分也要配置,打开配置文件,在对应的 http 模块中加入以下语句后重启 nginx 即可:
client_max_body_size 1024M;
以上就是利用 ssh 和 nginx 反向代理实现内网穿透的方法,大家有疑问或更好的办法请在评论区告知。