开发者经常需要访问某些服务器,做一些检查应用日志等工作。通常,使用公私密钥密码术控制访问,每个开发人员生成自己的公私密钥对。并且,每个开发人员的公钥都被添加到他们有权访问的每个服务器上的authorized_keys文件中。1.痛苦的手动更改到目前为止一切都很好。但是当开发人员离开时会发生什么?在这种情况下,应从所有服务器中删除开发者的公钥。根据他们有权访问的服务器数量,这可能需要大量工作。更糟糕的是,如果这个过程全部是手动的,操作员很可能会忘记删除某些服务器上的公钥。也就是说,离职员工的访问权限仍然可用。2.替代解决方案有一些商业和开源解决方案可以帮助我们解决这个问题。这里的基本思想是您添加并维护一个密钥列表和对此类服务的访问权限,当需要删除一个密钥时,该密钥将从所有服务器中删除。这听起来不错,但这个方案有一个很大的缺陷:它是一个潜在的单一失败源。如果有人获得了对服务的访问权限,则意味着他们可以访问您的所有服务器。而且,如果您无法访问此服务,在最坏的情况下,您将无法访问所有服务器。解决方案:签名密钥当我遇到这个问题时,我去了HackerNews并询问其他人是如何解决它的。https://news.ycombinator.com/item?id=24157180社区提供了一些很好的建议和见解,这个问题的最佳解决方案似乎是对密钥进行签名,本文对此进行了详细说明。基本思路该方??法的基本思路是:你还是要为每个开发者生成一对公私钥。但是,不要将公钥上传到服务器。相反,公钥使用先前生成的所谓证书颁发机构(CA)密钥进行签名。这个签名就是生成第三个证书文件,你返回给开发者,然后让他们把它放在.ssh/文件夹下,连同私钥和公钥。在服务器上,你只要告诉服务器你的CA的公钥,服务器就可以检测用户是否有正确签名的证书,只允许有这样签名证书的开发者自己访问。优点签署证书时,您可以定义此签名的有效时间。所以如果你签了3个月,然后开发人员离开了公司,3个月后他们肯定就不能访问任何服务器了。现在你说:好的,但我不想每3个月签署一次每个人的密钥,这是一个有效的投诉。一种方法是自动执行此过程,例如,您可以构建一项服务,让用户在使用公司电子邮件和密码进行授权时自动获得签名证书,但这超出了本文的范围。另一个简单的替代方法是您可以颁发有效期更长的证书。然后,如果有人离开公司,证书可以被撤销,即无效。您可以在服务器上放一个无效证书列表,它们将不再接受用户访问。例如,您可以通过AWSS3或其他存储托管此列表,并定期在每台服务器上创建一个cronjob来执行此操作。怎么做?明白了原理,其实做起来也很简单。首先,你需要生成一个证书颁发机构公钥-私钥对,你应该把这个私钥放在一个非常安全的地方:umask77#youwantittobeprivatemkdir~/my-ca&&cd~/my-cassh-keygen-CCA-fca-b4096#besuretouseapassphraseandstoreitsecurely然后在你的服务器上,设置为允许所有你CA签名的用户访问服务器:上传CA的公钥到服务器,比如放在/etc/ssh/ca.pub中/etc/在ssh/sshd_config中添加一行,指示服务器允许访问由该证书签名的用户TrustedUserCAKeys/etc/ssh/ca.pub#Trustallwithacertificatesignedbyca.pub要使更改生效,您应该重新加载ssh服务:sudoservicesshreload.现在,如果开发人员生成他的公私密钥对(例如ssh-keygen-tecdsa-b521),他们只会向您发送他们的公钥(请注意,您永远不需要发送任何私钥!)。然后,您可以通过简单地签署他们的公钥来生成他们的证书:#Insideyour~/my-cafolder,signtheirpublickey(here:id_ecdsa.pub)ssh-keygen-sca-IUSER_ID-V+12w-z1id_ecdsa.pubParts简要说明:-sca:你要使用CA来签名-IUSER_ID:你的用户ID/用户名-V+12w:证书过期前的有效时间,这里的有效期是12周-z1:这个证书编号的顺序,以后可以用来使这个证书失效,序列号应该是唯一的然后放在~/.ssh文件夹中的公钥/私钥对旁边。改进听起来不错,但您可以做得更好!您的组织可能有许多不同经验水平的开发人员,他们在不同的团队中并且承担不同的职责,并且并非每个人都可以访问相同的服务器。话虽如此,让我们在签名过程中添加角色。这样,您可以在服务器上设置允许哪些角色访问服务器,并且在签名过程中您可以指定要签名的开发人员的角色。然后,该开发人员可以访问与其角色匹配的所有服务器。当您添加新的开发人员时,只需生成一个证书,他们就有权访问所有相关服务器,而无需在这些服务器上添加任何内容。基本上它是这样的:使用角色进行ssh证书签名以下是在服务器上配置角色的方式:首先,创建配置访问的文件夹:sudomkdir/etc/ssh/auth_principals。在此文件夹中,您可以使用允许登录服务器的用户名创建文件。例如,要授予某些角色root访问权限,请添加文件/etc/ssh/auth_principals/root。在/etc/ssh/auth_principals/root里面,简单的列出所有可以root登录的角色,每行一个角色:adminsenior-developer最后在/etc/ssh/sshd_config中再添加一行,在服务器上配置使用角色:AuthorizedPrincipalsFile/etc/ssh/auth_principals/%u要使更改生效,您应该重新加载ssh服务:sudoservicesshreload。以下是使用角色对密钥进行签名的方式(它们被添加到证书中):ssh-keygen-sca-IUSER_ID-nROLE1,ROLE2-V+12w-z2id_ecdsa.pub这里与之前相同,但使用-nROLE1,ROLE2符号。重要提示:不同字符的逗号之间不能有空格!现在,该开发人员可以登录到auth_principals文件中具有ROLE1或ROLE2的任何服务器,以获取他们尝试登录时使用的用户名。撤销密钥最后,如果您想使证书失效,您可以通过用户名或证书的序列号(-z标志)来实现。建议您将生成的证书在Excel电子表格中列出,或者根据您的情况建立数据库。ssh-keygen-k-frevoked-keys-u-scalist-to-revoke在您已经有一个已撤销密钥列表并想要更新它(-u标志)时执行此操作。对于初始构建,删除更新标志。list-to-revoke需要包含用户名(id)或序列号(生成期间的-z标志),如下所示:serial:1id:test.user这将撤销序列号为1且ID为test的证书。访问用户的所有证书。为了让服务器知道已撤销的密钥,您需要将生成/更新的已撤销密钥文件添加到/etc/ssh/revoked-keys并在/etc/ssh/sshd_config中再次配置它:WARNING:Ensurerevoked-keys该文件是可访问和可读的,否则你可能无法访问服务器RevokedKeys/etc/ssh/revoked-keys3.总结:ssh密钥管理的好方法我认为这个解决方案是最好用的。您可以选择基于角色通过ssh管理对服务器的访问。您只需要配置一次服务器(允许哪些角色访问服务器)。对于新入职的开发人员,您只需生成一个签名证书,他们就可以立即访问与其角色/经验相匹配的所有相关机器。当他们离开公司时,您还可以轻松地撤销他们的访问权限。即使发生不幸的事故,开发人员没有取消访问权限就离开了,他们的证书会在一段时间后过期,因此他们也会自动失去访问权限。对于小团队,您可以手动执行这些步骤,因为它们可以很快完成;然后随着您的成长,您可以使用基于公司身份验证详细信息的登录服务来自动执行证书签名。
