From: Marcin Krol Date: Tue, 24 Oct 2017 00:29:18 +0000 (+0000) Subject: - from PLD, TLDized X-Git-Url: https://git.tld-linux.org/?p=packages%2Fdehydrated.git;a=commitdiff_plain;h=c64e35229801d5d23037b9d6e2b1d52bddd0c219 - from PLD, TLDized --- c64e35229801d5d23037b9d6e2b1d52bddd0c219 diff --git a/apache.conf b/apache.conf new file mode 100644 index 0000000..ac93b93 --- /dev/null +++ b/apache.conf @@ -0,0 +1,12 @@ +Alias /.well-known/acme-challenge /var/lib/dehydrated/acme-challenges + + # Apache 2.x + + Order allow,deny + Allow from all + + # Apache 2.4 + + Require all granted + + diff --git a/crontab b/crontab new file mode 100644 index 0000000..dc0c363 --- /dev/null +++ b/crontab @@ -0,0 +1,3 @@ +MAILTO=root + +42 02 * * 2 root /usr/sbin/dehydrated -c > /dev/null diff --git a/dehydrated.spec b/dehydrated.spec new file mode 100644 index 0000000..44ec771 --- /dev/null +++ b/dehydrated.spec @@ -0,0 +1,112 @@ +Summary: letsencrypt/acme client implemented as a shell-script +Name: dehydrated +Version: 0.4.0 +Release: 2 +License: MIT +Group: Applications/Networking +Source0: https://github.com/lukas2511/dehydrated/archive/v%{version}/%{name}-%{version}.tar.gz +# Source0-md5: 8114ba0144a158d5ad1bdf02e6f43195 +Source1: apache.conf +Source2: lighttpd.conf +Source3: nginx.conf +Source4: domains.txt +Source5: hook.sh +Source6: crontab +Patch0: tld.patch +URL: https://github.com/lukas2511/dehydrated +BuildRequires: rpmbuild(macros) >= 1.713 +Requires: ca-certificates +Requires: crondaemon +Requires: curl +Requires: diffutils +Requires: grep +Requires: mktemp +Requires: openssl-tools +Requires: sed +Requires: webapps +Suggests: webserver(access) +Suggests: webserver(alias) +BuildArch: noarch +BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n) + +%define _webapps /etc/webapps +%define _webapp %{name} +%define _sysconfdir %{_webapps}/%{_webapp} +%define _appdir %{_datadir}/%{_webapp} + +%description +This is a client for signing certificates with an ACME-server +(currently only provided by letsencrypt) implemented as a relatively +simple bash-script. + +Current features: +- Signing of a list of domains +- Signing of a CSR +- Renewal if a certificate is about to expire or SAN (subdomains) + changed +- Certificate revocation + +%prep +%setup -q +%patch0 -p1 + +%install +rm -rf $RPM_BUILD_ROOT +install -d $RPM_BUILD_ROOT{%{_sbindir},%{_sysconfdir}/certs,/etc/cron.d} \ + $RPM_BUILD_ROOT/var/lib/%{name}/{accounts,acme-challenges,certs} + +install -p %{name} $RPM_BUILD_ROOT%{_sbindir} +cp -p %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/apache.conf +cp -p %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/lighttpd.conf +cp -p %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/nginx.conf +cp -p docs/examples/config $RPM_BUILD_ROOT%{_sysconfdir} +cp -p %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir} +cp -p %{SOURCE6} $RPM_BUILD_ROOT/etc/cron.d/%{name} +install -p %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir} +cp -p $RPM_BUILD_ROOT%{_sysconfdir}/{apache,httpd}.conf + +%clean +rm -rf $RPM_BUILD_ROOT + +%triggerin -- apache1 < 1.3.37-3, apache1-base +%webapp_register apache %{_webapp} + +%triggerun -- apache1 < 1.3.37-3, apache1-base +%webapp_unregister apache %{_webapp} + +%triggerin -- apache < 2.2.0, apache-base +%webapp_register httpd %{_webapp} + +%triggerun -- apache < 2.2.0, apache-base +%webapp_unregister httpd %{_webapp} + +%triggerin -- lighttpd +%webapp_register lighttpd %{_webapp} + +%triggerun -- lighttpd +%webapp_unregister lighttpd %{_webapp} + +%triggerin -- nginx +%webapp_register nginx %{_webapp} + +%triggerun -- nginx +%webapp_unregister nginx %{_webapp} + +%files +%defattr(644,root,root,755) +%doc README.md CHANGELOG LICENSE +%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/cron.d/%{name} +%dir %attr(750,root,http) %{_sysconfdir} +%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/apache.conf +%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/httpd.conf +%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lighttpd.conf +%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/nginx.conf +%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/config +%attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/domains.txt +%attr(750,root,root) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/hook.sh +%attr(755,root,root) %{_sbindir}/%{name} +%dir %attr(751,root,root) /var/lib/%{name} +%dir %attr(700,root,root) /var/lib/%{name}/accounts +%dir %attr(700,root,root) /var/lib/%{name}/certs +# challenges written here, need to be readable by webserver +%dir %attr(751,root,root) /var/lib/%{name}/acme-challenges diff --git a/domains.txt b/domains.txt new file mode 100644 index 0000000..933e883 --- /dev/null +++ b/domains.txt @@ -0,0 +1 @@ +#example.org www.example.org example.net diff --git a/hook.sh b/hook.sh new file mode 100755 index 0000000..d5387a4 --- /dev/null +++ b/hook.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +# concat file atomic way +atomic_concat() { + local file=$1; shift + > $file.new + chmod 600 $file.new + cat "$@" > $file.new + cp -f $file $file.dehydrated~ + mv -f $file.new $file +} + +lighttpd_reload() { + if [ ! -x /usr/sbin/lighttpd ] || [ ! -f /etc/lighttpd/server.pem ]; then + return + fi + + echo " + Hook: Overwritting /etc/lighttpd/server.pem and reloading lighttpd..." + atomic_concat /etc/lighttpd/server.pem "$FULLCHAINCERT" "$PRIVKEY" + /sbin/service lighttpd reload +} + +haproxy_reload() { + if [ ! -x /usr/sbin/haproxy ] || [ ! -f /etc/haproxy/server.pem ]; then + return + fi + + echo " + Hook: Overwritting /etc/haproxy/server.pem and restarting haproxy..." + atomic_concat /etc/haproxy/server.pem "$FULLCHAINCERT" "$PRIVKEY" + /sbin/service haproxy reload +} + +nginx_reload() { + if [ ! -f /etc/nginx/server.crt ] || [ ! -f /etc/nginx/server.key ]; then + return + fi + + echo " + Hook: Overwritting /etc/nginx/server.{crt,key} and reloading nginx..." + atomic_concat /etc/nginx/server.crt "$FULLCHAINCERT" + atomic_concat /etc/nginx/server.key "$PRIVKEY" + /sbin/service nginx reload +} + +httpd_reload() { + if [ ! -x /etc/rc.d/init.d/httpd ]; then + return + fi + + echo " + Hook: Reloading Apache..." + /sbin/service httpd graceful +} + + +case "$1" in +deploy_cert) + DOMAIN="$2" + PRIVKEY="$3" + CERT="$4" + FULLCHAINCERT="$5" + CHAINCERT="$6" + TIMESTAMP="$7" + + lighttpd_reload + nginx_reload + httpd_reload + haproxy_reload + ;; +clean_challenge) + CHALLENGE_TOKEN="$2" + KEYAUTH="$3" + echo " + Hook: $1: Nothing to do..." + ;; +deploy_challenge) + echo " + Hook: $1: Nothing to do..." + ;; +unchanged_cert) + echo " + Hook: $1: Nothing to do..." + ;; +*) + echo " + Hook: $1: Nothing to do..." + ;; +esac diff --git a/lighttpd.conf b/lighttpd.conf new file mode 100644 index 0000000..0eb7625 --- /dev/null +++ b/lighttpd.conf @@ -0,0 +1,3 @@ +alias.url += ( + "/.well-known/acme-challenge" => "/var/lib/dehydrated/acme-challenges", +) diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..2ba49a4 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,3 @@ +location /.well-known/acme-challenge { + alias /var/lib/dehydrated/acme-challenges; +} diff --git a/tld.patch b/tld.patch new file mode 100644 index 0000000..2c6448e --- /dev/null +++ b/tld.patch @@ -0,0 +1,98 @@ +diff -ur dehydrated-0.4.0.orig/dehydrated dehydrated-0.4.0/dehydrated +--- dehydrated-0.4.0.orig/dehydrated 2017-02-05 14:33:17.000000000 +0000 ++++ dehydrated-0.4.0/dehydrated 2017-10-24 00:24:53.662801025 +0000 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env bash ++#!/bin/bash + + # dehydrated by lukas2511 + # Source: https://github.com/lukas2511/dehydrated +@@ -94,7 +94,7 @@ + load_config() { + # Check for config in various locations + if [[ -z "${CONFIG:-}" ]]; then +- for check_config in "/etc/dehydrated" "/usr/local/etc/dehydrated" "${PWD}" "${SCRIPTDIR}"; do ++ for check_config in "/etc/dehydrated" "/etc/webapps/dehydrated" "/usr/local/etc/dehydrated" "/etc/webapps/letsencrypt.sh" "${PWD}" "${SCRIPTDIR}"; do + if [[ -f "${check_config}/config" ]]; then + BASEDIR="${check_config}" + CONFIG="${check_config}/config" +@@ -115,7 +115,7 @@ + DOMAINS_TXT= + HOOK= + HOOK_CHAIN="no" +- RENEW_DAYS="30" ++ RENEW_DAYS="10" + KEYSIZE="4096" + WELLKNOWN= + PRIVATE_KEY_RENEW="yes" +@@ -166,7 +166,7 @@ + [[ -d "${BASEDIR}" ]] || _exiterr "BASEDIR does not exist: ${BASEDIR}" + + CAHASH="$(echo "${CA}" | urlbase64)" +- [[ -z "${ACCOUNTDIR}" ]] && ACCOUNTDIR="${BASEDIR}/accounts" ++ [[ -z "${ACCOUNTDIR}" ]] && ACCOUNTDIR="/var/lib/dehydrated/accounts" + mkdir -p "${ACCOUNTDIR}/${CAHASH}" + [[ -f "${ACCOUNTDIR}/${CAHASH}/config" ]] && . "${ACCOUNTDIR}/${CAHASH}/config" + ACCOUNT_KEY="${ACCOUNTDIR}/${CAHASH}/account_key.pem" +@@ -181,9 +181,9 @@ + mv "${BASEDIR}/private_key.json" "${ACCOUNT_KEY_JSON}" + fi + +- [[ -z "${CERTDIR}" ]] && CERTDIR="${BASEDIR}/certs" +- [[ -z "${DOMAINS_TXT}" ]] && DOMAINS_TXT="${BASEDIR}/domains.txt" +- [[ -z "${WELLKNOWN}" ]] && WELLKNOWN="/var/www/dehydrated" ++ [[ -z "${CERTDIR}" ]] && CERTDIR="/var/lib/dehydrated/certs" ++ [[ -z "${DOMAINS_TXT}" ]] && DOMAINS_TXT="/etc/webapps/dehydrated/domains.txt" ++ [[ -z "${WELLKNOWN}" ]] && WELLKNOWN="/var/lib/dehydrated/acme-challenges" + [[ -z "${LOCKFILE}" ]] && LOCKFILE="${BASEDIR}/lock" + [[ -n "${PARAM_LOCKFILE_SUFFIX:-}" ]] && LOCKFILE="${LOCKFILE}-${PARAM_LOCKFILE_SUFFIX}" + [[ -n "${PARAM_NO_LOCK:-}" ]] && LOCKFILE="" +diff -ur dehydrated-0.4.0.orig/docs/examples/config dehydrated-0.4.0/docs/examples/config +--- dehydrated-0.4.0.orig/docs/examples/config 2017-02-05 14:33:17.000000000 +0000 ++++ dehydrated-0.4.0/docs/examples/config 2017-10-24 00:23:06.163807433 +0000 +@@ -21,6 +21,7 @@ + # Path to certificate authority license terms redirect (default: https://acme-v01.api.letsencrypt.org/terms) + #CA_TERMS="https://acme-v01.api.letsencrypt.org/terms" + ++ + # Path to license agreement (default: ) + #LICENSE="" + +@@ -37,16 +38,16 @@ + #BASEDIR=$SCRIPTDIR + + # File containing the list of domains to request certificates for (default: $BASEDIR/domains.txt) +-#DOMAINS_TXT="${BASEDIR}/domains.txt" ++#DOMAINS_TXT="/etc/webapps/dehydrated/domains.txt" + + # Output directory for generated certificates +-#CERTDIR="${BASEDIR}/certs" ++#CERTDIR="/var/lib/dehydrated/certs" + + # Directory for account keys and registration information +-#ACCOUNTDIR="${BASEDIR}/accounts" ++#ACCOUNTDIR="/var/lib/dehydrated/accounts" + + # Output directory for challenge-tokens to be served by webserver or deployed in HOOK (default: /var/www/dehydrated) +-#WELLKNOWN="/var/www/dehydrated" ++#WELLKNOWN="/var/lib/dehydrated/acme-challenges" + + # Default keysize for private keys (default: 4096) + #KEYSIZE="4096" +@@ -64,13 +65,13 @@ + # + # BASEDIR and WELLKNOWN variables are exported and can be used in an external program + # default: +-#HOOK= ++#HOOK=/etc/webapps/dehydrated/hook.sh + + # Chain clean_challenge|deploy_challenge arguments together into one hook call per certificate (default: no) + #HOOK_CHAIN="no" + +-# Minimum days before expiration to automatically renew certificate (default: 30) +-#RENEW_DAYS="30" ++# Minimum days before expiration to automatically renew certificate (default: 10) ++#RENEW_DAYS="10" + + # Regenerate private keys instead of just signing new certificates on renewal (default: yes) + #PRIVATE_KEY_RENEW="yes"