需求:利用具有公网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 [email protected]
这句命令的意思是将访问服务器的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;