从弹性负载均衡器中删除上传的证书

31

我一直在测试和尝试,找出如何将 SSL 证书上传到 AWS 的弹性负载均衡器(解决不同密钥和证书编码的问题)。

因此,我有很多测试证书,其中包括使用错误信息、缺少证书链或虚假数据生成的证书。

据我所见,没有办法删除这些证书,甚至更新/替换缺少某些信息的证书。AWS 的“更新证书”说明 (http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/DeveloperGuide/US_UpdatingLoadBalancerSSL.html) 实际上只是告诉你如何更改负载均衡器侦听器以使用已经存在或者您可以上传的另一个证书!(这正是我最初为什么要在那里添加这么多证书的原因)。

可以有人告诉我我错了,并且有一种方法可以删除它们吗? :D (最好还能告诉我如何操作)


这个话题与本站无关,可能应该发布在http://superuser.com/。 - Eugene Mayevski 'Callback
1
虽然我能理解这可能不是一个直接的编程问题,但我认为很多使用AWS的人更倾向于在这里寻找答案(或者能够在这里回答)。尽管我的假设可能是错误的。是否可能将其转移到其他地方? - Svend Hansen
被接受的答案已经不再是正确的答案了。这就是这些类型问题的问题所在。我从来没有遇到过删除未使用证书的问题。只要它们没有分配给现有的ELB,它们就可以很好地被删除。也许曾经有一段时间它不是那么可靠,但截至2016年,它完美地工作着。 - hookenz
感谢更新,马特。很高兴自从我使用AWS以来已经取得了一些进展 :) 我仍然会保留已接受的答案,因为它解决了我当时遇到的问题。但是,确实不是所有问题都能经久不衰 :) - Svend Hansen
8个回答

42
你可以使用以下命令删除与ELB关联的证书。
 aws iam delete-server-certificate --server-certificate-name certificate_object_name

你可以拥有这些证书的数量是有限制的[10]。


1
这个运行得非常顺利,很高兴终于摆脱了那些旧证书。在心脏出血事件后尤其有用! - moodh
4
我找到了使用 aws iam list-server-certificates 命令获取不需要的证书清单,想和大家分享! - jmreicha
对我有用。当 AWS UI 没有暴露功能时,值得看看 AWS 命令行工具能做什么。
这些证书的数量有限制 [10]。
此限制可能已更新。 我们的限制是 20。但是我们还使用了 VPC,因此可能我们的限制不同。
- apotek
http://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html - hookenz
2023年4月更新:负载均衡器中证书的最大数量现在为40。此外,命令行用户必须拥有IAM权限之一才能列出或删除证书(例如:IAMFullAccess)。 - Russell G

13

编辑:七年后,命令有点变化:

aws iam delete-server-certificate --server-certificate-name <cert-name>

您可以使用以下命令获取证书名称:

aws iam list-server-certificates


您可以使用命令行工具iam-servercertdel来完成此操作。不过,首先需要获取路径:

iam-servercertlistbypath

一旦您拥有它,您可以将其删除:

iam-servercertdel arn:aws:iam::10494620000:server-certificate/my-company-cert

但是 chantheman 是正确的,AWS 服务有时会出现问题,因此重新创建 ELB 有时更好。


1
我尝试按照上述方式运行它,但出现了“不允许使用参数”的错误。我在长字符串前添加了“-s”,但它抱怨有非字母数字字符。然而,仅运行以下命令: iam-servercertdel -s my-company-cert 可以正常工作,只是像@chantheman所描述的那样,证书仍然存在于ELB中。 - Svend Hansen
2
我只是使用了名称本身(my-company-cert)加上s。对我有效。 - SamV

7
这是不可能的。您必须删除ELB并创建一个新的。
参见: https://forums.aws.amazon.com/thread.jspa?threadID=57632 虽然从IAM中删除它们是可能的,但它们并不总是能够正确地从ELB中移除,并且ELB可能会继续使用旧的。我肯定会建议最安全的方式是创建一个新的ELB并删除旧的。

1
我已经给了三个答案+1,但这个是我选择的,因为删除ELB最终使额外的证书消失了。这并不难做,但并不明显它会起作用 :) - Svend Hansen
现在可以在ELB上更改它们... 但仍然不可能完全删除它们。 - chantheman
2
创建一个新的ELB不会导致一个新的ELB域名,从而破坏所有CNAME映射吗? - thanikkal
还有其他答案不需要删除负载均衡器。请查看我的和@SDillard的答案。 - Scott Munro
我处于同样的情况。当您删除 ELB 并创建一个新的时,是否可以简单地在事后将新的负载均衡器与您的 Beanstalk 环境相关联? - Brian FitzGerald

6

使用亚马逊API工具发出以下命令:

iam-servercertdel -s SERVERCERTNAME

5

可以从 IAM 中将它们移除,但它们并不总是能够正确地从 ELB 中移除,ELB 可能会继续使用旧的。我肯定会说最安全的方法是创建一个新的 ELB 并删除旧的。 - chantheman
这确实可以用于从IAM中删除证书,但正如@chantheman所指出的那样,无法从ELB中删除证书。 - Svend Hansen
证书位于监听器级别,而不是 ELB 级别。移除证书和监听器可以防止删除整个负载均衡器。 - Brandon Nicoll
BNicoll的建议在这里替换监听器非常有效。 - Guerry

3
您的第一步应该是停止在负载均衡器中使用证书。要么将所有侦听器替换为另一个证书,要么根本不使用证书。@SDillard建议您在继续删除证书之前等待几分钟。
您可以使用以下命令在AWS Powershell控制台中删除证书(有关如何使用其他工具执行此操作的详细信息,请参见其他答案)。安装AWS SDK for .Net以获取控制台。
Remove-IAMServerCertificate <CertificateName>

请注意,<CertificateName> 不应该是完整的资源标识符,它看起来像以下内容。证书名称是最后一段。

arn:aws:iam::297826370175:server-certificate/

要获取所有证书的列表,可以使用以下命令。
Get-IAMServerCertificates

现在,当您返回负载均衡器中监听器的SSL证书配置(在AWS管理控制台中)时,您应该不再在下拉框中看到已删除的证书。
如果由于某种原因这不起作用,那么您还可以尝试重新创建负载均衡器(删除现有负载均衡器并创建新的负载均衡器)。但是请注意,这可能意味着您需要进行一些与DNS相关的更改,因为新的负载均衡器将具有不同的DNS名称。 您的CName记录可能需要更改。
更新:自从我最初发布这个答案以来,API似乎发生了一些变化。我刚刚能够删除当前由监听器使用的证书。虽然在监听器中,证书列显示“无效证书”,但旧证书在我浏览网站时继续返回 - 不确定这是否只是暂时的事情。

似乎不可能(至少通过boto)。
  • 您可以向侦听器添加新证书,但不能将其设置为默认值。
  • 当现有的“默认”证书是默认值时,您无法删除它。
  • 您无法修改哪个证书是默认值。
  • SSL侦听器可能没有证书(您无法删除所有证书并添加新的默认证书)。
- user48956

2
如果证书未在ELB上使用,则使用其他答案中提到的IAM工具。 如果它被使用,则不应从IAM中删除它,而应为ELB设置新的正确证书,然后使用IAM工具删除未使用的证书。 在您更改证书后建议等待几分钟再删除旧证书,因为正确证书需要一些时间传播;只需对ELB DNS名称进行dig并访问每个IP地址以确保返回新证书即可。
此外,AWS控制台的最新版本支持更新现有负载均衡器上的证书,但仍需要使用IAM工具删除不必要的证书。

我想这是我第一次做的事情,但是证书直到我删除并重新创建ELB后才消失。不确定是否因为在运行IAM删除之前等待的时间不够长,但我认为不是这样,因为当我运行删除时,有些证书已经很长时间没有分配给ELB了... - Svend Hansen

0

据我所知(至少在Boto3中)

  • 您可以向侦听器添加新证书,但不能将其作为默认证书(isDefault属性会被拒绝)
  • 在默认证书仍然是默认证书时,您无法删除现有的“默认”证书
  • 您无法修改哪个证书是默认证书
  • SSL侦听器可能没有证书(您无法删除所有证书并添加一个新的默认证书)。

因此,唯一剩下的选择是删除负载均衡器或删除侦听器(这是什么鬼!)。由于侦听器可能附加到大量路由信息,这很麻烦。因此,我建议:

  • 上传证书
  • 检索引用旧SSL的侦听器的状态
  • 记录它们的规则
  • 删除那些侦听器
  • 重新创建它们,只更改它们的CertificateArn(指向您的新证书)。

类似于这样:

   import boto3

   def fixRule(rule): 
            """Copy a rule so that it can be submitted as a new rule"""
            rule = rule.copy()
            if rule["IsDefault"]:
                # The default rule is set at create_listener
                return None

            def fix_condition(c):
                c = c.copy()
                del c["Values"]
                return c
            rule["Conditions"] = [fix_condition(c) for c in rule.get("Conditions",())]
            # del rule["Priority"]
            del rule["RuleArn"]
            del rule["IsDefault"]
            # rule["Priority"] = rule["Priority"]
            try:
                rule["Priority"] = int(rule["Priority"])
            except:
                del rule["Priority"]
            return rule


   acmClient = session.client('acm')
   response = acmClient.import_certificate(
                Certificate=certificate,
                PrivateKey=privatekey,
                CertificateChain=chain
            )
   current_ssl_arn = response[ 'CertificateArn']

   session.client('resourcegroupstaggingapi').tag_resources(
                ResourceARNList=[
                    current_ssl_arn
                ],
                Tags={ ... whaterver }
                }
            )

   # Replace each SSL listener with one that has a new certificate.
   lbClient = session.client('elbv2')
   listeners = lbClient.describe_listeners(LoadBalancerArn=self.lb_arn["Listeners"]


   # Make existing listeners use the certificate
   # Delete exisiting listeners with SSL certificates
   # Create a new one with the same parameters and rules as the old one.
   for l in listeners:
            oldListenerArn = l["ListenerArn"]

            # Only deal with SSL listeners
            if l.get("SslPolicy")==None: continue

            _listener_certs = l.get("Certificates",())
            _listener_cert_arns = set(c['CertificateArn'] for c in _listener_certs)

            # Great! already up-to-date
            if current_ssl_arn in _listener_cert_arns: continue


            # Backup the rules
            oldRules = lbClient.describe_rules(ListenerArn=oldListenerArn)['Rules']

            # Recreate the listener with the new certificate
            print("Replacing listener")
            _ = lbClient.delete_listener(ListenerArn = oldListenerArn)

            l = l.copy()
            del l["ListenerArn"]
            l["Certificates"] = [{"CertificateArn":current_ssl_arn}]
            newListener = lbClient.create_listener(**l)["Listeners"][0]
            newListenerArn = newListener["ListenerArn"]

            print("Replacing listener .. copying ({}) rules ".format(len(oldRules)))
            for rule in oldRules:
                rule = fixRule(rule)
                if rule is None: continue
                _ = lbClient.create_rule(
                    ListenerArn=newListenerArn,
                    **rule)
            print("Replacing listener .. OK")

这不是理想的,因为如果出现任何问题,就会有停机时间。但我认为这是使用亚马逊提供的工具最好的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接