# Certbot泛域名自动续期(非Nginx默认安装路径可用)

2019/2/26 21:6 下午 posted in  技术

https://github.com/zning1994/certbot-letencrypt-wildcardcertificates-alydns-au

certbot certonly  -d *.example.com --manual --preferred-challenges dns --dry-run  --manual-auth-hook /脚本目录/autxy.sh #以腾讯云为例


certbot certonly -d *.example.com --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory --manual-auth-hook /脚本目录/autxy.sh --post-hook "执行命令更新后服务重启命令"


certbot renew --manual --preferred-challenges dns --manual-auth-hook /脚本目录/autxy.sh --post-hook "执行命令更新后服务重启命令"


certbot renew --manual --preferred-challenges dns  --manual-auth-hook /脚本目录/autxy.sh --force-renewal --post-hook "执行命令更新后服务重启命令"


# 证书有效期<30天才会renew，所以crontab可以配置为1天或1周
# 每月的 1,7,21,28号， 3点29分 更新证书
29 3 1,7,21,28 * * root certbot renew --manual --preferred-challenges dns --manual-auth-hook /脚本目录/autxy.sh --post-hook "执行命令更新后服务重启命令"


shell~~certbot renew --pre-hook "nginx停止代码" --post-hook "nginx启动代码"

### 解决思路与问题分析

Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/zning.me.conf
-------------------------------------------------------------------------------
Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
Attempting to renew cert (zning.me) from /etc/letsencrypt/renewal/zning.me.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/zning.me/fullchain.pem (failure)

-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/zning.me/fullchain.pem (failure)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
-------------------------------------------------------------------------------
1 renew failure(s), 0 parse failure(s)



2018-11-17 22:46:38,466:DEBUG:certbot.main:certbot version: 0.24.0
2018-11-17 22:46:38,466:DEBUG:certbot.main:Arguments: ['--dry-run']
2018-11-17 22:46:38,466:DEBUG:certbot.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#manual,PluginEntryPoint#nginx,PluginEntryPoint#null,PluginEntryPoint#standalone,PluginEntryPoint#webroot)
2018-11-17 22:46:38,480:DEBUG:certbot.log:Root logging level set at 20
2018-11-17 22:46:38,480:INFO:certbot.log:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2018-11-17 22:46:38,495:DEBUG:certbot.plugins.selection:Requested authenticator <certbot.cli._Default object at 0x7f161ba95190> and installer <certbot.cli._Default object at 0x7f161ba95190>
2018-11-17 22:46:38,495:DEBUG:certbot.cli:Var dry_run=True (set by user).
2018-11-17 22:46:38,495:DEBUG:certbot.cli:Var server=set(['staging', 'dry_run']) (set by user).
2018-11-17 22:46:38,495:DEBUG:certbot.cli:Var dry_run=True (set by user).
2018-11-17 22:46:38,495:DEBUG:certbot.cli:Var server=set(['staging', 'dry_run']) (set by user).
2018-11-17 22:46:38,495:DEBUG:certbot.cli:Var account=set(['server']) (set by user).
2018-11-17 22:46:38,503:INFO:certbot.renewal:Cert not due for renewal, but simulating renewal for dry run
2018-11-17 22:46:38,507:DEBUG:certbot.plugins.selection:Requested authenticator manual and installer None
2018-11-17 22:46:38,508:DEBUG:certbot.plugins.disco:Other error:(PluginEntryPoint#manual): An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/certbot/plugins/disco.py", line 126, in prepare
self._initialized.prepare()
File "/usr/lib/python2.7/site-packages/certbot/plugins/manual.py", line 118, in prepare
self.option_name('auth-hook')))
PluginError: An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.
2018-11-17 22:46:38,508:DEBUG:certbot.plugins.selection:No candidate plugin
2018-11-17 22:46:38,508:DEBUG:certbot.plugins.selection:Selected authenticator None and installer None
2018-11-17 22:46:38,508:INFO:certbot.main:Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
2018-11-17 22:46:38,508:WARNING:certbot.renewal:Attempting to renew cert (zning.me) from /etc/letsencrypt/renewal/zning.me.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.
2018-11-17 22:46:38,509:DEBUG:certbot.renewal:Traceback was:
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/certbot/renewal.py", line 422, in handle_renewal_request
main.renew_cert(lineage_config, plugins, renewal_candidate)
File "/usr/lib/python2.7/site-packages/certbot/main.py", line 1144, in renew_cert
installer, auth = plug_sel.choose_configurator_plugins(config, plugins, "certonly")
File "/usr/lib/python2.7/site-packages/certbot/plugins/selection.py", line 207, in choose_configurator_plugins
diagnose_configurator_problem("authenticator", req_auth, plugins)
File "/usr/lib/python2.7/site-packages/certbot/plugins/selection.py", line 303, in diagnose_configurator_problem
raise errors.PluginSelectionError(msg)
PluginSelectionError: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)

2018-11-17 22:46:38,509:ERROR:certbot.renewal:All renewal attempts failed. The following certs could not be renewed:
2018-11-17 22:46:38,510:ERROR:certbot.renewal:  /etc/letsencrypt/live/zning.me/fullchain.pem (failure)
2018-11-17 22:46:38,510:DEBUG:certbot.log:Exiting abnormally:
Traceback (most recent call last):
File "/usr/bin/certbot", line 9, in <module>
File "/usr/lib/python2.7/site-packages/certbot/main.py", line 1315, in main
return config.func(config, plugins)
File "/usr/lib/python2.7/site-packages/certbot/main.py", line 1228, in renew
renewal.handle_renewal_request(config)
File "/usr/lib/python2.7/site-packages/certbot/renewal.py", line 443, in handle_renewal_request
len(renew_failures), len(parse_failures)))
Error: 1 renew failure(s), 0 parse failure(s)


2018-11-17 22:44:58,251:DEBUG:certbot.log:Root logging level set at 20
2018-11-17 22:44:58,251:INFO:certbot.log:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2018-11-17 22:44:58,252:DEBUG:certbot.plugins.selection:Requested authenticator None and installer None
2018-11-17 22:44:58,270:DEBUG:certbot.plugins.util:Failed to find executable apachectl in PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
2018-11-17 22:44:58,270:DEBUG:certbot.plugins.disco:No installation (PluginEntryPoint#apache): Cannot find Apache executable apachectl
Traceback (most recent call last):
File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/plugins/disco.py", line 132, in prepare
self._initialized.prepare()
File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot_apache/configurator.py", line 232, in prepare
self._verify_exe_availability(self.option("ctl"))
File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot_apache/configurator.py", line 277, in _verify_exe_availability
'Cannot find Apache executable {0}'.format(exe))
NoInstallationError: Cannot find Apache executable apachectl
2018-11-17 22:44:58,271:DEBUG:certbot.plugins.disco:No installation (PluginEntryPoint#nginx): Could not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.
Traceback (most recent call last):
File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot/plugins/disco.py", line 132, in prepare
self._initialized.prepare()
File "/opt/eff.org/certbot/venv/lib/python2.7/site-packages/certbot_nginx/configurator.py", line 145, in prepare
"Could not find a usable 'nginx' binary. Ensure nginx exists, "
NoInstallationError: Could not find a usable 'nginx' binary. Ensure nginx exists, the binary is executable, and your PATH is set correctly.
2018-11-17 22:44:58,272:DEBUG:certbot.plugins.selection:No candidate plugin
2018-11-17 22:44:58,272:DEBUG:certbot.plugins.selection:Selected authenticator None and installer None


Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/zning.me.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

-------------------------------------------------------------------------------

The following certs are not due for renewal yet:
/etc/letsencrypt/live/zning.me/fullchain.pem expires on 2019-02-15 (skipped)
No renewals were attempted.
No hooks were run.
-------------------------------------------------------------------------------


shell0 3 */7 * * certbot renew --pre-hook "nginx停止代码" --post-hook "nginx启动代码"

### 官网说明部分：Renewing certificates

Note

Let’s Encrypt CA issues short-lived certificates (90 days). Make sure you renew the certificates at least once in 3 months.

Many of the certbot clients obtained through a distribution come with automatic renewal out of the box, such as Debian and Ubuntu versions installed through apt, CentOS/RHEL 7 through EPEL, etc. See Automated Renewals for more details.

As of version 0.10.0, Certbot supports a renew action to check all installed certificates for impending expiry and attempt to renew them. The simplest form is simply

certbot renew

This command attempts to renew any previously-obtained certificates that expire in less than 30 days. The same plugin and options that were used at the time the certificate was originally issued will be used for the renewal attempt, unless you specify other plugins or options. Unlike certonlyrenew acts on multiple certificates and always takes into account whether each one is near expiry. Because of this, renew is suitable (and designed) for automated use, to allow your system to automatically renew each certificate when appropriate. Since renew only renews certificates that are near expiry it can be run as frequently as you want - since it will usually take no action.

The renew command includes hooks for running commands or scripts before or after a certificate is renewed. For example, if you have a single certificate obtained using the standalone plugin, you might need to stop the webserver before renewing so standalone can bind to the necessary ports, and then restart it after the plugin is finished. Example:

certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"


If a hook exits with a non-zero exit code, the error will be printed to stderr but renewal will be attempted anyway. A failing hook doesn’t directly cause Certbot to exit with a non-zero exit code, but since Certbot exits with a non-zero exit code when renewals fail, a failed hook causing renewal failures will indirectly result in a non-zero exit code. Hooks will only be run if a certificate is due for renewal, so you can run the above command frequently without unnecessarily stopping your webserver.

--pre-hook and --post-hook hooks run before and after every renewal attempt. If you want your hook to run only after a successful renewal, use --deploy-hook in a command like this.

certbot renew --deploy-hook /path/to/deploy-hook-script


For example, if you have a daemon that does not read its certificates as the root user, a deploy hook like this can copy them to the correct location and apply appropriate file permissions.

/path/to/deploy-hook-script

#!/bin/sh

set -e

for domain in $RENEWED_DOMAINS; do case$domain in
example.com)
daemon_cert_root=/etc/some-daemon/certs

# Make sure the certificate and private key files are
# never world readable, even just for an instant while
# we're copying them into daemon_cert_root.

cp "$RENEWED_LINEAGE/fullchain.pem" "$daemon_cert_root/$domain.cert" cp "$RENEWED_LINEAGE/privkey.pem" "$daemon_cert_root/$domain.key"

# Apply the proper file ownership and permissions for
# the daemon to read its certificate and key.
chown some-daemon "$daemon_cert_root/$domain.cert" \
"$daemon_cert_root/$domain.key"
chmod 400 "$daemon_cert_root/$domain.cert" \
"$daemon_cert_root/$domain.key"

service some-daemon restart >/dev/null
;;
esac
done


You can also specify hooks by placing files in subdirectories of Certbot’s configuration directory. Assuming your configuration directory is /etc/letsencrypt, any executable files found in/etc/letsencrypt/renewal-hooks/pre/etc/letsencrypt/renewal-hooks/deploy, and/etc/letsencrypt/renewal-hooks/post will be run as pre, deploy, and post hooks respectively when any certificate is renewed with the renew subcommand. These hooks are run in alphabetical order and are not run for other subcommands. (The order the hooks are run is determined by the byte value of the characters in their filenames and is not dependent on your locale.)

Hooks specified in the command line, configuration file, or renewal configuration files are run as usual after running all hooks in these directories. One minor exception to this is if a hook specified elsewhere is simply the path to an executable file in the hook directory of the same type (e.g. your pre-hook is the path to an executable in /etc/letsencrypt/renewal-hooks/pre), the file is not run a second time. You can stop Certbot from automatically running executables found in these directories by including --no-directory-hooks on the command line.

More information about hooks can be found by running certbot --help renew.

If you’re sure that this command executes successfully without human intervention, you can add the command to crontab (since certificates are only renewed when they’re determined to be near expiry, the command can run on a regular basis, like every week or every day). In that case, you are likely to want to use the -q or --quiet quiet flag to silence all output except errors.

If you are manually renewing all of your certificates, the --force-renewal flag may be helpful; it causes the expiration time of the certificate(s) to be ignored when considering renewal, and attempts to renew each and every installed certificate regardless of its age. (This form is not appropriate to run daily because each certificate will be renewed every day, which will quickly run into the certificate authority rate limit.)

Note that options provided to certbot renew will apply to every certificate for which renewal is attempted; for example, certbot renew --rsa-key-size 4096 would try to replace every near-expiry certificate with an equivalent certificate using a 4096-bit RSA public key. If a certificate is successfully renewed using specified options, those options will be saved and used for future renewals of that certificate.

An alternative form that provides for more fine-grained control over the renewal process (while renewing specified certificates one at a time), is certbot certonly with the complete set of subject domains of a specific certificate specified via -d flags. You may also want to include the -n or --noninteractive flag to prevent blocking on user input (which is useful when running the command from cron).

certbot certonly -n -d example.com -d www.example.com

All of the domains covered by the certificate must be specified in this case in order to renew and replace the old certificate rather than obtaining a new one; don’t forget any www. domains! Specifying a subset of the domains creates a new, separate certificate containing only those domains, rather than replacing the original certificate. When run with a set of domains corresponding to an existing certificate, the certonly command attempts to renew that specific certificate.

Please note that the CA will send notification emails to the address you provide if you do not renew certificates that are about to expire.

Certbot is working hard to improve the renewal process, and we apologize for any inconvenience you encounter in integrating these commands into your individual environment.

Note

certbot renew exit status will only be 1 if a renewal attempt failed. This means certbot renewexit status will be 0 if no certificate needs to be updated. If you write a custom script and expect to run a command only after a certificate was actually renewed you will need to use the --deploy-hook since the exit status will be 0 both on successful renewal and when renewal is not necessary.