WordPress: Site not Secure despite SSL Certificate

I’ve recently migrated all my sites to use SSL (I know, it’s long overdue) and despite the SSL-Certificates being valid and working, Chrome and Firefox would show my sites as “not secure”. (No padlock icon.)

After some digging, I discovered that WordPress really doesn’t play very nicely with SSL. Lots of themes, plugins, etc will use hard-coded or generated, absolute, http:// URLs, with no regards to what the site is actually using. Worse, posts may include absolute URLs in links to content.

Instead of fixing all themes, plugins, and content manually (or with a clever script), one easy solution is to include the following line in your .htaccess:

Header always set Content-Security-Policy "upgrade-insecure-requests;"

This will cause the users’ browsers to convert all insecure http-Links to https automatically. So far, it seems to work perfectly fine.

Easy-RSA: “failed to update database”

Attempted to create a new certificate using the EasyRSA suite and got the following error:

“failed to update database”

Unfortunately the script is pretty laconic, but some quick testing showed this was due to trying to re-use the default display name:

Name [EasyRSA]:

Picked a different name and the script committed my certificate correctly.

Easy-RSA Jabber SSL Certificate Problems

I’m currently setting up a new server and ran into something odd. Connecting to ejabberd with Pidgin, the later would reject the SSL certificate outright. At first I thought I had messed up the hostnames, or used an outdated Hash algorithm or whatever.

The errors I saw in the debug window were:

(22:17:42) nss: ERROR -8102: SEC_ERROR_INADEQUATE_KEY_USAGE
(22:17:42) nss: ERROR -8101: SEC_ERROR_INADEQUATE_CERT_TYPE

It turns out that SSL certificates can be flagged for what they can be used for, and I had simply created the certificate with the ./build-key command. Using ./build-key-server instead fixes the issue. The difference is that this will set nsCertType=server in the certificate.

I hope this helps anybody who runs into the same issue – it certainly had me pulling out my hair for a while.

Disable SSLv3 in Postfix, Dovecot

Postfix:

Disabling certain versions of SSL works like this in Postfix:

In your /etc/postfix/main.cf add or modify the following config parameter like so:

smtpd_tls_protocols=!SSLv2,!SSLv3

If you are using mandatory TLS you’ll want to set this instead:

smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3

These should be fairly self-explanatory, but for further detail read the Postfix configuration parameters documentation.

Do not forget to restart Postfix!

Dovecot:

In dovecot, add the following to your configuration:

ssl_protocols = !SSLv2 !SSLv3

…and restart Dovecot. If you use a version of Dovecot older than 2.1, upgrade and then do the above.

Can I safely send a Certificate Request (CSR) by Email?

Yes. The CSR is your public key, which will be verified and signed by the certificate authority (CA) and returned to you afterward. It is this signed version you will then use in your application. It is useless without the private key, so even if someone makes a copy of it, they won’t be able to attack you.

However, this does mean that you must not send your private key out! If your private key gets stolen, the SSL certificate is compromised and must be revoked.

Apache: How To Redirect http to https

If you want to direct traffic from your http so that it gets encrypted, this is really easy to do in Apache:

Step one: Set up your https vhost:

<IfModule mod_ssl.c>
<VirtualHost 10.1.1.1:443>
DocumentRoot /var/www
# other server options go here as needed
# – logging for example
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.cert
SSLCertificateKeyFile /etc/ssl/private/example.key
# Add other SSL specific options as needed</pre>
</VirtualHost>
</IfModule>

Step two: Set up your http vhost:

<VirtualHost 10.1.1.1:80>
ServerName my.example.com
RedirectPermanent / https://my.example.com/
</VirtualHost>

We have previously posted more information on enabling SSL in Apache.

Obviously, instead of 10.1.1.1 and my.example.com you’ll have to use your own IP and hostname, whatever they may be.

Note that this will redirect everything from http to https. Finer control is possible, for example you could do:

RedirectPermanent /secure/ https://my.example.com/secure/

Or you could use RewriteRules for even more control. However, in the age of mass surveillance and constant threats from hackers, a general redirect to https is a good idea.

Enabling SSL in Apache2 on Ubuntu

I’m using my server for various admin interfaces and so want to SSL encrypt all traffic to the web server. This is easy enough to add to the default vhosts.

First, we need an SSL certificate. Create it by running:

openssl req -new -x509 -days 3650 -nodes
-out /etc/ssl/certs/apacheserver.pem
-keyout /etc/ssl/private/apacheserver.pem

This generates a self-signed certificate. For tests this is good enough; for production sites you WILL want to use a real purchased certificate. Since one of the jobs of SSL is not only to encrypt, but also to authenticate a site to the user, a self-signed certificate will cause browsers to pop up a warning. Users can (permanently) accept this for your site, but it’s probably not the impression you want to leave.

Ubuntu’s Apache2 will come with the SSL module installed by default, but it’s not used. As our next step, we need to enable it:

a2enmod ssl

Finally, we need to create an SSL virtual host. In my case, I want all http traffic to be simply redirected to https. Find the file /etc/apache2/sites-enabled/000-default and edit it.

Change the existing vhost to listen to Port 443; edit the “VirtualHost” line so it reads:

<VirtualHost *:443>
[…]
</VirtualHost>

(Where […] is of course the rest of your vhost configuration)

Now, inside the VirtualHost definition we’ll need to enable SSL and tell it where the certificate resides:

<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ephesus.pem
SSLCertificateKeyFile /etc/ssl/private/ephesus.pem
[…]
</VirtualHost>

Finally, add a new vhost for redirection:

<VirtualHost *:80>
RedirectPermanent / https://server.example.org/
</VirtualHost>

Naturally, https://server.example.org/ should point to your machine’s name.

Restart Apache:

/etc/init.d/apache2 restart

And that’s all. If you go to http://server.example.org/ you should now be redirected to https://server.example.org

For final reference, here’s my configuration. Note that I commented out the Ubuntu documentation (No need to make this available to the big wide world) and cgi-bin (I’m not using this).

<VirtualHost *:80>
RedirectPermanent / https://ephesus.pandemonium.de/
</VirtualHost>

<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ephesus.pem
SSLCertificateKeyFile /etc/ssl/private/ephesus.pem

ServerAdmin webmaster@localhost

DocumentRoot /var/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>

#ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
#<Directory “/usr/lib/cgi-bin”>
# AllowOverride None
# Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
# Order allow,deny
# Allow from all
#</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog ${APACHE_LOG_DIR}/access.log combined
# Alias /doc/ “/usr/share/doc/”
# <Directory “/usr/share/doc/”>
# Options Indexes MultiViews FollowSymLinks
# AllowOverride None
# Order deny,allow
# Deny from all
# Allow from 127.0.0.0/255.0.0.0 ::1/128
# </Directory>

</VirtualHost>