Minimal SSH certificate authority.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 10 Jul 2011 22:17:11 +0000 (23:17 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 10 Jul 2011 22:17:11 +0000 (23:17 +0100)
.gitignore [new file with mode: 0644]
bin/update-ssh-certs [new file with mode: 0755]
etc/config [new file with mode: 0644]
etc/hosts [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..9bcbb6e
--- /dev/null
@@ -0,0 +1,2 @@
+keys
+log
diff --git a/bin/update-ssh-certs b/bin/update-ssh-certs
new file mode 100755 (executable)
index 0000000..cb202cd
--- /dev/null
@@ -0,0 +1,116 @@
+#! /bin/bash
+###
+### Update the site's SSH certificates.
+
+set -e
+cd "${0%/*}/.."
+
+###--------------------------------------------------------------------------
+### General setup stuff.
+
+## Read in a configuration file.
+if [ -f etc/config ]; then . etc/config; fi
+: ${keytypes="rsa:3072 dsa:1024"}
+: ${domain="your.site.example"}
+: ${cacomment="ssh-ca@$domain"}
+: ${scope="*.$domain"}
+: ${validity="-1d:+7d"}
+
+## The key types are adorned with bit lengths.  Work out the raw key type
+## names.
+cakeytypes=""
+for kt in $keytypes; do
+  cakeytypes="$cakeytypes ${kt%:*}"
+done
+
+## Make the keys if necessary.
+mkdir -p keys
+for kt in $keytypes; do
+  case $kt in
+    *:*) bits=-b${kt#*:} kt=${kt%:*} ;;
+    *) bits="" ;;
+  esac
+  if [ ! -f keys/ca-$kt ]; then
+    ssh-keygen -fkeys/ca-$kt -t$kt $bits -C"$cacomment" -N ""
+  fi
+  read pub <keys/ca-$kt.pub
+  echo "@cert-authority $scope $pub" >keys/ca-$kt.entry
+done
+
+## Functions for managing concurrency.
+kids=""
+mkdir -p log
+run () {
+  tag=$1; shift
+  "$@" >log/$tag 2>&1&
+  kids="$kids $tag:$!"
+}
+
+reap () {
+  outcome=0
+  for kid in $kids; do
+    tag=${kid%:*}
+    set +e; wait ${kid#*:}; rc=$?; set -e
+    case $rc in
+      0) ;;
+      *)
+       echo >&2 "$0: $tag failed (rc = $rc)"
+       sed 's,^,| ,' log/$tag
+       outcome=1
+       ;;
+    esac
+  done
+  return $outcome
+}
+
+## Read the hosts.
+dohost () {
+  host=$1; shift
+
+  set -x
+  hostkeytypes=$(
+    ssh $host "
+       cd /etc/ssh
+       for kt in $cakeytypes; do
+         if [ -f ssh_host_\${kt}_key.pub ]; then echo \$kt; fi
+       done"
+  )
+  names=""
+  for n in "$host" "$@"; do
+    names=${names:+$names,}$n
+    case "$n" in ".") ;; *) names=${names:+$names,}$n.$domain ;; esac
+  done
+  any=nil
+  for kt in $hostkeytypes; do
+    scp $host:/etc/ssh/ssh_host_${kt}_key.pub keys/$host-$kt.pub
+    ssh-keygen -skeys/ca-$kt \
+      -h -I"$cacomment:$host.$domain" -n$names \
+      -V$validity \
+      keys/$host-$kt.pub
+    scp keys/$host-$kt-cert.pub $host:/etc/ssh/ssh_host_${kt}_key-cert.pub
+    any=t
+  done
+  case "$any" in nil) echo >&2 "no matching key types"; exit 1 ;; esac
+}
+
+dotry () {
+  host=$1; shift
+  ping -c5 -q $host >/dev/null 2>&1 || return 0
+  dohost "$host" "$@"
+}
+
+must () { run "$1" dohost "$@"; }
+try () { run "$1" dotry "$@"; }
+
+. etc/hosts
+reap
+
+last=%%%
+for i in keys/*.pub; do
+  case "$i" in *-cert.pub) continue ;; esac
+  host=${i%-*}
+  case "$host" in "$last") ;; *) echo; echo "$host" ;; esac
+  last=$host
+  ssh-keygen -lv -f "$i" | sed 's,^,| ,'
+done >distorted-host-keys.new
+mv distorted-host-keys.new distorted-host-keys
diff --git a/etc/config b/etc/config
new file mode 100644 (file)
index 0000000..425bf9a
--- /dev/null
@@ -0,0 +1,5 @@
+### -*-sh-*-
+
+keytypes="rsa:3128 dsa:1024"
+domain=distorted.org.uk
+scope="*.distorted.org.uk,62.49.204.144,62.49.204.145,62.49.204.146,62.49.204.147,62.49.204.148,62.49.204.149,62.49.204.15?,172.29.198.*,172.29.199.*"
diff --git a/etc/hosts b/etc/hosts
new file mode 100644 (file)
index 0000000..866315c
--- /dev/null
+++ b/etc/hosts
@@ -0,0 +1,17 @@
+### -*-conf-*-
+
+## Servers.
+must ibanez 62.49.204.153 172.29.199.14
+must radius 62.49.204.146 172.29.199.2 172.29.198.1
+must roadstar 62.49.204.147 172.29.199.2
+must jem 62.49.204.148 172.29.199.3
+must artist 62.49.204.149 172.29.199.4
+must vampire git 62.49.204.150 172.29.199.5 172.29.198.3
+
+## Workstation and occasional guests.
+must gibson
+try marauder
+try invader
+
+## Mobile.
+try crybaby