9ddfc06
# acme-tiny Fedora package
9ddfc06
9ddfc06
The Fedora package for acme-tiny adds a tiny framework to make issuing
9ddfc06
and renewing [Let's Encrypt](https://letsencrypt.org/) certificates 
9ddfc06
convenient.  It does *not* alter your configuration in any way, other
9ddfc06
than to drop an acme.conf apache config snippet into `/etc/httpd/conf.d`
9ddfc06
and provide a systemd service.
9ddfc06
9ddfc06
If you want a package that tries to do everything for you as root,
9ddfc06
consider the `certbot` package.
9ddfc06
9ddfc06
The ACME protocol will work with other certificate authorities, but
9ddfc06
acme-tiny is currently hardwired to use letencrypt.org - which is
9ddfc06
also currently the only ACME certificate authority recognized in
9ddfc06
most browsers.
9ddfc06
9ddfc06
These instructions assume you are using letsencrypt for the first time
9ddfc06
with this acme-tiny package.  For example, you should not already have
9ddfc06
an account key for the domains it will manage.  If you do, see README.md
9ddfc06
for instructions on converting it.  Put any existing account key in
9ddfc06
PEM format in `/var/lib/acme/private`, readable by the acme user (only!).
9ddfc06
9ddfc06
## The web server must already serve your domains on HTTP
9ddfc06
9ddfc06
If you cannot access your web domains locally with commands like 
9ddfc06
`curl` and `wget`, then this framework won't work.  Acme-tiny will work with
9ddfc06
any web server package, but if you are not using apache (httpd package), you
9ddfc06
must provide the equivalent of `/etc/httpd/conf.d/acme.conf` to map
9ddfc06
`/var/www/challenges` to the ACME URL location.  The web server can even
9ddfc06
be on a remote machine - provided you have somehow arranged for it to
9ddfc06
serve files from `/var/www/challenges` (perhaps via NFS).  
9ddfc06
9ddfc06
If you are using Apache, and restrict access to `<location "/">`, then this
9ddfc06
will override the acme.conf global config snippet, and you must explicitly
9ddfc06
make the ACME URL (http://your.domain.here/.well-known/acme-challenge/)
9ddfc06
publicly accessible.
9ddfc06
9ddfc06
## Put your CSRs in `/var/lib/acme/csr`
9ddfc06
9ddfc06
You can use existing CSRs, or generate a new one using openssl.  Put
9ddfc06
all CSRs to be issued and renewed by acme-tiny in `/var/lib/acme/csr`.
9ddfc06
I like to symlink the CSRs into /var/lib/acme/csr, just make sure the acme
9ddfc06
user can read them (and follow the symlink).  The details for openssl are
9ddfc06
beyond the scope of this documentation, but this should work for creating a
9ddfc06
certificate for a single domain:
9ddfc06
```
9ddfc06
cd /etc/pki/tls
9ddfc06
ln -s /var/lib/acme/csr .
9ddfc06
openssl req -new -nodes -keyout private/your.domain.key \
9ddfc06
	-out csr/your.domain.csr
9ddfc06
chmod 0400 private/your.domain.key
9ddfc06
```
9ddfc06
If you have an existing key, replace  `-nodes -keyout` with `-key`.
9ddfc06
The default openssl config will ask you for data, be sure to give the
9ddfc06
domain you will be serving when it asks for "Common Name".  It is possible
9ddfc06
to cover multiple domains with a single certificate using openssl.  First, add
9ddfc06
a section to the end of `/etc/pki/tls/openssl.cnf` defining your extension:
9ddfc06
```
9ddfc06
[MYSERV]
9ddfc06
subjectAltName=DNS:your.domain,DNS:www.your.domain
9ddfc06
```
9ddfc06
Then add `-reqexts MYSERV` to the openssl command line.  One of the domains
9ddfc06
must match the common name. 
9ddfc06
9ddfc06
Make sure the CSR can be read by the acme user.
9ddfc06
9ddfc06
## Issue the certificate
9ddfc06
9ddfc06
The timer service in acme-tiny will check the certificate for all CSRs in csr
9ddfc06
every 24 hours, and issue or renew the certificate if it is missing or about to
9ddfc06
expire (in 7 days by default).  You don't have to wait for the timer, however.
9ddfc06
Use 
9ddfc06
```
9ddfc06
systemctl start acme-tiny
9ddfc06
```
9ddfc06
to run the service now.  The certificate should appear in `/var/lib/acme/certs`,
9ddfc06
and errors will be in journalctl.  Alternatively (and on EL6), run
9ddfc06
`/usr/libexec/acme-tiny/sign` as the acme user, and errors will go
9ddfc06
to your terminal.
9ddfc06
9ddfc06
## Use the certificate
9ddfc06
9ddfc06
The default httpd config uses a self-signed localhost certificate for https.
9ddfc06
Edit `/etc/httpd/conf.d/ssl.conf` and change `SSLCertificateFile` and
9ddfc06
`SSLCertificateChainFile` to `/var/lib/acme/certs/your.domain.crt` (or use a
9ddfc06
symlink to /etc/pki/tls/certs).  Change `SSLCertificateKeyFile` to
9ddfc06
`/etc/pki/tls/private/your.domain.key`.  
9ddfc06
9ddfc06
Obviously, you can change the locations to suit your sysadmin tastes.
9ddfc06
9ddfc06
Some SSL apps, like dovecot, require SSL certificates to be tagged in selinux.
9ddfc06
```
9ddfc06
semanage fcontext -a -f 'all files' -t cert_t '/var/lib/acme/certs(/.*)?'
9ddfc06
restorecon -rv /var/lib/acme/certs
9ddfc06
```
9ddfc06
The above will permanently change the selinux tag to work with dovecot
9ddfc06
and other apps.  
9ddfc06
9ddfc06
Sendmail is a special problem - it insists that any certificates it loads be
9ddfc06
only writable by root.  This is at odds with the privilege separation of the
9ddfc06
acme user.  (Obviously, the private key must be accessible only by root.)  You
9ddfc06
can, of course, copy the crt file to /etc/pki/tls/certs as root and change the
9ddfc06
mode.  But this has to be done every time the cert is renewed.  You can
9ddfc06
install `incron` to do this.  After installing, create `/etc/incron.d/acme`
9ddfc06
with the line
9ddfc06
```
9ddfc06
/var/lib/acme/certs/mail.crt IN_MOVED_TO cp $@ /etc/pki/tls/certs
9ddfc06
```
9ddfc06
where `mail.crt` is the certificate sendmail will use.  Sendmail
9ddfc06
can then load it from /etc/pki/tls/certs and be happy.  This also
9ddfc06
solves the file context problem if you add lines for other certificates.
9ddfc06
You might wonder why we don't simply supply an acme incrontab as part
9ddfc06
of the package with a wildcard, for example:
9ddfc06
```
9ddfc06
/var/lib/acme/certs/*.crt IN_MOVED_TO cp $@ /etc/pki/tls/certs
9ddfc06
```
9ddfc06
The answer is that incron is insecure, and very nasty things can be
9ddfc06
done by putting shell meta characters (including semicolon and quote!) in
9ddfc06
filenames that then become part of a command run as root.  The first example
9ddfc06
above uses a fixed filename, so that is safe.  Complain to incron
9ddfc06
upstream - they need an option to use a simple execvpe instead of
9ddfc06
using the shell.  Then it would at least be possible to carefully
9ddfc06
handle [malicious names](https://www.xkcd.com/327/).  
9ddfc06
880c508
## Logging and Error Reporting
880c508
880c508
On EL6, cron will email the acme user when certs are signed or errors
880c508
are encountered.  Under systemd, errors and certs signed are logged 
880c508
with the acme-tiny syslog identifier.
880c508
9ddfc06
## Virtual Hosts
9ddfc06
9ddfc06
Most web servers can handle multiple logical web hosts - configuring that is
9ddfc06
beyond the scope of this document.  Each virtual host may need to have its own
9ddfc06
certificate for SSL.  They can all share the same key file (see above for
9ddfc06
how to use an existing key for certificate requests), or use different keys.
9ddfc06
Put all the CSRs in /var/lib/acme/csr and the acme-tiny service will keep them
9ddfc06
all renewed.  This also works for certificates used by other SSL applications,
9ddfc06
such as dovecot, sendmail, jabberd, or znc.