What Do I Need?
- A Dedicated or VPS Linux Server
- CentOS 8
- Putty for Windows
What is WordPress?
WordPress is the simplest, most popular way to create a new website or blog for yourself. It powers over 38% of all websites and 63% of all content management systems used in the world. No doubt it’s a favorite as an open-source content management system that permits advanced code-level modification. The end result is that WordPress makes building websites easy and fun, mostly, for everyone, even those who aren’t developers.
- Prepare your Server
- Connect to your server via ssh console. I’d recommend using Putty for this as it’s super simple to use.
- Update CentOS to the latest version:
sudo dnf update -y
- Set server name:
sudo hostnamectl set-hostname server.example.com
- Install extra packages not included in the standard CentOS installation:
sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
- Install all other required components:
sudo dnf install httpd mariadb mariadb-server php php-common php-gd php-xml php-mbstring mod_ssl php php-pdo php-mysqlnd php-opcache php-xml php-gd php-devel php-json mod_ssl fail2ban nano firewalld certbot wget -y
- Start and enable firewalld:
sudo systemctl start firewalld sudo systemctl enable firewalld sudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --permanent --zone=public --add-service=https sudo firewall-cmd --reload
- Enable fail2ban:
sudo systemctl enable fail2ban
- Launch your text editor to edit the config file:
sudo nano /etc/fail2ban/jail.conf
- Comment out iptables and add firewalld:
#banaction = iptables-multiport #banaction_allports = iptables-allports banaction = firewallcmd-multiport banaction_allports = firewallcmd-allports
- Scroll down to sshd and switched to enabled:
[sshd] enabled = true
- Exit your editor with ‘ctrl+x’, hit ‘y’ and then ‘enter’ to save.
- Restart fail2ban after configuration:
sudo systemctl restart fail2ban
- Check if fail2ban is working. Banned clients should be zero for now but if you check after installation is over with these commands there should be multiple banned IPs since automatic vulnerability bots are scanning everything.
sudo tail -n 100 /var/log/secure | grep -i failed | tail -n 5 sudo fail2ban-client status sshd
- Start and enable Apache, Mariadb, and initiate MySQL secure installation:
sudo systemctl start httpd sudo systemctl start mariadb sudo systemctl enable httpd sudo systemctl enable mariadb sudo mysql_secure_installation
- You should secure your SQL installation with the following entries and make sure to change the password to your own complex one. Seriously.
Answers to mysql secure installation: Set root password? [Y/n] Y 3iMC2GVavHJ^u8#rx#mA Remove anonymous users? [Y/n] y Disallow root login remotely? [Y/n] y Remove test database and access to it? [Y/n] y Reload privilege tables now? [Y/n] y Create database for mariadb, you should use different password for both root mariadb password and wordpress database password: mysql -u root -p CREATE DATABASE wordpress; GRANT ALL PRIVILEGES on wordpress.* to 'wordpress_user'@'localhost' identified by 'UyWqwqrK5rysYXFQGoNHF'; FLUSH PRIVILEGES; Exit
- Create an SSL config file and generate Let's Encrypt certificate:
grep DocumentRoot /etc/httpd/conf.d/ssl.conf sudo certbot certonly --webroot -w /var/www/html/ --renew-by-default --email email@example.com --text --agree-tos -d example.com -d www.example.com sudo ls /etc/letsencrypt/live/example.com/
- Configure Let's encrypt renewal schedule:
- Paste schedule to run weekly:
0 0 * * 0 /usr/bin/certbot renew >> /var/log/certbot-renew.log
- Configure SSL config:
sudo nano /etc/httpd/conf.d/ssl.conf
- Forward HTTP to HTTPS in the SSL config file.
- Add the code below to forward http to https:
<VirtualHost *:80> ServerName example.com ServerAlias www.example.com Redirect permanent / https://example.com/ </VirtualHost>
- Comment out the pre-created SSL settings and give the SSL certificate file locations and define the SSL protocols and cipher suites. Doing this will ensure we score high on subsequent testing.
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256: ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256: DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256: ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384: ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA: DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256: DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256: AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES: !RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA SSLHonorCipherOrder on SSLOptions +StrictRequire
- After setting the SSL config, restart apache services.
- Restart the Apache services:
sudo apachectl -t sudo systemctl restart httpd
- To ensure security confidence I’d recommend testing your SSL configuration using ssllabs.com.
- Install WordPress
- Get WordPress:
sudo wget http://wordpress.org/latest.tar.gz
- Extract the archive:
tar -xzvf latest.tar.gz
- Create WordPress directory:
sudo cp -avr wordpress/* /var/www/html/
- Restore default SELinux security contexts:
restorecon -r /var/www/html
- Create upload directory:
sudo mkdir /var/www/html/wp-content/uploads
- Chown correct permissions for directories:
sudo chown -R apache:apache /var/www/html/ sudo chmod -R 755 /var/www/html/ cd /var/www/html/
- Copy sample WordPress config to new WordPress config file:
sudo mv wp-config-sample.php wp-config.php
- Edit WordPress config file:
sudo nano wp-config.php
- Insert previously defined database user and password:
define( 'DB_NAME', 'wordpress' ); /** MySQL database username */ define( 'DB_USER', 'wordpress_user' ); /** MySQL database password */ define( 'DB_PASSWORD', 'UyWqwqrK5rysYXFQGoNHF' )
- Salt and hash the WordPress passwords. This is an important step in ensuring that no one can guesstimate what you’ve got running in terms of passwords and keys. Only get your salt and hash from https://api.wordpress.org/secret-key/1.1/salt/.
- Copy and paste the secret keys from the site.
- Your WordPress installation is now partially complete so you should now be able to finish the installation via your browser.
- As soon as you’ve ‘landed’, your first port of call should be checking for any available updates.
I personally recommend then checking your install for vulnerabilities and security issues using WPSEC. WPSEC is an awesome website where you can conduct vulnerability scans for free. Check it out and do whatever you can to fix anything that comes up, as these are the very same vulnerabilities hackers and others will be looking to harness to either hack your site or turn your site into part of a botnet for hire.
WordPress is one of the most versatile platforms around for creating engaging and enjoyable websites. It’s flexibility and the fact it’s open-source is also the ‘double-edged’ sword as it were, as this means that it becomes a target for bad actors. The key to mitigating that ever present threat is to maintain regular updates and upgrades and download a plugin called Wordfence to help you stay protected and ban those bad actors knocking at your door.