237 lines
7.8 KiB
Markdown
237 lines
7.8 KiB
Markdown
# ip2nginx
|
||
<p align="center">
|
||
<a href="https://safe-cap.com/" target="_blank">
|
||
<img src="https://safe-cap.com/git/safe-cap-logo.png" width="100" height="100";>
|
||
</a>
|
||
<br><br>
|
||
<img src="https://img.shields.io/badge/version-0.0.1-green.svg?style=for-the-badge">
|
||
<a href="https://www.paypal.com/donate/?hosted_button_id=JNFS79EFEM7C6" target="_blank">
|
||
<img src="https://img.shields.io/badge/Donate-PayPal-blue.svg?style=for-the-badge">
|
||
</a>
|
||
</p>
|
||
|
||
---
|
||
|
||
## 💡 Project Overview
|
||
|
||
**ip2nginx** is a lightweight and secure system for dynamically updating NGINX reverse proxy configurations based on public IP address changes, typically reported by edge devices like **pfSense**. It ensures that NGINX always routes traffic through the correct IP, even in dynamic environments.
|
||
|
||
---
|
||
|
||
<!-- TOC -->
|
||
## 📚 Table of Contents
|
||
|
||
- [💡 Project Overview](#-project-overview)
|
||
- [🏠 What is ip2nginx?](#-what-is-ip2nginx)
|
||
- [💡 Example Use Case](#-example-use-case)
|
||
- [⚙️ Features](#-features)
|
||
- [📁 Project Structure](#-project-structure)
|
||
- [🚀 Update Process: update.php](#-remote-update-api-updatephp)
|
||
- [🚀 Update Process: updater.php](#-update-process-updaterphp)
|
||
- [🛠 Environment Setup: check_env.php](#-check_envphp-environment-setup)
|
||
- [📅 Cron Setup with run.sh](#-cron-setup-runsh)
|
||
- [🔄 Usage Example from pfSense](#-pfsense-shell-example)
|
||
- [✅ Example Entry in token.json](#-example-tokenjson)
|
||
- [✅ Example Entry in meta.json](#-example-metajson)
|
||
- [🛡 Security](#-security-highlights)
|
||
- [✅ Requirements](#-requirements)
|
||
- [📜 License](#-license)
|
||
- [🤝 Author](#-author)
|
||
<!-- /TOC -->
|
||
|
||
---
|
||
|
||
## 🏠 What is ip2nginx?
|
||
|
||
ip2nginx is a self-hosted system that allows you to make services running on your home network (like a NAS, internal web apps, or router interface) accessible under your own domain — even if your public IP address changes.
|
||
|
||
Unlike third-party solutions other dynamic DNS providers, this tool gives you full control and privacy by updating your reverse proxy configuration directly, without modifying DNS records or relying on external providers.
|
||
|
||
How It Works:
|
||
|
||
Your home device (e.g. pfSense or another gateway) periodically sends its current public IP to your server via an API request.
|
||
|
||
The server updates the reverse proxy configuration (nginx.conf) with the new IP.
|
||
|
||
The proxy_pass directive is updated inside the specific location block for the target domain.
|
||
|
||
NGINX is reloaded automatically to apply changes.
|
||
|
||
---
|
||
|
||
## 💡 Example Use Case
|
||
You want to host https://home.example.com and route it to a web interface at your home (like pfSense or a Raspberry Pi), but your IP changes regularly due to your ISP.
|
||
|
||
With ip2nginx, the server automatically updates the NGINX reverse proxy so your domain continues working — securely and without dynamic DNS services.
|
||
|
||
---
|
||
|
||
## ⚙️ Features
|
||
|
||
- Accepts remote updates via `update.php` using **token-authenticated** requests.
|
||
- Supports both `POST` and `GET`, though **POST is preferred** to avoid token caching.
|
||
- Updates only the `proxy_pass` line in the relevant `location` block of `nginx.conf`.
|
||
- Automatically marks entries in `meta.json` as `"changed": 1` when input changes.
|
||
- Logs all changes to `log.json` with timestamps.
|
||
- Automatically reloads NGINX: `nginx -t && systemctl reload nginx` (requires root).
|
||
- Built-in abuse protection: failed requests tracked and blocked.
|
||
- `.htaccess` ensures that only `update.php` is externally accessible.
|
||
|
||
---
|
||
|
||
## 📁 Project Structure
|
||
|
||
```
|
||
ip2nginx/
|
||
├── index.php # Shared configuration and fallback error handler
|
||
├── update.php # Receives incoming remote IP update requests
|
||
├── updater.php # CLI-only: applies changes to nginx.conf if marked
|
||
├── run.sh # Wrapper script for cron automation
|
||
├── check_env.php # Environment validator and bootstrapper
|
||
├── .htaccess # Blocks unauthorized access, routes traffic
|
||
├── data/
|
||
│ ├── meta.json # Stores current configuration state per domain
|
||
│ ├── token.json # Stores allowed tokens (auth)
|
||
│ ├── log.json # Stores audit log of changes
|
||
│ ├── blocklist.json # Temporarily blocked IPs (48h ban)
|
||
│ └── failures.json # Tracks failed attempts per IP
|
||
```
|
||
|
||
---
|
||
|
||
## 🌐 Remote Update API: `update.php`
|
||
|
||
Supports **POST** (preferred) and **GET** methods.
|
||
|
||
| Parameter | Required | Description |
|
||
|------------|----------|-----------------------------------------------------------------------------|
|
||
| `name` | ✅ | Identifier (e.g. `domain1.to.com`) |
|
||
| `token` | ✅ | Secret token assigned for this name |
|
||
| `ip` | ❌ | New public IP (default: auto-detected from request) |
|
||
| `domain` | ❌ | Backend domain to proxy to (default: same as IP) |
|
||
| `port` | ❌ | Port number (default: 443 for https, 80 for http) |
|
||
| `protocol` | ❌ | One of `http` or `https` (default: `http`) |
|
||
| `location` | ❌ | NGINX location block path to update (default: `/`) |
|
||
|
||
Any change in `ip`, `domain`, `port`, or `protocol` triggers `"changed": 1` in `meta.json`.
|
||
|
||
If **any parameter is received via GET**, then `ip` and `domain` will be overridden with the **client’s real IP** for security.
|
||
|
||
---
|
||
|
||
## 🧩 Update Process: `updater.php`
|
||
|
||
To apply updates made via `update.php`:
|
||
|
||
1. Load all entries from `meta.json`
|
||
2. Check for entries marked `"changed": 1`
|
||
3. Find `/var/www/vhosts/system/<domain>/conf/nginx.conf`
|
||
4. Modify the appropriate `location` block’s `proxy_pass` directive only
|
||
5. Validate and reload NGINX
|
||
6. Reset `"changed": 0`
|
||
|
||
---
|
||
|
||
## 🛠 `check_env.php`: Environment Setup
|
||
|
||
This CLI script validates:
|
||
|
||
- Config files and permissions
|
||
- JSON structure of each config file
|
||
- Auto-creates missing files (with defaults)
|
||
- Token file includes example if missing
|
||
|
||
---
|
||
|
||
## ⏱ Cron Setup: `run.sh`
|
||
|
||
To automate updates, add `run.sh` to your crontab as root:
|
||
|
||
```sh
|
||
sudo crontab -e
|
||
```
|
||
|
||
Then add:
|
||
|
||
```cron
|
||
*/5 * * * * /path/to/ip2nginx/run.sh
|
||
```
|
||
|
||
This ensures automatic application of proxy changes to NGINX config and reloads.
|
||
|
||
---
|
||
|
||
## 🔄 pfSense Shell Example
|
||
|
||
Add the following script to `pfSense` via `System > Advanced > Cron`:
|
||
|
||
```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"
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ Example: `token.json`
|
||
|
||
```json
|
||
{
|
||
"domain1.to.com": "SECRET_TOKEN_8v73jDKsdLzAq9DkeUz1",
|
||
"domain2.to.com": "SECRET_TOKEN_3im83jUj28mjo2mI23un"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ Example: `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
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🔒 Security Highlights
|
||
|
||
- `.htaccess` denies access to all files except `update.php`.
|
||
- Only HTTPS connections should be used.
|
||
- All tokens are stored securely and verified per name.
|
||
- After 3 failed attempts, IP is banned for 48 hours.
|
||
- Generic error messages avoid leaking details to attackers.
|
||
|
||
---
|
||
|
||
## ✅ Requirements
|
||
|
||
- PHP 7.4 or newer
|
||
- NGINX with reload access (`sudo systemctl reload nginx`)
|
||
- `curl` on the client side
|
||
- Token definitions in `token.json`
|
||
|
||
---
|
||
|
||
## 📜 License
|
||
|
||
MIT (or similar): Open-source, free for use and modification.
|
||
|
||
---
|
||
|
||
## 🤝 Author
|
||
|
||
**Maintained by [SAFE-CAP / Alexander Schiemann](https://safe-cap.com)** |