Giter Site home page Giter Site logo

saltstack-formulas / letsencrypt-formula Goto Github PK

View Code? Open in Web Editor NEW

This project forked from martinhoefling/letsencrypt-formula

56.0 33.0 151.0 369 KB

Saltstack formula for letsencrypt service

Home Page: http://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html

License: Other

SaltStack 48.16% Shell 7.56% Ruby 26.60% JavaScript 12.78% Jinja 4.90%

letsencrypt-formula's Introduction

letsencrypt-formula

Travis CI Build Status Semantic Release

Creates certificates and manages renewal using the letsencrypt service.

See the full SaltStack Formulas installation and usage instructions.

If you are interested in writing or contributing to formulas, please pay attention to the Writing Formula Section.

If you want to use this formula, please pay attention to the FORMULA file and/or git tag, which contains the currently released version. This formula is versioned according to Semantic Versioning.

See Formula Versioning Section for more details.

If you need (non-default) configuration, please pay attention to the pillar.example file and/or Special notes section.

Commit message formatting is significant!!

Please see How to contribute for more details.

None

This is a shortcut for letsencrypt.install letsencrypt.config and letsencrypt.domains.

if install_method is package (the default), the formula will try to install the certbot package from your Distro's repo. Keep in mind that most distros don't have a package available by default: Ie, previous stable Debian (Stretch) requires a backports repo installed. Centos 7 requires EPEL, etc. This formula DOES NOT manage these repositories. Use the apt-formula or the epel-formula to manage them.

If install_method is git it installs and configures the letsencrypt cli from git, creates the requested certificates and installs renewal cron job.

If install_method is pip it installs and configures the letsencrypt cli from pip, creates the requested certificates and installs renewwal cron job. Allows plugin installation with pip_pkgs.

** WARNING ** If you set install_method to package, it will:

  • Delete all certbot's crons if they exist from a previous git-based installation (as the package uses a systemd's timer unit to renew all the certs)
  • Delete git-based installation's scripts (usually installed under /usr/local/bin) if they still exist declared in letsencrypt's pillar.
  • As a safety measure, if there's an /opt/letsencrypt directory from a git-based installation, it will be left untouched, but unused.

To check dependencies to use the package for your distro, check https://certbot.eff.org/all-instructions.

Only installs the letsencrypt client (see above).

Manages /etc/letsencrypt/cli.ini config file.

Creates a certificate with the domains in each domain set (letsencrypt:domainsets in pillar). Letsencrypt uses a relatively short validity of 90 days. Therefore, a cron job for automatic renewal every 60 days is installed for each domain set as well.

Linux testing is done with kitchen-salt.

  • Ruby
  • Docker
$ gem install bundler
$ bundle install
$ bin/kitchen test [platform]

Where [platform] is the platform name defined in kitchen.yml, e.g. debian-9-2019-2-py3.

Creates the docker instance and runs the template main state, ready for testing.

Runs the inspec tests on the actual instance.

Removes the docker instance.

Runs all of the stages above in one go: i.e. destroy + converge + verify + destroy.

Gives you SSH access to the instance for manual testing.

letsencrypt-formula's People

Contributors

aboe76 avatar anderbubble avatar boltronics avatar dafyddj avatar dexbleeker avatar dmaphy avatar igarridoonestic avatar iggy avatar itbabu avatar javierbertoli avatar jinnatar avatar kiniou avatar kislik avatar mario-f avatar martinhoefling avatar michaelkuty avatar moebiuseye avatar mrichar1 avatar myii avatar noelmcloughlin avatar orangedog avatar pprkut avatar puneetk avatar semantic-release-bot avatar t0fik avatar tardypad avatar timidrobot avatar waynew avatar wwentland avatar xenophonf 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

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

letsencrypt-formula's Issues

create-fullchain-privkey-pem-for-X breaks cleanup

Because this formula creates an extra file under live, the certbot delete command cannot cleanup properly, leaving things in an invalid state.

Attempting to create another certificate for the same domain gives a "live directory exists" error.

Warnings due to file.absent with excessive flags

When I use this formula, I get the following warnings:

----------
          ID: /usr/bin/certbot renew --dry-run --cert-name
    Function: file.absent
      Result: True
     Comment: File /usr/bin/certbot renew --dry-run --cert-name is not present
     Started: 07:10:06.754729
    Duration: 3.858 ms
     Changes:   
    Warnings: 'source', 'mode' and 'template' are invalid keyword arguments for
              'file.absent'. If you were trying to pass additional data to be
              used in a template context, please populate 'context' with 'key:
              value' pairs. Your approach will work until Salt Nitrogen is out.
              Please update your state files.
----------
          ID: /usr/bin/certbot renew
    Function: file.absent
      Result: True
     Comment: File /usr/bin/certbot renew is not present
     Started: 07:10:06.770253
    Duration: 3.709 ms
     Changes:   
    Warnings: 'source', 'mode' and 'template' are invalid keyword arguments for
              'file.absent'. If you were trying to pass additional data to be
              used in a template context, please populate 'context' with 'key:
              value' pairs. Your approach will work until Salt Nitrogen is out.
              Please update your state files.

Presumably, those parameters should be conditioned on use_package being false.

Why renewing manually instead of using certbot?

Certbot has a renew option which will renew all certificates that are close to renewal date. ISTM that this would be a better approach than using renew_letsencrypt_cert.sh and check_letsencrypt_cert.sh ot is there a specific reason why certbot renew cannot be used?

[BUG] ACMEv1 enf of life

From Jun 2020 ACMEv1 is not supported any more and the formula fails.

              stderr:
                  An unexpected error occurred:
                  The client lacks sufficient authorization :: Account creation on ACMEv1 is disabled. Please upgrade your ACME client to a version that supports ACMEv2 / RFC 8555. See https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1/88430 for details.
                  Please see the logfiles in /var/log/letsencrypt for more details.

Specify a unique webroot for each domain set

There should be a way to specify a separate webroot for each domain set. Something like this:

domainsets:
  www:
    domains:
      - example.com
      - www.example.com
    webroot: /var/www/domain.com/public
  mail:
    domains:
      - imap.example.com
      - smtp.example.com
      - mail.example.com
    webroot: /var/www/mail/public
  intranet:
    domains:
      - intranet.example.com
    webroot: /var/www/intranet/public

I solved this by picking one real webroot and symlinking the others to it, but I dislike this manual step.

Wildcard Support?

Does this formula support wildcard certificates?

Looking through the pillar example it doesn't appear to but I wanted to confirm.

Initial lack of cert is not handled correctly

I ran into this while configuring a new server with a new domain earlier this week. The problem is if you use something like the nginx formula which serves up your custom nginx conf there's no way to avoid errors with the attempted redirect prior to the cert generation. I believe this issue is definitely related more closely to the nginx/apache formulas, but that we may wish to solve it here for initial certificate generation. This is by no means perfect, but it would allow users to do a top that looks something like:

base:
  '*':
    - letsencrypt.nginx
    - letsencrypt
    - letsencrypt.nginx-clean
    - nginx.blahblahblah

We would create a default site with the nginx config file inside of letsencrypt.nginx so the site is responsive pulling from the variables, do the letsencrypt work, then clean up the config and the associated dirs. This would also avoid conflicts between named nginx configs.

@martinhoefling Any thoughts or opinions on this? How are you working around this? Right now I have to drop on my salt config, let it bomb, modify the conf, then run salt again so letsencrypt finishes before the nginx component runs and everything works, definitely not ideal.

letsencrypt-crontab state fails when cron module is absent and can't be loaded

----------
          ID: letsencrypt-crontab-example.com
    Function: cron.absent
        Name: /usr/bin/certbot renew example.com
      Result: False
     Comment: State 'cron.absent' was not found in SLS 'letsencrypt.domains'
              Reason: 'cron' __virtual__ returned False: cron module could not be loaded
     Changes:   

This state should be encapsulated with a test to see if cron module is loaded or cron is available...

Problem when refreshing git repo

Modifications on the letsencrypt Git repo is often not a simple fast-forward.
in install.sls, the git.latest fails.
We need something like a force_fetch option.
I tried, it worked, but with a strange warning.

My modification :

diff --git a/letsencrypt/install.sls b/letsencrypt/install.sls
index 31b279b..6876a50 100644
--- a/letsencrypt/install.sls
+++ b/letsencrypt/install.sls
@@ -8,3 +8,4 @@ letsencrypt-client-git:
     - name: https://github.com/letsencrypt/letsencrypt
     - target: {{ letsencrypt.cli_install_dir }}
     - force_reset: True
+    - force_fetch: True

The Warning :

    git_|-letsencrypt-client-git_|-https://github.com/letsencrypt/letsencrypt_|-latest:
        ----------
        __run_num__:
            0
        changes:
            ----------
        comment:
        duration:                                                                                                                                                                         1691.61
        name:
            https://github.com/letsencrypt/letsencrypt
        result:
            True
        start_time:
            10:50:29.373780                                                                                                                                                           warnings:
            - 'force_fetch' is an invalid keyword argument for 'git.latest'. If you were trying to pass additional data to be used in a template context, please populate 'con
text' with 'key: value' pairs. Your approach will work until Salt Carbon is out. Please update your state files.

Virtualenv AssertionError

----------
          ID: letsencrypt_packages_pip_virtualenv
    Function: pip.installed
        Name: virtualenv
      Result: False
     Comment: Error installing 'virtualenv': Exception:
              Traceback (most recent call last):
                File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 122, in main
                  status = self.run(options, args)
                File "/usr/lib/python2.7/dist-packages/pip/commands/freeze.py", line 74, in run
                  req = pip.FrozenRequirement.from_dist(dist, dependency_links, find_tags=find_tags)
                File "/usr/lib/python2.7/dist-packages/pip/__init__.py", line 299, in from_dist
                  assert len(specs) == 1 and specs[0][0] == '=='
              AssertionError
              
              Storing debug log for failure in /root/.pip/pip.log
     Started: 02:49:07.301772
    Duration: 561.457 ms
     Changes:   

Certonly install fails because of argument placement

----------
          ID: create-initial-cert-www-my.domain.com
    Function: cmd.run
        Name: /opt/letsencrypt/letsencrypt-auto -d my.domain.com certonly
      Result: False
     Comment: Command "/opt/letsencrypt/letsencrypt-auto -d my.domain.com certonly" run
     Started: 14:02:52.437152
    Duration: 1165.16 ms
     Changes:  

Because of the positioning of the domain name before certonly.

This command succeeds without error:
/root/.local/share/letsencrypt/bin/letsencrypt certonly --standalone -d my.domain.com

Adding a new SubjectAlternativeName to a set doesn't cause a renew

If I first have a domainset such as:

domainsets:
    www:
      - example.com
      - www.example.com

And have that applied and then later on amend the domainset to for example:

domainsets:
    www:
      - example.com
      - www.example.com
      - www2.example.com

Applying the state won't trigger adding www2.example.com as an alternate name to the domainset's cert. The command visible in state apply output is correct and would cause the correct action, if it was actually executed:

/usr/bin/certbot certonly --quiet -d example.com -d www.example.com -d www2.example.com --non-interactive

.. but looks like it doesn't get executed. To me it seems because of this:

unless: {{ check_cert_cmd }} {{ domainlist[0] }}

i.e. only the status of the CN is checked, which ignores the fact of having new alternative names.

Support certbot distribution package

Hi,

I would like to suggest to add support for certbot installed from distribution packages:
Debian
Ubuntu

letsencrypt-client-git state could be renamed to generic letsencrypt-client and it would use package.installed or git.latest depending on pillar letsencrypt:use_distribution_client value, for example.

There is a little problem with Debian Jessie, as jessie-backports repository has to be configured additionally. In my setup, I have my own repository.backports state that I include where it's needed for some packages, and I wouldn't like that some salt formula would add yet another sources.list.d/backports.list file, so I guess repository requirement exercise could be left for the user.

Using packaged certbot, paths like /etc/letsencrypt/live/ should be changed accordingly.

I guess I could prepare PR if agreement is arrived at.

Support standalone mode

I am working on a patch to support the standalone mode. It should allow

  • stop service (e.g. apache or nginx)
  • call letsencrypt-auto standalone
  • restart service (e.g. apache or nginx)

This is needed in my setup, as the roots for my virtual hosts don't follow (for historical reason) a very clear pattern, and I can assume a small downtime during the night easily.

Support installing a specific version of Certbot

Blindly using git.latest seems inadvisable. Letsencrypt really made a big mistake in recommending this during its initial stages. Now Certbot uses proper semantic versioning, and we should support that as well. The latest version is tagged v0.9.3. At the very least, we should be able to specify the specific desired version in pillar, but ideally, we would be able to use e.g. "0.9.*" so that we pull in fixes as well, without risking automatically upgrading to any breaking changes.

The certbot-auto script will automatically fetch the latest version, but there is a --no-self-upgrade flag to prevent this. I'm not clear on whether this is the git master or a specific version tag.

[BUG] post_renew not active when use_package:True

Your setup

Formula commit hash / release tag

git hash : df1b31e

Pillar / config used

local:
    ----------
    post_renew:
        ----------
        cmds:
            - systemctl reload apache2
    config:
        ----------
        rsa-key-size:
            4096
    domainsets:
        ----------
        www:
            - www.test.localhost
            - test.localhost


Bug details

Describe the bug

post_renew is documented in pillar.example, but seems only used in letsencrypt/files/renew_letsencrypt_cert.sh.jinja which is not deployed when use_package: True (default) is used.

Expected behaviour

Deploy hooks

Attempts to fix the bug

Not yet

Additional context

Error with multiple domains

Hey @lgunsch, hey guys,
6cad4d7 adds a loop {% for domain in domainlist %}, which throws errors in case of multiple domains per set. Something like {{ setname }}-{{ domainlist[0] }} should do the thing.

Greetings
~HerHde

Document all states

The README only mentions the letsencrypt state. It should document them all so they can be used individually if a user wants (i.e. I want to install letsencrypt, but not have it actually manage my certs).

@martinhoefling not sure if you're watching this repo or not... so, ping!

[BUG] Installing on CentOS7 minion

Your setup

Formula commit hash / release tag

90d8a06

Versions reports (master & minion)

Salt Version:
Salt: 3001.3

Dependency Versions:
cffi: 1.11.5
cherrypy: unknown
dateutil: 2.6.1
docker-py: Not Installed
gitdb: 4.0.1
gitpython: 3.0.9
Jinja2: 2.10.1
libgit2: 0.26.8
M2Crypto: 0.35.2
Mako: Not Installed
msgpack-pure: Not Installed
msgpack-python: 0.6.2
mysql-python: Not Installed
pycparser: 2.14
pycrypto: Not Installed
pycryptodome: Not Installed
pygit2: 0.26.4
Python: 3.6.8 (default, Apr 16 2020, 01:36:27)
python-gnupg: Not Installed
PyYAML: 3.12
PyZMQ: 19.0.0
smmap: 3.0.1
timelib: Not Installed
Tornado: 4.5.3
ZMQ: 4.3.3

System Versions:
dist: centos 8 Core
locale: UTF-8
machine: x86_64
release: 4.18.0-193.28.1.el8_2.x86_64
system: Linux
version: CentOS Linux 8 Core

Pillar / config used

letsencrypt:
  domainsets:
    www:
      - example.com
  post_renew:
    cmds:
      - service httpd reload

Bug details

Describe the bug

In installed epel repo as described in Readme.md

Steps to reproduce the bug

salt -l debug my-minion state.apply letsencrypt

          ID: letsencrypt-client
    Function: pkg.installed
      Result: False
     Comment: Error occurred installing package(s). Additional info follows:

              errors:
     Started: 16:43:35.448172
    Duration: 12855.414 ms

Expected behaviour

Correct installation

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.