允许普通用户使用他们无法读取的私钥进行 SSH

允许普通用户使用他们无法读取的私钥进行 SSH

假设我有一组机器(此处称为客户机器),只允许一小部分人(称为支持人员)通过 SSH 访问,每台机器仅使用一个帐户(支持访问帐户)。

支持人员只能使用密钥登录客户的机器。此外,支持人员可以发展,因此离开支持人员的人不允许登录任何客户计算机。因此,禁止工作人员读取用于登录客户机器的私钥。另外,禁止修改authorized_keys客户机器上的文件。

为了实现该配置,我想到使用支持人员将登录的 SSH 代理(使用 LDAP 身份验证,但这是另一个问题)并且包含私钥。

问题是:如何允许支持人员在无法读取的情况下使用 SSH 私钥?

我相信我必须在代理计算机上创建一个以 root 身份运行的守护进程,它将接受用户的请求并为他们打开 SSH 会话,但我不知道该怎么做。有任何想法吗?

答案1

您真正想做的是使用 SSH CA 并签署每个支持人员使用的密钥(他们应该有自己的 ssh 密钥,如护照),并配置您的客户端服务器以使用TrustedUserCAKeys /etc/ssh/users_ca.pub/etc/ssh/sshd_config.conf 中的 SSH CA 和签名密钥。这样,服务器将接受由 CA 密钥(您有权访问)签名的任何密钥,并且您将能够撤销不再支持的人员的密钥,甚至无需触及授权密钥。

快速搜索“ssh ca”即可找到本教程:https://www.digitalocean.com/community/tutorials/how-to-create-an-ssh-ca-to-validate-hosts-and-clients-with-ubuntu(向下滚动到“如何配置用户密钥”)-虽然教程提到 Ubuntu 它是独立于发行版的,但您需要支持 SSH CA 的新版本 OpenSSH

关于该主题的另一个很好的博客文章是https://ef.gy/hardening-ssh(向下滚动到“SSH 证书”)。

请特别注意,您可以将密钥签名为在有限时间内有效,因此它们将自动过期!

答案2

我会建议几个选择。

  1. sudo保护 ssh 密钥并要求您的支持团队使用。您可以使用包装器透明地完成此操作。比如说,调用包装器,/usr/local/bin/ssh-support并让它包含类似这样的内容(未经测试):

    #!/bin/bash
    export PATH=/usr/local/bin:/usr/bin:/bin
    export IFS=$' \t\n'
    export SUSER=ssupport
    
    # Restart if not running under sudo
    test "X$1" != 'X-S' && exec sudo -u "$SUSER" /usr/local/bin/ssh-support -S "$@"
    shift
    export SHOME="$(getent passwd "$SUSER" | cut -d: -f6)"
    
    # Extract single argument as hostname LABEL and validate that we have
    # an RSA private key for it. The target username, real hostname, port,
    # etc. can be defined in ~/.ssh/config for the user $SUSER (ssupport)
    label="$1"
    idfile="$SUSER/.ssh/id_rsa_for_$label"
    cgfile="$SUSER/.ssh/config"
    
    ok=true
    [[ "$label" =~ '/' ]] && { echo "Invalid label: $label" >&2; ok=; }
    [[ ! -s "$idfile" ]] && { echo "Missing identity file: $idfile" >&2; ok=; }
    [[ ! -s "$cgfile" ]] && { echo "Missing configuration file: $cgfile" >&2; ok=; }
    
    if test -n "$ok"
    then
        logger -t ssh-support "$SUDO_USER requested ssh to $label"
        exec ssh -i "$idfile" -F "$cgfile" "$label"
    fi
    exit 1
    

    这将需要sudoers文件中的一个条目允许support组中的用户使用该工具。此命令允许他们以用户身份运行该ssh-support工具ssupport- 您必须创建该用户。它才不是授予任何 root 权限。

    %support ALL = (ssupport) /usr/local/bin/ssh-support
    

    如果您很高兴支持用户不需要提供自己的密码来运行该工具(根据sudo脚本本身内的调用的要求),您可以sudoers这样修改定义:

    %support ALL = (ssupport) NOPASSWD: /usr/local/bin/ssh-support
    

    假设PATH包含,/usr/local/bin/那么您将使用 来调用它ssh-support clientname。还假设您已经像创建证书对一样创建了用户,并且有一个主机条目为ssupport目标计算机定义了用户、主机、端口等。您可能会明确禁用 X11 转发、端口转发等。像往常一样,该目录需要使用权限进行保护。/home/ssupport/home/ssupport/.ssh/id_rsa_clientname/home/ssupport/.ssh/id_rsa_clientname.pub/home/ssupport/.ssh/configclientname/home/ssupport/.ssh0700

  2. 为每个支持成员提供自己的本地用户帐户,并让每个人使用自己的私有 ssh 密钥来访问客户端的服务器。当某人离开支持小组时,您将从客户端服务器中删除他们的 ssh 密钥。这意味着您不再需要担心阻止您的员工知道 ssh 私钥。

答案3

有几个不同的答案,涉及通过 sudo 或 setuid 可执行文件调用的 ssh 包装脚本(对于某些特殊用途非根帐户)。作为nkms 说,将所有参数传递给 ssh 可以让用户使用我们要保护的 ssh 密钥执行任意操作。有些人提出的另一个极端是只允许主机名。

OP 说管理员需要能够上传东西。

您可以有两个不同的固定参数到 ssh 包装器。一个用于登录 shell,另一个用于 scp。除了主机名(和要上传的文件名)之外,没有用户提供的参数。

或者一个包装器脚本,它使用getopt自身来解析非常有限的选项,并将内容插入到大部分固定的 ssh 命令中。忽略(或错误)无法识别的选项将是正确的方法。

不要尝试过滤掉“危险”的 ssh 选项,只需编写一个可以执行两件事的包装器:交互式登录或上传文件(本地和远程文件名)。我想你仍然需要在那里进行一些消毒。

其实这还是很容易出错的。您必须找到一种方法来阻止用户将保存 ssh 密钥的文件作为本地文件提供。所以你仍然试图考虑所有需要禁止的事情,而不是从不允许任何事情开始。首先要确保文件名不包含任何@:.

答案4

您的支持人员始终通过该代理计算机进行连接,并且只能通过它进行连接,因此客户可以简单地使用 HostbasedAuthentication 对代理计算机进行身份验证

假设代理机器是supporters.pc并且您提供支持customer.pc

客户.pc将会有基于主机的身份验证 是/etc/ssh/ssd_config支持者.pc中列出/etc/ssh/shosts.equiv,其公钥在 中/etc/ssh/ssh_known_hosts

当您的支持人员登录时[电子邮件受保护],并执行ssh customer.pc,它将产生ssh-keysign(8)(需要设置uid),它将使用您无法读取的文件处理密钥签名,并向supporters.pc提供连接确实来自的证明支持者.pc。作为客户.pc信托支持者.pc,您的员工登录为支持

相关内容