下面总结的是如何使用autossh的反向代理及ssh的正向代理实现内网穿透,使外网主机可以直接连接到内网中的某台服务器。
(虽然ssh也能配置代理,但是有时会断开。而autossh的使用方法及参数同ssh一致,但是在链接断开的时候,其会自动重连)
下面列出的示例,使用的是centos系统,可做参考,需根据实际情况进行配置。
建议所有的代理配置都写入/etc/rc.local或配置启动脚本,以免进程丢失后遗忘配置内容
A 外网可访问到的云服务器
B 内网中可访问外网的主机或服务器
C 任意可访问外网的pc
基本需求:
使C能通过A访问B(可登录A再登录B,也可在A中做一个转发,使C直接访问到B)
<1>登录B(内网服务器中),安装autossh
yum -y install autossh
<2>推送B的公钥到A,实现免密登录
(注意B的网络必须能访问到A)
B中执行如下命令:
ssh-keygen -t rsa (一直回车,无需配置密码)
ssh-copy-id -i ~/.ssh/id_rsa.pub -p A的某远程端口 A的用户名@A的IP
or
ssh-copy-id -i .ssh/id_rsa.pub A的用户名@A的IP
or
ssh-copy-id A的用户名@A的IP
or
复制B的~/.ssh/id_rsa.pub内容到A的~/.ssh/authorized_keys中
可根据情况指定端口(默认22)或用户名(默认root)推送公钥,需输入一次A的密码
<3>配置A云服务器的ssh参数(可选,ssh使用默认配置也可以)
如连接有问题,需要注意以下参数
vim /etc/ssh/sshd_config
连接超时及转发相关:
GatewayPorts yes
TCPKeepAlive yes
ClientAliveInterval 60
ClientAliveCountMax 3
证书相关:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
(如修改参数,修改后重启ssh服务)
systemctl restart sshd
<4>B中使用autossh反向代理
(端口需根据实际情况指定,此命令可放到screen中,也可放到开机自启中)
autossh -p 22 -M 11222 -fNR 11221:localhost:22 A的用户名@A的IP
or
autossh -p 22 -M 11222 -NR 11221:localhost:22 A的用户名@A的IP &
-p 指定外网服务器的ssh端口(默认22)
-M 在外网服务器中指定一个端口,监听连接的状态,使断开后进行重连
-f 隧道建立成功后在后台运行
-N 不执行远程指令
-L 建立本地SSH隧道,指定本地的某端口转发到远程主机的某端口
-R 建立远程SSH隧道,指定远程主机上的某端口转发到本地的某端口
-NR 11221:localhost:22 可理解为将本地的22端口转发/映射到A的11221端口,即A可通过自己的11221端口,连接到B
<5>登录A访问B
C可以先登录到A,再使用如下命令,登录B(需输入B的密码)
ssh -p11221 root@localhost
如无需密码登录,可将C的公钥内容复制到B的authorized_keys中
这种登录有些麻烦,于是可以结合下面的正向代理使C可以直接访问到B
<1>登录A,将11221这个端口本地转发
由于autossh转发后的端口,只支持本地访问,需要将那个转发端口再转发到本地的其他端口
ssh -fCNL *:11051:localhost:11221 localhost
* 代表接受来自任意机器的访问
11051是用于本地转发的一个端口,用于和外网通信(端口任选,不被占用即可)
11221是前面反向代理出的用于连接的端口
如需输入密码,输入A的即可
<2>安全组开放端口
由于A是云服务器,因此需要使安全组开放一下正向代理转发的端口(即11051)
不同厂商的云服务器安全组设置可从网上查询,这里就不介绍了
<3>C直接登录B
此时,C访问A的11051端口的数据会被转发到A的11221端口上,使C直接访问B
ssh -p11051 A的用户名@A的IP
如提示需要输入密码,则输入B的密码
也可将C的公钥推送到B:
ssh-copy-id -i ~/.ssh/id_rsa.pub -p 11051 A的用户名@A的IP
下面为将autossh作为服务,使用systemctl来控制的操作
实际上也可以写一个简易的脚本来控制不同项目,穿透不同的内网
<1>创建一个autossh配置文件
vim /lib/systemd/system/autossh.service
[Unit]
Description=Auto SSH Tunnel
After=network-online.target
[Service]
User=huchao
Type=simple
ExecStart=/usr/bin/autossh -NR 11221:localhost:22 -i /root/.ssh/id_rsa -p A的远程端口 A的用户@A的IP >> /dev/null 2>&1
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
KillMode=process
Restart=no
[Install]
WantedBy=multi-user.target
WantedBy=graphical.target
/root/.ssh/id_rsa为B的私钥的绝对路径
<2>使用systemctl启动及配置开机自启
systemctl enable autossh
systemctl start autossh