5

You have just got a new HTTPS (SSL/TLS) Certificate, and what you hope is the correct Intermediate Certificates.

This is setup in Apache with:

SSLCertificateKeyFile /etc/ssl/www.example.com.key
SSLCertificateChainFile /etc/ssl/www.example.com.chn
SSLCertificateFile /etc/ssl/www.example.com.crt

Or in Nginx with:

ssl_certificate_key /etc/apache2/ssl/www.example.com.key;
ssl_certificate /etc/apache2/ssl/www.example.com.pem;

Remembering apachectl configtest only checks that these files exist; and nginx -t "will fail if the website certificate is not first in the crt file, and also if the key is wrong" (thanks Drifter104).

So, how can you check everything before restarting?


Possible issues

  1. You have the wrong Intermediates (e.g. GeoTrust lists all of their Intermediates on one page).

  2. You accidentally mixed the Intermediate Certificate file with your websites Certificate file.

  3. You included the Root Certificate (effecting performance, as this sends unnecessary data).

  4. You are missing one or more Intermediate Certificates.

  5. The Certificate is for the wrong key.

  6. You have left these files as readable by anyone on the server (e.g. chmod 644).

  7. You are using the wrong certificate (domain is not in CN or SAN)


Some starting points

Extracting Information about the Key, CSR, or Certificate files:

openssl rsa -check -in "www.example.com.key";
openssl req -text -noout -verify -in "www.example.com.csr";
openssl x509 -text -noout -in "www.example.com.crt";

Getting the Public Key hash with sha256 (e.g. for setting up HPKP):

openssl rsa  -in "www.example.com.key"                             -pubout -outform der | openssl dgst -sha256 -binary | openssl enc -base64
openssl x509 -in "www.example.com.chn" -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
openssl req  -in "www.example.com.csr" -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

openssl s_client -connect www.example.com:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

It's possible to validate via SSL Labs, but only when you have started using that configuration.

Craig Francis
  • 633
  • 1
  • 8
  • 23
  • 4
    Nginx -t will fail if the website certificate is not first in the crt file, and also if the key is wrong. So it does a little more then validate the file exists – Drifter104 Apr 01 '16 at 16:35
  • @Drifter104, fair point, it's more my annoyance at Apache that doesn't do much more than that :-) – Craig Francis Apr 01 '16 at 21:42
  • @Drifter104, thanks again, I've just been able to update the question to include this information (must admit I'm more used to Apache). – Craig Francis Apr 04 '16 at 13:55
  • 2
    Yoiu fire up the config on a test system and point a browser at it, then point https://www.ssllabs.com/ssltest/ at it. – symcbean Apr 12 '16 at 10:46
  • Thanks @symcbean, but you can't really give SSL Labs a different IP address, and I'm really looking to identify simple mistakes (which a test server won't necessarily help with)... I suppose I should be complaining to Apache/nginx for not doing these checks themselves... that said SSL Labs is good to test once you have started using the certificate :-) – Craig Francis Apr 12 '16 at 10:53
  • I'd have a second Nginx install / server to test the configuration on. – Tim Aug 17 '17 at 09:15
  • Still doesn't stop mistakes when copying the config over ;-) ... admittedly this is no longer a problem for me, as I've automated this problem by using LetsEncrypt (I use a very careful bash script that creates the keys and csr, requests the certs though [acme-tiny](https://github.com/diafygi/acme-tiny), checks file permissions, and runs automatically on a cron job to replace certs that are within a month of expiry). – Craig Francis Aug 17 '17 at 09:23

2 Answers2

1

You could make a copy of the config files and edit the ports. From there you could start a second instance of the webserver (nginx/apache) and check for valid configuration.
Instead of accessing https://www.your-domain.com (port 443) you change to https://www.your-domain.com:8443 (port 8443).
With a running instance you can check with external tools and check the logs for errors. This minimizes the risk that your website gets unavailable after config and certificate changes.
Depending on the size of your config and amount of vhosts this might be a very time consuming solution.

Solution also metioned in the comments by @symcbean.

unNamed
  • 545
  • 2
  • 11
1

There is a good Linux command line script testssl.sh you can use for this purpose. I've used this for other protocols as well (e.g. FTPS).

As as final check I will still use the SSL Server Test. It generates a pretty test result you can forward to customers ;-) .

Jens Bradler
  • 6,503
  • 2
  • 17
  • 13
  • It's a good script to test a *running* site, but I was hoping for a way to test the certificates *before* restarting Apache/nginx... as in, if I was adding a new cert, I want to make sure that I can restart the server before I effect the customers who are currently using the website... e.g. if I had mixed up the main and intermediate certs, the website would stop working :-( – Craig Francis Aug 17 '17 at 09:06
  • Therefore I can recommend Vagrant. Setup a box based on the same system you are using for production and install all services you'd like to test. You can even run a cluster of servers to test load balancing and fall back mechanism. You can install your new certificates in this box and check if with the above mentioned script. We are doing this and we store the servers configuration in a version control system so I can be sure to deploy the same setup I have tested locally to our production system after everything is fine. – Jens Bradler Aug 24 '17 at 06:24
  • Hi @Jens, for us (and probably most websites), we can't put our private keys in something like Vagrant, ideally the private key will never leave the server that generated those keys... I also found that Vagrant is not able to create a perfect copy of the Live environment, so it's only able to cover some of the potential issues... automation with LetsEncrypt has solved most of our issues, but I think it's going to be Apache/nginx that needs to do a better job at checking their config before doing a restart :-( – Craig Francis Aug 24 '17 at 08:16
  • Actually you can do. Regarding SSL private keys: If you are working with key pinning (like I do) you have to store your reserve keys anywhere else. They should not be stored on the production web server. So storing the live private key is the same. Regarding Vagrant is not able to have a perfect copy: It is able to do that. I have copied a whole system into a Vagrant box to debug some crazy issues we had. Summary: I think there are a lot of solutions to do exactly what you are looking for. Also I understand that some do not fit in your current setup or include a lot of handiwork. – Jens Bradler Aug 24 '17 at 08:39
  • True, I do have backup keys in my password vault (not sure I'd trust Vagrant with it, simply because it's not encrypted)... but we are kind of getting off topic, I still think that commands like `apache2ctl configtest` should do basic sanity checks, like making sure the `SSLCertificateKeyFile` and `SSLCertificateFile` files are correct... and it must know they are correct, because a restart will do the shutdown bit just fine, then it won't start up again (which is not ideal on a Live server). – Craig Francis Aug 24 '17 at 11:57