letsencrypt configuration

Dave Cottlehuber dch at skunkwerks.at
Mon Apr 3 06:30:02 UTC 2017

> On Sat, Apr 1, 2017 at 2:40 AM, Andre Goree <andre at drenet.net> wrote:
> > So how is everyone going about configuring letsencrypt on FreeBSD?  It would
> > seem that multiple ports that used to exist for this very purpose are no
> > longer in the repos (letskencrypt, py-letsencrypt), so tutorials I'm finding
> > (and even letskencrypt, which is still in the FreeBDS wiki) aren't much
> > help.

I speculate that the letsencrypt trademark has been enforced
https://letsencrypt.org/trademarks/ so people needed to rename their

I've used a few of them and settled on security/acme-client with a very
simple config that is easy to manage with my config management setup.
Below is a complete example, using www/h2o web server,
/etc/periodic.conf to keep the script running, and security/acme-client
for the heavy lifting.  If there's any info missing let me know, I'll
blog this later in the week. 

# /etc/periodic.conf

#  /usr/local/etc/letsencrypt/example.sh 
#!/bin/sh -e
mkdir -p /usr/local/etc/ssl/acme_client/host.example.com \
  /usr/local/etc/acme_client/host.example.com \
# add `-s` flag below to use the staging server until you have it
# remember to remove all certs and keys when you switch from staging to
# add `-F` flag below to force renewal e.g. if you add another altName
# remove /usr/local/etc/ssl/acme_client/host.example.com/cert.pem
# so that the certificates are regenerated correctly

/usr/local/bin/acme-client -mnN -v \
  -F \
  -C /usr/local/www/acme_client \
  host.example.com \
  altname1.example.com \
  altname2.example.com \
  2>&1 | tee -a /var/log/acme.log

# the public certification chain is now at:
# /usr/local/etc/ssl/acme_client/host.example.com/fullchain.pem
# the private certificate key is now at:
# /usr/local/etc/ssl/acme_client/private/host.example.com/privkey.pem
# make a combined key for haproxy and friends
cat /usr/local/etc/ssl/acme_client/private/host.example.com/privkey.pem
    /usr/local/etc/ssl/acme_client/host.example.com/fullchain.pem \
  > /usr/local/etc/ssl/acme_client/host.example.com/combined.pem

chmod 0600 /var/log/acme.log

service h2o restart
service haproxy restart

Obviously this needs HTTP:80 support in your web server, I use www/h2o
for this:

# /usr/local/etc/h2o/h2o.conf
# vi: ft=yaml
# see https://h2o.examp1e.net/ for detailed documentation
# see h2o --help for command-line options and settings
user: www
pid-file: /var/run/h2o.pid
access-log: /var/log/h2o/h2o-access.log
error-log: /var/log/h2o/h2o-error.log
listen: 80
  port: 443
    minimum-version: TLSv1.2
    cipher-preference: server

file.dirlisting: on
file.send-gzip: on
http1-request-timeout: 10
http2-idle-timeout: 10
limit-request-body: 1024
max-connections: 1024

  image/svg+xml: .svg
  text/plain: .log
  text/css: .css
  application/atom+xml: .xml
  application/zip: .zip
  application/json: .json
  "text/html; charset=utf-8": .html

# host headers, global
header.add: "x-frame-options: deny"
header.add: "X-XSS-Protection: 1; mode=block"
header.add: "X-Content-Type-Options: nosniff"
header.add: "X-UA-Compatible: IE=Edge"
# 1 month HSTS pinning
header.add: "Strict-Transport-Security: max-age=2628000"
header.add: "Cache-Control: no-transform"

# per-host configuration
        mruby.handler: |
          require "htpasswd.rb"
        file.dir: "/var/www/host.example.com/"
        file.dir: "/var/www/acme"

        file.dir: "/var/www/acme"
        file.dir: "/var/www/altname1.example.com"

        file.dir: "/var/www/acme"
        file.dir: "/var/www/altname2.example.com"

Some notes to help you:

- you *need* to have port 80 open for http requests for the acme
protocol to do its verification on
- you could add a 301 for anything not in /.well-known/acme-challenge/
- in h2o.conf I don't force use of HTTPS anywhere, but the use of HSTS
will keep browsers that use https once, to use it in future
- the same /var/www/acme dir is re-used for each virtual host
- when you're getting started, use the -S flag in the script to get
dummy certs from the server without using up your acme "budget"
- when you have it all working, delete *all* the generated certs and
scripts before switching back to normal mode (without -S) 
- its possible to use the return code from acme-client to decide whether
to restart the daemons or not
- the simplest solution for me was to restart all the daemons every week
- the only file that actually matters is your "account key" for each
server, stored in /usr/local/etc/acme/host.example.com/privkey.pem as
all the rest will be regenerated automatically on the next acme-client
- if you have multiple servers or services that share the certificate,
you may need to use a reverse proxy to direct things to the appropriate
place so that letsencrypt can find them


More information about the freebsd-questions mailing list