mirror of
https://github.com/laurivosandi/certidude
synced 2024-11-17 02:16:45 +00:00
198 lines
5.0 KiB
Plaintext
198 lines
5.0 KiB
Plaintext
|
#!/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
|
||
|
|
||
|
[ $ACTION == "ifup" ] || exit 0
|
||
|
[ $INTERFACE == "wan" ] || exit 0
|
||
|
|
||
|
# TODO: iterate over all authorities
|
||
|
|
||
|
AUTHORITY=certidude.@authority[0]
|
||
|
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, attempting to bring up IPsec tunnel..."
|
||
|
ipsec up client-to-site
|
||
|
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 IPsec..."
|
||
|
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)"
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
###################################
|
||
|
### Generate /etc/ipsec.secrets ###
|
||
|
###################################
|
||
|
|
||
|
SECRETS_TEMP=$(mktemp -u)
|
||
|
|
||
|
for filename in /etc/ipsec.d/private/*.pem; do
|
||
|
echo ": RSA $filename" >> $SECRETS_TEMP
|
||
|
done
|
||
|
|
||
|
uci commit
|
||
|
|
||
|
mv $SECRETS_TEMP /etc/ipsec.secrets
|
||
|
mv $IPSEC_TEMP /etc/ipsec.conf
|
||
|
mv $CERTIFICATE_TEMP $CERTIFICATE_PATH
|
||
|
|
||
|
# Enable services
|
||
|
/etc/init.d/ipsec enable
|
||
|
|
||
|
# Restart services
|
||
|
/etc/init.d/ipsec restart
|
||
|
|
||
|
sleep 2
|
||
|
|
||
|
ipsec up client-to-site
|