Advanced Wordpess Hosting Server Setup Steps – SSH Keys, Firewall & Other Tweaks

Running your own server can be time consuming and difficult. If you are just starting your blogging journey then I highly recommend that you begin with BlueHost. It took me several years before I was comfortable enough to move some of my sites off onto their own servers, and it is by no means required for most websites or blogs anyway. If you aren’t sure whether you need either BlueHost hosting or your own server, you probably just need BlueHost. As always, if you have any questions, then please email me.

When moving from a web hosting control panel like cPanel, or BlueHost’s custom solution, to a command line interface (also known as “secure shell” or SSH for short), it’s understandable that you might feel a little apprehensive or intimidated. After all, you’re going from a graphical interface like that below, with lots of options and explanations, to a basic command like that seems to offer no help at all.

The easy to use control panel at BlueHost

Not to mention that you need to take personal responsibility for your site’s security now, and that of the server that it is hosted on. This means setting up a firewall and taking other steps to secure and optimise your server. Where would you even begin when all you have is a cursor blinking back at you?

That’s exactly how I felt when I first started making websites back in 2004. The thought of typing commands into a text only interface scared me to death and so I used BlueHost with cPanel for a long time.

Then I came across EasyEngine. EasyEngine is a command line interface that was the precursor to WordOps, which is what I use now. WordOps installs and sets up all the tricky stuff for you, and then offers simple commands to create new websites, edit and remove them, etc. It basically makes setting up a new WordPress site as simple as typing:

wo site create thisismydomain.com --wp

I’ll cover WordOps thoroughly in another post though. This particular article is a guide on the exact SSH commands that you need to enter once your VPS, cloud server or dedicated server has been created. By the way I personally use Ubuntu, version 20.04 being the most recent LTS release at this moment. LTS stands for Long Term Support and means that security and maintenance upgrades will be offered for five years from the time of its release, until April 2025.

I documented this process after much trial and error and now use it to initially setup and secure all my servers. I have never had a server or website hacked or compromised (fingers crossed). On Mac you can use the built-in Terminal app to access your server via SSH, while Windows users should try Putty.

  1. Connect To Your Server

  2. Open your SSH client (Terminal on Mac, Putty on Windows) and type in the following command:

    ssh -p 22 root@<server IP address>

    This tells your computer to connect to your server at IP address 152.44.45.16 for example, on port 22. The IP address is an example only. In reality you’d swap out the “server IP address” and put the IP number of your actual server.

    Using SSH to connect to a server via command line

    To understand what a port is, imagine your server having thousands of potential doors, each numbered 1 to approximately 65,000. Only a handful of the doors actually exist though, and each door is connected to a specific program running on your server. You can also change the port numbers of programs and deny access to other ports via firewalls (which we’ll talk about later).

    Some default port numbers are port 22 for SSH (as above), port 80 for HTTP (non-encrypted web pages) and port 443 for HTTPS (encrypted webpages).

  3. Run Updates and Reboot

  4. apt-get update && apt-get upgrade
    reboot now

    The first “update” command tells your server to update it’s internal list of file versions and possible updates. The second “upgrade” command tells your server to actually execute the upgrade. You’ll see a bunch of text across your screen. Just hit YES to upgrade at the end of it.

    Running the “apt-get update” command

    We can safely do this now because your server is brand new and its quite likely that your web host company used an old server image to create it. Kind of like when you first install Windows on your home desktop and then there is a lot of updates to download from Microsoft to make it safe and secure.

    The reboot command does as you’d expect and reboots your server, ensuring the updates are correctly applied and live.

  5. Change Root Password

  6. Next you’ll want to change your root password. Root is the name of the highest level administration account on a server. Logging in as root means that you can do literally anything on the server, and are able to execute any command whatsoever, even ones that would wipe the entire harddrive. When you are logged in as root you can see all the files and do absolutely anything.

    Because it’s likely that your hosting company either emailed your password to you, or you wrote the password on a form on their website, you should now change it to something more secure and that they wouldn’t have had access to. To do this just type:

    passwd

    Enter your new password twice to confirm and you’re done with this step.

  7. Create SSH Keys

  8. Right now, each time you login to your server, you’d need to type in the password, which should be a long and complex. However, it’s possible to create something called SSH keys which will enable you to login automatically – all you need to do is type in the command into your SSH client (or have that command saved and execute it) and you’d be logged in to your server and ready to go.

    Note that I only have a Macbook and am not familiar with this process on Windows PC. So I will defer to this site which has instructions for creating SSH keys for Windows. However, to create SSH keys on Mac, follow these instructions:

    On your local or home machine (your Macbook), run this command.

    ssh-keygen -b 4096

    When you are asked to choose a passphrase, think of something that is going to be easy for you to recall and type (ie it doesn’t have to be a secure, 30 character mix of capitalised letters, numbers and symbols).

    Once that step is done, login to your server and run these commands:

    cd /root
    ls -al

    Check if you can see a directory called “.ssh”. If you can, great. If you don’t, run this command and don’t enter a password when prompted, just press enter:

    ssh-keygen

    Now you need to lock down that .ssh folder by changing what’s called the permissions. This basically ensure that only you (with the root account) can access the SSH keys you’re about to create.

    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/*

    Next, you want to copy your local public key (that you created on your Mac with the “ssh-keygen” command above) to your server. This key file is safe to copy and send as it only allows you to access servers where it is authorised (so if someone stole it and placed it on their server, it would grant you access to their server and they gain nothing!). To operate it also needs your private key, which is something that you don’t copy and send around, so only you will have that (and not any attackers, so they can’t access your server if they only have your public key).

    Execute this command on your local machine (your Mac):

    scp -P 22 /Users/<your username>/.ssh/id_rsa.pub root@<your server IP>:/root/.ssh/uploaded_key.pub

    Swap out “your username” with your username on your Mac of course, and well as “your server IP” for the actual IP of your server. You will also be asked for the password to login as root on your server, so paste that in.

    Finally, now that your public key is on your server, you need to copy the contents of it to the authorised keys list. You can do this either on your server, or on your Mac. I’ll provide the commands for both.

    On your server itself just type in:

    cat ~/.ssh/uploaded_key.pub >> ~/.ssh/authorized_keys

    On your /Mac type:

    ssh root@<server IP> "echo `cat ~/.ssh/uploaded_key.pub` >> ~/.ssh/authorized_keys"

    Remember to swap out with the actual IP of your server.

    Finally, you should edit the configuration file of the SSH program on your server by typing the following:

    nano /etc/ssh/sshd_config

    Find the line that says “PermitRootLogin” and alter it as follows. Also, add the line that follows if it does not already exist:

    PermitRootLogin without-password
    PubkeyAuthentication yes

    Save the file and exit the editor by pressing CTRL+X and choosing yes to the prompt. Then you should restart the SSH program (it’s actually called a “service” in Linux speak) using the following command:

    service ssh restart

    We’re done with this step! Now, to test all this out, keep your existing Terminal or Putty windows open, and create a new window. In it, paste in the connection command from step 1 above:

    ssh -p 22 root@<server IP address>

    All going to plan, you should be logged in to your server without being asked for a password.

  9. Secure SSH

  10. Security is a large part of operating your own server successfully, but luckily the steps in order to secure your server are pretty straight forward.

    In this step, we are going to change the SSH port from the default port of 22 to something else random, like 43671 for example. This way, if a hacker is scanning your server and trying to find the SSH port to connect to, they won’t find it from a quick attempt.

    Type in the command to edit the SSH config file:

    nano /etc/ssh/sshd_config

    Find the port line, it should be near the top of the file, if it is commented out like this: “# port 22” then uncomment it by removing the “# ” part and then change the port number to something random and above 30000, like 43671. Do not use commas in the number. So you should end up with a line simply like this:

    port 43671

    Before we continue, here’s a quick explainer on commenting in files: On Linux systems like your server, when you add comments in a file by inserting “#” at the start of a line, it means that that line won’t be processed by whatever program uses the file, it will just ignore it instead. So when the port line was commented out, it meant that SSH would ignore whatever was typed there and just use the default port 22. That’s why we need to remove the comment (the hash symbol – #) when we change the port, so that the SSH program will read the line and actually change the port. Comments are also used by programmers to leave notes about the code they are writing.

    In addition to changing the port you should also limit the maximum number of concurrent SSH sessions that can be open at any one time and also the maximum number of failed logins that someone is able to attempt before their SSH connection will be closed. Do that by inserting the following (you can change the numbers if you want):

    MaxAuthTries 3
    MaxSessions 5

    Save the file and exit the editor (CTRL+X). Then, as above, you should restart SSH for these new settings to take effect. Paste in the following:

    service ssh restart

  11. Setup Iptables (Firewall)

  12. As I wrote above, you can imagine the ports on your server as thousands of doors, and each one might connect to different programs that are running on your server. The doors can let internet traffic in (directed towards your server) or out (originating from your server).

    A firewall is a type of software that only opens the specific ports that we want open and closes everything else off.

    If you imagine your server was your home, then closing all the doors off would make it more secure right? The same can be said for your server and blocking off as many ports as we can, to keep out intruders/hackers.

    Iptables is the name of the firewall that I use and you can set it up as follows:

    1. Check your existing firewall rules (if any).
    2. iptables -L

    3. Edit your rules with our settings.
    4. nano /etc/iptables.firewall.rules

    5. Paste in the following and then save and exit (CTRL+X). You’ll see that I made the two SSH rules the same port as we changed SSH to run on in the step above, 43671. It’s critical that these numbers match otherwise you might be locked out of your server. You can also change the port for the 4 lines that relate to “WordOps Tools” to something else random in the 3XXXX or 4XXXX range. We will use this setting later when we install WordOps.
    6. *filter

      # Delete all existing rules
      -F INPUT
      -F OUTPUT
      -F FORWARD

      # Set default chain policies
      -P INPUT DROP
      -P FORWARD DROP

      # Accepts all established inbound TCP connections
      -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

      # Allow incoming SSH
      -A INPUT -p tcp --dport 43671 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A OUTPUT -p tcp --sport 43671 -m state --state ESTABLISHED -j ACCEPT

      # Allow incoming HTTP
      -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

      # Allow NTP system time
      -A INPUT -p udp --dport 123 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A OUTPUT -p udp --sport 123 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

      # Allow outgoing HTTP
      -A OUTPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A INPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

      # Allow incoming HTTPS
      -A INPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A OUTPUT -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

      # Allow outgoing HTTPS
      -A OUTPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A INPUT -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

      # Allow incoming WordOps Tools
      -A INPUT -p tcp --dport 31837 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A OUTPUT -p tcp --sport 31837 -m state --state ESTABLISHED -j ACCEPT

      # Allow outgoing WordOps Tools
      -A OUTPUT -p tcp --dport 31837 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A INPUT -p tcp --sport 31837 -m state --state ESTABLISHED -j ACCEPT

      # Allow Sendmail or Postfix
      -A INPUT -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A OUTPUT -p tcp --sport 25 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

      # Ping from inside to outside
      -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
      -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

      # Ping from outside to inside
      -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
      -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

      # Allow loopback access
      -A INPUT -i lo -s 127.0.0.1 -j ACCEPT
      -A OUTPUT -o lo -s 127.0.0.1 -j ACCEPT

      # Allow outbound DNS
      -A OUTPUT -p udp --dport 53 -j ACCEPT
      -A INPUT -p udp --sport 53 -j ACCEPT

      # Allow inbound DNS
      -A INPUT -p udp --dport 53 -j ACCEPT
      -A OUTPUT -p udp --sport 53 -j ACCEPT

      # Enable all outbound TCP
      -A OUTPUT -p tcp -j ACCEPT

      # Drop all UDP traffic
      -A INPUT -p udp -j DROP
      -A OUTPUT -p udp -j DROP

      # Log iptables denied calls
      -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

      COMMIT

    7. Activate and check the rules. You should see the rules you pasted in reflected on the screen.
    8. iptables-restore < /etc/iptables.firewall.rules
      iptables -L

      Our iptables rules
    9. Save the rules.
    10. iptables-save > /etc/iptables.up.rules

    11. Set your Iptables rules to be applied at every boot (start up) of your server. Paste in this text “/sbin/iptables-restore < /etc/iptables.firewall.rules" so that it looks like the image below. Save and exit (CTRL+X)
    12. nano /etc/rc.local

      Ensuring that our iptables rules are applied every time the server is booted
    13. Now create a new SSH session by opening another copy of your Terminal program (or other SSH client) but keeping your current SSH window open and logged in. You should be able to login via SSH to your server just like before, with the firewall letting you through. If not, then something is wrong and you should carefully check the SSH lines in your firewall rules using the command below.
    14. nano /etc/iptables.firewall.rules

      At this stage, if there is a problem, it is very important that you keep all SSH windows open, because you will need to fix up the port error. The port number that you changed your SSH service to run on must be the same number that you inserted into your Iptables rules.

  13. Disable IPv6

  14. IPv6 is the “next” version of the Internet Protocol. In a nutshell, when it is deployed, your server will be given an IP address like 152.44.45.16 (for example). This IP address lets people find your website and it is linked to your domain name.

    A number in the aforementioned format is IPv4. An IPv6 address on the other hand looks like 0:0:0:0:0:FFFF:982C:2D10.

    IPv4 is all we need to worry about for now (it still works excellently for our purposes) and I have noticed that sometimes leaving IPv6 on can interfere with various programs and other things on the server. So we will disable it with the following commands.

    nano /etc/sysctl.conf

    Insert the following at the very end of the file (handy hit: press CTRL+V to jump down a page):

    net.ipv6.conf.all.disable_ipv6 = 1
    net.ipv6.conf.default.disable_ipv6 = 1
    net.ipv6.conf.lo.disable_ipv6 = 1

    Then run these two commands:

    sysctl -p
    cat /proc/sys/net/ipv6/conf/all/disable_ipv6

    If the final command reports back a “1” then you have been successful in disabling IPv6.

  15. Install LogWatch

  16. LogWatch is a handy program that we’ll install to keep an eye on our server. It will automatically send us a weekly email with some high level statistics about, for example, what new software was installed, deleted or upgraded on the server, who logged in via SSH and their IP addresses, disk space usage statistics and more.

    It’s good to run through each email and make sure that nothing looks out of place (like, for example, if there is one or more SSH logins from IP addresses you aren’t familiar with, or if your free disk space is getting dangerously low). We can install and setup LogWatch as follows:

    apt-get install logwatch
    nano /usr/share/logwatch/default.conf/logwatch.conf

    1. Find the line that begins with “Output” and make it as follows “Output = mail”
    2. Next find the MailTo line and change that to include your email address, eg “MailTo = myemail@gmail.com”
    3. You can change the MailFrom line to reflect your server, eg “MailFrom = MyWebsiteName-Logwatch”
    4. Change the Range as follows, “Range = between -7 days and -1 days”
    5. Save and exit (CTRL+X)

    Next you want to move the cronjob for LogWatch to the weekly folder. A “cron” is a job or task that your server will run automatically at an interval that you set. Currently, the LogWatch task is in the daily folder and so you will get a LogWatch email each day. We only want one each week, so we’ll move it with this command:

    mv /etc/cron.daily/00logwatch /etc/cron.weekly/

    Finally, you can test if LogWatch is installed and working correctly by simply typing “logwatch” in your shell. You should shortly receive an email with some info on your server. If you don’t, check your spam folder. You might need to set up some filtering rules to ensure that future Logwatch emails don’t go to your spam folder – particularly if you use Gmail.

  17. Turn Off IPv6 Emails

  18. We turned off IPv6 before, but now we’re going to turn it off specifically for emails too. I’ve noticed that sometimes Logwatch email sending might fail if it is left on. You can turn off IPv6 for email by editing the following file:

    nano /etc/postfix/main.cf

    Change the line “inet_protocols = all” to “inet_protocols = ipv4”. Then just run the following commands. The last command is a check to see if it worked, and should return only IPv4 if you’ve done this step correctly.

    service postfix restart
    postconf inet_protocols

  19. Add Root Default Email

  20. By now you’ll know that “root” is the highest administrative account on your server. In this final step, we are going to set a default root email address that any important system messages will be sent to. Do this with the following:

    nano /etc/aliases

    Add “root: myemail@gmail.com” to the last line, then simply save and exit (CTRL+X) and then type “newaliases” into your shell to register the change.

  21. All Finished

  22. We’re done! Your server is now setup securely and ready for WordOps (and WordPress) to be installed.

Published
Categorized as Hosting

By Sean Robinson

My name is Sean Robinson and I’ve been building and running my own blogs and websites since 2004, and have been doing it full-time for over a decade. If you'd like to know more about my story, please click here.

Leave a comment

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