Skip to content

Instantly share code, notes, and snippets.

@pedro0311
Last active January 28, 2025 22:28
Show Gist options
  • Select an option

  • Save pedro0311/bcd45dd4a0a22bf077d51de2ec43f3cc to your computer and use it in GitHub Desktop.

Select an option

Save pedro0311/bcd45dd4a0a22bf077d51de2ec43f3cc to your computer and use it in GitHub Desktop.
Script to generate server/client(s) keys for openvpn
#!/bin/sh
export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/home/root
#
# Script to generate server/client(s) keys for openvpn
# Use it on FreshTomato router
#
# Copyright (C) 2024 pedro
#
# ------------------ Some useful commands --------------------
# openssl ecparam -list_curves
# openvpn --show-tls
# openvpn --show-ciphers
# openvpn --show-digests
# CHECK pem : openssl ec -in cakey.pem -text -noout
# CHECK pem : openssl ecparam -in cakey.pem -text -param_enc explicit -noout
# CHECK csr : openssl req -in server.csr -verify -text -noout
# CHECK cert: openssl x509 -in server.crt -text -noout
# --------------------------------------------------------------
KEYS_TYPE="$1"
COUNT_CLIENTS="$2"
HOST="$3"
show_help() {
echo -e "\nScript to generate server/client(s) keys for openvpn; (C) 2024 pedro"
echo -e "Use it on a FreshTomato router.\n"
echo -e "Usage: $0 ecdh|rsa [number_of_clients] [hostname]\n"
echo -e " ecdh|rsa - type of keys"
echo -e " number_of_clients - optional, self explanatory, default: 1"
echo -e " hostname - optional, if you generate for different server than"
echo -e " this one on FT router use its hostname"
echo -e "\nECDH keys are preferred because they are smaller and also generating"
echo -e "DH params for RSA keys can take very long time\n"
exit 0
}
generate_ecdh() {
# (ecdsa-with-SHA256)
[ ! -f "$DIR/cacert.pem" ] && {
echo -e "\nGenerating ECDH CA cert ...\n"
# Generating cakey.pem file
openssl ecparam -genkey -name prime256v1 -out $DIR/cakey.pem -noout
# Generate the root certificate from the private key and the configs
openssl req -new -noenc -x509 -days 3650 -key $DIR/cakey.pem -out $DIR/cacert.pem -extensions v3_ca -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=server$HOSTNAME"
}
[ ! -f "$DIR/server.crt" ] && {
echo -e "\nGenerating ECDH keys for server ...\n"
# Generate the private key (server)
openssl ecparam -out $DIR/server.key -name prime256v1 -genkey -noout
# Create Certificate Signing Request
openssl req -new -noenc -key $DIR/server.key -out $DIR/server.csr -extensions server_cert -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=server"
# Generate Signed Certificate using the private key, configs and the CSR
openssl ca -batch -policy policy_anything -days 3650 -keyfile $DIR/cakey.pem -cert $DIR/cacert.pem -in $DIR/server.csr -out $DIR/server.crt -notext -extensions server_cert -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=server"
}
echo -e "\nGenerating ECDH keys for client$i ...\n"
# Generate the private key (client)
openssl ecparam -out $DIR/client$i.key -name prime256v1 -genkey -noout
# Create Certificate Signing Request
openssl req -new -noenc -key $DIR/client$i.key -out $DIR/client$i.csr -extensions usr_cert -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=client$i"
# Generate Signed Certificate using the private key, configs and the CSR
openssl ca -batch -policy policy_anything -days 3650 -keyfile $DIR/cakey.pem -cert $DIR/cacert.pem -in $DIR/client$i.csr -out $DIR/client$i.crt -notext -extensions usr_cert -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=client$i"
}
generate_rsa() {
# CA
[ ! -f "$DIR/cacert.pem" ] && {
echo -e "\nGenerating RSA CA cert ...\n"
openssl req -new -noenc -x509 -days 3650 -keyout $DIR/cakey.pem -out $DIR/cacert.pem -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=server$HOSTNAME"
}
# server (ca -verbose)
[ ! -f "$DIR/server.crt" ] && {
echo -e "\nGenerating RSA keys for server ...\n"
openssl req -new -noenc -keyout $DIR/server.key -out $DIR/server.csr -extensions server_cert -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=server"
openssl ca -batch -policy policy_anything -days 3650 -in $DIR/server.csr -out $DIR/server.crt -extensions server_cert -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=server"
openssl x509 -in $DIR/server.crt -inform PEM -out $DIR/server.crt -outform PEM
}
# client
echo -e "\nGenerating RSA keys for client$i ...\n"
openssl req -new -noenc -keyout $DIR/client$i.key -out $DIR/client$i.csr -extensions usr_cert -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=client$i"
openssl ca -batch -policy policy_anything -days 3650 -out $DIR/client$i.crt -in $DIR/client$i.csr -extensions usr_cert -subj "/C=GB/ST=Yorks/L=York/O=FT/OU=IT/CN=client$i"
openssl x509 -in $DIR/client$i.crt -inform PEM -out $DIR/client$i.crt -outform PEM
}
########################################
[ -z "$KEYS_TYPE" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ] && show_help
# Must be the same as the "dir" variable in /etc/ssl/openssl.cnf in the [ CA_default ] section
DIR="/tmp/openssl"
rm -fr $DIR >/dev/null 2>&1
mkdir -p $DIR
touch $DIR/serial
touch $DIR/index.txt
echo "00" >> $DIR/serial
KEYDIR="openvpn-keys-"$(echo $(date +%s))"-"$KEYS_TYPE
HOSTNAME=
[ -z "$COUNT_CLIENTS" ] && COUNT_CLIENTS=1
[ -z "$HOST" ] && {
NV_HOSTNAME=$(nvram get wan_domain)
[ -n "$NV_HOSTNAME" ] && HOSTNAME=".$NV_HOSTNAME"
} || {
HOSTNAME=".$HOST"
}
[ "$KEYS_TYPE" == "ecdh" ] && {
for i in $(seq 1 $COUNT_CLIENTS); do
generate_ecdh
ret=$?
[ $ret -ne 0 ] && break
done
}
[ "$KEYS_TYPE" == "rsa" ] && {
for i in $(seq 1 $COUNT_CLIENTS); do
generate_rsa
ret=$?
[ $ret -ne 0 ] && break
done
}
[ $ret -ne 0 ] && {
echo -e "\nAn error occurred while building the keys!\n\n"
} || {
mkdir -p $KEYDIR
[ "$KEYS_TYPE" == "rsa" ] && {
# DH
openssl dhparam -out $KEYDIR/dh.pem 1024
#openssl dhparam -out $KEYDIR/dh.pem 2048 # It may take a very long time!
}
mv -f $DIR/*.key $KEYDIR
mv -f $DIR/*.crt $KEYDIR
mv -f $DIR/*.csr $KEYDIR
cp -f $DIR/*.pem $KEYDIR
rm -f $KEYDIR/??.pem
# generate V1 static key
openvpn --genkey secret $KEYDIR/static.key
# and V2 static keys (to choose on)
openvpn --genkey tls-crypt-v2-server $KEYDIR/static_v2-server.key
openvpn --genkey tls-crypt-v2-client $KEYDIR/static_v2-client.key --tls-crypt-v2 $KEYDIR/static_v2-server.key
echo -e "\nDone!\nKeys are in $KEYDIR subdirectory\n\n"
}
# clean
rm -fr $DIR >/dev/null 2>&1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment