跳转至内容

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 下完成 —— 也可以在实际分区上完成,然后通过绑定挂载(bind mount)挂载进去。
  • 也可以直接 chroot 到 /home 目录,从而跳过绑定挂载,但目标用户主目录必须由 root 所有
# chown root:root /home/<username>
# chmod 0755 /home/<username>

将要共享的实际 文件系统绑定挂载到该目录。在本例中,使用 /mnt/data/share,由 用户 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
注意 通过密码进行 SSH 身份验证(不推荐)仅在用户拥有登录 shell 访问权限时才有效(即未设置 -s /usr/bin/nologin)。

设置一个(复杂的)密码以防止出现 account is locked 错误(即使使用密钥验证也可能会出现)

# 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 的标准路径时,chroot 用户的 SSH 密钥验证将失败。为了修复此问题,请在 /etc/ssh/sshd_configAuthorizedKeysFile追加一个 root 所有的目录,例如 /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 作为监狱目录

# 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 路径。

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.