Let's Encrypt

Say hello to encrypted world, free ,,green" certificates for everyone. Wet dreams come true !
I spent some time experimenting with default python client and inspired from official salt formula i maked improved version for us. Still under heavy testing, but working version will be available under tcpcloud github group. Here are some parts

map.jinja

{%- load_yaml as base_defaults %}
Debian:
  pkgs:
  - git
  - python-dialog

..

client.sls

{%- from "letsencrypt/map.jinja" import client with context %}

{%- if client.enabled %}

letsencrypt-packages:
  pkg.installed:
  - names: {{ client.pkgs }}

letsencrypt-config:
  file.managed:
    - name: /etc/letsencrypt/cli.ini
    - makedirs: true
    - contents_pillar: letsencrypt:client:config

letsencrypt-client-git:
  git.latest:
    - name: https://github.com/letsencrypt/letsencrypt
    - target: {{ client.cli_install_dir }}

{% for setname, domainlist in client.domainset.items() %}
create-initial-cert-{{ setname }}-{{ domainlist[0] }}:
  cmd.run:
    - unless: ls /etc/letsencrypt/live/{{ domainlist[0] }}
    - name: {{ client.cli_install_dir }}/letsencrypt-auto -d {{ domainlist|join(' -d ') }} certonly
    - require:
      - file: letsencrypt-config

letsencrypt-crontab-{{ setname }}-{{ domainlist[0] }}:
  cron.present:
    - name: {{ client.cli_install_dir }}/letsencrypt-auto -d {{ domainlist|join(' -d ') }} certonly
    - month: '*/2'
    - minute: random
    - hour: random
    - daymonth: random
    - identifier: letsencrypt-{{ setname }}-{{ domainlist[0] }}
    - require:
      - cmd: create-initial-cert-{{ setname }}-{{ domainlist[0] }}
{% endfor %}

{%- endif %}
Metadata e.g. pillars

letsencrypt:
  client:
    enabled: true
    config: |
      host = https://acme-v01.api.letsencrypt.org/directory
      email = webmaster@example.com
      authenticator = webroot
      webroot-path = /var/lib/www
      agree-tos = True
      renew-by-default = True
    domainset:
      www:
        - example.com
        - www.example.com
      mail:
        - imap.example.com
        - smtp.example.com
        - mail.example.com
      intranet:
        - intranet.example.com

This is the default configuration which could by called semi-automated because we need stop nginx or other server which listen on 80 or 443. Simple add proxy to your web server like this:

location /.well-known/acme-challenge/ {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://{{ site.host.name }}:9999/.well-known/acme-challenge/;
}

and then configure client to use other port:

letsencrypt:
  client:
    enabled: true
    config: |
      ...
      renew-by-default = True
      http-01-port = 9999
      standalone-supported-challenges = http-01
    domainset:
      www:
        - example.com

Read More