SSH端口转发脚本
概述
本脚本基于 autossh 工具实现 SSH 端口转发隧道管理,具备以下核心功能:
- 端口转发:将远程服务器端口暴露至跳板机指定端口,实现内网访问
- 自动重连:监控 SSH 连接状态,断线后自动重建隧道
- 多层跳板:支持通过
-J参数实现多级跳板机穿透
前置条件
- 跳板机(运行脚本的目标机器)
- 已安装
autossh工具 - SSH 免密登录或密钥认证已配置
安装 autossh
# CentOS / RHEL
yum install -y autossh
# Ubuntu / Debian
apt install -y autossh脚本源码
将以下脚本保存为 /script/ssh-tunnel(或其他自定义路径),并赋予执行权限:
chmod +x /script/ssh-tunnel#!/bin/bash
# SSH 隧道转发管理脚本
# 功能:通过跳板机开放端口,将远程服务转发至本地
export AUTOSSH_POLL=60
export AUTOSSH_PORT=0
# 启动所有隧道
function start() {
# 隧道1:将内网 10.0.0.2 的 SSH 服务,暴露在跳板机 10001 端口
autossh -M 0 \
-o "ExitOnForwardFailure yes" \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-fNL 0.0.0.0:10001:192.168.1.2:22 root@10.0.0.2
# 隧道2:通过两层跳板(10.0.0.2 → 172.32.0.2)访问 192.168.1.3:22,
# 暴露在跳板机 10002 端口
autossh -M 0 \
-o "ExitOnForwardFailure yes" \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-fNL 0.0.0.0:10002:192.168.1.3:22 \
-J root@10.0.0.2 root@172.32.0.2
}
# 停止所有隧道
function stop() {
ps aux | grep -E 'autossh.*-NL' | grep -v grep | awk '{print $2}' | while read pid; do
kill -9 "$pid"
done
}
# 列出可用端口
function ls(){
# 定义端口范围
START_PORT=10001
END_PORT=10499
# 定义需要查找的空闲端口数量
MAX_FREE=5
count=0
echo "正在扫描端口范围 $START_PORT - $END_PORT,查找前 $MAX_FREE 个空闲端口..."
# 遍历指定范围内的端口
for port in $(seq $START_PORT $END_PORT); do
# 使用 ss 命令检查端口是否处于监听状态
if ! ss -tln | grep -q ":$port "; then
echo "端口 $port 空闲"
((count++)) # 计数器加1
# 如果已经找到10个空闲端口,退出循环
if [ $count -ge $MAX_FREE ]; then
break
fi
fi
done
echo "扫描完成!共找到 $count 个空闲端口。"
}
# 主入口
case $1 in
start)
start
;;
restart)
stop
start
;;
stop)
stop
;;
ls)
ls
;;
*)
echo "用法: $0 {start|restart|stop|ls}"
;;
esac使用说明
| 命令 | 说明 |
|---|---|
./ssh-tunnel start |
启动所有配置的隧道 |
./ssh-tunnel stop |
停止所有隧道进程 |
./ssh-tunnel restart |
重启所有隧道 |
./ssh-tunnel ls |
列出当前运行的隧道端口及配置 |
参数详解
| 参数 | 含义 |
|---|---|
-M 0 |
禁用 autossh 监控端口(配合 ServerAlive 实现存活检测) |
-f |
后台运行 |
-N |
不执行远程命令(纯转发) |
-L |
本地端口转发,格式:[本地IP]:本地端口:目标IP:目标端口 |
-J |
跳板机(ProxyJump),多级用空格分隔 |
ExitOnForwardFailure yes |
端口转发失败时退出 |
ServerAliveInterval 30 |
每 30 秒发送保活包 |
ServerAliveCountMax 3 |
连续 3 次无响应则断开重连 |
隧道配置示例
单层跳板
autossh -M 0 -fNL 0.0.0.0:10001:192.168.1.2:22 root@10.0.0.2说明:通过跳板机 10.0.0.2,将远程主机 192.168.1.2 的 22 端口转发到跳板机的 10001 端口。
双层跳板
autossh -M 0 -fNL 0.0.0.0:10002:192.168.1.3:22 -J root@10.0.0.2 root@172.32.0.2说明:依次通过 10.0.0.2 → 172.32.0.2 两层跳板,访问 192.168.1.3 的 22 端口。
常见问题
Q:为什么使用 -M 0 而不是默认监控端口?
-M 0 会禁用 autossh 自带的监控端口,转而完全依赖 SSH 的 ServerAliveInterval 机制检测连接状态。这种方式更简洁,且避免额外端口占用。
Q:-J 参数的正确格式是什么?
错误写法:
-J root@root@10.0.0.2正确写法:
-J root@10.0.0.2 root@172.32.0.2多级跳板用空格分隔,按顺序依次跳转。
Q:如何添加更多隧道?
在 start() 函数中参照现有格式追加新的 autossh 命令即可。建议每条隧道使用不同端口,避免冲突。
Q:如何开机自启?
将启动命令添加到 /etc/rc.local 或使用 systemd 服务管理:
# /etc/rc.local
/script/ssh-tunnel start &