Ghost Admin Panel Exposed? How I Restricted Access by IP

Ghost CMS is powerful and user-friendly, but by default, the admin panel at /ghost/
is accessible to anyone who knows the URL. This creates a significant security risk, especially if you're running a public-facing blog. Here's how I secured my Ghost installation by restricting admin access to specific IP addresses.
The Problem
When you install Ghost, the admin interface is immediately accessible from anywhere on the internet. While Ghost has built-in authentication, this still presents several security concerns:
- Brute force attacks on admin login credentials
- Exposure of admin interface to automated scanners
- Potential exploitation of undiscovered vulnerabilities
- Information disclosure about your Ghost version and configuration
Solution Overview
The most effective approach is to implement IP-based access control at the web server level, before requests even reach Ghost. This creates a whitelist of allowed IP addresses that can access the admin panel.
Method 1: Nginx Configuration
If you're using Nginx as a reverse proxy (most common setup), add this configuration to your server block:
# Restrict access to Ghost admin panel
location /ghost/ {
# Allow specific IP addresses
allow 203.0.113.10; # Your home IP
allow 198.51.100.0/24; # Your office network
allow 192.168.1.0/24; # Local network (if applicable)
# Deny all other IPs
deny all;
# Proxy to Ghost
proxy_pass http://localhost:2368;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
After making changes, test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
Method 2: Apache Configuration
For Apache users, add this to your virtual host or .htaccess file:
<LocationMatch "^/ghost/">
Require ip 203.0.113.10
Require ip 198.51.100.0/24
Require ip 192.168.1.0/24
</LocationMatch>
Or using .htaccess in your Ghost directory:
<Files "ghost">
Order deny,allow
Deny from all
Allow from 203.0.113.10
Allow from 198.51.100.0/24
Allow from 192.168.1.0/24
</Files>
Method 3: Cloudflare WAF Rules
If you're using Cloudflare, create a WAF rule:
- Go to Security > WAF > Custom rules
- Create a new rule with these settings:
- Rule name: "Block Ghost Admin"
- Field: URI Path
- Operator: starts with
- Value:
/ghost
- AND Source IP Address is not in
{your.ip.address.here}
- Action: Block
Finding Your Current IP Address
Before implementing restrictions, identify your current IP addresses:
# Check your public IP
curl ifconfig.me
# Or
curl ipinfo.io/ip
# For IPv6
curl -6 ifconfig.me
Dynamic IP Considerations
If you have a dynamic IP address, consider these approaches:
Option 1: IP Range Allowlist
Allow your ISP's entire IP range (less secure but more convenient):
allow 203.0.113.0/24; # Replace with your ISP's range
Option 2: VPN with Static IP
Use a VPN service that provides static IP addresses for admin access.
Option 3: Dynamic DNS Updates
Create a script that updates your server configuration when your IP changes:
#!/bin/bash
CURRENT_IP=$(curl -s ifconfig.me)
OLD_IP=$(grep -oP 'allow \K[0-9.]+' /etc/nginx/sites-available/ghost)
if [ "$CURRENT_IP" != "$OLD_IP" ]; then
sed -i "s/allow $OLD_IP;/allow $CURRENT_IP;/" /etc/nginx/sites-available/ghost
nginx -t && systemctl reload nginx
echo "IP updated from $OLD_IP to $CURRENT_IP"
fi
Testing Your Configuration
After implementing IP restrictions:
- Test from allowed IP: You should access
/ghost/
normally - Test from blocked IP: Use a VPN or mobile data to verify access is denied
- Check error logs: Monitor server logs for blocked attempts
# Nginx logs
sudo tail -f /var/log/nginx/error.log
# Apache logs
sudo tail -f /var/log/apache2/error.log
Additional Security Measures
While IP restriction is effective, consider layering additional security:
1. Change Admin URL
Modify Ghost's configuration to use a custom admin path:
{
"url": "https://yourdomain.com",
"admin": {
"url": "https://yourdomain.com/secret-admin-path"
}
}
2. Enable Two-Factor Authentication
Ghost supports 2FA through apps like Google Authenticator or Authy.
3. Regular Updates
Keep Ghost updated to patch security vulnerabilities:
ghost update
4. Monitor Access Logs
Set up log monitoring to detect suspicious access attempts:
# Monitor for admin access attempts
tail -f /var/log/nginx/access.log | grep "/ghost"
Emergency Access
Always have a backup plan if you get locked out:
- Server console access through your hosting provider
- SSH access to modify configuration files
- Backup admin user with different access requirements
Monitoring and Alerts
Set up monitoring to track blocked attempts:
# Simple log monitoring script
#!/bin/bash
tail -f /var/log/nginx/error.log | while read line; do
if echo "$line" | grep -q "403.*ghost"; then
echo "Blocked admin access attempt: $line"
# Send alert (email, Slack, etc.)
fi
done
Conclusion
Implementing IP-based access control for your Ghost admin panel significantly improves security by creating a physical barrier to unauthorized access. While it requires some initial setup and ongoing maintenance (especially with dynamic IPs), the security benefits far outweigh the inconvenience.
Remember that security is about layering multiple protections. IP restrictions should be part of a broader security strategy that includes strong passwords, two-factor authentication, regular updates, and monitoring.
The key is finding the right balance between security and usability for your specific situation. Start with basic IP restrictions and gradually add additional security measures as needed.