Giter Club home page Giter Club logo

letsencrypt-aws's Introduction

letsencrypt-aws

Note: letsencrypt-aws is not well maintained at this point. You may prefer to use other Let's Encrypt automation solutions, or Amazon's Certificate Manager.

letsencrypt-aws is a program that can be run in the background which automatically provisions and updates certificates on your AWS infrastructure using the AWS APIs and Let's Encrypt.

How it works

letsencrypt-aws takes a list of ELBs, and which hosts you want them to be able to serve. It runs in a loop and every day does the following:

It gets the certificate for that ELB. If the certificate is going to expire soon (in less than 45 days), it generates a new private key and CSR and sends a request to Let's Encrypt. It takes the DNS challenge and creates a record in Route53 for that challenge. This completes the Let's Encrypt challenge and we receive a certificate. It uploads the new certificate and private key to IAM and updates your ELB to use the certificate.

In theory all you need to do is make sure this is running somewhere, and your ELBs' certificates will be kept minty fresh.

How to run it

Before you can use letsencrypt-aws you need to have created an account with the ACME server (you only need to do this the first time). You can register using (if you already have an account you can skip this step):

$ # If you're trying to register for a server besides the Let's Encrypt
$ # production one, see the configuration documentation below.
$ python letsencrypt-aws.py register [email protected]
2016-01-09 19:56:19 [acme-register.generate-key]
2016-01-09 19:56:20 [acme-register.register] email=u'[email protected]'
2016-01-09 19:56:21 [acme-register.agree-to-tos]
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----

You'll need to put the private key somewhere that letsencrypt-aws can access it (either on the local filesystem or in S3).

You will also need to have your AWS credentials configured. You can use any of the mechanisms documented by boto3, or use IAM instance profiles (which are supported, but not mentioned by the boto3 documentation). See below for which AWS permissions are required.

letsencrypt-aws takes it's configuration via the LETSENCRYPT_AWS_CONFIG environment variable. This should be a JSON object with the following schema:

{
    "domains": [
        {
            "elb": {
                "name": "ELB name (string)",
                "port": "optional, defaults to 443 (integer)"
            },
            "hosts": ["list of hosts you want on the certificate (strings)"],
            "key_type": "rsa or ecdsa, optional, defaults to rsa (string)"
        }
    ],
    "acme_account_key": "location of the account private key (string)",
    "acme_directory_url": "optional, defaults to Let's Encrypt production (string)"
}

The acme_account_key can either be located on the local filesystem or in S3. To specify a local file you provide "file:///path/to/key.pem" (on Windows use "file://C:/path/to/key.pem"), for S3 provide "s3://bucket-name/object-name". The key should be a PEM formatted RSA private key.

Then you can simply run it: python letsencrypt-aws.py update-certificates.

If you add the --persistent flag it will run forever, rather than just once, sleeping for 24 hours between each check for certificate expiration. This is useful for production environments.

If your certificate is not expiring soon, but you need to issue a new one anyways, the --force-issue flag can be provided.

If you're into Docker, there is an automatically built image of letsencrypt-aws available as alexgaynor/letsencrypt-aws.

Operational Security

Keeping the source of your certificates secure is, for obvious reasons, important. letsencrypt-aws relies heavily on the AWS APIs to do its business, so we recommend running this code from EC2, so that you can use the Metadata service for managing credentials. You can give your EC2 instance an IAM instance profile with permissions to manage the relevant services (see below for complete details).

You need to make sure that the ACME account private key is kept secure. The best choice is probably in an S3 bucket with encryption enabled and access limited with IAM.

Finally, wherever you're running letsencrypt-aws needs to be trusted. letsencrypt-aws generates private keys in memory and uploads them to IAM immediately, they are never stored on disk.

IAM Policy

The minimum set of permissions needed for letsencrypt-aws to work is:

  • route53:ChangeResourceRecordSets
  • route53:GetChange
  • route53:ListHostedZones
  • elasticloadbalancing:DescribeLoadBalancers
  • elasticloadbalancing:SetLoadBalancerListenerSSLCertificate
  • iam:ListServerCertificates
  • iam:UploadServerCertificate
  • iam:GetServerCertificate

If your acme_account_key is provided as an s3:// URI you will also need:

  • s3:GetObject

It's likely possible to restrict these permissions by ARN, though this has not been fully explored.

An example IAM policy is:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "route53:ChangeResourceRecordSets",
                "route53:GetChange",
                "route53:GetChangeDetails",
                "route53:ListHostedZones"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:SetLoadBalancerListenerSSLCertificate"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "iam:ListServerCertificates",
                "iam:GetServerCertificate",
                "iam:UploadServerCertificate"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

letsencrypt-aws's People

Contributors

adamchainz avatar alex avatar danni avatar dlamotte avatar keichan34 avatar moeterich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

letsencrypt-aws's Issues

update-certificates returns AttributeError: 'NoneType'

I am running the script from an EC2 instance in the same vpc as my EB/ELB
Here is what it returns

python letsencrypt-aws.py update-certificates
2016-03-22 14:24:48 [startup] 
2016-03-22 14:24:48 [running] mode='single'
2016-03-22 14:24:48 [updating-elb] elb_name=u'awseb-e-XXX'
2016-03-22 14:24:49 [updating-elb.certificate-expiration] expiration_date=datetime.date(2016, 5, 5) elb_name=u'awseb-e-XXX'
2016-03-22 14:24:49 [updating-elb.request-acme-challenge] host=u'example.com' elb_name=u'awseb-e-XXX'
2016-03-22 14:24:50 [updating-elb.create-txt-record] host=u'example.com' elb_name=u'awseb-e-XXX'
Traceback (most recent call last):
  File "letsencrypt-aws.py", line 523, in <module>
    cli()
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 486, in update_certificates
    force_issue, certificate_requests
  File "letsencrypt-aws.py", line 384, in update_elbs
    cert_request,
  File "letsencrypt-aws.py", line 344, in update_elb
    cert_request.cert_location.elb_name, host,
  File "letsencrypt-aws.py", line 252, in start_dns_challenge
    dns_challenge.validation(acme_client.key),
  File "letsencrypt-aws.py", line 161, in create_txt_record
    value,
  File "letsencrypt-aws.py", line 146, in _change_txt_record
    {"Value": '"{}"'.format(value)}
  File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 228, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 468, in _make_api_call
    api_params, operation_model, context=request_context)
  File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 518, in _convert_to_request_dict
    params=api_params, model=operation_model, context=context)
  File "/usr/local/lib/python2.7/site-packages/botocore/hooks.py", line 226, in emit
    return self._emit(event_name, kwargs)
  File "/usr/local/lib/python2.7/site-packages/botocore/hooks.py", line 209, in _emit
    response = handler(**kwargs)
  File "/usr/local/lib/python2.7/site-packages/botocore/handlers.py", line 469, in fix_route53_ids
    params[name] = orig_value.split('/')[-1]
AttributeError: 'NoneType' object has no attribute 'split'

It correctly identifies my elb and certificate (this is the right expiration date), but then fails.
So I sudo-modified /usr/local/lib/python2.7/site-packages/botocore/handlers.py to print the inputs for the function fix_route53_ids and got :

params fix_route53 
{}
model 
<botocore.model.OperationModel object at 0x7f7a65c04390>
args 
{'event_name': 'before-parameter-build.route53.ListHostedZones', 'context': {}}
params fix_route53 
{'HostedZoneId': None, 'ChangeBatch': {'Changes': [{'Action': 'CREATE', 'ResourceRecordSet': {'ResourceRecords': [{'Value': '"mX7cXXX"'}], 'Type': 'TXT', 'Name': '_acme-challenge.example.com', 'TTL': 30}}]}}
model 
<botocore.model.OperationModel object at 0x7f7a65bf8210>
args 
{'event_name': 'before-parameter-build.route53.ChangeResourceRecordSets', 'context': {}}

It seems params is empty while it shouldn't be. This is as far as I managed to debug it. Any help would be much appreciated. Thank you!

acme.challenges.DNS01 does not exist

Hi, I'm running into the following issue:

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 521, in <module>
    cli()
  File "/home/ubuntu/le-aws/local/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/home/ubuntu/le-aws/local/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/home/ubuntu/le-aws/local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/ubuntu/le-aws/local/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/ubuntu/le-aws/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 477, in update_certificates
    force_issue, domains
  File "letsencrypt-aws.py", line 383, in update_elbs
    domain.get("key_type", "rsa")
  File "letsencrypt-aws.py", line 335, in update_elb
    logger, acme_client, elb_client, route53_client, elb_name, host
  File "letsencrypt-aws.py", line 199, in start_dns_challenge
    [dns_challenge] = find_dns_challenge(authz)
  File "letsencrypt-aws.py", line 83, in find_dns_challenge
    isinstance(combo[0].chall, acme.challenges.DNS01)
AttributeError: 'module' object has no attribute 'DNS01'

When I print dir(acme.challenges) I get:

['Challenge', 'ChallengeResponse', 'ContinuityChallenge', 'DNS', 'DNSResponse', 'DVChallenge', 'HTTP01', 'HTTP01Response', 'KeyAuthorizationChallenge', 'KeyAuthorizationChallengeResponse', 'OpenSSL', 'ProofOfPossession', 'ProofOfPossessionResponse', 'RecoveryContact', 'RecoveryContactResponse', 'TLSSNI01', 'TLSSNI01Response', 'UnrecognizedChallenge', '_TokenDVChallenge', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'abc', 'crypto_util', 'errors', 'fields', 'functools', 'hashes', 'hashlib', 'jose', 'logger', 'logging', 'other', 'requests', 'socket']

I have run pip install -r requirements.txt
My acme version is: 0.5.0.dev0

Not sure if I'm doing something egregiously wrong, any help would be appreciated. Let me know if you need more information about my configuration.

Using an excrypted key in S3 as suggested by the README results in an error

I followed the instructions as suggested, with my key encrypted using S3 + AWS KMS, but when I try to run the command using that s3:// url, I get an error:

botocore.exceptions.ClientError: An error occurred (InvalidArgument) when calling the GetObject operation: Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.

I did the pip install -r requirements.txt, looks like I ended up with boto3 (1.2.6), which looks like the latest.

Modulus of private key and cert differ, but ELB still works?

Hi,

Many thanks for this lovely bit of software - I've been hacking on it to solve #4 since I have the same use case. I was delighted to be able to spit out the private key and chain cert so I could wrap Puppet around it (I hope to release a Puppet module for it).

At the end of this process, Nginx refused to start, and complained about mismatched keys. After some further digging, I found that the modulus of the private key did not match that of the generated certificate.

I immediately went back to your pristine sources and was able to update an ELB without problem, but again the modulus of the private key and certificate (after downloading it using openssl s_client ..... -showcerts) were different - yet the ELB was able to successfully negotiate a TLS 1.2 connection.

Does any of this sound familiar? I didn't want to paste a torrent of output if there was a simple step that I missed! :)

Cheers,
Gavin.

Multiple ELBs

The README says the following:

letsencrypt-aws takes a list of ELBs, and which hosts you want them to be able to serve

To clarify, can I pass in an array of ELB names as you can with domain names?

ImportError: No module named acme.challenges

I'm not a python user, but seems like everything is fine:

  Installing extra requirements: 'egg,subdirectory'
Requirement already satisfied (use --upgrade to upgrade): boto3>=1.2.3 in /usr/local/lib/python2.7/dist-packages (from -r requirements.txt (line 3))
Requirement already satisfied (use --upgrade to upgrade): click>=6.2 in /usr/local/lib/python2.7/dist-packages (from -r requirements.txt (line 4))
Requirement already satisfied (use --upgrade to upgrade): cryptography>=1.1.2 in /usr/local/lib/python2.7/dist-packages (from -r requirements.txt (line 5))
Requirement already satisfied (use --upgrade to upgrade): pyopenssl>=0.15.1 in /usr/local/lib/python2.7/dist-packages (from -r requirements.txt (line 6))
Requirement already satisfied (use --upgrade to upgrade): rfc3986>=0.3.1 in /usr/local/lib/python2.7/dist-packages (from -r requirements.txt (line 7))
Requirement already satisfied (use --upgrade to upgrade): ndg-httpsclient in /usr/local/lib/python2.7/dist-packages (from acme[dns]->-r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): pyasn1 in /usr/local/lib/python2.7/dist-packages (from acme[dns]->-r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): pyrfc3339 in /usr/local/lib/python2.7/dist-packages (from acme[dns]->-r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): pytz in /usr/lib/python2.7/dist-packages (from acme[dns]->-r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): requests in /usr/lib/python2.7/dist-packages (from acme[dns]->-r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): setuptools>=1.0 in /usr/lib/python2.7/dist-packages (from acme[dns]->-r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): six in /usr/lib/python2.7/dist-packages (from acme[dns]->-r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): mock in /usr/lib/python2.7/dist-packages (from acme[dns]->-r requirements.txt (line 2))
Requirement already satisfied (use --upgrade to upgrade): idna>=2.0 in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.1.2->-r requirements.txt (line 5))
Requirement already satisfied (use --upgrade to upgrade): enum34 in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.1.2->-r requirements.txt (line 5))
Requirement already satisfied (use --upgrade to upgrade): ipaddress in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.1.2->-r requirements.txt (line 5))
Requirement already satisfied (use --upgrade to upgrade): cffi>=1.4.1 in /usr/local/lib/python2.7/dist-packages (from cryptography>=1.1.2->-r requirements.txt (line 5))
Requirement already satisfied (use --upgrade to upgrade): pycparser in /usr/local/lib/python2.7/dist-packages (from cffi>=1.4.1->cryptography>=1.1.2->-r requirements.txt (line 5))
Installing collected packages: acme
  Running setup.py develop for acme

    Creating /usr/local/lib/python2.7/dist-packages/acme.egg-link (link to .)
    acme 0.6.0.dev0 is already the active version in easy-install.pth
    Installing jws script to /usr/local/bin

    Installed /home/ubuntu/letsencrypt-aws/src/acme
Successfully installed acme
Cleaning up...

But I get:

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 7, in <module>
    import acme.challenges
ImportError: No module named acme.challenges

ValueError: No JSON object could be decoded

My LETSENCRYPT_AWS_CONFIG file lives in /home/user/my-le-folder/letsencrypt-aws/LETSENCRYPT_AWS_CONFIG.json. I've exported this environment variable in ~/.profile and manually on the command line within my venv. However, I get this error:

(le-aws) $ python letsencrypt-aws.py update-certificates
2016-02-02 18:54:50 [startup]
Traceback (most recent call last):
  File "letsencrypt-aws.py", line 486, in <module>
    cli()
  File "/home/user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/home/user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/home/user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 425, in update_certificates
    config = json.loads(os.environ["LETSENCRYPT_AWS_CONFIG"])
  File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

Here's my LETSENCRYPT_AWS_CONFIG.json file:

{
    "domains": [
        {
            "elb": {
                "name": "elb-name"
            },
            "hosts": ["ec2-host-name"],
            "key_type": "rsa"
        }
    ],
    "acme_account_key": "/home/user/my-le-folder/le-cert-pem.key"
}

Problem with certificate and pem files

I am struggling to see where this application generates the certificate? I have generated a pem file with the register command, but where do I actually get a certificate from?

cryptography OpenSSL error

Hey guys,
I followed the README instructions and get the following error while executing.
Can somebody help? When I search for the error it seems the problem is related to the country code in the cert. But I can't remember that I have to manual set it for LE? Can somebody have a look?
Thanks a lot in advance!
Sebastian

2016-03-18 02:37:58 [startup] 
2016-03-18 02:37:58 [running] mode='single'
2016-03-18 02:37:58 [updating-elb] elb_name=u'xxxxLB'
2016-03-18 02:37:59 [updating-elb.certificate-expiration] expiration_date=datetime.date(2016, 3, 29) elb_name=u'xxxxLB '
Traceback (most recent call last):
  File "/home/ubuntu/letsencrypt-aws/letsencrypt-aws.py", line 523, in <module>
    cli()
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "/home/ubuntu/letsencrypt-aws/letsencrypt-aws.py", line 486, in update_certificates
    force_issue, certificate_requests
  File "/home/ubuntu/letsencrypt-aws/letsencrypt-aws.py", line 384, in update_elbs
    cert_request,
  File "/home/ubuntu/letsencrypt-aws/letsencrypt-aws.py", line 337, in update_elb
    csr = generate_csr(private_key, cert_request.hosts)
  File "/home/ubuntu/letsencrypt-aws/letsencrypt-aws.py", line 208, in generate_csr
    return csr_builder.sign(private_key, hashes.SHA256(), default_backend())
  File "/usr/local/lib/python2.7/dist-packages/cryptography/x509/base.py", line 354, in sign
    return backend.create_x509_csr(self, private_key, algorithm)
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/backends/multibackend.py", line 372, in create_x509_csr
    return b.create_x509_csr(builder, private_key, algorithm)
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 1325, in create_x509_csr
    x509_req, _encode_name_gc(self, builder._subject_name)
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 158, in _encode_name_gc
    subject = _encode_name(backend, attributes)
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 153, in _encode_name
    backend.openssl_assert(res == 1)
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/backends/openssl/backend.py", line 719, in openssl_assert
    return binding._openssl_assert(self._lib, ok)
  File "/usr/local/lib/python2.7/dist-packages/cryptography/hazmat/bindings/openssl/binding.py", line 43, in _openssl_assert
    errors
cryptography.exceptions.InternalError: Unknown OpenSSL error. Please file an issue at https://github.com/pyca/cryptography/issues with information on how to reproduce this. ([_OpenSSLError(code=218603671L, lib=13, func=122, reason=151)])

Re-using account from certbot client with letsencrypt-aws?

Is it possible to use an acme account created for another certificate request done with the official certbot client? I was looking around for a pem file created by certbot (to be used as private key in place of the one created with letsencrypt-aws as described in the readme) and couldn't find it.

In the end, my question is: is the above possible or should I create an account with the command in the README? If it's possible, any hint on where certbot stores that private key?

Thanks

setup_acme_client issue

I've now got the tool working to the point I can register. However on trying to update certificates I get this stack trace.

(leaws)jenkins@jenkins-np:~/jobs/SSLCertificateUpdate/workspace$ python letsencrypt-aws/letsencrypt-aws.py update-certificates
2016-04-15 03:55:23 [startup] 
Traceback (most recent call last):
  File "letsencrypt-aws/letsencrypt-aws.py", line 533, in <module>
    cli()
  File "/var/lib/jenkins/jobs/SSLCertificateUpdate/workspace/leaws/local/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/var/lib/jenkins/jobs/SSLCertificateUpdate/workspace/leaws/local/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/var/lib/jenkins/jobs/SSLCertificateUpdate/workspace/leaws/local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/var/lib/jenkins/jobs/SSLCertificateUpdate/workspace/leaws/local/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/var/lib/jenkins/jobs/SSLCertificateUpdate/workspace/leaws/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws/letsencrypt-aws.py", line 467, in update_certificates
    s3_client, acme_directory_url, acme_account_key
  File "letsencrypt-aws/letsencrypt-aws.py", line 401, in setup_acme_client
    with open(uri.path) as f:
TypeError: coercing to Unicode: need string or buffer, NoneType found

I've loaded config using the export statement for one ELB certificate.
I've used pip to import aws cli and setup awscli for the user running the script.
AwsCli is using an IAM user with access as specified in the readme.md via a group in IAM.

Any help would be appreciated.

Install Help

I'm a complete python hack having trouble getting this to work, I can see some others having similar trouble in the past, but I haven't found a solution in the issues.

I'm working on a clean ubuntu server precise server.
First up, is python 2.7.6 suitable? Or should I be using Python 3.X? (I've tried both to no avail, and I think I found suggestion that either is fine in the issues).

Using these commands:

$ sudo apt-get install git
$ git clone https://github.com/alex/letsencrypt-aws.git
$ sudo apt-get install python-pip
$ pip install -r requirements.txt

I first hit a permissions issue with pip trying to do things in "/usr/local/lib/python2.7....".
So I assumed that it also required root access (which worked).

$ sudo pip install -r requirements.txt

I then expected to be able to run

$ python letsencrypt-aws.py register [email protected]

This threw this error

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 7, in <module>
    import acme.challenges
ImportError: No module named acme.challenges

Multiple domains?

I currently have an EC2 instance with nginx and I'm running Let's Encrypt every time a new domain is created. Right now we have over 30 domains being hosted. I use the well-known validation currently.

What's the best way to set this up on a new ELB?

From what I've read, I need to create an ELB and create an instance (for example) to run the letsencrypt-aws script. Where do I specify all of the domains I already have certs for?

I'm clearly missing a piece of the puzzle :-) Thanks in advance!

AWS lambda setup?

It seems like this could run from lambda as well as the container service.

Supporting boilerplate for this would be nice to have.

DNS and LB in different accounts

Hi!
I have the requirement to actually have a centralized DNS in one AWS account, and the load balancer in another account.
With the current approach it seems that I can have only one account configured.

Is there a workaround to specify two access keys for DNS and LB separately?

Thanks a lot in advance.
Best Regards,
Sebastian

AttributeError: 'dict' object has no attribute 'iteritems'

Windows 10 x64, Python 3.5.2 x64. I cloned the repo and am trying to run the first command, python letsencrypt-aws.py register [email protected], but I'm getting the error AttributeError: 'dict' object has no attribute 'iteritems'.

Here's the traceback:

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 577, in <module>
    cli()
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 696, in main
    rv = self.invoke(ctx)
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 559, in register
    logger.emit("acme-register.generate-key")
  File "letsencrypt-aws.py", line 38, in emit
    "{}={!r}".format(k, v) for k, v in data.iteritems()
AttributeError: 'dict' object has no attribute 'iteritems'

List requirements in readme

Would be great to know what the requirements are in terms of python and pip, particularly for people who aren't familiar with python. It took me over an hour to figure out the right combination of python and pip versions on Ubuntu 14.04 (I didn't even know pip was a thing when I started).

For anyone else in a similar boat, here are the requirements:

Python 2.7.6 (2.6 and 3.4 didn't work)
Pip 8.1.2 (ubuntu default 1.5.4 didn't work)
Use virtualenv

Here are the commands I ran to get it working:

pip install --upgrade pip # to get 8.1.2 for Ubuntu 14.04 (YMMV)
git clone https://github.com/alex/letsencrypt-aws.git
cd letsencrypt-aws/
virtualenv -p /usr/bin/python2.7 venv
source venv/bin/activate
pip install -r requirements.txt
python letsencrypt-aws.py register [email protected]

ValueError: need more than 0 values to unpack

I ran this command python letsencrypt-aws.py update-certificates
Then I got this error:

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 500, in <module>
    cli()
  File "/Library/Python/2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/Library/Python/2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Library/Python/2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Library/Python/2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 463, in update_certificates
    force_issue, domains
  File "letsencrypt-aws.py", line 362, in update_elbs
    domain.get("key_type", "rsa")
  File "letsencrypt-aws.py", line 285, in update_elb
    elb_client, elb_name, elb_port
  File "letsencrypt-aws.py", line 147, in get_load_balancer_certificate
    if listener["Listener"]["LoadBalancerPort"] == elb_port
ValueError: need more than 0 values to unpack

Any suggestion to fix? Thanks

Self-Registering Private Instances

Hi There!

I stumbled across this project when it was mentioned in the LE dns-01 challenge thread. This looks awesome and very similar to functionality we'd be looking for in our environment. In addition to ELB management, basically we'd want to have our non-externally accessible backend instances self-register with ACME via the dns-01 challenge (so we don't need to manage their SSL certificates via our own CA). Seems like all we'd need is to tell your project that its not for an ELB, but rather the node itself.

Would you be interested in this functionality since you already have most of the legwork? I don't mind writing code or tests to support it if necessary. Thanks!

AWS Lambda?

It would be awesome to be able to run this using AWS Lambda, has anyone tried? Is it possible?

Add --force-issue to the readme

I almost created an issue for instances when a new host is added but then I noticed it was possible to use --force-issue to force an update of the certificate, which is really handy for when a new host is added to the JSON.

Only applicable using Amazon Route 53?

Hi Alex,

We're trying to use your library to add letsencrypt to AWS ELB. It looks like it's only applicable when using Amazon Route 53 as DNS? Is there any way to still use it with a different DNS?

Multiple ports?

Hi there! Is it possible to include support for multiple ports?

i.e. "port": ["443","465","10000"]

Using a separate domain

Just a quick thought: On my side (I manage my own DNS servers) I did a split between the DNS domain the cert is for and the domain the authorizations are in using CNAMEs (so _acme-challenge.www.example.com IN CNAME www.example.com.acme.example.com). This allows me to have static DNS entries for everything except one domain that contains all validations.

This allows me to have different ACLs on the account that can create validations and the account that can actually manage the DNS. And in my case the keys are additionally protected by DANE (so changing the cert by itself would not allow use of arbitrary keys).

Just wondering if route53 can do the same thing (different ACLs for different users managing different domains) and if it's worth it implementing a mapping from the verification name as returned by the API to some other name.

Getting started

OK So i've got it installed locally and registered an email but after that I'm finding the documentation a little unclear. In the documentation it says

letsencrypt-aws takes it's configuration via the LETSENCRYPT_AWS_CONFIG environment variable. This should be a JSON object with the following schema:

but it's not clear where this goes

'acme' package version 0.3.0 broke the script

On my system, I was running into this error:

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 8, in <module>
    import acme.client
  File "/usr/local/lib/python2.7/dist-packages/acme/client.py", line 29, in <module>
    requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3()
AttributeError: 'module' object has no attribute 'packages'

Couldn't figure it out, so I checked the dates on the acme package and saw it was recently updated, downgraded with this set of commands, and now we're working again:

pip uninstall acme
pip install -Iv acme==0.2.0

Just a heads up.

update_elb returns AttributeError: 'NoneType'

I am running letsencrypt-aws from a docker container on an EC2 instance that is in the same VPC, and security group, as my ELB. Here is what it returns:

Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]: Traceback (most recent call last):
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "letsencrypt-aws.py", line 572, in <module>
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]: 2016-06-06 01:36:54 [startup]
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]: 2016-06-06 01:36:55 [running] mode='persistent'
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]: 2016-06-06 01:36:55 [updating-elb] elb_name=u'pigeon-staff-api-development'
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     cli()
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 716, in __call__
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     return self.main(*args, **kwargs)
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 696, in main
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     rv = self.invoke(ctx)
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     return _process_result(sub_ctx.command.invoke(sub_ctx))
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 889, in invoke
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     return ctx.invoke(self.callback, **ctx.params)
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 534, in invoke
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     return callback(*args, **kwargs)
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "letsencrypt-aws.py", line 526, in update_certificates
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     force_issue, certificate_requests
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "letsencrypt-aws.py", line 427, in update_elbs
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     cert_request,
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:   File "letsencrypt-aws.py", line 346, in update_elb
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]:     expiration_date=current_cert.not_valid_after
Jun  6 01:36:55 ip-192-168-0-166 docker/9aca4ed8a3f6[2651]: AttributeError: 'NoneType' object has no attribute 'not_valid_after'

At first, I was using an AWS certificate for port 443 on my target ELB, and I thought that might be the issue but I got the same error message after I removed it. I also looked at issue #38 but I have a hosted zone setup on Route53 for my domain so I'm not sure what the issue could be. Any chance you've seen this issue before? Any help would be much appreciated!

"ValueError: need more than 0 values to unpack" error

I have come across the above error : "ValueError: need more than 0 values to unpack". It turned out that I had put double quotes around the value for "port:" in LETSENCRYPT_AWS_CONFIG, as per instruction :-)

$ export LETSENCRYPT_AWS_CONFIG='{"domains":[{"elb":{"name":"my-elb","port":"443"},"hosts":["my_host.com"],"key_type":"rsa"}],"acme_account_key":"file:///home/ec2-user/my-le-folder/letsencrypt_priv.pem"}'
$ python letsencrypt-aws.py update-certificates
2016-03-16 14:27:40 [startup] 
2016-03-16 14:27:41 [running] mode='single'
2016-03-16 14:27:41 [updating-elb] elb_name=u'my_elb'
Traceback (most recent call last):
  File "letsencrypt-aws.py", line 526, in <module>
    cli()
  File "/home/ec2-user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/home/ec2-user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/home/ec2-user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/ec2-user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/ec2-user/my-le-folder/le-aws/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 489, in update_certificates
    force_issue, certificate_requests
  File "letsencrypt-aws.py", line 387, in update_elbs
    cert_request,
  File "letsencrypt-aws.py", line 319, in update_elb
    expiration_date = cert_request.cert_location.get_expiration_date()
  File "letsencrypt-aws.py", line 72, in get_expiration_date
    if listener["Listener"]["LoadBalancerPort"] == self.elb_port
ValueError: need more than 0 values to unpack

This converted the value of port to unicode rather than int. By removing the double quotes, it worked just fine.

$ export LETSENCRYPT_AWS_CONFIG='{"domains":[{"elb":{"name":"my_elb","port":443},"hosts":["my_host.com"],"key_type":"rsa"}],"acme_account_key":"file:///home/ec2-user/my-le-folder/letsencrypt_priv.pem"}'
$ python letsencrypt-aws.py update-certificates
2016-03-16 14:30:38 [startup] 
2016-03-16 14:30:38 [running] mode='single'
2016-03-16 14:30:38 [updating-elb] elb_name=u'my_elb'
2016-03-16 14:30:39 [updating-elb.certificate-expiration] expiration_date=datetime.date(2016, 6, 14) elb_name=u'my_elb'

IMHO, it should either work (via some casting/checking within letsencrypt-aws.py) or have a better error message.

Add a certificate to an ELB that does not already have a listener added

Probably not the use case you want to address but if the ELB only has one listener, for port 80 perhaps, the script would not do anything and actually returns an error: ValueError: need more than 0 values to unpack. It would be handy if the script could populate a vanilla ELB with a certificate and added the necessary listener.

Remove Old SSL Certificate(s) after new one is successfully applied

After awhile you'll have a bunch of old certificates in your list. No reason this shouldn't' be tidied up automatically.

It should delete the prior installed certificate right after the new certificate is successfully applied to the ELB.

This can be done with AWS CLI:
http://docs.aws.amazon.com/cli/latest/reference/iam/delete-server-certificate.html

Eg.

aws iam delete-server-certificate --server-certificate-name "32192372168017-2016-10-18-www_mydomain_com-mydomain_com"

Elastic Beanstalk

Hi,
What is the currently recommended way to use this with Elastic Beanstalk?
Thanks
Sean

Could not unserialize key data

Any idea what the following error means? I have my private key install locally and is accessible

2016-02-15 11:18:01 [startup] 
Traceback (most recent call last):
  File "letsencrypt-aws.py", line 486, in <module>
    cli()
  File "/Library/Python/2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/Library/Python/2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Library/Python/2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Library/Python/2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 432, in update_certificates
    s3_client, acme_directory_url, acme_account_key
  File "letsencrypt-aws.py", line 378, in setup_acme_client
    key, password=None, backend=default_backend()
  File "/Library/Python/2.7/site-packages/cryptography/hazmat/primitives/serialization.py", line 20, in load_pem_private_key
    return backend.load_pem_private_key(data, password)
  File "/Library/Python/2.7/site-packages/cryptography/hazmat/backends/multibackend.py", line 282, in load_pem_private_key
    return b.load_pem_private_key(data, password)
  File "/Library/Python/2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1606, in load_pem_private_key
    password,
  File "/Library/Python/2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1802, in _load_key
    self._handle_key_loading_error()
  File "/Library/Python/2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1874, in _handle_key_loading_error
    raise ValueError("Could not unserialize key data.")
ValueError: Could not unserialize key data.

Release as package on PyPI

If this is OK with @alex , I'll submit a PR. We can (probably) keep the current dir/files structure and add entry_points to letsencrypt-aws.py.

Region missing

I am using AWS instances based in Singapore.

When I run letsencrypt-aws on my instance, I get a
botocore.exceptions.NoRegionError: You must specify a region.

Full error message:

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 486, in <module>
    cli()
  File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/app/.venv/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 414, in update_certificates
    elb_client = session.client("elb")
  File "/app/.venv/lib/python2.7/site-packages/boto3/session.py", line 207, in client
    aws_session_token=aws_session_token, config=config)
  File "/app/.venv/lib/python2.7/site-packages/botocore/session.py", line 809, in create_client
    client_config=config, api_version=api_version)
  File "/app/.venv/lib/python2.7/site-packages/botocore/client.py", line 62, in create_client
    verify, credentials, scoped_config, client_config)
  File "/app/.venv/lib/python2.7/site-packages/botocore/client.py", line 150, in _get_client_args
    service_name, region_name, endpoint_url, is_secure)
  File "/app/.venv/lib/python2.7/site-packages/botocore/client.py", line 272, in resolve
    service_name, region_name)
  File "/app/.venv/lib/python2.7/site-packages/botocore/regions.py", line 122, in construct_endpoint
    partition, service_name, region_name)
  File "/app/.venv/lib/python2.7/site-packages/botocore/regions.py", line 135, in _endpoint_for_partition
    raise NoRegionError()
botocore.exceptions.NoRegionError: You must specify a region.

installing requirements fails

Hello and first of all thanks for that tool
sudo /usr/local/bin/pip install -r requirements.txt fails with what seems to be an openSSL issue

` writing src/cryptography.egg-info/PKG-INFO
writing top-level names to src/cryptography.egg-info/top_level.txt
writing dependency_links to src/cryptography.egg-info/dependency_links.txt
writing entry points to src/cryptography.egg-info/entry_points.txt
warning: manifest_maker: standard file '-c' not found

reading manifest file 'src/cryptography.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
no previously-included directories found matching 'docs/_build'
warning: no previously-included files matching '*' found under directory 'vectors'
writing manifest file 'src/cryptography.egg-info/SOURCES.txt'
running build_ext
generating cffi module 'build/temp.linux-x86_64-2.7/_padding.c'
creating build/temp.linux-x86_64-2.7
generating cffi module 'build/temp.linux-x86_64-2.7/_constant_time.c'
generating cffi module 'build/temp.linux-x86_64-2.7/_openssl.c'
building '_openssl' extension
creating build/temp.linux-x86_64-2.7/build
creating build/temp.linux-x86_64-2.7/build/temp.linux-x86_64-2.7
gcc -pthread -fno-strict-aliasing -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/include/python2.7 -c build/temp.linux-x86_64-2.7/_openssl.c -o build/temp.linux-x86_64-2.7/build/temp.linux-x86_64-2.7/_openssl.o
build/temp.linux-x86_64-2.7/_openssl.c:423:27: fatal error: openssl/e_os2.h: No such file or directory
 #include <openssl/e_os2.h>
                           ^
compilation terminated.
error: command 'gcc' failed with exit status 1

----------------------------------------

Command "/usr/bin/python2.7 -u -c "import setuptools, tokenize;file='/tmp/pip-build-3NcnLy/cryptography/setup.py';exec(compile(getattr(tokenize, 'open', open)(file).read().replace('\r\n', '\n'), file, 'exec'))" install --record /tmp/pip-eE19gE-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-3NcnLy/`

Thanks a lot for your help!
(Alternatively, would you be kind to write a line in the README about how to use the docker image? I dabbled and got stuck at docker run alexgaynor/letsencrypt-aws update-certificates which returns a botocore.exceptions.NoRegionError: You must specify a region that neither a aws configure nor a export AWS_DEFAULT_REGION=xxx managed to fix)

Documentation with example

Hi,
I'm really poor in understanding how it works from the documentation. Could you explain it with an example ? And also I would like to know whether we need to do this process for ELB or for server domains.

For example,

Domain name: api.myapp.com (which is registered through different DNS provider, not route53)
ELB Domain: app-prod-web-987654xxxxx.us-west-2.elb.amazonaws.com (A Record)

TypeError: request_domain_challenges() got an unexpected keyword argument 'new_authz_uri'

Hi guys, I'm running into this issue when script is running [updating-elb.request-acme-challenge]:

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 486, in <module>
    cli()
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 449, in update_certificates
    force_issue, domains
  File "letsencrypt-aws.py", line 359, in update_elbs
    domain.get("key_type", "rsa")
  File "letsencrypt-aws.py", line 311, in update_elb
    logger, acme_client, elb_client, route53_client, elb_name, host
  File "letsencrypt-aws.py", line 173, in start_dns_challenge
    host, new_authz_uri=acme_client.directory.new_authz
TypeError: request_domain_challenges() got an unexpected keyword argument 'new_authz_uri'

I have run pip install -r requirements.txt. pip version is 8.0.3.

Any help is greatly appreciated.

No module named acme.challenges

I'm attempting to run letsencrypt-aws for the first time, but I keep getting the following error message:

$ python letsencrypt-aws.py register [email protected]
Traceback (most recent call last):
  File "letsencrypt-aws.py", line 7, in <module>
    import acme.challenges
ImportError: No module named acme.challenges

I'm running Python 2.7.6. on Ubuntu 14.04.

Run on Elastic Beanstalk using container_commands?

Thanks for starting this project.

I have an app on Elastic Beanstalk, and I am looking for a really simple way to get SSL working. I like that letsencrypt-aws uses Route 53 instead of email.

It seems to me that it would be possible to write some script that would run as a "leader only" container command that would run letsencrypt, figuring out the ELB name automatically. It could either set up a cron job, or it could just run once on deploy since I deploy frequently enough that I am not too worried about the certificate expiring because I waited too long.

Is this a viable approach? If so, maybe it would be worth including such a template for such a script and for the config needed to give the instance the right permissions. So it would really be a matter of following some simple instructions and filling in the domain names to put on the certificate.

I could perhaps try writing such a a script myself if the idea makes sense although I am not very familiar with AWS apis, and I was really just looking for a dead simple way to setup SSL.

ValueError: need more than 0 values to unpack

I'm getting the same error as in #34 when running with 2.7, Windows 10 x64. On 3.5 I'm getting a different error (below). I messed around with it for a while but couldn't figure out how to get past it.

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 577, in <module>
    cli()
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 696, in main
    rv = self.invoke(ctx)
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\Users\Steven\AppData\Local\Programs\Python\Python35-32\lib\site-packages\click\core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 540, in update_certificates
    force_issue, certificate_requests
  File "letsencrypt-aws.py", line 432, in update_certs
    cert_request,
  File "letsencrypt-aws.py", line 344, in update_cert
    current_cert = cert_request.cert_location.get_current_certificate()
  File "letsencrypt-aws.py", line 86, in get_current_certificate
    for listener in description["ListenerDescriptions"]
ValueError: not enough values to unpack (expected 1, got 0)

--force-issue raising a ValueError

Hi @alex

I really like this project and started using it yesterday to renew our certificates which we've created using letsencrypt couple days ago.

I have setup everything required for letsencrypt-aws but getting an issue with ValueError while updating-elb.wait-for-route53 is being ran. I am bit confuse, any help be much appreciated.
Here is the stacktrace for it.

Traceback (most recent call last):
  File "letsencrypt-aws.py", line 537, in <module>
    cli()
  File "/home/aws/letsencrypt-aws/lib/python2.7/site-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/home/aws/letsencrypt-aws/lib/python2.7/site-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/home/aws/letsencrypt-aws/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/aws/letsencrypt-aws/lib/python2.7/site-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/aws/letsencrypt-aws/lib/python2.7/site-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "letsencrypt-aws.py", line 500, in update_certificates
    force_issue, certificate_requests
  File "letsencrypt-aws.py", line 398, in update_elbs
    cert_request,
  File "letsencrypt-aws.py", line 365, in update_elb
    cert_request.cert_location.elb_name, authz_record
  File "letsencrypt-aws.py", line 297, in complete_dns_challenge
    raise ValueError("Failed verification")
ValueError: Failed verification 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.