My New Site

Introduction

I decided it was about time to expand my online presence.  I wanted to create some resources for others, as well as to keep an archive for myself for future reference.  I’ve never been much of a fan of social media, so this personal website was the outcome of my desire.  This is just a quick post about my decision processes to bring up this site.

Hosting Provider Decision

The first decision to be made was where to host the site.  There are a ton of options out there, but since this is just a hobby site, cost was a major consideration.  I ended up settling on Linode.  I had been aware of them for many years, and they had a $5/mo VPS plan with vanilla OS distribution images pre-made (1 vCPU, 1G RAM).  I could have used any of the big name providers like AWS, Azure, Google Cloud, but those were all more expensive and for what I needed didn’t provide any benefit.  I could have used any of the other off-brand cheap hosting providers too, but I wasn’t familiar with them and they definitely hadn’t been around as long.  

I’m not doing anything like multi-datacenter failover, or using a hosted DB solution like AWS RDS or Aurora.  In the unlikely event the site goes down due to my hosting provider’s failure, no big deal.  Either it will come back up when they recover, or I just re-spin it via Ansible in just a few minutes if there is complete data loss.  I’m not making money off the site, and it might be a slight inconvenience to some visiting, but even big name sites have failures; its not the end of the world.  Ansible makes deployment easy, backups make recovery easy.  It also means that if I do decide to switch hosting providers in the future, that too is quick and easy.

Once I made the decision to use WordPress, I could have used one of the many wordpress-specific hosting services, but I don’t like giving up that sort of control, and quite frankly, I don’t trust them to be able to secure the site to the same level.  I’d much rather not have my site compromised than it have five nines of uptime.

Outside of a personal website, I’d probably not use Linode, or any other cloud provider for that matter.  When it comes to business, I really think having your own servers in multiple geo-separated datacenters to create your own private cloud is the way to go.  Initially it may be more expensive, but you have better control over uptime and performance, and once you’ve scaled to a few hundred VMs, its always cheaper too!   Maybe in a future post I’ll talk about this more.

OS/Distribution Choice

This was a fairly easy one for me.  First, it needed to be free.  Second, it needed to be stable with a long support lifetime.  To me, the only real choice here was CentOS, and the latest version, 8.  We made this decision at work a while ago after going through issues with Ubuntu LTS releases clobbering service configurations on minor upgrades.  Plus CentOS is built off of the largest commercial distribution, RHEL, so you get all their engineering effort for free.  Not to mention,  its one of the few distributions to enable SELinux out of the box … and no, no matter what you read online, never disable SELinux, its not that hard!

Content Management

My content management choice I’m probably the most ashamed of with this site.  Being the fact that this is a hobby site, I needed to bring something up quickly, and I am NOT a front-end guy.  I wanted something that would look nice that I could concentrate on content and not fumbling my way through HTML and CSS to have a crappy looking site at the end.  So, they say WordPress powers 30% of the Web; now I guess it powers 30.000001% ….

I chose WordPress because there are tons of themes, templates, and plugins. I know WordPress has a horrible security track record.  I know I shouldn’t use WordPress, and I definitely would not for a business.  But at the end of the day, the risk/reward for a personal site, WordPress seemed like the best option.  There are alternatives like Drupal or Joomla, but they too have had their own security issues.  A lot of the vulnerabilities for WordPress come from plugins and themes, so those must be limited.  At the end, the only plugins I’m using are Elementor (which seems to be the most popular editor, which, yes, did have a recent vulnerability) with their Hello Elementor theme, and Invisible reCaptcha to prevent spam in my comments.  I’m also trying to employ the best practices of limiting access with SELinux that may have thwarted any possible Elementor attack vector (assuming I was using the registration form that had the vulnerability, which I’m not). 

At the end, I think I’m comfortable with my choice.  I don’t think I’m going to be the victim of a targeted attack, I just need to to secure my WordPress site better than 99% of the others, and keep things up to date.

Hardening

At this point, most other sites would disable SELinux and consider themselves done, but there’s a few extra simple steps that can greatly improve the security of the site.  I’ve posted my Ansible Scripts online that I use for deployment which can be further evaluated for hardening procedures.  I do not believe in security through obscurity, so keeping them private would not reduce my chances of being a victim.  (Eagle-eyed readers reviewing my scripts might question why I move the SSH port then, and truthfully, for me, its more of a load issue from all the people constantly bombarding my site with scripts trying to break in … its only a 1 vCPU VPS after all).

In general, the most important things when hardening are:

  • Do not allow password-based logins.  Use public keys (or an SSO approach like Kerberos).
  • Use a published set of guidelines to harden the OS being used.
  • Ensure SELinux is ENABLED
  • Configure SELinux to provide minimum required access to each service.
    • For instance, for WordPress, only the web root (and subdirectories) should be readable by the web server, and only the wp-content tree should be writable.
      • NOTE: This does mean that the WordPress built-in automatic update will not work since it doesn’t have permissions.  Instead, we rely on wp-cli and a cron task to automate upgrades.
  • Make sure all services have reconfigured default passwords (e.g. MariaDB)
  • Do not run more services than are absolutely critical to your deployment.
  • Have active monitoring services to detect suspicious behavior and take automated action
    • In this case, I’m only using Fail2Ban, however in a business deployment, I’d also deploy an IDS/IPS (Intrustion Detection and Prevention System) at the network layer. 
Things I am not doing on this site that I would for business:
 
  • Separate different services onto different OS installs (VMs).  E.g. DB node vs Web Server.
    • I’m not doing that here purely for cost reasons since it is a personal site, but critical for business!
  • Use network segmentation liberally.  Servers without need of internet access should not have it (e.g. DB Servers).  Servers with different levels of sensitive data should be in different network zones (VLANs).
    • Again, I’m not doing this here since its a simple personal site, but all businesses should.  Infact, Linode doesn’t support this concept yet anyhow …
  • Deploy firewalls in front of servers to limit both ingress and egress access for only essential ports and sources or destinations.
    • Linode does not offer this.  Only firewall in use is the Linux built-in one.  I’ve also chosen not to perform egress filtering due to the fact that it isn’t feasible with only a single server (e.g. packages for OS updates and WordPress are being pulled from random mirrors across the internet)
  •  Console or Remote console access (e.g. SSH) should not be open to the public internet but instead require a VPN with 2FA authentication to access the network necessary for access.
    • This isn’t feasible on Linode, but would be considered necessary for any business.
  • Monitor your systems for health and suspicious behavior (e.g. ElkStack, Icinga2)
    • This would require additional nodes for monitoring, not doing this on a personal site.
  • Centralize logging for issue and security investigation.  If the data isn’t solely on a machine that got compromised, you can better investigate and be confident of the integrity of the log data.
    • Again, would require additional nodes, not doing this on a personal site.
 

As you can see, there are definitely some important guidelines I’m not following with this site for cost reasons.  In fact, to do this site right, I’d need to choose a different hosting provider that had the concept of private VM networks, and spin up a couple dozen VMs just to get started (multiple DB nodes, load balancers, firewalls, web servers, authentication servers, monitoring and log servers, etc).  This also goes to show how quickly you can expand to hundreds of VMs for a business, thus limiting the cost effectiveness of using a cloud provider in the first place … assuming of course you want to do things right.

Update 2020/08/07:

I ended up installing 2 additional WordPress plugins.

I was having issues with Google Search Console’s Mobile view evaluation.  It was returning errors fetching resources randomly.  I think the Linode $5/mo server is just a bit underpowered and the number of resources being fetched was just too great … I’m guessing Google is very aggressive with request timeouts as well.  I installed the Autoptimize plugin and activated the options to minimize and combine JS and CSS.  This reduced the number of resources fetched on a page load by something like 15 and effectively resolved the issue.  I also noticed an improvement in page load speeds on my phone.

The second plugin was Yoast SEO.  I figured if I was going to put the effort into writing blog posts, I should make sure they get indexed properly in the various search engines.

Those two plugins each have millions of installations, so I’m hoping that means they’ve been vetted well.