Last active
March 22, 2025 04:34
-
-
Save mathershifter/a8f6b50c366706b2c28c39a447ea7539 to your computer and use it in GitHub Desktop.
This file contains hidden or 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/sh | |
# | |
# Lab / Testing CA | |
# | |
# generates: | |
# - a local authority | |
# - signs a server cert with a CN matching the hostname | |
# - client server for auth | |
# | |
# config: | |
# - creates an ssl profile | |
# - enables eapi with ssl/tls (for testing) | |
# | |
# Note: this script will invalidate any previously generated client and server certs | |
# | |
# usage: | |
# ./eos_ca.sh | |
# or ignore the warning... | |
# yes | ./eos_ca.sh | |
set -x | |
set -e | |
: ${HOSTNAME:=`hostname`} | |
#: ${USER:=`whoami`} | |
SSL_PROFILE=EOSCA | |
PASSPHRASE=eosca | |
# add custom alt names i.e. "DNS:${HOSTNAME}.sub.arista.io,DNS:somename.region.arista.io" | |
EXTRA_SAN= | |
# if any of the variables are left undefined the script will try to 'figure it out' | |
MGMT_VRF= | |
MGMT_NS= | |
MGMT_IP= | |
DNS_DOMAIN= | |
# DN | |
C=US | |
ST=CA | |
L="Santa Clara" | |
O=Arista | |
OU=CE | |
CA_CN="${OU} CA Root" | |
CLIENT_CN=admin | |
OPENSSL_CNF=/etc/ssl/openssl.cnf | |
CA_DIR=/etc/pki/CA | |
CERTS_DIR=${CA_DIR}/certs | |
PRIVATE_DIR=${CA_DIR}/private | |
TMP=/var/tmp | |
confirm() { | |
read -p "$1 (y/N)" -n 1 -r | |
echo | |
if [[ ! $REPLY =~ ^[Yy]$ ]] | |
then | |
echo Abort! | |
exit 0 | |
fi | |
} | |
MGMT_INTF_CONFIG=`Cli -p15 -c "show running-config section ^interface Management(0|1)$"` | |
if [ -z $MGMT_IP ]; then | |
# get management ip ad domain for SAN list | |
MGMT_IP=`echo "${MGMT_INTF_CONFIG}" | grep -m 1 'ip address' | awk '{print \$3}' | awk -F\/ '{print \$1}'` | |
fi | |
if [ -z $MGMT_VRF ]; then | |
# get manamgement vrf | |
MGMT_VRF=`echo "${MGMT_INTF_CONFIG}" | grep vrf | awk '{print \$2}'` | |
fi | |
if [ ${MGMT_VRF} != "" ] && [ ${MGMT_VRF} != "default" ]; then | |
MGMT_NS="ns-${MGMT_VRF}" | |
fi | |
if [ -z ${DNS_DOMAIN}]; then | |
DNS_DOMAIN=`Cli -p15 -c "show dns domain"` | |
fi | |
SAN="DNS:localhost,DNS:${HOSTNAME}" | |
if [ ${DNS_DOMAIN} != "" ]; then | |
SAN=${SAN},DNS:${HOSTNAME}.${DNS_DOMAIN} | |
fi | |
if [ ${MGMT_IP} != "" ]; then | |
SAN=${SAN},IP:${MGMT_IP} | |
fi | |
if [ ${EXTRA_SAN} != "" ]; then | |
SAN=${SAN},${EXTRA_SAN} | |
fi | |
cat << EOF | |
## SETTINGS ## | |
MGMT_IP: ${MGMT_IP} | |
MGMT_VRF: ${MGMT_VRF} | |
MGMT_NS: ${MGMT_NS} | |
DNS_DOMAIN: ${DNS_DOMAIN} | |
SAN ${SAN} | |
EOF | |
confirm "**DELETE** and re-generate the local CA and all certificates?" | |
sudo -v | |
sudo bash <<EOF | |
find /etc/pki/CA -type f | xargs rm | |
touch ${CA_DIR}/index.txt | |
echo 1000 > "${CA_DIR}/serial" | |
EOF | |
# enable copy extensions in openssl config | |
sudo sed -i 's/^#\? *copy_extensions.*/copy_extensions = copy/' /etc/ssl/openssl.cnf | |
# | |
# CA | |
# | |
sudo openssl genrsa -out ${PRIVATE_DIR}/cakey.pem 2048 | |
sudo openssl req \ | |
-batch -new -x509 -sha256 -days 3750 \ | |
-passout pass:${PASSPHRASE} \ | |
-config ${OPENSSL_CNF} \ | |
-key ${PRIVATE_DIR}/cakey.pem \ | |
-out ${CA_DIR}/cacert.pem \ | |
-subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CA_CN}" \ | |
-extensions v3_ca | |
# | |
# Server | |
# | |
openssl genrsa -out ${TMP}/${HOSTNAME}.key.pem 2048 | |
openssl req -new -sha256 \ | |
-config ${OPENSSL_CNF} \ | |
-key ${TMP}/${HOSTNAME}.key.pem \ | |
-out ${TMP}/${HOSTNAME}.csr.pem \ | |
-subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${HOSTNAME}" \ | |
-addext "subjectAltName = $SAN" | |
sudo openssl ca -batch -config ${OPENSSL_CNF} \ | |
-days 375 -md sha256 -notext \ | |
-in ${TMP}/${HOSTNAME}.csr.pem \ | |
-out ${TMP}/${HOSTNAME}.cert.pem \ | |
# | |
# Client | |
# | |
openssl genrsa -out ${TMP}/${CLIENT_CN}.key.pem 2048 | |
openssl req -new -sha256 \ | |
-config ${OPENSSL_CNF} \ | |
-key ${TMP}/${CLIENT_CN}.key.pem \ | |
-out ${TMP}/${CLIENT_CN}.csr.pem \ | |
-subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CLIENT_CN}" | |
sudo openssl ca -batch -config ${OPENSSL_CNF} \ | |
-days 375 -md sha256 -notext \ | |
-in ${TMP}/${CLIENT_CN}.csr.pem \ | |
-out ${TMP}/${CLIENT_CN}.cert.pem \ | |
-extensions usr_cert | |
# | |
# Install | |
# | |
Cli -p 15 -c "copy file:${CA_DIR}/cacert.pem certificate: | |
copy file:${TMP}/${HOSTNAME}.cert.pem certificate: | |
copy file:${TMP}/${HOSTNAME}.key.pem sslkey:" | |
Cli -p 15 -c " | |
configure | |
management security | |
ssl profile ${SSL_PROFILE} | |
trust certificate cacert.pem | |
certificate ${HOSTNAME}.cert.pem key ${HOSTNAME}.key.pem | |
end" | |
Cli -p 15 -c "show management security ssl profile ${SSL_PROFILE}" | |
# test the client certs with eapi... | |
Cli -p15 -c "configure | |
management api http-commands | |
protocol https ssl profile ${SSL_PROFILE} | |
no shutdown | |
end" | |
if [ -n ${MGMT_VRF} ]; then | |
Cli -p15 -c "configure | |
management api http-commands | |
vrf ${MGMT_VRF} | |
no shutdown | |
end" | |
fi | |
sleep 5 | |
CURL='curl' | |
if [ -n ${MGMT_NS} ]; then | |
CURL="sudo ip netns exec ${MGMT_NS} ${CURL}" | |
fi | |
$CURL -X POST -d "show hostname" \ | |
--cacert ${CA_DIR}/cacert.pem \ | |
--cert ${TMP}/${CLIENT_CN}.cert.pem \ | |
--key ${TMP}/${CLIENT_CN}.key.pem \ | |
https://${HOSTNAME}/command-api | |
echo "DONE" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment