反向 SSH 隧道
反向 SSH 隧道是解决内外网通信问题的一种简单高效的方法,特别适用于内网主节点无法直接暴露给外网的场景。以下是详细的操作步骤和原理:
原理
- 建立隧道:通过 SSH 隧道技术,让内网主节点主动连接到外网的机器。
- 端口转发:把内网 MongoDB 的服务端口(
27017
)映射到外网机器的某个端口(例如27018
)。 - 外网访问内网 MongoDB:外网服务器通过本地端口(
27018
)访问隧道中转的内网 MongoDB 实例。
实现步骤
1. 前置准备
检查 SSH 配置
- 确保内网的 Windows 主机可以通过 SSH 连接到外网的 Ubuntu 服务器。
- 确保外网的 Ubuntu 开启了 SSH 服务:
bash sudo systemctl status ssh
开放外网服务器端口
- 确保外网 Ubuntu 服务器上,映射的端口(如
27018
)未被防火墙阻止:bash sudo ufw allow 27018
测试连通性
- 在内网主机测试是否可以通过 SSH 连接到外网服务器:
bash ssh user@ubuntu_public_ip
2. 建立反向 SSH 隧道
在内网的 Windows 主机上执行以下命令:
ssh -R 27018:localhost:27017 user@ubuntu_public_ip
参数说明
-R
:指定反向端口转发。27018
:外网 Ubuntu 服务器开放的端口。localhost:27017
:表示内网 MongoDB 服务监听的地址和端口。user@ubuntu_public_ip
:SSH 登录的用户和外网服务器的公网 IP 地址。
效果
这条命令会在外网服务器的 27018
端口创建一个映射,连接这个端口会通过隧道访问内网 MongoDB 的 27017
端口。
3. 验证隧道是否工作
在外网的 Ubuntu 服务器上测试是否可以访问内网 MongoDB:
mongosh --host localhost --port 27018
如果能够连接到 MongoDB,则隧道已经建立成功。
4. 配置 MongoDB 副本集
内网主节点配置
-
登录内网 MongoDB 容器:
bash docker exec -it mongodb-primary mongosh
-
初始化副本集:
javascript rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "windows_internal_ip:27017" } ] });
外网副节点配置
-
登录外网 MongoDB 容器:
bash docker exec -it mongodb-secondary mongosh
-
添加内网主节点到副本集:
javascript rs.add("localhost:27018");
-
验证副本集状态:
javascript rs.status();
5. 自动化反向隧道(可选)
为了让隧道在系统启动时自动建立,可以使用以下方法:
Windows 中的自动化
- 创建一个批处理脚本(例如
ssh_tunnel.bat
):batch @echo off ssh -N -R 27018:localhost:27017 user@ubuntu_public_ip
- 将脚本添加到 Windows 启动项。
Linux 中的自动化
在 Ubuntu 外网服务器上使用 autossh
进行隧道保持:
1. 安装 autossh
:
bash
sudo apt install autossh
2. 添加以下命令到 crontab
:
bash
autossh -f -N -R 27018:localhost:27017 user@ubuntu_public_ip
6. 注意事项
- 安全性
- 使用 SSH 公钥认证代替密码认证,提高安全性:
bash ssh-keygen -t rsa ssh-copy-id user@ubuntu_public_ip
-
限制外网服务器的端口访问,只允许可信的客户端连接。
-
稳定性
- 配置
autossh
或其他工具,确保隧道断开后能够自动重连。 -
定期检查隧道状态。
-
性能
- 隧道传输会带来一些延迟和性能损耗,适用于小规模的副本集同步。如果同步量较大,建议采用 VPN 等方式。
通过反向 SSH 隧道,你可以实现内网 MongoDB 和外网 MongoDB 的直接通信,同时无需暴露内网 MongoDB 的服务端口,保证一定的安全性。这种方法特别适合临时性或小规模的副本集架构需求。