diff options
author | Erich Eckner <git@eckner.net> | 2019-08-29 11:30:11 +0200 |
---|---|---|
committer | Erich Eckner <git@eckner.net> | 2019-08-29 11:30:11 +0200 |
commit | 75f69aa7c19e1e29580bb0e4d62feb948ccdba18 (patch) | |
tree | 50c1948fb3e8b6717e255280fc3c3fe9913ba605 | |
parent | 1e1958704f12494a7dc60af5f7cf6d1fe14fd819 (diff) | |
download | simple-pki-75f69aa7c19e1e29580bb0e4d62feb948ccdba18.tar.xz |
cb stuff done
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | cb.conf | 13 | ||||
-rw-r--r-- | rotate-keys.in | 127 | ||||
-rw-r--r-- | rotate-keys.service.in | 6 | ||||
-rw-r--r-- | rotate-keys.timer | 11 | ||||
-rw-r--r-- | sign-ca.timer | 4 |
7 files changed, 170 insertions, 4 deletions
@@ -1,3 +1,5 @@ +rotate-keys +rotate-keys.service sign-ca sign-ca.service sign-request @@ -27,7 +27,7 @@ MANDIR = /usr/share/man VERSION = 0.0 -all: sign-ca sign-request sign-ca.service +all: rotate-keys rotate-keys.service sign-ca sign-ca.service sign-request %: %.in sed " \ @@ -37,8 +37,9 @@ all: sign-ca sign-request sign-ca.service s@#HELPTEXT#\(\s\+\)#@ --help \1display this help and exit\n --version\1display version and exit@; \ " $< > $@ [ "$@" = "sign-ca" ] && chmod +x "$@" || true + [ "$@" = "rotate-keys" ] && chmod +x "$@" || true -.PHONY: install dist clean +.PHONY: install-ca install-cb dist clean install-ca: install -D -m0755 -t $(DESTDIR)$(BINDIR) sign-ca sign-request @@ -46,6 +47,12 @@ install-ca: install -d -m0700 $(DESTDIR)$(ETCDIR)/simple-pki/keys install -D -m0644 -t $(DESTDIR)$(LIBDIR)/systemd/system sign-ca.service sign-ca.timer +install-cb: + install -D -m0755 -t $(DESTDIR)$(BINDIR) rotate-keys + install -D -m0644 -t $(DESTDIR)$(ETCDIR)/simple-pki cb.conf + install -d -m0700 $(DESTDIR)$(ETCDIR)/simple-pki/keys + install -D -m0644 -t $(DESTDIR)$(LIBDIR)/systemd/system rotate-keys.service rotate-keys.timer + clean: ls -A | \ grep "^\($(shell sed 's|\.|\\.|; s|\*|.*|; s|$$|\\|' .gitignore | tr '\n' '\|')\)\$$" | \ @@ -0,0 +1,13 @@ +#!/bin/bash + +# where do we belong? (must match the setting of the ca) +subject_prefix='/C=DE/ST=Thuringia/L=Jena/O=Eckner/OU=Net' + +# ignore these hosts +ignore_hosts=('localhost') + +# where should the certificates be requested? +ca_host='user@ca.example.com' + +# which user owns the certificates (not root) +certificate_user='http' diff --git a/rotate-keys.in b/rotate-keys.in new file mode 100644 index 0000000..f965928 --- /dev/null +++ b/rotate-keys.in @@ -0,0 +1,127 @@ +#!/bin/bash + +key_dir='#ETCDIR#/simple-pki/keys' + +if [ -r '#ETCDIR#/simple-pki/cb.conf' ]; then + . '#ETCDIR#/simple-pki/cb.conf' +fi + +hosts=$( + find '#ETCDIR#/nginx/' \ + -name keys -prune , \ + -name sites-available -prune , \ + \( -type f -o -type l \) \ + -exec sed -n ' + s/^\s*// + /^server_name\s.*;/ p + /^server_name[^;]*$/,/;/ p + ' {} \; 2>/dev/null \ + | tr '\n' ' ' \ + | sed ' + s/\s\+/ /g + s/;\s*/;\n/g + '"$( + printf 's/\\s%s\\(;\\|\\s\)//\n' "${ignore_hosts[@]}" + )"' + ' \ + | sed -n ' + s/^server_name // + T + s/;$// + T + p + ' \ + | sort -u +) + +host_key_files=$( + printf '%s\n' "${hosts}" \ + | cut -d' ' -f1 +) + +if [ "$(whoami)" != "${certificate_user}" ]; then + + if [ "$(whoami)" = 'root' ]; then + updated_something=false + for host_key_file in ${host_key_files}; do + if [ -f "${key_dir}/${host_key_file}.key.new" ] \ + && [ -f "${key_dir}/${host_key_file}.crt.new" ]; then + if [ "$(stat -c%Y "${key_dir}/${host_key_file}.key.new")" -ge "$(($(date +%s)-60*60*24*30))" ] \ + && [ -f "${key_dir}/${host_key_file}.key" ] \ + && [ "$(stat -c%Y "${key_dir}/${host_key_file}.crt.new")" -ge "$(($(date +%s)-60*60*24*30))" ] \ + && [ -f "${key_dir}/${host_key_file}.crt" ]; then + continue + fi + mv "${key_dir}/${host_key_file}.key"{.new,} + mv "${key_dir}/${host_key_file}.crt"{.new,} + updated_something=true + fi + done + if ${updated_something}; then + systemctl try-restart nginx + fi + + su "${certificate_user}" -s /bin/bash -c "$0" + fi + + exit +fi + +if [ -n "$(trap)" ]; then + >&2 echo 'outer traps set - those will be forgotten!' + exit 1 +fi + +tmp_dir=$(mktemp -d '/srv/http/httpdocs/.csr/tmp.XXXXXXXXXX') +trap 'rm -rf --one-file-system "${tmp_dir}"' EXIT + +printf '%s\n' "${hosts}" \ +| while read -r host other_hosts; do + if [ -f "${key_dir}/${host}.key.new" ] \ + && [ -f "${key_dir}/${host}.crt.new" ]; then + continue + fi + if [ -n "${other_hosts}" ]; then + extensions="-addext subjectAltName=$( + printf ',DNS:%s' \ + "${host}" \ + ${other_hosts} \ + | sed 's/^,//' + )" + else + extensions='' + fi + openssl req -newkey rsa:4096 \ + -keyout "${key_dir}/${host}.key.new" \ + -out "${tmp_dir}/${host}.csr" \ + -nodes -subj "${subject_prefix}"'/CN='"${host}" -sha256 \ + ${extensions} + printf 'https://%s/.csr/%s/%s.csr %s/CN=%s %s\n' \ + "${host}" \ + "${tmp_dir##*/}" \ + "${host}" \ + "${subject_prefix}" \ + "${host}" \ + "${extensions}" \ + >> "${tmp_dir}/commands" +done + +if [ ! -s "${tmp_dir}/commands" ]; then + >&2 echo 'nothing to do.' + exit +fi + +cd "${tmp_dir}" + +cut -d' ' -f1 \ +< 'commands' \ +| ssh -T "${ca_host}" \ +| tar -xzf - + +for host_key_file in ${host_key_files}; do + if [ ! -f "${tmp_dir}/${host_key_file}.crt" ]; then + continue + fi + cat "${tmp_dir}/${host_key_file}.crt" \ + > "${key_dir}/${host_key_file}.crt.new" +done diff --git a/rotate-keys.service.in b/rotate-keys.service.in new file mode 100644 index 0000000..7c933d8 --- /dev/null +++ b/rotate-keys.service.in @@ -0,0 +1,6 @@ +[Unit] +Description=rotate keys + +[Service] +Type=oneshot +ExecStart=#BINDIR#/rotate-keys diff --git a/rotate-keys.timer b/rotate-keys.timer new file mode 100644 index 0000000..d447063 --- /dev/null +++ b/rotate-keys.timer @@ -0,0 +1,11 @@ +[Unit] +Description=regularly rotate keys + +[Timer] +OnCalendar=* 00:00:00 +AccuracySec=1us +RandomizeDelaySec=10000000 +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/sign-ca.timer b/sign-ca.timer index 308a8e6..b9f9ac6 100644 --- a/sign-ca.timer +++ b/sign-ca.timer @@ -1,8 +1,8 @@ [Unit] -Description=generate and upload self-signed keys twice a year +Description=regularly generate new ca keys [Timer] -OnCalendar=*-01,05,09-01 00:00:00 +OnCalendar=* 00:00:00 AccuracySec=1us RandomizeDelaySec=10000000 Persistent=true |