From 9ddfc067227fde57feb094f78bb4b29cedd08cdf Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 6 Oct 2016 13:33:56 -0400 Subject: [PATCH 01/61] Initial fedora-scm import --- .gitignore | 1 + README-fedora.md | 133 +++++++++++++++++++++++ acme-tiny-chain.patch | 115 ++++++++++++++++++++ acme-tiny-sign.sh | 39 +++++++ acme-tiny.cron | 3 + acme-tiny.service | 15 +++ acme-tiny.spec | 181 +++++++++++++++++++++++++++++++ acme-tiny.timer | 13 +++ acme.conf | 17 +++ cert-check.py | 66 +++++++++++ lets-encrypt-x3-cross-signed.pem | 27 +++++ sources | 1 + 12 files changed, 611 insertions(+) create mode 100644 README-fedora.md create mode 100644 acme-tiny-chain.patch create mode 100644 acme-tiny-sign.sh create mode 100644 acme-tiny.cron create mode 100644 acme-tiny.service create mode 100644 acme-tiny.spec create mode 100644 acme-tiny.timer create mode 100644 acme.conf create mode 100644 cert-check.py create mode 100644 lets-encrypt-x3-cross-signed.pem diff --git a/.gitignore b/.gitignore index e69de29..352cd74 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/acme-tiny-5a7b4e7.tar.gz diff --git a/README-fedora.md b/README-fedora.md new file mode 100644 index 0000000..ecfc538 --- /dev/null +++ b/README-fedora.md @@ -0,0 +1,133 @@ +# acme-tiny Fedora package + +The Fedora package for acme-tiny adds a tiny framework to make issuing +and renewing [Let's Encrypt](https://letsencrypt.org/) certificates +convenient. It does *not* alter your configuration in any way, other +than to drop an acme.conf apache config snippet into `/etc/httpd/conf.d` +and provide a systemd service. + +If you want a package that tries to do everything for you as root, +consider the `certbot` package. + +The ACME protocol will work with other certificate authorities, but +acme-tiny is currently hardwired to use letencrypt.org - which is +also currently the only ACME certificate authority recognized in +most browsers. + +These instructions assume you are using letsencrypt for the first time +with this acme-tiny package. For example, you should not already have +an account key for the domains it will manage. If you do, see README.md +for instructions on converting it. Put any existing account key in +PEM format in `/var/lib/acme/private`, readable by the acme user (only!). + +## The web server must already serve your domains on HTTP + +If you cannot access your web domains locally with commands like +`curl` and `wget`, then this framework won't work. Acme-tiny will work with +any web server package, but if you are not using apache (httpd package), you +must provide the equivalent of `/etc/httpd/conf.d/acme.conf` to map +`/var/www/challenges` to the ACME URL location. The web server can even +be on a remote machine - provided you have somehow arranged for it to +serve files from `/var/www/challenges` (perhaps via NFS). + +If you are using Apache, and restrict access to ``, then this +will override the acme.conf global config snippet, and you must explicitly +make the ACME URL (http://your.domain.here/.well-known/acme-challenge/) +publicly accessible. + +## Put your CSRs in `/var/lib/acme/csr` + +You can use existing CSRs, or generate a new one using openssl. Put +all CSRs to be issued and renewed by acme-tiny in `/var/lib/acme/csr`. +I like to symlink the CSRs into /var/lib/acme/csr, just make sure the acme +user can read them (and follow the symlink). The details for openssl are +beyond the scope of this documentation, but this should work for creating a +certificate for a single domain: +``` +cd /etc/pki/tls +ln -s /var/lib/acme/csr . +openssl req -new -nodes -keyout private/your.domain.key \ + -out csr/your.domain.csr +chmod 0400 private/your.domain.key +``` +If you have an existing key, replace `-nodes -keyout` with `-key`. +The default openssl config will ask you for data, be sure to give the +domain you will be serving when it asks for "Common Name". It is possible +to cover multiple domains with a single certificate using openssl. First, add +a section to the end of `/etc/pki/tls/openssl.cnf` defining your extension: +``` +[MYSERV] +subjectAltName=DNS:your.domain,DNS:www.your.domain +``` +Then add `-reqexts MYSERV` to the openssl command line. One of the domains +must match the common name. + +Make sure the CSR can be read by the acme user. + +## Issue the certificate + +The timer service in acme-tiny will check the certificate for all CSRs in csr +every 24 hours, and issue or renew the certificate if it is missing or about to +expire (in 7 days by default). You don't have to wait for the timer, however. +Use +``` +systemctl start acme-tiny +``` +to run the service now. The certificate should appear in `/var/lib/acme/certs`, +and errors will be in journalctl. Alternatively (and on EL6), run +`/usr/libexec/acme-tiny/sign` as the acme user, and errors will go +to your terminal. + +## Use the certificate + +The default httpd config uses a self-signed localhost certificate for https. +Edit `/etc/httpd/conf.d/ssl.conf` and change `SSLCertificateFile` and +`SSLCertificateChainFile` to `/var/lib/acme/certs/your.domain.crt` (or use a +symlink to /etc/pki/tls/certs). Change `SSLCertificateKeyFile` to +`/etc/pki/tls/private/your.domain.key`. + +Obviously, you can change the locations to suit your sysadmin tastes. + +Some SSL apps, like dovecot, require SSL certificates to be tagged in selinux. +``` +semanage fcontext -a -f 'all files' -t cert_t '/var/lib/acme/certs(/.*)?' +restorecon -rv /var/lib/acme/certs +``` +The above will permanently change the selinux tag to work with dovecot +and other apps. + +Sendmail is a special problem - it insists that any certificates it loads be +only writable by root. This is at odds with the privilege separation of the +acme user. (Obviously, the private key must be accessible only by root.) You +can, of course, copy the crt file to /etc/pki/tls/certs as root and change the +mode. But this has to be done every time the cert is renewed. You can +install `incron` to do this. After installing, create `/etc/incron.d/acme` +with the line +``` +/var/lib/acme/certs/mail.crt IN_MOVED_TO cp $@ /etc/pki/tls/certs +``` +where `mail.crt` is the certificate sendmail will use. Sendmail +can then load it from /etc/pki/tls/certs and be happy. This also +solves the file context problem if you add lines for other certificates. +You might wonder why we don't simply supply an acme incrontab as part +of the package with a wildcard, for example: +``` +/var/lib/acme/certs/*.crt IN_MOVED_TO cp $@ /etc/pki/tls/certs +``` +The answer is that incron is insecure, and very nasty things can be +done by putting shell meta characters (including semicolon and quote!) in +filenames that then become part of a command run as root. The first example +above uses a fixed filename, so that is safe. Complain to incron +upstream - they need an option to use a simple execvpe instead of +using the shell. Then it would at least be possible to carefully +handle [malicious names](https://www.xkcd.com/327/). + +## Virtual Hosts + +Most web servers can handle multiple logical web hosts - configuring that is +beyond the scope of this document. Each virtual host may need to have its own +certificate for SSL. They can all share the same key file (see above for +how to use an existing key for certificate requests), or use different keys. +Put all the CSRs in /var/lib/acme/csr and the acme-tiny service will keep them +all renewed. This also works for certificates used by other SSL applications, +such as dovecot, sendmail, jabberd, or znc. diff --git a/acme-tiny-chain.patch b/acme-tiny-chain.patch new file mode 100644 index 0000000..17e46b9 --- /dev/null +++ b/acme-tiny-chain.patch @@ -0,0 +1,115 @@ +diff -up ./acme_tiny.py.chain ./acme_tiny.py +--- ./acme_tiny.py.chain 2016-08-01 15:53:22.000000000 -0400 ++++ ./acme_tiny.py 2016-08-22 19:20:51.208523709 -0400 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/python + import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging + try: + from urllib.request import urlopen # Python 3 +@@ -12,7 +12,7 @@ LOGGER = logging.getLogger(__name__) + LOGGER.addHandler(logging.StreamHandler()) + LOGGER.setLevel(logging.INFO) + +-def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA): ++def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA, chain=False): + # helper function base64 encode for jose spec + def _b64(b): + return base64.urlsafe_b64encode(b).decode('utf8').replace("=", "") +@@ -57,9 +57,9 @@ def get_crt(account_key, csr, acme_dir, + }) + try: + resp = urlopen(url, data.encode('utf8')) +- return resp.getcode(), resp.read() ++ return resp.getcode(), resp.read(), resp.info() + except IOError as e: +- return getattr(e, "code", None), getattr(e, "read", e.__str__)() ++ return getattr(e, "code", None), getattr(e, "read", e.__str__)(), None + + # find domains + log.info("Parsing CSR...") +@@ -80,7 +80,7 @@ def get_crt(account_key, csr, acme_dir, + + # get the certificate domains and expiration + log.info("Registering account...") +- code, result = _send_signed_request(CA + "/acme/new-reg", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-reg", { + "resource": "new-reg", + "agreement": "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", + }) +@@ -96,7 +96,7 @@ def get_crt(account_key, csr, acme_dir, + log.info("Verifying {0}...".format(domain)) + + # get new challenge +- code, result = _send_signed_request(CA + "/acme/new-authz", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-authz", { + "resource": "new-authz", + "identifier": {"type": "dns", "value": domain}, + }) +@@ -123,7 +123,7 @@ def get_crt(account_key, csr, acme_dir, + wellknown_path, wellknown_url)) + + # notify challenge are met +- code, result = _send_signed_request(challenge['uri'], { ++ code, result, headers = _send_signed_request(challenge['uri'], { + "resource": "challenge", + "keyAuthorization": keyauthorization, + }) +@@ -153,17 +153,32 @@ def get_crt(account_key, csr, acme_dir, + proc = subprocess.Popen(["openssl", "req", "-in", csr, "-outform", "DER"], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + csr_der, err = proc.communicate() +- code, result = _send_signed_request(CA + "/acme/new-cert", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-cert", { + "resource": "new-cert", + "csr": _b64(csr_der), + }) + if code != 201: + raise ValueError("Error signing certificate: {0} {1}".format(code, result)) + ++ certchain = [result] ++ if chain: ++ def parse_link_header(line): ++ m = re.search(r"^Link:\s*<([^>]*)>(?:\s*;\s*(.*))?\r\n$", line) ++ return (m.group(1), dict([(a[0],a[1].strip('"')) ++ for a in [attr.split("=") ++ for attr in m.group(2).split("\s*;\s*")]])) ++ ++ up = [ ++ link for link, attr in [ ++ parse_link_header(l) for l in headers.getallmatchingheaders("Link") ++ ] if attr['rel'] == 'up' ++ ] ++ certchain += [urlopen(url).read() for url in up] ++ + # return signed certificate! + log.info("Certificate signed!") +- return """-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( +- "\n".join(textwrap.wrap(base64.b64encode(result).decode('utf8'), 64))) ++ return "".join(["""-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( ++ "\n".join(textwrap.wrap(base64.b64encode(cert).decode('utf8'), 64))) for cert in certchain]) + + def main(argv): + parser = argparse.ArgumentParser( +@@ -188,11 +203,19 @@ def main(argv): + parser.add_argument("--acme-dir", required=True, help="path to the .well-known/acme-challenge/ directory") + parser.add_argument("--quiet", action="store_const", const=logging.ERROR, help="suppress output except for errors") + parser.add_argument("--ca", default=DEFAULT_CA, help="certificate authority, default is Let's Encrypt") ++ parser.add_argument("--chain", action="store_true", ++ help="fetch and append intermediate certs to output") + + args = parser.parse_args(argv) + LOGGER.setLevel(args.quiet or LOGGER.level) +- signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca) +- sys.stdout.write(signed_crt) ++ try: ++ signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, ++ log=LOGGER, CA=args.ca, chain=args.chain) ++ sys.stdout.write(signed_crt) ++ except Exception as e: ++ #if not args.quiet: raise e ++ LOGGER.error(e) ++ sys.exit(1) + + if __name__ == "__main__": # pragma: no cover + main(sys.argv[1:]) diff --git a/acme-tiny-sign.sh b/acme-tiny-sign.sh new file mode 100644 index 0000000..c3005b3 --- /dev/null +++ b/acme-tiny-sign.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +if test "$(id -u)" -eq 0; then + echo "Do not run as root!" + exit 2 +fi + +DAYS="${1:-7}" + +cd /var/lib/acme + +if ! test -s private/account.key; then + touch private/account.key + chmod 0600 private/account.key + openssl genrsa 4096 >private/account.key +fi + +for csr in csr/*.csr; do + test -s "$csr" || continue + test -r "$csr" || continue + crt="${csr%%.csr}" + tmp="certs/${crt##csr/}.tmp" + crt="certs/${crt##csr/}.crt" + if test -s "$crt" && /usr/sbin/cert-check --days="$DAYS" "$crt"; then + continue + fi + test -w "$crt" || test ! -e "$crt" || continue + echo acme_tiny --account-key private/account.key --csr "$csr" \ + --acme-dir /var/www/challenges/ --chain --out "$crt" + + if /usr/sbin/acme_tiny --account-key private/account.key --csr "$csr" \ + --acme-dir /var/www/challenges/ --chain > "$tmp"; then + mv "$tmp" "$crt" + else + test -e "$tmp" && test ! -s "$tmp" && rm "$tmp" + fi + # append intermediate certs + #cat *.pem >>"$crt" +done diff --git a/acme-tiny.cron b/acme-tiny.cron new file mode 100644 index 0000000..206fd39 --- /dev/null +++ b/acme-tiny.cron @@ -0,0 +1,3 @@ +# Check daily for csrs in /var/lib/acme/csr that need signing or renewing +# within 7 days. +31 2 * * * acme /usr/libexec/acme-tiny/sign 7 diff --git a/acme-tiny.service b/acme-tiny.service new file mode 100644 index 0000000..a9bedfc --- /dev/null +++ b/acme-tiny.service @@ -0,0 +1,15 @@ +[Unit] +Description=Check for acme certs about to expire + +[Service] +Type=oneshot +Nice=19 +ProtectHome=true +ProtectSystem=true +User=acme +Group=acme +SyslogIdentifier=acme-tiny +ExecStart=/usr/libexec/acme-tiny/sign 7 + +[Install] +Also=acme-tiny.timer diff --git a/acme-tiny.spec b/acme-tiny.spec new file mode 100644 index 0000000..12054ee --- /dev/null +++ b/acme-tiny.spec @@ -0,0 +1,181 @@ +%global commit 5a7b4e79bc9bd5b51739c0d8aaf644f62cc440e6 +%global shortcommit 5a7b4e7 + +%if 0%{?rhel} >= 5 && 0%{?rhel} < 7 +%global use_systemd 0 +%else +%global use_systemd 1 +%endif + +%if 0%{?fedora} +# Explicity require python3 on Fedora to help track which packages +# no longer need python2. +%global use_python3 1 +%else +%global use_python3 0 +%endif + +Name: acme-tiny +Version: 0.1 +Release: 10.git%{shortcommit}%{?dist} +Summary: Tiny auditable script to issue, renew Let's Encrypt certificates + +Group: Applications/Internet +License: MIT +URL: https://github.com/diafygi/acme-tiny +Source0: https://github.com/diafygi/%{name}/archive/%{commit}.tar.gz#/%{name}-%{shortcommit}.tar.gz +Source1: acme-tiny-sign.sh +Source2: cert-check.py +Source3: acme.conf +Source4: lets-encrypt-x3-cross-signed.pem +Source5: acme-tiny.cron +Source6: acme-tiny.timer +Source7: acme-tiny.service +Source8: README-fedora.md +# Fetch and include intermediate cert(s), too. +Patch0: acme-tiny-chain.patch + +Requires: openssl +Requires(pre): shadow-utils +%if %{use_systemd} +# systemd macros are not defined unless systemd is present +BuildRequires: systemd +%{?systemd_requires} +%else +Requires: cronie +%endif +BuildArch: noarch +%if 0%{?fedora} > 22 +Suggests: httpd, mod_ssl, nginx +Enhances: httpd, mod_ssl, nginx +%endif + +%description +This is a tiny, auditable script that you can throw on your server to issue and +renew Let's Encrypt certificates. Since it has to be run on your server and +have access to your private Let's Encrypt account key, I tried to make it as +tiny as possible (currently less than 200 lines). The only prerequisites are +python and openssl. + +Well, that and a web server - but then you only need this with a web server. +This package adds a simple directory layout and timer service that runs +acme_tiny on installed CSRs as the acme user for privilege separation. + +%prep +%setup -q -n %{name}-%{commit} +%patch0 -p1 -b .chain +cp -p %{SOURCE1} %{SOURCE2} %{SOURCE8} . +%if %{use_python3} +sed -i.old -e '1,1 s/python$/python3/' *.py +%endif + +%build + +%install +mkdir -p %{buildroot}/var/www/challenges +mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d +mkdir -p %{buildroot}%{_sbindir} +mkdir -p %{buildroot}%{_libexecdir}/%{name} +mkdir -p %{buildroot}%{_sharedstatedir}/acme/{private,csr,certs} +chmod 0700 %{buildroot}%{_sharedstatedir}/acme/private + +install -m 0755 acme-tiny-sign.sh %{buildroot}%{_libexecdir}/%{name}/sign +install -m 0755 acme_tiny.py %{buildroot}%{_sbindir}/acme_tiny +ln -sf acme_tiny %{buildroot}%{_sbindir}/acme-tiny +ln -sf %{_libexecdir}/%{name}/sign %{buildroot}%{_sbindir}/acme-tiny-sign +install -m 0755 cert-check.py %{buildroot}%{_sbindir}/cert-check +install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/httpd/conf.d +install -m 0644 %{SOURCE4} %{buildroot}%{_sharedstatedir}/acme +%if %{use_systemd} +mkdir -p %{buildroot}%{_unitdir} +install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} +install -pm 644 %{SOURCE7} %{buildroot}%{_unitdir} +%else +mkdir -p %{buildroot}%{_sysconfdir}/cron.d +install -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/cron.d/acme-tiny +%endif + +%pre +getent group acme > /dev/null || groupadd -r acme +getent passwd acme > /dev/null || /usr/sbin/useradd -g acme \ + -c "Tiny Auditable ACME Client" \ + -r -d %{_sharedstatedir}/acme -s /sbin/nologin acme +exit 0 + +%if %{use_systemd} + +%post +%systemd_post acme-tiny.service acme-tiny.timer + +%postun +%systemd_postun_with_restart acme-tiny.service acme-tiny.timer + +%preun +%systemd_preun acme-tiny.service acme-tiny.timer + +%endif + +%files +%{!?_licensedir:%global license %%doc} +%license LICENSE +%doc README.md README-fedora.md +%attr(0755,acme,acme) /var/www/challenges +%attr(-,acme,acme) %{_sharedstatedir}/acme +%{_libexecdir}/%{name} +%config(noreplace) %{_sysconfdir}/httpd/conf.d/acme.conf +%if %{use_systemd} +%{_unitdir}/* +%else +%config(noreplace) %{_sysconfdir}/cron.d/acme-tiny +%endif +/usr/sbin/acme_tiny +/usr/sbin/acme-tiny +/usr/sbin/acme-tiny-sign +/usr/sbin/cert-check + +%changelog +* Mon Aug 22 2016 Stuart D. Gathman 0.1-10 +- Fix cert writable check in sign script +- More tips in README-fedora.md + +* Mon Aug 22 2016 Stuart D. Gathman 0.1-9 +- Use %%{systemd_requires} +- Remove unneeded cronie, python dependencies +- Add acme-tiny.timer to systemd scriptlets +- Add README-fedora.md +- acme_tiny: Fix --chain patch for python2.6 (el6) +- acme_tiny: Suppress traceback on error + +* Sun Aug 21 2016 Stuart D. Gathman 0.1-8 +- Add use_systemd flag to use systemd timer and enable on Fedora and epel7 +- Enable use_python3 flag for Fedora (but not epel7). + +* Sat Aug 20 2016 Stuart D. Gathman 0.1-7 +- sign: Actually use the new --chain flag +- cron: Make days to expiration explicit +- spec: Set file modes with install +- acme.conf: mark as config + +* Fri Aug 19 2016 Stuart D. Gathman 0.1-6 +- Python3 fixes for cert-check +- acme-tiny: Update patch to leave default behavior unchanged +- make /var/lib/acme readable by all except private + +* Thu Aug 11 2016 Stuart D. Gathman 0.1-5 +- sign: Use tmp output to avoid wiping existing cert on error +- acme_tiny: get intermediate cert from acme protocol + +* Thu Aug 11 2016 Stuart D. Gathman 0.1-4 +- Fix path of acme_tiny and make days explicit in sign script +- Add crontab + +* Wed Aug 10 2016 Stuart D. Gathman 0.1-3 +- Add global acme httpd conf +- Append intermediate certs, add current lets-encrypt intermediate cert + +* Tue Aug 9 2016 Stuart D. Gathman 0.1-2 +- add private, csr, certs directories +- add sign script suitable for cron + +* Mon Aug 8 2016 Stuart D. Gathman 0.1-1 +- Initial RPM diff --git a/acme-tiny.timer b/acme-tiny.timer new file mode 100644 index 0000000..687c820 --- /dev/null +++ b/acme-tiny.timer @@ -0,0 +1,13 @@ +[Unit] +Description=check for acme certs about to expire and renew them +ConditionKernelCommandLine=!rd.live.image +After=network-online.target +After=httpd.service nginx.service + +[Timer] +OnBootSec=20min +OnUnitInactiveSec=24h +Unit=acme-tiny.service + +[Install] +WantedBy=timers.target diff --git a/acme.conf b/acme.conf new file mode 100644 index 0000000..3768c5c --- /dev/null +++ b/acme.conf @@ -0,0 +1,17 @@ +Alias /.well-known/acme-challenge/ "/var/www/challenges/" + +# Note, blocking access to in a will override +# these global permissions. You will need to modify those domains +# to allow access to /.well-known/, or just copy the from below. +# See: http://httpd.apache.org/docs/2.2/sections.html + + + Options -Indexes + Order allow,deny + Allow from all + + + Options -Indexes + Order allow,deny + Allow from all + diff --git a/cert-check.py b/cert-check.py new file mode 100644 index 0000000..89f545c --- /dev/null +++ b/cert-check.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +from __future__ import print_function +from sys import stderr + +import subprocess, time, calendar, os, getopt + +def usage(): + print("""Usage: cert-check [options] files ... + -h,--help this message + -q,--quiet do not print cert files needing (re)newing + -d n,--days=n days before expiration to renew (default 7) +Succeeds only if all certs exist and are more than from expiration.""", + file=stderr) + return 2 + +def main(argv): + days = 7 # days ahead to + quiet = False + + try: + opts,args = getopt.getopt(argv,'hqd:',['days=','quiet','help']) + except getopt.GetoptError as err: + # print help information and exit: + print(err,file=stderr) # prints something like "option -a not recognized" + return usage() + + for opt,val in opts: + if opt in ('-h','--help'): + return usage() + if opt in ('-q','--quiet'): + quiet = True + if opt in ('-d','--days'): + try: + days = int(val) + except: + return usage() + + now = time.time() + soon = now + days * 24 * 60 * 60 + rc = 0 + + for fn in args: + try: + size = os.path.getsize(fn) + except: + size = 0 + if size == 0: + if not quiet: print(fn) + rc += 1 + continue + proc = subprocess.Popen( + ["openssl", "x509", "-in", fn, "-noout", "-enddate"], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = proc.communicate() + if proc.returncode != 0: + raise IOError("{1}: OpenSSL Error: {0}".format(err,fn)) + t = time.strptime(out.decode(),'notAfter=%b %d %H:%M:%S %Y GMT\n') + t = calendar.timegm(t) + if soon > t: + if not quiet: print(fn) + rc += 1 + return rc > 0 + +if __name__ == '__main__': + import sys + sys.exit(main(sys.argv[1:])) diff --git a/lets-encrypt-x3-cross-signed.pem b/lets-encrypt-x3-cross-signed.pem new file mode 100644 index 0000000..0002462 --- /dev/null +++ b/lets-encrypt-x3-cross-signed.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow +SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT +GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF +q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 +SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 +Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA +a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj +/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T +AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG +CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv +bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k +c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw +VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC +ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz +MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu +Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF +AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo +uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ +wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu +X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG +PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 +KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== +-----END CERTIFICATE----- diff --git a/sources b/sources index e69de29..6e92207 100644 --- a/sources +++ b/sources @@ -0,0 +1 @@ +c18d4e5cceae3a01aae4fb2d1aa93d73 acme-tiny-5a7b4e7.tar.gz From aed9609bd396710274572da20ee1ff16538b403f Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 6 Oct 2016 13:51:30 -0400 Subject: [PATCH 02/61] Fix tabs/spaces rpmlint complaint --- acme-tiny.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 12054ee..80457eb 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -88,8 +88,8 @@ install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/httpd/conf.d install -m 0644 %{SOURCE4} %{buildroot}%{_sharedstatedir}/acme %if %{use_systemd} mkdir -p %{buildroot}%{_unitdir} -install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} -install -pm 644 %{SOURCE7} %{buildroot}%{_unitdir} +install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} +install -pm 644 %{SOURCE7} %{buildroot}%{_unitdir} %else mkdir -p %{buildroot}%{_sysconfdir}/cron.d install -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/cron.d/acme-tiny From 74353918263287f12ab84665356c3acdbd6fa15c Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 6 Oct 2016 16:53:41 -0400 Subject: [PATCH 03/61] add checkout date --- acme-tiny.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 80457eb..2f08eb7 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -1,5 +1,6 @@ %global commit 5a7b4e79bc9bd5b51739c0d8aaf644f62cc440e6 %global shortcommit 5a7b4e7 +%global checkout 20160810git%{shortcommit} %if 0%{?rhel} >= 5 && 0%{?rhel} < 7 %global use_systemd 0 @@ -17,7 +18,7 @@ Name: acme-tiny Version: 0.1 -Release: 10.git%{shortcommit}%{?dist} +Release: 10.%{checkout}%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet @@ -134,11 +135,11 @@ exit 0 /usr/sbin/cert-check %changelog -* Mon Aug 22 2016 Stuart D. Gathman 0.1-10 +* Mon Aug 22 2016 Stuart D. Gathman 0.1-10.2016git5a7b4e7 - Fix cert writable check in sign script - More tips in README-fedora.md -* Mon Aug 22 2016 Stuart D. Gathman 0.1-9 +* Mon Aug 22 2016 Stuart D. Gathman 0.1-9.2016git5a7b4e7 - Use %%{systemd_requires} - Remove unneeded cronie, python dependencies - Add acme-tiny.timer to systemd scriptlets From 8d1d6876f86418f096a2403c09754080bbce0909 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 6 Oct 2016 18:06:22 -0400 Subject: [PATCH 04/61] Forgot month and day on changelog checkouts. --- acme-tiny.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 2f08eb7..15328de 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -135,11 +135,11 @@ exit 0 /usr/sbin/cert-check %changelog -* Mon Aug 22 2016 Stuart D. Gathman 0.1-10.2016git5a7b4e7 +* Mon Aug 22 2016 Stuart D. Gathman 0.1-10.20160810git5a7b4e7 - Fix cert writable check in sign script - More tips in README-fedora.md -* Mon Aug 22 2016 Stuart D. Gathman 0.1-9.2016git5a7b4e7 +* Mon Aug 22 2016 Stuart D. Gathman 0.1-9.20160810git5a7b4e7 - Use %%{systemd_requires} - Remove unneeded cronie, python dependencies - Add acme-tiny.timer to systemd scriptlets From 80c0679eb39cb1c3ed136f5cf3b20cefdf501e4d Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Mon, 10 Oct 2016 22:21:32 -0400 Subject: [PATCH 05/61] acme-tiny included twice in %files --- acme-tiny.spec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 15328de..21e052c 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -46,7 +46,7 @@ BuildRequires: systemd Requires: cronie %endif BuildArch: noarch -%if 0%{?fedora} > 22 +%if 0%{?fedora} Suggests: httpd, mod_ssl, nginx Enhances: httpd, mod_ssl, nginx %endif @@ -129,7 +129,6 @@ exit 0 %else %config(noreplace) %{_sysconfdir}/cron.d/acme-tiny %endif -/usr/sbin/acme_tiny /usr/sbin/acme-tiny /usr/sbin/acme-tiny-sign /usr/sbin/cert-check From 1eacdf0a6f37337a77ab9e14dc569b98477734b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 19 Dec 2016 18:20:36 +0100 Subject: [PATCH 06/61] Rebuild for Python 3.6 --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 2f08eb7..8fa23f7 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -18,7 +18,7 @@ Name: acme-tiny Version: 0.1 -Release: 10.%{checkout}%{?dist} +Release: 11.%{checkout}%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet @@ -135,6 +135,9 @@ exit 0 /usr/sbin/cert-check %changelog +* Mon Dec 19 2016 Miro Hrončok - 0.1-11.20160810git5a7b4e7 +- Rebuild for Python 3.6 + * Mon Aug 22 2016 Stuart D. Gathman 0.1-10.2016git5a7b4e7 - Fix cert writable check in sign script - More tips in README-fedora.md From 9b5f08321c10113428eb03cdf7b8a79d5c6895ab Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Mon, 2 Jan 2017 22:50:07 -0500 Subject: [PATCH 07/61] Fix for BZ#1409686, revert 80c06 (acme_tiny != acme-tiny) --- acme-tiny-chain.patch | 4 ++-- acme-tiny.spec | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/acme-tiny-chain.patch b/acme-tiny-chain.patch index 17e46b9..6669364 100644 --- a/acme-tiny-chain.patch +++ b/acme-tiny-chain.patch @@ -70,14 +70,14 @@ diff -up ./acme_tiny.py.chain ./acme_tiny.py + certchain = [result] + if chain: + def parse_link_header(line): -+ m = re.search(r"^Link:\s*<([^>]*)>(?:\s*;\s*(.*))?\r\n$", line) ++ m = re.search(r"^<([^>]*)>(?:\s*;\s*(.*))?$", line) + return (m.group(1), dict([(a[0],a[1].strip('"')) + for a in [attr.split("=") + for attr in m.group(2).split("\s*;\s*")]])) + + up = [ + link for link, attr in [ -+ parse_link_header(l) for l in headers.getallmatchingheaders("Link") ++ parse_link_header(l) for l in headers.get_all("Link") + ] if attr['rel'] == 'up' + ] + certchain += [urlopen(url).read() for url in up] diff --git a/acme-tiny.spec b/acme-tiny.spec index 21e052c..06c6321 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -129,11 +129,15 @@ exit 0 %else %config(noreplace) %{_sysconfdir}/cron.d/acme-tiny %endif +/usr/sbin/acme_tiny /usr/sbin/acme-tiny /usr/sbin/acme-tiny-sign /usr/sbin/cert-check %changelog +* Mon Jan 2 2017 Stuart D. Gathman 0.1-11.20160810git5a7b4e7 +- BZ#1409686 Message.getallmatchingheaders() is broken in python3. + * Mon Aug 22 2016 Stuart D. Gathman 0.1-10.20160810git5a7b4e7 - Fix cert writable check in sign script - More tips in README-fedora.md From d0dda28f927d1c1e5ab9bc585e45d791a2f0185a Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 10 Feb 2017 05:43:19 +0000 Subject: [PATCH 08/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 25b3eca..23897b7 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -18,7 +18,7 @@ Name: acme-tiny Version: 0.1 -Release: 11.%{checkout}%{?dist} +Release: 12.%{checkout}%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet @@ -135,6 +135,9 @@ exit 0 /usr/sbin/cert-check %changelog +* Fri Feb 10 2017 Fedora Release Engineering - 0.1-12.20160810git5a7b4e7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + * Mon Jan 2 2017 Stuart D. Gathman 0.1-12.20160810git5a7b4e7 - BZ#1409686 Message.getallmatchingheaders() is broken in python3. From 3bb45ece6237205a91154f5238f15696812db5ad Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 6 Jul 2017 20:06:13 -0400 Subject: [PATCH 09/61] Move to new commit --- .gitignore | 1 + acme-tiny.spec | 6 +++--- sources | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 352cd74..38b8735 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /acme-tiny-5a7b4e7.tar.gz +/acme-tiny-af025f5.tar.gz diff --git a/acme-tiny.spec b/acme-tiny.spec index 25b3eca..94ef702 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -1,6 +1,6 @@ -%global commit 5a7b4e79bc9bd5b51739c0d8aaf644f62cc440e6 -%global shortcommit 5a7b4e7 -%global checkout 20160810git%{shortcommit} +%global commit af025f5bf19c70be7fafab67f4dd718ca7bf9adf +%global shortcommit af025f5 +%global checkout 20170516git%{shortcommit} %if 0%{?rhel} >= 5 && 0%{?rhel} < 7 %global use_systemd 0 diff --git a/sources b/sources index 6e92207..d2283a2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -c18d4e5cceae3a01aae4fb2d1aa93d73 acme-tiny-5a7b4e7.tar.gz +SHA512 (acme-tiny-af025f5.tar.gz) = b8d81f7b8fce6e21bcb3b5c5f5156c9c004cb05a9621bcf0aa4fe776dfbd0106cb0f9fa47db27198c91e8058a12aa748c944830e293fbfc43489a7fb46d38654 From 55e65660ca646a4d17a8549592370da9d67469bf Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 6 Jul 2017 20:14:17 -0400 Subject: [PATCH 10/61] Add prefix to source archive --- acme-tiny.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 94ef702..14fd96d 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -17,8 +17,8 @@ %endif Name: acme-tiny -Version: 0.1 -Release: 11.%{checkout}%{?dist} +Version: 0.2 +Release: 1.%{checkout}%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet @@ -135,6 +135,9 @@ exit 0 /usr/sbin/cert-check %changelog +* Thu Jul 6 2017 Stuart D. Gathman 0.2-1.20170616gitaf025f5 +- Update to new upstream version + * Mon Jan 2 2017 Stuart D. Gathman 0.1-12.20160810git5a7b4e7 - BZ#1409686 Message.getallmatchingheaders() is broken in python3. diff --git a/sources b/sources index d2283a2..c8b3be2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (acme-tiny-af025f5.tar.gz) = b8d81f7b8fce6e21bcb3b5c5f5156c9c004cb05a9621bcf0aa4fe776dfbd0106cb0f9fa47db27198c91e8058a12aa748c944830e293fbfc43489a7fb46d38654 +SHA512 (acme-tiny-af025f5.tar.gz) = 7203f6070d99bd232e5317340d2582dceebc58fc364c8d5499bfafe1603615df1193cc557ec951c3c4e04545260347b611e79496683a1baaa09ee24861a0b46d From 4911682efdb21f7a3686dec9a0f20b02675163f4 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 6 Jul 2017 20:21:03 -0400 Subject: [PATCH 11/61] Forgot trailing slash --- sources | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources b/sources index c8b3be2..2bc2674 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (acme-tiny-af025f5.tar.gz) = 7203f6070d99bd232e5317340d2582dceebc58fc364c8d5499bfafe1603615df1193cc557ec951c3c4e04545260347b611e79496683a1baaa09ee24861a0b46d +SHA512 (acme-tiny-af025f5.tar.gz) = e322bcdda859cca1afd9c3b8c707d33ee46e590a63a28346a3eaf76b2ef1961ea0cf8be1aabe600ddf5c47caef1d2972cdc50c693a42170fd7ddfe124db319e0 From 63d5d90d84469044adfc1ee253ab083259a98834 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 26 Jul 2017 02:33:41 +0000 Subject: [PATCH 12/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 1e07b62..e8245a6 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -18,7 +18,7 @@ Name: acme-tiny Version: 0.2 -Release: 1.%{checkout}%{?dist} +Release: 2.%{checkout}%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet @@ -135,6 +135,9 @@ exit 0 /usr/sbin/cert-check %changelog +* Wed Jul 26 2017 Fedora Release Engineering - 0.2-2.20170516gitaf025f5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + * Thu Jul 6 2017 Stuart D. Gathman 0.2-1.20170616gitaf025f5 - BZ#1468045 Update to new upstream version - BZ#1409686 Message.getallmatchingheaders() is broken in python3. From 880c508590a9b32b447b1c66a542b4d737029e65 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Wed, 22 Nov 2017 12:57:38 -0500 Subject: [PATCH 13/61] Release 0.2-3 --- README-fedora.md | 6 ++++++ acme-tiny-chain.patch | 13 ++++++++----- acme-tiny-sign.sh | 13 ++++++++++--- acme-tiny.spec | 11 ++++++++++- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/README-fedora.md b/README-fedora.md index ecfc538..775e524 100644 --- a/README-fedora.md +++ b/README-fedora.md @@ -122,6 +122,12 @@ upstream - they need an option to use a simple execvpe instead of using the shell. Then it would at least be possible to carefully handle [malicious names](https://www.xkcd.com/327/). +## Logging and Error Reporting + +On EL6, cron will email the acme user when certs are signed or errors +are encountered. Under systemd, errors and certs signed are logged +with the acme-tiny syslog identifier. + ## Virtual Hosts Most web servers can handle multiple logical web hosts - configuring that is diff --git a/acme-tiny-chain.patch b/acme-tiny-chain.patch index 6669364..20f53f8 100644 --- a/acme-tiny-chain.patch +++ b/acme-tiny-chain.patch @@ -1,9 +1,9 @@ diff -up ./acme_tiny.py.chain ./acme_tiny.py ---- ./acme_tiny.py.chain 2016-08-01 15:53:22.000000000 -0400 -+++ ./acme_tiny.py 2016-08-22 19:20:51.208523709 -0400 +--- ./acme_tiny.py.chain 2017-05-16 03:57:46.000000000 -0400 ++++ ./acme_tiny.py 2017-11-22 12:18:56.963653336 -0500 @@ -1,4 +1,4 @@ -#!/usr/bin/env python -+#!/usr/bin/python ++#!/usr/bin/python3 import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging try: from urllib.request import urlopen # Python 3 @@ -28,15 +28,18 @@ diff -up ./acme_tiny.py.chain ./acme_tiny.py # find domains log.info("Parsing CSR...") -@@ -80,7 +80,7 @@ def get_crt(account_key, csr, acme_dir, +@@ -80,9 +80,9 @@ def get_crt(account_key, csr, acme_dir, # get the certificate domains and expiration log.info("Registering account...") - code, result = _send_signed_request(CA + "/acme/new-reg", { + code, result, headers = _send_signed_request(CA + "/acme/new-reg", { "resource": "new-reg", - "agreement": "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", +- "agreement": "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", ++ "agreement": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf", }) + if code == 201: + log.info("Registered!") @@ -96,7 +96,7 @@ def get_crt(account_key, csr, acme_dir, log.info("Verifying {0}...".format(domain)) diff --git a/acme-tiny-sign.sh b/acme-tiny-sign.sh index c3005b3..93eda8a 100644 --- a/acme-tiny-sign.sh +++ b/acme-tiny-sign.sh @@ -15,6 +15,7 @@ if ! test -s private/account.key; then openssl genrsa 4096 >private/account.key fi +rc="0" for csr in csr/*.csr; do test -s "$csr" || continue test -r "$csr" || continue @@ -24,16 +25,22 @@ for csr in csr/*.csr; do if test -s "$crt" && /usr/sbin/cert-check --days="$DAYS" "$crt"; then continue fi - test -w "$crt" || test ! -e "$crt" || continue - echo acme_tiny --account-key private/account.key --csr "$csr" \ + if test -w "$crt" || test ! -e "$crt"; then + echo acme_tiny --account-key private/account.key --csr "$csr" \ --acme-dir /var/www/challenges/ --chain --out "$crt" + else + echo "Can't write to $crt" + rc="1" + continue + fi if /usr/sbin/acme_tiny --account-key private/account.key --csr "$csr" \ --acme-dir /var/www/challenges/ --chain > "$tmp"; then - mv "$tmp" "$crt" + mv "$tmp" "$crt" || exit 1 else test -e "$tmp" && test ! -s "$tmp" && rm "$tmp" fi # append intermediate certs #cat *.pem >>"$crt" done +exit "$rc" diff --git a/acme-tiny.spec b/acme-tiny.spec index e8245a6..231e55f 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -18,7 +18,7 @@ Name: acme-tiny Version: 0.2 -Release: 2.%{checkout}%{?dist} +Release: 3.%{checkout}%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet @@ -38,6 +38,10 @@ Patch0: acme-tiny-chain.patch Requires: openssl Requires(pre): shadow-utils +%if 0%{?rhel} >= 5 && 0%{?rhel} < 7 +# EL6 uses python2.6, which does not include argparse +Requires: python-argparse +%endif %if %{use_systemd} # systemd macros are not defined unless systemd is present BuildRequires: systemd @@ -135,6 +139,11 @@ exit 0 /usr/sbin/cert-check %changelog +* Wed Nov 22 2017 Stuart D. Gathman 0.2-3.20170616gitaf025f5 +- BZ#1507333 EL6 missing python-argparse dependency +- BZ#1515781 Agreement updated. +- BZ#1409345 Unwritable certs silently skipped + * Wed Jul 26 2017 Fedora Release Engineering - 0.2-2.20170516gitaf025f5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild From bce93d0d0c55b5f7a6a9c46ed1f385db675dfccb Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Wed, 22 Nov 2017 20:17:36 -0500 Subject: [PATCH 14/61] do not select python3 with chain patch --- acme-tiny-chain.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme-tiny-chain.patch b/acme-tiny-chain.patch index 20f53f8..5e681d9 100644 --- a/acme-tiny-chain.patch +++ b/acme-tiny-chain.patch @@ -3,7 +3,7 @@ diff -up ./acme_tiny.py.chain ./acme_tiny.py +++ ./acme_tiny.py 2017-11-22 12:18:56.963653336 -0500 @@ -1,4 +1,4 @@ -#!/usr/bin/env python -+#!/usr/bin/python3 ++#!/usr/bin/python import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging try: from urllib.request import urlopen # Python 3 From 651e6647bb34ecf225e871ae47249dd1bd00395f Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Wed, 22 Nov 2017 20:55:53 -0500 Subject: [PATCH 15/61] Revert to python2 --- acme-tiny-chain2.patch | 118 +++++++++++++++++++++++++++++++++++++++++ acme-tiny.spec | 6 ++- 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 acme-tiny-chain2.patch diff --git a/acme-tiny-chain2.patch b/acme-tiny-chain2.patch new file mode 100644 index 0000000..1c46c7d --- /dev/null +++ b/acme-tiny-chain2.patch @@ -0,0 +1,118 @@ +diff -up ./acme_tiny.py.chain ./acme_tiny.py +--- ./acme_tiny.py.chain 2017-05-16 03:57:46.000000000 -0400 ++++ ./acme_tiny.py 2017-11-22 15:14:19.270485351 -0500 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/python + import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging + try: + from urllib.request import urlopen # Python 3 +@@ -12,7 +12,7 @@ LOGGER = logging.getLogger(__name__) + LOGGER.addHandler(logging.StreamHandler()) + LOGGER.setLevel(logging.INFO) + +-def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA): ++def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA, chain=False): + # helper function base64 encode for jose spec + def _b64(b): + return base64.urlsafe_b64encode(b).decode('utf8').replace("=", "") +@@ -57,9 +57,9 @@ def get_crt(account_key, csr, acme_dir, + }) + try: + resp = urlopen(url, data.encode('utf8')) +- return resp.getcode(), resp.read() ++ return resp.getcode(), resp.read(), resp.info() + except IOError as e: +- return getattr(e, "code", None), getattr(e, "read", e.__str__)() ++ return getattr(e, "code", None), getattr(e, "read", e.__str__)(), None + + # find domains + log.info("Parsing CSR...") +@@ -80,9 +80,9 @@ def get_crt(account_key, csr, acme_dir, + + # get the certificate domains and expiration + log.info("Registering account...") +- code, result = _send_signed_request(CA + "/acme/new-reg", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-reg", { + "resource": "new-reg", +- "agreement": "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", ++ "agreement": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf", + }) + if code == 201: + log.info("Registered!") +@@ -96,7 +96,7 @@ def get_crt(account_key, csr, acme_dir, + log.info("Verifying {0}...".format(domain)) + + # get new challenge +- code, result = _send_signed_request(CA + "/acme/new-authz", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-authz", { + "resource": "new-authz", + "identifier": {"type": "dns", "value": domain}, + }) +@@ -123,7 +123,7 @@ def get_crt(account_key, csr, acme_dir, + wellknown_path, wellknown_url)) + + # notify challenge are met +- code, result = _send_signed_request(challenge['uri'], { ++ code, result, headers = _send_signed_request(challenge['uri'], { + "resource": "challenge", + "keyAuthorization": keyauthorization, + }) +@@ -153,17 +153,32 @@ def get_crt(account_key, csr, acme_dir, + proc = subprocess.Popen(["openssl", "req", "-in", csr, "-outform", "DER"], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + csr_der, err = proc.communicate() +- code, result = _send_signed_request(CA + "/acme/new-cert", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-cert", { + "resource": "new-cert", + "csr": _b64(csr_der), + }) + if code != 201: + raise ValueError("Error signing certificate: {0} {1}".format(code, result)) + ++ certchain = [result] ++ if chain: ++ def parse_link_header(line): ++ m = re.search(r"^Link:\s*<([^>]*)>(?:\s*;\s*(.*))?\r\n$", line) ++ return (m.group(1), dict([(a[0],a[1].strip('"')) ++ for a in [attr.split("=") ++ for attr in m.group(2).split("\s*;\s*")]])) ++ ++ up = [ ++ link for link, attr in [ ++ parse_link_header(l) for l in headers.getallmatchingheaders("Link") ++ ] if attr['rel'] == 'up' ++ ] ++ certchain += [urlopen(url).read() for url in up] ++ + # return signed certificate! + log.info("Certificate signed!") +- return """-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( +- "\n".join(textwrap.wrap(base64.b64encode(result).decode('utf8'), 64))) ++ return "".join(["""-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( ++ "\n".join(textwrap.wrap(base64.b64encode(cert).decode('utf8'), 64))) for cert in certchain]) + + def main(argv): + parser = argparse.ArgumentParser( +@@ -188,11 +203,19 @@ def main(argv): + parser.add_argument("--acme-dir", required=True, help="path to the .well-known/acme-challenge/ directory") + parser.add_argument("--quiet", action="store_const", const=logging.ERROR, help="suppress output except for errors") + parser.add_argument("--ca", default=DEFAULT_CA, help="certificate authority, default is Let's Encrypt") ++ parser.add_argument("--chain", action="store_true", ++ help="fetch and append intermediate certs to output") + + args = parser.parse_args(argv) + LOGGER.setLevel(args.quiet or LOGGER.level) +- signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca) +- sys.stdout.write(signed_crt) ++ try: ++ signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, ++ log=LOGGER, CA=args.ca, chain=args.chain) ++ sys.stdout.write(signed_crt) ++ except Exception as e: ++ #if not args.quiet: raise e ++ LOGGER.error(e) ++ sys.exit(1) + + if __name__ == "__main__": # pragma: no cover + main(sys.argv[1:]) diff --git a/acme-tiny.spec b/acme-tiny.spec index 231e55f..bf90289 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -35,6 +35,8 @@ Source7: acme-tiny.service Source8: README-fedora.md # Fetch and include intermediate cert(s), too. Patch0: acme-tiny-chain.patch +# Version that works with python2 (python3 broke getallmatchingheaders) +Patch1: acme-tiny-chain2.patch Requires: openssl Requires(pre): shadow-utils @@ -68,10 +70,12 @@ acme_tiny on installed CSRs as the acme user for privilege separation. %prep %setup -q -n %{name}-%{commit} -%patch0 -p1 -b .chain cp -p %{SOURCE1} %{SOURCE2} %{SOURCE8} . %if %{use_python3} +%patch0 -p1 -b .chain sed -i.old -e '1,1 s/python$/python3/' *.py +%else +%patch1 -p1 -b .chain %endif %build From ff3c1182db4ac33949fbe04b5a3e234a7bf2dbcf Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Wed, 22 Nov 2017 22:40:39 -0500 Subject: [PATCH 16/61] Don't break python2 in case someone manually selects it --- acme-tiny-chain2.patch | 118 +++++++++++++++++++++++++++++++++++++++++ acme-tiny.spec | 6 ++- 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 acme-tiny-chain2.patch diff --git a/acme-tiny-chain2.patch b/acme-tiny-chain2.patch new file mode 100644 index 0000000..1c46c7d --- /dev/null +++ b/acme-tiny-chain2.patch @@ -0,0 +1,118 @@ +diff -up ./acme_tiny.py.chain ./acme_tiny.py +--- ./acme_tiny.py.chain 2017-05-16 03:57:46.000000000 -0400 ++++ ./acme_tiny.py 2017-11-22 15:14:19.270485351 -0500 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/python + import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging + try: + from urllib.request import urlopen # Python 3 +@@ -12,7 +12,7 @@ LOGGER = logging.getLogger(__name__) + LOGGER.addHandler(logging.StreamHandler()) + LOGGER.setLevel(logging.INFO) + +-def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA): ++def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA, chain=False): + # helper function base64 encode for jose spec + def _b64(b): + return base64.urlsafe_b64encode(b).decode('utf8').replace("=", "") +@@ -57,9 +57,9 @@ def get_crt(account_key, csr, acme_dir, + }) + try: + resp = urlopen(url, data.encode('utf8')) +- return resp.getcode(), resp.read() ++ return resp.getcode(), resp.read(), resp.info() + except IOError as e: +- return getattr(e, "code", None), getattr(e, "read", e.__str__)() ++ return getattr(e, "code", None), getattr(e, "read", e.__str__)(), None + + # find domains + log.info("Parsing CSR...") +@@ -80,9 +80,9 @@ def get_crt(account_key, csr, acme_dir, + + # get the certificate domains and expiration + log.info("Registering account...") +- code, result = _send_signed_request(CA + "/acme/new-reg", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-reg", { + "resource": "new-reg", +- "agreement": "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", ++ "agreement": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf", + }) + if code == 201: + log.info("Registered!") +@@ -96,7 +96,7 @@ def get_crt(account_key, csr, acme_dir, + log.info("Verifying {0}...".format(domain)) + + # get new challenge +- code, result = _send_signed_request(CA + "/acme/new-authz", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-authz", { + "resource": "new-authz", + "identifier": {"type": "dns", "value": domain}, + }) +@@ -123,7 +123,7 @@ def get_crt(account_key, csr, acme_dir, + wellknown_path, wellknown_url)) + + # notify challenge are met +- code, result = _send_signed_request(challenge['uri'], { ++ code, result, headers = _send_signed_request(challenge['uri'], { + "resource": "challenge", + "keyAuthorization": keyauthorization, + }) +@@ -153,17 +153,32 @@ def get_crt(account_key, csr, acme_dir, + proc = subprocess.Popen(["openssl", "req", "-in", csr, "-outform", "DER"], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + csr_der, err = proc.communicate() +- code, result = _send_signed_request(CA + "/acme/new-cert", { ++ code, result, headers = _send_signed_request(CA + "/acme/new-cert", { + "resource": "new-cert", + "csr": _b64(csr_der), + }) + if code != 201: + raise ValueError("Error signing certificate: {0} {1}".format(code, result)) + ++ certchain = [result] ++ if chain: ++ def parse_link_header(line): ++ m = re.search(r"^Link:\s*<([^>]*)>(?:\s*;\s*(.*))?\r\n$", line) ++ return (m.group(1), dict([(a[0],a[1].strip('"')) ++ for a in [attr.split("=") ++ for attr in m.group(2).split("\s*;\s*")]])) ++ ++ up = [ ++ link for link, attr in [ ++ parse_link_header(l) for l in headers.getallmatchingheaders("Link") ++ ] if attr['rel'] == 'up' ++ ] ++ certchain += [urlopen(url).read() for url in up] ++ + # return signed certificate! + log.info("Certificate signed!") +- return """-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( +- "\n".join(textwrap.wrap(base64.b64encode(result).decode('utf8'), 64))) ++ return "".join(["""-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( ++ "\n".join(textwrap.wrap(base64.b64encode(cert).decode('utf8'), 64))) for cert in certchain]) + + def main(argv): + parser = argparse.ArgumentParser( +@@ -188,11 +203,19 @@ def main(argv): + parser.add_argument("--acme-dir", required=True, help="path to the .well-known/acme-challenge/ directory") + parser.add_argument("--quiet", action="store_const", const=logging.ERROR, help="suppress output except for errors") + parser.add_argument("--ca", default=DEFAULT_CA, help="certificate authority, default is Let's Encrypt") ++ parser.add_argument("--chain", action="store_true", ++ help="fetch and append intermediate certs to output") + + args = parser.parse_args(argv) + LOGGER.setLevel(args.quiet or LOGGER.level) +- signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca) +- sys.stdout.write(signed_crt) ++ try: ++ signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, ++ log=LOGGER, CA=args.ca, chain=args.chain) ++ sys.stdout.write(signed_crt) ++ except Exception as e: ++ #if not args.quiet: raise e ++ LOGGER.error(e) ++ sys.exit(1) + + if __name__ == "__main__": # pragma: no cover + main(sys.argv[1:]) diff --git a/acme-tiny.spec b/acme-tiny.spec index 231e55f..a2d3cb5 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -35,6 +35,8 @@ Source7: acme-tiny.service Source8: README-fedora.md # Fetch and include intermediate cert(s), too. Patch0: acme-tiny-chain.patch +# Python3 broke getallmatchingheaders() and the fix breaks python2 +Patch1: acme-tiny-chain2.patch Requires: openssl Requires(pre): shadow-utils @@ -68,10 +70,12 @@ acme_tiny on installed CSRs as the acme user for privilege separation. %prep %setup -q -n %{name}-%{commit} -%patch0 -p1 -b .chain cp -p %{SOURCE1} %{SOURCE2} %{SOURCE8} . %if %{use_python3} +%patch0 -p1 -b .chain sed -i.old -e '1,1 s/python$/python3/' *.py +%else +%patch1 -p1 -b .chain %endif %build From daf0c4b4075e4e42cff22896c286bfd1ac641b4d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 7 Feb 2018 01:48:54 +0000 Subject: [PATCH 17/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index a2d3cb5..f8f482b 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -18,7 +18,7 @@ Name: acme-tiny Version: 0.2 -Release: 3.%{checkout}%{?dist} +Release: 4.%{checkout}%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet @@ -143,6 +143,9 @@ exit 0 /usr/sbin/cert-check %changelog +* Wed Feb 07 2018 Fedora Release Engineering - 0.2-4.20170516gitaf025f5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + * Wed Nov 22 2017 Stuart D. Gathman 0.2-3.20170616gitaf025f5 - BZ#1507333 EL6 missing python-argparse dependency - BZ#1515781 Agreement updated. From 7f9043064a6728221d717adaf246040d5c3f5365 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Tue, 22 May 2018 15:11:43 -0400 Subject: [PATCH 18/61] Update to new upstream release and create core subpackage. --- .gitignore | 1 + acme-tiny.spec | 58 ++++++++++++++++++++++++++++++++------------------ sources | 2 +- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 38b8735..d30c65e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /acme-tiny-5a7b4e7.tar.gz /acme-tiny-af025f5.tar.gz +/acme-tiny-4.0.4.tar.gz diff --git a/acme-tiny.spec b/acme-tiny.spec index f8f482b..476c138 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -1,6 +1,3 @@ -%global commit af025f5bf19c70be7fafab67f4dd718ca7bf9adf -%global shortcommit af025f5 -%global checkout 20170516git%{shortcommit} %if 0%{?rhel} >= 5 && 0%{?rhel} < 7 %global use_systemd 0 @@ -17,14 +14,14 @@ %endif Name: acme-tiny -Version: 0.2 -Release: 4.%{checkout}%{?dist} +Version: 4.0.4 +Release: 1%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet License: MIT URL: https://github.com/diafygi/acme-tiny -Source0: https://github.com/diafygi/%{name}/archive/%{commit}.tar.gz#/%{name}-%{shortcommit}.tar.gz +Source0: https://github.com/diafygi/acme-tiny/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz Source1: acme-tiny-sign.sh Source2: cert-check.py Source3: acme.conf @@ -34,16 +31,11 @@ Source6: acme-tiny.timer Source7: acme-tiny.service Source8: README-fedora.md # Fetch and include intermediate cert(s), too. -Patch0: acme-tiny-chain.patch +#Patch0: acme-tiny-chain.patch # Python3 broke getallmatchingheaders() and the fix breaks python2 Patch1: acme-tiny-chain2.patch -Requires: openssl Requires(pre): shadow-utils -%if 0%{?rhel} >= 5 && 0%{?rhel} < 7 -# EL6 uses python2.6, which does not include argparse -Requires: python-argparse -%endif %if %{use_systemd} # systemd macros are not defined unless systemd is present BuildRequires: systemd @@ -51,6 +43,7 @@ BuildRequires: systemd %else Requires: cronie %endif +Requires: %{name}-core = %{version}-%{release} BuildArch: noarch %if 0%{?fedora} Suggests: httpd, mod_ssl, nginx @@ -68,14 +61,29 @@ Well, that and a web server - but then you only need this with a web server. This package adds a simple directory layout and timer service that runs acme_tiny on installed CSRs as the acme user for privilege separation. +%package core +Summary: core python module of acme-tiny +Group: System Environment/Base +Requires: openssl +%if 0%{?rhel} >= 5 && 0%{?rhel} < 7 +# EL6 uses python2.6, which does not include argparse +Requires: python-argparse +%endif +BuildArch: noarch + +%description core +Includes only the core acme_tiny.py script and its dependencies. +Alternate frameworks that use acme_tiny.py can install this to avoid pulling in +unneeded packages. + %prep -%setup -q -n %{name}-%{commit} +%setup -q -n %{name}-%{version} cp -p %{SOURCE1} %{SOURCE2} %{SOURCE8} . %if %{use_python3} -%patch0 -p1 -b .chain +#patch0 -p1 -b .chain sed -i.old -e '1,1 s/python$/python3/' *.py -%else -%patch1 -p1 -b .chain +#else +#patch1 -p1 -b .chain %endif %build @@ -127,7 +135,7 @@ exit 0 %files %{!?_licensedir:%global license %%doc} %license LICENSE -%doc README.md README-fedora.md +%doc README-fedora.md %attr(0755,acme,acme) /var/www/challenges %attr(-,acme,acme) %{_sharedstatedir}/acme %{_libexecdir}/%{name} @@ -137,12 +145,20 @@ exit 0 %else %config(noreplace) %{_sysconfdir}/cron.d/acme-tiny %endif -/usr/sbin/acme_tiny -/usr/sbin/acme-tiny -/usr/sbin/acme-tiny-sign -/usr/sbin/cert-check +%{_sbindir}/acme-tiny-sign +%{_sbindir}/cert-check +%{_sbindir}/acme-tiny + +%files core +%license LICENSE +%doc README.md +%{_sbindir}/acme_tiny %changelog +* Tue May 22 2018 Stuart D. Gathman 4.0.4-1 +- Official upstream release! +- Move acme_tiny.py to acme-tiny-core subpackage + * Wed Feb 07 2018 Fedora Release Engineering - 0.2-4.20170516gitaf025f5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild diff --git a/sources b/sources index 2bc2674..298ec7e 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (acme-tiny-af025f5.tar.gz) = e322bcdda859cca1afd9c3b8c707d33ee46e590a63a28346a3eaf76b2ef1961ea0cf8be1aabe600ddf5c47caef1d2972cdc50c693a42170fd7ddfe124db319e0 +SHA512 (acme-tiny-4.0.4.tar.gz) = e66befe8262b3396e5e55ea01fc47c668c527868832d2ccdc2786156ec52e698fd20cb6fa4fe861d97947d64f4b6c751be9c79bf546eaac34978c53b9e6f85e4 From ecd867acdf5380ade6874c160e8a00ce14d3f8ba Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Tue, 22 May 2018 16:53:36 -0400 Subject: [PATCH 19/61] Get rid of --chain which is now default upstream. --- acme-tiny-sign.sh | 4 ++-- acme-tiny.spec | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/acme-tiny-sign.sh b/acme-tiny-sign.sh index 93eda8a..edceb37 100644 --- a/acme-tiny-sign.sh +++ b/acme-tiny-sign.sh @@ -27,7 +27,7 @@ for csr in csr/*.csr; do fi if test -w "$crt" || test ! -e "$crt"; then echo acme_tiny --account-key private/account.key --csr "$csr" \ - --acme-dir /var/www/challenges/ --chain --out "$crt" + --acme-dir /var/www/challenges/ --out "$crt" else echo "Can't write to $crt" rc="1" @@ -35,7 +35,7 @@ for csr in csr/*.csr; do fi if /usr/sbin/acme_tiny --account-key private/account.key --csr "$csr" \ - --acme-dir /var/www/challenges/ --chain > "$tmp"; then + --acme-dir /var/www/challenges/ > "$tmp"; then mv "$tmp" "$crt" || exit 1 else test -e "$tmp" && test ! -s "$tmp" && rm "$tmp" diff --git a/acme-tiny.spec b/acme-tiny.spec index 476c138..14683b3 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -31,7 +31,7 @@ Source6: acme-tiny.timer Source7: acme-tiny.service Source8: README-fedora.md # Fetch and include intermediate cert(s), too. -#Patch0: acme-tiny-chain.patch +Patch0: acme-tiny-chain.patch # Python3 broke getallmatchingheaders() and the fix breaks python2 Patch1: acme-tiny-chain2.patch @@ -79,11 +79,12 @@ unneeded packages. %prep %setup -q -n %{name}-%{version} cp -p %{SOURCE1} %{SOURCE2} %{SOURCE8} . +sed -i.orig -e '1,1 s,^.*python$,#!/usr/bin/python,' acme_tiny.py %if %{use_python3} #patch0 -p1 -b .chain sed -i.old -e '1,1 s/python$/python3/' *.py #else -#patch1 -p1 -b .chain +#patch1 -p1 -b .chain2 %endif %build From 0b10f97e6aa66f6c092cee3129360402c27ab8ce Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Tue, 22 May 2018 18:16:10 -0400 Subject: [PATCH 20/61] Add BZs to spec comment --- acme-tiny.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 14683b3..b67e081 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -157,8 +157,8 @@ exit 0 %changelog * Tue May 22 2018 Stuart D. Gathman 4.0.4-1 -- Official upstream release! -- Move acme_tiny.py to acme-tiny-core subpackage +- Official upstream release! BZ#1560531 +- Move acme_tiny.py to acme-tiny-core subpackage BZ#1438181 * Wed Feb 07 2018 Fedora Release Engineering - 0.2-4.20170516gitaf025f5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild From 1074567ec34b1ceb8e7489487bbb16f5a86cdf24 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 12 Jul 2018 19:57:39 +0000 Subject: [PATCH 21/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index b67e081..d48d517 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -15,7 +15,7 @@ Name: acme-tiny Version: 4.0.4 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates Group: Applications/Internet @@ -156,6 +156,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Thu Jul 12 2018 Fedora Release Engineering - 4.0.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + * Tue May 22 2018 Stuart D. Gathman 4.0.4-1 - Official upstream release! BZ#1560531 - Move acme_tiny.py to acme-tiny-core subpackage BZ#1438181 From e2d212e3ef35ac04985b9446a7961add0924405f Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Tue, 25 Sep 2018 11:50:22 -0400 Subject: [PATCH 22/61] gitignore src.rpm --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d30c65e..146d7a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /acme-tiny-5a7b4e7.tar.gz /acme-tiny-af025f5.tar.gz /acme-tiny-4.0.4.tar.gz +/*.src.rpm +/.build-* From 5cf1553c5ab7cb9326e0e6a84d01bb69c291d171 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Mon, 28 Jan 2019 20:17:38 +0100 Subject: [PATCH 23/61] Remove obsolete Group tag Signed-off-by: Igor Gnatenko --- acme-tiny.spec | 2 -- 1 file changed, 2 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index d48d517..2add148 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -18,7 +18,6 @@ Version: 4.0.4 Release: 2%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates -Group: Applications/Internet License: MIT URL: https://github.com/diafygi/acme-tiny Source0: https://github.com/diafygi/acme-tiny/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz @@ -63,7 +62,6 @@ acme_tiny on installed CSRs as the acme user for privilege separation. %package core Summary: core python module of acme-tiny -Group: System Environment/Base Requires: openssl %if 0%{?rhel} >= 5 && 0%{?rhel} < 7 # EL6 uses python2.6, which does not include argparse From 04841bde2bea02dd81987d20ded266d32e1efffb Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 31 Jan 2019 12:54:55 +0000 Subject: [PATCH 24/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 2add148..8628dfe 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -15,7 +15,7 @@ Name: acme-tiny Version: 4.0.4 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -154,6 +154,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Thu Jan 31 2019 Fedora Release Engineering - 4.0.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + * Thu Jul 12 2018 Fedora Release Engineering - 4.0.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild From 2ea4b87521352a2aa8606b2fa22be1ecc78591a5 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Mon, 8 Apr 2019 11:47:30 -0400 Subject: [PATCH 25/61] Add generic notify script. --- acme-tiny.spec | 9 ++++++++- notify.sh | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100755 notify.sh diff --git a/acme-tiny.spec b/acme-tiny.spec index 8628dfe..0b0356d 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -15,7 +15,7 @@ Name: acme-tiny Version: 4.0.4 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -29,6 +29,8 @@ Source5: acme-tiny.cron Source6: acme-tiny.timer Source7: acme-tiny.service Source8: README-fedora.md +# simple script hook to kick services when cert is updated +Source9: notify.sh # Fetch and include intermediate cert(s), too. Patch0: acme-tiny-chain.patch # Python3 broke getallmatchingheaders() and the fix breaks python2 @@ -93,6 +95,7 @@ mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d mkdir -p %{buildroot}%{_sbindir} mkdir -p %{buildroot}%{_libexecdir}/%{name} mkdir -p %{buildroot}%{_sharedstatedir}/acme/{private,csr,certs} +mkdir -p %{buildroot}%{_sysconfdir}/acme/notify.d chmod 0700 %{buildroot}%{_sharedstatedir}/acme/private install -m 0755 acme-tiny-sign.sh %{buildroot}%{_libexecdir}/%{name}/sign @@ -102,6 +105,7 @@ ln -sf %{_libexecdir}/%{name}/sign %{buildroot}%{_sbindir}/acme-tiny-sign install -m 0755 cert-check.py %{buildroot}%{_sbindir}/cert-check install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/httpd/conf.d install -m 0644 %{SOURCE4} %{buildroot}%{_sharedstatedir}/acme +install -m 0755 %{SOURCE9} %{buildroot}%{_sysconfdir}/acme %if %{use_systemd} mkdir -p %{buildroot}%{_unitdir} install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} @@ -154,6 +158,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Mon Mar 08 2019 Stuart D. Gathman 4.0.4-4 +- Add notify script for incron + * Thu Jan 31 2019 Fedora Release Engineering - 4.0.4-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild diff --git a/notify.sh b/notify.sh new file mode 100755 index 0000000..d027247 --- /dev/null +++ b/notify.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +cert="$1" +name="${cert##*/}" +script="/etc/acme/notify.d/${name%.crt}.sh" + +# kick apache if cert is mentioned +if grep "$cert" /etc/httpd/conf.d/*.conf >/dev/null 2>&1; then + apachectl graceful +fi + +# kick sendmail if cert is mentioned +if grep "/etc/pki/tls/certs/$name" /etc/mail/*.cf >/dev/null 2>&1; then + cp "$cert" /etc/pki/tls/certs && systemctl restart sendmail +fi + +# run any dropin extension +if test -x "$script"; then + "$script" "$cert" +fi From b767ed5e0be681412e94181c5b1c2d5fe85b241d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 24 Jul 2019 17:30:08 +0000 Subject: [PATCH 26/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 8628dfe..d9ab2f0 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -15,7 +15,7 @@ Name: acme-tiny Version: 4.0.4 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -154,6 +154,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Jul 24 2019 Fedora Release Engineering - 4.0.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + * Thu Jan 31 2019 Fedora Release Engineering - 4.0.4-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild From 50fcf9dea9d336e38f9cad1a06d93408088d25d1 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Fri, 11 Oct 2019 16:10:41 -0400 Subject: [PATCH 27/61] Add generic notify script --- acme-tiny.spec | 15 ++++++++------- notify.sh | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 0b0356d..44600f7 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -19,8 +19,8 @@ Release: 4%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT -URL: https://github.com/diafygi/acme-tiny -Source0: https://github.com/diafygi/acme-tiny/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz +URL: https://github.com/diafygi/%{name} +Source0: https://github.com/diafygi/%{name}/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz Source1: acme-tiny-sign.sh Source2: cert-check.py Source3: acme.conf @@ -95,17 +95,17 @@ mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d mkdir -p %{buildroot}%{_sbindir} mkdir -p %{buildroot}%{_libexecdir}/%{name} mkdir -p %{buildroot}%{_sharedstatedir}/acme/{private,csr,certs} -mkdir -p %{buildroot}%{_sysconfdir}/acme/notify.d +mkdir -p %{buildroot}%{_sysconfdir}/%{name}/notify.d chmod 0700 %{buildroot}%{_sharedstatedir}/acme/private install -m 0755 acme-tiny-sign.sh %{buildroot}%{_libexecdir}/%{name}/sign install -m 0755 acme_tiny.py %{buildroot}%{_sbindir}/acme_tiny -ln -sf acme_tiny %{buildroot}%{_sbindir}/acme-tiny +ln -sf acme_tiny %{buildroot}%{_sbindir}/%{name} ln -sf %{_libexecdir}/%{name}/sign %{buildroot}%{_sbindir}/acme-tiny-sign install -m 0755 cert-check.py %{buildroot}%{_sbindir}/cert-check install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/httpd/conf.d install -m 0644 %{SOURCE4} %{buildroot}%{_sharedstatedir}/acme -install -m 0755 %{SOURCE9} %{buildroot}%{_sysconfdir}/acme +install -m 0755 %{SOURCE9} %{buildroot}%{_sysconfdir}/%{name} %if %{use_systemd} mkdir -p %{buildroot}%{_unitdir} install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} @@ -146,11 +146,12 @@ exit 0 %if %{use_systemd} %{_unitdir}/* %else -%config(noreplace) %{_sysconfdir}/cron.d/acme-tiny +%config(noreplace) %{_sysconfdir}/cron.d/%{name} %endif %{_sbindir}/acme-tiny-sign %{_sbindir}/cert-check -%{_sbindir}/acme-tiny +%{_sbindir}/%{name} +%{_sysconfdir}/%{name} %files core %license LICENSE diff --git a/notify.sh b/notify.sh index d027247..2d04011 100755 --- a/notify.sh +++ b/notify.sh @@ -2,7 +2,7 @@ cert="$1" name="${cert##*/}" -script="/etc/acme/notify.d/${name%.crt}.sh" +script="/etc/acme-tiny/notify.d/${name%.crt}.sh" # kick apache if cert is mentioned if grep "$cert" /etc/httpd/conf.d/*.conf >/dev/null 2>&1; then From 73d7264479b3ceb14ce7d907067e47c60496225b Mon Sep 17 00:00:00 2001 From: Tim Jackson Date: Fri, 11 Oct 2019 22:22:32 +0200 Subject: [PATCH 28/61] Update to 4.1.0; force Python3 support for EL8 --- acme-tiny.spec | 9 ++++++--- sources | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index d9ab2f0..0ca955f 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -5,7 +5,7 @@ %global use_systemd 1 %endif -%if 0%{?fedora} +%if 0%{?fedora} || 0%{?rhel} >= 8 # Explicity require python3 on Fedora to help track which packages # no longer need python2. %global use_python3 1 @@ -14,8 +14,8 @@ %endif Name: acme-tiny -Version: 4.0.4 -Release: 4%{?dist} +Version: 4.1.0 +Release: 1%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -154,6 +154,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Oct 11 2019 Tim Jackson - 4.0.4-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild diff --git a/sources b/sources index 298ec7e..a5fdfcf 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (acme-tiny-4.0.4.tar.gz) = e66befe8262b3396e5e55ea01fc47c668c527868832d2ccdc2786156ec52e698fd20cb6fa4fe861d97947d64f4b6c751be9c79bf546eaac34978c53b9e6f85e4 +SHA512 (acme-tiny-4.1.0.tar.gz) = 31d69a5031c019acbc23b3f06041eae8e261766396d4a7420fd70a71cfa16de953bea4c0c2ad0c6a6e793ed61ab5331f40145352ffce69f4f062f35dd0db7519 From ebceebf5979060d4f0538d8c82f0a4338f08d37e Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Fri, 11 Oct 2019 16:52:57 -0400 Subject: [PATCH 29/61] Require python3 on epel > 7 --- acme-tiny.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index ca3b064..ace5467 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -5,7 +5,7 @@ %global use_systemd 1 %endif -%if 0%{?fedora} +%if 0%{?fedora} || 0%{?rhel} > 7 # Explicity require python3 on Fedora to help track which packages # no longer need python2. %global use_python3 1 From 18951676b2a96e9e079364c4eedec15cc0be5e7e Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Sat, 12 Oct 2019 12:11:33 -0400 Subject: [PATCH 30/61] new source --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 146d7a8..8d64d85 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /acme-tiny-4.0.4.tar.gz /*.src.rpm /.build-* +/acme-tiny-4.1.0.tar.gz From 85315723c466d6ea8afda8d0a4cc48711fbab5cc Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 5 Dec 2019 19:04:30 -0500 Subject: [PATCH 31/61] Fix changelog dates. --- acme-tiny.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 56ba7df..dd7b091 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -159,10 +159,10 @@ exit 0 %{_sbindir}/acme_tiny %changelog -* Wed Oct 11 2019 Tim Jackson 4.0.4-5 +* Fri Oct 11 2019 Stuart D. Gathman 4.0.4-5 - Add generic notify script for incron * Wed Jul 24 2019 Fedora Release Engineering - 4.0.4-4 From 5bf9ac63df57d8e3e07c59cec48d60ca7a3d3fe5 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 5 Dec 2019 19:47:24 -0500 Subject: [PATCH 32/61] Update README-fedora.md to describe notify.sh --- README-fedora.md | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/README-fedora.md b/README-fedora.md index 775e524..afe51af 100644 --- a/README-fedora.md +++ b/README-fedora.md @@ -99,20 +99,21 @@ and other apps. Sendmail is a special problem - it insists that any certificates it loads be only writable by root. This is at odds with the privilege separation of the acme user. (Obviously, the private key must be accessible only by root.) You -can, of course, copy the crt file to /etc/pki/tls/certs as root and change the -mode. But this has to be done every time the cert is renewed. You can +can, of course, copy the crt file to `/etc/pki/tls/certs` as root and change +the mode. But this has to be done every time the cert is renewed. You can install `incron` to do this. After installing, create `/etc/incron.d/acme` with the line ``` -/var/lib/acme/certs/mail.crt IN_MOVED_TO cp $@ /etc/pki/tls/certs +/var/lib/acme/certs/mail.crt IN_MOVED_TO /etc/acme-tiny/notify.sh $@ ``` -where `mail.crt` is the certificate sendmail will use. Sendmail -can then load it from /etc/pki/tls/certs and be happy. This also -solves the file context problem if you add lines for other certificates. -You might wonder why we don't simply supply an acme incrontab as part -of the package with a wildcard, for example: +where `mail.crt` is the certificate sendmail will use. The notify.sh script +sees the reference to `/etc/pki/tls/certs/mail.crt` in `/etc/mail/*.cf`, and +copies it to `/etc/pki/tls/certs`. Sendmail can then load it from there and be +happy. This also solves the file context problem if you add lines for other +certificates. You might wonder why we don't simply supply an acme incrontab as +part of the package with a wildcard, for example: ``` -/var/lib/acme/certs/*.crt IN_MOVED_TO cp $@ /etc/pki/tls/certs +/var/lib/acme/certs/*.crt IN_MOVED_TO /etc/acme-tiny/notify.sh $@ ``` The answer is that incron is insecure, and very nasty things can be done by putting shell meta characters (including semicolon and quote!) in @@ -134,6 +135,9 @@ Most web servers can handle multiple logical web hosts - configuring that is beyond the scope of this document. Each virtual host may need to have its own certificate for SSL. They can all share the same key file (see above for how to use an existing key for certificate requests), or use different keys. -Put all the CSRs in /var/lib/acme/csr and the acme-tiny service will keep them -all renewed. This also works for certificates used by other SSL applications, -such as dovecot, sendmail, jabberd, or znc. +Note that apache can load certs directly from `/var/lib/acme/certs`, and +so notify.sh simply does `apachectl graceful`. + +Put all the CSRs in `/var/lib/acme/csr` and the acme-tiny service will keep +them all renewed. This also works for certificates used by other SSL +applications, such as dovecot, sendmail, jabberd, or znc. From 28ca09289c77a779490fb6e2572322911f44a007 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 28 Jan 2020 11:10:00 +0000 Subject: [PATCH 33/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index dd7b091..c299761 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -15,7 +15,7 @@ Name: acme-tiny Version: 4.1.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -159,6 +159,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Tue Jan 28 2020 Fedora Release Engineering - 4.1.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + * Fri Oct 11 2019 Tim Jackson Date: Thu, 9 Apr 2020 13:27:33 -0400 Subject: [PATCH 34/61] notify.sh docs --- acme-tiny.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/acme-tiny.spec b/acme-tiny.spec index dd7b091..6e932ce 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -159,6 +159,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Thu Dec 5 2019 Stuart D. Gathman 4.1.0-2 +- Update README-fedora.md to describe notify.sh + * Fri Oct 11 2019 Tim Jackson Date: Thu, 9 Apr 2020 13:53:30 -0400 Subject: [PATCH 35/61] Cleanup EL6 support and unused patches: Marcel Metz --- README-fedora.md | 7 +- acme-tiny-chain.patch | 118 ------------------------------- acme-tiny-chain2.patch | 118 ------------------------------- acme-tiny-sign.sh | 3 +- acme-tiny.cron | 3 - acme-tiny.spec | 41 ++--------- lets-encrypt-x3-cross-signed.pem | 27 ------- 7 files changed, 11 insertions(+), 306 deletions(-) delete mode 100644 acme-tiny-chain.patch delete mode 100644 acme-tiny-chain2.patch delete mode 100644 acme-tiny.cron delete mode 100644 lets-encrypt-x3-cross-signed.pem diff --git a/README-fedora.md b/README-fedora.md index afe51af..9f359a9 100644 --- a/README-fedora.md +++ b/README-fedora.md @@ -74,7 +74,7 @@ Use systemctl start acme-tiny ``` to run the service now. The certificate should appear in `/var/lib/acme/certs`, -and errors will be in journalctl. Alternatively (and on EL6), run +and errors will be in journalctl. Alternatively, run `/usr/libexec/acme-tiny/sign` as the acme user, and errors will go to your terminal. @@ -125,9 +125,8 @@ handle [malicious names](https://www.xkcd.com/327/). ## Logging and Error Reporting -On EL6, cron will email the acme user when certs are signed or errors -are encountered. Under systemd, errors and certs signed are logged -with the acme-tiny syslog identifier. +Under systemd, errors and certs signed are logged with the acme-tiny +syslog identifier. ## Virtual Hosts diff --git a/acme-tiny-chain.patch b/acme-tiny-chain.patch deleted file mode 100644 index 5e681d9..0000000 --- a/acme-tiny-chain.patch +++ /dev/null @@ -1,118 +0,0 @@ -diff -up ./acme_tiny.py.chain ./acme_tiny.py ---- ./acme_tiny.py.chain 2017-05-16 03:57:46.000000000 -0400 -+++ ./acme_tiny.py 2017-11-22 12:18:56.963653336 -0500 -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/python - import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging - try: - from urllib.request import urlopen # Python 3 -@@ -12,7 +12,7 @@ LOGGER = logging.getLogger(__name__) - LOGGER.addHandler(logging.StreamHandler()) - LOGGER.setLevel(logging.INFO) - --def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA): -+def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA, chain=False): - # helper function base64 encode for jose spec - def _b64(b): - return base64.urlsafe_b64encode(b).decode('utf8').replace("=", "") -@@ -57,9 +57,9 @@ def get_crt(account_key, csr, acme_dir, - }) - try: - resp = urlopen(url, data.encode('utf8')) -- return resp.getcode(), resp.read() -+ return resp.getcode(), resp.read(), resp.info() - except IOError as e: -- return getattr(e, "code", None), getattr(e, "read", e.__str__)() -+ return getattr(e, "code", None), getattr(e, "read", e.__str__)(), None - - # find domains - log.info("Parsing CSR...") -@@ -80,9 +80,9 @@ def get_crt(account_key, csr, acme_dir, - - # get the certificate domains and expiration - log.info("Registering account...") -- code, result = _send_signed_request(CA + "/acme/new-reg", { -+ code, result, headers = _send_signed_request(CA + "/acme/new-reg", { - "resource": "new-reg", -- "agreement": "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", -+ "agreement": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf", - }) - if code == 201: - log.info("Registered!") -@@ -96,7 +96,7 @@ def get_crt(account_key, csr, acme_dir, - log.info("Verifying {0}...".format(domain)) - - # get new challenge -- code, result = _send_signed_request(CA + "/acme/new-authz", { -+ code, result, headers = _send_signed_request(CA + "/acme/new-authz", { - "resource": "new-authz", - "identifier": {"type": "dns", "value": domain}, - }) -@@ -123,7 +123,7 @@ def get_crt(account_key, csr, acme_dir, - wellknown_path, wellknown_url)) - - # notify challenge are met -- code, result = _send_signed_request(challenge['uri'], { -+ code, result, headers = _send_signed_request(challenge['uri'], { - "resource": "challenge", - "keyAuthorization": keyauthorization, - }) -@@ -153,17 +153,32 @@ def get_crt(account_key, csr, acme_dir, - proc = subprocess.Popen(["openssl", "req", "-in", csr, "-outform", "DER"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - csr_der, err = proc.communicate() -- code, result = _send_signed_request(CA + "/acme/new-cert", { -+ code, result, headers = _send_signed_request(CA + "/acme/new-cert", { - "resource": "new-cert", - "csr": _b64(csr_der), - }) - if code != 201: - raise ValueError("Error signing certificate: {0} {1}".format(code, result)) - -+ certchain = [result] -+ if chain: -+ def parse_link_header(line): -+ m = re.search(r"^<([^>]*)>(?:\s*;\s*(.*))?$", line) -+ return (m.group(1), dict([(a[0],a[1].strip('"')) -+ for a in [attr.split("=") -+ for attr in m.group(2).split("\s*;\s*")]])) -+ -+ up = [ -+ link for link, attr in [ -+ parse_link_header(l) for l in headers.get_all("Link") -+ ] if attr['rel'] == 'up' -+ ] -+ certchain += [urlopen(url).read() for url in up] -+ - # return signed certificate! - log.info("Certificate signed!") -- return """-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( -- "\n".join(textwrap.wrap(base64.b64encode(result).decode('utf8'), 64))) -+ return "".join(["""-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( -+ "\n".join(textwrap.wrap(base64.b64encode(cert).decode('utf8'), 64))) for cert in certchain]) - - def main(argv): - parser = argparse.ArgumentParser( -@@ -188,11 +203,19 @@ def main(argv): - parser.add_argument("--acme-dir", required=True, help="path to the .well-known/acme-challenge/ directory") - parser.add_argument("--quiet", action="store_const", const=logging.ERROR, help="suppress output except for errors") - parser.add_argument("--ca", default=DEFAULT_CA, help="certificate authority, default is Let's Encrypt") -+ parser.add_argument("--chain", action="store_true", -+ help="fetch and append intermediate certs to output") - - args = parser.parse_args(argv) - LOGGER.setLevel(args.quiet or LOGGER.level) -- signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca) -- sys.stdout.write(signed_crt) -+ try: -+ signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, -+ log=LOGGER, CA=args.ca, chain=args.chain) -+ sys.stdout.write(signed_crt) -+ except Exception as e: -+ #if not args.quiet: raise e -+ LOGGER.error(e) -+ sys.exit(1) - - if __name__ == "__main__": # pragma: no cover - main(sys.argv[1:]) diff --git a/acme-tiny-chain2.patch b/acme-tiny-chain2.patch deleted file mode 100644 index 1c46c7d..0000000 --- a/acme-tiny-chain2.patch +++ /dev/null @@ -1,118 +0,0 @@ -diff -up ./acme_tiny.py.chain ./acme_tiny.py ---- ./acme_tiny.py.chain 2017-05-16 03:57:46.000000000 -0400 -+++ ./acme_tiny.py 2017-11-22 15:14:19.270485351 -0500 -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/python - import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging - try: - from urllib.request import urlopen # Python 3 -@@ -12,7 +12,7 @@ LOGGER = logging.getLogger(__name__) - LOGGER.addHandler(logging.StreamHandler()) - LOGGER.setLevel(logging.INFO) - --def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA): -+def get_crt(account_key, csr, acme_dir, log=LOGGER, CA=DEFAULT_CA, chain=False): - # helper function base64 encode for jose spec - def _b64(b): - return base64.urlsafe_b64encode(b).decode('utf8').replace("=", "") -@@ -57,9 +57,9 @@ def get_crt(account_key, csr, acme_dir, - }) - try: - resp = urlopen(url, data.encode('utf8')) -- return resp.getcode(), resp.read() -+ return resp.getcode(), resp.read(), resp.info() - except IOError as e: -- return getattr(e, "code", None), getattr(e, "read", e.__str__)() -+ return getattr(e, "code", None), getattr(e, "read", e.__str__)(), None - - # find domains - log.info("Parsing CSR...") -@@ -80,9 +80,9 @@ def get_crt(account_key, csr, acme_dir, - - # get the certificate domains and expiration - log.info("Registering account...") -- code, result = _send_signed_request(CA + "/acme/new-reg", { -+ code, result, headers = _send_signed_request(CA + "/acme/new-reg", { - "resource": "new-reg", -- "agreement": "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf", -+ "agreement": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf", - }) - if code == 201: - log.info("Registered!") -@@ -96,7 +96,7 @@ def get_crt(account_key, csr, acme_dir, - log.info("Verifying {0}...".format(domain)) - - # get new challenge -- code, result = _send_signed_request(CA + "/acme/new-authz", { -+ code, result, headers = _send_signed_request(CA + "/acme/new-authz", { - "resource": "new-authz", - "identifier": {"type": "dns", "value": domain}, - }) -@@ -123,7 +123,7 @@ def get_crt(account_key, csr, acme_dir, - wellknown_path, wellknown_url)) - - # notify challenge are met -- code, result = _send_signed_request(challenge['uri'], { -+ code, result, headers = _send_signed_request(challenge['uri'], { - "resource": "challenge", - "keyAuthorization": keyauthorization, - }) -@@ -153,17 +153,32 @@ def get_crt(account_key, csr, acme_dir, - proc = subprocess.Popen(["openssl", "req", "-in", csr, "-outform", "DER"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - csr_der, err = proc.communicate() -- code, result = _send_signed_request(CA + "/acme/new-cert", { -+ code, result, headers = _send_signed_request(CA + "/acme/new-cert", { - "resource": "new-cert", - "csr": _b64(csr_der), - }) - if code != 201: - raise ValueError("Error signing certificate: {0} {1}".format(code, result)) - -+ certchain = [result] -+ if chain: -+ def parse_link_header(line): -+ m = re.search(r"^Link:\s*<([^>]*)>(?:\s*;\s*(.*))?\r\n$", line) -+ return (m.group(1), dict([(a[0],a[1].strip('"')) -+ for a in [attr.split("=") -+ for attr in m.group(2).split("\s*;\s*")]])) -+ -+ up = [ -+ link for link, attr in [ -+ parse_link_header(l) for l in headers.getallmatchingheaders("Link") -+ ] if attr['rel'] == 'up' -+ ] -+ certchain += [urlopen(url).read() for url in up] -+ - # return signed certificate! - log.info("Certificate signed!") -- return """-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( -- "\n".join(textwrap.wrap(base64.b64encode(result).decode('utf8'), 64))) -+ return "".join(["""-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n""".format( -+ "\n".join(textwrap.wrap(base64.b64encode(cert).decode('utf8'), 64))) for cert in certchain]) - - def main(argv): - parser = argparse.ArgumentParser( -@@ -188,11 +203,19 @@ def main(argv): - parser.add_argument("--acme-dir", required=True, help="path to the .well-known/acme-challenge/ directory") - parser.add_argument("--quiet", action="store_const", const=logging.ERROR, help="suppress output except for errors") - parser.add_argument("--ca", default=DEFAULT_CA, help="certificate authority, default is Let's Encrypt") -+ parser.add_argument("--chain", action="store_true", -+ help="fetch and append intermediate certs to output") - - args = parser.parse_args(argv) - LOGGER.setLevel(args.quiet or LOGGER.level) -- signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca) -- sys.stdout.write(signed_crt) -+ try: -+ signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, -+ log=LOGGER, CA=args.ca, chain=args.chain) -+ sys.stdout.write(signed_crt) -+ except Exception as e: -+ #if not args.quiet: raise e -+ LOGGER.error(e) -+ sys.exit(1) - - if __name__ == "__main__": # pragma: no cover - main(sys.argv[1:]) diff --git a/acme-tiny-sign.sh b/acme-tiny-sign.sh index edceb37..6256f5d 100644 --- a/acme-tiny-sign.sh +++ b/acme-tiny-sign.sh @@ -22,7 +22,8 @@ for csr in csr/*.csr; do crt="${csr%%.csr}" tmp="certs/${crt##csr/}.tmp" crt="certs/${crt##csr/}.crt" - if test -s "$crt" && /usr/sbin/cert-check --days="$DAYS" "$crt"; then + secs=$(( "$DAYS" * 24 * 60 * 60 )) + if test -s "$crt" && openssl x509 -in "$crt" -noout -checkend "$secs"; then continue fi if test -w "$crt" || test ! -e "$crt"; then diff --git a/acme-tiny.cron b/acme-tiny.cron deleted file mode 100644 index 206fd39..0000000 --- a/acme-tiny.cron +++ /dev/null @@ -1,3 +0,0 @@ -# Check daily for csrs in /var/lib/acme/csr that need signing or renewing -# within 7 days. -31 2 * * * acme /usr/libexec/acme-tiny/sign 7 diff --git a/acme-tiny.spec b/acme-tiny.spec index 0e77ba1..84bb6f2 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -1,10 +1,4 @@ -%if 0%{?rhel} >= 5 && 0%{?rhel} < 7 -%global use_systemd 0 -%else -%global use_systemd 1 -%endif - %if 0%{?fedora} || 0%{?rhel} > 7 # Explicity require python3 on Fedora to help track which packages # no longer need python2. @@ -15,7 +9,7 @@ Name: acme-tiny Version: 4.1.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -24,26 +18,16 @@ Source0: https://github.com/diafygi/%{name}/archive/%{version}.tar.gz#/%{name}-% Source1: acme-tiny-sign.sh Source2: cert-check.py Source3: acme.conf -Source4: lets-encrypt-x3-cross-signed.pem -Source5: acme-tiny.cron Source6: acme-tiny.timer Source7: acme-tiny.service Source8: README-fedora.md # simple script hook to kick services when cert is updated Source9: notify.sh -# Fetch and include intermediate cert(s), too. -Patch0: acme-tiny-chain.patch -# Python3 broke getallmatchingheaders() and the fix breaks python2 -Patch1: acme-tiny-chain2.patch Requires(pre): shadow-utils -%if %{use_systemd} # systemd macros are not defined unless systemd is present BuildRequires: systemd %{?systemd_requires} -%else -Requires: cronie -%endif Requires: %{name}-core = %{version}-%{release} BuildArch: noarch %if 0%{?fedora} @@ -81,10 +65,7 @@ unneeded packages. cp -p %{SOURCE1} %{SOURCE2} %{SOURCE8} . sed -i.orig -e '1,1 s,^.*python$,#!/usr/bin/python,' acme_tiny.py %if %{use_python3} -#patch0 -p1 -b .chain sed -i.old -e '1,1 s/python$/python3/' *.py -#else -#patch1 -p1 -b .chain2 %endif %build @@ -104,16 +85,10 @@ ln -sf acme_tiny %{buildroot}%{_sbindir}/%{name} ln -sf %{_libexecdir}/%{name}/sign %{buildroot}%{_sbindir}/acme-tiny-sign install -m 0755 cert-check.py %{buildroot}%{_sbindir}/cert-check install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/httpd/conf.d -install -m 0644 %{SOURCE4} %{buildroot}%{_sharedstatedir}/acme install -m 0755 %{SOURCE9} %{buildroot}%{_sysconfdir}/%{name} -%if %{use_systemd} mkdir -p %{buildroot}%{_unitdir} install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} install -pm 644 %{SOURCE7} %{buildroot}%{_unitdir} -%else -mkdir -p %{buildroot}%{_sysconfdir}/cron.d -install -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/cron.d/acme-tiny -%endif %pre getent group acme > /dev/null || groupadd -r acme @@ -122,8 +97,6 @@ getent passwd acme > /dev/null || /usr/sbin/useradd -g acme \ -r -d %{_sharedstatedir}/acme -s /sbin/nologin acme exit 0 -%if %{use_systemd} - %post %systemd_post acme-tiny.service acme-tiny.timer @@ -133,8 +106,6 @@ exit 0 %preun %systemd_preun acme-tiny.service acme-tiny.timer -%endif - %files %{!?_licensedir:%global license %%doc} %license LICENSE @@ -143,11 +114,7 @@ exit 0 %attr(-,acme,acme) %{_sharedstatedir}/acme %{_libexecdir}/%{name} %config(noreplace) %{_sysconfdir}/httpd/conf.d/acme.conf -%if %{use_systemd} %{_unitdir}/* -%else -%config(noreplace) %{_sysconfdir}/cron.d/%{name} -%endif %{_sbindir}/acme-tiny-sign %{_sbindir}/cert-check %{_sbindir}/%{name} @@ -161,11 +128,15 @@ exit 0 %changelog * Thu Apr 9 2020 Stuart D. Gathman 4.1.0-3 - Update README-fedora.md to describe notify.sh +- Apply selected changes from Marcel Metz : +- Use openssl x509 -checkend parameter to determine certificate expiration +- Remove Let's Encrypt intermediate certificate +- Remove cron job used on non systemd systems * Tue Jan 28 2020 Fedora Release Engineering - 4.1.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild -* Fri Oct 11 2019 Tim Jackson - 4.1.0-1 - Update to 4.1.0 * Fri Oct 11 2019 Stuart D. Gathman 4.0.4-5 diff --git a/lets-encrypt-x3-cross-signed.pem b/lets-encrypt-x3-cross-signed.pem deleted file mode 100644 index 0002462..0000000 --- a/lets-encrypt-x3-cross-signed.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow -SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT -GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF -q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 -SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 -Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA -a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj -/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T -AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG -CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv -bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k -c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw -VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC -ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz -MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu -Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF -AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo -uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ -wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu -X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG -PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 -KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== ------END CERTIFICATE----- From e62eb5289d51d017e472e1f663bf5c769c44d4f6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 27 Jul 2020 11:42:21 +0000 Subject: [PATCH 36/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 84bb6f2..9c35820 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 4.1.0 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -126,6 +126,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Mon Jul 27 2020 Fedora Release Engineering - 4.1.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Thu Apr 9 2020 Stuart D. Gathman 4.1.0-3 - Update README-fedora.md to describe notify.sh - Apply selected changes from Marcel Metz : From 1d4a4aa823121880a8ec87cba7d6787a119657b2 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 25 Jan 2021 23:46:09 +0000 Subject: [PATCH 37/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 9c35820..a4ba647 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 4.1.0 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -126,6 +126,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Mon Jan 25 2021 Fedora Release Engineering - 4.1.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Mon Jul 27 2020 Fedora Release Engineering - 4.1.0-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild From 6859d7092ccc9587eb224fd578f28c2ddfada712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Mar 2021 16:14:12 +0100 Subject: [PATCH 38/61] Rebuilt for updated systemd-rpm-macros See https://pagure.io/fesco/issue/2583. --- acme-tiny.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index a4ba647..70f8abd 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 4.1.0 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -126,6 +126,10 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 4.1.0-6 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + * Mon Jan 25 2021 Fedora Release Engineering - 4.1.0-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild From 23a0e061492357e8088e3782ee5827bc6d138ab6 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Sat, 20 Mar 2021 13:37:08 -0400 Subject: [PATCH 39/61] Add built-in kicker for dovecot --- notify.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/notify.sh b/notify.sh index 2d04011..fbf5f38 100755 --- a/notify.sh +++ b/notify.sh @@ -14,6 +14,11 @@ if grep "/etc/pki/tls/certs/$name" /etc/mail/*.cf >/dev/null 2>&1; then cp "$cert" /etc/pki/tls/certs && systemctl restart sendmail fi +# kick dovecot if cert is mentioned +if grep "/etc/pki/dovecot/certs/$name" /etc/dovecot/conf.d/10-ssl.conf >/dev/null 2>&1; then + cp "$cert" /etc/pki/dovecot/certs && systemctl restart dovecot +fi + # run any dropin extension if test -x "$script"; then "$script" "$cert" From 766eae26edcbffd5d31d7f18e13b664bedb3fa11 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Fri, 28 May 2021 00:08:58 -0400 Subject: [PATCH 40/61] Fix BZ#1839904 and enhance notify script so incrond is not needed. --- README-fedora.md | 52 +++++++++++++++++------------ acme-tiny-notify.service | 8 +++++ acme-tiny.service | 2 ++ acme-tiny.spec | 21 ++++++++---- notify.sh | 72 +++++++++++++++++++++++++++++----------- 5 files changed, 107 insertions(+), 48 deletions(-) create mode 100644 acme-tiny-notify.service diff --git a/README-fedora.md b/README-fedora.md index 9f359a9..7a010fc 100644 --- a/README-fedora.md +++ b/README-fedora.md @@ -1,3 +1,8 @@ +# acme-tiny-core Fedora package + +This package contains only the upstream python script - for those +who prefer their own framework for cert maintenance. + # acme-tiny Fedora package The Fedora package for acme-tiny adds a tiny framework to make issuing @@ -100,28 +105,32 @@ Sendmail is a special problem - it insists that any certificates it loads be only writable by root. This is at odds with the privilege separation of the acme user. (Obviously, the private key must be accessible only by root.) You can, of course, copy the crt file to `/etc/pki/tls/certs` as root and change -the mode. But this has to be done every time the cert is renewed. You can -install `incron` to do this. After installing, create `/etc/incron.d/acme` -with the line -``` -/var/lib/acme/certs/mail.crt IN_MOVED_TO /etc/acme-tiny/notify.sh $@ -``` -where `mail.crt` is the certificate sendmail will use. The notify.sh script +the mode. But this has to be done every time the cert is renewed. +The systemd `acme-tiny.service` runs `acme-tiny-notify.service` +afterward which executes as root. It calls +`/usr/libexec/acme-tiny/notify` for each nenewed cert. (This used +to be `/etc/acme-tiny/notify.sh` - which is now a symlink.) + +Suppose `/var/lib/acme/certs/mail.crt` is renewed, where `mail.crt` is the +certificate sendmail will use. The notify script sees the reference to `/etc/pki/tls/certs/mail.crt` in `/etc/mail/*.cf`, and -copies it to `/etc/pki/tls/certs`. Sendmail can then load it from there and be -happy. This also solves the file context problem if you add lines for other -certificates. You might wonder why we don't simply supply an acme incrontab as -part of the package with a wildcard, for example: -``` -/var/lib/acme/certs/*.crt IN_MOVED_TO /etc/acme-tiny/notify.sh $@ -``` -The answer is that incron is insecure, and very nasty things can be -done by putting shell meta characters (including semicolon and quote!) in -filenames that then become part of a command run as root. The first example -above uses a fixed filename, so that is safe. Complain to incron -upstream - they need an option to use a simple execvpe instead of -using the shell. Then it would at least be possible to carefully -handle [malicious names](https://www.xkcd.com/327/). +copies the renewed cert to `/etc/pki/tls/certs`. Sendmail can then load it +from there and be happy. This also solves the file context problem. + +The notify script has built in support for the httpd, sendmail, and dovecot +packages for Fedora. To avoid restarting services multiple times, +the notify script records in `/var/lib/acme/.notify` +when it last restarted each service. + +By dropping scripts with names ending in `.sh` in `/etc/acme-tiny/notify.d`, +additional packages (e.g. nginx) can be supported. + +This new system should be compatible with older incrond configs, +but the additional `/etc/acme-tiny/notify.sh` calls from incrond are redundant. +Making them redundant, incidentally fixes +[BZ#1839904](https://bugzilla.redhat.com/show_bug.cgi?id=1839904). There +could still be a race condition missed in testing, so I would disable your old +acme incrontab. ## Logging and Error Reporting @@ -140,3 +149,4 @@ so notify.sh simply does `apachectl graceful`. Put all the CSRs in `/var/lib/acme/csr` and the acme-tiny service will keep them all renewed. This also works for certificates used by other SSL applications, such as dovecot, sendmail, jabberd, or znc. + diff --git a/acme-tiny-notify.service b/acme-tiny-notify.service new file mode 100644 index 0000000..bcd93b7 --- /dev/null +++ b/acme-tiny-notify.service @@ -0,0 +1,8 @@ +[Unit] +Description=Notify services of updates to acme certs + +[Service] +Type=oneshot +Nice=19 +SyslogIdentifier=acme-tiny +ExecStart=/usr/libexec/acme-tiny/notify --scan diff --git a/acme-tiny.service b/acme-tiny.service index a9bedfc..7b3f21b 100644 --- a/acme-tiny.service +++ b/acme-tiny.service @@ -1,5 +1,7 @@ [Unit] Description=Check for acme certs about to expire +Wants=acme-tiny-notify.service +Before=acme-tiny-notify.service [Service] Type=oneshot diff --git a/acme-tiny.spec b/acme-tiny.spec index 70f8abd..a5b1825 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 4.1.0 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -23,6 +23,7 @@ Source7: acme-tiny.service Source8: README-fedora.md # simple script hook to kick services when cert is updated Source9: notify.sh +Source10: acme-tiny-notify.service Requires(pre): shadow-utils # systemd macros are not defined unless systemd is present @@ -47,7 +48,7 @@ This package adds a simple directory layout and timer service that runs acme_tiny on installed CSRs as the acme user for privilege separation. %package core -Summary: core python module of acme-tiny +Summary: Core python module of acme-tiny Requires: openssl %if 0%{?rhel} >= 5 && 0%{?rhel} < 7 # EL6 uses python2.6, which does not include argparse @@ -75,20 +76,22 @@ mkdir -p %{buildroot}/var/www/challenges mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d mkdir -p %{buildroot}%{_sbindir} mkdir -p %{buildroot}%{_libexecdir}/%{name} -mkdir -p %{buildroot}%{_sharedstatedir}/acme/{private,csr,certs} +mkdir -p %{buildroot}%{_sharedstatedir}/acme/{private,csr,certs,.notify} mkdir -p %{buildroot}%{_sysconfdir}/%{name}/notify.d chmod 0700 %{buildroot}%{_sharedstatedir}/acme/private install -m 0755 acme-tiny-sign.sh %{buildroot}%{_libexecdir}/%{name}/sign +install -m 0755 %{SOURCE9} %{buildroot}%{_libexecdir}/%{name}/notify install -m 0755 acme_tiny.py %{buildroot}%{_sbindir}/acme_tiny ln -sf acme_tiny %{buildroot}%{_sbindir}/%{name} ln -sf %{_libexecdir}/%{name}/sign %{buildroot}%{_sbindir}/acme-tiny-sign +ln -sf %{_libexecdir}/%{name}/notify %{buildroot}%{_sysconfdir}/%{name}/notify.sh install -m 0755 cert-check.py %{buildroot}%{_sbindir}/cert-check install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/httpd/conf.d -install -m 0755 %{SOURCE9} %{buildroot}%{_sysconfdir}/%{name} mkdir -p %{buildroot}%{_unitdir} install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} install -pm 644 %{SOURCE7} %{buildroot}%{_unitdir} +install -pm 644 %{SOURCE10} %{buildroot}%{_unitdir} %pre getent group acme > /dev/null || groupadd -r acme @@ -98,13 +101,13 @@ getent passwd acme > /dev/null || /usr/sbin/useradd -g acme \ exit 0 %post -%systemd_post acme-tiny.service acme-tiny.timer +%systemd_post acme-tiny.service acme-tiny-notice.service acme-tiny.timer %postun -%systemd_postun_with_restart acme-tiny.service acme-tiny.timer +%systemd_postun_with_restart acme-tiny.service acme-tiny-notice.service acme-tiny.timer %preun -%systemd_preun acme-tiny.service acme-tiny.timer +%systemd_preun acme-tiny.service acme-tiny-notice.service acme-tiny.timer %files %{!?_licensedir:%global license %%doc} @@ -126,6 +129,10 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Thu May 27 2021 Stuart D. Gathman 4.1.0-7 +- Fix BZ#1839904 +- enhance notify after cert update, incrond no longer needed + * Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 4.1.0-6 - Rebuilt for updated systemd-rpm-macros See https://pagure.io/fesco/issue/2583. diff --git a/notify.sh b/notify.sh index fbf5f38..9c58838 100755 --- a/notify.sh +++ b/notify.sh @@ -1,25 +1,57 @@ -#!/bin/sh +#!/usr/bin/sh -cert="$1" -name="${cert##*/}" -script="/etc/acme-tiny/notify.d/${name%.crt}.sh" +acmedir="/var/lib/acme" +#acmedir="test" +notify="${acmedir}/.notify" +verbose="n" +mkdir -p "$notify" -# kick apache if cert is mentioned -if grep "$cert" /etc/httpd/conf.d/*.conf >/dev/null 2>&1; then - apachectl graceful -fi +scancerts() { + if test -e "${notify}/notify"; then + find "${acmedir}/certs" -name '*.crt' -newer "${notify}/notify" -print0 + else + find "${acmedir}/certs" -name '*.crt' -print0 + fi | xargs -0 /usr/libexec/acme-tiny/notify -v + touch "${notify}/notify" +} -# kick sendmail if cert is mentioned -if grep "/etc/pki/tls/certs/$name" /etc/mail/*.cf >/dev/null 2>&1; then - cp "$cert" /etc/pki/tls/certs && systemctl restart sendmail -fi +for cert in "$@"; do + case "$cert" in + -v|--verbose) verbose="y"; continue;; + -s|--scan) scancerts; continue;; + -*) echo "Invalid option $cert"; exit 2;; + esac + name="${cert##*/}" + script="/etc/acme-tiny/notify.d/${name%.crt}.sh" -# kick dovecot if cert is mentioned -if grep "/etc/pki/dovecot/certs/$name" /etc/dovecot/conf.d/10-ssl.conf >/dev/null 2>&1; then - cp "$cert" /etc/pki/dovecot/certs && systemctl restart dovecot -fi + # kick apache if cert is mentioned + if test "$cert" -nt "${notify}/httpd"; then + if grep "$cert" /etc/httpd/conf.d/*.conf >/dev/null 2>&1; then + apachectl graceful && touch "${notify}/httpd" && \ + [ "$verbose" = "y" ] && echo "Httpd reloaded" + fi + fi -# run any dropin extension -if test -x "$script"; then - "$script" "$cert" -fi + # kick sendmail if cert is mentioned + if test "$cert" -nt "${notify}/sendmail"; then + if grep "/etc/pki/tls/certs/$name" /etc/mail/*.cf >/dev/null 2>&1; then + cp "$cert" /etc/pki/tls/certs && systemctl restart sendmail \ + && touch "${notify}/sendmail" && \ + [ "$verbose" = "y" ] && echo "Sendmail reloaded" + fi + fi + + # kick dovecot if cert is mentioned + if test "$cert" -nt "${notify}/dovecot"; then + if grep "/etc/pki/dovecot/certs/$name" /etc/dovecot/conf.d/10-ssl.conf >/dev/null 2>&1; then + cp "$cert" /etc/pki/dovecot/certs && systemctl restart dovecot \ + && touch "${notify}/dovecot" && \ + [ "$verbose" = "y" ] && echo "Dovecot reloaded" + fi + fi + + # run any dropin extension + if test -x "$script"; then + "$script" "$cert" + fi +done From 6a6a98e3c312141c025eacefcf462a5c7f5e08ae Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 21 Jul 2021 12:18:13 +0000 Subject: [PATCH 41/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering From e96af0a3c9d613af7219e56c33e25865d7f7d8d6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 21 Jul 2021 17:13:20 +0000 Subject: [PATCH 42/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index a5b1825..3250891 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 4.1.0 -Release: 7%{?dist} +Release: 8%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -129,6 +129,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Jul 21 2021 Fedora Release Engineering - 4.1.0-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Thu May 27 2021 Stuart D. Gathman 4.1.0-7 - Fix BZ#1839904 - enhance notify after cert update, incrond no longer needed From 6606afa0cde9a826a996552d151af3f244e90a63 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Tue, 7 Sep 2021 13:33:16 -0400 Subject: [PATCH 43/61] ignore mockbuild results dir --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8d64d85..ab0b2fe 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /*.src.rpm /.build-* /acme-tiny-4.1.0.tar.gz +/results_acme-tiny From 8ae612179c2f0213eca61d862a7a1a480772df98 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Tue, 7 Sep 2021 14:35:08 -0400 Subject: [PATCH 44/61] New upstream release --- .gitignore | 1 + acme-tiny.spec | 7 +++++-- sources | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ab0b2fe..3b0550e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /.build-* /acme-tiny-4.1.0.tar.gz /results_acme-tiny +/acme-tiny-4.1.1.tar.gz diff --git a/acme-tiny.spec b/acme-tiny.spec index a5b1825..fe3641c 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -8,8 +8,8 @@ %endif Name: acme-tiny -Version: 4.1.0 -Release: 7%{?dist} +Version: 4.1.1 +Release: 1%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -129,6 +129,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Tue Sep 7 2021 Stuart D. Gathman 4.1.1-1 +- New upstream release + * Thu May 27 2021 Stuart D. Gathman 4.1.0-7 - Fix BZ#1839904 - enhance notify after cert update, incrond no longer needed diff --git a/sources b/sources index a5fdfcf..2d635b6 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (acme-tiny-4.1.0.tar.gz) = 31d69a5031c019acbc23b3f06041eae8e261766396d4a7420fd70a71cfa16de953bea4c0c2ad0c6a6e793ed61ab5331f40145352ffce69f4f062f35dd0db7519 +SHA512 (acme-tiny-4.1.1.tar.gz) = 9e1aac03f3aa744061b8b03bb7bb6ede52ccf1a72d729775f106eb0fef786ee495dedd4f44c672e4ee2a8fc385477366bf164ab5e78d85e0a031558cde68f4b1 From e84794303a636d6b4d8b209161c6b91214959cec Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Tue, 7 Sep 2021 21:45:22 -0400 Subject: [PATCH 45/61] Set default days before expiration in /etc/sysconfig/acme-tiny --- acme-tiny-sign.sh | 5 ++++- acme-tiny.conf | 4 ++++ acme-tiny.spec | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 acme-tiny.conf diff --git a/acme-tiny-sign.sh b/acme-tiny-sign.sh index d2f1799..9999005 100755 --- a/acme-tiny-sign.sh +++ b/acme-tiny-sign.sh @@ -5,8 +5,11 @@ if test "$(id -u)" -eq 0; then exit 2 fi -DAYS="${1:-7}" +. /etc/sysconfig/acme-tiny +DAYS="${1:-$DAYS}" +test -n "$DAYS" || DAYS="7" if [[ "$DAYS" =~ ^[0-9]+$ ]]; then + echo "Days before expiration: $DAYS" secs=$(( $DAYS * 24 * 60 * 60 )) else echo "Invalid number of days: $DAYS" diff --git a/acme-tiny.conf b/acme-tiny.conf new file mode 100644 index 0000000..28e81fe --- /dev/null +++ b/acme-tiny.conf @@ -0,0 +1,4 @@ +# Default settings for acme-tiny wrapper script + +# Number of days before expiration to renew a certificate +DAYS=7 diff --git a/acme-tiny.spec b/acme-tiny.spec index fe3641c..cc2ec20 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -24,6 +24,7 @@ Source8: README-fedora.md # simple script hook to kick services when cert is updated Source9: notify.sh Source10: acme-tiny-notify.service +Source11: acme-tiny.conf Requires(pre): shadow-utils # systemd macros are not defined unless systemd is present @@ -78,6 +79,7 @@ mkdir -p %{buildroot}%{_sbindir} mkdir -p %{buildroot}%{_libexecdir}/%{name} mkdir -p %{buildroot}%{_sharedstatedir}/acme/{private,csr,certs,.notify} mkdir -p %{buildroot}%{_sysconfdir}/%{name}/notify.d +mkdir -p %{buildroot}%{_sysconfdir}/sysconfig chmod 0700 %{buildroot}%{_sharedstatedir}/acme/private install -m 0755 acme-tiny-sign.sh %{buildroot}%{_libexecdir}/%{name}/sign @@ -92,6 +94,7 @@ mkdir -p %{buildroot}%{_unitdir} install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} install -pm 644 %{SOURCE7} %{buildroot}%{_unitdir} install -pm 644 %{SOURCE10} %{buildroot}%{_unitdir} +install -m 0644 %{SOURCE11} %{buildroot}%{_sysconfdir}/sysconfig/%{name} %pre getent group acme > /dev/null || groupadd -r acme @@ -117,6 +120,7 @@ exit 0 %attr(-,acme,acme) %{_sharedstatedir}/acme %{_libexecdir}/%{name} %config(noreplace) %{_sysconfdir}/httpd/conf.d/acme.conf +%config(noreplace) %{_sysconfdir}/sysconfig/%{name} %{_unitdir}/* %{_sbindir}/acme-tiny-sign %{_sbindir}/cert-check @@ -131,6 +135,7 @@ exit 0 %changelog * Tue Sep 7 2021 Stuart D. Gathman 4.1.1-1 - New upstream release +- Set days before expiration in /etc/sysconfig * Thu May 27 2021 Stuart D. Gathman 4.1.0-7 - Fix BZ#1839904 From 4ec0479c689179ae0ff83e74f33fa38199e1cae4 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Wed, 8 Sep 2021 00:59:47 -0400 Subject: [PATCH 46/61] Remove days override in service --- acme-tiny.service | 2 +- acme-tiny.spec | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/acme-tiny.service b/acme-tiny.service index 7b3f21b..c00fc5d 100644 --- a/acme-tiny.service +++ b/acme-tiny.service @@ -11,7 +11,7 @@ ProtectSystem=true User=acme Group=acme SyslogIdentifier=acme-tiny -ExecStart=/usr/libexec/acme-tiny/sign 7 +ExecStart=/usr/libexec/acme-tiny/sign [Install] Also=acme-tiny.timer diff --git a/acme-tiny.spec b/acme-tiny.spec index f640fd7..087f59f 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 4.1.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Tue Sep 8 2021 Stuart D. Gathman 4.1.1-2 +- Remove CLI override in acme-tiny.service (uses /etc/sysconfig/acme-tiny now) + * Tue Sep 7 2021 Stuart D. Gathman 4.1.1-1 - New upstream release - Set days before expiration in /etc/sysconfig From 4c3d6134a61de2b790a304eb246de4f074422e22 Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Thu, 28 Oct 2021 19:49:03 -0400 Subject: [PATCH 47/61] Upstream release 5.0.1 --- .gitignore | 1 + acme-tiny.spec | 7 +++++-- sources | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3b0550e..c48d8bb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /acme-tiny-4.1.0.tar.gz /results_acme-tiny /acme-tiny-4.1.1.tar.gz +/acme-tiny-5.0.1.tar.gz diff --git a/acme-tiny.spec b/acme-tiny.spec index 087f59f..605194d 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -8,8 +8,8 @@ %endif Name: acme-tiny -Version: 4.1.1 -Release: 2%{?dist} +Version: 5.0.1 +Release: 1%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Thu Oct 28 2021 Stuart D. Gathman 5.0.1-1 +- New upstream release + * Tue Sep 8 2021 Stuart D. Gathman 4.1.1-2 - Remove CLI override in acme-tiny.service (uses /etc/sysconfig/acme-tiny now) diff --git a/sources b/sources index 2d635b6..f4629f8 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ SHA512 (acme-tiny-4.1.1.tar.gz) = 9e1aac03f3aa744061b8b03bb7bb6ede52ccf1a72d729775f106eb0fef786ee495dedd4f44c672e4ee2a8fc385477366bf164ab5e78d85e0a031558cde68f4b1 +SHA512 (acme-tiny-5.0.1.tar.gz) = 6e0619917b31a5795c2c7d8aa811b46231b81fc6b57227f611f7f4b9f73eb3de669676482563c33d935a4a0812498677bcbe974663a561af61abb441a880947e From 6196b1a0ed0864900458d082939c9e502b5bbb0d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jan 2022 20:53:24 +0000 Subject: [PATCH 48/61] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 605194d..6b16467 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Jan 19 2022 Fedora Release Engineering - 5.0.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Thu Oct 28 2021 Stuart D. Gathman 5.0.1-1 - New upstream release From 51195094a81843886f36bf4bc4a2e0fed7638b02 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 20 Jul 2022 20:24:07 +0000 Subject: [PATCH 49/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 6b16467..8a877fb 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Jul 20 2022 Fedora Release Engineering - 5.0.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Wed Jan 19 2022 Fedora Release Engineering - 5.0.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild From a24ade1723530bdf6a5fb8d58ebf0d5d1a21614f Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 18 Jan 2023 21:21:34 +0000 Subject: [PATCH 50/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 8a877fb..4b5b69b 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Jan 18 2023 Fedora Release Engineering - 5.0.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Wed Jul 20 2022 Fedora Release Engineering - 5.0.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From 5614e7fd15259c5bf2a6eaf7579de573cf66aaef Mon Sep 17 00:00:00 2001 From: "Stuart D. Gathman" Date: Wed, 29 Mar 2023 00:02:46 -0400 Subject: [PATCH 51/61] Verify SPDX licence match --- acme-tiny.spec | 7 +++++-- notify.sh | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 4b5b69b..2cc8945 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Tue Mar 28 2023 Stuart D. Gathman - 5.0.1-5 +- Verified SPDX license + * Wed Jan 18 2023 Fedora Release Engineering - 5.0.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild @@ -145,7 +148,7 @@ exit 0 * Thu Oct 28 2021 Stuart D. Gathman 5.0.1-1 - New upstream release -* Tue Sep 8 2021 Stuart D. Gathman 4.1.1-2 +* Wed Sep 8 2021 Stuart D. Gathman 4.1.1-2 - Remove CLI override in acme-tiny.service (uses /etc/sysconfig/acme-tiny now) * Tue Sep 7 2021 Stuart D. Gathman 4.1.1-1 diff --git a/notify.sh b/notify.sh index 9c58838..edcd529 100755 --- a/notify.sh +++ b/notify.sh @@ -52,6 +52,7 @@ for cert in "$@"; do # run any dropin extension if test -x "$script"; then + [ "$verbose" = "y" ] && echo "Running $script $cert" "$script" "$cert" fi done From c0325ba9916cd893bb96c76942441b1fd11c3275 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jul 2023 12:51:50 +0000 Subject: [PATCH 52/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 2cc8945..5a554b9 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Jul 19 2023 Fedora Release Engineering - 5.0.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Tue Mar 28 2023 Stuart D. Gathman - 5.0.1-5 - Verified SPDX license From d0da9ba3482a6ab78cdf848997ddd80a9d1bbe71 Mon Sep 17 00:00:00 2001 From: Herr Ernst Date: Tue, 29 Aug 2023 08:21:35 +0000 Subject: [PATCH 53/61] Source dropin script So variables like $acmedir and $notify are also available and checks like for httpd and sendmail are possible in external script --- notify.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify.sh b/notify.sh index edcd529..290a95b 100755 --- a/notify.sh +++ b/notify.sh @@ -53,6 +53,6 @@ for cert in "$@"; do # run any dropin extension if test -x "$script"; then [ "$verbose" = "y" ] && echo "Running $script $cert" - "$script" "$cert" + source "$script" "$cert" fi done From 11b4bc888d591b6b1e87eb1f8165e0c1efc29464 Mon Sep 17 00:00:00 2001 From: Herr Ernst Date: Tue, 29 Aug 2023 17:15:43 +0000 Subject: [PATCH 54/61] Undo sourcing dropin script, instead pass vars as env --- notify.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notify.sh b/notify.sh index 290a95b..f3ca76b 100755 --- a/notify.sh +++ b/notify.sh @@ -53,6 +53,6 @@ for cert in "$@"; do # run any dropin extension if test -x "$script"; then [ "$verbose" = "y" ] && echo "Running $script $cert" - source "$script" "$cert" + ACMEDIR="$acmedir" NOTIFY="$notify" VERBOSE="$verbose" "$script" "$cert" fi done From f66dd5959acc72b74f3ef9829441c2452a6ffc47 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 19 Jan 2024 12:06:07 +0000 Subject: [PATCH 55/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 5a554b9..def332b 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Fri Jan 19 2024 Fedora Release Engineering - 5.0.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Wed Jul 19 2023 Fedora Release Engineering - 5.0.1-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild From ac00c1c43e2e514c45eae259db2323f7a3d5408b Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 22 Jan 2024 22:37:04 +0000 Subject: [PATCH 56/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index def332b..35ee3c8 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 7%{?dist} +Release: 8%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Mon Jan 22 2024 Fedora Release Engineering - 5.0.1-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Fri Jan 19 2024 Fedora Release Engineering - 5.0.1-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 91e84d7225eb0797eb674dbe2080ec811e717a37 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 17 Jul 2024 16:33:22 +0000 Subject: [PATCH 57/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 35ee3c8..e3bfb0c 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 8%{?dist} +Release: 9%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Jul 17 2024 Fedora Release Engineering - 5.0.1-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Mon Jan 22 2024 Fedora Release Engineering - 5.0.1-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From c41bfb7f5727586797eac9027c231b564b74fb19 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 10:31:50 +0000 Subject: [PATCH 58/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index e3bfb0c..768c3de 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 9%{?dist} +Release: 10%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -133,6 +133,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Thu Jan 16 2025 Fedora Release Engineering - 5.0.1-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Wed Jul 17 2024 Fedora Release Engineering - 5.0.1-9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From e2cc44637e45c5e30777febb9660ab12981319cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 16 Jan 2025 18:37:46 +0100 Subject: [PATCH 59/61] Add sysusers.d config file This will help with https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers. Once automatic creation in rpm is turned on, the scriptlets can be dropped here. For now, just add a sysusers file that is equivalent to the scriptlets, to allow rpm to generate its metadata. --- acme-tiny.spec | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 768c3de..dde3585 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 10%{?dist} +Release: 11%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -27,8 +27,7 @@ Source10: acme-tiny-notify.service Source11: acme-tiny.conf Requires(pre): shadow-utils -# systemd macros are not defined unless systemd is present -BuildRequires: systemd +BuildRequires: systemd-rpm-macros %{?systemd_requires} Requires: %{name}-core = %{version}-%{release} BuildArch: noarch @@ -70,6 +69,8 @@ sed -i.orig -e '1,1 s,^.*python$,#!/usr/bin/python,' acme_tiny.py sed -i.old -e '1,1 s/python$/python3/' *.py %endif +echo 'u acme - "Tiny Auditable ACME Client" %{_sharedstatedir}/acme' >acme.sysusers.conf + %build %install @@ -95,6 +96,7 @@ install -pm 644 %{SOURCE6} %{buildroot}%{_unitdir} install -pm 644 %{SOURCE7} %{buildroot}%{_unitdir} install -pm 644 %{SOURCE10} %{buildroot}%{_unitdir} install -m 0644 %{SOURCE11} %{buildroot}%{_sysconfdir}/sysconfig/%{name} +install -m 0644 -D acme.sysusers.conf %{buildroot}%{_sysusersdir}/acme.conf %pre getent group acme > /dev/null || groupadd -r acme @@ -126,6 +128,7 @@ exit 0 %{_sbindir}/cert-check %{_sbindir}/%{name} %{_sysconfdir}/%{name} +%{_sysusersdir}/acme.conf %files core %license LICENSE @@ -133,6 +136,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Thu Jan 16 2025 Zbigniew Jędrzejewski-Szmek - 5.0.1-11 +- Add sysusers.d config file + * Thu Jan 16 2025 Fedora Release Engineering - 5.0.1-10 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From a96fdb7828e634cab09a79c3379c2ec847b68d16 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 16:43:50 +0000 Subject: [PATCH 60/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index dde3585..89f8288 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 11%{?dist} +Release: 12%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -136,6 +136,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Wed Jul 23 2025 Fedora Release Engineering - 5.0.1-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Thu Jan 16 2025 Zbigniew Jędrzejewski-Szmek - 5.0.1-11 - Add sysusers.d config file From cb5965263c065409c6dde0aecbaad31b30f75059 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 16 Jan 2026 03:25:13 +0000 Subject: [PATCH 61/61] Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild --- acme-tiny.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme-tiny.spec b/acme-tiny.spec index 89f8288..c4e4387 100644 --- a/acme-tiny.spec +++ b/acme-tiny.spec @@ -9,7 +9,7 @@ Name: acme-tiny Version: 5.0.1 -Release: 12%{?dist} +Release: 13%{?dist} Summary: Tiny auditable script to issue, renew Let's Encrypt certificates License: MIT @@ -136,6 +136,9 @@ exit 0 %{_sbindir}/acme_tiny %changelog +* Fri Jan 16 2026 Fedora Release Engineering - 5.0.1-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild + * Wed Jul 23 2025 Fedora Release Engineering - 5.0.1-12 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild