Title: Support HTTP-01 Challenge over Port 443 with Self-Signed Certificate for Upgrade Path
I'm working in an environment where port 80 is permanently blocked by firewall policy, and DNS is managed by a separate team, so the dns-01 challenge is not feasible.
Our web server (NGINX) is running on port 443 with a self-signed certificate, and we would like to use Let's Encrypt to upgrade to a trusted certificate.
Unfortunately, none of the current ACME challenge flows allow us to do this:
http-01 is hardcoded to require port 80
tls-alpn-01 requires shutting down NGINX so Certbot can bind to port 443 directly
dns-01 is not an option in our environment
A self-signed certificate on 443 is rejected by the CA when trying to follow http → https redirects
Proposal
Support an explicit, opt-in fallback that allows:
Serving the http-01 challenge over HTTPS on port 443
Presenting a self-signed certificate
Let’s Encrypt’s validation server skipping TLS validation and just checking the HTTP payload
Why this makes sense
Port 80 offers no encryption or authentication at all — it is not safer than 443 with a self-signed cert
http-01 challenges are about serving content, not proving TLS identity
This would allow users to transition from self-signed to trusted certs without taking down mission-critical services or depending on outside DNS admins
Constraints and Mitigations
This could be limited to:
Initial issuance only (not renewal)
Explicit --insecure-https-challenge flag
Rate-limited or audit-logged
Fallback-only behavior if port 80 fails or is known to be blocked
Request for Consideration
I understand that the ACME spec favors simplicity and deterministic behavior, but this is a real-world issue that affects users in locked-down environments.
Could the Certbot project and/or Let's Encrypt consider enabling a controlled fallback for http-01 validation over HTTPS with a self-signed cert to support this upgrade path?
Thanks for your consideration and all your work on the ACME ecosystem.
The HTTP-01 challenge can only be done on port 80. Allowing clients to specify arbitrary ports would make the challenge less secure, and so it is not allowed by the ACME standard.
When redirected to an HTTPS URL, it does not validate certificates (since this challenge is intended to bootstrap valid certificates, it may encounter self-signed or expired certificates along the way).
Unfortunately this is not possible. I'm not really knowledgeable with the exact details, but there are (apparently) good reasons why it's not possible to start the http-01 challenge over HTTPS.
You can probably find out details about this here on the Community, maybe from the earlier days of ACME.
A different solution might be to terminate TLS not by nginx, but by an application that terminates TLS and that will reverse proxy the connection to nginx but also can do the tls-alpn-01 challenge.
Maybe things like lets-proxy2 (I just saw that in the list of ACME Client Implementations, no experience with it), and there might be others out there too. HAProxy unfortunately only seems to have http-01 support.
For this example you'd need to have your http {} block listen on 4433. And you'd need a tls-alpn-01 capable ACME client which Certbot isn't. E.g. lego.
Note that ChatGPT probably made some mistakes (as LLM most often do) and I haven't tested the above.
Other than the ideas already suggested, you could look at below. It handles TLS-ALPN challenges and passes through anything else unchanged to your webserver.
It does require exclusive use of port 443 so you'd have to change nginx to listen on some alternate port and pass through from this to that new port.
Putting something like Caddy in front of your nginx is another option
In this situation, you can either use the TLS-ALPN-01 challenge, or delegate the required _acme-challenge DNS records to a secondary system that you control and use the DNS-01 challenge. The other team would only have to create a single CNAME record once; ACME Servers will follow that record to the secondary dns system for authentication. Many people will self-host this with acme-dns, many others will use a commercial service. Some even use self-host with bind.
Unfortunately your request is not something viable. It would fall victim to the same security concerns that caused the TLS-SNI-01 challenge to be rescinded. The TLS-ALPN-01 challenge was introduced as a replacement, because it is not subject to the same vulnerabilities.
In the ACME drafts there even was a tls-sni-02 apparently, but I don't think Let's Encrypt ever implemented that challenge. Also gone now though, didn't survive to the RFC status. Not sure what the differences are between tls-sni-01 and tls-sni-02, but probably a good bet tls-sni-02 was deemed insecure too.
I still don't see how using https is any less secure than http - the web server is responsible for using the right server {} block based on SNI - what am I missing?
If the paid certificate vendors allow verification via https using self signed certs - then letsencrypt should as well. If some users are worried about a specific security issue related to using https instead of http, then they don't need to use it, but by not having https as an option, letencrypt shuts the door on users that can't use port 80, or don't want to do DNS delegation, or can't have their web servers give up port 443 for any amount of time.
Let's Encrypt isn't, doesn't claim to be, and doesn't attempt to be all things to all people. Users who have made choices that preclude their use of Let's Encrypt are free to use a different CA, or perhaps to rethink those choices.
Just curious why it would. Requests inbound on port 443 get seen first by the uacme proxy handler. If it is a TLS-ALPN request it processes it. If it is not it passes it unchanged to nginx on some other port. Front-end proxies often proxy to backend servers on alternate ports.
The short of it is that if you (1) don't have control over port 80, (2) don't have control over the ALPN negotiated on port 443, and (3) don't have control over DNS, then you really don't have control over that domain name.
If you can't get your network administrators to open up port 80 (even to redirect to another place, such as port 443 with a self-signed certificate), or allow you to run software on 443 that can automatically handle getting certificates via ALPN (such as Caddy, uacme, or something else), or allow you control over DNS (even a CNAME to delegate to something like acme-dns that you can control), then your network administrators clearly don't think you should control the name and get a certificate for it.
Nginx has a standard module (though not built by default) that enables tls-alpn auth through a proxy to another service
I don't know of any ACME nginx modules. IIRC, there are a few OpenResty modules that handle this. Last I checked, most nginx ACME implementations involved offloading the ACME process onto a secondary service (shell script, app, docker container, etc).
An alternative is to defer certificate management to your infrastructure team (assuming they are the ones who control DNS) and setup a certificate request process where:
folks who need one can ask for a cert to be created (using DNS domain validation)
the cert + key can then be:
automatically deployed to a know location on the target machine
and/or stored in secrets vault you have access to and periodically pulled via API.
At the risk of self promotion, Certify Management Hub (beta) does all that, with role based access etc: Getting Started | Certify The Web Docs - it also has a managed challenges feature where you can let the hub complete DNS challenge on behalf of your client, so you don't need to know/store privileged secrets. There is also an experimental ACME proxy option in the works (which lets you use any EAB enabled ACME client to create an order, the hub sorts out the challenge responses for you, controlled by the hub administrator).