Install Securely Wordpress in NAT VPS

Merhaba,

After giving NanoKVM's first impression before, I want to try to install wordpress on it.

My NAT VPS Specifications:

  • 1x Virtual Core (Shared)
  • 1024MB RAM
  • 10GB HDD/SSD/NVMe
  • 20x forwarded Ports v4 (Ports 6900-6920)
  • 80/443 port with haproxy
  • 150Mbit Uplink (Fair Use)

Prerequisites

Install the LEMP (Linux, EngineX (NGINX), MariaDB, and PHP) on Ubuntu 22.04

Please refer to this article to install the LEMP Stack 🦾

Install the LEMP (Linux, NGINX, MariaDB, and PHP) on Ubuntu 22.04
This tutorial is done with my NAT VPS by NanoKVM. Prerequisites To follow this tutorial, you need a root account on Ubuntu 22.04 OS running on your remote server. If you need a virtual private server (VPS) / a virtual computer with 1 IP public that is online --and can

But there is a note because this is a NAT VPS:

  • If you still remember that article, on the HAProxy tab, we must add our domain first. For example, I add a domain: nanokvm.nauf.al
https://ns1.my.id/unggah/2023/02/nanokvm-haproxy-ariq.jpg
HAProxy menu on NanoKVM
  • This HAProxy helps us to use standard HTTP/HTTPS ports (port 80/443) rather than using given ports.
  • You must have added DNS A record to your domain using your favorite hosted DNS Provider too!
    For example mine: Add DNS A record of hostname "nanokvm" in my domain nauf.al to IP 184.71.251.60 (Shared public IP Address of NAT VPS).

Next Step?

After LEMP (Linux, NGINX, MariaDB, and PHP) stack is successfully installed, we can proceed to install wordpress by following these instructions:

Step 1: Download Fresh Wordpress (Latest)

First, download a fresh copy of wordpress with wget in your Linux SSH session:

wget https://wordpress.org/latest.zip

Output:

root@ariq01:~# wget https://wordpress.org/latest.zip
--2023-02-09 11:16:22--  https://wordpress.org/latest.zip
Resolving wordpress.org (wordpress.org)... 198.143.164.252
Connecting to wordpress.org (wordpress.org)|198.143.164.252|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 24369959 (23M) [application/zip]
Saving to: ‘latest.zip’

latest.zip          100%[===================>]  23.24M  14.9MB/s    in 1.6s

2023-02-09 11:16:24 (14.9 MB/s) - ‘latest.zip’ saved [24369959/24369959]

the latest.zip file (at this time I posted 09/02/2023, Wordpress latest = Wordpress 6.1.1) has been downloaded in current directory.

Unzip the latest.zip to the working directory (nginx conf webroot) with command:

unzip latest.zip -d /var/www/html/

If your system doesn't have unzip command, install it first with

apt install unzip

Since the extracted zip will be placed on /var/www/html/wordpress, we need to move the whole file in /var/www/html/wordpress folder to /var/www/html

mv /var/www/html/wordpress/* /var/www/html/

The directory inside /var/www/html should be like this:

root@ariq01:~# ls -lah /var/www/html
total 236K
drwxr-xr-x  6 root root 4.0K Feb 10 17:21 .
drwxr-xr-x  3 root root 4.0K Feb  9 08:34 ..
-rw-r--r--  1 root root  405 Feb  6  2020 index.php
-rw-r--r--  1 root root  20K Jan  1  2022 license.txt
-rw-r--r--  1 root root 7.3K Sep 16 22:27 readme.html
drwxr-xr-x  2 root root 4.0K Feb 10 17:21 wordpress
-rw-r--r--  1 root root 7.1K Sep 16 23:13 wp-activate.php
drwxr-xr-x  9 root root 4.0K Nov 15 19:03 wp-admin
-rw-r--r--  1 root root  351 Feb  6  2020 wp-blog-header.php
-rw-r--r--  1 root root 2.3K Nov  9  2021 wp-comments-post.php
-rw-r--r--  1 root root 3.0K Dec 14  2021 wp-config-sample.php
drwxr-xr-x  4 root root 4.0K Nov 15 19:03 wp-content
-rw-r--r--  1 root root 5.5K Sep 20 15:44 wp-cron.php
drwxr-xr-x 27 root root  12K Nov 15 19:03 wp-includes
-rw-r--r--  1 root root 2.5K Mar 19  2022 wp-links-opml.php
-rw-r--r--  1 root root 3.9K Sep 19 08:59 wp-load.php
-rw-r--r--  1 root root  48K Sep 19 22:26 wp-login.php
-rw-r--r--  1 root root 8.4K Oct 17 11:06 wp-mail.php
-rw-r--r--  1 root root  25K Sep 26 10:17 wp-settings.php
-rw-r--r--  1 root root  34K Sep 17 00:35 wp-signup.php
-rw-r--r--  1 root root 4.8K Oct 17 11:22 wp-trackback.php
-rw-r--r--  1 root root 3.2K Jun  8  2020 xmlrpc.php

Step 2: Change ownership of all files to www-data

If you still remember the last article (Install LEMP stack):

By default installation, the nginx service run as nginx user, we need to change the user to www-data in order to php and nginx services running smoothly.

We need to change the ownership chown all wordpress files in order to easily further updates in the wordpress admin like wordpress-core, themes, or plugins with

chown -R www-data:www-data /var/www/html/

Result:

root@ariq01:~# ls -lah /var/www/html
total 236K
drwxr-xr-x  6 www-data www-data 4.0K Feb 10 17:37 .
drwxr-xr-x  3 root     root     4.0K Feb  9 08:34 ..
-rw-r--r--  1 www-data www-data  405 Feb  6  2020 index.php
-rw-r--r--  1 www-data www-data  20K Jan  1  2022 license.txt
-rw-r--r--  1 www-data www-data 7.3K Sep 16 22:27 readme.html
drwxr-xr-x  2 www-data www-data 4.0K Feb 10 17:21 wordpress
-rw-r--r--  1 www-data www-data 7.1K Sep 16 23:13 wp-activate.php
drwxr-xr-x  9 www-data www-data 4.0K Nov 15 19:03 wp-admin
-rw-r--r--  1 www-data www-data  351 Feb  6  2020 wp-blog-header.php
-rw-r--r--  1 www-data www-data 2.3K Nov  9  2021 wp-comments-post.php
-rw-r--r--  1 www-data www-data 3.0K Dec 14  2021 wp-config-sample.php
drwxr-xr-x  4 www-data www-data 4.0K Nov 15 19:03 wp-content
-rw-r--r--  1 www-data www-data 5.5K Sep 20 15:44 wp-cron.php
drwxr-xr-x 27 www-data www-data  12K Nov 15 19:03 wp-includes
-rw-r--r--  1 www-data www-data 2.5K Mar 19  2022 wp-links-opml.php
-rw-r--r--  1 www-data www-data 3.9K Sep 19 08:59 wp-load.php
-rw-r--r--  1 www-data www-data  48K Sep 19 22:26 wp-login.php
-rw-r--r--  1 www-data www-data 8.4K Oct 17 11:06 wp-mail.php
-rw-r--r--  1 www-data www-data  25K Sep 26 10:17 wp-settings.php
-rw-r--r--  1 www-data www-data  34K Sep 17 00:35 wp-signup.php
-rw-r--r--  1 www-data www-data 4.8K Oct 17 11:22 wp-trackback.php
-rw-r--r--  1 www-data www-data 3.2K Jun  8  2020 xmlrpc.php
https://ns1.my.id/unggah/2023/02/wordpress-installation.jpg
Wordpress Installation

Step 3: Installing Certbot

Before proceeding to install wordpress, better if we enable HTTPS first on our website with LetsEncrypt (CertBot).

You need two packages: certbot, and python3-certbot-nginx. The python3-certbot-nginx integrates Certbot with NGINX, making it possible to automate obtaining a certificate and configuring HTTPS within your web server with a single command:

apt install certbot python3-certbot-nginx

Step 4: Secure the HTTP with Certbot (Letsencrypt)

To start using the certbot-nginx plugin, run the following command:

certbot --nginx

The command will prompt you to multiple questions that you have to answer it:

root@ariq01:~# certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): myemail@nauf.al

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Account registered.

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: nanokvm.nauf.al
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1

On the last question, choose the domain name that is already activated on NGINX, which is mine nanokvm.nauf.al, Press the number, or leave input blank to select all options shown.

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/nanokvm.nauf.al/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/nanokvm.nauf.al/privkey.pem
This certificate expires on 2023-05-12.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in t                              he background.

Deploying certificate
Successfully deployed certificate for nanokvm.nauf.al to /etc/nginx/conf.d/defau                              lt.conf
Congratulations! You have successfully enabled HTTPS on https://nanokvm.nauf.al

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Certbot SSL Letsencrypt activated and deployed automatically

Your certificate is now installed and loaded into Nginx’s configuration, you may check your virtual host config on /etc/nginx/conf.d directory, run:

root@ariq01:~# cat /etc/nginx/conf.d/default.conf

Output:

root@ariq01:~# cat /etc/nginx/conf.d/default.conf
server {
    server_name  nanokvm.nauf.al;
    root /var/www/html;
    index index.html index.php;
    #access_log  /var/log/nginx/host.access.log  main;

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

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

        location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        add_header X-Cache $upstream_cache_status;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/nanokvm.nauf.al/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/nanokvm.nauf.al/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = nanokvm.nauf.al) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen       80;
    server_name  nanokvm.nauf.al;
    return 404; # managed by Certbot

}
Nginx virtual host automatically updated with HTTPS

And then visit your domain name on the web browser:

https://ns1.my.id/unggah/2023/02/https-nanokvm-naufal-securely.jpg
Now website served securely with HTTPS

Step 5: Create a Database and User for WordPress Site

Log into MariaDB shell as root with the following command:

sudo mysql -u root

Once you are logged in, create a database for WordPress using the following command. You can use whatever name you like such as your site name.

create database wpnanokvm;

Then enter the command below to create a database user for WordPress.

This command also grants all privileges of WordPress database to the user. Replace user and your-password with your preferred username and password.

grant all privileges on wpnanokvm.* to user@localhost identified by 'your-password';

Flush the privileges table for the changes to take effect and then get out of MariaDB session.

flush privileges;

exit;

Step 6: Installing Wordpress

After mysql user has been created, Install wordpress by access your domain name on the web browser, in my case https://nanokvm.nauf.al

https://ns1.my.id/unggah/2023/02/https-nanokvm-naufal-securely2.jpg

In this step, we need to fill in Database Name, Username, Password, Database Host, and Table Prefix by using Step 5: Create a Database and User for WordPress Site above.

All right, sparky! You’ve made it through this part of the installation. WordPress can now communicate with your database. If you are ready, time now to… Run the installation

Step 7: Finish the Installation with the Setup Wizard

Next, you will come to the main setup page.

Select a name for your WordPress site and choose a username (it is recommended not to choose something like “admin” for security purposes). A strong password is generated automatically.  Save this password or select an alternative strong password.

Enter your email address and select whether you want to discourage search engines from indexing your site

Create an admin account and click the Install WordPress button.

https://ns1.my.id/unggah/2023/02/https-nanokvm-naufal-securely3.jpg

Congratulations, your Wordpress successfully installed

https://ns1.my.id/unggah/2023/02/https-nanokvm-naufal-securely4.jpg

Once again, thank you NanoKVM!