Securing a simple website

sanesecurityguy.com is more than a year old now and I’ve made quite a few changes recently.

ʕ·ᴥ·ʔ: Is that why this article took so long?

Yes, yes, there were several hiccups in the migration.

If you’ve been wondering how to secure a simple website, then this article is for you. This article is meant for people who have a simple website that they want to secure and who aren’t web developers, but even web developers managing huge, complex websites might learn a thing or two here.

With that out of the way, let’s start with an old and important idea I’ve written about before.

Multiple points of failure

Let’s talk about the various internet infrastructure platforms that make a website work. A website is kind of like a mobile phone number. In order for people to call your mobile phone number, you need to have a SIM card tied to the phone number itself, a phone to put the SIM card into, a battery to turn the phone on, and a charger to keep the battery charged. You might think the battery and charger come with the phone, but they’re not necessarily part of the phone nor are they always irreplaceable (well, at least old phones had replaceable batteries).

So, looking at it that way, the various parts of a website are:

  1. The domain name of a website (like sanesecurityguy.com)
  2. The DNS nameserver that points to the IP address of the web server (and email server, if any)
  3. The web server that contains the actual website
  4. The email server, if there is one

Most people usually leave all of these things up to one single service provider, like Namecheap, GoDaddy, or AWS. I say: don’t. Use a different service provider for each of these functions.

So, for example, sanesecurityguy.com is currently set up like this:

  1. Epik is my domain name registrar handling the domain name sanesecurityguy.com
  2. Cloudflare handles my DNS records, so I use a couple of Cloudflare DNS nameservers
  3. Hetzner is my hosting provider, so I use a Hetzner web server
  4. Zoho is my email service provider, so I use three Zoho email servers

The reason why you want to use different service providers for each of these different functions is that if one of them causes your site to fail, it’s far less work to get a new service provider to replace them and get your site back up and running.

So if Hetzner ever fails me, I can always pay Bluehost to be my hosting provider and get Cloudflare to point my domain name to Bluehost instead. If Zoho ever fails me, I can do the same thing with Fastmail. If Cloudflare fails me, I can tell Epik to switch my DNS nameservers to Hetzner’s or somebody else’s. And if Epik fails me, I can buy sanesecurityguy.me on NameSilo and point that domain name to my Cloudflare DNS nameservers to get back up and running again, just with a new domain name until I can get sanesecurityguy.com back.

With a setup like this, there are multiple independent points of failure that can be replaced. Yes, any one of them failing will still take my website down, but getting it back up will be a lot less trouble and take a lot less time. Remember:

ʕ·ᴥ·ʔ: Don’t put all your picnics in one basket!

Eh, not quite, but good enough.

Small site, big shield

You’ve probably heard of Distributed Denial-of-Service (DDoS) Attacks before. If not, it’s kind of like getting your mailbox flooded with mail. You get so much mail in your mailbox that you can’t read it all and you miss important mail, like from friends or from your bank. A DDoS Attack is similar, in that it floods your website with so much useless traffic that your web server can’t handle it and goes down, locking out traffic from legitimate website visitors.

DDoS Attacks are the most common cyber attacks on the internet. And unless your site is being hosted on a big cloud computing service provider like Google Cloud, Microsoft Azure, or AWS, your website is almost certainly vulnerable to DDoS Attacks (Linode being a notable exception). So unless your site is already hosted on a big cloud computing platform, you’ll have to deal with DDoS Attacks somehow.

One of the best ways to do so is with a Content Delivery Network (CDN). A CDN is kind of like a secretary who goes through all your mail and hands you only the mail that you need to read and respond to. All other mail, she takes care of it, mailing back a canned response or dropping them entirely.

With a CDN, your website’s visitors will never visit your web server directly. Instead, they’ll visit your CDN’s server, and your CDN’s server will ask your web server for only the content that it needs to show to the visitor. If another visitor asks the CDN server for the same content, the CDN will hand them an exact copy of the same content without bothering your web server a second time, freeing up your web server’s resources and protecting it from DDoS Attacks.

So, when a DDoS Attack does strike your website, unless the attack is bypassing your CDN and attacking your web server directly, it’s gonna’ be your CDN’s server getting DDoS’ed rather than your web server.

ʕ·ᴥ·ʔ: Hold on. Does that mean then that a DDoS Attack can bypass my CDN and attack my web server directly?

Oh, yeah, totally.

ʕ ಠ ᴥಠ ʔ: Well… well… what then?!

Oh, the solution is pretty simple: never publish your web server’s IP address.

If nobody but your CDN ever connects to your web server directly, then nobody except your CDN ever needs to know your web server’s IP address. If nobody other than your CDN knows your web server’s IP address, then anybody who wants to DDoS you has to go through your CDN. And guess what: you might not be in the business of withstanding DDoS Attacks, but CDN’s are. They have to withstand DDoS Attacks all the time, because their business model requires them to be standing in the front lines of DDoS Attacks.

So, if you’re in the business of selling widgets, that’s what you’re good at, and that’s what people pay you for, then CDN’s are in the business of delivering web content, DDoS or no DDoS. And you might not even have to pay for it. Cloudflare offers free DDoS protection, which I have been using and been satisfied with for about a year, now. And, as already mentioned, if your site is hosted on Linode, then you’ve already got DDoS protection from Linode for free, though I’m sure you can still add Cloudflare on top of that.

Just be sure that your web server’s IP address isn’t getting leaked anywhere. First of all, when I say: “never publish your web server’s IP address,” I really do mean never. That’s the mistake I made recently when I moved to Hetzner. I was having some DNS issues that I was troubleshooting, and so I decided to let Cloudflare publish my new Hetzner web server’s IP address in saneseurityguy.com’s DNS records for just a day so that I could fix the problem. Actually, it was for a lot less than a day. But, guess what, in that short span of time, my IP address was picked up and saved on at least one historical DNS database, which is a database that saves published DNS records.

ʕ·ᴥ·ʔ: Secret IP address to DDoS sanesecurityguy.com revealed!

Exactly. So let me emphasize one more time: never publish your web server’s IP address, at least not on your real domain name like sanesecurityguy.com. If you really must publish your IP address, you can buy a cheap unrelated domain like blahblahtestingdomain.io to use as a staging or testing site for a while, but never tie it to your real domain name like sanesecurityguy.com.

Some of you tech guys reading this might know that such a rule will cause complications (it will), but if you really want to make full use of the DDoS protection of a CDN, then this rule must be followed; secrecy is a must.

ʕ·ᴥ·ʔ: Nobody said security comes easy.

Nope, nobody.

Lastly, make sure your web server’s IP address doesn’t get leaked elsewhere too, like email headers. My previous article about IP addresses being leaked in email headers applies to web servers and email servers just as much as it applies to your home network.

No spoofing = no spamming

Speaking of email, how do you prevent Email Address Spoofing, which is when other people send emails pretending to be coming from your website? Imagine some hacker sending spam emails to you, or even phishing emails to you, pretending to be me by marking it as From: [email protected]. That’d put me in a bad spot.

ʕ·ᴥ·ʔ: Huh. Yeah. I dunno’. How do you stop people from sending emails as coming from sanesecurityguy.com?

Well, Kuma, if you’d read that short glossary page I just linked to about Spoofing, then you’d know: with SPF, DKIM, and DMARC.

The Sender Policy Framework, or SPF, is an email authentication protocol that defines which domains and IP addresses are allowed to send emails for your domain. So, for example, sanesecurityguy.com’s SPF record looks like this (at the time of this article getting published):

v=spf1 include:zoho.com -all

What that short line means is: zoho.com IP addresses are allowed to send emails for sanesecurityguy.com. However…

ʕ·ᴥ·ʔ: Ho, wait! I just read the glossary page about Spoofing. IP addresses can be spoofed too, so sanesecurityguy.com can still be impersonated if the faker spoofs both a sanesecurityguy.com email address and a zoho.com IP address!

Yep, that’s right. And that’s where DKIM comes in.

Asymmetric Cryptography to the rescue once again

I’ve talked about Asymmetic Cryptography before. Many times, in fact. If you dunno’ what it is, read that linked glossary page. But the gist of how DomainKeys Identified Mail, or DKIM, works on sanesecurityguy.com is that I created a private key for Zoho to use to encrypt emails on my behalf, and published a public key for people like Gmail and Yahoo! Mail to decrypt any emails purporting to be from sanesecurityguy.com to verify that they were actually from Zoho on my behalf, and not from some impostor.

So, for example, my public DKIM record is as follows:

v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCubeMAQM2odcmcXx1wjeiaLYTNOzUTB5EmKthGKve2ZBLHioFqhpMZcOdS3UJNKRll9N98HoA4zxUFPAX5QjSaXLABtdtmOcKHjeHp84kqSRVov/3Fymu8Y5xtdUmikoeVhmIBjH9OXu7Dk48KVTvdcOR7X7hz4rOWzW/wVWFL7QIDAQAB

That entire portion after the p= is the public key, which anyone including Outlook, ProtonMail, and even you can use to verify that an email was encrypted using the private key I gave to Zoho. Someone trying to impersonate me might be able to spoof my email address and Zoho’s IP address, but they wouldn’t be able to get that private key to encrypt their emails without hacking Zoho, which is much harder to do than spoofing.

Managing SPF and DKIM with DMARC

Finally, we come to Domain-based Message Authentication, Reporting, and Conformance, or DMARC.

ʕ·ᴥ·ʔ: Wow, that’s a mouthful.

Yeah, it is. But don’t let that intimidate you. All it does, really, is allow you to manage what Gmail or Yahoo! Mail or Outlook or ProtonMail do when they receive an email from your domain that fails the SPF and/or DKIM check.

So, with sanesecurityguy.com as an example once more, my DMARC record is this:

v=DMARC1; p=reject; aspf=s; adkim=s; sp=reject; fo=1; rua=mailto:[email protected]; ruf=mailto:[email protected];

There’s a lot going on here, but here’s what it all means:

  1. Drop all emails that fail both SPF and DKIM. “Drop” meaning that the failed emails don’t get to the recipient’s mailbox at all, not even their junk/spam folder.
  2. Any emails coming from a subdomain like hacked.subdomain.sanesecurityguy.com also get dropped
  3. If any emails fail SPF or DKIM, send me an email about it at [email protected]
  4. Send me statistics about pass and failure rates, also to [email protected]

So what that all comes down to is this: Only emails coming from sanesecurityguy.com that pass SPF or DKIM are allowed to reach recipients’ mailboxes. No emails that fail both are allowed; no emails from subdomains are allowed; and anything that fails, report that to me.

ʕ·ᴥ·ʔ: Hey, wait. So what happens if an email fails only one of SPF or DKIM, but passes the other? I mean, other than reporting that to you, what happens to the email itself? Does it still reach the recipients’ mailboxes?

Yes, those emails still reach recipients’ mailboxes just fine. DMARC doesn’t currently offer any way to require passing both SPF and DKIM to pass DMARC validation, as the DMARC protocol assumes passing either SPF or DKIM is secure enough.

Don’t worry if this is a little confusing at first; you don’t have to get it all right the first time, or even completely wrap your head around it the first time. The most important variable here is the policy tag, which is the p= tag. A policy of reject instructs mail servers to drop all emails claiming to be from your domain that fail DMARC validation. You probably shouldn’t immediately start dropping emails if you’re just starting out with DMARC. Start with p=quarantine first to send fails to the junk/spam folder, or p=none to treat DMARC fails no differently from successes. Set an email address for you to receive all reports of DMARC failures and just keep that setup for a while until you see that everything will work exactly as you want when you move to p=reject.

Once you move to a working p=reject DMARC policy, then congratulate yourself, ‘cuz your website’s emails will be more trustworthy than even Gmail’s and Outlook’s which are still using p=none.

Man, securely migrating even a simple website can be a pain. And I’m not even done as of this writing, actually.

ʕ·ᴥ·ʔ: Nobody said security comes easy!

Yes, yes, I know, Kuma.

ʕ·ᴥ·ʔ: And if you’d like some help with making it easier, consider subscribing! You’ll be notified of new articles – and only new articles – once a month, assuming Lambert’s email setup doesn’t fail for some reason.

Hey, man. Uh – I mean – bear. I’m workin’ on it! The RSS feed works fine, though; I’m sure of that!

ʕ·ᴥ·ʔ: Oh! And if you don’t wanna’ give an email address, you can also subscribe via the RSS feed linked to in the menu.

♫ RSS: Really Simple Syndication ♫