When I decided that I was going to start this blog, I knew from some previous experiences that Ghost CMS was going to be my platform of choice. WordPress is the standard, it's estimated that WP hosts around 43% of all websites, so why not go with a platform that ubiquitous? Simple, I don't need the power that WP comes with. WP is highly flexible and can do just about whatever you need it to with plugins and themes, but for this site, I don't need that kind of flexibility. Ghost is a beautiful and simple Content Management System that is incredibly easy to get started with. (I haven't been paid a dime to say this, I just love a good FOSS project).

Okay, so I had my CMS system chosen, but now I needed to answer a more technical question: Where am I going to host it from, and how can I keep it secure and inexpensive?

There were two main options:

  1. I could create a new Virtual Machine in Azure or other cloud VPS provider
  2. I could run it locally on my home-lab hardware

With a cloud option, there are some tradeoffs. I'd be using Azure since I already have a subscription there anyways. The primary con to this option is the cost associated with running a VPS in the cloud. There is no such thing as the cloud really, it's just renting someone else's computer, and sadly that isn't free. From some previous testing, I knew that Ghost needs at least 2gb of RAM, so that ruled out an ultra cheap 1vCPU x 1GB/RAM VPS. So, my cost to run a VM with a shared CPU and a minimum of 2GB of RAM would cost me ~$15 for computer in Azure (B1ms SKU). That doesn't include disk, public IP, or data costs either so including those would be about ~$20/month to host this blog. Not a ton of money, at least no more than Netflix these days, but still more than I'd like to spend on a pet project right now. Alternatively, I could use another VPS provider such as Linode or Vultr, but I already have some infrastructure running in Azure and I like to keep things centralized.

With the self-hosted option, there were some different concerns. Mainly ones revolving around speed, scalability, and security. The homelab hardware I have at my disposal are 2 Zima boards, both model 432s. Essentially, they're raspberry pi sized mini computers, both with low power x86 Celeron chips, and 4GB of RAM. Both of mine run a lightweight hypervisor and are already populated with some other VMs for my lab. The problem with these devices is memory, there's enough CPU horsepower to handle a couple VMs and a number of concurrent site visitors here, but it wouldn't be able to scale much further than that and there isn't any room to grow. In addition, these aren't some abstract computer in a massive data center, they're two little mini PCs I can see from my desk. It's not as easy to hand wave security away with the thought process of 'it's not my machine and it's data I can live without'.

Decision Time

In order to get this project off the ground with as little cost as possible, I went with the self-hosted option. For privacy reasons, I won't be diving too deep into how I have things set up, but the short of it is, the website you're on right now is running off a tiny little microcomputer! I think it's deeply cool that an entire website can run on something that so easily fits into the palm of my hand.

With this decision, I'm knowingly limiting myself in terms of future scalability for this site, and for how many more things I can run on my tiny homelab in general. I strongly suspect that this site won't always live on one of my Zima boards, and if (when) I move it somewhere else, I'll be sure to write a new post about the process. For now though, I'm excited to have the site up and running at no cost to me since I already had and was using the Zima boards. Being an IT profession, I've found time and time again that there is always going to be a tradeoff somewhere when deploying a new system. There are certainly tradeoffs to this decision, just like any system deployment, but for right now I'm content with these tradeoffs and that's enough for me.

Mitigating Risk

I have my CMS platform and hosting plan in place. I've created the necessary infrastructure in my lab to host this site and have isolated it from being directly on my network. However, there were still some pain points that I wanted to address, most relating to security and ease of setup.

Since this site is ultimately going to run on my home network, that presents some challenges. I don't have a business grade ISP and am stuck with a dynamic public IP address. Sure, I could setup dynamic DNS, or potentially some automated monitoring to notify me if my public IP changed, but that's a lot of unnecessary work and still leaves my IP exposed with 443 port forwarded to a reverse proxy. That's sub-optimal and leaves a larger threat vector open than I'm comfortable with.

The solution, a Cloudflare tunnel! Cloudflare tunnels provide an incredibly easy way to get a site up and running without having to port forward anything or expose my public IP. As a bonus, CF tunnels handles SSL certificates too, so I don't have to worry about setting up LetsEncrypt or dealing with a reverse proxy. I simply create the tunnel on the isolated network where Ghost will run and boom, public connectivity for no additional cost, and very little manual work!

The final risk to mitigate is that Ghost, much like WordPress, has a publicly available admin console with an exposed login page. Considering the hardware Ghost runs on, a brute force attach on that login page could easily take down the site. Once again, the solution here is another free Cloudflare tool, this time Cloudflare Access. I don't want the entire site behind Access, that wouldn't make much sense for a blog, but I can easily move the admin console link behind it. This way, only authenticated users can access the Ghost admin login page in the first place.

Okay, so I should be completely secure now, right? Of course not! There's no such thing in fact. Having any presence on the public internet is a risk, and while I've implemented a number of security controls to mitigate those risks, nothing is perfect. While security through obscurity isn't really security at all, writing a blog post about the security controls I'm running isn't exactly helping my case either. Sure, I could have not mentioned anything about what I have in place, but it's still visible to anyone who knows where to look. Plus, a blog post about the technical details of running said blog wouldn't be as interesting if I didn't mention security.