31

I've been testing and experimenting a bit to find out how exactly to upload SSL Certificates to AWS's Elastic Load Balancer (figuring out issues with different key and certificate encodings).

Therefore I have quite a few test certificates on there that I've generated with either the wrong information, missing certificate chains or just bogus data.

As far as I can see there is no way to delete these certificates, or even update/replace the ones that are missing certain information. AWS's instructions to "updating a certificate" (http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/DeveloperGuide/US_UpdatingLoadBalancerSSL.html) actually just shows you how to change the load balancer listener to use a different certificate that is either already on there or that you can then upload as well! (that's exactly how I ended up with so many certificates on there in the first place).

Could someone please tell me that I'm wrong and there is a way to delete them? :D (and preferably also how to do that)

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Svend Hansen
  • 3,277
  • 3
  • 31
  • 50
  • This is offtopic here. Probably belongs to http://superuser.com/ – Eugene Mayevski 'Callback Jun 01 '12 at 16:15
  • 1
    While I can see why that would be (not directly a programming issue) I think quite a lot of people working with AWS would be more likely to look for it here (or be able to answer it here). Though I might be wrong in that assumption. Would it be possible to move it sideways? – Svend Hansen Jun 06 '12 at 08:18
  • The accepted answer is no longer the correct answer. This is the problem with these types of questions. I've never had an issue removing unused cert's. Provided they are not assigned to an existing ELB they just delete fine. Maybe there was a time when it wasn't so reliable but as of 2016 it works perfectly. – hookenz Mar 10 '16 at 21:41
  • Thanks for the update, Matt. I'm glad there's been some progress since I worked with AWS :) I'll still leave the accepted answer, as it solved the issue I had at the time. But yes, not all questions age well :) – Svend Hansen Mar 11 '16 at 07:32

8 Answers8

42

You can delete the ELB associated certificate by using the following command

 aws iam delete-server-certificate --server-certificate-name certificate_object_name

There is a limit on the number of these certificates you can have [10].

Rahul
  • 1,549
  • 3
  • 17
  • 35
  • 1
    This worked without a hitch, glad to finally get rid of those old certificates. Especially useful in the aftermath of heartbleed! – moodh Apr 09 '14 at 17:27
  • 4
    I found which certs I needed to get rid of with `aws iam list-server-certificates`, thought I would share! – jmreicha Jan 31 '15 at 02:04
  • Worked for me. When the aws UI doesn't expose functionality, it's worth looking at what the aws command line tools can do. > There is a limit on the number of these certificates you can have [10]. This limit might have been updated since. We have a limit of 20. But we are also using a VPC so maybe our limits are different. – apotek Jul 24 '15 at 16:36
  • http://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html – hookenz Mar 10 '16 at 21:42
  • Update in April 2023: the max number of certificates you can have in a load balancer is now 40. Also, the command line user must have one of the IAM permissions to list or delete certificates (for example: IAMFullAccess). – Russell G Apr 09 '23 at 11:17
13

Edit: Seven years later the commands have changed a bit:

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

You can get the certificate name using:

aws iam list-server-certificates


You can use the command line tool iam-servercertdel to do this. You'll need to get the path first though:

iam-servercertlistbypath

Once you have that, you can delete it:

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

However chantheman is correct in that AWS services can be flaky sometimes, so recreating the ELB is sometimes better.

seren
  • 306
  • 2
  • 12
  • 1
    I tried running it as above and got the error "No argument is allowed". I added a '-s' before the long string, but it then complained about non-alpha-numerics. However, running it as just: `iam-servercertdel -s my-company-cert` worked except that, as @chantheman describes, the certificate still exists with the ELB. – Svend Hansen Jun 06 '12 at 08:38
  • 2
    I just used the name itself (my-company-cert) with `s`. Worked for me. – SamV Mar 27 '14 at 21:01
7

This is not possible. You have to delete the ELB and make a new one.

See: https://forums.aws.amazon.com/thread.jspa?threadID=57632

It is possible to remove them from the IAM but they do not always remove correctly from the ELB, and the ELB can continue to use an old one. I would definitely say the safest way is to create a new ELB and delete the old one

chantheman
  • 5,256
  • 4
  • 23
  • 34
  • 1
    I've +1'ed all three answers, but this one is the one that I've gone with as it's the deleting the ELB that has now finally made the extra certificates go away. Wasn't that difficult to do, but not obvious that it would work :) – Svend Hansen Jun 06 '12 at 08:43
  • It's actually possible to change them on the ELB now.... but still not possible to delete them all together. – chantheman Oct 23 '12 at 16:06
  • 2
    wouldn't creating a new ELB result in a new ELB domain and hence breaking all the CNAME mappings? – thanikkal Nov 05 '12 at 01:25
  • There are other answers that do not require the load balancer to be deleted. See mine and the one from @SDillard. – Scott Munro Mar 13 '13 at 06:18
  • I'm in the same situation. When you delete the ELB and create a new one, is it simple to associate the new load balancer with your Beanstalk environment "after the fact"? – Brian FitzGerald Mar 22 '16 at 04:38
6

Issue the following command using the amazon API tools:

iam-servercertdel -s SERVERCERTNAME
Martijn Burger
  • 7,315
  • 8
  • 54
  • 94
5

It is not possible through the Amazon console, but through API calls. http://docs.amazonwebservices.com/IAM/latest/APIReference/API_DeleteServerCertificate.html You may not have noticed this because they are under IAM, not EC2.

Brandon Nicoll
  • 434
  • 2
  • 10
  • It is possible to remove them from the IAM but they do not always remove correctly from the ELB, and the ELB can continue to use an old one. I would definitely say the safest way is to create a new ELB and delete the old one. – chantheman Jun 04 '12 at 20:11
  • This _did_ work for removing the certificate from IAM, but not from the ELB as @chantheman points out. – Svend Hansen Jun 06 '12 at 08:41
  • Certificates are on the listener level, not the ELB level. Removing the certificate and listeners could have prevented deleting the entire load balancer. – Brandon Nicoll Jun 07 '12 at 13:48
  • +1 BNicoll's recommendation here to replace the listeners worked like a charm. – Guerry Apr 10 '14 at 17:47
3

Your first step should be to stop using the certificate in the load balancer. Either swap all listeners to another certificate or don't use a certificate at all. @SDillard recommended in his answer that you should wait a few minutes before continuing on to delete the certificate.

You can delete a certificate using the following command in the AWS Powershell console (see the other answers for details of how to do this using other tools). Install the AWS SDK for .Net to get the console.

Remove-IAMServerCertificate <CertificateName>

Note that the <CertificateName> should not be the full resource identifier which looks like the following. The certificate name is the last segment.

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

To get a list of all certificates, you can use the following command.

Get-IAMServerCertificates

Now when you return to the SSL certificate configuration for the listeners in the load balancer (within the AWS Management Console), you should no longer see the certificate that you deleted in the drop down box.

If for some reason, this does not work then you could also try recreating the load balancer (delete the existing one and create a new one). Be aware though, that this will probably mean that you need to make some changes related to DNS as the new load balancer will have different DNS names. Your CName records will probably need to be changed.

Update: It looks as though there have been some changes to the API since I first posted this answer. I was just able to remove a certificate that was currently being used by a listener. Although in the listener, certificate column it said 'Invalid Certificate' the old certificate continued to be returned when I browsed to the site - not sure if this was just a temporary thing.

Scott Munro
  • 13,369
  • 3
  • 74
  • 80
  • It doesn't seem possible (via boto at least). - you can add a new certificate to the listener, but not as the default - you cannot delete the existing "default" certificate while it is the default - you cannot modify which certificate is the default - an SSL listener may not have no certificates (you can't delete all the certificates and add a new default one). – user48956 Feb 18 '20 at 00:09
2

If the certificate is not used on an ELB, use the IAM tools as mentioned in other answers. If it is, then you shouldn't delete it from IAM, but instead should set the new, correct one for the ELB then delete the unused certificate(s) using the IAM tools. I would also recommend waiting a few minutes after you change the certificate before you delete the old one, as it can take a little time for the correct certificate to propagate; simply do a dig on the ELB DNS name and hit each IP address to make sure it is returning the new certificate to be sure.

Also, the latest version of the AWS Console does support updating the certificate on an existing load balancer, but you still have to use the IAM tools to delete unneeded certificates.

SDillard
  • 21
  • 1
  • I think this was what I did the first time, but then the certificates didn't disappear until I had deleted and re-created the ELB. Not sure if that was because I didn't wait long enough before running the IAM delete, but I don't think so, as some of the certificates hadn't been assigned to an ELB for a while when I ran the delete... – Svend Hansen Jun 11 '12 at 09:24
0

As far as I can tell (at least with Boto3)

  • you can add a new certificate to the listener, but not as the default certificate (the isDefault attribute is rejected)
  • you cannot delete the existing "default" certificate while it is the default
  • you cannot modify which certificate is the default
  • an SSL listener may not have no certificates (you can't delete all the certificates and add a new default one).

Therefore, the only option left is either to delete the loadbalancer or delete the listener (what the hey!). Because the listener may be attached to a lot of routing information, this is a PITA. So, what I recommend is:

  • upload the certificate
  • retrieve the state of the listeners referencing the old SSL
  • make a note of their rules
  • delete those listeners
  • recreate them with just their CertificateArn changed (an pointing to your new certificate.

Something like this:

   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")

Its not ideal, since if anything goes wrong then there's downtime. Though I think this is the best with the tools Amazon provided.

user48956
  • 14,850
  • 19
  • 93
  • 154