ssh的match指令仅控制ssh连接阶段行为,如认证、端口转发、命令限制等,不能修改内核路由表或指定网络出口;差异化路由需ssh层(forcecommand+proxyjump)与系统层(iptables+策略路由)协同实现。

SSH 的 Match 指令本身不处理网络层路由(如策略路由、多出口转发),它只控制 SSH 连接建立阶段的行为——比如认证方式、Shell 权限、命令限制、端口转发开关等。所谓“差异化路由访问控制”,实际要分两层实现:SSH 层限制用户能做什么,系统网络层决定流量从哪条路径出去。两者需协同,但不能混为一谈。
明确 Match Group/User 的作用边界
Match Group 和 Match User 只能设置 SSH 协议栈内的参数,例如:
-
AllowTcpForwarding yes/no—— 控制是否允许本地/远程端口转发(即 SSH 隧道) -
PermitTTY yes/no—— 决定能否分配交互式终端 -
ForceCommand—— 强制执行某命令(如internal-sftp或自定义脚本) -
X11Forwarding、ClientAliveInterval、MaxAuthTries等
它不能修改内核路由表、不能指定数据包走 eth0 还是 eth1、也不能调用 ip rule 或 iptables。把“路由”理解成“SSH 隧道出口选择”或“用户可发起的端口转发目标范围”,才是它能管的范畴。
用 AllowTcpForwarding + 强制脚本模拟“部门级出口路由”
若目标是让 dev_team 用户只能通过跳板机 A(192.168.10.5)访问测试环境,而 ops_team 必须经跳板机 B(10.10.20.8)访问生产环境,可结合 Match Group 与 ForceCommand 实现:
- 为每组用户配置专属登录 Shell 脚本,脚本中封装
ssh -o ProxyJump=...或nc连接逻辑 - 禁用原始 Shell 和端口转发,防止绕过
示例(/etc/ssh/sshd_config 末尾):
Match Group dev_team
PermitTTY no
AllowTcpForwarding no
ForceCommand /usr/local/bin/dev-access.sh
Match Group ops_team
PermitTTY no
AllowTcpForwarding no
ForceCommand /usr/local/bin/ops-access.sh
对应脚本 /usr/local/bin/dev-access.sh 内容可为:
#!/bin/bash
exec ssh -o StrictHostKeyChecking=no \
-o ProxyJump=192.168.10.5 \
"${1:-dev-env.internal}"
这样用户登录后自动跳转,且无法执行其他命令——本质是把“路由策略”前移到连接入口,由 SSH 层兜底。
真·网络层路由需靠系统策略路由配合用户组
如果确实需要让某用户的全部出站流量(不限于 SSH)走特定网卡或网关,就得在系统层面做策略路由,并用用户 UID/GID 标记流量:
- 用
iptables或nftables给属于dev_team组的进程打标记(如--uid-owner或--gid-owner) - 添加 ip rule 匹配 fwmark,查独立路由表
- 该路由表指向指定出口网关
例如,给 dev_team 组(GID=1001)所有 TCP 流量打标:
iptables -t mangle -A OUTPUT -m owner --gid-owner 1001 -j MARK --set-mark 0x100 ip rule add fwmark 0x100 table dev_route ip route add default via 192.168.10.1 dev eth0 table dev_route
注意:owner 模块仅对本地生成流量有效(非转发),且要求进程未切换 UID。适合运维人员登录后执行的命令,不适用于守护进程。
关键落地提醒
-
Match块必须放在sshd_config文件末尾,顺序敏感,先匹配者生效 - 修改配置后务必运行
sudo sshd -t检查语法,再sudo systemctl reload sshd - Chroot 或
ForceCommand环境下,确保脚本有执行权限、路径可访问、依赖命令已安装 - 策略路由配置需持久化(写入
/etc/network/if-up.d/或 systemd service),否则重启失效











