As I understand it, you’re using the webroot plugin. What this plugin does is write a file to the path you provide, under the assumption that your web server is configured to serve files under this path as-is, like you’d expect something like apache or nginx to do with its stock configuration.
If that is not the case for you, maybe because you’re running some kind of application server that doesn’t do that by default, there are a couple of options. If you’re running some kind of reverse proxy (nginx, etc.) in front of your application server, you could configure requests that match the path /.well-known/acme-challenge/* to be served from your filesystem instead. Another approach would be to implement the reading of that file in your application code, with the HTTP response being the file contents.
Alternatively, you could use one of the various low-level ACME libraries and essentially implement your own ACME client. This option would be the most involved. ACME is the internet standard that’s used by Let’s Encrypt to automate issuance and validation. The relevant specification would be the acme-01 draft. This is also where the format and content of the response is specified (under 7.1 Key Authorizations).
Thanks for answer. I was able to make it work using DNS validation.
Honestly, I still do not understand how this method work, but is not important, the DNS solution makes so much more sense to me.
Now I have another similar issue.
It seem I have to use --csr command in order to have certbot verify a certificate I self signed.
I’m following this: Using certbot with --csr
This is what I get:
$ certbot certonly --csr unifi_certificate.csr.pem --staging --standalone
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Performing the following challenges:
tls-sni-01 challenge for portal.cotech.co
Waiting for verification...
Cleaning up challenges
An unexpected error occurred:
The request message was malformed :: Error parsing certificate request: asn1: syntax error: sequence truncated
Please see the logfiles in /var/log/letsencrypt for more details.
Again, I face a similar issue: what is my server at portal.cotech.co supposed to answer and where?
If you can’t find anything, feel free to post the CSR here - someone in the community might find a non-obvious issue that causes the CA server to trip over it.
As a side note, the challenge mechanism in dns-01 works quite similar to the HTTP challenge. The only difference is that instead of the key authorization itself, the response (i.e. the content of the TXT record) should be the hash of the key authorization.
With the --standalone option, certbot handles the challenge verification for you. In your particular case, it spawns a web server on port 443 and responds with a special certificate that demonstrates domain ownership. Note that this option will not continue to work if you ever start running your own web server on port 443 - in that scenario, you would have to either stop your web server for renewal (so that certbot can listen on the port), or use one of the other methods (webroot, etc.) that work with existing, running web servers.
Regarding the CSR you posted, is that the output of the OpenSSL command I posted, or is that the actual file? If it’s the latter: That’s not a PEM or DER file. Otherwise, would you mind posting the file itself?
I’m running certbot from a virtual machine that is indeed the one running the server that answer to unifi.cotech.co. After your description, I understand is mandatory to run certbot from the machine linked to the domain I am trying to verify, right?
on that machine, the server is a java webapp, that do NOT use port 443 for HTTPS (java convention is 8443) so I do not need to turn it off
I posted the output of the openssl command against the .pem.
Correct, if you don't use port 443, you can continue to use standalone.
I was able to verify that Go's x509 library (which is what the CA server uses) chokes on this particular CSR: Go Playground - go.dev
I had a bit of a déjà vu while doing this and eventually found this thread, where someone else was experiencing the same problem with a CSR generated by unifi:
Unfortunately, it doesn't look like a solution was posted. There's either an issue in unifi that produces invalid CSRs, or Go's ASN.1 parser has a bug. I tried to find the problem using various ASN.1 parsers, but couldn't find anything. Perhaps someone with more of an understanding of ASN.1 will find the problem.
@allrik: Did you ever find a solution for this? Thanks!
You got it working with JKS, but for the record, all you have to do is replace the JKS file with a PKCS#12 file, and change type="JKS" to type="PKCS12" in your server.xml file if it is explicitly defined. (IIRC the server.xml shipped with the UniFi Controller doesn’t require this; I just dropped a PKCS12 file in place of the original JKS store with my LE certificate, chain, and key, encrypted with the password “aircontrolenterprise” and everything Just Worked.)
Is not fixed when you are redirected there by the Access point, and that page act as the Captive Portal of a protected network.
Now I know why. The issue is not in the certificate of portal.cotech.co (which was working perfectly since the beginning) or the certificate of the machine where the network controller software workds (the one I imported in the keystore). Both are irrelevant. The issue is that the portal is running on heroku and the Captive Portal pre-authorization whitre-list does NOT work with domain (As stated in webapp and doc) but must also have IPs.
The worst is that heroku have dynamic IPs so in the end the solution will be install the portal webapp on Digital Ocean.
In the end, all this tour on SSL and certbot has been “useless” for the sake of the project, but at least now I a little more knowledgable with SSL