# Usage ## Selftest Verify a new setup (or changes in the config) with `./cm.sh selftest`. ## Show help Without -h or --help it shows a help. ```text ./cm.sh -h _______________________________________________________________________________ - - - ---===>>> CERT MANAGER - v2025-01-09 <<<===--- - - - _______________________________________________________________________________ HELP Wrapper script for acme.sh to handle certificates. For automation you should use the "ensure" action that detects if a certificate must be created, renewed or re-created. 📄 Source: <https://git-repo.iml.unibe.ch/iml-open-source/iml-certman> 📜 License: GNU GPL 3.0 📗 Docs: <https://os-docs.iml.unibe.ch/iml-certman/> SYNTAX: cm.sh [OPTIONS] ACTION <FQDN> [<ALIASES>] OPTIONS: -a|--alias Use http challenge with existing http server on port 80 Challenge file will be written into ../alias-dir/ -f|--force Force renew of certificate even if it is not due yet. Use it carefully - remember the execution limits on Let's Encrypt. -t|--trace the output additionally will be written into a tracelog file below ./log. -v|--verbose show debug infos on console. Remark: for permanent usage set CM_showdebug=1 in inc_config.sh -w|--webroot <DIR> Use http challenge with existing http server on port 80 Challenge file will be written into given directory 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 list-old list all certificates older 65 and older 90 days and exit. Exitcodes: 0 - all certs are up to date. 1 - certificates to renew were found 2 - outdatedt certificates were found 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. ``` ## CRUD actions for a certificate ### Create (Issue) 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` #### Mehtod: DNS auth By default the cert manager tries to use the DNS challenge `[APPPATH]/cm.sh add www.example.com mail.example.com` In the configuration you need these variables: * CM_certmatch defines the domains that are allowed to use DNS auth.<br>to allow all: `export CM_certmatch="."`<br>To allow a specific subdomain: `export CM_certmatch="\.org\.example\.com"` * CM_challenge_alias is the domain you can manage via DNS api. <br>All hosts of this domain will be issued by a TXT record.<br>External domains need a CNAME. See <https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode> #### Mehtod: Http - using webroot If you have a http website of a domain you can authorize with a written challenge file. The file will be written below webroot. The SSL provider will make an http request `http://www.example.com/.well-known/acme-challenge/<generated-challenge-file>` The parameter --webroot is used to define the webroot of the existing web (without /.well-known/acme-challenge). Example: `[APPPATH]/cm.sh --webroot <webroot> add www.example.com mail.example.com` #### Mehtod: Http - using alias You can use an alias to place the generated challenge file outside webroot. The SSL provider will make an http request `http://www.example.com/.well-known/acme-challenge/<generated-challenge-file>` - this url must fit here too. (1) Create a .well-known directory Remark: this path is hardcoded :-/ The directory is ../alias-dir/ - one directory outside the cm.sh. If your installation is in `/opt/letsencrypt/iml-certman/` then you need to create this directory: `/opt/letsencrypt/alias-dir/.well-known` (2) In Webserver enable mod_alias eg. on Debian /etc/apache2/mods-enabled/alias.load ``` LoadModule alias_module /usr/lib/apache2/modules/mod_alias.so ``` (3) In Webserver create an alias pointing to your .well-known directory In your vhost (or global apache config) define an alias. ```text Alias /.well-known "/opt/letsencrypt/alias-dir/.well-known" ``` If you have rewrite rules or proxy rules in the webroot keep in mind to have an exclude to allow file access on challenge files. ```text RewriteEngine On RewriteCond %{REQUEST_URI} !^/.well-known RewriteRule ^(.*)$ index.php [QSA,L] ``` (4) Issue the cert use the parameter --alias without any value to create the challenge file in ../alias-dir/. Example: `[APPPATH]/cm.sh --alias add www.example.com mail.example.com` All other actions need the first domain only. ### Read Use the parameter **list** to show all certificates, aliases and dates. `[APPPATH]/cm.sh list` The parameter **show** shows details of a single certificate. `[APPPATH]/cm.sh show www.example.com` ### Update (renew) 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. ### Delete `[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. This ensure action handles the logic if a certificate must be * created (if it does not exist) or * renewed (it already exists) or * re-created (the list of dns names in the certificate was changed) It detects if a domain in the certificate can use a txt record or needs dns auth mode. ## 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. ## List old certificates If you have many ssl certificates - during the time there are outdated domains and unneeded certificate files. The parameter `list-old` shows old certificates in 2 blocks: * Certificates with age 65 ... 90 days<br>Remark: the Certificates are valid for 90 days. The will be renewed 4 weeks before expiration. This list shows certificates that are still valid but should bew renewed soon. * Certificates older 90 days<br>Remark: expired certificates. Use `[APPPATH]/cm.sh delete <Domain>` to delete the files. Exitcodes: 0 - all certs are up to date. 1 - certificates to renew were found 2 - outdatedt certificates were found