I just set up blog.riamaria.com a few days ago. It's been really fun setting up the server. I looked up some ways to secure my Ghost instance better. Great ideas here and there, and mostly just regular AppSec things.
With this guide, I assume that Ghost handled the NGINX configs for you upon installation. Here are some things that you can do with NGINX to harden your Self-Hosted Ghost instance:
nginx -tbefore reloading NGINX (
server reload nginx) to propagate changes gracefully.
Redirect from HTTP to HTTPS
Unfortunately, the default Ghost instance will allow http://yourblog.example to go through to your site. I hope at this point in time people know better than to go to HTTP only sites due to lack of encryption in-transit.
As root, edit
This will permanently redirect you from HTTP to HTTPS if you go to the HTTP site.
Removing HTTP headers
One reason to not publish the NGINX version in the response headers of your site is to make it a little more difficult for attackers to sniff what version you are running on. Running on a known vulnerable version will make it more likely for bad actors to try and do something funny on your instance.
As root, edit
/etc/nginx/nginx.conf and uncomment
server_tokens off;. It should look like this:
Another thing is that you might want to remove the
X-Powered-By: Express header as well. In both
/etc/nginx/sites-enabled/yourblog.example-ssl.conf, add the following line:
proxy_hide_header X-Powered-By;. It should look like this:
Restrict Admin Access to your IP only
This part was a little tricky for me to get. Depending on whether or not you are using Cloudflare, you may have to use a different conditional.
As you can see above, we are using the
$proxy_add_x_forwarded_for variable to match with the IP address. Below is an example of a server that does not use Cloudflare:
Do take note that if you made a mistake and you tested it, your browser may cache the 301 Redirect. Simply turn on your Developer tools (F11) and under Network, tick Disable Cache. That should allow you to go back to
http://yourblog.example/ghost and try again.
Configure Security Headers in NGINX
Another things you can do is add security headers to your NGINX config.
Read the following article for more information: https://webdock.io/en/docs/how-guides/security-guides/how-to-configure-security-headers-in-nginx-and-apache
Note: I have spent a long while to try and establish a proper Content Security Policy, but that doesn't seem to be possible with how Ghost themes are currently made. Your mileage may vary.