mirror of
				https://github.com/laurivosandi/certidude
				synced 2025-10-30 17:09:19 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			198 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| #!/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
 |