# MikroTik Proxy API Dashboard A modern, secure web interface and proxy API for managing MikroTik Firewall Address Lists. Designed for remote control with IP identification and administrative management. ## 🌟 Key Features - **JWT Authentication**: Secure administrative access with username/password hashing. - **Structured List Management**: Define named lists (e.g., `trusted`, `guests`) and assign IPs via a strict interface. - **Client Dashboard**: Pure IP-based identification for end-users to toggle their own access status. - **Glassmorphism UI**: Premium, responsive interface using modern CSS and the "Outfit" typography. - **SQLite Integration**: Local source of truth for synchronization consistency. --- ## 🏗 Architecture ```mermaid graph TD Client[End-User Browser] -->|IP Auth| API[Flask Proxy] Admin[Admin Browser] -->|JWT Auth| API API --> DB[(SQLite DB)] API --> MT[MikroTik RouterOS] ``` --- ## ⚙️ Configuration Copy `.env.example` to `.env` and fill in your details: | Variable | Description | | :--- | :--- | | `MT_HOST` | MikroTik Router IP/Hostname | | `MT_USER` | MikroTik API User | | `MT_PASS` | MikroTik API Password | | `APP_SECRET_KEY` | Key for signing JWT tokens | | `ADMIN_PASS` | Initial password for the `admin` user | --- ## 🚀 Installation & Deployment ### 1. Requirements - Python 3.8+ - `pip install -r requirements.txt` ### 2. Running as a Service #### **Alpine Linux (OpenRC)** Create `/etc/init.d/mt-proxy`: ```bash #!/sbin/openrc-run description="MikroTik Proxy API" command="/usr/bin/python3" command_args="/path/to/app/main.py" command_background="yes" pidfile="/run/mt-proxy.pid" directory="/path/to/app" environment="PYTHONPATH=/path/to/app" depend() { need net } ``` `chmod +x /etc/init.d/mt-proxy && rc-update add mt-proxy default && rc-service mt-proxy start` #### **Debian / Ubuntu (systemd)** Create `/etc/systemd/system/mt-proxy.service`: ```ini [Unit] Description=MikroTik Proxy API After=network.target [Service] User=www-data WorkingDirectory=/var/www/mt-proxy Environment="PATH=/var/www/mt-proxy/venv/bin" ExecStart=/var/www/mt-proxy/venv/bin/python main.py Restart=always [Install] WantedBy=multi-user.target ``` `systemctl enable mt-proxy && systemctl start mt-proxy` --- ## 🌐 Nginx Reverse Proxy To access the API on port 80/443: ```nginx server { listen 80; server_name proxy.example.com; location / { proxy_pass http://127.0.0.1:5001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } ``` --- ## 🛠 API Documentation ### 1. Authentication *Used to obtain a JWT token for administrative actions.* **POST** `/api/v1/auth/login` - **Body**: `{"username": "admin", "password": "..."}` - **Success (200)**: ```json { "success": true, "data": { "token": "ey..." } } ``` - **Error (401)**: `{"success": false, "error": "Invalid credentials"}` --- ### 2. Administrative API (Protected) *Required Header: `Authorization: Bearer `* #### **Address Assignments** - **GET** `/api/v1/addresses`: List all IP assignments. - **Success**: `{"success": true, "data": [{"id": 1, "ip": "1.2.3.4", "list_name": "trusted", "enabled": true, ...}]}` - **POST** `/api/v1/addresses`: Assign IP to a list. - **Body**: `{"address": "1.2.3.4", "list": "trusted", "comment": "Work PC"}` - **Success (201)**: `{"success": true, "data": {"mikrotik_id": "*1A"}}` - **DELETE** `/api/v1/addresses/`: Remove assignment. - **PUT** `/api/v1/addresses//enable`: Activate IP. - **PUT** `/api/v1/addresses//disable`: Deactivate IP. #### **Named Lists Management** - **GET** `/api/v1/named-lists`: List all managed address lists. - **Success**: `{"success": true, "data": [{"id": 1, "name": "trusted"}, {"id": 2, "name": "guests"}]}` - **POST** `/api/v1/named-lists`: Create a new list name. - **Body**: `{"name": "office_vpn"}` - **DELETE** `/api/v1/named-lists/`: Remove list definition. - **Error (400)**: `{"success": false, "error": "Cannot delete: 5 addresses are still in this list"}` #### **Profile Management** - **POST** `/api/v1/admin/profile`: Update your credentials. - **Body**: `{"username": "new_admin", "password": "new_password"}` (password optional) --- ### 3. Client Dashboard API (No Auth) *Determines status based on the calling user's public IP.* #### **Check Status** - **GET** `/api/v1/client/status` - **Success (200)**: ```json { "success": true, "data": { "ip": "82.202.10.5", "enabled": true, "list": "trusted", "comment": "Home Office" } } ``` - **Forbidden (403)**: `{"success": false, "error": "Access denied for IP 8.8.8.8"}` (IP not in any whitelist) #### **Toggle Status** - **PUT** `/api/v1/client/toggle` - **Success**: `{"success": true, "data": {"new_state": false}}` --- ## 🔍 Architecture & Sync Details - **Master Database**: SQLite is the source of truth. Changes are committed to DB *before* calling the MikroTik API to ensure consistency. - **MikroTik Sync**: The proxy uses the native MikroTik API (`/ip/firewall/address-list/set`) using internal IDs for high performance. - **Security**: Admin passwords are salted and hashed using PBKDF2. JWT tokens expire after 24 hours. ## 📜 Maintenance - **Primary Admin**: Created automatically on first run using values from `.env`. - **Logs**: Standard output. On Alpine/Debian, use `logread` or `journalctl -u mt-proxy`.