Set up Let’s Encrypt with Nginx web server with webroot plugin

This will allow the Nginx web server to read /.well-known/acme-challenge/ from each domain. This path is used by the webroot plugin.

We’ll need to make a directory to service the challenge files from, we’ll call this /home/www/letsencrypt from now on, and we’ll need to make sure this is set up with appropriate permissions so Nginx can serve these files to the public.

In Nginx’s config, we can add the following to each server block configuration:

location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /home/www/letsencrypt;
}

Generally, adding this in /etc/nginx/global/global.conf and including this file (usually already done by a default install) in each .conf file in each of /etc/nginx/conf.d/ files is recommended.

Install certbot-auto

wget https://dl.eff.org/certbot-auto && chmod a+x certbot-auto && mv certbot-auto /usr/local/bin    

Add a certificate for a domain

certbot-auto certonly --webroot -w /home/www/letsencrypt -d domain.com

Renew all certs if near expiry

certbot-auto renew --webroot -w /home/www/letsencrypt

This can be added as a cron job.

00 2 * * * root /usr/local/bin/certbot-auto renew --webroot -w /home/www/letsencrypt 2> /dev/null

If you wish the automation to apply for a single domain only, use:

00 2 * * * root /usr/local/bin/certbot-auto renew --webroot -w /home/www/letsencrypt --cert-name NAME 2> /dev/null

Certificate names are usually the same as the domain name, however this may not always be the case. You can check your certificate names with:

certbot-auto certificates

To test configuration

certbot-auto renew --webroot -w /home/www/letsencrypt --dry-run

Configure nginx server blocks

In each domain’s server block add:

listen 443 ssl;

ssl_certificate      /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key  /etc/letsencrypt/live/domain.com/privkey.pem;
include ssl/ssl.conf;

In ssl.conf we have:

ssl_session_timeout       5m;
ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers               "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS";
ssl_prefer_server_ciphers on;
ssl_session_cache         shared:SSL:10m;
ssl_dhparam               /etc/nginx/ssl/dhparams.pem;

The above SSL config is my personal preference, but you can adjust to your liking.

Moving WordPress blog across domains using the shell

Here’s a rundown, or more accurately a set of personal notes I made, for moving a WordPress blog from one domain name to another. This will also work when moving from one web host to another.

First you’ll need to know some details of your old database:

  • database host name, e.g mysql.yourdomain.com or localhost
  • database name
  • username
  • password

You can find these details in wp-config.php on the old WordPress site.

Create a new database on the new web host, and an appropriate user account which can be used to manage the database. You may need to do this in a web interface, e.g cPanel, as some web hosting companies only allow database creation and deletion via a web interface. Make note of these details of the new database, you’ll need these new details for the new site.

We’ll assume here that on your web host, web served files are stored in a subdirectory named the same as the domain name.

Old Blog

Save WordPress files from the old blog to blog_old.tar.gz:

tar -zcvf blog_old.tar.gz -C OLDDOMAIN.COM .

Save the old database to blog_db_old.sql. Use the details from the old database here.

mysqldump -uUSERNAME -p -h DBSERVER DBNAME --quick > blog_db_old.sql

Check the database dump is okay, we’ll just read the first couple of lines just to make sure all is well.

head blog_db_old.sql

New blog

Now we get to work on the new site. First up the archive of the WordPress files and database dump, move those onto the new server if required.

Write to new database and WordPress directory

Import the dumped SQL file from the old database, into the new database. You’ll need to type in here the details of the new database that was just created, and use a appropriate path to the archive files (the .tar.gz and .sql files).

mysql -h DB_SERVER -uUSERNAME -p DB_NAME < blog_db_old.sql

Extract contents of WordPress install into the new domain.

tar xvf blog_old.tar.gz -C NEWDOMAIN.COM/

Edit wp-config.php and enter in the new database details.

cd NEWDOMAIN.COM
vim wp-config.php

Search and replace operation on database

The database still references the old domain in its URLs. So we need to replace the domain name and URLs in database. There is a PHP script by interconnectit you can use, as a search and replace tool.

Download this handy database search and replace tool, unzip the single PHP file, and rename it:

wget http://www.interconnectit.com/wp-content/uploads/2011/05/searchreplacedb21.zip
unzip searchreplacedb21.zip
mv searchreplacedb2.php sr.php

Visit your new domain http://NEWDOMAIN.COM/sr.php to run the search and replace script.

  1. Select script to obtain database parameters from wp-config.php. Use this option, only if you have already edited wp-config.php on the new site with the new database details.
  2. Select all tables to perform the search and replace in.
  3. Type your search and replace parameters. Search for your old URLs and replace with your new URL. Take note of www. at the start of addresses. Some sites use it and some don’t (normally set in cPanel or equivalent interface). For example when I was moving sites from my old domain to this one, I searched for http://micro.gock.net and replace it with http://agock.com.
  4. Check your web site on the new domain and check all is working fine.

Remove the search and replace script once completed. Don’t leave this script on your web site.

rm sr.php

Alternate method

As an alternate method to using the above PHP script, we could have performed a search and replace on the SQL dump file, or peformed some search and replace commands directly on the databse using SQL queries.

Test web site

After performing the search and replace, the new site should work as normal. All media and user accounts should be as before. Visit your new site and check that it is all working fine.

Redirect the old domain

Once we know the new domain is working okay, we can remove the old files (remember you still backups from earlier). Make sure you’re in the right directory before doing the mass delete!

cd OLDDOMAIN.COM
rm -rf *

Set up a .htaccess file for the old domain.

touch .htaccess
vim .htaccess

Insert the following but replace with your site domain names:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !newdomain.com$ [NC]
RewriteRule ^(.*)$ http://newdomain.com/$1 [L,R=301]

Test the redirection, by visiting an old URL, your browser should automatically redirect to the new domain name. This will redirect all pages. Search engines crawling your site should recognise this 301 redirect code, and update its indexes appropriately.

Finishing up

You can now delete the old database as well. This can be done via cPanel or similar web host interface, if that is the only method your web host allows.

Copy your old site archive (.tar.gz) and database dump (.sql) somewhere for safekeeping.

If you were using Google Analytics, remember to go and change the settings in there, you are able to change the site name and URL for a Google Analytics account / property. Also fix any linking with Google Webmaster Tools.

New Base Conversion Tool

I just wanted to share a little tool I recently created. An online number base conversion tool. I know there are quite a few of them around. I created this mainly for myself and as a Javascript learning exercise, and I thought it might be useful to someone. It is very fast with “update as you type” ability and also a button for copying results to the clipboard. It converts between decimal, hexadecimal and binary.

base_converter_screenshotYou can visit the site at base-converter.gock.net

How to get ICC profiles working with TimThumb

I was working on a web site that used TimThumb, and ran into an issue.

TimThumb uses the PHP GD library, which does not support color profiles. It is a very common library used in WordPress themes. This can be an issue with web sites which are for photographers, as sometimes, it may be desired to have embedded color profiles in thumbnails. But when timthumb processes an images, it strips the embedded color profile and all metadata.

The metadata I am not too fussed about, but I need to have the sRGB profile embedded in the displayed profile. For visitors using a wide gamut monitor, untagged sRGB images are not displayed properly in Firefox, as color management by default is set such that color management only works on tagged images (see this link on how to enable it for all images). This is really only an issue for visitors on wide gamut monitors.

Here is how to fix this problem.

We modify timthumb so when it writes images to the cache, it adds the ICC profile back in. I used the PHP JPEG ICC profile manipulator by Richard Toth

Download this and place class.jpeg_icc.php into the same directory as timthumb.php

Now download this file in-srgb.jpg (right click and “Save link as…” or “Save target as…”) and place it in the same directory as timthumb.php as well.

Add the following at the start of timthumb.php:

require_once('class.jpeg_icc.php');

Look for the processImageAndWriteToCache() method and look for the following snippet:

		if(preg_match('/^image\/(?:jpg|jpeg)$/i', $mimeType)){
			$imgType = 'jpg';
			imagejpeg($canvas, $tempfile, $quality);
		} else if(preg_match('/^image\/png$/i', $mimeType)){

And replace it with the following:

		$tempfile = tempnam($this-&gt;cacheDirectory, 'timthumb_tmpimg_');
		if(preg_match('/^image\/(?:jpg|jpeg)$/i', $mimeType)){
			$imgType = 'jpg';
			imagejpeg($canvas, $tempfile, $quality);

			// Add sRGB ICC profile
			$icc = new JPEG_ICC();
			$icc-&gt;LoadFromJPEG('in-srgb.jpg');
			$icc-&gt;SaveToJPEG($tempfile);

		} else if(preg_match('/^image\/png$/i', $mimeType)){

Now it would be a good idea to clear the timthumb cache, just go into the cache directory and delete its contents.

That is all.

Now whenever timthumb generates a thumbnail, the thumbnail will have an embedded sRGB ICC profile.