The anwser?
You don’t.
However, there are many precautions you can take when running a public WordPress site, which will reduce the chances of you being PWNED, or, at least, greatly mitigate the damages.
WordPress itself, has frequent security issues. This site itself, isn’t immune to them. However, over the course of the last decade running this site, it has so far, only managed to be pwned once…. and that was due to a plugin which introduced a vulnerability. The impact was limited, due to precautions I will discuss below… and it took me all of 10 minutes to get everything back up and running.
Use a dedicated DMZ.
A DMZ, is typically a subnet reserved for “Untrusted services”.
It is best to treat any publicly available service on your home network, as thought it WILL be exploited, and attackers WILL be able to gain full control over it.
Step one, is to run your public services as either a dedicated server, or a dedicated VM. You want to limit this server’s network access to only the bare minimal required for its operation.
- Internet Access – Your server will need to be able to access the internet.
- DNS – To limit exposure of potential vulnerabilities on your local DNS server, I would recommend using a public DNS server, instead of your internal server….. Just in the event this box gets PWNED, and your internal DNS server has a potential vulnerability.
- NTP – Again- I recommend using public NTP services, rather then your internal services, in the event you have a vulnerability in your NTP server.
- Allow NOTHING else. This server should be able to ping the internet, but, have NO access to any of your internal services.
I personally, leverage vlans to control my DMZ network. The switch enforces, only properly tagged traffic is accepted on the port. Even better, would be to step it up and use a dedicated switch for your vlan.
Keep everything up to date.
If you intend on exposing services to the internet, you NEED to keep everything up to date.
This means, you need to keep your firewall up to date. You need to keep your server up to date, and, you need to keep your wordpress up to date.
For me, this blog you are currently reading, is hosted on a linux server, inside of my DMZ. Since, I don’t log into my server daily to check for updates, I setup AUTOMATIC security update installations.
The above step, also includes updates to your php libraries.
Your WordPress itself, also has updates. I enabled automatic platform security updates to keep it up to date.
Most importantly- your WordPress PLUGINs are THE most common attack vector for WordPress. I cannot say I would recommend automatic updates here, but, I would ensure you keep a very close eye on them.
TLDR; You need to keep everything up to date for security patches.
Limit Attack Surface
Some endpoints, such as /wp-admin, have no functionality which a general user should have access to. I would recommend blocking access to any requests hitting /wp-admin, and locking this behind a trusted IP / SSO. For an example on how this would look, visit https://xtremeownage.com/wp-admin
I personally, leverage cloudflare’s tools for providing a layer of SSO on top of this.
From your PHP configuration, I also recommend disabling php info, and headers which may give out version information. Knowing the particular version of software running on a server, makes it much easier to find relevant vulnerabilities for that particular piece of software.
Use Secure/Unique Passwords
If say, you use a common and simple password such as “hunter2” for all of your internal services.
Lets say, an attacker managers to get access to the local server running your blog. Lets assume they managed to find a way to escape your DMZ, such as… you neglecting to block a certain service, neglecting to apply your security updates, etc….
Now, they have access to your network. When they do determine you use the credentials admin // hunter2 for all of your internal services…. they have just obtained access to everything.
My recommend here, is to use a password manager, and use unique/strong passwords for all of your internal accounts. There are both paid, free, and self-hosted services you can use for managing credentials.
I would personally, recommend either paying for such a service, or hosting your own…. assuming you can keep it secure.
Have Backups
The MOST IMPORTANT thing you can do when hosting a public service, always assume it will be pwned, and always assume everything on the box will become a complete loss.
To mitigate this risk, have backups.
In my case, assuming the server hosting this blog becomes a total loss, I have the capability of rolling back to a previous snapshot (which are taken daily), or pulling a backup out of cold storage.
Anything worth having, is worth backing up.
I am not going to go in depth on how to make proper backups- but, having a folder on the same server, named “backups”, isn’t going to cut it… If someone can gain access to your server, and delete your backups, your “backups” aren’t going to help you.
Ideally, you want your backups stored offsite. There are services such as backblaze which can assist you with this.
Use Cloudflare Argo / Access
I personally, recommend cloudflare argo tunnel.
It allows you to expose a service on your local network, WITHOUT opening a port on your firewall. It does this, by doing a reverse proxy from your network, back into cloudflare’s network.
There are a few advantages to doing this.
- It hides your actual IP Address
While- your actual IP might not seem like a huge thing to give out- I personally don’t want you to know roughly where I live. Even knowing the general vicinity of where you live, causes a small attack surface… such as being able to figure out your zip-code, ISP, etc.
While- that information by itself, usually isn’t an issue at all….. if you are ever targeted by a dedicated “hacker”, you want to disclose as little information as possible.
Another thing to consider- your security questions you provide on many websites, generally have a question of, where did you grow up? What school did you attend, etc.
Assuming, you may live around the area you grew up- by giving out your public IP address, you just gave away a few potential pieces of information.
Also- don’t assume you can KEEP your ip address hidden. There are occasionally vulnerabilities/exploits which will disclose this information.
The second advantage- you can add an additional layer of authentication around “sensitive” endpoints, such as your admin settings.
Lastly, I personally use cloudflare to block a few countries…. China, Russia, Belarus, for example… Because I receive a TON of vulnerability scans from those countries. Also- this particular website does not cater to those countries.
“Security” plugins
There are many “security” plugins you can acquire for wordpress, which will help mitigate some risk. Jetpack, for example, has its own security plugins. Cleartalk does a great job of blocking spam and a few other potential security issues.
I do advise you to look around…. the cheapest option here, is not always the best.
Also, these plugins aren’t going to be the be-all/end-all solution, as they DO rely on WordPress itself… which might have an unmitigated vulnerability.
Fail2Ban
I enjoy the use of fail2ban for detecting vulnerability scanning attempts in my logs. Detecting scan attempts is quite easy. Look at the 404 not found records being logged on your server.
I receive THOUSANDS of such attempts every single day on this site. Using fail2ban to temporarily block the IP greatly reduces the chance of a valid vulnerability being located.
Why temporarily? Hackers/Scammers frequently rotate to new IPs. Chances are- the one scanning now, won’t be in use in a few weeks.
If you have a sensor of humor, you can get very creative with a reverse proxy / .htaccess / nginx configuration.
Example, https://xtremeownage.com/backup.gz
Security Event Notifications
I personally, recommend a solution for syslog traffic. My favorite solution, happens to be Splunk.
You can also use logstash/influx/other service.
The service you choose isn’t the important part. The important part, is having notifications for when something “unexpected” happens.
Generally- there shouldn’t be any logins to your servers, unless you are logging into them to do maintenance. As such, setup a notification for new/unexpected logins.
One of the most important steps here, is to just ensure you have a way to be aware something is wrong.
The most important tip
The most important thing to remember- you CANNOT perfectly secure your public facing WordPress site. There are always new vulnerabilities occurring. Your best line of defense, is to PLAN on it being PWNED, and to have steps in place to mitigate the amount of risk / reduce the amount of time to recover.
As well, ensure you are logging requests to a location where the attacker has a much, much harder time of finding / removing the logs.
TLDR;
- Keep everything up to date.
- Treat your DMZ Server hosting wordpress, like it has an attacker already on it. Keep it isolated from EVERYTHING else.
- Keep backups of everything.
- Maintain logs and paper trails.
Why am I posting this article?
So you don’t end up like THIS GUY.
Great article, and it really got me thinking about running various servers from my home.
Question, does running WordPress from a docker container change any of this, I’ve not really studied the security implications / differences, but I would think that egress from my docker container out to my network would be impossible / more difficult, or am I naive?
Also, something I’ve thought about is this:
https://developers.cloudflare.com/workers/tutorials/deploy-a-static-wordpress-site
Basically, just have Cloudflare serve up a static version of my WP site. I would lose comments, but maybe that’s worth it in the end.
Thoughts?
Actually, a good question.
In practice, I would assume running wordpress in a non-root docker container should improve security, as attackers would need to perform a container elevation/escape before getting access to the actual host it self.
I personally, do, run this particular website in docker. However, I still have a lot of mitigations in place for when this site does managed to get PWNED.
Regarding static sites, I have legitimately been wanting to do that. It vastly improves performance, reduces the amount of dependencies, etc. The link you sent, essentially runs the entire site in cloudflare, which means, you basically don’t have to worry about anything at all.
But, the issues with static sites in general- they are static!
Things such, as this comments field…. the power savings calculator on one of my other posts. Other dynamic content- doesn’t exactly always work on a static site.