[en/fr] Workaround for the Subscriber Agreement Update or Let's Encrypt / Contournement pour la récente mis à jour des conditions d'utilisation de Lets Encrypt



Hello !

A few of you might have noticed that Let’s Encrypt certificate fetching/renewing is broken. This is due to a recent change on Let’s Encrypt’s side. While we fix the issue upstream, a workaround is to run the following command on your server using SSH :

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py -O /usr/lib/moulinette/yunohost/vendor/acme_tiny/acme_tiny.py


Coucou !

Certains d’entres vous ont peut-être remarqué que la récupération et le renouvellement de certificats Let’s Encrypt est actuellement cassé. Ceci est du a une mise à jour récente dans les conditions d’utilisation de Let’s Encrypt. En attendant que nous corrigions le problème directement dans YunoHost, vous pouvez contourner le problème en execurant la commande suivante sur votre serveur en SSH :

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py -O /usr/lib/moulinette/yunohost/vendor/acme_tiny/acme_tiny.py

Didn’t work for me.

After that command it still says, that it cannot update because of the wrong agreement url. It seems, that the update doesn’t get recognized. (?)

(And yes, the update worked - the new “agreement” part is:
“agreement”: json.loads(urlopen(CA + “/directory”).read().decode(‘utf8’))[‘meta’][‘terms-of-service’], - but this doesn’t lead to the new ToS)

2017-11-19 14:32:17,658 INFO geventwebsocket.handler log_request - - - [2017-11-19 14:32:17] “POST /domains/cert-install/domain HTTP/1.1” 201 148 7.986514

2017-11-19 14:32:17,806 INFO     moulinette.actionsmap process - processing action [4192.78]: yunohost.domain.cert-status

2017-11-19 14:32:18,101 INFO     urllib3.connectionpool _new_conn - Starting new HTTP connection (1): *ip*

2017-11-19 14:32:18,115 INFO     geventwebsocket.handler log_request - - - [2017-11-19 14:32:18] "GET /domains/cert-status/*domain*?full&locale=de HTTP/1.1" 200 400 0.430308

2017-11-19 14:33:15,778 INFO     moulinette.actionsmap process - processing action [4192.79]: yunohost.domain.cert-status

2017-11-19 14:33:16,111 INFO     urllib3.connectionpool _new_conn - Starting new HTTP connection (1): *ip*

2017-11-19 14:33:16,126 INFO     geventwebsocket.handler log_request - - - [2017-11-19 14:33:16] "GET /domains/cert-status/*domain*?full&locale=de HTTP/1.1" 200 400 0.509194

2017-11-19 14:36:11,502 INFO     moulinette.actionsmap process - processing action [4192.80]: yunohost.domain.cert-install

2017-11-19 14:36:11,829 INFO     urllib3.connectionpool _new_conn - Starting new HTTP connection (1): *ip*

2017-11-19 14:36:11,841 INFO     yunohost.certmanager _certificate_install_letsencrypt - [4192.80] Now attempting install of certificate for domain *domain*!

2017-11-19 14:36:12,130 INFO     urllib3.connectionpool _new_conn - Starting new HTTP connection (1): *ip*

2017-11-19 14:36:12,142 INFO     yunohost.certmanager _configure_for_acme_challenge - [4192.80] Nginx configuration file for ACME challenge already exists for domain, skipping.

2017-11-19 14:36:12,371 INFO     yunohost.certmanager _fetch_and_enable_new_certificate - [4192.80] Prepare key and certificate signing request (CSR) for *domain*...

2017-11-19 14:36:14,138 INFO     yunohost.certmanager _prepare_certificate_signing_request - [4192.80] Saving to /tmp/acme-challenge-private/*domain*.csr.

2017-11-19 14:36:14,139 INFO     yunohost.certmanager _fetch_and_enable_new_certificate - [4192.80] Now using ACME Tiny to sign the certificate...

2017-11-19 14:36:14,140 INFO     yunohost.certmanager get_crt - [4192.80] Parsing account key...

2017-11-19 14:36:14,195 INFO     yunohost.certmanager get_crt - [4192.80] Parsing CSR...

2017-11-19 14:36:14,250 INFO     yunohost.certmanager get_crt - [4192.80] Registering account...

2017-11-19 14:36:15,125 ERROR    yunohost.certmanager _fetch_and_enable_new_certificate - [4192.80] Error registering: 400 {

  "type": "urn:acme:error:malformed",

  "detail": "Provided agreement URL [https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf] does not match current agreement URL [https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf]",

  "status": 400


It’s not working for me either.

Not working for me either.

Error registering: 400 { "type": "urn:acme:error:malformed", "detail": "Provided agreement URL [https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf] does not match current agreement URL [https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf]", "status": 400 }
Certificate installation for squirrel.science failed ! Exception: [Errno 22] Signing the new certificate failed

Found it ! I modified the python script that is call the Agreement :

you just do :
nano /usr/lib/moulinette/yunohost/vendor/acme_tiny/acme_tiny.py
and replace the line :
with this one :
Then go back and do :
yunohost domain cert-install

Then it worked.


Bam! Worked like a charm, thanks!

1 Like

I have no such line.
I guess this is due to the workaround. Where can I find the old acme_tiny file?

Just have a look for the line beginning with “agreement” and replace everything after that with the line written above. It worked for me!

Like this?

admin@Xroklaus:~ $ cat /usr/lib/moulinette/yunohost/vendor/acme_tiny/acme_tiny.py
#!/usr/bin/env python
import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging
    from urllib.request import urlopen # Python 3
except ImportError:
    from urllib2 import urlopen # Python 2

#DEFAULT_CA = "https://acme-staging.api.letsencrypt.org"
DEFAULT_CA = "https://acme-v01.api.letsencrypt.org"


    # get the certificate domains and expiration
    log.info("Registering account...")
    code, result = _send_signed_request(CA + "/acme/new-reg", {
        "resource": "new-reg",
        "agreement": "https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf",
    if code == 201:
    elif code == 409:
        log.info("Already registered!")
        raise ValueError("Error registering: {0} {1}".format(code, result))


if __name__ == "__main__": # pragma: no cover

It doesn’t work for me. I’m still getting this error:

admin@Xroklaus:~ $ sudo yunohost domain cert-renew --force
Error: Wrote file to /tmp/acme-challenge-public/TH6t-IY0aBep7n4SYY_twgopTqaLyAKb7hsPVm6r6JE, but couldn't download http://duniter-folatt.nohost.me/.well-known/acme-challenge/TH6t-IY0aBep7n4SYY_twgopTqaLyAKb7hsPVm6r6JE
Error: Certificate renewing for duniter-folatt.nohost.me failed !
Error: Traceback (most recent call last):
  File "/usr/lib/moulinette/yunohost/certificate.py", line 382, in certificate_renew
    _fetch_and_enable_new_certificate(domain, staging)
  File "/usr/lib/moulinette/yunohost/certificate.py", line 567, in _fetch_and_enable_new_certificate
MoulinetteError: [Errno 22] Signing the new certificate failed

Error: [Errno 22] Signing the new certificate failed

You have not the same error as me and I don’t think it’s related to this workaround.
Maybe you should open a new thread for this.

It worked for me too! However before running :
yunohost domain cert-install
I tried to install the certificate through the web admin interface, and it didn’t work.
Thanks a lot!

Your issue is not related to the agreement issue. And your error message si quite clear :
"[quote=“folatt, post:10, topic:3823”]
Error: Wrote file to /tmp/acme-challenge-public/TH6t-IY0aBep7n4SYY_twgopTqaLyAKb7hsPVm6r6JE, but couldn’t download http://duniter-folatt.nohost.me/.well-known/acme-challenge/TH6t-IY0aBep7n4SYY_twgopTqaLyAKb7hsPVm6r6JE
your script is trying to download a file and it failed, try to download your self using wget : cd /tmp/acme-challenge-public/ && wget http://duniter-folatt.nohost.me/.well-known/acme-challenge/TH6t-IY0aBep7n4SYY_twgopTqaLyAKb7hsPVm6r6JE ( not the answer put the idea is there ) .

1 Like

(The file is ‘ephemerous’ so when doing this kind of tests, one needs to create a dummy file, e.g. :

touch /tmp/acme-challenge-public/toto
wget http://duniter-folatt.nohost.me/.well-known/acme-challenge/toto
1 Like

that is why I said " ( not the answer put the idea is there )" …

1 Like

Yes, sorry, I was not blaming you :wink: That’s actually pretty cool to take the time to explain this. I just thought @folaht will be trying this at some point so I thought I’d elaborate a bit :sweat_smile:


It’s not working.

admin@Xroklaus:/tmp $ sudo touch /tmp/acme-challenge-public/toto
admin@Xroklaus:/tmp $ sudo wget http://duniter-folatt.nohost.me/.well-known/acme-challenge/toto
--2017-11-27 18:43:40--  http://duniter-folatt.nohost.me/.well-known/acme-challenge/toto
Resolving duniter-folatt.nohost.me (duniter-folatt.nohost.me)... my.ip.v.4
Connecting to duniter-folatt.nohost.me (duniter-folatt.nohost.me)|my.ip.v.4|:80... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: https://duniter-folatt.nohost.me/yunohost/admin [following]
--2017-11-27 18:43:40--  https://duniter-folatt.nohost.me/yunohost/admin
Connecting to duniter-folatt.nohost.me (duniter-folatt.nohost.me)|my.ip.v.4|:443... connected.
ERROR: The certificate of ‘duniter-folatt.nohost.me’ is not trusted.
ERROR: The certificate of ‘duniter-folatt.nohost.me’ hasn't got a known issuer.
The certificate's owner does not match hostname ‘duniter-folatt.nohost.me’

Instead of just commenting out a line, I’ve completely uninstalled Duniter.
Uninstalling duniter does not work either.

I still get the same error.


I think I just figured out what I’m doing wrong.
I have two servers and Let’s Encrypt is fetching them over IPv4.

Looks like I need to set inet6_only = on in /etc/wgetrc for starters.


Looks like my domain is not registered as ipv6.

admin@Xroklaus:~ $ sudo wget -6 http://duniter-folatt.nohost.me/.well-known/acme-challenge/toto
--2017-11-28 19:20:08--  http://duniter-folatt.nohost.me/.well-known/acme-challenge/toto
Resolving duniter-folatt.nohost.me (duniter-folatt.nohost.me)... failed: Name or service not known.
wget: unable to resolve host address ‘duniter-folatt.nohost.me’

Thanks! It saved my evening! :hugging:

Worked for me too!