How to install and Secure WordPress on Ubuntu 16.04

WordPress is the number one CMS and has been used by many people around the world to power their site.

Throughout the years WordPress has seen many updates and changes.

Due to its flexibility and easy to use characteristics, it is loved by the webmasters to host their site.

There are a lot of plugins available in WordPress to optimize your site.

Since it is a open source CMS, it is available free of cost to use.

You can run your websites and blogs in WordPress. WordPress runs with the help of MySQL and PHP on the background.

Once you are done with setting up the WordPress, you can do the remaining tasks from the front end.

In this guide, we are going to see how to install WordPress on LAMP stack on Ubuntu 16.04 and How to Secure WordPress with the SSL certificate.

install wordpress ubuntu 16.04

Prerequisites

The non-root user with sudo privileges: Here in this tutorial we are going to use sudo non-root user.

Install LAMP Stack:

WordPress requires

  • Web Server
  • A database
  • PHP

to function smoothly.

The LAMP stack(Linux, Apache, MySQL and PHP) is enough for the WordPress installation.

Secure your site with SSL/TSL: You should have SSL to encrypt the traffic to your server and client. You can do that with Let’s Encrypt.

Create a MySQL Database and User for WordPress

WordPress uses the MySQL to store and retrieve data. So we have to create a database and user for WordPress to use.

First, Login to MySQL as a root account using the following command.

$ mysql -u root -p

You will be asked to enter the root password you set during the installation process. Enter and continue.

The next step is to create a separate database for WordPress to use.

You can give any name to this database but here we will use wordpressdb as Database Name.

Use the following command to create the database for wordpress.

mysql> CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

All MySQL command should end with (;)If you get any issue, check if you used (;) in the query.

Now:

We are going to create a new user to access and perform operations exclusively on this database.

It is a secure one as the database and user are created for only one purpose.

Here we will use wordpressuser as user name. You can choose any name for your WordPress database.

Now, we are going to

  • create the user
  • set the password
  • grant access to the database.

Execute the below command to perform all the operations mentioned above.

mysql> GRANT ALL ON wordpress.* TO 'wordpressuser'@'localhost' IDENTIFIED BY 'password';

That’s all.

Here, we have created a database and user only for WordPress.

You have to flush the privileges so that MySQL can get to know about the recent changes we have made.

mysql>FLUSH PRIVILEGES;

Now, Exit from the MySQL.

mysql> EXIT;

Install Additional PHP Extensions

Now, let us install the additional PHP extensions here.

Because when we install the LAMP, the PHP only requires minimum extensions to connect with MySQL.

But:

WordPress and many of its plugins require additional PHP extensions.

You have to download the required PHP extension in order for WordPress to use.

Execute the below commands to get the PHP extensions.

$ sudo apt-get update
$sudo apt-get install php-curl php-gd php-mbstring php-mcrypt php-xml php-xmlrpc

Note: The PHP extension requirement of each WordPress plugin varies according to their needs.

To get the exact PHP extension, look at the Plugin Documentation.

Once you found, download that extension with apt-get as demonstrated above.

Now:

Restart the Apache to use these new extensions.

$ sudo systemctl restart apache2

Enable .htaccess Rewrites and Overwrites

By default, the access to the .htaccess file is disabled in apache.

But Many of the Plugin requires the .htaccess to work.

*For example, * The cache plugin has to write cache expiry setup codes in .htaccess.

Here, We also have to enable the mod_rewrite. It will help WordPress permalinks to work perfectly.

Enable .htaccess overrides

Open the apache configuration file.

$ sudo nano /etc/apache2/apache2.conf

To allow .htaccess override we have to add the following line the in the directory block pointing to our document root.

/etc/apache2/apache2.conf
. . .

<Directory /var/www/html/>
AllowOverride All
</Directory>

. . .

Once you are done, save and close the file.

Enable Rewrite Module

Now enable the rewrite module so that we can use the wordpress permalink feature.

$ sudo a2enmod rewrite
Make the Changes to take Effect

Now, you have to check whether you have made any syntax error before implementing the changes by executing the following command.

$ sudo apache2ctl configtest

The output will contain a message like this.

Output
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
Syntax OK

If you like to fix the first message, you have to add the ServerName directive to the */etc/apache2/apache2.conf *file pointing to the server domain name or IP address.

The Message has nothing to do with the functionality of the site unless the syntax is ok.

Now restart the apache to make the updates to take effect.

$ sudo systemctl restart apache2

Download WordPress

The server is fully configured and now ready to install the WordPress.

We always have to download the latest version of WordPress from their site for security purpose.

Now move to the writeable directory and download the WordPress there.

$ cd /tmp
$ curl -O https://wordpress.org/latest.tar.gz

Here we are using the temporary folder to download the compressed WordPress file.

Once the download is finished, extract the WordPress to create its directory structure.

$ tar xzvf latest.tar.gz

We have to move these file to our document root.

But prior to that:

we need to create dummy .htaccess file and set its permissions for WordPress to use later.

First, create the file and then set the permission to the file.

$ touch /tmp/wordpress/.htaccess
$ chmod 660 /tmp/wordpress/.htaccess

Now copy the sample configuration file to a file name that WordPress can read.

$ cp /tmp/wordpress/wp-config-sample.php /tmp/wordpress/wp-config.php

We have to create the upgrade directory so that WordPress won’t be running on permission issues when it is upgraded.

$ mkdir /tmp/wordpress/wp-content/upgrade

After that, we can copy the entire directory content into the document root.

The -a flag indicates the terminal to maintain file permission as it is while copying.

The (.) after source directory (wordpress/) Indicates that all the content in that directory has to be copied entirely including the hidden files.

$ sudo cp -a /tmp/wordpress/. /var/www/html

Configure the WordPress directory

We have to do some adjustment in the configuration before going for the final step of configuring it at the web interface.

Adjusting the Ownership and file permission

In order for WordPress to function correctly and to avoid the file permission problem, we have to set the file permission so that it will be accessible to read and write as a regular user.

Also, the web server could access and change the file permission of certain files and directories to function correctly.

So, Here we are going to allocate the ownership of the files in our document root to the user name.

I am going to use selva as the user name and you have to use the usernamewhich has the sudo permissions.

First, Let us assign group ownership to the www-data group.

$ sudo chown -R selva:www-data /var/www/html

Now let us set setgid to all the directories inside the document root.

So, the files created within these directories will inherit the group of the parent directory. So that it does not need to create the user’s primary group.

If we create a file using the command line, the web server will get the control over it.

Now:

Let us set the setgid bit to all the directories in WordPress installation.

$ sudo find /var/www/html -type d -exec chmod g+s {} \;

We have to make some more adjustment regarding the file permissions.

We will often install new plugins and make changes in the theme.

For that, We have to set the group write access to the wp-content directory.

$ sudo chmod g+w /var/www/html/wp-content

So, we also have to grant the access to the web server to the plugin directory and theme directory.

Here is the command which will grant the access to web server.

$ sudo chmod -R g+w /var/www/html/wp-content/themes
$ sudo chmod -R g+w /var/www/html/wp-content/plugins

These permissions are enough for WordPress as of now. Some plugins and procedure may require additional permissions.

Setting Up the WordPress Configuration File

Our next step is to setup the WordPress configuration file for the secure installation of the WordPress site.

In the WordPress configuration file, you have to add some secret keys. Here, WordPress generates the security key for you.

So, you don’t need to generate the keys by yourself. The keys are used internally, So it won’t brings complexity to the usability.

WordPress has a secret key generator which you can use to generate secret values.

Here is the command to get the secret value from the WordPress.

curl -s https://api.wordpress.org/secret-key/1.1/salt/

You will get the unique keys that look like this.

Please don’t copy the value here. Generate your own keys.

Output
define('AUTH_KEY',         '1jl/vqfs<XhdXoAPz9 c_j{iwqD^<+c9.k<J@4H');
define('SECURE_AUTH_KEY',  'E2N-h2]Dcvp+aS/p7X {Ka(f;rv?Pxf})CgLi-3');
define('LOGGED_IN_KEY',    'W(50,{W^,OPB%PB<JF 2;y&,2m%3]R6DUth[;88');
define('NONCE_KEY',        'll,4UC)7ua+8<!4VM+#`DXF+[$atzM7 o^-C7g');
define('AUTH_SALT',        'koMrurzOA+|L_lG}kf07VC*Lj*lD&?3w!BT#-');
define('SECURE_AUTH_SALT', 'p32*p,]z%LZ+pAu:VYC-?y+K0DK_+F|0h{!_xY');
define('LOGGED_IN_SALT',   'i^/G2W7!-1H2OQ+t$3t6**bRVFSD[Hi])-qS`|');
define('NONCE_SALT',       'Q6]U:K?j4L%Z]}h^q71% ^qUswWgn+6&xqHN&%');

The above codes can be directly added to the configuration file.

Once you received the code, just copy them.

Now, open the WordPress configuration file.

$ nano /var/www/html/wp-config.php

You have to find the section with dummy values in the configuration file and replace that with the copied content.

The dummy text file will look like this.

         /var/www/html/wp-config.php
. . .

define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase 
here');
define('NONCE_KEY',        'put your unique phrase 
here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

As I mentioned above, you have to replace the above text with the copied values.

Just delete the lines and add the content.

/var/www/html/wp-config.php
. . .

define('AUTH_KEY',         'COPIED KEY VALUE FROM THE 
COMMAND LINE');
define('SECURE_AUTH_KEY',  'COPIED KEY VALUE FROM THE 
COMMAND LINE');
define('LOGGED_IN_KEY',    'COPIED KEY VALUE FROM THE 
COMMAND LINE');
define('NONCE_KEY',         COPIED KEY VALUE FROM THE 
COMMAND LINE);
define('AUTH_SALT',         COPIED KEY VALUE FROM THE 
COMMAND LINE);
define('SECURE_AUTH_SALT',  COPIED KEY VALUE FROM THE 
COMMAND LINE);
define('LOGGED_IN_SALT',    COPIED KEY VALUE FROM THE 
COMMAND LINE);
define('NONCE_SALT',        COPIED KEY VALUE FROM THE 
COMMAND LINE);

Once you finished the above process, your next task will be changing the database connection settings.

Here you have to set the following

  • database name,
  • the database user
  • the password we created for that user in MySQL.

Thereafter, you have to adjust the file permission settings in order for WordPress to write the files.

Previously we set the file permission to the web server so that it can read and write.

Now:

Let us set the file system method to direct.

If you fail to do that, the WordPress will prompt for FTP credentials to authenticate while you try to make some changes.

For e.g. If you try to change your theme, you will be asked to enter the FTP credentials.

You can add these settings anywhere in the file.

Here we add the settings below the database connection settings.

/var/www/html/wp-config.php
. . .

define('DB_NAME', 'wordpress');

 /** MySQL database username */
define('DB_USER', 'wordpressuser');

/** MySQL database password */
define('DB_PASSWORD', 'password');

. . .

define('FS_METHOD', 'direct');

Now, Save and close the file.

Complete the Installation through the web Interface

We have finished the server level configuration.

Now:

We have to setup the WordPress through the web interface.

It is a very easy process as it can be done through GUI.

Go to any of your browsers and put domain name or IP address and go.

http://server_domain_or_IP

First, you will be asked to select the language of your choice.

In The next step, you have to enter a name for the website and enter the username of your choice.

Don’t use common words like admin, administrator and etc. Choose a unique username.

strong password will be automatically generated by the WordPress. You can use that or generate any strong password by yourself.

Enter your email address. It will be used as recovery and notification mail.

Once you finished with that step, you will be asked to enter the username and password you set in the previous step.

Once you finished, the WordPress administrator panel will open.

There will be some default themes available, you can search for more themes and use it for your site.

You can also upload the theme of your choice.

Upgrade the WordPress

It is always recommended to have the upgraded version of WordPress.

You can’t upgrade the WordPress from the interface itself with current permissions.

Due to the security purpose, we gave the balanced permission to WordPress.

So whenever you get the WordPress update, you can update it by making some temporary changes.

Login to our server as sudo user and temporarily grant the web server process access to the document root.

$ sudo chown -R www-data /var/www/html

Now, come back to the interface and upgrade the WordPress.

Once you complete the update process, now it is the time to lock down the permissions.

$ sudo chown -R sammy /var/www/html

You need to perform the above steps when you only need to upgrade the WordPress.

Create SSL certificate for your WordPress

Now let us see how to protect your WordPress with Let’s Encrypt. This method will work if you have a domain name.

Now, Google has started to give preference to the websites which uses the SSL Certificate.

Also, they started to notify the users about the websites which don’t have SSL/TLS certificate.

Often you can see a notification in chrome browser with the following message

“Your connection is not private”

This alert is making the user not to visit your site. It makes them feel insecure and go back.

The Result:

You will lose the visitor and at the same time, google will not give preference to your site.

To get your position up or maintain it on the top, you have to have SSL certificate for your site. But security comes first.

If you don’t have an SSL certificate for your website, then you should create one today.

This Tutorial is going to help you to install the SSL certificate with let’s encrypt on your Ubuntu 16.04 server running apache as a webserver.

The Let’s encrypt certificate is valid for 90 days only. After that, you have to renew it.

Here, I am going to show you how to auto renew the SSL certificate using cron Job.

Why Choose Let’s Encrypt?

  • Let’s encrypt is free for anyone who is looking to create a trusted SSL certificate for their site.
  • The Renewal can be automated as the web server can communicate the Let’s encrypt to obtain the certificate.
  • Let’s encrypt provides the more security to the servers. It helps the webmaster to protect the server.
  • The certificates are available for the public so that anyone can inspect it.
  • No Organization is holding the Let’s Encrypt. it is operated by the community.

The Best part is:

You are not paying any amount for the encryption.

SSL’s work is to encrypt the traffic between the client and server. You can provide security to the users who are accessing your website using SSL.

Let’s Encrypt provide you the SSL certificate free of cost.

Requirement

  • Ubuntu 16.04 server with sudo non-root user.
  • Apache web server with one or more domains( should be configured perfectly with virtual host)

Install the Let’s Encrypt.

You need to have the Let’s Encrypt client. It can be easily downloaded from the official repositories.

Note: Let’s Encrypt client is renamed to certbot.

Ubuntu 16.04 repository has let’s encrypt client called letsencrypt and it is sufficient for our implementation.

First, update the server’s apt package indexes and install the client.

$ sudo apt-get update
$ sudo apt-get install python-letsencrypt-apache

Now, the Let’s Encrypt client will be downloaded and ready for use.

Installing the SSL Certificate

Installing the Let’s Encrypt SSL certificate in the apache web server is easy.

All you have to do is just pass the domain name for which you need the SSL certificate.

You will receive the SSL certificates for the domains you passed as parameters.

You can pass one or more domains at a time to obtain the SSL certificate.

But:

The first domain will be the base domain for the SSL certificate.

You can use the same certificate for all other domains.

To get the certificate for a single domain, use the following command.

$ sudo letsencrypt --apache -d mydomain.com

To create SSL certificates for additional domains, subdomains and aliases, you can simply pass them as parameters.

As I mentioned above, the SSL certificate will be generated for your first domain. So pass the top level domain of yours as the first parameter.

Here is the command for you to get SSL certificate for multiple domains at the same time.

$ sudo letsencrypt --apache -d mydomain.com -d www.mydomain.com

Replace example.com with your domains.

Once all the dependencies are installed, you will be guided through the step by step guide to customizing your SSL certificate.

You will be asked for an email and it will be used to send you the lost key recovery and notices.

You have the option to use both http and https requests or you can force all the request to redirect to https.

I recommend you to choose to force all requests to redirect to https.

If you have any requirement to allow http request, then go for it.

Once the installation process is finished, you can see the installed SSL certificate at /etc/letsencrypt/live.

Now:

You have to check whether the SSL certificate is installed properly or not.

To check the status, use this link

https://www.ssllabs.com/ssltest/analyze.html?d=mydomain.com&latest

Replace mydomain.com with your domain name.

Now you could access your website using https.

Auto renewal

The SSL Certificate you generated using Let’s Encrypt is valid for 90 days.

But:

You have to renew it once every 60 days. The Let’s Encrypt client came with the auto renewal option.

You can auto renew the SSL Certificate within a specific interval.

To renew automatically you have to create a cron job that usually checks the validity and update the SSL certificate.

The client uses the renew command to renew the SSL certificate.

$ sudo letsencrypt renew

The above command will only check the SSL certificate validity because we have installed the SSL certificate recently.

The output will look like the following.

Processing /etc/letsencrypt/renewal/example.com.conf

The following certs are not due for renewal yet:
 /etc/letsencrypt/live/example.com/fullchain.pem (skipped)
 No renewals were attempted. 

You can check for the SSL certificate validity daily, weekly or every 30 days using the automated function.

This is the only way to make sure that the certificate won’t expire.

Now you have to create a cron job that checks for the SSL validity in specific intervals.

The SSL certificate will be renewed if it has only 30 days remaining until the expiration date.

Now, let us create a cron job which checks the SSL certificate validity for every week.

$ sudo crontab -e

Now, you will be asked to select an editor.

Output
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
 1. /bin/ed
 2. /bin/nano        <---- easiest
 3. /usr/bin/vim.basic
 4. /usr/bin/vim.tiny

Choose 1-4 [2]:

Unless you have previously used the ed or vim, just choose the nano editorand Press Enter.

Add the following lines at the end of cron tab.

crontab

30 5 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log

Save and exit the file.

This cron job will check for the Let’s Encrypt renew on every Monday 5:30 am.

The output of the command execution will be saved in the log file at /var/log/le-renewal.log.

Conclusion

Here you have seen,

  • How to Install WordPress on Ubuntu 16.04 with Apache web server.
  • How to install Let’s Encrypt SSL certificate for domains hosted in apache web server.
  • How to use cron job to automate the renew process.

WordPress is the widely used CMS. It will make your job of web creation very easy.

So, start using that from today.

Since, Let’s Encrypt is free and best SSL certificate, you can get them to your site instantly.

So start using the SSL certificate now and provide the secure access to the users.

If you have any doubts, please let us know that comment, we will help you.