Skip to content

Instantly share code, notes, and snippets.

@mathershifter
Last active March 22, 2025 04:34
Show Gist options
  • Save mathershifter/a8f6b50c366706b2c28c39a447ea7539 to your computer and use it in GitHub Desktop.
Save mathershifter/a8f6b50c366706b2c28c39a447ea7539 to your computer and use it in GitHub Desktop.
#!/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