我已经在我的 centos 机器上配置了 sshd_conf,如下所示:
Match group pilots
ChrootDirectory /home/pilots
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no
目录 /home/pilots 如下:
# ls -al /home/pilots
total 12
drwxr-x---. 3 root pilots 4096 Mar 10 14:20 .
drwxr-xr-x. 7 root root 4096 Mar 10 14:10 ..
drwxrwxr-x. 2 root pilots 4096 Mar 10 15:21 data
-rwxrwxrwx. 1 root root 0 Mar 10 14:20 topLevel
#
如果我以 pilots 组中的用户身份通过 sftp 进入,并且没有启用 ChrootDirectory 指令,我就可以 cd 到 /home/pilots 文件夹(或其子目录)并毫无困难地执行 ls 或 get。但是,如果我启用了 ChrootDirectory 指令,虽然我仍然可以 sftp 进入,并且可以 cd 到 data,但我无法在任何一个目录中执行 ls 或 get。例如,尝试 ls 会给出 remote readdir("/"): Permission denied 错误,而尝试 get topLevel 会给出 File "/topLevel" not found 错误。我在想也许我没有进入我期望的目录,但 cd data 的能力似乎表明 chroot 确实按预期工作了。
查看消息日志,当 ls 被拒绝时,我看到以下内容:
type=1400 audit(1394494944.504:50): avc: denied { read } for pid=22758 comm="sshd" name="pilots" dev=dm-0 ino=400504 scontext=unconfined_u:system_r:chroot_user_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=dir
所以有拒绝记录。但还是没有告诉我原因。
我可能做错了什么?
一些可能重要的注意事项:
- 相关用户存在于远程 LDAP 服务器上,可通过 sssd 访问
- 访问控制必须按组进行,因为许多用户都需要对同一文件夹进行读取访问。因此所有权仍为 root。
编辑:经过进一步调查,似乎这与 SELinux 有关 - 修复了echo 0 >/selinux/enforce
这个问题,尽管有点笨拙,就像用大锤杀死蚂蚁一样。如果可能的话,我想知道“正确”的修复方法。
答案1
我找到了解决方案这一页总结一下,按照上面的配置配置好 sftp 后,需要运行以下两个命令才能在启用 SELinux 的情况下进行访问:
setsebool -P ssh_chroot_rw_homedirs on
restorecon -R /home/$USERNAME
在这种情况下,第二个命令将是restorecon -R /home/pilots
。此后,即使在 chrooted 的情况下,sftp 仍可按预期工作,而无需完全禁用 SELinux。
答案2
尾随@ibrewster回答(包括外部资源他链接到的这个页面),这里是来自该外部页面的完整说明,其中有一些附加信息,以使无密码登录和 SELinux 强制执行能够正常工作。
万一将来外部链接的页面消失的话,就在这里重新发布。
这些说明适用于 RHEL7 和 CentOS7(也许还有其他版本):
在远程系统上:
首先,添加并配置要 chroot 的用户帐户:
请注意外部资源使用了不同的路径sftp-server
。请确保您的系统上有正确的路径,否则请做好承受痛苦的准备。;-) 以下路径适用于 RHEL7 和 CentOS7 的最小安装。
# From command line:
groupadd sftponly
useradd -d /home/$USERNAME -s /usr/libexec/openssh/sftp-server -M -N -g sftponly $USERNAME
mkdir -p /home/$USERNAME/uploads /home/$USERNAME/downloads /home/$USERNAME/.ssh
chown $USERNAME:sftponly /home/$USERNAME/uploads /home/$USERNAME/downloads /home/$USERNAME/.ssh
chown root /home/$USERNAME
chmod 755 /home/$USERNAME
chmod 700 /home/$USERNAME/.ssh
passwd $USERNAME
echo '/usr/libexec/openssh/sftp-server' >> /etc/shells
虽然我在上面设置了密码,但一旦我知道配置有效,我就会使用无密码登录。继续...
假设您已SELinux
启用并执行(您应该这样做),发出以下命令以使其正常运行:
setsebool -P ssh_chroot_rw_homedirs on
restorecon -R /home/$USERNAME
现在,编辑 sshd 配置如下:
[root@remote]# vi /etc/ssh/sshd_config
#
# CHANGE lines:
#
# override default of no subsystems
#Subsystem sftp /usr/libexec/openssh/sftp-server # commented out
Subsystem sftp internal-sftp # added
#
# ADD the following at the bottom:
#
Match group sftponly
ChrootDirectory %h
AllowTcpForwarding no
ForceCommand internal-sftp
最后,重启 sshd
[root@remote]# systemctl restart sshd.service
在客户端系统上
首先在本地创建相同的帐户。
[root@client]# useradd -m $USERNAME
[root@client]# passwd $USERNAME
[root@client]# su $USERNAME
好的,现在让我们设置我们的 RSA 密钥对。
[$USERNAME@client]# ssh-keygen
我无法让 ssh-copy-id 与上面的 chroot 配置一起工作,所以我authorized_keys
使用客户端的 id_rsa.pub 文本手动创建了该文件。
[$USERNAME@client]# cat .ssh/id_rsa.pub
---some key here---
然后回到远程系统,
[root@remote]# vi /home/$USERNAME/.ssh/authorized_keys
---past key from right above, then wq---
不要忘记设置此文件的权限:
[root@remote]# chown $USERNAME:sftpusers /home/$USERNAME/.ssh/authorized_keys
准备测试
现在一切都应该准备就绪了。来自客户:
[$USERNAME@client]# sftp $USERNAME@remote
这应该能帮你进入。如果系统提示你输入密码(我们还没有在远程系统上禁用 PasswordAuthentication),则远程系统存在配置问题。扫描你的 /var/log/secure 以获取详细信息。
如果您登录时没有提示输入密码,则说明您已经基本完蛋了。
回到远程系统:
[root@remote]# vi /etc/ssh/sshd_config
# disable PasswordAuthentication
PasswordAuthentication no
# or optionally, just comment that line out
# PasswordAuthentication no
-- save and exit with :wq --
在远程系统上重新启动 sshd:
[root@remote]# systemctl restart sshd.service
客户的最终测试
[$USERNAME@client]# sftp $USERNAME@remote
# in like Flynn? yay!
完成的
你应该准备好chroot sftp和无密码登录(SELinux
设置为执行)