SFTP chroot

来自 ArchWiki

OpenSSH 4.9+ 包含针对 SFTP 的内置 chroot 功能,但需要对正常安装进行一些调整。

安装

安装并配置 OpenSSH。运行后,请确保 sftp-server 已正确设置

/etc/ssh/sshd_config
Subsystem sftp /usr/lib/ssh/sftp-server

使用 sftpSSHFS 访问文件。许多标准 FTP 客户端也应该可以工作。

配置

设置文件系统

注意
  • 读者可以自行选择文件访问方案。例如,可以选择创建一个子目录用于传入(可写)空间和/或只读空间。这不必直接在 /srv/ssh/jail 下完成 - 也可以在实时分区上完成,该分区也将通过绑定挂载进行挂载。
  • 也可以 chroot 到 /home 目录,从而跳过绑定挂载的使用,但是所需的用户主目录应归 root 所有
# chown root:root /home/<username>
# chmod 0755 /home/<username>

将要共享的实时文件系统绑定挂载到此目录。在此示例中,将使用 /mnt/data/share,它由 user root 拥有,并且八进制权限755

# chown root:root /mnt/data/share
# chmod 755 /mnt/data/share
# mkdir -p /srv/ssh/jail
# mount -o bind /mnt/data/share /srv/ssh/jail

将条目添加到 fstab 以使绑定挂载在重启后仍然存在

/etc/fstab
/mnt/data/share /srv/ssh/jail  none   bind   0   0

创建非特权用户

注意: 您不需要创建组,可以使用 Match User 而不是 Match Group

创建 sftponly 用户组

# groupadd sftponly 

创建一个用户,该用户是 sftponly 组的成员,并且 shell 登录访问被拒绝

# useradd -G sftponly -s /usr/bin/nologin -d /srv/ssh/jail username
注意: 仅当用户有权访问登录 shell 时,通过密码进行的 SSH 身份验证(不推荐)才有效(即未设置 -s /usr/bin/nologin)。

设置一个(复杂)密码以防止帐户被锁定错误(即使使用密钥身份验证也可能出现)

# passwd username

配置 OpenSSH

注意: 您可能希望使用 Match User 而不是 Match Group,如上一步所示。
/etc/ssh/sshd_config
Subsystem sftp /usr/lib/ssh/sftp-server

Match Group sftponly
  ChrootDirectory %h
  ForceCommand internal-sftp
  AllowTcpForwarding no
  X11Forwarding no
  PasswordAuthentication no

重启 sshd.service 以确认更改。

修复 authorized_keys 的路径

提示: 如果出现 (pre)auth 错误,请在客户端和服务器上使用 OpenSSH 的调试模式

使用 AuthorizedKeysFile 的标准路径,SSH 密钥身份验证将对 chroot 用户失败。要解决此问题,请将 root 拥有的目录附加AuthorizedKeysFile/etc/openssh/sshd_config 例如 /etc/ssh/authorized_keys,作为示例

/etc/ssh/sshd_config
AuthorizedKeysFile /etc/ssh/authorized_keys/%u .ssh/authorized_keys
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
Subsystem sftp /usr/lib/ssh/sftp-server

创建 authorized_keys 文件夹,在客户端上生成 SSH 密钥复制密钥的内容到服务器的 /etc/ssh/authorized_keys(或任何其他首选方法),并设置正确的权限

# mkdir /etc/ssh/authorized_keys
# chown root:root /etc/ssh/authorized_keys
# chmod 755 /etc/ssh/authorized_keys
# echo 'ssh-rsa <key> <username@host>' >> /etc/ssh/authorized_keys/username
# chmod 644 /etc/ssh/authorized_keys/username

重启 sshd.service

技巧与提示

写入权限

绑定路径需要完全由 root 拥有,但是文件和/或子目录不必如此。在以下示例中,用户 www-demo 使用 /srv/ssh/www/demo 作为 jail 目录

# mkdir /srv/ssh/www/demo/public_html
# chown www-demo:sftponly /srv/ssh/www/demo/public_html
# chmod 755 /srv/ssh/www/demo/public_html

用户现在应该能够在此目录内创建文件/子目录。有关更多信息,请参阅文件权限和属性

仅允许上传

要仅允许通过 sftp 上传文件并拒绝下载文件,请更改 ForceCommand internal-sftp

/etc/ssh/sshd_config
Match Group sftponly
  ForceCommand internal-sftp -u 0666 -p realpath,open,write,close,lstat

日志记录

用户将无法访问 /dev/log。一旦用户连接并尝试下载文件,通过在进程上运行 strace 可以看到这一点。

创建子目录

ChrootDirectory 中创建子目录 dev,例如

# mkdir /usr/local/chroot/user/dev
# chmod 755 /usr/local/chroot/user/dev

现在您应该在 /usr/local/chroot/user/dev/log 创建一个套接字,openssh 将使用它。您可以将此套接字直接绑定到 /dev/log(如果您正在使用 journald,则为 /run/systemd/journal/dev-log),或者使用 syslog-ng/rsyslog 创建。

绑定到 journald

# touch /usr/local/chroot/user/dev/log
# mount --bind /run/systemd/journal/dev-log /usr/local/chroot/user/dev/log

要使其永久生效,请将条目添加到 fstab

/etc/fstab
/run/systemd/journal/dev-log /usr/local/chroot/user/dev/log none bind,nofail,x-systemd.requires=sshd.service

Syslog-ng 配置

/etc/syslog-ng/syslog-ng.conf 中为日志添加一个新源并添加配置,例如更改以下部分

source src {
  unix-dgram("/dev/log");
  internal();
  file("/proc/kmsg");
};

source src {
  unix-dgram("/dev/log");
  internal();
  file("/proc/kmsg");
  unix-dgram("/usr/local/chroot/theuser/dev/log");
};

并附加

#sftp configuration
destination sftp { file("/var/log/sftp.log"); };
filter f_sftp { program("internal-sftp"); };
log { source(src); filter(f_sftp); destination(sftp); };

(可选)如果您想将 SSH 消息类似地记录到其自己的文件中

#sshd configuration
destination ssh { file("/var/log/ssh.log"); };
filter f_ssh { program("sshd"); };
log { source(src); filter(f_ssh); destination(ssh); };

(来自 Syslog-ng#Move log to another file

OpenSSH 配置

编辑 /etc/ssh/sshd_config 以将所有 internal-sftp 实例替换为 internal-sftp -f AUTH -l VERBOSE

重启服务

重启 syslog-ngsshd 服务。

/usr/local/chroot/theuser/dev/log 现在应该存在。

SFTP 的替代方案

安全复制协议 (SCP)

安装 openssh 提供了 scp 命令来传输文件。SCP 可能比使用 SFTP 更快 [1]

安装 rsshAURscponly 作为替代 shell 解决方案。

Scponly

安装 scponly

对于现有用户,只需将用户的 shell 设置为 scponly

# usermod -s /usr/bin/scponly username

有关更多详细信息,请参阅 Scponly Wiki

添加 chroot 监狱

该软件包附带一个用于创建 chroot 的脚本。要使用它,请运行

# /usr/share/doc/scponly/setup_chroot.sh
  • 提供答案。
  • 检查 /path/to/chroot 是否具有 root:root 所有者,以及其他人的 r-x 权限。
  • 将所选用户的 shell 更改为 /usr/bin/scponlyc
  • sftp-server 可能需要一些 libnss 模块,例如 libnss_files。将它们复制到 chroot 的 /lib 路径。

参见