Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Option to dry-run #561

Open
mrhackcz opened this issue May 14, 2018 · 8 comments
Open

Feature: Option to dry-run #561

mrhackcz opened this issue May 14, 2018 · 8 comments
Milestone

Comments

@mrhackcz
Copy link

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

@mrhackcz mrhackcz changed the title Add option to dry-run Feature: Option to dry-run May 14, 2018
@lukas2511 lukas2511 added this to the Release 0.7.0 milestone May 22, 2018
@danimo
Copy link
Contributor

danimo commented Sep 30, 2020

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

  • how to deal with hooks (as they may break when the acual operation does not happen and re likely not written to consider dry-runs or be idempotent)
  • how to deal with an account in an invalid state (not registered, etc)

@lukas2511 lukas2511 modified the milestones: Things I'd like to get done, but uhm.. not now, Long term Dec 11, 2020
@kousu
Copy link
Contributor

kousu commented Jun 12, 2021

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
  • If run with valid certs, this leaves them alone
  • can't be run with non-existent certs, because in certbot, configuration is the same as getting an initial cert (certbot certonly -d "$(hostname) [and probably some other options]")
  • If run with expiring certs, either:
    • discovers your configuration is bad or
    • replaces them with valid certs

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:

  • --ca letsencrypt vs --ca letsencrypt-test
  • --ca buypass vs --ca buypass-test
  • --ca zerossl (which doesn't have a staging server; but it also doesn't have rate limits, so maybe we can consider it its own staging server)
    Then I tried

@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 Feature: Option to dry-run #561 (comment)
  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
  • If run with valid certs, this leaves them alone
  • If run with non-existent certs, either
    • discovers your configuration is bad or
    • outputs test certs
  • If run with expiring certs, either
    • discovers your configuration is bad or
    • replaces them with test certs

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
  • If run with valid certs, leaves them alone
  • If run with non-existent or expiring certs, either
    • discovers your configuration is bad or
    • destroys all your certs and outputs new certs

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
  • If run with valid certs, leaves them alone
  • If run with non-existent or expiring certs, either
    • discovers your configuration is bad or
    • outputs new certs

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:

  • If run with valid certs, leaves them alone
  • If run with non-existent or expiring certs, either
    • discovers your configuration is bad or
    • outputs new certs

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

@lukas2511
Copy link
Member

@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
Copy link
Contributor

kousu commented Jun 13, 2021

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
Copy link

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
Copy link
Contributor

kousu commented Jun 13, 2021

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

@kousu
Copy link
Contributor

kousu commented Jun 13, 2021

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 <certbot.cli._Default object at 0x7ff787daa790> and installer <certbot.cli._Default object at 0x7ff787daa790>
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: <certbot.plugins.webroot.Authenticator object at 0x7ff787ddbcd0>
Prep: True
Selected authenticator <certbot.plugins.webroot.Authenticator object at 0x7ff787ddbcd0> 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: <https://acme-staging-v02.api.letsencrypt.org/directory>;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: <https://acme-staging-v02.api.letsencrypt.org/directory>;rel="index", <https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf>;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: <Account(RegistrationResource(body=Registration(key=JWKRSA(key=<ComparableRSAKey(<cryptography.hazmat.backends.openssl.rsa._RSAPublicKey object at 0x7ff787daf910>)>), 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=<UTC>), 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: <https://acme-staging-v02.api.letsencrypt.org/directory>;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: <https://acme-staging-v02.api.letsencrypt.org/directory>;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: <https://acme-staging-v02.api.letsencrypt.org/directory>;rel="index", <https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/67880884>;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: <https://acme-staging-v02.api.letsencrypt.org/directory>;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: <https://acme-staging-v02.api.letsencrypt.org/directory>;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: <https://acme-staging-v02.api.letsencrypt.org/directory>;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: <https://acme-staging-v02.api.letsencrypt.org/directory>;rel="index", <https://acme-staging-v02.api.letsencrypt.org/acme/cert/fac50cc5390520982984b30527783fc51cea/1>;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
Copy link
Contributor

kousu commented Jun 13, 2021

@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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants