如何在 Linux 上将 SSH 用户访问限制在主目录中?

你可以通过结合文件系统规则与严格的账户隔离机制来加固 Linux 环境的安全性。你可以配置 SSH 用户访问策略,将用户限制在单一主目录内。系统管理员通常会实施 chroot 监狱,以阻止用户横向遍历服务器上的敏感目录与系统路径。
你还必须对父级目录实施严格的 POSIX 权限控制,以防止未经授权的文件浏览。要实现有效的目录隔离,在编辑配置文件之前需要满足三个明确前提条件:你需要拥有主机服务器的 root 权限、系统中正在运行的 OpenSSH 守护进程,以及一个用于测试的标准账户。这些基础管理条件能够帮助你安全地完成安全配置部署,避免把自己锁在远程系统之外。
配置 SSH Chroot Jail 环境
你可以配置 SSH 设置,将账户隔离在安全的 chroot 监狱中。系统管理员通过将用户限制到指定目录,来阻止其未经授权地遍历关键系统路径。
在 sshd_config 中应用 SSH Chroot 指令
当你为目标账户创建 chroot 监狱配置时,需要编辑 /etc/ssh/sshd_config。OpenSSH 会根据单个账户或组定义来评估参数。下表突出展示了不同匹配条件在运行行为上的差异:
| 观察项 | 使用 Match User 配合 ChrootDirectory | 额外添加 Match Group 指令 |
|---|---|---|
| 配置重新处理 | 用户会被正常解析;调试日志中会显示有效用户名,例如 user test matched group list ...。 | 组匹配会在用户名为空的情况下尝试执行,从而产生 Can't match group ... because user does not exist。 |
| ChrootDirectory 行为 | ChrootDirectory 会被可靠应用,例如应用到 C:\,并且 SFTP 会话会被正确地限制在监狱中。 | 由于在用户被完整重新解析前配置重处理已失败,ChrootDirectory 无法被稳定应用。 |
| 连接结果 | SFTP 会话成功;pwd 和目录列表功能均可正常工作。 | 会间歇性出现 Permission denied 或 client_loop: send disconnect: Connection reset;失败表现可能因尝试次数而异。 |
你可以将以下指令追加到 /etc/ssh/sshd_config 文件末尾,以强制实施会话隔离:
Subsystem sftp internal-sftp
Match Group sftpgroup
ChrootDirectory /sftp/%u
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no设置 Chroot 目录所有权
严格的所有权规则支配着 Linux 上的每一个隔离环境。OpenSSH 会在授予访问权限之前验证所有父级目录:
sshd 会验证 chroot 路径中的每一层目录都归 root 所有,并且不能被任何其他用户或组写入。认证完成后,它会 chroot 到该目录,然后再切换到用户的主目录。
你应按照顺序执行部署步骤,以安全地创建并配置 SSH 用户访问:
- 使用
groupadd sftpgroup创建一个专用组。 - 使用
mkdir /sftp创建 chroot 根目录,然后通过chown root:root /sftp设置所有者,并通过chmod 755 /sftp设置权限。 - 执行
useradd -g sftpgroup -s /sbin/nologin sftpuser创建一个没有 shell 访问权限的账户,然后使用passwd sftpuser设置密码。 - 在该隔离环境中创建上传目录,执行
mkdir /sftp/sftpuser/upload,然后设置访问属性:chown root:root /sftp/sftpuser以及chmod 777 /sftp/sftpuser/upload。 - 使用
systemctl restart sshd.service重启守护进程。
在设置过程中管理账户时,你必须执行精确的命令序列:
- 在初始创建账户时运行
useradd,以分配基础属性。 - 使用
usermod -d /sftp/sftpuser/upload sftpuser修改现有目录路径。 - 应用
usermod -s /sbin/nologin sftpuser来禁用交互式 shell 访问。 - 执行
usermod -aG sftpgroup sftpuser将现有用户加入该组。 - 必须保持父级目录归 root 所有,否则 chroot 过程将彻底失败。
这种常见的 chroot jail 配置可以将文件传输限制在监狱环境内,同时阻止文件系统导航越界。如果你使用密钥认证,请设置 AuthorizedKeysFile /home/%u/.ssh/authorized_keys,因为密钥验证发生在进入 chroot 环境之前。在监狱中提供一个可写目录,可以在保持监狱安全的同时允许文件上传与传输。
通过 POSIX 权限限制用户访问
默认的 Linux 配置通常会允许非 root 账户查看共享系统路径下的目录名称。非特权账户可能在未经授权的情况下列出父级路径中的内容。你必须调整系统配置设置,才能彻底限制用户访问。限制用户访问,是保护机密数据安全的重要手段。
系统管理员会修改 POSIX 规则,以保护主要主目录路径的安全。你可以通过配置严格的访问权限,防止用户越权浏览其他用户目录。
加固父级 Home 目录访问控制
标准 Linux 安装通常允许账户查看共享父级路径下的目录结构。你可以通过修改主系统级别的目录访问控制,来保护这些位置。
管理员会使用明确的命令选项来控制目录进入与文件列表操作:
chmod 750 /home:授予所有者完整控制权限,授予组成员读取和执行权限,而对其他账户不授予任何权限。chmod 711 /home:为所有账户授予执行权限,使用户可以穿过/home进行路径访问,但无法查看其目录列表内容。
这些设置能够阻止非特权账户枚举主机的目录结构,同时保留合法账户所需的正常路径遍历能力。
保护用户主目录权限
在保护主父目录之后,你还必须锁定单个用户目录的权限设置。对用户主目录设置 chmod 700,意味着只给目录所有者授予读取、写入和执行权限。该模式会阻止组成员和其他外部账户查看私人文件。
OpenSSH 会在实际认证过程中检查文件系统安全性。如果目标账户目录权限过于宽松,远程 SSH 服务可能会拒绝连接。
| 模式 | 所有者 | 组 | 其他人 | 安全含义 |
|---|---|---|---|---|
| 700 | 读取、写入、执行 | 无 | 无 | 将访问权限完全锁定给目标用户本人。 |
| 755 | 读取、写入、执行 | 读取、执行 | 读取、执行 | 允许外部账户读取该主目录中的文件。 |
你可以通过直接对每个用户的主目录应用 700 模式,在整台主机上维持强有力的账户隔离。
实施受限 Shell 与命令控制
除了基础系统配置之外,你还可以部署受限 shell 来进一步限制用户。受限 shell 能锁定执行权限,并阻止账户离开指定位置。
配置 Restricted Bash Shell 环境
系统管理员会使用受限 shell 来阻止 SSH 会话中未经授权的命令执行。你首先需要确认系统中存在 rbash。如果系统缺少默认二进制文件,你可以从 /usr/bin/bash 创建一个指向 /usr/bin/rbash 的符号链接。
接下来,你可以创建一个新账户,或更新现有用户配置。你可在创建账户时使用 useradd -s /usr/bin/rbash newuser 指定 rbash 作为登录 shell。你也可以使用 usermod -s /usr/bin/rbash targetuser 来修改现有目标账户。无论何时需要更新 shell 分配,你都可以再次执行 usermod。如果你在迁移账户,也可以调用 usermod 来调整配置文件设置。系统管理员会通过运行 usermod 来维护所有受管账户的 shell 边界。
在自定义命令路径中限制可执行文件
你需要实施路径隔离,以防止执行未经授权的二进制文件。你可以在用户主目录中创建一个由 root 拥有的目录,例如 /home/targetuser/.bin,作为安全命令的专用目录。然后只将被批准的命令链接到该目录中,例如 ls、su 和 clear。
在用户配置文件 .bashrc 中,你需要定义 PATH=$HOME/.bin 并设置 umask 077。你还应将文件所有权改为 root:targetuser,这样账户本人就无法修改启动脚本。
下表总结了受限 shell 内建强制执行的安全保护机制:
| rbash 限制 | 它所阻止的行为 | 实际表现证据 |
|---|---|---|
cd 被禁用 | 更改当前工作目录 | cd /tmp 会因 “restricted” 错误而失败 |
exec、set、unset 被阻止 | 修改 shell 环境及启动新 shell 会话 | exec bash 会因 “restricted” 错误而失败 |
| 重定向被禁用 | 通过 >、<、>> 写入或读取文件 | echo "Test" > test.txt 会被拒绝 |
包含 / 的路径名被拒绝 | 通过绝对/相对路径在 PATH 之外启动命令 | 尝试执行 /bin/ls 会因 “restricted” 错误被拒绝 |
PATH 被设置为特定用户的 bin | 执行允许列表之外的任意命令 | 只能运行像 hello.sh 这样的白名单脚本 |
| SSH 一次性命令 | 不受 rbash 交互模式限制的阻止 | 注释指出 ssh some_host any_command 仍然可用 |
使用受限 shell 可以阻止用户启动未批准程序、执行目录切换,或修改关键环境变量。
验证用户隔离与访问限制
测试 SFTP 与 Shell 边界控制
在更新服务器配置后,你需要通过实际的 SFTP 测试来验证 chroot jail 参数是否生效。该测试能够确认远程账户是否被锁定在指定边界位置内。你可以打开终端,通过 SSH 执行 sftp user@host 来测试文件传输约束。服务器会在登录后立即实施目录限制。在 /etc/ssh/sshd_config 中设置 ForceCommand internal-sftp,可以将会话能力完全限制为文件管理。你可以借助这些严格规则,将用户访问限制在指定系统范围之内。
接下来,你还要评估交互式会话限制。通过执行 ssh user@host 启动一个会话来测试系统安全性。受限 shell 会阻止改变工作位置的命令。像 pwd、echo 和 history 这样的 shell 内建命令仍能成功运行,因为它们由 bash 在内部处理。然而,当你锁定用户主目录路径后,像 ls、date 或 uname 这样的外部二进制命令将彻底失败。一个配置正确的受限 shell 会拒绝执行越界二进制文件,也会阻止用户更改环境路径。正确的 chroot jail 设置则能持续保持账户隔离。
验证 SSH 用户访问与目录遍历限制
你可以通过直接测试目录导航控制来验证 SSH 用户访问限制。请按照以下步骤检查你的 chroot jail 实现:
- 以受限用户身份登录:
ssh jailuser@localhost。 - 在远程 shell 中切换到表面上的根目录:
cd /。 - 使用
ls查看目录;应当只能看到监狱内部内容,而不是真实文件系统。 - 尝试通过
cd ..向上移动;会话应仍停留在/,这证明目录遍历已被阻止。 - 在审计日志中验证 chroot 是否已激活:
sudo grep -i chroot /var/log/auth.log。
这套结构化测试流程能够确认系统边界是否有效地限制了远程会话中的用户访问。
测试可以确保你的 chroot jail 配置真正隔离账户,而不会出现意外的访问泄漏。
你可以通过执行实际测试命令来验证隔离环境。运行 ssh user@host 建立新的远程会话。随后执行 pwd,并尝试使用 cd .. 进行目录导航。活动会话应将你的路径锁定在目标目录结构内部。你必须定期对 Linux 主机上的目录权限进行安全审计,以防止权限回退并持续维护访问控制安全。
你还应监控系统日志,以尽早发现未授权访问尝试。检查 /var/log/auth.log,或在服务器上运行 journalctl -u ssh。这些系统日志会显示登录认证详情,并立即记录失败的目录遍历事件。持续检查日志,能够长期维持服务器环境中的账户边界控制效果。
常见问题
为什么在 chroot jail 上设置错误权限会导致 SSH 失败?
OpenSSH 会强制执行严格的安全标准。在启动 chroot jail 之前,路径中的每一层父目录都必须归 root 所有。组写权限会破坏这些安全检查。因此,你的连接会失败,或者环境初始化会被跳过。
如何在不提供 shell 访问的情况下将账户限制在 jail 中?
你可以将账户的 shell 设置为 /sbin/nologin。然后在配置文件中指定 ForceCommand internal-sftp。这一设置会将远程文件传输限制在指定 jail 内部。
账户能否在 Linux 环境中逃离其主目录?
不能,受限 shell 会阻止像 cd 这样的导航内建命令。系统会拒绝路径修改以及允许路径之外的命令执行。用户无法逃离其目标目录,也不能修改系统变量。
哪些权限设置可以阻止用户查看其他人的主目录?
你可以对每个个人目录应用 chmod 700。该命令仅向目录所有者授予完整访问权限。此外,你还可以对 /home 设置 chmod 750,以阻止非特权账户读取父级路径内容。
如何确认 chroot 已隔离 SSH 会话?
你可以通过 SSH 建立一个会话来测试边界限制。执行 cd .. 检查目录遍历是否被阻止。活动会话会将你的路径锁定在第二层 jail 内部,同时系统日志会确认 chroot 已正确激活。
