From eb8701bb1ae2fd7e345a5a02eb882cf21a40366c Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 10 Jul 2011 23:17:11 +0100 Subject: [PATCH] Minimal SSH certificate authority. --- .gitignore | 2 + bin/update-ssh-certs | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ etc/config | 5 +++ etc/hosts | 17 ++++++++ 4 files changed, 140 insertions(+) create mode 100644 .gitignore create mode 100755 bin/update-ssh-certs create mode 100644 etc/config create mode 100644 etc/hosts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9bcbb6e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +keys +log diff --git a/bin/update-ssh-certs b/bin/update-ssh-certs new file mode 100755 index 0000000..cb202cd --- /dev/null +++ b/bin/update-ssh-certs @@ -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.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 index 0000000..425bf9a --- /dev/null +++ b/etc/config @@ -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 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 -- 2.11.0