Last active
October 26, 2019 01:34
-
-
Save craigphicks/20681c2eb7c04e3921980c11862265c4 to your computer and use it in GitHub Desktop.
self managed private CA and certs - no config files, two levels only, no intermediate, no revocation list, file names are CN - ideal for personal IoT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# craigphicks 2019 | |
set -u | |
function CreateCertificateAuthority { | |
if [[ $# -ne 2 ]] ; then | |
echo "two args only: CA common name, CA org name" | |
exit 1 | |
fi | |
CA_CN=${1} | |
CA_ORG=${2} | |
if ! [[ $USER = "root" ]] ; then | |
echo "must be root" | |
exit 1 | |
fi | |
CAKeyFN=$(pwd)/private/${CA_CN}.key | |
CACrtFN=$(pwd)/public/${CA_CN}.crt | |
if [[ ! -d ./private ]] ; then | |
mkdir ./private; | |
sudo chmod 700 ./private | |
fi | |
if [[ ! -d ./public ]] ; then | |
mkdir ./public; | |
fi | |
if [[ -f ${CAKeyFN} ]] || [[ -f $CACrtFN ]] ; then | |
echo "server pem or key already exist" | |
exit 2 | |
fi | |
# | |
# Create the Root Key | |
# | |
openssl genrsa -out ${CAKeyFN} 2048 || exit 3 | |
# | |
# Now self-sign this certificate using the root key. | |
# | |
# CN: CommonName | |
# OU: OrganizationalUnit | |
# O: Organization | |
# L: Locality | |
# S: StateOrProvinceName | |
# C: CountryName | |
# | |
openssl req -x509 \ | |
-new \ | |
-nodes \ | |
-key ${CAKeyFN} \ | |
-sha256 \ | |
-days 3650 \ | |
-subj "/C=US/ST=--/L=--/O=${CA_ORG}/OU=--/CN=${CA_CN}" \ | |
-out ${CACrtFN} || exit 4 | |
} | |
# $1 = server CN, $2 = CA CN | |
function CreateServerCertificate { | |
if [[ $# -ne 3 ]] ; then | |
echo "three args only: CA common name, server common name. serverAltName arg" | |
exit 10 | |
fi | |
CA_CN=${1} | |
SRV_CN=${2} | |
subjectAltNameArg=${3} | |
for f in ./private/${SRV_CN}.key ./public/${SRV_CN}.crt ; do | |
if [[ -f $f ]] ; then echo "$f exists already"; exit 1; fi | |
done | |
mkdir $(pwd)/temp | |
CAKeyFN=$(pwd)/private/${CA_CN}.key | |
CACrtFN=$(pwd)/public/${CA_CN}.crt | |
SrvKeyFN=$(pwd)/private/${SRV_CN}.key | |
SrvCsrFN=$(pwd)/temp/${SRV_CN}.csr | |
SrvCrtFN=$(pwd)/public/${SRV_CN}.crt | |
for f in ${SrvKeyFN} ${SrvCrtFN} ; do | |
if [[ -f $f ]] ; then echo "$f already exists"; exit 1; fi | |
done | |
# | |
# Create A Certificate | |
# | |
if ! openssl genrsa -out ${SrvKeyFN} 2048 | |
then exit 12 | |
fi | |
# | |
# Now generate the certificate signing request. | |
# | |
if ! openssl req -new \ | |
-key ${SrvKeyFN} \ | |
-subj "/C=US/ST=--/L=--/O=--/OU=--/CN=${SRV_CN}" \ | |
-out ${SrvCsrFN} | |
then exit 13 | |
fi | |
# | |
# Now generate the final certificate from the signing request. | |
# | |
if ! openssl x509 -req \ | |
-in ${SrvCsrFN} \ | |
-CA ${CACrtFN} \ | |
-CAkey ${CAKeyFN} \ | |
-CAcreateserial \ | |
-extfile <(printf "subjectAltName=${subjectAltNameArg}") \ | |
-out ${SrvCrtFN} -days 3650 -sha256 | |
then exit 14 | |
fi | |
} | |
function MakeForLighttpd { | |
if [[ $# -ne 2 ]] ; then | |
echo "three args only: CA common name, server common name" | |
exit 31 | |
fi | |
CA_CN=${1} | |
SRV_CN=${2} | |
# DST_PIHOLE=${3} | |
CACrtFN=$(pwd)/public/${CA_CN}.crt | |
SrvKeyFN=$(pwd)/private/${SRV_CN}.key | |
SrvCrtFN=$(pwd)/public/${SRV_CN}.crt | |
mkdir -p lighttpd/ssl/Pihole-Home-Lan/private | |
mkdir -p lighttpd/ssl/Pihole-Home-Lan/public | |
chmod 750 lighttpd/ssl/Pihole-Home-Lan/private || exit 32 | |
SrvKeyCrtFN=lighttpd/ssl/Pihole-Home-Lan/private/${SRV_CN}.key-crt.pem | |
SrvCAChainFN=lighttpd/ssl/Pihole-Home-Lan/public/${SRV_CN}-fullchain.pem | |
if ! cat ${SrvKeyFN} ${SrvCrtFN} > ${SrvKeyCrtFN} | |
then exit 33 | |
fi | |
chmod 640 ${SrvKeyCrtFN} | |
if ! cat ${SrvCrtFN} ${CACrtFN} > ${SrvCAChainFN} | |
then exit 34 | |
fi | |
# chown -R :$SUDO_USER lighttpd | |
# sudo --set-home -u $SUDO_USER scp -r lighttpd ${DST_PIHOLE} \ | |
# || { chown -R :root lighttpd ; exit 35 ; } | |
# chown -R :root lighttpd | |
cat <<EOF | |
manually copy lighttpd directory to pihole device, e.g. | |
$SUDO_USER:$(pwd)# sudo chown -R :$SUDO_USER lighttpd | |
$SUDO_USER:$(pwd)# scp -r lighttpd user@pihole.home.lan:. | |
$SUDO_USER:$(pwd)# sudo chown -R :root lighttpd | |
$SUDO_USER:$(pwd)# ssh user@pihole.home.lan # set up for lighttpd, c.f. https://discourse.pi-hole.net/t/enabling-https-for-your-pi-hole-web-interface/5771 Note: make it www-data group readable! | |
EOF | |
} | |
trap "on_exit" 0 | |
function on_exit { | |
exitval=$? | |
if [[ $exitval -eq 0 ]] ; | |
then echo "SUCCESS" | |
else echo "FAILED with error $exitval" | |
fi | |
$(exit $exitval) | |
} | |
function Usage { | |
cat <<EOF_ | |
NOTE: NO SPACES ALLOWED IN COMMON NAMES - will be used as cert filenames. | |
$0 CreateCertificateAuthority <CA Common Name> <CA organization name> | |
$0 CreateServerCertificate <CA common name> <Server common name> <subjectAltNames> | |
$0 MakeForLighttpd <CA common name> <Server common name> | |
Examples: | |
$0 CreateCertificateAuthority Home-Lan "Self managed private certs" | |
$0 CreateServerCertificate Home-Lan Pihole-Home-Lan DNS:pihole.home.lan,DNS:pihole,IP:192.168.1.20 | |
$0 MakeForLighttpd Home-Lan Pihole-Home-Lan | |
EOF_ | |
} | |
if [[ $# -eq 0 ]] ; then Usage ; exit 1; fi | |
case $1 in | |
CreateCertificateAuthority) | |
if [[ $# -eq 3 ]] ; then CreateCertificateAuthority ${2} "${3}"; else Usage; fi | |
;; | |
CreateServerCertificate) | |
if [[ $# -eq 4 ]] ; then CreateServerCertificate ${2} ${3} ${4} ; else Usage; fi | |
;; | |
MakeForLighttpd) | |
if [[ $# -eq 3 ]] ; then MakeForLighttpd ${2} ${3} ; else Usage; fi | |
;; | |
*) Usage ; exit 1; | |
;; | |
esac | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment