1
This commit is contained in:
commit
885ec7e678
12
Dockerfile.bridge
Normal file
12
Dockerfile.bridge
Normal file
@ -0,0 +1,12 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN pip install --no-cache-dir flask gunicorn
|
||||
|
||||
COPY app.py .
|
||||
COPY mapping.json .
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["gunicorn", "--bind", "0.0.0.0:3000", "app:app"]
|
||||
67
app.py
Normal file
67
app.py
Normal file
@ -0,0 +1,67 @@
|
||||
import json
|
||||
import os
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from flask import Flask, request, jsonify
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
KUMA_BASE_URL = os.getenv("KUMA_BASE_URL", "http://localhost:3001/api/push")
|
||||
MAPPING_FILE = os.getenv("MAPPING_FILE", "mapping.json")
|
||||
# Shared secret for authentication
|
||||
WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET", "super-secret-key-change-me")
|
||||
|
||||
def load_mapping():
|
||||
if not os.path.exists(MAPPING_FILE):
|
||||
return {}
|
||||
try:
|
||||
with open(MAPPING_FILE, "r") as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Failed to parse {MAPPING_FILE}: {e}")
|
||||
return {}
|
||||
|
||||
@app.route("/webhook/ppp", methods=["POST"])
|
||||
def ppp_webhook():
|
||||
# 1. Validate Secret Token in Header
|
||||
auth_header = request.headers.get("X-API-Key")
|
||||
if not auth_header or auth_header != WEBHOOK_SECRET:
|
||||
print(f"[WARN] Unauthorized webhook attempt from IP: {request.remote_addr}")
|
||||
return jsonify({"status": "error", "message": "Unauthorized"}), 401
|
||||
|
||||
data = request.get_json(silent=True) or {}
|
||||
|
||||
user = data.get("user")
|
||||
status = data.get("status")
|
||||
ip = data.get("ip", "0.0.0.0")
|
||||
msg = data.get("msg", "")
|
||||
ping = data.get("ping", 0)
|
||||
|
||||
if not user or not status:
|
||||
return jsonify({"status": "error", "message": "Missing required fields"}), 400
|
||||
|
||||
mapping = load_mapping()
|
||||
token = mapping.get(user)
|
||||
|
||||
if not token:
|
||||
print(f"[WARN] No token found for user: '{user}'")
|
||||
return jsonify({"status": "ignored", "message": f"User '{user}' not mapped."}), 404
|
||||
|
||||
kuma_status = "up" if str(status).lower() == "up" else "down"
|
||||
if not msg:
|
||||
msg = f"PPP status is {kuma_status.upper()} for user '{user}' ({ip})"
|
||||
|
||||
encoded_msg = urllib.parse.quote(msg)
|
||||
kuma_url = f"{KUMA_BASE_URL}/{token}?status={kuma_status}&msg={encoded_msg}&ping={ping}"
|
||||
|
||||
try:
|
||||
req = urllib.request.Request(kuma_url, headers={"User-Agent": "MikroTik-Bridge/1.0"})
|
||||
with urllib.request.urlopen(req, timeout=5) as resp:
|
||||
print(f"[INFO] Forwarded push for '{user}' -> status: {kuma_status}")
|
||||
return jsonify({"status": "success"}), 200
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Failed to contact Uptime Kuma: {e}")
|
||||
return jsonify({"status": "error", "message": str(e)}), 500
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=3000)
|
||||
42
docker-compose-with-uptime.yml
Normal file
42
docker-compose-with-uptime.yml
Normal file
@ -0,0 +1,42 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# Uptime Kuma Monitoring Service
|
||||
uptime-kuma:
|
||||
image: louislam/uptime-kuma:1
|
||||
container_name: uptime-kuma
|
||||
restart: always
|
||||
ports:
|
||||
- "3001:3001"
|
||||
volumes:
|
||||
- kuma-data:/app/data
|
||||
networks:
|
||||
- kuma-net
|
||||
|
||||
# MikroTik to Uptime Kuma Python Webhook Bridge
|
||||
mikrotik-bridge:
|
||||
build:
|
||||
context: ./bridge
|
||||
dockerfile: Dockerfile
|
||||
container_name: mikrotik-kuma-bridge
|
||||
restart: always
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
# Internal Docker network URL pointing to the Uptime Kuma service container
|
||||
- KUMA_BASE_URL=http://uptime-kuma:3001/api/push
|
||||
- MAPPING_FILE=mapping.json
|
||||
volumes:
|
||||
# Mount mapping.json so you can edit tokens on the host without rebuilding the container
|
||||
- ./bridge/mapping.json:/app/mapping.json:ro
|
||||
depends_on:
|
||||
- uptime-kuma
|
||||
networks:
|
||||
- kuma-net
|
||||
|
||||
networks:
|
||||
kuma-net:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
kuma-data:
|
||||
15
docker-compose.yml
Normal file
15
docker-compose.yml
Normal file
@ -0,0 +1,15 @@
|
||||
services:
|
||||
mikrotik-bridge:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: Dockerfile.bridge
|
||||
container_name: mikrotik-kuma-bridge
|
||||
restart: always
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- KUMA_BASE_URL=http://uptime-kuma:3001/api/push
|
||||
- MAPPING_FILE=mapping.json
|
||||
- WEBHOOK_SECRET=MySuperSecretToken123!
|
||||
volumes:
|
||||
- ./bridge/mapping.json:/app/mapping.json:ro
|
||||
6
mapping.json
Normal file
6
mapping.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"john_doe": "A1b2C3d4E5",
|
||||
"branch_office_vpn": "F6g7H8i9J0",
|
||||
"site2site_tunnel": "K1l2M3n4O5",
|
||||
"admin_laptop": "P6q7R8s9T0"
|
||||
}
|
||||
19
mikrotik-script-examples.rsc
Normal file
19
mikrotik-script-examples.rsc
Normal file
@ -0,0 +1,19 @@
|
||||
# --- Define Local Variables ---
|
||||
:local status "up"
|
||||
:local serverUrl "http://localhost/webhook-test.php"
|
||||
:local apiKey "MySuperSecretToken123!"
|
||||
|
||||
# --- Fetch PPP System Variables safely ---
|
||||
:local u $"user"
|
||||
:local lip $"local-address"
|
||||
:local rip $"remote-address"
|
||||
:local cid $"caller-id"
|
||||
:local iface $"interface"
|
||||
|
||||
:local msg ("PPP session " . $status . " on interface " . $iface)
|
||||
|
||||
# --- Construct JSON Body ---
|
||||
:local jsonBody "{\"user\":\"$u\", \"local_ip\":\"$lip\", \"ip\":\"$rip\", \"caller_id\":\"$cid\", \"interface\":\"$iface\", \"status\":\"$status\", \"msg\":\"$msg\"}"
|
||||
|
||||
# --- Send Webhook ---
|
||||
/tool fetch url=$serverUrl http-method=post http-header-field="Content-Type: application/json,X-API-Key: $apiKey" http-data=$jsonBody keep-result=no
|
||||
10
testing.sh
Normal file
10
testing.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
curl -X POST http://localhost:3000/webhook/ppp \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: MySuperSecretToken123!" \
|
||||
-d '{
|
||||
"user": "john_doe",
|
||||
"ip": "10.0.0.5",
|
||||
"status": "up"
|
||||
}'
|
||||
Loading…
x
Reference in New Issue
Block a user