Skip to content
Snippets Groups Projects
Commit 83a55965 authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

initial commit

parents
No related branches found
No related tags found
1 merge request!1Update docs
csr/*
log/*
inc_config.sh
templates/csr.txt
cm.sh 0 → 100755
#!/usr/bin/env bash
# ======================================================================
#
# WRAPPER FOR ACME.SH
# Let's Encrypt client
#
# requires
# - bash
# - openssl
# - curl
# - dig (opional)
# - acme.sh client
#
# ----------------------------------------------------------------------
# 2021-02-02
# ======================================================================
# ----------------------------------------------------------------------
#
# CONFIG
#
# ----------------------------------------------------------------------
selfdir="$( dirname $0 )"
touchfile="${selfdir}/log/lastchange.txt"
logfile="${selfdir}/log/certmanager-$( date +"%Y%M%d" ).log"
line="_______________________________________________________________________________"
showdebug=1
# ----------------------------------------------------------------------
#
# INTERNAL FUNCTIONS
#
# ----------------------------------------------------------------------
function _certExists(){
_listCerts | awk '{ print $1 }' | grep "^${CM_fqdn}$" >/dev/null
}
function _certMustExist(){
_certExists
if [ $? -ne 0 ]; then
echo "ERROR: cert ${CM_fqdn} was not added yet."
exit 1
fi
}
function _certMustNotExist(){
_certExists
if [ $? -eq 0 ]; then
echo "ERROR: cert ${CM_fqdn} was added already."
exit 1
fi
}
# internal function: transfer generated/ updated cert data to a
# known directory (based on ACME_Outdir - see inc_config.sh)
# used in public_add and public_renew
function _certTransfer(){
_wd "--- acme internal data"
ls -l ~/.acme.sh/${CM_fqdn}
_wd "--- transfer acme.sh files to ${CM_dircerts}"
$ACME \
--install-cert \
-d ${CM_fqdn} \
--cert-file ${CM_dircerts}/${CM_fqdn}.cert.pem \
--fullchain-file ${CM_dircerts}/${CM_fqdn}.fullchain.pem \
|| exit 1
# --key-file ${CM_dircerts}/${CM_fqdn}.key.pem \
_wd "--- copy key to ${CM_dircerts}"
cp ${CM_filekey} ${CM_dircerts}/${CM_fqdn}.key.pem
_wd "--- content of output dir $CM_dircerts:"
ls -l $CM_dircerts/*
}
# internal function: dig for given fqdn.
# Function stops if fqdn was not found in DNS.
# If dig is not found the function skips the DNS check.
# This function is used in _gencsr
# param string fqdn to check
function _checkDig(){
local myfqdn=$1
which dig >/dev/null
if [ $? -eq 0 ]; then
_wd "CHECK: $myfqdn exists in DNS (using dig) ..."
dig $myfqdn | grep -v '^;' | grep $myfqdn
if [ $? -ne 0 ]; then
echo "ERROR: not found. Was there a typo in the hostname??"
exit 2
fi
_wd "OK"
else
_wd "SKIP: dig was not found"
fi
echo
}
# internal function; generate a csr file before creating a new certifcate
# this function is used in public_add
function _gencsr(){
altdns=
_checkDig $CM_fqdn
for myalt in $*
do
altdns="${altdns},DNS:$myalt"
done
_wd "--- $CM_fqdn"
_wd "DNS alternative names: $altdns"
rm -f $CM_filecnf $CM_filekey $CM_filecsr
cat ./templates/csr.txt \
| sed "s#__FQDN__#$CM_fqdn#g" \
| sed "s#__ALTNAMES__#$altdns#g" \
> $CM_filecnf || exit 1
# generate csr
_wd "creating key and csr"
openssl req -new -config $CM_filecnf -keyout $CM_filekey -out $CM_filecsr || exit 1
# view csr
# openssl req -noout -text -in $CM_filecsr
ls -ltr $CM_filecnf $CM_filekey $CM_filecsr
}
# internal function; list certificates incl. creation date and renew date
function _listCerts(){
$ACME --list
}
function _requiresFqdn(){
if [ -z "$CM_fqdn" ]; then
echo "ERROR: 2nd parameter must be a FQDN for Main_Domain."
exit 1
fi
}
# set update message in a file
# param string(s) message
function _update(){
echo $( date ) $* > ${touchfile}
}
# write debug output if showdebug is set to 1
function _wd(){
test ${showdebug} && echo "DEBUG: $*"
}
# ----------------------------------------------------------------------
#
# PUBLIC FUNCTIONS
#
# ----------------------------------------------------------------------
#
# pulic function ADD certificate
#
function public_add(){
_requiresFqdn
_certMustNotExist
_gencsr $CM_fqdn $*
_wd "--- create output dir $dircerts"
mkdir -p "${CM_dircerts}" 2>/dev/null
# _wd "--- domains in csr"
./acme.sh/acme.sh --showcsr --csr $CM_filecsr || exit 1
_wd "--- create certificate"
$ACME --signcsr --force --csr $CM_filecsr $ACME_Params || exit 1
_certTransfer
_update "added $CM_fqdn $*"
}
#
# public function to delete a cert
#
function public_delete(){
_requiresFqdn
_certMustExist
# TODO: revoke it too??
# $ACME --revoke -d ${CM_fqdn} || exit 2
$ACME --remove -d ${CM_fqdn} || exit 2
rm -rf ${CM_dircerts} ${CM_filecnf} ${CM_filekey} ${CM_filecsr} ~/.acme.sh/${CM_fqdn}
_update "deleted ${CM_fqdn}"
}
#
# public function; list certificates incl. creation date and renew date
#
function public_list(){
_listCerts
}
#
# public function - renew a certificate
# param string fqdn of domain to renew
function public_renew(){
_requiresFqdn
_certMustExist
$ACME --renew --force -d ${CM_fqdn} || exit 2
_certTransfer
_update "renew ${CM_fqdn}"
}
#
# list existing certs
# param string fqdn of domain to renew
function public_show(){
_requiresFqdn
_certMustExist
ls -l ${CM_filecsr} ${CM_dircerts}/*
echo $line
echo $CM_filecsr
openssl req -noout -text -in $CM_filecsr
echo $line
echo ${CM_dircerts}/${CM_fqdn}.cert.pem
openssl x509 -noout -text -in ${CM_dircerts}/${CM_fqdn}.cert.pem
}
# ----------------------------------------------------------------------
#
# main
#
# ----------------------------------------------------------------------
cd $( dirname $0 )
cat <<ENDOFHEADER
$line
- - - ---===>>> CERT MANAGER <<<===--- - - -
$line
ENDOFHEADER
which openssl >/dev/null || exit 1
. ./inc_config.sh
if [ $? -ne 0 ]; then
echo "ERROR: loading the config failed."
echo "Copy the inc_config.sh.dist to inc_config.sh and make your settings in it."
echo
exit 1
fi
grep "function\ public_$1" $0 >/dev/null
if [ $# -gt 0 -a $? -eq 0 ]; then
# _wd $*
action=$1
CM_fqdn=$2
shift 2
test -z "${ACME_Outdir}" && ACME_Outdir=./certs
test -z "${ACME}" && ACME=$( which acme.sh )
if [ ! -x "${ACME}" ]; then
echo "ERROR: acme.sh not found. You need to install acme.sh client and configure it in inc_config.sh."
exit 1
fi
CM_filecsr="./csr/${CM_fqdn}.csr"
CM_filecnf="./csr/${CM_fqdn}.cnf"
CM_filekey="./csr/${CM_fqdn}.key"
CM_dircerts="${ACME_Outdir}/${CM_fqdn}"
# echo $CM_fqdn
# set | grep "^CM_"
_wd "A C T I O N -->> $action <<--"
eval "public_$action $*"
else
self=$( basename $0 )
cat <<EOF
HELP
The basic syntax is
$self ACTION [FQDN]
The ACTIONs are:
add FQDN [.. FQDN-N]
create new certificate ... or force it
The first FQDN is a hostname to generate the certificate for.
Following hostnames will be used as DNS aliases in the same certificate.
delete FQDN
delete a given certificate
list
list all certificates including creation and renew date
renew FQDN
renew (an already added) certificate
show FQDN
show place of csr + certificate data and show certificate
EOF
fi
# ======================================================================
#
# add dns credentials and default params here
#
# ======================================================================
# ----------------------------------------------------------------------
# DNS API
# see https://github.com/acmesh-official/acme.sh/wiki/dnsapi
# - set the env vars of your dns provider
# - add provider in ACME_Params="--dns [PROVIDER]"
# ----------------------------------------------------------------------
# -- for infoblox access
# export Infoblox_Creds="[user]:[Passwort]"
# export Infoblox_Server="infoblox.localhost"
# export ACME_Params="--dns dns_infoblox"
# ----------------------------------------------------------------------
# general settings
# ----------------------------------------------------------------------
# set path to acme.sh
export ACME=../acme.sh/acme.sh
# activate LE staging server for testing ... uncomment it for development
# and testing purposes
# export ACME_Params="$ACME_Params --staging"
# where to write certificate data
# export ACME_Outdir="./certs"
# ----------------------------------------------------------------------
# iml-certman
Wrapper for acme.sh to create Let's Encrypt certificates based on CSR files using DNS authentication
source: https://git-repo.iml.unibe.ch/open-source/iml-certman
## Installation
* Install acme.sh client: https://github.com/acmesh-official/acme.sh
* Clone or extract files of iml-certman
* Make your changes by copying *dist files to file without ".dist" extension and edit
+ inc_config.sh
- set credentials for dns api
- set path to acme.sh script
- optional: set custom target for generated certificates
- optional: for testing enable Let's Encrypt stage server to prevent running into weekly limits during tests
+ templates/csr.txt
- set location, company and department
## Usage
```text
./cm.sh
_______________________________________________________________________________
- - - ---===>>> CERT MANAGER <<<===--- - - -
_______________________________________________________________________________
HELP
The basic syntax is
cm.sh ACTION [FQDN]
The ACTIONs are:
add FQDN [.. FQDN-N]
create new certificate ... or force it
The first FQDN is a hostname to generate the certificate for.
Following hostnames will be used as DNS aliases in the same certificate.
delete FQDN
delete a given certificate
list
list all certificates including creation and renew date
renew FQDN
renew (an already added) certificate
show FQDN
show place of csr + certificate data and show certificate
```
# OpenSSL configuration file for creating a CSR for a server certificate
# Adapt at least the FQDN and ORGNAME lines, and then run
# openssl req -new -config myserver.cnf -keyout myserver.key -out myserver.csr
# on the command line.
# (1) the name of your location
LOCATION = Anywhere
# (2) the name of your organization
ORGNAME = My company
# (3) the name of your organization unit
UNITNAME = Department for magic things
# --- no modifications required below ---
# the fully qualified server (or service) name
FQDN = __FQDN__
# subjectAltName entries: to add DNS aliases to the CSR, delete
ALTNAMES = DNS:$FQDN__ALTNAMES__
[ req ]
default_bits = 2048
prompt = no
encrypt_key = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[ dn ]
C = CH
ST = Bern
L = $LOCATION
O = $ORGNAME
OU = $UNITNAME
CN = $FQDN
[ req_ext ]
subjectAltName = $ALTNAMES
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment