Skip to content

Instantly share code, notes, and snippets.

@koter84
Last active February 12, 2016 15:56
Show Gist options
  • Save koter84/aa4dab2ea48ac8b96116 to your computer and use it in GitHub Desktop.
Save koter84/aa4dab2ea48ac8b96116 to your computer and use it in GitHub Desktop.
OpenWRT IPsec Certificates
#!/bin/bash
# check commands
for cmd in 'bash' 'strongswan'
do
which $cmd > /dev/null 2>&1
if [ "$?" != "0" ]
then
echo "Command not found: $cmd"
cmd_not_found="true"
fi
done
if [ "$cmd_not_found" != "" ]
then
echo "some commands not found."
exit
fi
# load defaults
if [ -f ~/.ipsec_certificates ]
then
. ~/.ipsec_certificates
else
echo "no defaults-file found at ~/.ipsec_certificates"
default_hostname="root@server"
default_C="Country"
default_O="Organisation"
default_CA="CertificateAuthority"
default_SRV="server"
fi
read -p "what is the hostname of the openwrt router? [$default_hostname] " hostname
if [ "$hostname" == "" ]
then
hostname="$default_hostname"
fi
# make tmp-dir
cert_tmp=$(mktemp -dt ipsecCerts-XXXXXX)
mkdir "$cert_tmp/cacerts" "$cert_tmp/private" "$cert_tmp/certs" "$cert_tmp/clients"
# make tmp-dir for config
config_tmp=$(mktemp -dt ipsecCertsConfig-XXXXXX)
# exit trap to cleanup when script exits
function finish {
# remove tmp-dir
rm -r "$cert_tmp"
# remove tmp-dir
rm -rf "$config_tmp"
}
trap finish EXIT
# fill tmp-dir with current certificates
scp -rq $hostname:/etc/ipsec.d/* "$cert_tmp/"
# fill tmp-dir with current config
scp -rq $hostname:/etc/ipsec.conf "$config_tmp/"
scp -rq $hostname:/etc/ipsec.secrets "$config_tmp/"
# create simple git
(cd $config_tmp; git init -q; git add ipsec.conf ipsec.secrets; git commit -q -m "config from source")
if [ -f "$cert_tmp/cacerts/caCert.pem" ]
then
read -p "do you want to regenerate all certificates? [y/N] " regenerateQ
if [ "$regenerateQ" == "Y" ] || [ "$regenerateQ" == "y" ]
then
echo "ReGenerate!"
rm $cert_tmp/cacerts/* $cert_tmp/private/* $cert_tmp/certs/* $cert_tmp/clients/*
echo "remove certificates from $hostname"
ssh $hostname 'rm /etc/ipsec.d/cacerts/* /etc/ipsec.d/private/* /etc/ipsec.d/certs/* /etc/ipsec.d/clients/*'
upload="1"
fi
fi
# on openwrt
#cmd_pki="/sbin/ipsec pki"
# on fedora
cmd_pki="/usr/sbin/strongswan pki"
# check for a CA
echo -n "> CA - "
if [ ! -f "$cert_tmp/cacerts/caCert.pem" ]
then
echo "generate"
read -p "C= [$default_C] " certC
if [ "$certC" == "" ]; then
certC="$default_C"
fi
read -p "O= [$default_O] " certO
if [ "$certO" == "" ]; then
certO="$default_O"
fi
read -p "CA= [$default_CA] " certCA
if [ "$certCA" == "" ]; then
certCA="$default_CA"
fi
$cmd_pki --gen --outform pem > "$cert_tmp/private/caKey.pem"
$cmd_pki --self --in "$cert_tmp/private/caKey.pem" --dn "C=$certC, O=$certO, CN=$certCA" --ca --outform pem > "$cert_tmp/cacerts/caCert.pem"
else
echo "found"
certC=$(openssl x509 -in "$cert_tmp/cacerts/caCert.pem" -noout -text | grep 'Subject:' | sed s/","//g | awk '{ print $2 }' | cut -d"=" -f2)
certO=$(openssl x509 -in "$cert_tmp/cacerts/caCert.pem" -noout -text | grep 'Subject:' | sed s/","//g | awk '{ print $3 }' | cut -d"=" -f2)
certCA=$(openssl x509 -in "$cert_tmp/cacerts/caCert.pem" -noout -text | grep 'Subject:' | sed s/","//g | awk '{ print $4 }' | cut -d"=" -f2)
fi
echo -n ">>"
openssl x509 -in "$cert_tmp/cacerts/caCert.pem" -noout -text | grep 'Subject:' | cut -d":" -f2
# check for a server certificate
echo -n "> SERVER - "
if [ ! -f "$cert_tmp/certs/serverCert.pem" ]
then
echo "generate"
read -p "SRV= [$default_SRV] " certSRV
if [ "$certSRV" == "" ]; then
certSRV="$default_SRV"
fi
$cmd_pki --gen --outform pem > "$cert_tmp/private/serverKey.pem"
$cmd_pki --pub --in "$cert_tmp/private/serverKey.pem" | $cmd_pki --issue --cacert "$cert_tmp/cacerts/caCert.pem" --cakey "$cert_tmp/private/caKey.pem" --dn "C=$certC, O=$certO, CN=$certSRV" --san="$certSRV" --flag serverAuth --flag ikeIntermediate --outform pem > "$cert_tmp/certs/serverCert.pem"
else
echo "found"
certSRV=$(openssl x509 -in "$cert_tmp/certs/serverCert.pem" -noout -text | grep 'Subject:' | sed s/","//g | awk '{ print $4 }' | cut -d"=" -f2)
fi
echo -n ">>"
openssl x509 -in "$cert_tmp/certs/serverCert.pem" -noout -text | grep 'Subject:' | cut -d":" -f2
# Check for client certificates
echo "> CLIENTS"
for file in $(ls "$cert_tmp/certs/")
do
if [ "$file" == "caCert.pem" ] || [ "$file" == "serverCert.pem" ]; then
continue
fi
# echo ">> $file"
echo -n ">>"
openssl x509 -in "$cert_tmp/certs/$file" -noout -text | grep 'Subject:' | cut -d":" -f2
done
echo ""
echo "> Config"
echo ">> Connections"
for conn in $(cat $config_tmp/ipsec.conf | grep 'conn' | awk '{ print $2 }')
do
echo "--> $conn"
done
echo ">> Secrets"
for secret in $(cat $config_tmp/ipsec.secrets | grep 'XAUTH' | awk '{ print $1 }')
do
echo "--> $secret"
done
# Main Loop
while true; do
echo ""
echo "Options:"
echo "1: add new client"
echo "2: store client-certificates on this computer"
echo "3: store config-files on this computer"
echo "5: edit config-files"
echo "6: upload config-files"
echo "8: save current settings to defaults-file"
echo "9: quit (and upload to $hostname)"
if [ "$upload" != "1" ]; then
echo "0: quit (without uploading)"
fi
echo ""
read -p "> " option
if [ "$option" == "" ]; then
echo "unknown option"
continue
fi
case $option in
1)
read -p "create client certificate for: " certCN
if [ "$certCN" == "" ]
then
echo "no client name given"
else
# ToDo - check if CN already exists
# create a client certificate
$cmd_pki --gen --outform pem > "$cert_tmp/private/${certCN}_key.pem"
# and sign it
$cmd_pki --pub --in "$cert_tmp/private/${certCN}_key.pem" | $cmd_pki --issue --cacert "$cert_tmp/cacerts/caCert.pem" --cakey "$cert_tmp/private/caKey.pem" --dn "C=$certC, O=$certO, CN=$certCN" --outform pem > "$cert_tmp/certs/${certCN}.pem"
echo "> $certCN"
# create a .p12
openssl pkcs12 -export -inkey "$cert_tmp/private/${certCN}_key.pem" -in "$cert_tmp/certs/${certCN}.pem" -name "$certCN" -certfile "$cert_tmp/cacerts/caCert.pem" -caname "$certCA" -out "$cert_tmp/clients/${certCN}.p12"
# create a .pem
openssl pkcs12 -in "$cert_tmp/clients/${certCN}.p12" -out "$cert_tmp/clients/${certCN}.pem" -nodes
fi
;;
2)
read -e -p "in which directory do you want to store the certificates? " storage
mkdir -p "$storage"
cp -r $cert_tmp/cacerts/caCert.pem "$storage"
echo "caCert copied to $storage"
cp -r $cert_tmp/certs/serverCert.pem "$storage"
echo "serverCert copied to $storage"
cp -r $cert_tmp/clients/* "$storage"
echo "client-files copied to $storage"
;;
3)
echo "WiP - store config"
read -e -p "in which directory do you want to store the config files? " storage
mkdir -p "$storage"
cp -r $config_tmp/ipsec.conf "$storage"
cp -r $config_tmp/ipsec.secrets "$storage"
;;
5)
echo "WiP - edit config"
cd $config_tmp
export PS1="[IPsec Config]\$ "
${SHELL}
;;
6)
echo "WiP - upload config"
scp -rq $config_tmp/ipsec.conf $hostname:/etc/ipsec.conf
scp -rq $config_tmp/ipsec.secrets $hostname:/etc/ipsec.secrets
;;
8)
echo "default_hostname=\"$hostname\"" | tee ~/.ipsec_certificates
echo "default_C=\"$certC\"" | tee -a ~/.ipsec_certificates
echo "default_O=\"$certO\"" | tee -a ~/.ipsec_certificates
echo "default_CA=\"$certCA\"" | tee -a ~/.ipsec_certificates
echo "default_SRV=\"$certSRV\"" | tee -a ~/.ipsec_certificates
echo "saved"
;;
9)
upload="1"
break
;;
0)
upload="0"
break
;;
*)
echo "option not found"
;;
esac
sleep 3
done
# [debug] show files which were changed
#find $cert_tmp/
if [ "$upload" == "1" ]
then
echo "send changes back to openwrt host $hostname"
scp -rq $cert_tmp/* $hostname:/etc/ipsec.d/
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment