用内网PC当服务器的几种实现方案的比较

一直有一个想法,如何把身边的PC当成服务器给外网用户提供服务,比如搭建一个网站呢?最近研究了一下,踩了一些坑把过程和结果分享一下:

第一种方法是直接访问:

当分配给用户的外网IP地址发生变化时及时修改动态域名解析指向。这个方案最简单,但是也有很多问题,最大的问题是如今想获得一个外网IP已经很难了,即使非固顶IP也很难,所以这个方案已经没有了可行性。

第二个方法是通过外网服务器中转:顾名思义这个方法需要有一台外网服务器作为代理。

几种常用的方案:

方案一 通过ssh隧道

这个方案的优点是:服务器不需要额外安装软件:外网服务器通常为Linux系操作系统,默认都会安装sshd服务(Windows需要自行安装配置)。

如果想通过sshd提供服务需要修改两处设置,默认配置文件的位置是/etc/ssh/sshd_config

GatewayPorts yes
TCPKeepAlive yes

保存后重启sshd服务即可生效。

而内网的服务器则使用各种ssh客户端都可以。

如果是在Windows下,可以通过Xshell、Secure CRT、Putty等终端自带的隧道功能,以流行的Xshell为例:

新建会话时,在连接/SSH/隧道中,类型选择:远程(传入),源主机和目标主机都是localhost,侦听端口是外网服务器的端口(比如:8081),目标端口是内网电脑的端口(比如:80)。

除了这些第三方ssh终端之外,操作系统也有自带的ssh命令。所有Linux发行版都集成了ssh命令,最新的Win10中也自带了ssh命令。通过命令建立ssh隧道的命令如下:

ssh -R 132.232.0.1:8081:127.0.0.1:80

回车之后输入登录密码,就建立了连接。建立连接后,用户通过访问外网服务器的8081端口都会转到本机的80端口。

如果出现报错应从以下方向入手检查:

1 端口是不是已经占用?如果是的话,关闭打开的端口或者换一个端口。

2 sshd_config配置中的GatewayPorts是不是没有修改?如果是就会存在连接建立了,但是没有监听端口。

3 断线后服务端连接僵死,占用端口无法重连?修改TCPKeepAlive,使连接中断后自动结束进程。

已知问题:有时候会因为连接建立后长时间没有长时间没有活动而断线,我不知道如何彻底解决这个问题,我用的土办法是连接建立后,运行一个top这样的命令,输出不断变化,让连接始终保持活动。但这个方法不是万能的,总有意外发生,比如:物理连接的短暂中断时不可避免的,ssh隧道想稳定运行,还需要来个守护程序让连接保活。或者干脆使用autossh:

autossh -M 连接端口 -CNR 外网端口:0.0.0.0:内网端口 root@外网IP

连接端口为实际传输数据的端口,用来与代理服务器交互,外网端口为代理服务器上的端口,内网端口为被代理服务器上的端口,外网IP为代理服务器IP地址。浏览器访问 http://外网IP:外网端口,即可代理到内网127.0.0.1:内网端口上。

autossh在各大发行版的软件仓库都有,CentOS下:

yum install autossh

Debian(含Ubuntu、Deepin)下:

apt install autossh

方案二:通过frp

frp是一款专门用于内网穿透的软件,但与ssh不同的是:它需要在外网主机和内网主机分别安装软件才可以。外网服务器安装frps、内网服务器安装frpc。

同时frp还自带一个简易的仪表盘功能,可以看到当天的流量使用情况以及代理进程的信息。

经过实际测试,稳定性和性能都比ssh隧道要好一些,推荐使用frp的方案。

frp的两个程序frps、frpc都在同一个软件包内。