Giter VIP home page Giter VIP logo

lecm's Introduction

lecm: Let's Encrypt Certificates Manager

buildstatus release versions

Let's Encrypt Certificates Manager (lecm) is an utility that allows one to manage (generate and renew) Let's Encrypt SSL certificates.

Goal

The goal of lecm is to be able to generate and renew Let's Encrypt SSL certificates automatically.

lecm is configuration driven. Each certificate that needs to be managed is described in the configuration file.

Installation

Using pypi

You just need to

$ pip install lecm

Debian-based distro (Debian, Ubuntu, …)

There is an official Debian package for lecm

$ sudo apt-get install lecm

How to run it

lecm is configuration driven. The configuration file is (by order of priority):

  1. The one specified on the command line (lecm --conf /path/to/conf.yml)
  2. The one specified in the environment variable $LECM_CONFIGURATION
  3. The /etc/lecm.conf

lecm supports various commands:

--generate

lecm --generate will generate SSL certificates for items listed in the configuration file that are not present in the filesystem.

--renew

lecm --renew will renew SSL certificates already present on the filesystem if its expiry date is lower than the remaining_days value.

--force

lecm --force will force the regeneration or renewal of SSL certificates, even if its expiry date is not lower than the remainin_days value.

--list

lecm --list will display basic informations about currently configured items.

+--------- +----------------------------------+---------------+------------------------------------------------------------------+-----------------------------------------------------------+------+
|  In Sync |               Item               |     Status    |                          subjectAltName                          |                          Location                         | Days |
+--------- +----------------------------------+---------------+------------------------------------------------------------------+-----------------------------------------------------------+------+
|  True    |   lecm-test.distributed-ci.io    |   Generated   |                 DNS:lecm-test.distributed-ci.io                  |    /etc/letsencrypt/pem/lecm-test.distributed-ci.io.pem   |  89  |
|  False   | lecm-test-test.distributed-ci.io | Not-Generated | DNS;lecm-test-test.distributed-ci.io,DNS:lecm.distributedi-ci.io | /etc/letsencrypt/pem/lecm-test-test.distributed-ci.io.pem | N/A  |
+----------+----------------------------------+---------------+------------------------------------------------------------------+-----------------------------------------------------------+------+

--list-details

lecm --list-details will display details informations about currently configured items.

+--------- +----------------------------------+---------------+------------------------------------------------------------------+---------------------------+--------------+-----------------------------------------------------------+------+------+--------+------+
|  In Sync |               Item               |     Status    |                          subjectAltName                          |        emailAddress       |  Environment |                          Location                         | Type | Size | Digest | Days |
+--------- +----------------------------------+---------------+------------------------------------------------------------------+---------------------------+--------------+-----------------------------------------------------------+------+------+--------+------+
|  True    |   lecm-test.distributed-ci.io    |   Generated   |                 DNS:lecm-test.distributed-ci.io                  | [email protected] |  production  |    /etc/letsencrypt/pem/lecm-test.distributed-ci.io.pem   | RSA  | 4096 | sha256 |  89  |
|  False   | lecm-test-test.distributed-ci.io | Not-Generated | DNS;lecm-test-test.distributed-ci.io,DNS:lecm.distributedi-ci.io | [email protected] |    staging   | /etc/letsencrypt/pem/lecm-test-test.distributed-ci.io.pem | RSA  | 2048 | sha256 | N/A  |
+----------+----------------------------------+---------------+------------------------------------------------------------------+---------------------------+--------------|-----------------------------------------------------------+------+------+--------+------+

Configuration

Every parameters are either applicable globally or within the scope of a certificate. The finest specification wins.

Parameter Scope Default Description
path global, certificate None Folder where will reside all the relevant files
type global, certificate RSA Type of the key to generate (Possible: RSA, DSA)
size global, certificate 4096 Size of the key to generate
digest global, certificate sha256 Digest of the key to generate
version global, certificate 3 Version of the SSL Certificate to generate
subjectAltName global, certificate None subjectAltName value of the Certificate Signing Request (csr)
countryName global, certificate None countryName value of the Certificate Signing Request (csr)
stateOrProvinceName global, certificate None stateOrProvinceName value of the Certificate Signing Request (csr)
localityName global, certificate None localityName value of the Certificate Signing Request (csr)
organizationName global, certificate None organizationName value of the Certificate Signing Request (csr)
organizationalUnitName global, certificate None organizationalUnitName value of the Certificate Signing Request (csr)
commonName global, certificate None commonName value of the Certificate Signing Request (csr)
emailAddress global, certificate None emailAddress value of the Certificate Signing Request (csr)
account_key_name global, certificate account_$fqdn.key Name of the account key to generate
remaining_days global, certificate 10 Number of days of validity below which the SSL Certificate should be renewed
service_name global, certificate httpd Service that needs to be reloaded for the change to be taken in consideration
service_provider global, certificate systemd Service management system (Possible: systemd, sysv)
environment global, certificate production Let's Encrypt environment to use (Possible: production, staging)

Configuration file example

---
path: /etc/letsencrypt

certificates:
  my.example.com:
  app.example.com:
    subjectAltName:
      - app.example.com
      - app1.example.com
      - app2.example.com

More example can be found in the sample/ directory.

Httpd and Nginx

lecm does not configure the webservers, they have to be previously configured to be able to answer the challenges. NOTE: Let's Encrypt will perform a plain HTTP request to port 80 on your server, so you must serve the challenge files via HTTP. See the HTTP Challenge section of the ACME specification for more details.

httpd

Alias /.well-known/acme-challenge /etc/letsencrypt/challenges/my.example.com
<Directory /etc/letsencrypt/challenges/my.example.com>
    Require all granted
</Directory>

nginx

location /.well-known/acme-challenge/ {
  alias /etc/letsencrypt/challenges/my.example.com/;
  try_files $uri =404;
}

lecm's People

Contributors

albatros69 avatar fcharlier avatar oaubert avatar psycojoker avatar sbadia avatar spredzy 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lecm's Issues

AttributeError module 'platform' has no attribute 'dist'

lecm 0.0.9 on Ubuntu 20.10:

sudo lecm --generate
Traceback (most recent call last):
  File "/usr/bin/lecm", line 33, in <module>
    sys.exit(load_entry_point('lecm==0.0.9', 'console_scripts', 'lecm')())
  File "/usr/lib/python3/dist-packages/lecm/shell.py", line 79, in main
    cert.generate()
  File "/usr/lib/python3/dist-packages/lecm/certificate.py", line 290, in generate
    self._create_filesystem()
  File "/usr/lib/python3/dist-packages/lecm/certificate.py", line 105, in _create_filesystem
    utils.enforce_selinux_context(self.path)
  File "/usr/lib/python3/dist-packages/lecm/utils.py", line 49, in enforce_selinux_context
    if platform.dist()[0] in ['fedora', 'centos', 'redhat']:
AttributeError: module 'platform' has no attribute 'dist'

Don't hardcode intermediate certificate

Related to #63 and #64 (ping @sbadia )

It's likely that Let's Encrypt will change its intermediate cert again to switch to ECDSA : https://letsencrypt.org/certificates/
It would be better to avoid hardcoding the intermediate in lecm. In fact, if Let's Encrypt start using several intermediate certs at the same time, lecm would be completely broken.

It should be possible to retrieve the right intermediate in the ACME response, but it's poorly documented. I found this doc which is quite sparse but gives the idea: https://letsencrypt.org/docs/integration-guide/

CA chain invalid since let's encrypt switched to the R3 certificates

Beginning of dec. Let's encrypt started issuing certificates signed with the R3 intermediate certificate instead of the X3 one.
However, lecm still includes the x3 one in the pem file.

The naïve solution would be to change _INTERMEDIATE_CERTIFICATE_URL but I guess this wouldn't be very robust as other intermediates CA certificates can also be used.

Be able to use staging environment for testing purpose

We highly recommend testing against our staging environment before using our production environment. This will allow you to get things right before issuing trusted certificates and reduce the chance of your running up against rate limits.

It would be nice for lecm to be able to run either against staging or production environment based on the need of the user.

Agreement URL has changed

On a fresh install, got this error:

ERROR:lecm.certificate:[host.example.com] b'Parsing account key...\nParsing CSR...\nRegistering account...\nTraceback (most recent call last):\n  File "/usr/bin/acme-tiny", line 11, in <module>\n    load_entry_point(\'acme-tiny==20160326\', \'console_scripts\',
 \'acme-tiny\')()\n  File "/usr/lib/python3/dist-packages/acme_tiny.py", line 208, in __entry_point\n    main(sys.argv[1:])\n  File "/usr/lib/python3/dist-packages/acme_tiny.py", line 194, in main\n    signed_crt = get_crt(args.account_key, args.csr, args.acm
e_dir, log=LOGGER, CA=args.ca)\n  File "/usr/lib/python3/dist-packages/acme_tiny.py", line 92, in get_crt\n    raise ValueError("Error registering: {0} {1}".format(code, result))\nValueError: Error registering: 400 b\'{\\n  "type": "urn:acme:error:malformed",
\\n  "detail": "Provided agreement URL [https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf] does not match current agreement URL [https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf]",\\n  "status": 400\\n}\'\n'

Probably a change on LE side ?

Ensure days_before_expiry is an int before doing any operation on it

When none of the certificate has been generated, there 'days_before_expiry' value is the literal strinb 'N/A', which is used to know if it is lower than 'remaining_days'. This leads to the issue below

#> lecm --list
+----------------------------------+---------------+------------------------------------------------------------------+-----------------------------------------------------------+------+
|               Item               |     Status    |                          subjectAltName                          |                          Location                         | Days |
+----------------------------------+---------------+------------------------------------------------------------------+-----------------------------------------------------------+------+
| lecm-test-test.distributed-ci.io | Not-Generated | DNS:lecm-test-test.distributed-ci.io,DNS:lecm.distributedi-ci.io | /etc/letsencrypt/pem/lecm-test-test.distributed-ci.io.pem | N/A  |
|   lecm-test.distributed-ci.io    | Not-Generated |                 DNS:lecm-test.distributed-ci.io                  |    /etc/letsencrypt/pem/lecm-test.distributed-ci.io.pem   | N/A  |
+----------------------------------+---------------+------------------------------------------------------------------+-----------------------------------------------------------+------+
 #> lecm --renew
Traceback (most recent call last):
  File "/usr/bin/lecm", line 9, in <module>
    load_entry_point('lecm==0.0.6', 'console_scripts', 'lecm')()
  File "/usr/lib/python3.4/site-packages/lecm/shell.py", line 89, in main
    if cert.days_before_expiry <= cert.remaining_days:
TypeError: unorderable types: str() <= int()

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.