171 lines
6.4 KiB
Markdown
171 lines
6.4 KiB
Markdown
# ip2nginx
|
||
|
||
**ip2nginx** is a lightweight and secure system for dynamically updating NGINX reverse proxy configurations based on IP address changes reported by remote systems (e.g., pfSense). It is particularly useful in scenarios where IP addresses change dynamically and need to be synchronized with a web server’s reverse proxy configuration.
|
||
|
||
## ⚙️ Features
|
||
|
||
- Accepts remote updates via update.php (must be present on the server).
|
||
- Logs all changes to log.json.
|
||
- Access is controlled using tokens stored in token.json.
|
||
- Protects against abuse by blocking IPs after repeated failed attempts, using blocklist.json and failures.json.
|
||
- The core function is to locate a specific location block inside the domain’s nginx.conf and update only the proxy_pass value — without overwriting the entire file.
|
||
- Automatically reloads NGINX using nginx -t && systemctl reload nginx.
|
||
|
||
## 📁 Project Structure
|
||
```
|
||
ip2nginx/
|
||
├── .htaccess # Restricts access, routes all requests to updater
|
||
├── updater.php # Applies proxy_pass updates to nginx.conf
|
||
├── update.php # Processes and applies external IP update requests
|
||
├── run.sh # CLI wrapper script for triggering update
|
||
├── index.php # Default entry point and fallback error handling
|
||
├── data/ # Data storage directory
|
||
│ ├── meta.json # Central metadata file for all domains
|
||
│ ├── token.json # Authorized tokens for each client
|
||
│ ├── log.json # Log of updates and timestamps
|
||
│ ├── blocklist.json # IPs blocked after repeated failed attempts
|
||
│ └── failures.json # Failed authentication tracking
|
||
```
|
||
|
||
## ✅ Example Entry in `token.json`
|
||
|
||
```json
|
||
{
|
||
"domain1.to.com": "SECRET_TOKEN_8v73jDKsdLzAq9DkeUz1",
|
||
"domain2.to.com": "SECRET_TOKEN_3im83jUj28mjo2mI23un"
|
||
}
|
||
```
|
||
|
||
|
||
## ✅ Example Entry in `meta.json`
|
||
|
||
```json
|
||
{
|
||
"domain1.to.com": {
|
||
"domain": "domain.from.com",
|
||
"ip": "192.0.2.4",
|
||
"port": "443",
|
||
"protocol": "https",
|
||
"location": "/",
|
||
"time": "2025-05-16T09:00:00+00:00",
|
||
"changed": 1
|
||
}
|
||
}
|
||
```
|
||
|
||
## 🚀 Remote update Process: `update.php`
|
||
|
||
The API supports both GET and POST requests, though POST is recommended to prevent token caching by proxies or browsers.
|
||
|
||
| Parameter | Required | Description |
|
||
|------------|----------|-----------------------------------------------------------------------------|
|
||
| `name` | ✅ | Identifier for the configuration entry (e.g., `domain1.to.com`) |
|
||
| `token` | ✅ | Secret token assigned to the client for authentication |
|
||
| `ip` | ❌ | New public IP address (auto-detected if omitted) |
|
||
| `domain` | ❌ | Target domain name to connect to (e.g., `domain.from.com`) |
|
||
| | | (default: IP address) |
|
||
| `port` | ❌ | Proxy port (default: `443` for HTTPS, `80` for HTTP) |
|
||
| `protocol` | ❌ | Protocol to use: `http` or `https` (default: `http`) |
|
||
| `location` | ❌ | Specific `location` block in NGINX to update (default: `/`) |
|
||
|
||
If the domain, IP, port, or protocol differ from the previously saved values, the entry in `meta.json` is automatically marked with `"changed": 1`.
|
||
|
||
|
||
## 🚀 Local update Process: `updater.php`
|
||
|
||
This script is meant to be run via CLI (e.g. cronjob). It will:
|
||
|
||
1. Load all entries from `meta.json`
|
||
2. Process only those marked as `"changed": 1`
|
||
3. Locate the virtual host config: `/var/www/vhosts/system/<domain>/conf/nginx.conf`
|
||
4. Replace only the `proxy_pass` inside the matching `location` block
|
||
5. Validate and reload Nginx (`sudo nginx -t && sudo systemctl reload nginx`)
|
||
6. Reset the `"changed"` flag in `meta.json`
|
||
|
||
## ⏱ Cronjob Setup: Running `run.sh` Every 5 Minutes
|
||
|
||
To automatically apply updates to `nginx.conf` when new data is received via `update.php`, you should schedule the `run.sh` script to run regularly. This ensures that any entries marked as `"changed": 1` in `meta.json` are processed and deployed without manual intervention.
|
||
|
||
### 🔧 Recommended Cron Configuration
|
||
|
||
To run the update script every 5 or 10 minutes as **root** (required for writing to NGINX config files and reloading the server):
|
||
|
||
1. Open the root user’s crontab:
|
||
|
||
```sh
|
||
sudo crontab -e
|
||
```
|
||
|
||
2. Add the following line:
|
||
|
||
```cron
|
||
*/5 * * * * /path/to/ip2nginx/run.sh
|
||
```
|
||
|
||
Replace `/path/to/ip2nginx/` with the actual path where your `run.sh` script is located.
|
||
|
||
### ✅ Why It Must Run as Root
|
||
|
||
The updater modifies system-level files, typically located in:
|
||
|
||
```
|
||
/var/www/vhosts/system/<domain>/conf/nginx.conf
|
||
```
|
||
|
||
These files usually require **root** privileges for writing. Additionally, reloading NGINX via:
|
||
|
||
```sh
|
||
sudo nginx -t && sudo systemctl reload nginx
|
||
```
|
||
|
||
also requires elevated permissions. If `run.sh` is not run as root, the updates will silently fail or be skipped due to insufficient access rights.
|
||
|
||
## 🛡 Security
|
||
|
||
- `.htaccess` blocks direct access to internal logic.
|
||
- Only HTTPS connections should be used.
|
||
- Only `update.php` is directly accessible. All other access is routed through `index.php`.
|
||
- All access is name and token-authenticated
|
||
- IP addresses are blocked for 48 hours after 3 failed attempts
|
||
- API responses are intentionally generic to prevent brute-force probing
|
||
|
||
## 🔄 Usage Example from pfSense
|
||
You can create a cron task in pfSense or use a shell script to send updated IP info to the server:
|
||
|
||
```sh
|
||
#!/bin/sh
|
||
|
||
SERVER="https://your-server.com/ip2nginx"
|
||
NAME="domain1.to.com"
|
||
DOMAIN="domain.from.com"
|
||
TOKEN="YOUR_SECRET_TOKEN"
|
||
|
||
curl -s -X POST "$SERVER/update.php" \
|
||
-d "name=$NAME" \
|
||
-d "domain=$DOMAIN" \
|
||
-d "protocol=https" \
|
||
-d "port=443" \
|
||
-d "token=$TOKEN"
|
||
```
|
||
|
||
OR
|
||
|
||
curl -s -X POST "https://your-server.com/ip2nginx/update.php" "name=domain1.to.com" -d "token=SECRET_TOKEN_8v73jDKsdLzAq9DkeUz1" -d "protocol=https"
|
||
|
||
Add this script to pfSense via `System > Advanced > Cron` and run it every 5 or 10 minutes.
|
||
|
||
## ✅ Dependencies
|
||
|
||
- PHP 7.4+
|
||
- `nginx` installed with permissions to reload via `systemctl`
|
||
- `curl` for shell scripts (on client side)
|
||
- Token-based access configuration in `token.json`
|
||
|
||
## 📜 License
|
||
|
||
MIT or similar — free to use, modify, and deploy.
|
||
|
||
---
|
||
|
||
Created by **SAFE-CAP / https://safe-cap.com / Alexander Schiemann**
|