SSH自己动手的单点登录

TL; DR在本文中,我们将安装Google的SSH单点登录。在幕后,我们使用OpenID Connect(OICD),SSH的短期证书,一些SSH配置技巧和opensorsnymi软件包step-ca以及stepSmallstep。我们将配置SSH证书颁发机构,并使用它在系统中加载新用户和新主机。这种方法除了单点登录外,还具有许多优点,因为authorized_keys与设置典型的公用/专用SSH密钥对相比,尽管需要更多的准备工作,但无需收集,传输和控制文件

如何不使用SSH


早在2004年,有人教我如何将公钥复制到文件中authorized_keys。从那时起,我继续无辜地将相同的旧公共密钥复制到必须使用的每个服务器上,由于忘记了正确配置,所以我第一次始终无法这样做chmod

仅一次,当OpenSSH在2015年宣布我的密钥类型已弃用时,我不愿更换密钥。几年前的现在,只能猜测我的公钥仍位于哪些服务器上。也许我曾经与之合作的老创业公司?自由客户有吗?在我侄女的加密农场吗?

从组织的角度来看,文件authorized_keys很烂。也许起初有人像我一样手动编写它们,但是随着主机和用户数量的增加,这样的任务变成了一场噩梦。一天早晨,您在拖延了基础架构的大量公共密钥中醒来。

大多数组织通常会创建一个剧本来自动执行文件管理。authorized_keys但是,无论执行的合理性如何,它们的收集,卸载和维护都一团糟。

Single Sign-On OpenID Connect SSH


我们不使用文件,authorized_keys而是配置SSH证书颁发机构并通过SSH通过短期证书进行访问,并且为了支持单点登录,我们添加了OpenID Connect(OICD)。一旦成功,结果将非常好,所以请耐心等待,因为与开箱即用的典型SSH配置相比,我们需要更多的准备设置。

什么是SSH证书? SSH证书是替代一对公共/秘密SSH密钥的替代方案。用户和主机在SSH连接(握手)期间交换证书,这是TLX X.509证书的一种截断版本,其方式与一对SSH密钥相同。为了进行更深入的分析,我们建议您阅读下一篇文章

您可以在下面看到解密的SSH证书:

-:
        Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
        Public key: ECDSA-CERT SHA256:N7ErGTPjhmruRS/4OiwyRi6Iyr59z0Ur1ifkHIHu4V8
        Signing CA: ECDSA SHA256:E0GH/kZ/CGUIe8mMzzpujIiEYGC2IHDHafYBnye1WSU
        Key ID: "carl@smallstep.com"
        Serial: 16253962425132258867
        Valid: from 2020-03-23T16:01:39 to 2020-03-24T08:01:39
        Principals:
                carl
                carl@smallstep.com
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

如上例所示,用户证书允许主机对用户进行身份验证,而主机证书可帮助用户识别主机。关键区别在于领域Principals

默认情况下,在SSH连接期间,SSHD将允许您在
Principals用户证书字段的用户名下输入主机同样,SSH希望在Principals主机证书

字段中看到主机名 此外,证书可以具有允许特权SSH功能(例如,代理转发和端口转发)或强制配置指令的扩展。

为使一切正常,我们将配置SSH证书颁发机构(CA),即-step-caSmallstep的服务器。如果他们具有适当的权限,则用户和主机将从我们的CA接收SSH证书。

下面是Alice如何获得用户证书并输入主机的示意图:



我们将通过与命令行工具 一起使用的stepOpenSSH配置单元来配置CA。

好处


  • 不再需要公共密钥管理。您将不再遇到基础结构分散了无数(实际上相等users * hosts)个文件的情况authorized_keys主机上的用户将不再需要分区.ssh
  • . SSH , SSH , SSH , OAuth.
  • . SSH OAuth OICD Google ( 2FA ). .
  • . EC2 Instance Identity Documents (IIDs), AWS .
  • . — .
  • Trust On First Use (TOFU). , :

    The authenticity of host 'ec2-3-15-28-130.us-east-2.compute.amazonaws.com (3.15.28.130)' can`t be established.
    
    ECDSA key fingerprint is SHA256:HYDAjwFL/qEmTuKm903tIk0fbPNk1CSRqH/usavToLw.
    Are you sure you want to continue connecting (yes/no/[fingerprint])?
    	


  • (, SCIM LDAP).
  • sudo.
  • (access control lists, ACLs) .
  • CA.
  • , .


  • EC2.
  • GSuite.
  • step
    • macOS brew install step.
    • Linux Debian.

Certificate Authority!


也许您认为这很困难和可怕。这种声誉赢得了证书颁发机构的神秘细节TLS X.509证书,只有一个号码在PKI(公钥基础设施,PKI)的世界首字母缩写,而仪器,如复杂openssl.

此外,大型CA,例如对于咱们加密,有一个巨大的确保Internet安全的职责数量。

我们不会使用“让我们加密”。

SSH证书比TLS证书简单。 SSH CA仅允许我们将对多台主机进行身份验证和授权的部分责任委托给一个集中式服务。

在这个项目中,我们将建立一个由三个提供者组成的CA,这是三种颁发证书的方法:

  • 对于用户证书,我们将使用与Google OAuth应用程序相对应OAuth OIDC提供程序。我们相信Google可以安全地访问人员,并仅向经过身份验证的用户发布有效的,由Google签名的OAuth身份验证令牌。CA将使用Google的公钥验证令牌。
  • 对于新的EC2主机,我们需要一个与我们的AWS账户匹配的AWS提供程序新主机将通过此提供程序请求SSH主机证书。我们信任AWS提供签名的Amazon IID,CA将使用Amazon的公钥验证它们。
  • 最后,我们使用SSHPOP提供程序进行每周主机证书更新

让我们开始吧?

1.创建一个Google OAuth凭证


在此项目中,您将需要Google 2.0 OAuth凭据,这需要花费几分钟的时间来创建它们。


写下客户ID客户机密,下一步将需要它们!
注意:您的CA仅会向与您的Google Cloud项目帐户相对应的GSuite组织中授权的用户颁发用户证书。

2.启动您的证书颁发机构


我们将在AWS实例的Ubuntu 18.04step-ca安装LTS我们应该有足够的免费AWS实例级别(t2.micro / t3.micro)。

采取此CA启动脚本并将所需值粘贴在顶部:

  • 客户OICD ID
  • OICD客户机密
  • 您的GSuite的域名
  • 您的CA名称
  • 根密钥密码
  • 你的邮件

将其下载为EC2用户数据脚本,然后在启动EC2实例时在第3步(设置实例)中使用它。

为了实现互连,您的VPC将需要连接的Internet网关,并且您的实例应位于一个安全组中,所有主机和用户都可以通过端口22(SSH)和443(HTTPS)访问该组。

需要注意的是,它
step-ca仅通过mTLS接受HTTPS连接-与典型的Web服务器相比,可以更好地保护其免受攻击。

使用您的PEM密钥连接到您的CA实例。

用户数据脚本的结果在中/var/log/cloud-init-output.log。检查它,并确保一切均已正确初始化并且step-ca可以正常工作。

CA必须创建以下密钥和证书:

  • /etc/step-ca/certs/root_ca.crt -您的CA的根TLS证书(自签名)。
  • /etc/step-ca/certs/ssh_host_ca_key.pub -CA SSH主机密钥允许用户验证主机证书。
  • /etc/step-ca/certs/ssh_user_ca_key.pub -CA SSH用户密钥允许主机验证用户证书。
  • 您还将具有/etc/step-ca/secrets上述证书和密钥的CA私钥签名密钥。要解密这些密钥,CA会在启动时从文件中读取其密码/etc/step-ca/password.txt

在根目录下,使用根CA密码删除用户数据脚本:

# rm /var/lib/cloud/instances/i-**/user-data.txt**

您将需要来自CA的一些信息:

  • 公共主机名,以便我们可以再次找到它。
  • 根证书的指纹-与该主机建立公共TLS连接。

在根目录下运行以下命令:

# step certificate fingerprint $(step path)/certs/root_ca.crt
5bc2b4779ad1562f6ed0809857fbed7925d2432eb25083f41a468532495ca658

记得写下来。您的CA已获得!

下载新主机


让我们加载Ubuntu实例,它将是我们的第一个ssh目标主机。

注意:您的CA仅将主机证书颁发给其AWS账户上的实例。

这次,要启动新实例,请使用“ 用户数据”主机脚本并填写以下值:

  • 您的CA地址(https://[CA hostname])。
  • CA的根证书的指纹。

在下面,您可以看到用户数据脚本应该做什么:



因此,我们获得了主机证书,以换取实例身份文档(IID)及其签名。

谈到IID ...如果您以前从未与他们合作过,这就是其中之一的样子:

$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/dynamic/instance-identity/document
{
  "accountId" : "8072125551212",
  "architecture" : "x86_64",
  "availabilityZone" : "us-east-2c",
  "billingProducts" : null,
  "devpayProductCodes" : null,
  "marketplaceProductCodes" : null,
  "imageId" : "ami-0fc20dd1da406780b",
  "instanceId" : "i-01bd292377d6d8fec",
  "instanceType" : "t2.micro",
  "kernelId" : null,
  "pendingTime" : "2020-03-11T23:18:12Z",
  "privateIp" : "172.31.46.150",
  "ramdiskId" : null,
  "region" : "us-east-2",
  "version" : "2017-09-30"
}

此JSON段由Amazon签名,签名如下所示:

$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
    && curl -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/dynamic/instance-identity/signature
c0p6ygyFNFxyjs/73QGCQN+7khkZBr6H5cP/gefBgAwe80GmSTNlQy68LBSQQYrQczv2aHTXj3xa
CFkaGE4GPYiAogCkywcnt5VAp3t176GQwVxqfmawTliPMs31dY7ZeZvixN/1uoe8x1pt0EXAMPLE

使用您的PEM密钥登录并验证一切是否正确启动。用户数据脚本的结果应为/var/log/cloud-init-output.log

在主机上创建用户


您创建的新用户的登录必须与您登录Google所使用的邮件名称相同,例如:

$ sudo adduser --quiet --disabled-password --gecos '' carl

至此,我们在主机端完成了配置!

4.开设新帐户


让我们设置您的第一个用户帐户。在本地设备上运行以下命令:

$ CA_URL=https://[YOUR CA].compute.amazonaws.com
$ CA_FINGERPRINT=[CA FINGERPRINT]
$ step ca bootstrap \
       --ca-url $CA_URL \
       --fingerprint $CA_FINGERPRINT

此命令将在您的设备上安装和配置根CA证书。您将拥有两个新文件:(~/.step/config/defaults.json配置文件step)和~/.step/certs/root_ca.crt(您的根CA的TSL证书)。

之后,我们可以为自己颁发用户证书:

$ step ssh login [your email address] --provisioner "Google"

这个团队做什么?

  1. 启动系统浏览器并启动Google OICD授权过程。
  2. 授权后,将从Google收到的令牌发送到您的CA。
  3. 您的CA会确认令牌并颁发与您的邮件相对应的SSH证书。
  4. 证书已添加到您的SSH代理中。要查看它,请使用它step ssh list,然后对其进行分析和研究step ssh list --raw | step ssh inspect

最后,让我们配置SSH以使用我们的CA:

$ step ssh config

该命令执行以下操作:

  1. 首先,她检索CA主机的公共密钥(用于验证主机证书),并将此密钥安装在SSH配置中,并显示以下结果(存储在中~/.step/known_hosts):

    @cert-authority * ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHyWTo9TLDwhyLlHq2ANkjtSGLyJ3xPtfL+7faiV+YA0k4kLUc8cJ5rWFHdUShbwtkOsLhkqeDDXoFnH/C5BG+4=
  2. 然后,将.step/ssh/config这个不显眼的块导入到您的SSH配置(c )中:

    Match exec "step ssh check-host %h"
    		ForwardAgent yes
    		User carl
    		UserKnownHostsFile "/Users/carl/.step/ssh/known_hosts"
    		ProxyCommand step ssh proxycommand %r %h %p --provisioner "Google"

Match exec仅当以上命令返回true时,才考虑

该命令联系您的CA,并询问您尝试通过SSH连接的主机名是否具有适当的证书。如果是,则命令返回true。我们不希望CA托管的主机干扰您sconfig中的任何其他主机。

该指令ProxyCommand实现了单点登录过程的所有魔力。在启动连接之前,它将step ssh proxycommand验证您的SSH证书,如果它丢失或过期,它将引导您完成OAuth OIDC流程并从您的CA请求新证书。

注意: CA的配置块由模板确定,该模板存储在<代码> / etc / step-ca / templates / ssh中,如果要更改某些内容(例如,删除指令)ForwardAgent,则只需引用此模板即可。

是时候尝试了!


我们准备通过SSH连接到您配置的主机。您可以使用命令运行SSH -v来观察握手。特别是,您应该看到以下内容:

debug1: Server host certificate: ecdsa-sha2-nistp256-cert-v01@openssh.com SHA256:KUwZbRewusotBbO4Wbrj1EpPexMqKEj0ZUr1Fvf41+g, serial 782
1790606781444805 ID "i-0fa7218db55ac0536" CA ecdsa-sha2-nistp256 SHA256:VIwnVtTJJwdUsjGaPyOS5yT1O/uxyxj0CQJd+Ce/w0M valid from 2020-03-2
3T16:23:32 to 2020-04-22T16:24:32
debug1: Host 'ec2-3-135-235-172.us-east-2.compute.amazonaws.com' is known and matches the ECDSA-CERT host certificate.
debug1: Found CA key in /Users/carl/.step/ssh/known_hosts:1
...
debug1: Offering public key: carl@smallstep.com ECDSA-CERT SHA256:mBQXA0znZvd+21hhvViUVEybzrO4x190xZftFXAYCFY agent
debug1: Server accepts key: carl@smallstep.com ECDSA-CERT SHA256:mBQXA0znZvd+21hhvViUVEybzrO4x190xZftFXAYCFY agent

瞧!你做到了。

提示:您可以要求CA通过命令列出已向其颁发证书的所有主机的列表step ssh hosts

问答环节


如何在CA中注册现有主机?


对于Ubuntu 18.04 LTS主机,此过程类似于加载新主机,只需在root下运行主机启动脚本。对于其他平台,您将需要根据需要移植脚本。

启动并配置所有主机后,您可能需要调整instanceAgeCA的AWS提供程序设置。这些设置存储在中/etc/step-ca/config/ca.json。任何年龄的实例默认情况下都可以运行。将设置设置为例如将设置为5m,这将产生附加的预防措施,有效地迫使CA仅接受小于五分钟的实例的IID令牌。

笔记:实例身份脚本创建的令牌是一次性令牌。您不能重新注册主机;只能更新其证书。为什么?因为主机上的任何用户都可以随时访问IID,所以我们不希望用户能够从CA获取主机证书。

我可以使用其他OAuth OIDC提供程序吗?


当然!为此,只需更改OAuth配置服务器的网络地址并在CA的用户数据脚本中更改OIDC提供程序的名称。

我可以使用GCP或Azure代替AWS吗?


是! step-ca三个都有提供程序,您只需更改CA配置和主机启动脚本。您可以在供应商文档中 阅读有关此内容的更多信息step-ca

我可以使用主机堡垒(安装服务器)吗?


您可以。首先,向所有主机颁发证书,然后将known_hosts主机密钥添加到您的CA堡垒中:

$ CA_URL=https://[YOUR CA].compute.amazonaws.com
$ CA_FINGERPRINT=[CA FINGERPRINT]
$ step ca bootstrap \
      --ca-url $CA_URL \
      --fingerprint $CA_FINGERPRINT
$ mkdir -p ~/.ssh && echo "@cert-authority * $(step ssh config --host --roots)" > ~/.ssh/known_hosts

之后,ssh对堡垒而言再ssh对内部主机而言就足够

我可以更改SSH证书的到期日期吗?


是。默认情况下,它们的有效期为16小时,并且在OIDC提供程序ca.json的object下的CA(配置文件中claims,您可以在相应的行中进行更改,例如:

"defaultUserSSHCertDuration": "720h",
"maxUserSSHCertDuration": "720h"

断开CA的连接后,我会与所有主机断开连接吗?


您将,尽管SSH和SHHD不会直接与CA交互。CA颁发证书并维护主机数据库。您的用户依靠此基础来确定您是否应该尝试通过证书身份验证连接到主机。

为了系统安全,请勿使用SSH证书直接连接到CA:这是您应继续使用密钥对的唯一位置。

我可以在多个AWS账户上使用主机吗?


当然。为此,只需将帐户ID添加到CA(/etc/step-ca/config/ca.json配置文件中,然后重新启动CA服务器。

如何添加支持sudo


使用代理转发和身份验证插件 pam_ussh

我的CA还可以做什么?


许多!有了个人CA之后,您就可以配置TSL证书,以通过共享TLS加密所有内部流量如果您想了解有关CA,供应商,配置选项等的更多信息,请阅读“ 步骤证书文档”

总结


通过我们的基本设置,您Google组织的任何用户都可以获取证书。他还将仅访问其拥有帐户的那些主机。

All Articles