使用 SFTP 限制无密码备份

Que*_*low 11 ssh sftp account-restrictions key-authentication

我需要使用 Duplicity 将服务器备份到我的计算机:

duplicity /etc sftp://backup@my.dynamic.ip.address//home/backup
Run Code Online (Sandbox Code Playgroud)

在此之前,我需要通过执行以下操作来允许无密码访问:

$ ssh-keygen
$ ssh-copy-id backup@my.dynamic.ip.address
$ ssh backup@my.dynamic.ip.address
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何在生成的公钥中将命令限制为仅此 SFTP 传输?

command="restrict to sftp",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAA…

并且由于我使用的是动态 IP 地址,因此每次 IP 更改时我如何克服“丢失已知主机”的问题?

slm*_*slm 15

问题#1

我的问题是,如何在生成的公钥中将命令限制为仅此 SFTP 传输?

有两种方法可以做到这一点。

1. -- 通过sshd限制

此方法涉及在 SSH 守护程序中设置 SFTP 功能,sshd. 这是通过/etc/ssh/sshd_config配置文件控制的。注意:这将限制用户backup只能通过 SFTP 进入服务器。

# /etc/ssh/sshd_config

Subsystem       sftp    internal-sftp

## You want to put only certain users (i.e users who belongs to sftpusers 
## group) in the chroot jail environment. Add the following lines at the end 
## of /etc/ssh/sshd_config

Match User backup
  ForceCommand internal-sftp
Run Code Online (Sandbox Code Playgroud)

2. -- 通过authorized_keys限制

此方法不涉及对sshd_config文件的任何更改。您可以通过command=您在问题中已经提到的功能将用户 + SSH 密钥限制为单个命令。诀窍在于您包含的命令。你可以把SFTP服务器放在这一command=行,这和在你的sshd_config文件中设置SFTP服务器的效果是一样的。

# User backup's $HOME/.ssh/authorized_keys file
command="/usr/libexec/openssh/sftp-server" ssh-dss AAAAC8ghi9ldw== backup@host
Run Code Online (Sandbox Code Playgroud)

注意:如果用户对 有写访问权限 ~/.ssh/authorized_keys,他们可以读取和/或修改它。例如,他们可以下载、编辑并重新上传它,去掉 . commmand=...,授予他不受限制的命令访问权限,包括 shell。如果用户拥有对 的写访问权限~/.ssh,他们也可以简单地取消链接并重新创建文件,或者chmod对其进行写访问。存在许多可能的解决方案,例如将~/.ssh/authorized_keys文件放在非用户可写的地方,例如:

Match Group sftponly
    AuthorizedKeysFile      /etc/ssh/authorized_keys/%u
Run Code Online (Sandbox Code Playgroud)

问题2

并且由于我使用的是动态 IP 地址,因此每次 IP 更改时我如何克服“丢失已知主机”的问题?

这有点棘手,但也可以使用文件中的from=功能authorized_keys。在这里,我们只限制来自主机的访问,somehost.dyndns.org

from="somehost.dyndns.org",command="/usr/libexec/openssh/sftp-server",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-dss AAAAC8ghi9ldw == 备份@主机

后面的附加设置command=同样重要,因为它们会进一步限制 SSH 密钥的使用。

特征分解

  • from='hostname1,hostname2,'' - 限制来自指定 IP 或主机名模式的访问
  • command='command' - 认证后运行指定的命令
  • no-pty - 不分配 pty(不允许交互式登录)
  • no-port-forwarding - 不允许端口转发
  • no-X11-forwarding - 用户将无法删除显示 X11 GUI
  • no-agent-forwarding - 用户将无法通过此主机转发到其他内部主机

要摆脱有关“缺少已知主机”的消息,您可以在客户端连接时将此 SSH 选项添加到客户端,如下所示:

$ ssh -o StrictHostKeyChecking=no ....
Run Code Online (Sandbox Code Playgroud)

ssh_config有关此开关的完整详细信息,请参阅手册页。

限制用户的shell

对于上述两种解决方案,您可能还希望backup通过在/etc/passwd文件中限制此用户的 shell来锁定用户。通常您希望将其设置为scponly,但也有其他选择。参见这个 U&L 问答题:“你需要一个 SCP 的外壳吗? ”了解这样做的方法。

采用/sbin/nologin可以的,如果你选择使用chroot功能的也可以用来sshd_config作为概括#1以上。但是,如果您选择使用#2 中概述的方法,那么您可能必须scponly/etc/passwd.


奖励 - 扩展上面的 #2

如果您需要为该用户公开一组命令,您也可以这样做。像这样创建一个脚本,/home/backup/commands.sh

#!/bin/sh

case $SSH_ORIGINAL_COMMAND in
  "diskspace")
    df -h
    ;;
  "dirlist")
    ls -1
    ;;
  "apache_restart")
    /etc/init.d/apache restart
    ;;
  *)
    echo "Unknown command"
esac
Run Code Online (Sandbox Code Playgroud)

然后authorized_keys像这样设置文件:

command="/bin/sh /home/user/commands.sh" ssh-dss AAAAC8ghi9ldw== user@host
Run Code Online (Sandbox Code Playgroud)

然后backup用户可以像这样运行这些命令:

# diskspace
$ ssh -q user@remote_host diskspace
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/dev-root   39G  2.2G   35G   6% /

# dirlist
$ ssh -q remote_host dirlist
commands.sh
dump.sql
Run Code Online (Sandbox Code Playgroud)

参考

  • 请注意允许用户访问哪些命令,或者用户可能有能力获得完整的 shell。举个例子,如果你让某人访问 vim,他们可以轻松地 :!/bin/bash 或 :!/bin/someotherprogram。 (2认同)