Multiple WordPress with SSL in Ubuntu 16.04


Complete guide to host multiple WordPress sites in a LEMP stack in a Ubuntu 16.04 LTS. Installation of SSL by Let’s Encrypt has been illustrated also.

Buy a VPS

This is the right time to move your sites from shared hosting to a VPS if you are getting moderate traffic for your sites. You can purchase a VPS with a minimum price of $5 per month from DigitalOcean.

digitalocean

You should select nearest data center region. Note down the ip address of the newly created droplet.

Login to your droplet

In Windows install Putty. Open it with ip address.

run-putty

A security alert will pop up. Click Yes. Login as root.

Set a Hostname

Execute:

hostnamectl set-hostname wordpress
nano /etc/hosts

set-hostname

Change the line of text where the cursor is, to

127.0.1.1 wordpress

Verify:

hostname

You will get wordpress as output.

Set Timezone

Execute:

dpkg-reconfigure tzdata

Verify:

date

It will show your local date and time.

Create User

adduser admin

add-admin

usermod -a -G sudo admin
logout

Run Putty again and login as admin.

Lock with a Private Key

Open puTTYgen. Generate a Public/Private key pair.
puttygen
Save Private key in your PC.
Copy Public key.
public-key
Execute:

mkdir .ssh
sudo nano .ssh/authorized_keys

Paste the copied public key into this file.
Save and Exit.
Execute:

sudo chown -R admin:admin .ssh
sudo chmod 700 .ssh
sudo chmod 600 .ssh/authorized_keys
sudo nano /etc/ssh/sshd_config

Now disable root login and password authentication:

PasswordAuthentication no
PermitRootLogin no

Execute:

sudo service ssh restart

Open the private key and login with admin user. No password is necessary.

Firewall Setup

Execute:

sudo ufw app list
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

ufw-status

Install Nginx

Execute:

sudo apt-get update
sudo apt-get install nginx
sudo ufw allow 'Nginx HTTP'
sudo ufw status

Open your browser and type IP address. You will see the following:
nginx-welcome

Configure Default Virtual Host

Execute:

sudo nano /etc/nginx/sites-available/default

Edit:

server {
	listen 80 default_server;
	listen [::]:80 default_server;

	root /var/www/html;
	index index.php index.html;

	server_name _;

	location / {
			try_files $uri $uri/ /index.php?$args;
	}

	location ~ \.php$ {
			include snippets/fastcgi-php.conf;
			fastcgi_pass unix:/run/php/php7.0-fpm.sock;
	}

	location ~ /\.ht {
			deny all;
	}
}

Create Virtual Host for example.com

Create root directory for example.com
Execute:

sudo mkdir /var/www/html/example

Execute:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
sudo nano /etc/nginx/sites-available/example.com

Edit:

server {
	listen 80;
	listen [::]:80;

	root /var/www/html/example;
	index index.php index.html;

	server_name example.com;

	location / {
			try_files $uri $uri/ /index.php?$args;
	}

	location ~ \.php$ {
			include snippets/fastcgi-php.conf;
			fastcgi_pass unix:/run/php/php7.0-fpm.sock;
	}

	location ~ /\.ht {
			deny all;
	}
}

Execute:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled
sudo service nginx restart

Multiple Virtual Host

Repeat the above process for example2.com and so on.
Now you can see example.com, example2.com etc in your browser if you have already changed DNS records of the domains pointing to new host.

Install MySQL Server

Execute:

sudo apt-get install mysql-server
sudo mysql_secure_installation

Since you have already set up a password for your root user, you can answer “no” to the question for changing root password. Answer “yes” to rest of other questions.

Create MySQL Databases

Execute:

mysql -u root -p
show databases;
CREATE DATABASE wpdb1 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
GRANT ALL ON wppdb1.* TO 'wp_user'@'localhost' IDENTIFIED BY 'wp_password';
FLUSH PRIVILEGES;
EXIT;

Similarly, you can create as many database as you need.

PHP-FPM Install

Execute:

sudo apt-get install php-fpm php-mysql php-xml php-gd
sudo nano /etc/php/7.0/fpm/php.ini

Set:

cgi.fix_pathinfo=0;
post_max_size = 20M
upload_max_filesize = 20M

Restart:

sudo service php7.0-fpm restart
sudo service nginx restart

Execute:

sudo nano /var/www/html/test.php

phpinfo
Browse:

http://ipaddress/test.php

if it results the following then all is okay. Now you can remove the test file.

test-php

sudo rm /var/www/html/test.php

Install WordPress

Execute:

sudo wget https://wordpress.org/latest.zip
sudo apt-get install unzip
sudo unzip latest.zip
sudo cp -R wordpress/* /var/www/html/example/
cd /var/www/html/
chown -R www-data example
Hit the browser:
http://example.com

You should see:
wordpress-start
Continue the installation:
wordpress-setup

Transfer files from Old Host to New Host

If you are migrating from any other host you should transfer your files as well as database.
Follow this guide: How to Copy Files from Old Host to New Host

Secure example.com with SSL

Now that you have successfully hosted many wordpress sites. You may secure example.com with a FREE SSL provided by Let’s Encrypt.
Execute:

sudo ufw disable
sudo service nginx stop
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
sudo nano /etc/nginx/snippets/ssl-params.conf

Add:

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Execute:

sudo nano /etc/nginx/sites-available/example.com

Change to:

server {
	listen 80;
	listen [::]:80;
	server_name example.com;
	return 301 https://$server_name$request_uri;
}
server {
	server_name www.example.com;
	return 301 $scheme://example.com$request_uri;
}
server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	include snippets/ssl-params.conf;

	root /var/www/html/example;
	index index.php index.html;

	server_name example.com;

	location / {
			try_files $uri $uri/ /index.php?$args;
	}

	location ~ \.php$ {
			include snippets/fastcgi-php.conf;
			fastcgi_pass unix:/run/php/php7.0-fpm.sock;
	}

	location ~ /\.ht {
			deny all;
	}
	
	location ~ /.well-known {
		allow all;
	}
}

Execute:

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory --help
./letsencrypt-auto certonly -a webroot --webroot-path /var/www/html/example -d example.com -d www.example.com --server https://acme-v01.api.letsencrypt.org/directory --agree-dev-preview
sudo service nginx restart

As the SSL certificate should be renewed every three months, you should add the following to automate the renewal process.
Execute:

sudo crontab -e
30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
35 2 * * 1 /bin/systemctl reload nginx

Now hit the browser, you will be redirected to https://example.com with a green padlock. Happy Browsing.

, , , ,

One response to “Multiple WordPress with SSL in Ubuntu 16.04”

Leave a Reply to vanshanu raj Cancel reply

Your email address will not be published. Required fields are marked *