dehydrated-io / dehydrated

letsencrypt/acme client implemented as a shell-script – just add water
https://dehydrated.io
MIT License
5.95k stars 715 forks source link

Feature: Option to dry-run #561

Open mrhackcz opened 6 years ago

mrhackcz commented 6 years ago

Can you please to the next version add a option to run "dry-run" ?

danimo commented 3 years ago

Here is a Gist with a conceptual patch. However, it does not implement some vital aspects, especially

kousu commented 3 years ago

Hello friends :)

I am motivated to figure out some kind of --dry-run so I can wrap dehydrated in an ansible script. It will cover anywhere from 1 to 1000 servers, and I can't, and definitely can't ask my lab to, manually verify the configuration of each server before attempting to get a cert. But letsencrypt's rate limits are set to 5 per week

Renewals are treated specially: they don’t count against your Certificates per Registered Domain limit, but they are subject to a Duplicate Certificate limit of 5 per week. Note: renewals used to count against your Certificate per Registered Domain limit until March 2019, but they don’t anymore. Exceeding the Duplicate Certificate limit is reported with the error message too many certificates already issued for exact set of domains.

so are buypass's:

We also have a Duplicate Certificate limit of 5 certificates per week.

and I already ran into this once and had to wait a week before I could continue developing.

--dry-run could also be a solution for #792: instead of implementing retry logic, include a dry run step in the regular cronjob: the cronjob will take care of retrying and there's less risk of negative consequences from turning up the cronjob's rate.

prior art

I discovered that certbot has

       --dry-run             Perform a test run of the client, obtaining test
                             (invalid) certificates but not saving them to disk.
                             This can currently only be used with the 'certonly'
                             and 'renew' subcommands. Note: Although --dry-run
                             tries to avoid making any persistent changes on a
                             system, it is not completely side-effect free: if used
                             with webserver authenticator plugins like apache and
                             nginx, it makes and then reverts temporary config
                             changes in order to obtain test certificates, and
                             reloads webservers to deploy and then roll back those
                             changes. It also calls --pre-hook and --post-hook
                             commands if they are defined because they may be
                             necessary to accurately simulate renewal. --deploy-
                             hook commands are not called. (default: False)

So with certbot, I think they expect that if you're at all unsure about your configuration (in DNS, webserver, domains, connectivity) you should always do:

certbot renew --dry-run && certbot renew

which:

  1. connects to letsencrypt-test to try to make new certs
  2. if so, connects to letsencrypt to make new ones, burning one of your attempts for the week

To do a proper dry run, you must contact a server. I just wish I could do that dry run without And now with multiple ACME servers in the wild it's complicated:

@danimo's patch doesn't seem to address this? Maybe it was written before multiple ACME CAs existed?

dehydrated-based workarounds/extensions

dehydrated --ca testencrypt-test -c && dehydrated -c

which will

  1. check if certs need renewing/creating not true; see https://github.com/dehydrated-io/dehydrated/issues/561#issuecomment-860274941
  2. if so, will connect to letsencrypt-test to get new certs, replacing the working certs with test certs
  3. if so, will again test if certs need renewing, discover that the certs exist, and stop

So this is closer, but leaves me with invalid test certs on my server.

This form:

dehydrated --ca testencrypt-test -c && (eval "$(dehydrated -e)"; rm "$CERTDIR"/*/cert.pem) && dehydrated -c
  1. check if certs need renewing/creating
  2. if so, will connect to letsencrypt-test to get new certs, replacing the working certs with test certs
  3. Will forget those test certs -- but also all other certs that happen to exist
  4. if so, will again test if certs need renewing, discover that the certs exist, and stop

Destryoing all certs is okay for my situation, as I am only planning one domain per server at the moment, but it's a dangerous precedent to set.

This form:

dehydrated --ca testencrypt-test -o $(mktemp -d) -c && dehydrated -c
  1. connects to letsencrypt-test to try to make new certs, and then forgets them
  2. if so, checks if certs need renewing/*or creating
  3. if so, connects to letsencrypt to get new certs, burning one of your attempts for the week

However, this wastes about 10s per deploy, by not being smart enough.

So the previous two forms both have the right result, at the expense of a. danger or b. time.

Maybe a hook could do it?

cat > /usr/local/bin/dehydrated/dehydrated-dry-run.sh <<EOF && chmod +x /usr/local/bin/dehydrated/dehydrated-dry-run.sh
#!/bin/sh
# a dehydrated hook script that deletes newly generated certs
# emulates `certbot --dry-run`
# see https://github.com/dehydrated-io/dehydrated/issues/561
deploy_cert() {
    local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}"
    rm "${CERTFILE}" "${KEYFILE}" "${CHAINFILE}" "${FULLCHAINFILE}"
}

HANDLER="$1"; shift
if [[ "${HANDLER}" =~ ^(deploy_cert)$ ]]; then
  "$HANDLER" "$@"
fi
EOF
dehydrated --ca testencrypt-test --hook /usr/local/bin/dehydrated/dehydrated-dry-run.sh -c && dehydrated -c

This seems to check all my boxes:

and it is idempotent, only doing work when work is needed.

lukas2511 commented 3 years ago

@kousu Mh, from what I understand you are suggesting that a "dry-run" would connect to a staging environment of the corresponding CA? My understanding of a dry-run would be something that involves no real connections and only internal / partially mocked data. The staging environments have API limits too, so using them as some form of dry-run would only postpone eventual rate limit issues.

My big goal (for which I unfortunately didn't find much time yet...) is to restructure dehydrated into smaller internal parts, making it easier to change overall execution flow and replace parts in the future. That would make it a lot easier to implement real dry-runs, would allow for more flexibility with e.g. different CAs for different certificates, CA specific weirdness, etc.

kousu commented 3 years ago

That's right. I want to be able to vet my setup: DNS, file permissions, webserver, ACME configuration files. Some of these can be tricky the first time, and others can get changed over time outside of my control. The only way to be sure is to run the complete ACME protocol.

The rate limits on the staging servers are much higher and designed to support this sort of testing and development.

Maybe --dry-run is the wrong name for the feature I'm looking for. Maybe I want --test and I should start a separate issue for it. --ca letsencrypt-test goes most of the way to what I want, I just wish it wouldn't overwrite my existing certs on success, because then I could automate `` and be pretty confident that I can detect and fix a bad configuration long before getting banned.

Right now I either run

dehydrated -c

which got me banned last time

dehydrated -c --ca letsencrypt-test && dehydrated -c

which doesn't get me banned but leaves me with invalid certs or

dehydrated -c --ca letsencrypt-test -o $(mktemp -d) && dehydrated -c

which gets me valid certs, but spends an extra 10s per attempt that it really doesn't need to.

The ideal for me would be a --test that didn't save certs to disk so that

dehydrated -c --ca letsencrypt-test --test && dehydrated -c

would only run when certs are expiring, would still produce valid certs, and would avoid getting banned all at the same time.

My big goal (for which I unfortunately didn't find much time yet...)

Oh this is the story of my life too! No worries. We're all volunteers here.

jasoncodes commented 3 years ago
dehydrated -c --ca letsencrypt-test -o $(mktemp -d) && dehydrated -c

which gets me valid certs, but spends an extra 10s per attempt that it really doesn't need to.

Have you tried copying your current real certs over to a temporary directory before running against letsencrypt-test?

Something like this should avoid requesting certs from the test CA unnecessarily:

rsync --archive /etc/dehydrated/certs{,.tmp}/ &&
  dehydrated -c --ca letsencrypt-test -o /etc/dehydrated/certs.tmp &&
  rm -r /etc/dehydrated/certs.tmp &&
  dehydrated -c
kousu commented 3 years ago

@jasoncodes it's genius. I think I will use it! Thank you.

kousu commented 3 years ago

For what it's worth, certbot decided that their --dry-run implies contacting the staging server; their --dry-run ~= --ca letsencrypt-test -o $(mktemp -d). -v --dryrun reports:

Sending GET request to https://acme-staging-v02.api.letsencrypt.org/directory.

certbot -v renew --dry-run ``` root@monitor:~# certbot -v renew --dry-run Root logging level set at 10 Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/monitor.neuro.polymtl.ca.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Requested authenticator and installer Var dry_run=True (set by user). Var server={'staging', 'dry_run'} (set by user). Var dry_run=True (set by user). Var server={'staging', 'dry_run'} (set by user). Var account={'server'} (set by user). Cert not due for renewal, but simulating renewal for dry run Requested authenticator webroot and installer None Single candidate plugin: * webroot Description: Place files in webroot directory Interfaces: IAuthenticator, IPlugin Entry point: webroot = certbot.plugins.webroot:Authenticator Initialized: Prep: True Selected authenticator and installer None Plugins selected: Authenticator webroot, Installer None Sending GET request to https://acme-staging-v02.api.letsencrypt.org/directory. Starting new HTTPS connection (1): acme-staging-v02.api.letsencrypt.org:443 https://acme-staging-v02.api.letsencrypt.org:443 "GET /directory HTTP/1.1" 200 724 Received response: HTTP 200 Server: nginx Date: Sun, 13 Jun 2021 17:28:04 GMT Content-Type: application/json Content-Length: 724 Connection: keep-alive Cache-Control: public, max-age=0, no-cache X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 { "keyChange": "https://acme-staging-v02.api.letsencrypt.org/acme/key-change", "meta": { "caaIdentities": [ "letsencrypt.org" ], "termsOfService": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf", "website": "https://letsencrypt.org/docs/staging-environment/" }, "newAccount": "https://acme-staging-v02.api.letsencrypt.org/acme/new-acct", "newNonce": "https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce", "newOrder": "https://acme-staging-v02.api.letsencrypt.org/acme/new-order", "revokeCert": "https://acme-staging-v02.api.letsencrypt.org/acme/revoke-cert", "so2QCBhNDCk": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417" } Requesting fresh nonce Sending HEAD request to https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce. https://acme-staging-v02.api.letsencrypt.org:443 "HEAD /acme/new-nonce HTTP/1.1" 200 0 Received response: HTTP 200 Server: nginx Date: Sun, 13 Jun 2021 17:28:04 GMT Connection: keep-alive Cache-Control: public, max-age=0, no-cache Link: ;rel="index" Replay-Nonce: 0002Fspaj6S2OV4jcxNVQwbIqAL_61Vub84f1rPeoskolOg X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 Storing nonce: 0002Fspaj6S2OV4jcxNVQwbIqAL_61Vub84f1rPeoskolOg JWS payload: b'{\n "termsOfServiceAgreed": true,\n "resource": "new-reg"\n}' Sending POST request to https://acme-staging-v02.api.letsencrypt.org/acme/new-acct: { "protected": "eyJhbGciOiAiUlMyNTYiLCAiandrIjogeyJuIjogIjRFWGtTSXQ1OTZIT2Q5NEZaZjM0Xzh5M2JWRU1CcGhiRlhDLUdpTmRoSXlHOG0xdU9vZlN3ZjAtaTNvUnhLZkpmOEd2X0NXRTRubzdHaGxnQTh2RDBycDFWSDRtNmtRck9jX1hNOWtFNE40V21jNGxQY3FOdHJ5Zm1maDdXanVDNHEzeE5hU2JoYlVjcTY4OFZHWWR6UWJZSmZDb1dWbFRFQUkwdVg4aV9JUGljWGNjclRtWE95bm5pSnBSQmFCWldZd3d4cUhVYTN4TmwxajduaFoyaXdjUzJVbXFCbGE2TVNYaVZSSUdncW5VaGJ4TFp3Z0tJUjNqWWd2T2dmbnZBejZUUEJUT3J4SXZ3aDFVdld2UjFiaHdPaEJlM01tSElzNzEwLWdsc0FBYmdvTTlkdTBRYWdubmRBbkJBTkk0WHBrYlczY3FoVnEtTHlUNGtPbXFnUSIsICJlIjogIkFRQUIiLCAia3R5IjogIlJTQSJ9LCAibm9uY2UiOiAiMDAwMkZzcGFqNlMyT1Y0amN4TlZRd2JJcUFMXzYxVnViODRmMXJQZW9za29sT2ciLCAidXJsIjogImh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvbmV3LWFjY3QifQ", "signature": "z-Cq7SYgBpJQP-rOSxn59F2Qpg4unUNgw9N2_Vs4krDxCSPEsEwJsehLGcKpJ3C0diWfrSPqYa-VBYbfs7AiEITc4TLGQAIGU2HN64Odlor9wOK6uDFL49BuO9oOR1sig8k2eRlWawj0K86wuTBwyF3BBDctzDLFwUv238ETrZUXs6V2XnScN1PLTKvZqJV4EtjdakCAyVlKFEPtx-qb65EVREbcfZQRtKA7eVa6k4V0xjRSwaEWcXFRNkbJJdlKhe0ZkRHaAltim485G7llo7kK6SZFE_GvsR1q2BafdIedwQgHXDbkiH2VrGSkKozGiIuCNq1HFvSo0zyos0KD_A", "payload": "ewogICJ0ZXJtc09mU2VydmljZUFncmVlZCI6IHRydWUsCiAgInJlc291cmNlIjogIm5ldy1yZWciCn0" } https://acme-staging-v02.api.letsencrypt.org:443 "POST /acme/new-acct HTTP/1.1" 201 527 Received response: HTTP 201 Server: nginx Date: Sun, 13 Jun 2021 17:28:04 GMT Content-Type: application/json Content-Length: 527 Connection: keep-alive Boulder-Requester: 19889007 Cache-Control: public, max-age=0, no-cache Link: ;rel="index", ;rel="terms-of-service" Location: https://acme-staging-v02.api.letsencrypt.org/acme/acct/19889007 Replay-Nonce: 0002W4bKvA4gRbEVYVt2QK64Wjk80xJwaAvMugbbbW03nTQ X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 { "key": { "kty": "RSA", "n": "4EXkSIt596HOd94FZf34_8y3bVEMBphbFXC-GiNdhIyG8m1uOofSwf0-i3oRxKfJf8Gv_CWE4no7GhlgA8vD0rp1VH4m6kQrOc_XM9kE4N4Wmc4lPcqNtryfmfh7WjuC4q3xNaSbhbUcq688VGYdzQbYJfCoWVlTEAI0uX8i_IPicXccrTmXOynniJpRBaBZWYwwxqHUa3xNl1j7nhZ2iwcS2UmqBla6MSXiVRIGgqnUhbxLZwgKIR3jYgvOgfnvAz6TPBTOrxIvwh1UvWvR1bhwOhBe3MmHIs710-glsAAbgoM9du0QagnndAnBANI4XpkbW3cqhVq-LyT4kOmqgQ", "e": "AQAB" }, "contact": [], "initialIp": "132.207.65.218", "createdAt": "2021-06-13T17:28:04.804933581Z", "status": "valid" } Storing nonce: 0002W4bKvA4gRbEVYVt2QK64Wjk80xJwaAvMugbbbW03nTQ Reporting to user: Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. Picked account: )>), contact=(), agreement=None, status='valid', terms_of_service_agreed=None, only_return_existing=None, external_account_binding=None), uri='https://acme-staging-v02.api.letsencrypt.org/acme/acct/19889007', new_authzr_uri=None, terms_of_service='https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf'), e4253bc12eaa9405d1617da3722a7e8d, Meta(creation_dt=datetime.datetime(2021, 6, 13, 17, 28, 4, tzinfo=), creation_host='monitor.neuro.polymtl.ca'))> Renewing an existing certificate JWS payload: b'{\n "identifiers": [\n {\n "type": "dns",\n "value": "monitor.neuro.polymtl.ca"\n }\n ]\n}' Sending POST request to https://acme-staging-v02.api.letsencrypt.org/acme/new-order: { "protected": "eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvYWNjdC8xOTg4OTAwNyIsICJub25jZSI6ICIwMDAyVzRiS3ZBNGdSYkVWWVZ0MlFLNjRXams4MHhKd2FBdk11Z2JiYlcwM25UUSIsICJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9uZXctb3JkZXIifQ", "signature": "13F6ez0-dmv2mo-VSflm0DqiegvdtyeZlhIbh514kDRKDuKX0_G1udgHAJLoIJwqOrYqybMrsUN56-TpGDKFiI-oJ0a-gdiUGdnhfP7mEJ5yeo0wJxsMv8bzQgnvzb3N_eQBn5EWX-Ov9gKRWRmw8G_XGpKXjPQS6682u8CLmexVuGQHlb_llIv1xR4LZIjSdLcL_C_ZfDS6_aeI80nmvQJVdqQ_1XDI48yavWmXvuOxDRVXe0CyOLMX6psydorXcGzBHPcD3Sw0gd9X-JGxH-dHmDgCIYHNxSS-lj4QuYOoOPzgWSSqdBG2RsdVzLADX5hGrfJK4oO2jEl_6KJ4Dw", "payload": "ewogICJpZGVudGlmaWVycyI6IFsKICAgIHsKICAgICAgInR5cGUiOiAiZG5zIiwKICAgICAgInZhbHVlIjogIm1vbml0b3IubmV1cm8ucG9seW10bC5jYSIKICAgIH0KICBdCn0" } https://acme-staging-v02.api.letsencrypt.org:443 "POST /acme/new-order HTTP/1.1" 201 356 Received response: HTTP 201 Server: nginx Date: Sun, 13 Jun 2021 17:28:05 GMT Content-Type: application/json Content-Length: 356 Connection: keep-alive Boulder-Requester: 19889007 Cache-Control: public, max-age=0, no-cache Link: ;rel="index" Location: https://acme-staging-v02.api.letsencrypt.org/acme/order/19889007/75727166 Replay-Nonce: 0002k-EUgbqnxBmDOSC4vzDx6HUHFGuB_hEk7tpvjXEwLeo X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 { "status": "pending", "expires": "2021-06-20T17:28:05Z", "identifiers": [ { "type": "dns", "value": "monitor.neuro.polymtl.ca" } ], "authorizations": [ "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/67880884" ], "finalize": "https://acme-staging-v02.api.letsencrypt.org/acme/finalize/19889007/75727166" } Storing nonce: 0002k-EUgbqnxBmDOSC4vzDx6HUHFGuB_hEk7tpvjXEwLeo JWS payload: b'' Sending POST request to https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/67880884: { "protected": "eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvYWNjdC8xOTg4OTAwNyIsICJub25jZSI6ICIwMDAyay1FVWdicW54Qm1ET1NDNHZ6RHg2SFVIRkd1Ql9oRWs3dHB2alhFd0xlbyIsICJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9hdXRoei12My82Nzg4MDg4NCJ9", "signature": "DoLcs5KxH5erTO1C-rNjhYq4nnEPnRsg49puK1FkuFzdT4zwJiq6zo_joqzxrYNjwZPtaBsqDR425qCyJAMxoTXauc-hLRmwPnpMjkEon7YCTR41TVkYSDXafyLwi8jCqks35wd2lZ17_Q-zxs-4f2f6E1reICAAPuTM-JDiEHkTuDASJA4MhAwcsgO1iS_TJt2hVcpfjMd4goZlGRvuuS8MzzIbBE89A0S0L4ABbGgPFHCA1sdhcVVIWo9dPy5T8wN_ug0dRpkH2Ok6wim13W0Lbwl2gnWo5WQNGMdQ3Om6rZ-FOuIZN4oUgJ7EmTi11Po9K7ladNKCiZv0sNdqxA", "payload": "" } https://acme-staging-v02.api.letsencrypt.org:443 "POST /acme/authz-v3/67880884 HTTP/1.1" 200 820 Received response: HTTP 200 Server: nginx Date: Sun, 13 Jun 2021 17:28:05 GMT Content-Type: application/json Content-Length: 820 Connection: keep-alive Boulder-Requester: 19889007 Cache-Control: public, max-age=0, no-cache Link: ;rel="index" Replay-Nonce: 0001WsbBa8d7ZpKCsw0-J97rMtD3k1PNwgakDcI7QRldp8o X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 { "identifier": { "type": "dns", "value": "monitor.neuro.polymtl.ca" }, "status": "pending", "expires": "2021-06-20T17:28:05Z", "challenges": [ { "type": "http-01", "status": "pending", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/67880884/OQNDcA", "token": "-EWx0vjTzD1x2tDbXfKlU-YO-hyfAO7Q4kIyYNoEYGY" }, { "type": "dns-01", "status": "pending", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/67880884/NfS3NA", "token": "-EWx0vjTzD1x2tDbXfKlU-YO-hyfAO7Q4kIyYNoEYGY" }, { "type": "tls-alpn-01", "status": "pending", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/67880884/zA2ohQ", "token": "-EWx0vjTzD1x2tDbXfKlU-YO-hyfAO7Q4kIyYNoEYGY" } ] } Storing nonce: 0001WsbBa8d7ZpKCsw0-J97rMtD3k1PNwgakDcI7QRldp8o Performing the following challenges: http-01 challenge for monitor.neuro.polymtl.ca Using the webroot path /var/lib/dehydrated/acme-challenges for all unmatched domains. Creating root challenges validation dir at /var/lib/dehydrated/acme-challenges/.well-known/acme-challenge Attempting to save validation to /var/lib/dehydrated/acme-challenges/.well-known/acme-challenge/-EWx0vjTzD1x2tDbXfKlU-YO-hyfAO7Q4kIyYNoEYGY Waiting for verification... JWS payload: b'{\n "resource": "challenge",\n "type": "http-01"\n}' Sending POST request to https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/67880884/OQNDcA: { "protected": "eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvYWNjdC8xOTg4OTAwNyIsICJub25jZSI6ICIwMDAxV3NiQmE4ZDdacEtDc3cwLUo5N3JNdEQzazFQTndnYWtEY0k3UVJsZHA4byIsICJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9jaGFsbC12My82Nzg4MDg4NC9PUU5EY0EifQ", "signature": "2f1VMphCf1Lvol_glJSKB2QjQ3hoC2ZWJGyZIJR1daVr_qsvgbA9NYhfGu6VMWAkKzsAhSuS0UDT6wyLbTz9P_EZqv3NZX-D7GxIRkZ98Z1nf7ghwpWB-_QV7257qvEnzqhqB9GpjSKHA70d856cv3J9Kq4YOdR_1Ge2pMLtqSMMiFicIMC5fFdmEJJDrjpiCDWq9OB_zNxFs4PCaLc-cjyCE6xfFE_2oRVYwzva2wcXF5pTRUJipdXDxN4p92-VeEl_uk8qCePZ2_GHB6eKLSTrWcWQ_Jk9InJ_02zOMcLdw_MCzhASqqrNZtlXZB7yHcPvpIZezjqzEObW0Qoq5g", "payload": "ewogICJyZXNvdXJjZSI6ICJjaGFsbGVuZ2UiLAogICJ0eXBlIjogImh0dHAtMDEiCn0" } https://acme-staging-v02.api.letsencrypt.org:443 "POST /acme/chall-v3/67880884/OQNDcA HTTP/1.1" 200 191 Received response: HTTP 200 Server: nginx Date: Sun, 13 Jun 2021 17:28:05 GMT Content-Type: application/json Content-Length: 191 Connection: keep-alive Boulder-Requester: 19889007 Cache-Control: public, max-age=0, no-cache Link: ;rel="index", ;rel="up" Location: https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/67880884/OQNDcA Replay-Nonce: 0002knBm4T--AtnIBRf7DIWO_9FY6zS53_DIopUbXyYUbrg X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 { "type": "http-01", "status": "pending", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/67880884/OQNDcA", "token": "-EWx0vjTzD1x2tDbXfKlU-YO-hyfAO7Q4kIyYNoEYGY" } Storing nonce: 0002knBm4T--AtnIBRf7DIWO_9FY6zS53_DIopUbXyYUbrg JWS payload: b'' Sending POST request to https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/67880884: { "protected": "eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvYWNjdC8xOTg4OTAwNyIsICJub25jZSI6ICIwMDAya25CbTRULS1BdG5JQlJmN0RJV09fOUZZNnpTNTNfRElvcFViWHlZVWJyZyIsICJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9hdXRoei12My82Nzg4MDg4NCJ9", "signature": "xcgBgtC3cbAT9smMZ7y0Hnda6pY6tix1qiTcCcTT0tsF3IdPVQ2D8v6FfqHUneCOdoXGBtsPT0KFiIpuiNTQjfoIVMPHAEByZDrzaPfBouNLGSBWES-rakIgiOmxKBtfAeO1arenQJsyleO4p62yZIEuMgHZyqndddxQf7D4QDTOdA19cdPgWfliSB7SepciWMfyqg5IBZGWkUZ_JUWJG4eELrlucchIPgoEVWfK85_ukAiVR4dQlAK_M7FHXESUDxSzMa_RcJcW8QHuA4qltjbOsSivzgTyBXjhmKD8pB0dg7TMmWPylqvh1SUZV1Kj8ms-CSRB9YMuuTuIFLijBA", "payload": "" } https://acme-staging-v02.api.letsencrypt.org:443 "POST /acme/authz-v3/67880884 HTTP/1.1" 200 793 Received response: HTTP 200 Server: nginx Date: Sun, 13 Jun 2021 17:28:06 GMT Content-Type: application/json Content-Length: 793 Connection: keep-alive Boulder-Requester: 19889007 Cache-Control: public, max-age=0, no-cache Link: ;rel="index" Replay-Nonce: 0001FIkooDfmIhqJY55Qr4Q3NlagwlJx4FulCJqbz6xxviA X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 { "identifier": { "type": "dns", "value": "monitor.neuro.polymtl.ca" }, "status": "valid", "expires": "2021-07-13T17:28:05Z", "challenges": [ { "type": "http-01", "status": "valid", "url": "https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/67880884/OQNDcA", "token": "-EWx0vjTzD1x2tDbXfKlU-YO-hyfAO7Q4kIyYNoEYGY", "validationRecord": [ { "url": "http://monitor.neuro.polymtl.ca/.well-known/acme-challenge/-EWx0vjTzD1x2tDbXfKlU-YO-hyfAO7Q4kIyYNoEYGY", "hostname": "monitor.neuro.polymtl.ca", "port": "80", "addressesResolved": [ "132.207.65.218" ], "addressUsed": "132.207.65.218" } ], "validated": "2021-06-13T17:28:05Z" } ] } Storing nonce: 0001FIkooDfmIhqJY55Qr4Q3NlagwlJx4FulCJqbz6xxviA Calling registered functions Cleaning up challenges Removing /var/lib/dehydrated/acme-challenges/.well-known/acme-challenge/-EWx0vjTzD1x2tDbXfKlU-YO-hyfAO7Q4kIyYNoEYGY All challenges cleaned up CSR: CSR(file=None, data=b'-----BEGIN CERTIFICATE REQUEST-----\nMIICezCCAWMCAQIwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMot\nSvuuJDlGnKwLVyB7epp6uek9zUkVBZnZeim86+kPyYF/aF+d6KRST9GNOux4affu\nzOv7FjbvIAxR0WPYKjJlJxCc46VRsD5rLL4rA/EWL6VkL7QpVdqKt84kuCcLL6uf\nBTyXqzj3YfQvdC8XQnTv9AC3VyjcTn2/5K+Ca9mL6hanxTjK9/1RJwsENBoaT+Br\nrsSj6azUFIh4dAmv/oTyyiqE0QpmUmv/ptE5/d9/byi0FwOvp00mfD+DFIwWeU/k\nn0vq4ecJEETN5yRdw6CYxEM0TH2hndJyYrqRuW1VbUMHPDKg09D4v52IHQn8I5/9\nvldcR4cagNAB00Qf24UCAwEAAaA2MDQGCSqGSIb3DQEJDjEnMCUwIwYDVR0RBBww\nGoIYbW9uaXRvci5uZXVyby5wb2x5bXRsLmNhMA0GCSqGSIb3DQEBCwUAA4IBAQA7\nzqipcsK+tpH9EZ5NRsNZokCSiZqDVbYqWTzEhVCSb0Fs/Y6XL+Y+AEVaXXdO/fe7\n3x5AXrCVnbg2PLi06laf6isNw24zP5/AoTnRfju2YmEVhartE3e7HND1BDsebZMF\nvMfJ45A964P+fWbnrsg0j7qmkjNX1V7gkiobJzYrlf+TASUnxdn3IrUfxeD9CfiI\nylvXsrS9UxmNxEXF7GHQbg0/hwvlgPjsyLamHj/V1xFdbUNBdQFeJFGxSPuCZCOW\nwSiOoOzVOLim13kgRoWgQM1ievUtuP8LyiezU92vHwSRdhA4Zi+duwzdTlHBMXAI\nyFx7FO38nWsEPNnQtz0N\n-----END CERTIFICATE REQUEST-----\n', form='pem') JWS payload: b'{\n "resource": "new-cert",\n "csr": "MIICezCCAWMCAQIwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMotSvuuJDlGnKwLVyB7epp6uek9zUkVBZnZeim86-kPyYF_aF-d6KRST9GNOux4affuzOv7FjbvIAxR0WPYKjJlJxCc46VRsD5rLL4rA_EWL6VkL7QpVdqKt84kuCcLL6ufBTyXqzj3YfQvdC8XQnTv9AC3VyjcTn2_5K-Ca9mL6hanxTjK9_1RJwsENBoaT-BrrsSj6azUFIh4dAmv_oTyyiqE0QpmUmv_ptE5_d9_byi0FwOvp00mfD-DFIwWeU_kn0vq4ecJEETN5yRdw6CYxEM0TH2hndJyYrqRuW1VbUMHPDKg09D4v52IHQn8I5_9vldcR4cagNAB00Qf24UCAwEAAaA2MDQGCSqGSIb3DQEJDjEnMCUwIwYDVR0RBBwwGoIYbW9uaXRvci5uZXVyby5wb2x5bXRsLmNhMA0GCSqGSIb3DQEBCwUAA4IBAQA7zqipcsK-tpH9EZ5NRsNZokCSiZqDVbYqWTzEhVCSb0Fs_Y6XL-Y-AEVaXXdO_fe73x5AXrCVnbg2PLi06laf6isNw24zP5_AoTnRfju2YmEVhartE3e7HND1BDsebZMFvMfJ45A964P-fWbnrsg0j7qmkjNX1V7gkiobJzYrlf-TASUnxdn3IrUfxeD9CfiIylvXsrS9UxmNxEXF7GHQbg0_hwvlgPjsyLamHj_V1xFdbUNBdQFeJFGxSPuCZCOWwSiOoOzVOLim13kgRoWgQM1ievUtuP8LyiezU92vHwSRdhA4Zi-duwzdTlHBMXAIyFx7FO38nWsEPNnQtz0N"\n}' Sending POST request to https://acme-staging-v02.api.letsencrypt.org/acme/finalize/19889007/75727166: { "protected": "eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvYWNjdC8xOTg4OTAwNyIsICJub25jZSI6ICIwMDAxRklrb29EZm1JaHFKWTU1UXI0UTNObGFnd2xKeDRGdWxDSnFiejZ4eHZpQSIsICJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9maW5hbGl6ZS8xOTg4OTAwNy83NTcyNzE2NiJ9", "signature": "LFwDhRioiR9SMT2EN6y14aZftsyqq0EQMYG4xuWt_NopDsrw_Y-X3ScstN3YCswsQzOdPNTpAt_NYqm5RjEzaQQjMd1KChjny8rroYCfD3MJdWo2-betFsqTDoKSZq7E3-p8TjhDHaYleN2_oKcjd3nY1s8F-NDIhet1WT8ohzj6dfjWMwXR-SaaoDfMY4OOcszKe95dDOFRGD-WVeA3VslgIDuvNMrl45VydveWu2iBcJDQyUiqEGeu_Wk33KOm0lAYHkxf8069GmCX3FmL_XED_A-V_9Oc-YdxFInHP9kM-7ac08_knM5LyMW5h-JY_Qzd2dFAz508u-xBU1dPXw", "payload": "ewogICJyZXNvdXJjZSI6ICJuZXctY2VydCIsCiAgImNzciI6ICJNSUlDZXpDQ0FXTUNBUUl3QURDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTW90U3Z1dUpEbEduS3dMVnlCN2VwcDZ1ZWs5elVrVkJablplaW04Ni1rUHlZRl9hRi1kNktSU1Q5R05PdXg0YWZmdXpPdjdGamJ2SUF4UjBXUFlLakpsSnhDYzQ2VlJzRDVyTEw0ckFfRVdMNlZrTDdRcFZkcUt0ODRrdUNjTEw2dWZCVHlYcXpqM1lmUXZkQzhYUW5UdjlBQzNWeWpjVG4yXzVLLUNhOW1MNmhhbnhUaks5XzFSSndzRU5Cb2FULUJycnNTajZhelVGSWg0ZEFtdl9vVHl5aXFFMFFwbVVtdl9wdEU1X2Q5X2J5aTBGd092cDAwbWZELURGSXdXZVVfa24wdnE0ZWNKRUVUTjV5UmR3NkNZeEVNMFRIMmhuZEp5WXJxUnVXMVZiVU1IUERLZzA5RDR2NTJJSFFuOEk1Xzl2bGRjUjRjYWdOQUIwMFFmMjRVQ0F3RUFBYUEyTURRR0NTcUdTSWIzRFFFSkRqRW5NQ1V3SXdZRFZSMFJCQnd3R29JWWJXOXVhWFJ2Y2k1dVpYVnlieTV3YjJ4NWJYUnNMbU5oTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFBN3pxaXBjc0stdHBIOUVaNU5Sc05ab2tDU2lacURWYllxV1R6RWhWQ1NiMEZzX1k2WEwtWS1BRVZhWFhkT19mZTczeDVBWHJDVm5iZzJQTGkwNmxhZjZpc053MjR6UDVfQW9UblJmanUyWW1FVmhhcnRFM2U3SE5EMUJEc2ViWk1Gdk1mSjQ1QTk2NFAtZldibnJzZzBqN3Fta2pOWDFWN2draW9iSnpZcmxmLVRBU1VueGRuM0lyVWZ4ZUQ5Q2ZpSXlsdlhzclM5VXhtTnhFWEY3R0hRYmcwX2h3dmxnUGpzeUxhbUhqX1YxeEZkYlVOQmRRRmVKRkd4U1B1Q1pDT1d3U2lPb096Vk9MaW0xM2tnUm9XZ1FNMWlldlV0dVA4THlpZXpVOTJ2SHdTUmRoQTRaaS1kdXd6ZFRsSEJNWEFJeUZ4N0ZPMzhuV3NFUE5uUXR6ME4iCn0" } https://acme-staging-v02.api.letsencrypt.org:443 "POST /acme/finalize/19889007/75727166 HTTP/1.1" 200 466 Received response: HTTP 200 Server: nginx Date: Sun, 13 Jun 2021 17:28:09 GMT Content-Type: application/json Content-Length: 466 Connection: keep-alive Boulder-Requester: 19889007 Cache-Control: public, max-age=0, no-cache Link: ;rel="index" Location: https://acme-staging-v02.api.letsencrypt.org/acme/order/19889007/75727166 Replay-Nonce: 0001zq-oCUSlOUB-x6Bx-p34r-DwV8lQlD_bhZ756w0ks4Y X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 { "status": "valid", "expires": "2021-06-20T17:28:05Z", "identifiers": [ { "type": "dns", "value": "monitor.neuro.polymtl.ca" } ], "authorizations": [ "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/67880884" ], "finalize": "https://acme-staging-v02.api.letsencrypt.org/acme/finalize/19889007/75727166", "certificate": "https://acme-staging-v02.api.letsencrypt.org/acme/cert/fac50cc5390520982984b30527783fc51cea" } Storing nonce: 0001zq-oCUSlOUB-x6Bx-p34r-DwV8lQlD_bhZ756w0ks4Y JWS payload: b'' Sending POST request to https://acme-staging-v02.api.letsencrypt.org/acme/order/19889007/75727166: { "protected": "eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvYWNjdC8xOTg4OTAwNyIsICJub25jZSI6ICIwMDAxenEtb0NVU2xPVUIteDZCeC1wMzRyLUR3VjhsUWxEX2JoWjc1Nncwa3M0WSIsICJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9vcmRlci8xOTg4OTAwNy83NTcyNzE2NiJ9", "signature": "XMlCVSqlLG0ZnUrnZGBy8SMuDC1qkTaq-x1O_u8V3x0Gm-AaQxj2eVCrgHWDFKbiiz56tZurSzjQC2meDChJY0BWHx5AQym6oxP9AZgUURKB2P4Ei3ixTiNhgPHVk6B4LsINzvTD2Rvu5oiP_lEhzwT4M0uAQ0ZOaof3-5SQGhDKKcMXQ0wf9Qnd-yqDCspIBQbJC_0kdFrzXakcOYKfWrQl8WMpypWYUsdyf85OkdABHk0mZ_DWEwl5abVKE9vxABV8WUKWyt27F47qsCSD3nU2ueUwoMuVDPsnWmVqAxu6k0iDnqKMbNEazZ7NZcGQm6NalLya58ehzo8wDsJGNw", "payload": "" } https://acme-staging-v02.api.letsencrypt.org:443 "POST /acme/order/19889007/75727166 HTTP/1.1" 200 466 Received response: HTTP 200 Server: nginx Date: Sun, 13 Jun 2021 17:28:10 GMT Content-Type: application/json Content-Length: 466 Connection: keep-alive Cache-Control: public, max-age=0, no-cache Link: ;rel="index" Replay-Nonce: 0002CL7XZbBBtOpvUn00pELnN_sEhfchhxe6koCJ8eHVFoE X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 { "status": "valid", "expires": "2021-06-20T17:28:05Z", "identifiers": [ { "type": "dns", "value": "monitor.neuro.polymtl.ca" } ], "authorizations": [ "https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/67880884" ], "finalize": "https://acme-staging-v02.api.letsencrypt.org/acme/finalize/19889007/75727166", "certificate": "https://acme-staging-v02.api.letsencrypt.org/acme/cert/fac50cc5390520982984b30527783fc51cea" } Storing nonce: 0002CL7XZbBBtOpvUn00pELnN_sEhfchhxe6koCJ8eHVFoE JWS payload: b'' Sending POST request to https://acme-staging-v02.api.letsencrypt.org/acme/cert/fac50cc5390520982984b30527783fc51cea: { "protected": "eyJhbGciOiAiUlMyNTYiLCAia2lkIjogImh0dHBzOi8vYWNtZS1zdGFnaW5nLXYwMi5hcGkubGV0c2VuY3J5cHQub3JnL2FjbWUvYWNjdC8xOTg4OTAwNyIsICJub25jZSI6ICIwMDAyQ0w3WFpiQkJ0T3B2VW4wMHBFTG5OX3NFaGZjaGh4ZTZrb0NKOGVIVkZvRSIsICJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9jZXJ0L2ZhYzUwY2M1MzkwNTIwOTgyOTg0YjMwNTI3NzgzZmM1MWNlYSJ9", "signature": "mgoqjCy7uRwP5iEabgnWBSNThcuzSwiVtAffUK3RfbxMy9YHbdREwygcfutbUvzGhbsFA7BX0orczESK6QqRZkzoqrPjxCPGbgJilKaV36RKbrNIxzEvom00nFvdYtVQNR5-jXDqL5pIOJoUmrNczLMk8DaqCrCcYF0-MRaBcl1Rgy1k6F2grlSKRo3h1eb67fxnyJ3TSjrtm-eSD-cJgMOlGj71DhI6jH5PpRKcPoKCDnDiIg5qiYMayFriC7yfglBiYI2W8fep2B_thqwPzT9LzYJ4WOLwZjcP-aoPz0xw_a1CBLBTAacw-jP4Ifma2ztPEOi-2V7o_P0tBqnu3w", "payload": "" } https://acme-staging-v02.api.letsencrypt.org:443 "POST /acme/cert/fac50cc5390520982984b30527783fc51cea HTTP/1.1" 200 5759 Received response: HTTP 200 Server: nginx Date: Sun, 13 Jun 2021 17:28:11 GMT Content-Type: application/pem-certificate-chain Content-Length: 5759 Connection: keep-alive Cache-Control: public, max-age=0, no-cache Link: ;rel="index", ;rel="alternate" Replay-Nonce: 0001CdeSN05JXuElpq5HnCqKUcSMhWPaZ5xj719Xlb8RmcI X-Frame-Options: DENY Strict-Transport-Security: max-age=604800 -----BEGIN CERTIFICATE----- MIIFZjCCBE6gAwIBAgITAPrFDMU5BSCYKYSzBSd4P8Uc6jANBgkqhkiG9w0BAQsF ADBZMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXKFNUQUdJTkcpIExldCdzIEVuY3J5 cHQxKDAmBgNVBAMTHyhTVEFHSU5HKSBBcnRpZmljaWFsIEFwcmljb3QgUjMwHhcN MjEwNjEzMTYyODA2WhcNMjEwOTExMTYyODA1WjAjMSEwHwYDVQQDExhtb25pdG9y Lm5ldXJvLnBvbHltdGwuY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQDKLUr7riQ5RpysC1cge3qaernpPc1JFQWZ2XopvOvpD8mBf2hfneikUk/RjTrs eGn37szr+xY27yAMUdFj2CoyZScQnOOlUbA+ayy+KwPxFi+lZC+0KVXairfOJLgn Cy+rnwU8l6s492H0L3QvF0J07/QAt1co3E59v+SvgmvZi+oWp8U4yvf9UScLBDQa Gk/ga67Eo+ms1BSIeHQJr/6E8soqhNEKZlJr/6bROf3ff28otBcDr6dNJnw/gxSM FnlP5J9L6uHnCRBEzeckXcOgmMRDNEx9oZ3ScmK6kbltVW1DBzwyoNPQ+L+diB0J /COf/b5XXEeHGoDQAdNEH9uFAgMBAAGjggJbMIICVzAOBgNVHQ8BAf8EBAMCBaAw HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYD VR0OBBYEFNutAf0txIhWsRoynXlsopZ7vFtaMB8GA1UdIwQYMBaAFN5yekjfMcOm UN+fhSPfVzdLXS5lMF0GCCsGAQUFBwEBBFEwTzAlBggrBgEFBQcwAYYZaHR0cDov L3N0Zy1yMy5vLmxlbmNyLm9yZzAmBggrBgEFBQcwAoYaaHR0cDovL3N0Zy1yMy5p LmxlbmNyLm9yZy8wIwYDVR0RBBwwGoIYbW9uaXRvci5uZXVyby5wb2x5bXRsLmNh MEwGA1UdIARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUH AgEWGmh0dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBBAYKKwYBBAHWeQIEAgSB 9QSB8gDwAHYAsMyD5aX5fWuvfAnMKEkEhyrH6IsTLGNQt8b9JuFsbHcAAAF6BmqX 5wAABAMARzBFAiEAhTdSEIOajv6KTrokngUEE2io3P7gHmE9LpO/OBkTiz4CIHxO 0zNdVDVEGzJIMRkY4Dvl/pDMQw8tul0GCn1pwBzPAHYA3Zk0/KXnJIDJVmh9gTSZ CEmySfe1adjHvKs/XMHzbmQAAAF6BmqhoQAABAMARzBFAiBU1JvWPhd3/IXAAj1u eS9KmEonmOm/e3yLCWqufG0pjgIhAJD8Es+IFbFnzTrpFprvZyr4Nm1flW63uLzf 55+NMiYjMA0GCSqGSIb3DQEBCwUAA4IBAQBbjKZWuc/VBvTaWpvCSv2kYD7k2RVO jU/MJYN6JdlO7EYJD3mGVQSFGsd1i4LIfpR1fYY3kCWJrXb8NryA9mZuwClrfTxe 1xq0c71jAUzscwHCuZCcbSefaGIJPv6se8XohQbJzxXsEHTg+hN2daBAIoLLJb8B ExluSFqmZ1hkx1buTsk701PcUxrmfY3S0DZXE5e+Ntv9u7KT0YrtOLY8Psww9YJP tuAl4UFNhBl+03NjkvdXEaAcVqxCKwe5c6a1eV/PLDyuTxUX2rHthXYEd+dIyIEY bWlEAkfKgOLwiB3Yb9N8lp0XSK5Uq2jUOKGPObdl905UfPY2rFOR/4Oj -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFWzCCA0OgAwIBAgIQTfQrldHumzpMLrM7jRBd1jANBgkqhkiG9w0BAQsFADBm MQswCQYDVQQGEwJVUzEzMDEGA1UEChMqKFNUQUdJTkcpIEludGVybmV0IFNlY3Vy aXR5IFJlc2VhcmNoIEdyb3VwMSIwIAYDVQQDExkoU1RBR0lORykgUHJldGVuZCBQ ZWFyIFgxMB4XDTIwMDkwNDAwMDAwMFoXDTI1MDkxNTE2MDAwMFowWTELMAkGA1UE BhMCVVMxIDAeBgNVBAoTFyhTVEFHSU5HKSBMZXQncyBFbmNyeXB0MSgwJgYDVQQD Ex8oU1RBR0lORykgQXJ0aWZpY2lhbCBBcHJpY290IFIzMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEAu6TR8+74b46mOE1FUwBrvxzEYLck3iasmKrcQkb+ gy/z9Jy7QNIAl0B9pVKp4YU76JwxF5DOZZhi7vK7SbCkK6FbHlyU5BiDYIxbbfvO L/jVGqdsSjNaJQTg3C3XrJja/HA4WCFEMVoT2wDZm8ABC1N+IQe7Q6FEqc8NwmTS nmmRQm4TQvr06DP+zgFK/MNubxWWDSbSKKTH5im5j2fZfg+j/tM1bGaczFWw8/lS nukyn5J2L+NJYnclzkXoh9nMFnyPmVbfyDPOc4Y25aTzVoeBKXa/cZ5MM+WddjdL biWvm19f1sYn1aRaAIrkppv7kkn83vcth8XCG39qC2ZvaQIDAQABo4IBEDCCAQww DgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAS BgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTecnpI3zHDplDfn4Uj31c3S10u ZTAfBgNVHSMEGDAWgBS182Xy/rAKkh/7PH3zRKCsYyXDFDA2BggrBgEFBQcBAQQq MCgwJgYIKwYBBQUHMAKGGmh0dHA6Ly9zdGcteDEuaS5sZW5jci5vcmcvMCsGA1Ud HwQkMCIwIKAeoByGGmh0dHA6Ly9zdGcteDEuYy5sZW5jci5vcmcvMCIGA1UdIAQb MBkwCAYGZ4EMAQIBMA0GCysGAQQBgt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCN DLam9yN0EFxxn/3p+ruWO6n/9goCAM5PT6cC6fkjMs4uas6UGXJjr5j7PoTQf3C1 vuxiIGRJC6qxV7yc6U0X+w0Mj85sHI5DnQVWN5+D1er7mp13JJA0xbAbHa3Rlczn y2Q82XKui8WHuWra0gb2KLpfboYj1Ghgkhr3gau83pC/WQ8HfkwcvSwhIYqTqxoZ Uq8HIf3M82qS9aKOZE0CEmSyR1zZqQxJUT7emOUapkUN9poJ9zGc+FgRZvdro0XB yphWXDaqMYph0DxW/10ig5j4xmmNDjCRmqIKsKoWA52wBTKKXK1na2ty/lW5dhtA xkz5rVZFd4sgS4J0O+zm6d5GRkWsNJ4knotGXl8vtS3X40KXeb3A5+/3p0qaD215 Xq8oSNORfB2oI1kQuyEAJ5xvPTdfwRlyRG3lFYodrRg6poUBD/8fNTXMtzydpRgy zUQZh/18F6B/iW6cbiRN9r2Hkh05Om+q0/6w0DdZe+8YrNpfhSObr/1eVZbKGMIY qKmyZbBNu5ysENIK5MPc14mUeKmFjpN840VR5zunoU52lqpLDua/qIM8idk86xGW xx2ml43DO/Ya/tVZVok0mO0TUjzJIfPqyvr455IsIut4RlCR9Iq0EDTve2/ZwCuG hSjpTUFGSiQrR2JK2Evp+o6AETUkBCO1aw0PpQBPDQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFVDCCBDygAwIBAgIRAO1dW8lt+99NPs1qSY3Rs8cwDQYJKoZIhvcNAQELBQAw cTELMAkGA1UEBhMCVVMxMzAxBgNVBAoTKihTVEFHSU5HKSBJbnRlcm5ldCBTZWN1 cml0eSBSZXNlYXJjaCBHcm91cDEtMCsGA1UEAxMkKFNUQUdJTkcpIERvY3RvcmVk IER1cmlhbiBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQw M1owZjELMAkGA1UEBhMCVVMxMzAxBgNVBAoTKihTVEFHSU5HKSBJbnRlcm5ldCBT ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEiMCAGA1UEAxMZKFNUQUdJTkcpIFByZXRl bmQgUGVhciBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALbagEdD Ta1QgGBWSYkyMhscZXENOBaVRTMX1hceJENgsL0Ma49D3MilI4KS38mtkmdF6cPW nL++fgehT0FbRHZgjOEr8UAN4jH6omjrbTD++VZneTsMVaGamQmDdFl5g1gYaigk kmx8OiCO68a4QXg4wSyn6iDipKP8utsE+x1E28SA75HOYqpdrk4HGxuULvlr03wZ GTIf/oRt2/c+dYmDoaJhge+GOrLAEQByO7+8+vzOwpNAPEx6LW+crEEZ7eBXih6V P19sTGy3yfqK5tPtTdXXCOQMKAp+gCj/VByhmIr+0iNDC540gtvV303WpcbwnkkL YC0Ft2cYUyHtkstOfRcRO+K2cZozoSwVPyB8/J9RpcRK3jgnX9lujfwA/pAbP0J2 UPQFxmWFRQnFjaq6rkqbNEBgLy+kFL1NEsRbvFbKrRi5bYy2lNms2NJPZvdNQbT/ 2dBZKmJqxHkxCuOQFjhJQNeO+Njm1Z1iATS/3rts2yZlqXKsxQUzN6vNbD8KnXRM EeOXUYvbV4lqfCf8mS14WEbSiMy87GB5S9ucSV1XUrlTG5UGcMSZOBcEUpisRPEm QWUOTWIoDQ5FOia/GI+Ki523r2ruEmbmG37EBSBXdxIdndqrjy+QVAmCebyDx9eV EGOIpn26bW5LKerumJxa/CFBaKi4bRvmdJRLAgMBAAGjgfEwge4wDgYDVR0PAQH/ BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLXzZfL+sAqSH/s8ffNE oKxjJcMUMB8GA1UdIwQYMBaAFAhX2onHolN5DE/d4JCPdLriJ3NEMDgGCCsGAQUF BwEBBCwwKjAoBggrBgEFBQcwAoYcaHR0cDovL3N0Zy1kc3QzLmkubGVuY3Iub3Jn LzAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8vc3RnLWRzdDMuYy5sZW5jci5vcmcv MCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQBgt8TAQEBMA0GCSqGSIb3DQEB CwUAA4IBAQB7tR8B0eIQSS6MhP5kuvGth+dN02DsIhr0yJtk2ehIcPIqSxRRmHGl 4u2c3QlvEpeRDp2w7eQdRTlI/WnNhY4JOofpMf2zwABgBWtAu0VooQcZZTpQruig F/z6xYkBk3UHkjeqxzMN3d1EqGusxJoqgdTouZ5X5QTTIee9nQ3LEhWnRSXDx7Y0 ttR1BGfcdqHopO4IBqAhbkKRjF5zj7OD8cG35omywUbZtOJnftiI0nFcRaxbXo0v oDfLD0S6+AC2R3tKpqjkNX6/91hrRFglUakyMcZU/xleqbv6+Lr3YD8PsBTub6lI oZ2lS38fL18Aon458fbc0BPHtenfhKj5 -----END CERTIFICATE----- Storing nonce: 0001CdeSN05JXuElpq5HnCqKUcSMhWPaZ5xj719Xlb8RmcI Dry run: skipping updating lineage at /etc/letsencrypt/live/monitor.neuro.polymtl.ca - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed without reload, fullchain is /etc/letsencrypt/live/monitor.neuro.polymtl.ca/fullchain.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Skipping updaters in dry-run mode. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/monitor.neuro.polymtl.ca/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - no renewal failures IMPORTANT NOTES: - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. ```

I take back what I said above: their --dry-run runs regardless of the state of your actual certs. So

certbot renew --dry-run && certbot renew

is functionally identical to

dehydrated --ca testencrypt-test -o $(mktemp -d) -c && dehydrated -c

Which is probably good enough for my purposes, honestly. But Jason's solution is better :)

kousu commented 3 years ago

@jasoncodes I've refined your suggestion into:

(
  # create/renew certs if necessary, while doing a dry-run to first verify the configuration
  # the dry-run helps avoid hitting https://letsencrypt.org/docs/rate-limits/.
  # see also https://github.com/dehydrated-io/dehydrated/issues/561
  set -eu
  eval "$(dehydrated --env)"  # load $CERTDIR
  TMP_CERTDIR="$(mktemp -d)"
  trap 'rm -r "$TMP_CERTDIR"' EXIT  # beware: bashism
  rsync -a "$CERTDIR"/ "$TMP_CERTDIR" 
  dehydrated -c --ca letsencrypt-test -o "$TMP_CERTDIR" >/dev/null # dry-run
  dehydrated -c
)

It's working well so far :)