若已有远程有独立 IP 的服务器,可以使用 SSH 反向隧道的方式实现本地 Linux 电脑内网穿透。以下是具体的步骤:
在本地 Linux 电脑上设置 SSH 服务,开启 SSH 服务监听端口,默认情况下为 22 端口。
在远程服务器上安装 SSH 服务,并开启 SSH 服务监听端口,默认情况下为 22 端口。确保能够从服务器上 SSH 登录本地 Linux 电脑。
在本地 Linux 电脑上通过 SSH 命令将流量转发到远程服务器上:
ssh -N -R 0.0.0.0:2222:localhost:22 {remoteuser}@{remoteip}
其中:remoteuser 是远程服务器的用户名,remoteip 是远程服务器的 IP 地址。上述命令将本地 Linux 电脑的 22 端口 (localhost:22) 转发到远程服务器的 2222 端口 (0.0.0.0:2222)。
通过上一步的流量转发后即可在远程服务器连接到本地 Linux 电脑:
ssh -p 2222 {localuser}@localhost
其中:localuser 是本地 Linux 电脑的用户名。
如果需要其他应用的内网穿透,可将其端口号加入到转发命令中。
ssh -N -R 0.0.0.0:8080:localhost:80 {remoteuser}@{remoteip}
将本地 Linux 电脑的 80 端口转发到远程服务器的 8080 端口。
上述操作可以实现本地 Linux 电脑的内网穿透,可以通过远程服务器访问本地 Linux 电脑上的应用和服务。注意确保远程服务器的安全性,并适当设置防火墙规则。
相比于 ssh
, autossh
可以在网络断开后自动重新连接,保证了服务的稳定性。
autossh
sudo apt-get update
sudo apt-get install autossh
在本地机器上建立 SSH 连接,并使用 autossh
将服务器上的端口映射到本地机器的端口。其中,remote_port
是服务器上的端口号,local_port
是本地机器上的端口号。
autossh -M 2223 -R remote_port:localhost:local_port -o ServerAliveInterval=15 {remoteuser}@{remoteip}
-M
参数表示指定一个监控端口,如果连接断开就会自动重连;
-o
参数用于指定SSH连接选项,这里设置了每隔15秒发送一次心跳包以保持连接;
-N
参数表示建立一个不执行远程命令的SSH连接;
-R
参数用于指定端口转发规则,这里表示将公网服务器的2222端口映射到目标机器的22端口;
最后的{remoteuser}@{remoteip}
表示登录目标机器的用户名和IP地址
执行以上命令后,SSH 连接会一直保持开启,在服务器上访问 localhost:remote_port
即可访问到本地机器上的服务。
[program:autossh22]
command = autossh -N -R 0.0.0.0:2222:localhost:22 -o ServerAliveInterval=15 -i ~/.ssh/id_rsa remoteuser@remoteip
user=wml
process_name = %(program_name)s_%(process_num)s
numprocs = 1
autostart = true
autorestart = true
startretries = 1000 ; 启动失败自动重试次数,默认是 3, 把这个值调大点,防止redis长时间连不上的情况(如之前遇到的主备切换长时间连不上)
stdout_logfile = /alidata/log/supervisor/autossh22.log
stdout_logfile_maxbytes = 100MB
redirect_stderr=true
[program:autossh80]
command = autossh -N -R 0.0.0.0:2280:localhost:80 -o ServerAliveInterval=15 -i ~/.ssh/id_rsa remoteuser@remoteip
user=wml
process_name = %(program_name)s_%(process_num)s
numprocs = 1
autostart = true
autorestart = true
startretries = 1000 ; 启动失败自动重试次数,默认是 3, 把这个值调大点,防止redis长时间连不上的情况(如之前遇到的主备切换长时间连不上)
stdout_logfile = /alidata/log/supervisor/autossh80.log
stdout_logfile_maxbytes = 100MB
redirect_stderr=true
可以在远程服务端用 nginx 做服务转发,如 配置远程端口 2280 转发到本地服务器 80, nginx 配置如下
upstream home{
server 127.0.0.1:2280;
}
server {
listen 80;
listen [::]:80;
server_name test.com;
server_tokens off;
auth_basic "请输入账号密码"; #这里是验证时的提示信息
auth_basic_user_file /alidata/data/auth_basic/ip_passwdfile;
index index.html index.htm index.php default.html default.htm default.php;
charset utf-8;
error_page 404 /index.php;
location /
{
proxy_pass http://home;
proxy_set_header Host $host:$server_port;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /alidata/log/nginx/test.com.log main;
error_log /alidata/log/nginx/nginx_error.log;
}
当本地机器重启后虽然通过 supervisor 重新启动了 autossh, 但可能会报错Warning: remote port forwarding failed for listen port 2222
,发现远程服务器的 2222 端口被占用,需要杀掉进程
# 运行该命令查看占用端口的进程id
sudo netstat -plant | grep 2222
# 杀掉该进程
sudo kill -9 {pid}
之后再来本地重新执行 autossh 命令即可