Compare commits

...
Sign in to create a new pull request.

38 commits

Author SHA1 Message Date
Fedora Release Engineering
cb5965263c Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild 2026-01-16 03:25:13 +00:00
Fedora Release Engineering
a96fdb7828 Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild 2025-07-23 16:43:50 +00:00
Zbigniew Jędrzejewski-Szmek
e2cc44637e 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.
2025-01-16 18:38:21 +01:00
Fedora Release Engineering
c41bfb7f57 Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild 2025-01-16 10:31:50 +00:00
Fedora Release Engineering
91e84d7225 Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild 2024-07-17 16:33:22 +00:00
Fedora Release Engineering
ac00c1c43e Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-22 22:37:04 +00:00
Fedora Release Engineering
f66dd5959a Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-19 12:06:07 +00:00
Herr Ernst
11b4bc888d Undo sourcing dropin script, instead pass vars as env 2023-08-29 17:15:43 +00:00
Herr Ernst
d0da9ba348 Source dropin script
So variables like $acmedir and $notify are also available and checks like for httpd and sendmail are possible in external script
2023-08-29 08:21:35 +00:00
Fedora Release Engineering
c0325ba991 Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-07-19 12:51:50 +00:00
Stuart D. Gathman
5614e7fd15 Verify SPDX licence match 2023-03-29 00:09:43 -04:00
Fedora Release Engineering
a24ade1723 Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-01-18 21:21:34 +00:00
Fedora Release Engineering
51195094a8 Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-07-20 20:24:07 +00:00
Fedora Release Engineering
6196b1a0ed - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-01-19 20:53:24 +00:00
Stuart D. Gathman
4c3d6134a6 Upstream release 5.0.1 2021-10-28 19:49:03 -04:00
Stuart D. Gathman
4ec0479c68 Remove days override in service 2021-09-08 09:29:03 -04:00
Stuart D. Gathman
a9d75e6644 Merge branch 'main' of ssh://pkgs.fedoraproject.org/rpms/acme-tiny 2021-09-08 00:21:29 -04:00
Stuart D. Gathman
e84794303a Set default days before expiration in /etc/sysconfig/acme-tiny 2021-09-08 00:05:05 -04:00
Stuart D. Gathman
8ae612179c New upstream release 2021-09-07 14:35:08 -04:00
Stuart D. Gathman
6606afa0cd ignore mockbuild results dir 2021-09-07 13:33:16 -04:00
Fedora Release Engineering
e96af0a3c9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-07-21 17:13:20 +00:00
Fedora Release Engineering
6a6a98e3c3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-07-21 12:18:13 +00:00
Stuart D. Gathman
de07a8cc67 Fix sign script 2021-06-19 18:34:33 -04:00
Stuart D. Gathman
766eae26ed Fix BZ#1839904 and enhance notify script so incrond is not needed. 2021-05-28 00:08:58 -04:00
Stuart D. Gathman
23a0e06149 Add built-in kicker for dovecot 2021-03-20 13:37:08 -04:00
Zbigniew Jędrzejewski-Szmek
6859d7092c Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
2021-03-02 16:14:12 +01:00
Fedora Release Engineering
1d4a4aa823 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-01-25 23:46:09 +00:00
Fedora Release Engineering
e62eb5289d - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-07-27 11:42:21 +00:00
Stuart D. Gathman
640fa49ef9 Cleanup EL6 support and unused patches: Marcel Metz <mmetz@adrian-broher.net> 2020-04-09 13:53:30 -04:00
Stuart D. Gathman
5c6956e7cc Merge branch 'master' of ssh://pkgs.fedoraproject.org/rpms/acme-tiny 2020-04-09 13:29:04 -04:00
Stuart D. Gathman
592fc09fb7 notify.sh docs 2020-04-09 13:27:33 -04:00
Fedora Release Engineering
28ca09289c - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-01-28 11:10:00 +00:00
Stuart D. Gathman
5bf9ac63df Update README-fedora.md to describe notify.sh 2019-12-05 19:47:24 -05:00
Stuart D. Gathman
2cc9f0adbf Fix changelog 2019-12-05 19:05:55 -05:00
Stuart D. Gathman
c9d3920f74 Merge branch 'master' into epel7 2019-12-05 18:29:19 -05:00
Stuart D. Gathman
bfa7928076 Merge branch 'master' into epel7 2019-04-08 11:49:10 -04:00
Stuart D. Gathman
038d15cdf3 Merge branch 'master' into epel7 2018-05-22 17:51:52 -04:00
Stuart D. Gathman
651e6647bb Revert to python2 2017-11-22 20:55:53 -05:00
13 changed files with 222 additions and 360 deletions

3
.gitignore vendored
View file

@ -4,3 +4,6 @@
/*.src.rpm
/.build-*
/acme-tiny-4.1.0.tar.gz
/results_acme-tiny
/acme-tiny-4.1.1.tar.gz
/acme-tiny-5.0.1.tar.gz

View file

@ -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
@ -74,7 +79,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.
@ -99,34 +104,38 @@ 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/).
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.
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 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
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
@ -134,6 +143,10 @@ 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.

View file

@ -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:])

View file

@ -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:])

8
acme-tiny-notify.service Normal file
View file

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

15
acme-tiny-sign.sh Normal file → Executable file
View file

@ -1,11 +1,20 @@
#!/bin/sh
#!/bin/bash
if test "$(id -u)" -eq 0; then
echo "Do not run as root!"
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"
exit 1
fi
cd /var/lib/acme
@ -22,7 +31,7 @@ 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
if test -s "$crt" && openssl x509 -in "$crt" -noout -checkend "$secs"; then
continue
fi
if test -w "$crt" || test ! -e "$crt"; then

4
acme-tiny.conf Normal file
View file

@ -0,0 +1,4 @@
# Default settings for acme-tiny wrapper script
# Number of days before expiration to renew a certificate
DAYS=7

View file

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

View file

@ -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
@ -9,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

View file

@ -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.
@ -14,8 +8,8 @@
%endif
Name: acme-tiny
Version: 4.1.0
Release: 1%{?dist}
Version: 5.0.1
Release: 13%{?dist}
Summary: Tiny auditable script to issue, renew Let's Encrypt certificates
License: MIT
@ -24,26 +18,17 @@ 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
Source10: acme-tiny-notify.service
Source11: acme-tiny.conf
Requires(pre): shadow-utils
%if %{use_systemd}
# systemd macros are not defined unless systemd is present
BuildRequires: systemd
BuildRequires: systemd-rpm-macros
%{?systemd_requires}
%else
Requires: cronie
%endif
Requires: %{name}-core = %{version}-%{release}
BuildArch: noarch
%if 0%{?fedora}
@ -63,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
@ -81,12 +66,11 @@ 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
echo 'u acme - "Tiny Auditable ACME Client" %{_sharedstatedir}/acme' >acme.sysusers.conf
%build
%install
@ -94,26 +78,25 @@ 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
mkdir -p %{buildroot}%{_sysconfdir}/sysconfig
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 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
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
@ -122,18 +105,14 @@ 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
%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
%endif
%systemd_preun acme-tiny.service acme-tiny-notice.service acme-tiny.timer
%files
%{!?_licensedir:%global license %%doc}
@ -143,15 +122,13 @@ exit 0
%attr(-,acme,acme) %{_sharedstatedir}/acme
%{_libexecdir}/%{name}
%config(noreplace) %{_sysconfdir}/httpd/conf.d/acme.conf
%if %{use_systemd}
%config(noreplace) %{_sysconfdir}/sysconfig/%{name}
%{_unitdir}/*
%else
%config(noreplace) %{_sysconfdir}/cron.d/%{name}
%endif
%{_sbindir}/acme-tiny-sign
%{_sbindir}/cert-check
%{_sbindir}/%{name}
%{_sysconfdir}/%{name}
%{_sysusersdir}/acme.conf
%files core
%license LICENSE
@ -159,7 +136,80 @@ exit 0
%{_sbindir}/acme_tiny
%changelog
* Fri Oct 11 2019 Tim Jackson <rpm@timj.co.uK - 4.1.0-1
* Fri Jan 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
* Wed Jul 23 2025 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Thu Jan 16 2025 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 5.0.1-11
- Add sysusers.d config file
* Thu Jan 16 2025 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Wed Jul 17 2024 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Mon Jan 22 2024 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Fri Jan 19 2024 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Wed Jul 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Tue Mar 28 2023 Stuart D. Gathman <stuart@gathman.org> - 5.0.1-5
- Verified SPDX license
* Wed Jan 18 2023 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Wed Jul 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Wed Jan 19 2022 Fedora Release Engineering <releng@fedoraproject.org> - 5.0.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Thu Oct 28 2021 Stuart D. Gathman <stuart@gathman.org> 5.0.1-1
- New upstream release
* Wed Sep 8 2021 Stuart D. Gathman <stuart@gathman.org> 4.1.1-2
- Remove CLI override in acme-tiny.service (uses /etc/sysconfig/acme-tiny now)
* Tue Sep 7 2021 Stuart D. Gathman <stuart@gathman.org> 4.1.1-1
- New upstream release
- Set days before expiration in /etc/sysconfig
* Wed Jul 21 2021 Fedora Release Engineering <releng@fedoraproject.org> - 4.1.0-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Thu May 27 2021 Stuart D. Gathman <stuart@gathman.org> 4.1.0-7
- Fix BZ#1839904
- enhance notify after cert update, incrond no longer needed
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 4.1.0-6
- Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
* Mon Jan 25 2021 Fedora Release Engineering <releng@fedoraproject.org> - 4.1.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.1.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Thu Apr 9 2020 Stuart D. Gathman <stuart@gathman.org> 4.1.0-3
- Update README-fedora.md to describe notify.sh
- Apply selected changes from Marcel Metz <mmetz@adrian-broher.net>:
- 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 <releng@fedoraproject.org> - 4.1.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Fri Oct 11 2019 Tim Jackson <rpm@timj.co.uk> - 4.1.0-1
- Update to 4.1.0
* Fri Oct 11 2019 Stuart D. Gathman <stuart@gathman.org> 4.0.4-5

View file

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

View file

@ -1,20 +1,58 @@
#!/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"
# run any dropin extension
if test -x "$script"; then
"$script" "$cert"
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
# 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
[ "$verbose" = "y" ] && echo "Running $script $cert"
ACMEDIR="$acmedir" NOTIFY="$notify" VERBOSE="$verbose" "$script" "$cert"
fi
done

View file

@ -1 +1,2 @@
SHA512 (acme-tiny-4.1.0.tar.gz) = 31d69a5031c019acbc23b3f06041eae8e261766396d4a7420fd70a71cfa16de953bea4c0c2ad0c6a6e793ed61ab5331f40145352ffce69f4f062f35dd0db7519
SHA512 (acme-tiny-4.1.1.tar.gz) = 9e1aac03f3aa744061b8b03bb7bb6ede52ccf1a72d729775f106eb0fef786ee495dedd4f44c672e4ee2a8fc385477366bf164ab5e78d85e0a031558cde68f4b1
SHA512 (acme-tiny-5.0.1.tar.gz) = 6e0619917b31a5795c2c7d8aa811b46231b81fc6b57227f611f7f4b9f73eb3de669676482563c33d935a4a0812498677bcbe974663a561af61abb441a880947e