Current output of `uname` on Darwin/macOS 11 is only `Darwin`, which
breaks the premisse used in `command_version()`. This update adds
`Darwin` alongside `BSD`.
letsencrypt is phasing out the v1 server:
```
+ ERROR: An error occurred while sending get-request to https://acme-staging.api.letsencrypt.org/directory (Status 403)
Details:
HTTP/2 403
server: nginx
date: Thu, 01 Apr 2021 20:48:17 GMT
content-type: application/problem+json
content-length: 189
etag: "600b3710-bd"
{
"type": "urn:acme:error:serverInternal",
"detail": "ACMEv1 Brownout in Progress. ACMEv1 will fully turn off on June 1, 2021. Check https://letsencrypt.status.io/ for more details."
}
```
- Ensure that all per-certificate settings are saved and restored in
store_configvars() and reset_configvars() - that's what makes them
per-certificate in the first place...
- Add OCSP_FETCH and OCSP_DAYS in the documented list of supported
per-certificate configs, since the code does allow these.
This commit introduces a new cli argument `--force-validation` which,
when used in combination with `--force` ignores valid domain
authorizations and forces a revalidation.
This has been implemented since at least LE seems to have changed some
behavior on valid authorizations. Only the previously validated
authorization-type is reusable, causing dehydrated to error out when
changing from recently validated authorization types while still trying
to force-renew certificates for whatever reason (e.g. changing algorithms).
The cleanup command skips filetypes for which the symlink is broken or
doesn't exist. However, if dehydrated fails, we may end up in exactly
the situation that the symlink doesn't exist (yet). If dehydrated fails
repeatedly, we may end up with a lot of old cert.csr, cert.pem and
privkey.pem files, so we really want to be able to clean them up.
Remove all files if the symlink is broken/missing, instead of skipping
those files.
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
libressl did not pick up the implicit host header patches
of OpenSSL 1.1 even in version 3 and thus exhibits the same
behavior as OpenSSL 1.0.
Patch by Chen, Chih-Chia <pigfoot@gmail.com>
Fixes#778
before applying heuristics, use PRETTY_NAME from os-release(3),
which reliably exists on all common linux distributions.
keep the /etc/issue parsing as fallback.
We store the account URL on account creation in the account_id.json file.
When reading the file, if the attribute is missing, we retrieve the account URL
from the CA ( https://tools.ietf.org/html/rfc8555#section-7.3.1 ) and edit the
file.
Per https://tools.ietf.org/html/rfc8555#section-7.3
> The server returns this account object in a 201 (Created) response, with the
> account URL in a Location header field. The account URL is used as the "kid"
> value in the JWS authenticating subsequent requests by this account (see
> Section 6.2). The account URL is also used for requests for management
> actions on this account, as described below.
Per https://tools.ietf.org/html/rfc8555#section-7.1.3
> status (required, string): The status of this order. Possible values are
> "pending", "ready", "processing", "valid", and "invalid". See Section 7.1.6.
Per https://tools.ietf.org/html/rfc8555#section-7.5.1
> The client indicates to the server that it is ready for the challenge
> validation by sending an empty JSON body ("{}") carried in a POST
> request to the challenge URL (not the authorization URL).
Since a few CAs out there actually seem to (only) support ACME v1 I
decided to revert the removal and keep ACME v1 around, at least until
it eventually becomes a bigger inconvenience to maintain.
This reverts commit aadf7d5e64.
With the globbing changes made in
61083cf522 to globally disable globbing by
default, this broke the ability to load the CONFIG_D `*.sh` files.
This re-enables globbing when reading these `*.sh` files and then disables it
again afterwards. Note that this also keeps globbing enabled inside the
loop, when sourcing the individual `*.sh` files for backwards
compatibility (so if the individual config scripts relied on the default
of globbing being enabled, there won't be any change in behavior).
In some situations it might be necessary to pass extra commands to
the curl binary, e.g. proxy authentication credentials.
Adds the CURL_OPTS config option.
Bash 3.0 and others seem to have serious issues running dehydrated.
https://github.com/lukas2511/dehydrated/issues/284 tracks the
problem but got closed as it seems too hard to support "stone age"
distributions.
Turns out it is actually only a three line change. ;-)
When all names in a cert have already been validated, the challenge_altnames array will be empty, causes an error in later code. This patch adds a test to handle that case.
* Add new parameter --lock-suffix.
This enables automation systems to run multiple instances of dehydrated
while still maintaining a locking facility. This is necessary for
projects like https://github.com/GUI/lua-resty-auto-ssl.
With this feature, one could run the script multiple times, while still
having a form of locking:
./dehydrated --lock-suffix test1.example.com -d test1.example.com
./dehydrated --lock-suffix test2.example.com -d test2.example.com
./dehydrated --lock-suffix test3.example.com -d test3.example.com
./dehydrated --lock-suffix test4.example.com -d test4.example.com
./dehydrated --lock-suffix test5.example.com -d test5.example.com
When starts the script with the same locking suffix, the scripts exits
like it normally would when locked. This will give you the benefits of
using --no-lock, without the disadvantages of it.
* Fixed unbound variable error for new PARAM_LOCKFILE_SUFFIX.
* skip challenge for already validated domains
* only call deploy_challenge hook if there is work
No need to call the hook if there are no challenges to deploy
at least in 1.4 the syntax is `server.modules` and it's an array.
and it's always good idea to keep trailing comma to avoid syntax errors when adding new entries.
@@ -3,7 +3,118 @@ This file contains a log of major changes in dehydrated
## [x.x.x] - xxxx-xx-xx
## Changed
- ...
- `--force` no longer forces domain name revalidation by default, a new argument `--force-validation` has been added for that
- Added support for EC secp521r1 algorithm (works with e.g. zerossl)
- `EC PARAMETERS` are no longer written to privkey.pem (didn't seem necessary and was causing issues with various software)
## Added
- Implemented EC for account keys
- Domain list now also read from domains.txt.d subdirectory (behaviour might change, see docs)
- Implemented RFC 8738 (validating/signing certificates for IP addresses instead of domain names) support (this will not work with most public CAs, if any!)
## [0.7.0] - 2020-12-10
## Added
- Support for external account bindings
- Special support for ZeroSSL
- Support presets for some CAs instead of requiring URLs
This is a client for signing certificates with an ACME-server (currently only provided by letsencrypt) implemented as a relatively simple bash-script.
Dehydrated is a client for signing certificates with an ACME-server (e.g. Let's Encrypt) implemented as a relatively simple (zsh-compatible) bash-script.
This client supports both ACME v1 and the new ACME v2 including support for wildcard certificates!
It uses the `openssl` utility for everything related to actually handling keys and certificates, so you need to have that installed.
Other dependencies are: curl, sed, grep, mktemp (all found on almost any system, curl being the only exception)
Other dependencies are: cURL, sed, grep, awk, mktemp (all found pre-installed on almost any system, cURL being the only exception).
Current features:
- Signing of a list of domains
- Signing of a CSR
- Renewal if a certificate is about to expire or SAN (subdomains) changed
- Signing of a list of domains (including wildcard domains!)
- Signing of a custom CSR (either standalone or completely automated using hooks!)
- Renewal if a certificate is about to expire or defined set of domains changed
- Certificate revocation
- and lots more..
Please keep in mind that this software and even the acme-protocol are relatively young and may still have some unresolved issues.
Feel free to report any issues you find with this script or contribute by submitting a pullrequest.
Please keep in mind that this software, the ACME-protocol and all supported CA servers out there are relatively young and there might be a few issues. Feel free to report any issues you find with this script or contribute by submitting a pull request,
but please check for duplicates first (feel free to comment on those to get things rolling).
### Getting started
## Getting started
For getting started I recommend taking a look at [docs/domains_txt.md](docs/domains_txt.md), [docs/wellknown.md](docs/wellknown.md) and the [Usage](#usage) section on this page (you'll probably only need the `-c` option).
Generally you want to set up your WELLKNOWN path first, and then fill in domains.txt.
**Please note that you should use the staging URL when experimenting with this script to not hit letsencrypts rate limits.** See [docs/staging.md](docs/staging.md).
**Please note that you should use the staging URL when experimenting with this script to not hit Let's Encrypt's rate limits.** See [docs/staging.md](docs/staging.md).
If you have any problems take a look at our [Troubleshooting](docs/troubleshooting.md) guide.
## Config
dehydrated is looking for a config file in a few different places, it will use the first one it can find in this order:
-`/etc/dehydrated/config`
-`/usr/local/etc/dehydrated/config`
- The current working directory of your shell
- The directory from which dehydrated was run
Have a look at [docs/examples/config](docs/examples/config) to get started, copy it to e.g. `/etc/dehydrated/config`
--env (-e) Output configuration variables for use in other scripts
Parameters:
--accept-terms Accept CAs terms of service
--full-chain (-fc) Print full chain when using --signcsr
--ipv4 (-4) Resolve names to IPv4 addresses only
--ipv6 (-6) Resolve names to IPv6 addresses only
--domain (-d) domain.tld Use specified domain name(s) instead of domains.txt entry (one certificate!)
--ca url/preset Use specified CA URL or preset
--alias certalias Use specified name for certificate directory (and per-certificate config) instead of the primary domain (only used if --domain is specified)
--keep-going (-g) Keep going after encountering an error while creating/renewing multiple certificates in cron mode
--force (-x) Force renew of certificate even if it is longer valid than value in RENEW_DAYS
--force-validation Force revalidation of domain names (used in combination with --force)
--no-lock (-n) Don't use lockfile (potentially dangerous!)
--lock-suffix example.com Suffix lockfile name with a string (useful for with -d)
--ocsp Sets option in CSR indicating OCSP stapling to be mandatory
--privkey (-p) path/to/key.pem Use specified private key instead of account key (useful for revocation)
--domains-txt path/to/domains.txt Use specified domains.txt instead of default/configured one
--config (-f) path/to/config Use specified config file
--hook (-k) path/to/hook.sh Use specified script for hooks
--preferred-chain issuer-cn Use alternative certificate chain identified by issuer CN
--out (-o) certs/directory Output certificates into the specified directory
--challenge (-t) http-01|dns-01 Which challenge should be used? Currently http-01 and dns-01 are supported
--alpn alpn-certs/directory Output alpn verification certificates into the specified directory
--challenge (-t) http-01|dns-01|tls-alpn-01 Which challenge should be used? Currently http-01, dns-01, and tls-alpn-01 are supported
--algo (-a) rsa|prime256v1|secp384r1 Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1
The ACME API version 1 was never really standardized and was only supported by Let's Encrypt. Even though the protocol specification was public,
it wasn't really friendly to be integrated into existing CA systems so initial adoption was basically non-existant.
ACME version 2 is being designed to overcome these issues by becoming an official IETF standard and supporting a more traditional approach of account
and order management in the backend, making it friendlier to integrate into existing systems centered around those. It has since become a semi-stable IETF
standard draft which only ever got two breaking changes, Content-Type enforcement and `POST-as-GET`, the latter being announced in October 2018 to be enforced
by November 2019. See https://datatracker.ietf.org/wg/acme/documents/ for a better insight into the draft and its changes.
Next to backend changes that many users won't really care about ACME v2 has all of the features ACME v1 had, but also some additional new features like
e.g. support for [wildcard certificates](domains_txt.md#wildcards).
Since ACME v2 is basically to be considered stable and ACME v1 has no real benefits over v2, there doesn't seem to be much of a reason to keep the old
protocol around, but since there actually are a few Certificate Authorities and resellers that implemented the v1 protocol and didn't yet make the change
to v2, so dehydrated still supports the old protocol for now.
Please keep in mind that support for the old ACME protocol version 1 might get removed at any point of bigger inconvenience, e.g. on code changes that
would require a lot of work or ugly workarounds to keep both versions supported.
This script also supports the new `dns-01`-type verification. This type of verification requires you to be able to create a specific `TXT` DNS record for each hostname included in the certificate.
You need a hook script that deploys the challenge to your DNS server!
You need a hook script that deploys the challenge to your DNS server.
The hook script (indicated in the config file or the --hook/-k command line argument) gets four arguments: an operation name (clean_challenge, deploy_challenge, or deploy_cert) and some operands for that. For deploy_challenge $2 is the domain name for which the certificate is required, $3 is a "challenge token" (which is not needed for dns-01), and $4 is a token which needs to be inserted in a TXT record for the domain.
The hook script (indicated in the config file or the `--hook/-k` command line argument) gets four arguments:
$1 an operation name (`clean_challenge`, `deploy_challenge`, `deploy_cert`, `invalid_challenge` or `request_failure`) and some operands for that.
For `deploy_challenge`
$2 is the domain name for which the certificate is required,
$3 is a "challenge token" (which is not needed for dns-01), and
$4 is a token which needs to be inserted in a TXT record for the domain.
Typically, you will need to split the subdomain name in two, the subdomain name and the domain name separately. For example, for "my.example.com", you'll need "my" and "example.com" separately. You then have to prefix "_acme-challenge." before the subdomain name, as in "_acme-challenge.my" and set a TXT record for that on the domain (e.g. "example.com") which has the value supplied in $4
@@ -13,10 +22,10 @@ _acme-challenge IN TXT $4
_acme-challenge.my IN TXT $4
```
That could be done manually (as most providers don't have a DNS API), by having your hook script echo $1, $2 and $4 and then wait (read -s -r -e < /dev/tty) - give it a little time to get into their DNS system. Usually providers give you a boxes to put "_acme-challenge.my" and the token value in, and a dropdown to choose the record type, TXT.
That could be done manually (as most providers don't have a DNS API), by having your hook script echo $1, $2 and $4 and then wait (`read -s -r -e < /dev/tty`) - give it a little time to get into their DNS system. Usually providers give you a boxes to put "_acme-challenge.my" and the token value in, and a dropdown to choose the record type, TXT.
Or when you do have a DNS API, pass the details accordingly to achieve the same thing.
You can delete the TXT record when called with operation clean_challenge, when $2 is also the domain name.
You can delete the TXT record when called with operation `clean_challenge`, when $2 is also the domain name.
Here are some examples: [Examples for DNS-01 hooks](https://github.com/lukas2511/dehydrated/wiki/Examples-for-DNS-01-hooks)
Here are some examples: [Examples for DNS-01 hooks](https://github.com/dehydrated-io/dehydrated/wiki)
If you want to import existing keys from the official letsencrypt client have a look at [Import from official letsencrypt client](https://github.com/lukas2511/dehydrated/wiki/Import-from-official-letsencrypt-client).
Alternatively you can define the CA using the CLI argument `--ca letsencrypt-test` (`letsencrypt-test` is an integrated preset-CA corresponding to the URL above).
@@ -11,12 +11,6 @@ the current workaround is to move `private_key.pem` (and, if you care, `private_
This will hopefully be fixed in the future.
## "Provided agreement URL [LICENSE1] does not match current agreement URL [LICENSE2]"
Set LICENSE in your config to the value in place of "LICENSE2".
LICENSE1 and LICENSE2 are just placeholders for the real values in this troubleshooting document!
## "Error creating new cert :: Too many certificates already issued for: [...]"
This is not an issue with dehydrated but an API limit with boulder (the ACME server).
@@ -31,8 +25,28 @@ This also is an API limit from boulder, you are requesting to sign a certificate
There are a few factors that could result in invalid challenges.
If you are using http validation make sure that the path you have configured with WELLKNOWN is readable under your domain.
If you are using HTTP validation make sure that the path you have configured with WELLKNOWN is readable under your domain.
To test this create a file (e.g. `test.txt`) in that directory and try opening it with your browser: `http://example.org/.well-known/acme-challenge/test.txt`.
To test this create a file (e.g. `test.txt`) in that directory and try opening it with your browser: `http://example.org/.well-known/acme-challenge/test.txt`. Note that if you have an IPv6 address, the challenge connection will be on IPv6. Be sure that you test HTTP connections on both IPv4 and IPv6. Checking the test file in your browser is often not sufficient because the browser just fails over to IPv4.
If you get any error you'll have to fix your web server configuration.
## DNS invalid challenge since dehydrated 0.6.0 / Why are DNS challenges deployed first and verified later?
Since Let's Encrypt (and in general the ACMEv2 protocol) now supports wildcard domains there is a situation where DNS caching can become a problem.
If somebody wants to validate a certificate with `example.org` and `*.example.org` there are two tokens that have to be deployed on `_acme-challenge.example.org`.
If dehydrated would deploy and verify each token on its own the CA would cache the first token on `_acme-challenge.example.org` and the next challenge would simply fail.
Let's Encrypt uses your DNS TTL with a max limit of 5 minutes, but this doesn't seem to be part of the ACME protocol, just some LE specific configuration,
so with other CAs and certain DNS providers who don't allow low TTLs this could potentially take hours.
Since dehydrated now deploys all challenges first that no longer is a problem. The CA will query and cache both challenges, and both authorizations can be validated.
Some hook-scripts were written in a way that erases the old TXT record rather than adding a new entry, those should be (and many of them already have been) fixed.
There are certain DNS providers which really only allow one TXT record on a domain. This is really odd and you should probably contact your DNS provider and ask them
to fix this.
If for whatever reason you can't switch DNS providers and your DNS provider only supports one TXT record and doesn't want to fix that you could try splitting your
certificate into multiple certificates and add a sleep in the `deploy_cert` hook.
If you can't do that or really don't want to please leave a comment on https://github.com/lukas2511/dehydrated/issues/554,
if many people are having this unfixable problem I might try to implement a workaround.
_CHECK_LOG "Moving unused file to archive directory: ${TMP_URL}/cert-"
_CHECK_LOG "Moving unused file to archive directory: ${TMP_URL}/chain-"
_CHECK_LOG "Moving unused file to archive directory: ${TMP_URL}/fullchain-"
_CHECK_ERRORLOG
# All done
exit0
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.