--- /dev/null
+Alias /.well-known/acme-challenge /var/lib/dehydrated/acme-challenges
+<Directory /var/lib/dehydrated/acme-challenges>
+ # Apache 2.x
+ <IfModule !mod_authz_core.c>
+ Order allow,deny
+ Allow from all
+ </IfModule>
+ # Apache 2.4
+ <IfModule mod_authz_core.c>
+ Require all granted
+ </IfModule>
+</Directory>
--- /dev/null
+MAILTO=root
+
+42 02 * * 2 root /usr/sbin/dehydrated -c > /dev/null
--- /dev/null
+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
--- /dev/null
+#example.org www.example.org example.net
--- /dev/null
+#!/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
--- /dev/null
+alias.url += (
+ "/.well-known/acme-challenge" => "/var/lib/dehydrated/acme-challenges",
+)
--- /dev/null
+location /.well-known/acme-challenge {
+ alias /var/lib/dehydrated/acme-challenges;
+}
--- /dev/null
+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: <unset>)
+ #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: <unset>
+-#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"