LetsEncrypt 'Token did not match'

Please note that this topic is not a duplicate of the other similar posts I could find. This is a ‘Token did not match’ failure, not a “Token unavailable…” error.

On the Dashboard I get a message:

Security Issue

Some Certificates are expiring or have expired

This is a critical issue and should be resolved urgently

When I go to Admin > Certificate Management and click on the Edit button for the default certificate (which is of type “Let’s Encrypt”), I get the “Edit Let’s Encrypt Certificate” page with a green “Firewall Validated” message. So far, so good.

Unfortunately, when I click on the “Update Certificate” button, I get the message:

There was an error updating the certificate: Error ‘Token did not match’ when requesting http://pbx.survivalflightinc.com//.freepbx-known/b5b701f4cfe5db1ae8c888895008c1fe

Our VPS is hosted on freepbxhosting.com, so I am certain that there is no “other firewall” blocking LetsEncrypt access. In addition. I have verified that I can fetch/wget the URL (you can too!) which returns the token: c9da31faa9f07d6160a7eb53b1b022d0

I am a tiny bit concerned that the URI is malformed (there should not be a double slash just before .freepbx-known, but that does not seem to be the issue with the failure to update the certificate since a token is returned.

What I don’t understand is how the token could have changed, either on our VPS or at Let’s Encrypt.

I did try the fix that was outlined by @invdrv here. But that didn’t affect the problem either way.

Does anyone who understands how FreePBX/Asterisk issues the Let’s Encrypt update request? How could the default configured token fail to match?

Has anyone else come across this problem?

I’m about to delete the default certificate and see if I can get the system to generate a new Let’s Encrypt certificate from scratch, but I’m a little reluctant to make that change and risk losing my connection to our FreePBX image.

Thanks in advance for any suggestions.



You should probably revoke the cert you got from Digital Signature Trust Co.and the one you got from LetsEncrypt , then have one or the other reissue cleanly

@dicko, THANK YOU for the quick response, and for that awesome link to sslshopper. I have not seen that before.

Unfortunately, the link you included above shows that the certificate is as good as it gets. Everything is green, and the cert was issued by Let’s Encrypt. Woo hoo!

I’m not certain how I could revoke the certificate issued by Let’s Encrypt to us, and I’m 100% certain nobody would like it if I could somehow revoke the certificate issued from Digital Signature Trust Co. to Let’s Encrypt. :grin: But, eitherway, it wouldn’t address the two concerns I have,

  1. Why/how did the token that FreePBX is serving up stop matching the token Let’s Encrypt is expecting to find? :man_shrugging:

  2. Does anyone know if my FreePBX control panel will become unaccessible if I Delete the existing Let’s Encrypt certificate on the Certificate Management screen?

I really don’t want to loose access while trying to fix this bizarre issue with the FreePBX <–> Let’s Encrypt configuration.

Well, I’ve been spelunking in the code for FreePBX/certman.

I still don’t know what’s causing the failure, but I can see that a new Let’s Encrypt certificate is requested iff (a) there is no existing certificate or (b) the existing certificate will expire in less than 30 days. (see lines 612-626 of Console/Certman.class.php)

If (a) or (b) is true, two things happen:

  1. a new file is created at /var/www/html/.freepbx-known/<value-of-token> where <value-of-token> is the random 32-hexet ASCII string generated by $token = bin2hex(openssl_random_pseudo_bytes(16)), and

  2. a GET request is made to http://mirror1.freepbx.org/lechecker.php with host=pbx.acme.org&path=/.freepbx-known/<value-of-token>&token=<value-of-token>&type=http using an instance of PestJSON (see lines 637 to 642)

I have not found the source to lechecker.php (yet), so I’m not sure what kind of magic is being performed over at mirror1.freepbx.org on our behalf. But, I can see in the /var/log/httpd/access_log on my FreePBX VPS that it causes an request to be generated back to the URL: http://pbx.acme.org/.freepbx-known/<value-of-token>

By trying wget -qO - 'http://mirror1.freepbx.org/lechecker.php?host=pbx.survivalflightinc.com&path=/.freepbx-known/c9da31faa9f07d6160a7eb53b1b022d0&token=c9da31faa9f07d6160a7eb53b1b022d0&type=http' I can see that lechecker.php returns {"status":false,"message":"Token did not match"} (BTW, the GET request to lechecker.php must be issued from the same IP as host resolves to or else lechecker.php will return an error.)

Yet a plain wget -qO - 'http://pbx.survivalflightinc.com/.freepbx-known/c9da31faa9f07d6160a7eb53b1b022d0' returns c9da31faa9f07d6160a7eb53b1b022d0

For some reason, the token matches when I wget it, but not when lechecker.php does.

Still scratching my head…

The only thing I can suggest is running a tcpdump on your machine when mirror1 reaches out to it, and make sure that your machine IS ACTUALLY RETURNING the correct data. The code (from what I can remember) is super simple - it’s basically just a if ($token === $expected).

If what you’re seeing in tcpdump matches what you expect to see, you’ll have to open a ticket on issues.freepbx.org about it.

Probably your webserver redirects all HTTP requests to HTTPS.

Change the webserver config to restrict redirections:

<VirtualHost *:80>
 RewriteEngine on
 RewriteRule ^/(admin|ucp)/(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [NC,R=301,NE,L]

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.