I am using the Let's Encrypt IIS client from https://github.com/Lone-Coder/letsencrypt-win-simple to generate a certificate for a server. Since the certificate is only valid for three months, I want it to auto-renew.
But the server for which I need that auto-renewing certificate is only bound to https:||mysubdomain.mydomain.com:443 and smtp:||mysubdomain.mydomain.com:25.
Both http:||mysubdomain.mydomain.com:80 and ftp:||mysubdomain.mydomain.com:21 point to a different server.
As you may have guessed, the error that is now thrown during the process is "The ACME server was probably unable to reach http:||mysubdomain.mydomain.com:80/.well-known/acme-challenge/abcdefgh...xyz".
It is completely clear to me why, but I can't fix it, because http:||mysubdomain.mydomain.com has to point to the other server. If the ACME server would try https:||mysubdomain.mydomain.com:443/.well-known/acme-challenge/abcdefgh...xyz, but ignore any certificate issue, he would successfully find the challenge.
Is there anything I can do, any feature I have overlooked, that would help me to get automated renewal working?
There are multiple options:
http-01
Redirect http://example.com/.well-known/acme-challenge/* to https://example.com/.well-known/acme-challenge/*, Boulder will happily follow any such redirect and ignore the provided certificate. That's the most simple way if you have access to the other server and can configure that redirect. It's a permanent redirect that you don't have to adjust, it'll be just fine every three months.
The option to use HTTPS directly has been removed due to security issues with some popular server software that uses the first host defined if some other virtual host doesn't define any HTTP host, which might lead to wrong issuances in multi-user environments aka shared hosting.
tls-sni-01
If you want to use just port 443, you can use another challenge type called tls-sni-01. But I think there's no client for Windows available yet that supports that challenge type.
dns-01
If you have control over the DNS via a simple API, you could also use the DNS challenge, it's completely independent of the port you can use.
Related
I've been investigating the possibility of migrating to using Let's Encrypt to maintain the SSL certificates we have in place for the various resources we use for our operations. We have the following resources using SSL certificates:
Main website (www.example.com / example.com) - Hosted and maintained by a 3rd party who also maintains the SSL certificate
Client portal website (client.example.com) - IIS site hosted and maintained by us on a server located in a remote data center
FTP server (ftp.example.com) - WS_FTP Server hosted and maintained by us on a server located in a remote data center
Hardware firewall (firewall.example.com) - Local security appliance for our internal network
Remote Desktop Gateway (rd.example.com) - RDP server hosted and maintained by us on a server located locally
As indicated above, the SSL certificate for the main website (www) is maintained by the 3rd-party host, so I don't generally mess with that one. However, as you can tell, the DNS records for each of these endpoints point to a variety of different IP addresses. This is where my inexperience with the overall process of issuing and deploying SSL certificates has me a bit confused.
First of all, since I don't manage or maintain the main website, I'm currently manually generating the CSR's for each of the endpoints from the server/service that provides the endpoint - one from the IIS server, a different one from the RDP server, another from the WS_FTP server, and one from the hardware firewall. The manual process, while not excessively time-consuming, still requires me to go through several steps with different server systems requiring different processes.
I've considered using one of Let's Encrypt's free wildcard SSL certificates to cover all four of these endpoints (*.example.com), but I don't want to "interfere" with what our main website host is doing on that end. I realize the actual certificate itself is presented by the server to which the client is connecting, so it shouldn't matter (right?), but I'd probably still be more comfortable with individual SSL certificates for each of the subdomain endpoints.
So, I've been working on building an application using the Certes ACME client library in an attempt to automatically handle the entire SSL process from CSR to deployment. However, I've run into a few snags:
The firewall is secured against connections on port 80, so I wouldn't be able to serve up the HTTP-01 validation file for that subdomain (fw.example.com) on the device itself. The same is true for the FTP server's subdomain (ftp.example.com).
My DNS is hosted with a provider that does not currently offer an API (they say they're working on one), so I can't automate the process of the DNS-01 validation by writing the TXT record to the zone file.
I found the TLS-ALPN-01 validation method, but I'm not sure whether or not this is appropriate for the use case I'm trying to implement. According to the description of this method from Let's encrypt (emphasis mine):
This challenge is not suitable for most people. It is best suited to authors of TLS-terminating reverse proxies that want to perform host-based validation like HTTP-01, but want to do it entirely at the TLS layer in order to separate concerns. Right now that mainly means large hosting providers, but mainstream web servers like Apache and Nginx could someday implement this (and Caddy already does).
Pros:
It works if port 80 is unavailable to you.
It can be performed purely at the TLS layer.
Cons:
It’s not supported by Apache, Nginx, or Certbot, and probably won’t be soon.
Like HTTP-01, if you have multiple servers they need to all answer with the same content.
This method cannot be used to validate wildcard domains.
So, based on my research so far and my environment, my three biggest questions are these:
Would the TLS-ALPN-01 validation method be an effective - or even available - option for generating the individual SSL certificates for each subdomain? Since the firewall and FTP server cannot currently serve up the appropriate files on port 80, I don't see any way to use the HTTP-01 validation for these subdomains. Not being able to use an API to automate a DNS-01 validation would make that method generally more trouble than it's worth. While I could probably do the HTTP-01 validation for the client portal - and maybe the RDP server (I haven't gotten that far in my research yet) - I'd still be left with handling the other two subdomains manually.
Would I be better off trying to do a wildcard certificate for the subdomains? Other than "simplifying" the process by reducing the number of SSL certificates that need to be issued, is there any inherent benefit to going this route versus using individual certificates for each subdomain? Since the main site is hosted/managed by a 3rd-party and (again) I can't currently use an API to automate a DNS-01 validation, I suppose I would need to use an HTTP-01 validation. Based on my understanding, that means that I would need to get access/permission to create the response file, along with the appropriate directories on that server.
Just to be certain, is there any chance of causing some sort of "conflict" if I were to generate/deploy a wildcard certificate to the subdomains while the main website still used its own SSL certificate for the www? Again, I wouldn't think that to be the case, but I want to do my best to avoid introducing more complexity and/or problems into the situation.
I've responded to your related question on https://community.certifytheweb.com/t/tls-alpn-01-validation/1444/2 but the answer is to use DNS validation and my suggestion is to use Certify DNS (https://docs.certifytheweb.com/docs/dns/providers/certifydns), which is an alternative managed alternative cloud implementation of acme-dns (CNAME delegation of DNS challenge responses.
Certify DNS is compatible with most existing acme-dns clients so it can be used with acme-dns compatible clients as well as with Certify The Web (https://certifytheweb.com)
I am quite new to ssl stuffs but I am afraid I can guess the final answer of the following problem/question:
We are building hardware (let's call them servers) that WILL have IP address modifications along there lifetime. Each Server must be reachable in a secured manner. We are planning to use a TLS 1.3 secured connection to perform some actions on the servers (update firmware, change configuration and so on). As a consequence we need to provide the server's with one certificate (each) so that they can state their identity. PKI issue is out of the scope of this question (we suppose) and we can take for granted that the clients and the servers will share a common trusted CA to ensure the SSL handshake goes ok. The server's will serve http connection on there configured (changeable) IP addresses only. There is no DNS involved on the loop.
We are wondering how to set the servers' certificates appropriately.
As IP will change, it cannot be used as the common name in the server's certificate.
Therefore, we are considering using something more persistent such as a serial number or a MAC address.
The problem is, as there is no DNS in the loop, the client can not issue http request to www.serialNumberOfServer.com and must connect to http://x.y.z.t (which will change frequently (at least frequently enough so that we don't issue a new server's certificate at each time))
If we get it right, ssl handshake requires to have the hostname (that's in the URL we are connecting to) matching either the commonName of the server's Certificate or one of its Subject's Alternative Name (SAN). Right? Here, it would be x.y.z.t.
So we think we are stucked in a situation in which the server cannot use it's IP to prove its identity and the client wants to use it exclusively to connect to the server.
Is there any work around?
Are we missing something?
Any help would be very (VERY) appreciated. Do not hesitated in cas you should need more detailed explanation!
For what it's worth, the development environment will be Qt using the QNetworkAccessManager/QSSlstuffs framework.
If you're not having the client use DNS at all, then you do have a problem. The right solution is to use DNS or static hostname lists (/etc/hosts, eg, on unix* or hosts.txt on windows eg.). That will let you set names appropriately.
If you can only use IP addresses, another option is to put all of your IP addresses into the certificate that the server might use. This is only doable if you have a reasonable small number of addresses that they might get assigned to.
Or you could keep a cache of certificates on the server with one address for each, and have part of the webserver start process to select the right certificate. Requires a bit more complex startup.
Edit: Finally, some SSL stacks (e.g. openssl) let you decide whether or not each particular verification error should be accepted as an error or that it can be ignored. This would let you override the errors on the client side. However, this is hard to implement properly and very prone to security issues if you don't bind the remote certificate properly it means you're subjecting yourself to man-in-the-middle or other attacks by blindly accepting any old certificate. I don't remember if Qt's SSL library gives you this level of flexibility or not (I don't believe so but didn't go pull up the documentation).
Went back on the subject 9 mont later!
Turns out there is an easy solution (at least with Qt framework)
Qt's QNetworkRequest::setPeerVerifyName does the job for us. It allows to connect to an host using its IP and verify a given CN during SSL handshake
See Qt's documentation extract below:
void QNetworkRequest::setPeerVerifyName(const QString &peerName)
Sets peerName as host name for the certificate validation, instead of the one used for the TCP connection.
This function was introduced in Qt 5.13.
See also peerVerifyName.
Just tested it positively right now
We have a website with SSL configured. 2 days back SSL certificate was expired so I purchased a new instead of renewing. I have configured the new one. Now some of users are still getting SSL certificate expired issue although the new one is configured.
I want to force the browser to recheck the new SSL certificate using some server side configuration since we can not go and update each user browser certificate manually. It have to be done using some server side configuration. We are using Nginx.
This is really critical to us.
Please help in this regard.
Thanks!
The certificate is validated by the client only when the server sends one. The server sends one with each full TLS handshake. The browser does not somehow cache an old certificate and ignore the one sent by the server when validating.
It is more likely that you've not fully rolled out the new certificate on the server side. For example if you have multiple servers make sure that all have the new certificate. If your server provides access for IPv4 and IPv6 make sure that in both cases the proper certificate is served. If you provide service on multiple ports make sure that they all use the new certificate.
It's also possible your affected users are behind a proxy that caches certificates. For example if they're behind a Smoothwall proxy that generates its own certificates after inspecting HTTPS traffic and caches them.
Either way, if you've updated the certificates on your server and restarted the necessary services, it's probably nothing you have control over and will most likely resolve itself in time.
I configured NGINX as a reverse proxy and also use it to handle HTTPS with Let’s Encrypt. Well, Let’s Encrypt certificate is about to expire within 3 months and administrator needs to configure to renew it automatically in a production environment.
This scenario works well for a single instance. But what about if I want to scale out the NGINX instance behind Amazon ELB or Route 53. It doesn't make sense to renew the certificate in each instance.
Any one have an experiences in the use case like this? Please suggest.
Thank you.
There are various options available.
The newest version of the spec includes an address parameter for http-01. You can use it, so the validation authority will choose that address to verify the domain ownership. I don't know if that's already implemented in Boulder, the software that Let's Encrypt uses.
Another option is to redirect all requests to a specific domain. http-01 follows any redirect, so you can redirect /.well-known/acme-client/* to acme.example.com or directly to an IP that runs the client.
There's the dns-01 challenge type. It works by providing a TXT record for _acme-challenge.example.com with the same payload as for http-01.
For any of those options, you need just one machine running the client. You can then write a small script that distributes your private keys and certificates to all other servers.
The official client is probably not the best client available for scripting. There are many available clients. One of those is my own client that can be used for scripting. Depending on the size of the integration you're planning, a library might be more useful.
I have a doubt that I had for years and now I decided to try to understand it. I know that when a user hits a website with SSL all headers are encrypted, even the HOST header.
So, in order to enable SSL in a server, you need to have a single IP to every certificate you have cause Apache, for example, wont know which VHOST it should redirect the user if the HOST header is encrypted.
My question is: how does Cloudflare knows which domain the user is using to access its CDN if it does not know the HOST before the decrypt happens?
Server Name Indication (SNI) allows TLS clients to specify the host they are attempting to connect to give the server a chance to serve the right certificate. It is supported in most browsers.
CloudFlare's page on their free SSL offering indicates they use SNI.
Now, CloudFlare has multiple offerings. Their paid plans don't actually rely on SNI (that's why they support all browsers). Only the free plans do.
For the paid plans, CloudFlare presumably uses dedicated IPs, though even in that case they can still pool multiple domains under a single certificate (using Subject Alternative Names).