#!/bin/sh # To paste, press Ctrl-D to finish: cat > /etc/hotplug.d/iface/50-certidude # To test: ACTION=ifup INTERFACE=wan sh /etc/hotplug.d/iface/50-certidude # TODO: renewal AUTHORITY=certidude.@authority[0] [ $ACTION == "ifup" ] || exit 0 [ $INTERFACE == "$(uci get $AUTHORITY.trigger)" ] || exit 0 # TODO: iterate over all authorities URL=$(uci get $AUTHORITY.url) GATEWAY=$(uci get $AUTHORITY.gateway) COMMON_NAME=$(uci get $AUTHORITY.common_name) if [ $? -ne 0 ]; then COMMON_NAME=$(uci get system.@system[0].hostname) fi KEY_PATH=$(uci get $AUTHORITY.key_path) KEY_TYPE=$(uci get $AUTHORITY.key_type) KEY_LENGTH=$(uci get $AUTHORITY.key_length) CERTIFICATE_PATH=$(uci get $AUTHORITY.certificate_path) REQUEST_PATH=$(uci get $AUTHORITY.request_path) AUTHORITY_PATH=$(uci get $AUTHORITY.authority_path) RED_LED=/sys/class/leds/$(uci get $AUTHORITY.red_led) GREEN_LED=/sys/class/leds/$(uci get $AUTHORITY.green_led) NTP_SERVERS=$(uci get system.ntp.server) logger -t certidude -s "Fetching time from NTP servers: $NTP_SERVERS" ntpd -q -n -d -p $NTP_SERVERS logger -t certidude -s "Time is now: $(date)" # If certificate file is there assume everything's set up if [ -f $CERTIFICATE_PATH ]; then SERIAL=$(openssl x509 -in $CERTIFICATE_PATH -noout -serial | cut -d "=" -f 2 | tr [A-F] [a-f]) logger -t certidude -s "Certificate with serial $SERIAL already exists in $CERTIFICATE_PATH, attempting to bring up VPN tunnel..." /etc/init.d/openvpn start /etc/init.d/ipsec start exit 0 fi # Turn green off and red on if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then echo timer > $GREEN_LED/trigger echo 100 | tee $GREEN_LED/delay_* echo none > $RED_LED/trigger fi ######################################### ### Generate private key if necessary ### ######################################### if [ ! -f $KEY_PATH ]; then KEY_TEMP=$(mktemp -u) logger -t certidude -s "Generating RSA key for VPN..." if [ -d $GREEN_LED ]; then echo 250 | tee $GREEN_LED/delay_* fi openssl gen$KEY_TYPE -out $KEY_TEMP $KEY_LENGTH chmod 0600 $KEY_TEMP mv $KEY_TEMP $KEY_PATH fi ############################ ### Fetch CA certificate ### ############################ if [ ! -f $AUTHORITY_PATH ]; then AUTHORITY_TEMP=$(mktemp -u) logger -t certidude -s "Fetching CA certificate from $URL/api/certificate/" curl -f -s $URL/api/certificate/ > $AUTHORITY_TEMP if [ $? -ne 0 ]; then logger -t certidude -s "Failed to receive CA certificate, server responded: $(cat $AUTHORITY_TEMP)" if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then echo none > $GREEN_LED/trigger echo timer > $RED_LED/trigger echo 100 | tee $RED_LED/delay_* fi exit 10 fi openssl x509 -in $AUTHORITY_TEMP -noout if [ $? -ne 0 ]; then logger -t certidude -s "Received invalid CA certificate" if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then echo none > $GREEN_LED/trigger echo timer > $RED_LED/trigger echo 250 | tee $RED_LED/delay_* fi exit 11 fi mv $AUTHORITY_TEMP $AUTHORITY_PATH fi logger -t certidude -s "CA certificate md5sum: $(md5sum -b $AUTHORITY_PATH)" ##################################### ### Generate request if necessary ### ##################################### if [ ! -f $REQUEST_PATH ]; then REQUEST_TEMP=$(mktemp -u) openssl req -new -sha256 -key $KEY_PATH -out $REQUEST_TEMP -subj "/CN=$COMMON_NAME" mv $REQUEST_TEMP $REQUEST_PATH fi logger -t certidude -s "Request md5sum is $(md5sum -b $REQUEST_PATH)" # Wait for certificate if [ -d $GREEN_LED ]; then echo 500 | tee $GREEN_LED/delay_* fi CERTIFICATE_TEMP=$(mktemp -u) curl -f -L \ -H "Content-Type: application/pkcs10" \ --data-binary @$REQUEST_PATH \ $URL/api/request/?autosign=true\&wait=yes > $CERTIFICATE_TEMP # TODO: Loop until we get exitcode 0 # TODO: Use backoff time $((2\*X)) if [ $? -ne 0 ]; then echo "Failed to fetch certificate" if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then echo none > $GREEN_LED/trigger echo timer > $RED_LED/trigger echo 500 | tee $RED_LED/delay_* fi exit 21 fi # Verify certificate openssl verify -CAfile $AUTHORITY_PATH $CERTIFICATE_TEMP if [ $? -ne 0 ]; then logger -t certidude -s "Received bogus certificate!" if [ -d $GREEN_LED ] && [ -d $RED_LED ]; then echo none > $GREEN_LED/trigger echo timer > $RED_LED/trigger echo 1000 | tee $RED_LED/delay_* fi exit 22 fi logger -t certidude -s "Certificate md5sum: $(md5sum -b $CERTIFICATE_TEMP)" uci commit mv $CERTIFICATE_TEMP $CERTIFICATE_PATH # Restart services /etc/init.d/ipsec start /etc/init.d/openvpn start