diff --git a/cm.sh b/cm.sh index e839fe5001bea0370f4896e7c09c6b8f6fa0b165..e3dc9da5411eca435a95fdac1262d8ceacb69317 100755 --- a/cm.sh +++ b/cm.sh @@ -25,6 +25,8 @@ # 2021-09-27 <axel.hahn@iml.unibe.ch> softer behaviour: do not revoke changed certs (add does not stop; ensure does not delete) # 2021-12-23 <axel.hahn@iml.unibe.ch> added param --trace as 1st param to generate a trace log # 2022-01-10 <axel.hahn@iml.unibe.ch> _wait_for_free_slot: exclude ssh calls +# 2022-03-30 <axel.hahn@iml.unibe.ch> remove usage of csr and generation of key file +# 2022-03-31 <axel.hahn@iml.unibe.ch> dns authentication with alias domain # ====================================================================== @@ -38,7 +40,8 @@ logdir="./log" touchfile="$logdir/lastchange.txt" logfile="$logdir/certmanager.log" -csrfile="./templates/csr.txt" +# CSR USAGE WAS REMOVED +# csrfile="./templates/csr.txt" line="_______________________________________________________________________________" @@ -84,12 +87,12 @@ function _certMustExist(){ # the script will be aborted # param string FQDN function _certMustNotExist(){ - _certExists - if [ $? -eq 0 ]; then - echo "WARNING: cert ${CM_fqdn} was added already." - # exit 1 - echo "Press Ctrl+C to abort within the next 10 sec..." - sleep 10 + if _certExists + then + echo "ERROR: cert ${CM_fqdn} was added already." + exit 1 + # echo "Press Ctrl+C to abort within the next 10 sec..." + # sleep 10 fi } @@ -105,39 +108,47 @@ function _certTransfer(){ test -d ${CM_dircerts} && rm -f "${CM_dircerts}/*" 2>/dev/null _wd "--- transfer acme.sh files to ${CM_dircerts}/" - $ACME \ + if ! $ACME \ --install-cert \ - -d ${CM_fqdn} \ - --cert-file ${CM_outfile_cert} \ - --fullchain-file ${CM_outfile_chain} \ - --ca-file ${CM_outfile_ca} - if [ $? -ne 0 ]; then - echo "ERROR occured during transfer. Removing files in ${CM_dircerts} to prevent strange effects..." + -d "${CM_fqdn}" \ + --key-file "${CM_outfile_key}" \ + --cert-file "${CM_outfile_cert}" \ + --fullchain-file "${CM_outfile_chain}" \ + --ca-file "${CM_outfile_ca}" + then + echo "ERROR occured during acme transfer. Removing files in ${CM_dircerts} to prevent strange effects..." rm -f "${CM_dircerts}/*" - exit + exit 2 fi echo "OK." - _wd "--- copy key to ${CM_dircerts}" - cp ${CM_filekey} ${CM_outfile_key} + # _wd "--- copy key to ${CM_dircerts}" + # cp ${CM_filekey} ${CM_outfile_key} _wd "--- create chained file for haproxy" - cat ${CM_outfile_chain} ${CM_outfile_key} > ${CM_outfile_haproxy} + cat "${CM_outfile_chain}" "${CM_outfile_key}" > "${CM_outfile_haproxy}" _wd "--- content of output dir $CM_dircerts:" - ls -l $CM_dircerts/* + if ! ls -l "${CM_outfile_cert}" "${CM_outfile_chain}" "${CM_outfile_key}" "${CM_outfile_haproxy}" + then + echo "ERROR missing a file (or no access?)" + rm -f "${CM_dircerts}/*" + exit 2 + fi } -# internal function; show md5 hashsums for certificate, csr and key +# internal function; show md5 hashsums for certificate and key # for visual comparison if the match function _certMatching(){ - local md5_csr=$( test -f ${CM_filecsr} && openssl req -noout -modulus -in ${CM_filecsr} | openssl md5 | cut -f 2 -d " " ) + # CSR USAGE WAS REMOVED + # local md5_csr=$( test -f ${CM_filecsr} && openssl req -noout -modulus -in ${CM_filecsr} | openssl md5 | cut -f 2 -d " " ) local md5_key=$( test -f ${CM_outfile_key} && openssl rsa -noout -modulus -in ${CM_outfile_key} | openssl md5 | cut -f 2 -d " " ) local md5_cert=$( test -f ${CM_outfile_cert} && openssl x509 -noout -modulus -in ${CM_outfile_cert} | openssl md5 | cut -f 2 -d " " ) echo echo "--- compare hashes" - echo "csr : $md5_csr (used for creation of cert)" + # CSR USAGE WAS REMOVED + # echo "csr : $md5_csr (used for creation of cert)" echo "key : $md5_key" echo "cert : $md5_cert" if [ "$md5_key" = "$md5_cert" ]; then @@ -151,19 +162,24 @@ function _certMatching(){ # 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 +# This function is used in _dnsCheck # param string fqdn to check +# param string type of dns entry; one of a|cname +# param string optional filter on output of dig (regex) 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??" + local _type=${2:-"a"} + local _verify=${3:-"."} + + if which dig >/dev/null + then + # _wd "[$myfqdn] exists as type [$_type] in DNS?" + if ! dig "${myfqdn}" "${_type}" | grep "^${myfqdn}" | grep -E "${_verify}" + then + echo "ERROR: [$myfqdn] was not found. Maybe there is a typo in the hostname or it does not exist in DNS." exit 2 fi - _wd "OK" + _wd "OK: [$myfqdn] exists in DNS." else _wd "SKIP: dig was not found" fi @@ -171,36 +187,64 @@ function _checkDig(){ } +# internal function: check DNS entries +# - the hostname to be added in the certificate must exist +# - if a hostname does not match and CM_challenge_alias was set: +# - _acme-challenge.FQDN must be a cname to _acme-challenge.${CM_challenge_alias} +# Function stops if a fqdn was not found in DNS. +# param string fqdn(s) that are part of the certificate +function _dnsCheck(){ + local altdns= + local _mydomain= + local _subdomain='_acme-challenge' + + for _mydomain in $* + do + _wd "dig check - domain for cert" + _checkDig "$_mydomain" "a" "IN.*(A|CNAME)" # matches A and CNAME records + + if [ -n "${CM_challenge_alias}" ] && ! echo "$_mydomain" | grep "${CM_certmatch}" >/dev/null + then + _wd "dig check - cname ${_subdomain}.${_mydomain} must exist" + _checkDig "${_subdomain}.${_mydomain}" "cname" + _wd "dig check - cname ${_subdomain}.${_mydomain} must point to ${_subdomain}.${CM_challenge_alias}" + _checkDig "${_subdomain}.${_mydomain}" "cname" "${_subdomain}.${CM_challenge_alias}" + fi + done + +} + +# CSR USAGE WAS REMOVED # internal function; generate a csr file before creating a new certifcate # this function is used in public_add -function _gencsr(){ +# function _UNUSED_gencsr(){ - altdns= - _checkDig $CM_fqdn - for myalt in $* - do - altdns="${altdns}DNS:$myalt," - done - altdns=$( echo $altdns | sed "s#,\$##" ) - _wd "--- $CM_fqdn" - _wd "DNS alternative names: $altdns" +# local altdns= - rm -f $CM_filecnf $CM_filekey $CM_filecsr - mkdir -p "${CM_dircsr}" 2>/dev/null +# for myalt in $* +# do +# altdns="${altdns}DNS:$myalt," +# done +# altdns=$( echo $altdns | sed "s#,\$##" ) +# _wd "--- $CM_fqdn" +# _wd "DNS alternative names: $altdns" - cat $csrfile \ - | sed "s#__FQDN__#$CM_fqdn#g" \ - | sed "s#__ALTNAMES__#$altdns#g" \ - > $CM_filecnf || exit 1 +# rm -f $CM_filecnf $CM_filekey $CM_filecsr +# mkdir -p "${CM_dircsr}" 2>/dev/null - # generate csr - _wd "creating key and csr" - openssl req -new -config $CM_filecnf -keyout $CM_filekey -out $CM_filecsr || exit 1 +# cat $csrfile \ +# | sed "s#__FQDN__#$CM_fqdn#g" \ +# | sed "s#__ALTNAMES__#$altdns#g" \ +# > $CM_filecnf || exit 1 - # view csr - # openssl req -noout -text -in $CM_filecsr - ls -ltr $CM_filecnf $CM_filekey $CM_filecsr -} +# # 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; get a sorted list of DNS aliases in the current cert function _getAliases(){ @@ -285,6 +329,8 @@ function _wd(){ # param string FQDN function _setenv(){ CM_fqdn=$1 + # CSR USAGE WAS REMOVED + # keeping vars to delete files of existing certs that used a csr CM_filecsr="${CM_dircsr}/${CM_fqdn}.csr" CM_filecnf="${CM_dircsr}/${CM_fqdn}.cnf" CM_filekey="${CM_dircsr}/${CM_fqdn}.key" @@ -331,29 +377,31 @@ function _testFqdncount(){ # pulic function ADD certificate # function public_add(){ + local _params="" + _wait_for_free_slot _requiresFqdn _certMustNotExist - for myhost in $( echo $CM_fqdn $*) - do - echo $myhost | grep "$CM_certmatch" >/dev/null - if [ $? -ne 0 ]; then - echo "ERROR: host $myhost does not match [$CM_certmatch]." - exit 1 + _dnsCheck $CM_fqdn $* + + for _mydomain in $CM_fqdn $* + do + _params+="-d $_mydomain " + + if [ -n "${CM_challenge_alias}" ] && ! echo "$_mydomain" | grep "${CM_certmatch}" >/dev/null + then + _params+="--challenge-alias ${CM_challenge_alias}" fi done - _gencsr $CM_fqdn $* _wd "--- create output dir $dircerts" mkdir -p "${CM_dircerts}" 2>/dev/null - _wd "--- csr data" - $ACME --showcsr --csr $CM_filecsr || exit 1 - _wd "--- create certificate" - $ACME --signcsr --csr $CM_filecsr $ACME_Params - if [ $? -ne 0 ]; then + echo $ACME --issue $_params $ACME_Params + if ! $ACME --issue $_params $ACME_Params + then echo "ERROR: adding cert failed. Trying to delete internal data ..." public_delete $CM_fqdn exit 1 @@ -366,6 +414,44 @@ function public_add(){ _update "added $CM_fqdn $*" } +# CSR USAGE WAS REMOVED +# function OLD__public_add(){ +# _wait_for_free_slot +# _requiresFqdn +# _certMustNotExist + +# for myhost in $( echo $CM_fqdn $*) +# do +# echo $myhost | grep "$CM_certmatch" >/dev/null +# if [ $? -ne 0 ]; then +# echo "ERROR: host $myhost does not match [$CM_certmatch]." +# exit 1 +# fi +# done +# _gencsr $CM_fqdn $* + +# _wd "--- create output dir $dircerts" +# mkdir -p "${CM_dircerts}" 2>/dev/null + +# _wd "--- csr data" +# $ACME --showcsr --csr $CM_filecsr || exit 1 + +# _wd "--- create certificate" +# echo $ACME --signcsr --csr $CM_filecsr $ACME_Params +# $ACME --signcsr --csr $CM_filecsr $ACME_Params +# if [ $? -ne 0 ]; then +# echo "ERROR: adding cert failed. Trying to delete internal data ..." +# public_delete $CM_fqdn +# exit 1 +# fi +# # $ACME --issue -d $CM_fqdn $ACME_Params || exit 1 + +# _certTransfer +# _certMatching + +# _update "added $CM_fqdn $*" +# } + # # pulic function ADD OR RENEW certificate # @@ -409,6 +495,8 @@ function public_delete(){ _wd "--- delete ACME.SH data" $ACME --remove -d ${CM_fqdn} $ACME_Params _wd "--- delete local data" + + # CSR USAGE WAS REMOVED rm -rf ${CM_dircerts} ${CM_filecnf} ${CM_filekey} ${CM_filecsr} ~/.acme.sh/${CM_fqdn} && echo OK _update "deleted ${CM_fqdn}" } @@ -490,7 +578,7 @@ function public_selftest(){ echo echo --- dependencies - _selftestItem "which openssl" "opemssl was found" + _selftestItem "which openssl" "openssl was found" _selftestItem "which curl" "curl was found" echo @@ -504,15 +592,16 @@ function public_selftest(){ _selftestItem "test -w ~/.acme.sh/" "it is writable" echo - echo --- csr template - _selftestItem "ls -ld ${csrfile}" "csr base template exists" - _selftestItem "test -r ${csrfile}" "it is readable" - echo - - echo --- output directory for csr and key - _selftestItem "ls -ld ${CM_dircsr}" "data dir for csr exists" - _selftestItem "test -w ${CM_dircsr}" "it is writable" - echo + # CSR USAGE WAS REMOVED + # echo --- csr template + # _selftestItem "ls -ld ${csrfile}" "csr base template exists" + # _selftestItem "test -r ${csrfile}" "it is readable" + # echo + # + # echo --- output directory for csr and key + # _selftestItem "ls -ld ${CM_dircsr}" "data dir for csr exists" + # _selftestItem "test -w ${CM_dircsr}" "it is writable" + # echo echo --- output dir for centralized place of certificates _selftestItem "ls -ld ${CM_diracme}" "central output dir for certificate data exists" @@ -540,11 +629,15 @@ function public_show(){ _requiresFqdn _certMustExist - ls -l ${CM_filecsr} ${CM_dircerts}/* + # CSR USAGE WAS REMOVED + # ls -l ${CM_filecsr} ${CM_dircerts}/* + ls -l ${CM_dircerts}/* _certMatching - echo $line - echo CSR $CM_filecsr - openssl req -noout -text -in $CM_filecsr | grep -E "(Subject:|DNS:)" | sed "s#^\ *##g" + + # CSR USAGE WAS REMOVED + # echo $line + # echo CSR $CM_filecsr + # openssl req -noout -text -in $CM_filecsr | grep -E "(Subject:|DNS:)" | sed "s#^\ *##g" for myfile in ${CM_outfile_cert} ${CM_outfile_haproxy} do @@ -668,7 +761,7 @@ The ACTIONs for SINGLE certificate handlings are: and update files in ${CM_diracme} show FQDN - show place of csr + certificate data and show basic certificate data + show place of certificate data and show basic certificate data (issuer, subject, aliases, ending date) transfer FQDN diff --git a/csr/.keep b/csr/.keep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/docs/10_Home.md b/docs/10_Home.md new file mode 100644 index 0000000000000000000000000000000000000000..56bd99296df971e4b165bdce5f7bb3fc3712a301 --- /dev/null +++ b/docs/10_Home.md @@ -0,0 +1,14 @@ +# IML certman + +Wrapper for **acme.sh** to create Let's Encrypt certificates using DNS authentication. +It was written to create/ renew all needed certificates at a central system to deploy it from there (Ansible, Puppet, ...). + +source: <https://git-repo.iml.unibe.ch/open-source/iml-certman> +license: GNU GPL 3.0 <http://www.gnu.org/licenses/gpl-3.0.html> + +## Requirements + +* bash +* openssl +* curl +* acme.sh client diff --git a/docs/20_Installation.md b/docs/20_Installation.md new file mode 100644 index 0000000000000000000000000000000000000000..0417755b0230814777d75b52aa6fb256cac04da9 --- /dev/null +++ b/docs/20_Installation.md @@ -0,0 +1,35 @@ +# Installation + +* Install acme.sh client: <https://github.com/acmesh-official/acme.sh> +* If you use Ansible/ Puppet/ ... to renew and deploy new certificates then you can deactivate the acme cronjob (`crontab -e`) +* 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; the default is a relative path for the suggested contellation below. + * optional: set custom target for generated certificates + * optional: for testing enable Let's Encrypt stage server to prevent running into weekly limits during tests + * optional: set a filter that must match to new certificate and all aliases + * UNUSED: templates/csr.txt + * set location, company and department ... remark: (currently?) it is removed by LE + +A suggested structure is having acme.sh and this wrapper below the same parent directory, i.e. + +```text +/opt/letsenecrypt/ + | + +-- acme.sh/ + | | + | + acme.sh + | + ... + | + +-- iml-certman/ + | + +-- certs/ + +-- templates/ + + cm.sh + + inc_config.sh + + ... +``` + +Verify a new setup (or changes in the config) with `./cm.sh selftest`. diff --git a/docs/30_Usage.md b/docs/30_Usage.md new file mode 100644 index 0000000000000000000000000000000000000000..e2cd95a4872c76e0ca18c81f374acc7b527d1ce2 --- /dev/null +++ b/docs/30_Usage.md @@ -0,0 +1,139 @@ +# Usage + +## Selftest + +Verify a new setup (or changes in the config) with `./cm.sh selftest`. + +## Show help + +Without any parameter it shows a help. + +```text + +./cm.sh +_______________________________________________________________________________ + + + - - - ---===>>> CERT MANAGER <<<===--- - - - + +_______________________________________________________________________________ + +DEBUG: Using Let's Encrypt STAGE environment ... +DEBUG: You can test and mess around. Do not use certs in production. + +HELP + +The basic syntax is +cm.sh [--trace] ACTION [FQDN] [ALIAS_1 [.. ALIAS_N]] + +The ACTIONs for SINGLE certificate handlings are: + + add FQDN [.. FQDN-N] + create new certificate + The first FQDN is a hostname to generate the certificate for. + Following multiple hostnames will be used as DNS aliases in the + same certificate. + It updates files in ./certs + + ensure FQDN [.. FQDN-N] + It ensures that a certificate with given aliases exists and is up to date. + This param is for simple usage in automation tools like Ansible or Puppet. + It is required to add all aliases as parameters what is unhandy for + direct usage on cli. + + If the cert does not exist it will be created (see "add"). + If fqdn and aliases are the same like in the certificate it performs a renew. + If fqdn and aliases differ: + - the current certificate will be rejected + deleted (see "delete") + - a new certificate will be added () + + delete FQDN + delete all files of a given certificate + + renew FQDN + renew (an already added) certificate + and update files in ./certs + + show FQDN + show place of certificate data and show basic certificate data + (issuer, subject, aliases, ending date) + + transfer FQDN + Transfer cert from acme.sh internal cache to our output dir again. + It is done during add or renew. With transfer command you can repeat it. + +ACTIONs for ALL certs + + list + list all certificates including creation and renew date + + renew-all + renew all certificates (fast mode - without --force) + and update files in ./certs + It is useful for a cronjob. + +other ACTIONs + + selftest + check of health with current setup and requirements. + This command is helpful for initial setups. + +OPTIONS + --trace (it must be the 1st parameter) + the output additionally will be written into a tracelog file + below ./log. + +DEBUG: Using Let's Encrypt STAGE environment ... +DEBUG: You can test and mess around. Do not use certs in production. + +``` + +## CRUD actions for a certificate + +With parameter `add` you need to add all domains that should be included in a new certificate. + +`[APPPATH]/cm.sh add www.example.com mail.example.com` + +All other actions need the first domain only. + +The parameter **show** shows details. + +`[APPPATH]/cm.sh show www.example.com` + +If a certificate reaches the time for renewing (i.e. 4 weeks before expiration) you can renew it with **renew**. + +Remark: if you try to renew before renewing date this results in a skip message (and exitcode 0). + +`[APPPATH]/cm.sh renew www.example.com` + +With a delete command the certificate will be revoked and the local files will be deleted. + +`[APPPATH]/cm.sh delete www.example.com` + +Then a certificate does not appear with cm.sh list anymore. + +## The action "ensure" + +In a scenario of automatic deployment with Ansible or Puppet you don't want to find out what action is needed: action add, remove old and add a new certificate or renew. The ensure action is a universal command to ensure somehow that the certificate exists, contains all DNS alt names and is up to date. + +`[APPPATH]/cm.sh ensure www.example.com mail.example.com` + +creates (or renews if close to expiriation) a certificate with 2 hostnames in it. + +## Show certificate data + +Use the listing `[APPPATH]/cm.sh list` or maybe filter it `[APPPATH]/cm.sh list | grep "mail."` + +to get a list of existing certs an then use the hostname in the 1st column to show details: + +`[APPPATH]/cm.sh show mail.example.com` + +## Renew all certificates + +`[APPPATH]/cm.sh renew-all` + +## Logs + +In **log/certmanager.log** you find a logging about time of changes for a certificate: when it was added, renewed, deleted. A skipped renew execution (even if it was triggered internally by "ensure") won't be logged. + +Additionally there is a --trace option (must be the 1st param) - an execution output will be put to logfile that contains domain and timestamp. diff --git a/inc_config.sh.dist b/inc_config.sh.dist index 9b12fcd6c70a19cf5fe838c28f58d5fe11530fa6..cf41e8a36c95e7dc3dffdda2ceca1096561f868b 100644 --- a/inc_config.sh.dist +++ b/inc_config.sh.dist @@ -43,6 +43,10 @@ export ACME=../acme.sh/acme.sh # have no permission # export CM_certmatch="\.example\.com" +# if a host is not matching CM_certmatch we will use authentication +# with an alias domain +# export CM_challenge_alias="example.com" + # optional: force a user to execute cm.sh # this is for a central installation with a software deployment # like Ansible or puppet; default: none (=any user can run cm.sh) diff --git a/readme.md b/readme.md index 4b7ef2b9aa542c0498dd8b441fc9a029179d20e7..17906c18ff0d73d689102b7ca4ddfc1a8f156d91 100644 --- a/readme.md +++ b/readme.md @@ -1,158 +1,9 @@ -# iml-certman +# IML certman -Wrapper for **acme.sh** to create Let's Encrypt certificates based on CSR files using DNS authentication. +Wrapper for **acme.sh** to create Let's Encrypt certificates using DNS authentication. It was written to create/ renew all needed certificates at a central system to deploy it from there (Ansible, Puppet, ...). source: <https://git-repo.iml.unibe.ch/open-source/iml-certman> license: GNU GPL 3.0 <http://www.gnu.org/licenses/gpl-3.0.html> -## Installation - -* Install acme.sh client: <https://github.com/acmesh-official/acme.sh> -* If you use Ansible/ Puppet/ ... to renew and deploy new certificates then you can deactivate the acme cronjob (`crontab -e`) -* 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; the default is a relative path for the suggested contellation below. - * optional: set custom target for generated certificates - * optional: for testing enable Let's Encrypt stage server to prevent running into weekly limits during tests - * optional: set a filter that must match to new certificate and all aliases - * templates/csr.txt - * set location, company and department ... remark: (currently?) it is removed by LE - -A suggested structure is having acme.sh and this wrapper below the same parent directory, i.e. - -```text -/opt/letsenecrypt/ - | - +-- acme.sh/ - | | - | + acme.sh - | + ... - | - +-- iml-certman/ - | - +-- certs/ - +-- csr/ - +-- templates/ - + cm.sh - + inc_config.sh - + ... -``` - -## Usage - -### Selftest - -Verify a new setup (or changes in the config) with ``./cm.sh selftest``. - -### Show help - -Without any parameter it shows a help. - -```text - -./cm.sh -_______________________________________________________________________________ - - - - - - ---===>>> CERT MANAGER <<<===--- - - - - -_______________________________________________________________________________ - -DEBUG: Using Let's Encrypt STAGE environment ... -DEBUG: You can test and mess around. Do not use certs in production. - -HELP - -The basic syntax is -cm.sh [--trace] ACTION [FQDN] [ALIAS_1 [.. ALIAS_N]] - -The ACTIONs for SINGLE certificate handlings are: - - add FQDN [.. FQDN-N] - create new certificate - The first FQDN is a hostname to generate the certificate for. - Following multiple hostnames will be used as DNS aliases in the - same certificate. - It updates files in ./certs - - ensure FQDN [.. FQDN-N] - It ensures that a certificate with given aliases exists and is up to date. - This param is for simple usage in automation tools like Ansible or Puppet. - It is required to add all aliases as parameters what is unhandy for - direct usage on cli. - - If the cert does not exist it will be created (see "add"). - If fqdn and aliases are the same like in the certificate it performs a renew. - If fqdn and aliases differ: - - the current certificate will be rejected + deleted (see "delete") - - a new certificate will be added () - - delete FQDN - delete all files of a given certificate - - renew FQDN - renew (an already added) certificate - and update files in ./certs - - show FQDN - show place of csr + certificate data and show basic certificate data - (issuer, subject, aliases, ending date) - - transfer FQDN - Transfer cert from acme.sh internal cache to our output dir again. - It is done during add or renew. With transfer command you can repeat it. - -ACTIONs for ALL certs - - list - list all certificates including creation and renew date - - renew-all - renew all certificates (fast mode - without --force) - and update files in ./certs - It is useful for a cronjob. - -other ACTIONs - - selftest - check of health with current setup and requirements. - This command is helpful for initial setups. - -OPTIONS - --trace (it must be the 1st parameter) - the output additionally will be written into a tracelog file - below ./log. - -DEBUG: Using Let's Encrypt STAGE environment ... -DEBUG: You can test and mess around. Do not use certs in production. - -``` - -### CRUD actions for a certificate - -A certificate is created for a host and can have additional DNS names (optional). -For integration into a system deployment with Ansible & co the `ensure` prameter -is the best choice because it detects what action is required. -The command - -`[APPPATH]/cm.sh ensure www.example.com mail.example.com` - -creates (or renews if close to expiriation) a certificate with 2 hostnames in it. - -The "manual way" with atomic actions is: - -* Create `[APPPATH]/cm.sh add www.example.com mail.example.com` -* Renew `[APPPATH]/cm.sh renew www.example.com` -* Modify hostnames with add command `[APPPATH]/cm.sh add www.example.com mail.example.com newhost.example.com` what creates a new certificate. Optionally you can/ should revoke the existing certificate with the former host list before (see next command). The impact is: Your SSL certificate on the website is invalid up to the moment you create and deploy the new certificate what can take a few minutes. If you maintain many certificates with the same domain and the request limit is reached your application can be broken broken for an even longer time. -* Deletin the certificates includes a revoke `[APPPATH]/cm.sh delete www.example.com` - -### Show certificate data - -Use the listing `[APPPATH]/cm.sh list` or maybe filter it `[APPPATH]/cm.sh list | grep "mail."` - -to get a list of existing certs an then use the hostname in the 1st column to show details: - -`[APPPATH]/cm.sh show www.example.com` +See [docs](docs/) diff --git a/templates/readme.md b/templates/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..3dc2c6a813a245e41436447535d194a866a5885f --- /dev/null +++ b/templates/readme.md @@ -0,0 +1,4 @@ +# CSR template is not used anymore + +We added support for authentication with an dns alias. +The CSR template won't be used anymore.