如何正确管理用于服务器访问的SSH密钥

2020-09-27 03:15:46

通常,这是使用公钥-私钥加密实现的,每个开发人员都会生成自己的公钥-私钥对。每个开发人员的公钥都会添加到他们有权访问的每台服务器上的AUTHORIZED_KEYS文件中。

在这种情况下,应该从所有服务器中删除该开发人员的公钥。这可能是一项相当大的工作,具体取决于他们有权访问的服务器数量。更糟糕的是,如果手动完成此操作,则可能会有相当大的风险,即某些服务器上的密钥仍会被遗忘,因此访问仍然是开放的。

有一些商业和开源解决方案想要帮助解决这个问题。基本思想是您添加和维护该服务上的密钥和访问列表,当您删除密钥时,它们会将其从所有服务器中删除。

听起来不错,但它有一个非常大的缺点:它是一个潜在的失败的单一来源。如果有人捕获了对该服务的访问权限,他们就可以访问您的所有服务器。如果您无法访问该服务,那么在最坏的情况下,您也会失去对所有服务器的访问权限。

当我面临这个问题时,我在HackerNews上询问别人是如何解决这个问题的。

社会人士提出了一些很好的建议和见解,而解决这个问题的最好办法似乎是签署密钥,我将在这里向大家详细介绍这一点。

粗略的想法是:您仍然为每个开发人员生成一个公钥-私钥对。但是,您不会将公钥上传到您的服务器。

相反,您可以使用之前生成的所谓的证书颁发机构(CA)密钥对公钥进行签名。此签名只生成第三个证书文件,您将该文件返回给开发人员,开发人员将其放在私钥和公钥旁边的.ssh/文件夹中。

在服务器上,您只需告诉服务器您的CA的公钥,服务器就可以检测用户是否具有正确签名的证书,并且只允许拥有此类签名证书的开发人员访问。

签署证书时,您可以确定该签名的有效期。因此,如果您签署的有效期为3个月,而开发人员离开了公司,那么在3个月之后,他们肯定无法访问任何服务器。

现在你会说:嗯,但是我不想每3个月签一次每个人的钥匙,这是一个公平的观点。

一种可能性是自动化该过程,例如,通过构建一个服务,用户在使用公司电子邮件和密码授权时可以自动获得签名证书,但这超出了本文的讨论范围。

另一种简单的选择是,您签发有效期更长的证书,然后如果有人离开公司,您可以吊销证书,即使其无效。您可以在服务器上放置一个无效证书列表,而服务器将不再接受该用户。例如,可以通过在AWS S3或其他一些存储上放置此列表,并在每台定期拉取此证书的服务器上设置cronjob来实现此目的。

首先,您生成一个证书颁发机构公钥-私钥对,其中的私钥应该非常安全:

Umask 77#您希望它是private kdir~/my-ca&;&;cd~/my-caSSH-keygen-C ca-f ca-b 4096#请确保使用密码并将其安全存储。

然后,在您的服务器上指定允许您的CA签名的所有用户访问该服务器:

通过在/etc/ssh/sshd_config中添加一行,告诉服务器允许由其签名的用户访问:

要使更改生效,您应该重新加载ssh服务:sudo服务ssh reload。

现在,如果开发人员生成了他们的公钥-私钥对(例如,ssh-keygen-tecdsa-b521),他们只需向您发送他们的公钥(请注意,您永远不需要发送任何私钥!)。然后,您可以签署他们的公钥来生成他们的证书:

#在~/my-ca文件夹中,签署其公钥(此处:id_ecdsa.pub)ssh-keygen-s ca-i USER_ID-V+12w-z 1 id_ecdsa.pub。

-V+12w-证书过期前多长时间-此处有效期为12周。

-z 1-此证书的序列号-可用于以后使此特定证书无效,应该是唯一的。

它将生成证书id_ecdsa-cert.pub,您可以将其发送给开发人员,开发人员将其放入公钥-私钥对旁边的~/.ssh文件夹。

您的开发人员可能有不同的经验、不同的团队和角色,而且不是每个人都访问相同的服务器。

这样,您就可以在服务器上指定允许哪些角色访问服务器,并在签名过程中指定要签名的开发人员的角色。

当你加入一个新的开发人员时,你只需要生成一个证书,然后他们就可以访问所有相关的服务器,而不需要在这些服务器上添加任何东西。

首先,创建要配置访问权限的文件夹:sudo mkdir/etc/ssh/auth_projecals在该文件夹中,您可以使用服务器用户的名称创建文件,用户可以使用该名称登录。例如,要向某些角色授予root访问权限,请添加文件/etc/ssh/auth_projecals/root。

在/etc/ssh/auth_projecals/root中,您只需列出应该能够以root身份登录的所有角色,每行一个角色:

最后,通过在/etc/ssh/sshd_config中再次添加一行,在服务器上配置为使用角色:

要使更改生效,您应该重新加载ssh服务:sudo服务ssh reload。

这是使用角色对密钥进行签名的方式(角色将被添加到证书中):

它与前面相同,但是使用了-nROLE1、ROLE2标志。重要提示:不同角色的逗号之间不能有空格!

现在,开发人员可以登录到任何服务器,其中ROLE1或ROLE2在auth_projecals文件中,以获得他们试图登录的用户名。

最后,如果希望使证书无效,可以通过用户名或证书序列号(-z标志)来执行此操作。建议在Excel电子表格中列出生成的证书列表,或者根据窥视次数建立数据库。

这是当您已经有一个已撤销的密钥列表并想要更新它的时候(-u标志)。对于初始生成,请在不带更新标志的情况下使用它。

要撤销的列表需要由用户名(ID)或序列号(生成期间的-z标志)组成,如下所示:

这将撤销对序列号为1的证书和ID为test.user的所有证书的访问。

要让服务器尊重已撤销的密钥,您需要将生成/更新的已撤销密钥文件添加到/etc/ssh/revoked-key中,并在/etc/ssh/sshd_config中重新配置:

警告:请确保吊销的密钥文件是可访问和可读的,否则可能会失去对服务器的访问权限。

在我看来,这个解决方案是最好的。您可以选择根据角色通过ssh管理对服务器的访问。您只需配置您的服务器一次(允许哪些角色访问它)。对于每个新开发人员,您只需要生成签名证书,他们就可以立即访问与其角色/经验匹配的所有相关计算机。当他们离开公司时,您还可以通过简单的方式撤销他们的访问权限。

而且,即使发生意外,开发人员在访问权限没有被撤销的情况下离开,他们的证书也会在一段时间后过期,因此他们也会自动失去访问权限。

对于小型团队,您可以手动完成这些步骤,因为它们的执行速度非常快;然后,随着您的发展,您可以根据公司身份验证详细信息使用登录服务自动执行证书签名。

由Disqus提供支持的评论