I'm trying to install a cert on Ubuntu 14.04/Apache 2.4 with the command
$ sudo certbot --apache -d site.com
but I get the error
Domain: site.com
Type: malformed
Detail: Server only speaks HTTP, not TLS
To fix these errors, please make sure that you did not provide any invalid information to the client, and try running Certbot again.
According to the error and to jsha in this question, this indicates that Apache is not configured properly. The installation instructions for this setup say that
Running this command will get a certificate for you and have Certbot edit your Apache configuration automatically to serve it.
This led me to believe I didn't need to worry about Apache configuration, but evidently there's something I missed.
It order to create the right configuration, the following things need to happen:
Enable mod_ssl (sudo a2enmod ssl)
Identify a site-specific config file /etc/apache2/sites-available/site.conf or create it if it does not exist
Add a VHost block to that config file with SSL directives:
Which of these will Certbot take care of, and which do I need to have in place before running the certbot command? And have I missed any important steps?
Normally Certbot can take care of setting up HTTPS for you. In this case, the most likely explanation is that you already have some VirtualHost that is listening on port 443, yet without the SSLEngine on part. You might be able to find that with a command like
grep -r :443 /etc/apache2
Although Certbot can do a lot of kinds of setup, it won’t remove existing VirtualHosts even if they conflict with the goal of having an HTTPS (rather than HTTP) listener on port 443.
There are no enabled Apache config files with “:443”. I do have some <VirtualHost IP:*> blocks, but those wildcards should be subordinate to anything with an explicit “443”.
If I disable configuration entirely for the site (a2dissite site.com, reload), certbot complains that it can’t find a VHost by the name of site.com, then it lists the sites I do have enabled config files for. So, it’s clear that I need some sort of pre-existing configuration for the site before I run certbot, but it isn’t clear to me how much, based on reading the installation guide and the docs I can find.
Also, although I’m glad to have the help, I’m not actually asking a specific support question, but a general question about how certbot works.
For example, if I knew exactly what needs to communicate with what, and via what channel, I could troubleshoot the issue on my own by making sure that channel is clear.
Short of reading the source code, is there any publicly accessible documentation about how the Apache plugin for certbot works that doesn’t amount to “don’t worry about it?”
Is there something listening on port 443 on your system normally when you’re not running Certbot? If so, is it still listening when Apache isn’t running?
I don't think so. I can tell you that it uses a library called Augeas to parse Apache configuration files, and that there are two components to the Apache plugin, an authenticator and an installer. The authenticator is used to prove control of domain names in order to satisfy the TLS-SNI-01 challenge from the certificate authority and thereby obtain certificates, while the installer is used to reconfigure your existing Apache instance in order to tell it to use a newly-obtained certificate.
Both the authenticator and installer modify your existing Apache configuration by editing configuration files. The authenticator will create temporary configuration files containing new additional virtual hosts which attempt to listen on port 443 and speak HTTPS using temporary self-signed certificates that refer to specific values requested by the certificate authority. Normally users don't see these configuration files, virtual hosts, or certificates at all because they only exist for a short time while the certificate authority is validating the challenge.
When the certificate has been obtained, the installer will attempt to create new HTTPS virtual hosts based on the existing HTTP virtual hosts that apply to the domain names that the new certificate covers. These virtual host definitions go in the sites-available directory just like existing ones, and are given names ending in -le-ssl.conf.
I'm happy to answer other questions about how this works.
Actually it appears to be the opposite: that the *:443 VirtualHosts certbot creates are subordinate to your explicit IP:* VirtualHosts, because Apache matches the IP address before the port.
You could explicitly define port 80 in your existing VirtualHost blocks, so they won't match for port 443 at all. Or don't explicitly define the IP address by replacing it with a wildcard, since certbot will do that for its new VirtualHosts anyway, and then its *:443 host will take precedence over your *:* one.
I don't believe certbot supports IP-based virtual hosting at this time. If you want to define an explicit IP address for your SSL virtual hosts you would indeed need to configure Apache manually for now.