关注了就能看到更多这么棒的文章哦~

Restricting SSH agent keys

By Jake Edge
January 5, 2022
DeepL assisted translation
https://lwn.net/Articles/880458/

OpenSSH 这一系列工具是用于安全地进行远程登录的,在我们的社区中已经在广泛使用了。它也是远程访问 Git 仓库等功能的基础。最近,即将发布的 OpenSSH 8.9 中有了一个实验性的功能,希望有助于填补一个安全漏洞。当用户在把 authentication 转发给本地的 ssh-agent 时,攻击者控制的 SSH 服务进程(例如 sshd)就有机会利用这个漏洞。原本 SSH agent 里保存的这些安全密钥会被用来跟任何 host 来进行认证,现在 SSH agent restriction 则允许用户指定这些密钥可以用在什么地方,以及如何使用。

ssh-agent 是用来简化对同一 host 进行重复连接的场景。它会存储和管理 SSH 密钥,这样就不需要在每次连接时输入保护密钥的口令(passphrase)了。通常情况下,至少需要用 passphrase 口令来解锁一次密钥,然后就使用 ssh-add 操作时会被 agent 保存起来。此外也可以用 ssh_config 里的 AddKeysToAgent 选项来实现相同目的。ssh-agent 是一个 "专门设计得尽量简单的程序",因为它会持有私钥。Damien Miller 对这个新功能的描述是这样的:

它采用的是一个简单的、由 client 来发起的协议,带有少量的操作,包括添加或删除密钥、从加载的密钥来检索出一系列的公钥,以及最重要的功能是用私钥来进行签名。跟 agent 进行交互大多数是通过 ssh-add 工具来完成的,包括添加、删除和列举密钥,此外还有 ssh 工具会使用 agent 中持有的密钥来进行用户认证,但也可以支持其他工具,只要它们都遵守这个协议就行。

由于 agent 中持有非常重要的密钥信息,因此它是 "一个经常被攻击者利用的、理想的攻击对象"。agent 只能从本地系统来访问到,这就大大地限制了攻击面(attach surface),除非对该 agent 的访问专门被转发(forward)到远端系统。使用 ssh 的 -A 选项(或 ForwardAgent 这个 config 选项)就能让远程 host 能够与本地 agent 通信。然后,该远程 host 就跟本地程序一样可以发起所有 agent 相关操作了。

这种代理转发(agent forwarding)通常是用来进行多跳 SSH 连接的(multi-hop SSH connections),这个过程中不再需要多次重新输入 passphrase 来解锁远端 host 上的密钥。这也意味着私钥不需要存储在远程 host 上。当一个用户远程连接到 HostA,并从 HostA 来使用相同的 SSH 密钥连接到一个或多个其他 host 的时候,就会了解到与 HostA 进行初始 SSH 连接就启用 agent-forwarding 的话就会非常方便。从 HostA 发起的 SSH 连接都可以继续扩大 agent-forwarding 的范围。

当把 agent 的访问转发到一个攻击者控制的系统时,问题就出现了,这个恶意系统可以使用存储在 agent 中的密钥来认证并登入这个密钥所支持的任何其他 host 了。因此,用户可能对 HostA、HostB 和 HostC 使用了 forwarding 功能,但他们的密钥也会授予他们对 HostV 或 HostZ 的访问权,也许这两个就是攻击者希望访问的目标了。目前,SSH 没有办法限制代理所持有的密钥是如何使用的,这就是这里的新功能希望要解决的问题。

解决方案的一部分就是将对于 agent 的本地访问以及远程访问区分开,因此,即使 agent 的访问权被转发出去,那么一些密钥也只能是在从本地访问时才可以获取。其实将这两种类型访问 agent 的操作混为一谈是很久以前所做的一个错误决定,所以现在可以添加密钥时限制其使用方式的话就可以帮助改善这个问题。作者为 ssh-add 新增了一个 -h 选项,用来描述一个密钥的合法用途,正如功能描述中一个例子所说的:

新增的功能使得用户可以为他们所添加到 ssh-agent 中的密钥来增加一个 destination 限制,并让 ssh 能确保施行这些限制。比如这个命令:
$ ssh-add -h "perseus@cetus.example.org" \
-h "scylla.example.org" \
-h "scylla.example.org>medea@charybdis.example.org" \
~/.ssh/id_ed25519

所添加的密钥只能在以下情况之下用来进行认证:

  1. 从原始 host 发起的到 scylla.example.org 的人和用户的连接。

  2. 从原始 host 的用户 perseus 发起的到 cetus.example.org 的连接。

  3. 从 scylla.example.org 的用户 medea 发起的到 charybdis.example.org 的连接。

试图利用这个密钥来对其他 host 进行认证的话,就会被 agent 拒绝,因为不在上面明确列出的访问清单里面。比如试图通过 scylla.example.org 来对 cetus.example.org 进行认证就是不允许的。同样,试图登录为其他用户名,然后想访问 cetus.example.org 的 perseus 用户或 charybdis.example.org 的 medea 用户也都会失败,因为不符合指定的用户。

还可以指定更复杂的路径,但其中每一个跳板都需要在其 -h 选项中列出。所以一个多级跳板的路径可能看起来像这样:

$ ssh-add -h "HostA" \-h "HostA>HostB" \-h "HostB>HostC" \key-file

需要注意的是,像上面这样配置的 agent 就不会再允许使用 agent 里的密钥来直接从本地系统访问到 HostB 或 HostC,也就是它们只能通过指定的跳板才能到达了。然而,用户仍然能够绕过 agent,通过在 ssh 提示时输入密钥的 passphrase 的方式来直接进入 HostB 或 HostC。

要使用这个新功能的话就需要更新客户端工具,但也需要更新远程系统上的 SSH 服务。agent 的协议也需要改变,才能在认证请求中加上服务端的 host 密钥,所以旧版本的 SSH 服务就无法参与到这个新的方案里面了。如果 ssh-add 或 SSH 服务端不支持这个 agent restriction 功能的话,该功能也将采用 "fail safe (安全后备)" 方案。如果 ssh-add 不能理解对于访问目标的限制条件,它会直接失败,agent 也就会拒绝这些没有发送方的 host 密钥的认证请求。

这里还有一些注意事项。其中最大的问题是,攻击者仍然可以劫持 agent connection,因此他们可以使用不符合预期要求的 host 来请求对已经授权的 host(和用户)进行认证:

有个不太明显的问题,那就是他们还能将 agent 的访问转发给其他 host,例如通过使用不能配合 ssh-agent 的 SSH 实现版本,或者完全是使用另一种工具比如 socat。请注意,攻击者在这里并没有获得任何新的密钥,他们仍然需要被迫通过被攻击的 host 来做事,他们仍然被限制在只能访问到那些只允许在指定 host 上使用的密钥。

[……]因为有这些微妙之处,所以最好把密钥限制功能看作是允许“经过”某个特定 host 来使用密钥,而不是“从”指定的 host,而且,更广泛地来说的话,任何一条 forward 链路的强度完全取决于链路中最薄弱的那个环节。还有另一种理解密钥限制功能的方法,那就是每一个密钥限制都代表把一个密钥委托给了一个 host,可信程度上只比委托者略高一点。

总的来说,这似乎是 SSH 工具中的一个会受到欢迎的补充。其所提供的限制功能肯定会有用的。很高兴知道 agent forwarding 功能不再会能够访问到这个密钥可能会访问到的所有主机。介绍该功能的文档非常详细,令人钦佩,其中包括了实施细节、未来的计划等等。鼓励感兴趣的读者自己也看看。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

LWN:限制SSH agent密钥!相关推荐

  1. SSH Agent Forwarding原理

    转载自:http://blog.pkufranky.com/2012/08/ssh-agent-forwarding-guide/ ssh-agent的manual写得倒是挺详细,可看了好几次都没怎么 ...

  2. SSH配置密钥登录时需要注意私钥是否设置了密码(passphrase)

    如题 最近需要配置SSH于登录后台服务器查日志,然后使用的是SSH的密钥登录方式,因为密钥对(公钥与私钥)是在服务器后台管理系统生成的,而且是前一段时间申请下来的,自己忘记了密钥申请的有填写过私钥的p ...

  3. 016 在大数据中,SSH无密钥登录

    一:概述 1.关于ssh ssh是一种安全协议. 会生成一对公钥和私钥. 2.问题的由来 3.解决方式 将生成的公钥发送到远程的机器上. 4.位置 主目录下的.ssh文件下. 二:在伪分布式下的操作 ...

  4. 多台服务器通过ssh 无密钥直接登陆主机

    实验环境:两台centos服务器,一台叫centos_68,一台叫512430,两台都有做秘钥远程登陆. 实验目的:两台服务器实现ssh无密钥直接登陆对方服务器. 1)首先要保证ssh开放端口为22, ...

  5. gitlab用户添加ssh免密钥认证后clone还是要求输入密码

    今天在centos 7公网服务器上安装gitlab在配置ssh免密钥时遇到一个奇怪的事,正确添加了本机的公钥到gitlab账户上,进行clone时死活都要你输入密码gitlab使用yum安装的,之前在 ...

  6. linux 多个秘钥,linux管理多个ssh公钥密钥

    很多网上免ssh密码使用git的命令都没有考虑到多个公钥密钥的情况,这里搜集并整理一下管理多个ssh公钥密钥的步骤. 首先生成公钥和密钥,默认情况公钥的文件名比密钥末尾多.pub ssh-keygen ...

  7. jenkins用ssh agent插件在pipeline里实现scp和远程执行命令

    现在ssh agent的认证,已不支持明文用户密码,而只能用加密方式实现. 所以我先在jenknis和nginx服务器之后,实现ssh免密码rsa证书登陆. 私钥放jenkins,公钥放nginx.然 ...

  8. SSH agent refused operation

    SSH agent refused operation 今天用ubantu16.0桌面版配置ssh免密码登录自己的时候,出现了这个灵异事件,最后终于找到了问题 首先,打开这个文件的权限 chmod 7 ...

  9. ssh密钥代理转发(ssh agent forwarding)

    之前一直用SecureCRT登陆服务器A然后再跳到服务器B,某日突然需要从另一台可信任的机器C用ssh登陆,ssh的key已经复制好,所以登陆A没有问题,但是登陆B会出现Pubkey Unauthor ...

最新文章

  1. Java学习笔记45:Java 线程与主线程之间的变量关系
  2. Android开发_如何调用系统默认浏览器访问
  3. Matlab中typecast函数由int8转换为int32
  4. 解决sublime3 中文乱码问题
  5. ASP.NET MVC 3: Razor视图引擎中 @: 和text 语法【转载】
  6. 关于redis集群脑裂及其解决方案
  7. Linux添加环境变量与GCC编译器添加INCLUDE与LIB环境变量
  8. 大数据时代个人隐私权保护机制构建与完善
  9. 双十一来临,你就不想知道阿里后台都做了哪些准备吗?
  10. 学习并掌握结构化写作方法,提高写作能力 ——结构化写作学习笔记(1)
  11. kubernetes(k8s)第五部分之K8s部署nginx
  12. 浅谈Ubuntu 18.04.1 LTS x86_64安装,美化配置及常用软件安装配置的历程
  13. Superset安装部署
  14. Nodeparty-SZ-1 深圳聚会活动回顾总结[2012.01.08] - CNode
  15. C语言程序设计实践题,2020年C语言程序设计实践实验题目.doc
  16. 无法调用自己电脑的gpu,即torch.cuda.is_available()返回false
  17. python实现爬取非小号相关性(btc)数据
  18. python封装mel命令
  19. 2021InfoComm|钉钉会议 Rooms 的 “全场景“ 智能化解决方案
  20. 基于热电偶的温控系统

热门文章

  1. 计算机电子表格三维簇状柱形图怎么设置,excel怎么制作三维簇状柱形图 excel三维簇状柱形图如何添加标题...
  2. 【Pytorch基础教程32】基于transformer的情感分类
  3. 中国象棋java算法_Java中国象棋博弈程序探秘[5]——搜索算法
  4. 【云原生】设备入云之FlexManager实际项目操作流程
  5. vue + echarts+地图实现功能,实现地图上数据显示,四川省地图echarts地市数据案列
  6. 【C++ 之 C++ 操作 json 文件(C++读写json文件)及jsoncpp配置详解】
  7. 小红书店铺需不需要开?在小红书开店需要注意什么
  8. NTlite给window瘦身+定制程序员专属环境
  9. 30款 香水品牌logo设计灵感 - logo设计公司 - ci设计
  10. MATLAB画图——设置轴标签不同字体