This guide will show you how to create a reverse proxy to hide any domain or server IP with a frontend admin panel that blocks IPs, IP ranges and ASNs. This guide uses Ubuntu 22.04, I installed it on a DigitalOcean droplet. You can get $200 free credit from DigitalOcean using my referral link here https://m.do.co/c/c08a36ec894f
+----------------+ +---------------------+ +------------------+
| Client | <---> | NGINX Reverse Proxy | <---> | Target Server |
| (Browser/User) | | (proxy.yourdomain.com) | | (192.168.1.100) |
+----------------+ +---------------------+ +------------------+
| Blocks IPs via |
| blocklist.conf |
+---------------------+
Step 1: Update the SystemEnsure your Ubuntu system is up to date.
sudo apt update && sudo apt upgrade -y sudo apt install -y software-properties-common
Step 2: Install NGINXInstall NGINX to serve as the reverse proxy.
sudo apt install -y nginx sudo systemctl enable nginx sudo systemctl start nginx
Verify NGINX is running:
sudo systemctl status nginx
Step 3: Configure NGINX as a Reverse ProxyCreate a new NGINX configuration file for your reverse proxy.
sudo nano /etc/nginx/sites-available/reverse-proxy
Add the following configuration, replacing proxy.yourdomain.com with your domain and http://192.168.1.100:3000 with your target server’s IP and port:
server { listen 80; server_name proxy.yourdomain.com; # Proxy all requests to the backend server location / { proxy_pass http://192.168.1.100:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; 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; proxy_cache_bypass $http_upgrade; } # Include blocklist file include /etc/nginx/blocklist.conf; }
Enable the configuration by creating a symbolic link:
sudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/
Create an empty blocklist file for IPs, IP ranges, and ASNs:
sudo touch /etc/nginx/blocklist.conf sudo chmod 644 /etc/nginx/blocklist.conf
Test the NGINX configuration for syntax errors:
sudo nginx -t
If no errors are reported, reload NGINX:
sudo systemctl reload nginx
This configuration hides the target server’s IP by routing all traffic through the proxy server.
Step 4: Install and Configure UFW (Uncomplicated Firewall)UFW will be used to enforce IP-based blocking at the system level for added security.Install UFW:
sudo apt install -y ufw
Allow SSH (to prevent lockout) and HTTP traffic:
sudo ufw allow 22 sudo ufw allow 80
Enable UFW:
sudo ufw enable
Step 5: Install PHP and SQLite for the Front End
The front end will be a simple PHP application with SQLite to store and manage blocked IPs, IP ranges, and ASNs.
Install PHP and required dependencies:
sudo apt install -y php-fpm php-sqlite3 sqlite3
Configure NGINX to serve the PHP front end. Create a new configuration file:
sudo nano /etc/nginx/sites-available/blocklist-admin
Add the following configuration, replacing admin.yourdomain.com with your admin subdomain.
server { listen 80; server_name admin.yourdomain.com; root /var/www/blocklist-admin; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.ht { deny all; } }
Enable the configuration:
sudo ln -s /etc/nginx/sites-available/blocklist-admin /etc/nginx/sites-enabled/
Create the web root directory for the front end:
sudo mkdir /var/www/blocklist-admin sudo chown www-data:www-data /var/www/blocklist-admin
Test and reload NGINX:
sudo nginx -t sudo systemctl reload nginx
Step 6: Create the PHP Front-End Application
Create the PHP files for the front end to manage the blocklist.
Database SetupCreate an SQLite database for storing blocked IPs, ranges, and ASNs:
sudo sqlite3 /var/www/blocklist-admin/blocklist.db <<EOF CREATE TABLE blocklist ( id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT NOT NULL, -- 'ip', 'range', or 'asn' value TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); EOF sudo chown www-data:www-data /var/www/blocklist-admin/blocklist.db sudo chmod 660 /var/www/blocklist-admin/blocklist.db
PHP Front-End FilesCreate the main PHP file for the front end:
sudo nano /var/www/blocklist-admin/index.php
Add the following code:
<?php $db = new SQLite3('/var/www/blocklist-admin/blocklist.db'); // Handle form submission if ($_SERVER['REQUEST_METHOD'] === 'POST') { $type = $_POST['type']; $value = trim($_POST['value']); if (!empty($value)) { // Validate input if ($type === 'ip' && (filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))) { $stmt = $db->prepare('INSERT INTO blocklist (type, value) VALUES (:type, :value)'); $stmt->bindValue(':type', $type, SQLITE3_TEXT); $stmt->bindValue(':value', $value, SQLITE3_TEXT); $stmt->execute(); } elseif ($type === 'range' && preg_match('/^[\d.:\/]+$/i', $value)) { $stmt = $db->prepare('INSERT INTO blocklist (type, value) VALUES (:type, :value)'); $stmt->bindValue(':type', $type, SQLITE3_TEXT); $stmt->bindValue(':value', $value, SQLITE3_TEXT); $stmt->execute(); } elseif ($type === 'asn' && preg_match('/^AS\d+$/i', $value)) { $stmt = $db->prepare('INSERT INTO blocklist (type, value) VALUES (:type, :value)'); $stmt->bindValue(':type', $type, SQLITE3_TEXT); $stmt->bindValue(':value', strtoupper($value), SQLITE3_TEXT); $stmt->execute(); } } } // Handle deletion if (isset($_GET['delete'])) { $id = (int)$_GET['delete']; $stmt = $db->prepare('DELETE FROM blocklist WHERE id = :id'); $stmt->bindValue(':id', $id, SQLITE3_INTEGER); $stmt->execute(); } // Fetch all blocked entries $results = $db->query('SELECT * FROM blocklist ORDER BY created_at DESC'); ?> <!DOCTYPE html> <html> <head> <title>Blocklist Manager</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } .error { color: red; } </style> </head> <body> <h2>Blocklist Manager</h2> <form method="post"> <label>Type:</label> <select name="type"> <option value="ip">IP Address</option> <option value="range">IP Range</option> <option value="asn">ASN</option> </select> <input type="text" name="value" placeholder="Enter IP, Range, or ASN (e.g., AS12345)" required> <button type="submit">Add to Blocklist</button> </form> <h3>Current Blocklist</h3> <table> <tr> <th>ID</th> <th>Type</th> <th>Value</th> <th>Created At</th> <th>Action</th> </tr> <?php while ($row = $results->fetchArray(SQLITE3_ASSOC)) { ?> <tr> <td><?php echo htmlspecialchars($row['id']); ?></td> <td><?php echo htmlspecialchars($row– ['type']); ?></td> <td><?php echo htmlspecialchars($row['value']); ?></td> <td><?php echo htmlspecialchars($row['created_at']); ?></td> <td><a href="?delete=<?php echo $row['id']; ?>" onclick="return confirm('Are you sure?')">Delete</a></td> </tr> <?php } ?> </table> </body> </html> <?php $db->close(); ?>
This PHP script creates a web interface to add and delete IPs, IP ranges, and ASNs. It validates IPv4/IPv6 addresses, CIDR ranges, and ASN formats (e.g., AS12345).
Step 7: Script to Sync Blocklist with NGINX and UFW
Create a script to convert the SQLite blocklist into NGINX deny directives and UFW rules.
This script will also resolve ASNs to IP ranges using an external API (e.g., ipinfo.io or similar).
Install jq for JSON parsing and curl for API requests:
sudo apt install -y jq curl
Create the sync script:
sudo nano /usr/local/bin/update-blocklist.sh
Add the following script, replacing YOUR_IPINFO_TOKEN with your ipinfo.io API token (optional, for ASN resolution):
#!/bin/bash BLOCKLIST_FILE="/etc/nginx/blocklist.conf" DB_FILE="/var/www/blocklist-admin/blocklist.db" UFW_RULES="/etc/ufw/before.rules" IPINFO_TOKEN="YOUR_IPINFO_TOKEN" # Clear existing blocklist file echo "" > "$BLOCKLIST_FILE" # Fetch blocklist from SQLite sqlite3 "$DB_FILE" "SELECT type, value FROM blocklist" | while IFS='|' read -r type value; do if [ "$type" = "ip" ]; then echo "deny $value;" >> "$BLOCKLIST_FILE" sudo ufw deny from "$value" to any elif [ "$type" = "range" ]; then echo "deny $value;" >> "$BLOCKLIST_FILE" sudo ufw deny from "$value" to any elif [ "$type" = "asn" ]; then # Resolve ASN to IP ranges using ipinfo.io (requires API token) if [ -n "$IPINFO_TOKEN" ]; then curl -s "https://ipinfo.io/$value/ranges?token=$IPINFO_TOKEN" | jq -r '.ranges[]' | while read -r range; do echo "deny $range;" >> "$BLOCKLIST_FILE" sudo ufw deny from "$range" to any done fi fi done # Reload NGINX sudo nginx -t && sudo systemctl reload nginx # Reload UFW sudo ufw reload
Make the script executable:
sudo chmod +x /usr/local/bin/update-blocklist.sh
Run the script manually to test:
sudo /usr/local/bin/update-blocklist.sh
Step 8: Automate Blocklist Updates
Set up a cron job to run the script periodically (e.g., every 5 minutes):
sudo crontab -e
Add the following line:
*/5 * * * * /usr/local/bin/update-blocklist.sh
Step 9: Secure the Front End
To prevent unauthorized access to the admin interface, add basic authentication.
Install apache2-utils to create a password file:
sudo apt install -y apache2-utils sudo htpasswd -c /etc/nginx/.htpasswd admin
Enter a password when prompted.
Update the blocklist-admin NGINX configuration to require authentication:
sudo nano /etc/nginx/sites-available/blocklist-admin
Add the following to the server block:
auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd;
Reload NGINX:
sudo nginx -t sudo systemctl reload nginx
Step 10: Test the Setup
- Access the Front End: Navigate to http://admin.yourdomain.com (or your chosen admin URL). Log in with the admin username and password.
- Add Entries: Add an IPv4 address (e.g., 192.168.1.100), an IPv6 address (e.g., 2001:db8::1), an IP range (e.g., 192.168.1.0/24), or an ASN (e.g., AS12345).
- Verify Blocklist: Check /etc/nginx/blocklist.conf to ensure deny directives are added. Run sudo ufw status to confirm UFW rules.
- Test Proxy: Access http://proxy.yourdomain.com to verify the reverse proxy is forwarding requests to the target server.
- Test Blocking: Try accessing the proxy from a blocked IP to confirm it’s denied.
Step 11: (Optional) Enable SSL with Let’s Encrypt
sudo apt install -y certbot python3-certbot-nginx
Obtain and install SSL certificates:
sudo certbot --nginx -d proxy.yourdomain.com -d admin.yourdomain.com