mirror of
git://f0xx.org/ac/ac-deploy
synced 2026-07-29 07:37:47 +03:00
added 'monitoring' path - ask devs why it's there
This commit is contained in:
52
monitoring/artc0/grafana-auth-check.php
Normal file
52
monitoring/artc0/grafana-auth-check.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* Grafana auth_request endpoint — nginx calls this to validate PHP session
|
||||
* before proxying to cast04:3000 (Grafana).
|
||||
*
|
||||
* If session is valid: HTTP 200 + X-WEBAUTH-USER header (username)
|
||||
* If not authenticated: HTTP 401 (nginx redirects to /app/androidcast_project/login)
|
||||
*
|
||||
* Deploy to: /var/www/localhost/htdocs/apps/app/androidcast_project/api/grafana-auth-check.php
|
||||
*/
|
||||
|
||||
// Only allow calls from nginx itself (127.0.0.1) — block direct browser access
|
||||
if (!in_array($_SERVER['REMOTE_ADDR'] ?? '', ['127.0.0.1', '::1'], true)) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Session handling — must match the main app's session settings
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_set_cookie_params([
|
||||
'path' => '/app/androidcast_project/',
|
||||
'secure' => isset($_SERVER['HTTPS']),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Check if user is logged in — Auth.php stores array in $_SESSION['user']
|
||||
// with at least { 'id' => int, 'username' => string, ... }
|
||||
$user = $_SESSION['user'] ?? null;
|
||||
|
||||
if (empty($user) || empty($user['id'])) {
|
||||
http_response_code(401);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Require full login (not just 2FA pending)
|
||||
if (isset($user['pending_2fa']) && $user['pending_2fa']) {
|
||||
http_response_code(401);
|
||||
exit;
|
||||
}
|
||||
|
||||
$username = (string)($user['username'] ?? $user['email'] ?? 'user_' . $user['id']);
|
||||
|
||||
// Sanitize — Grafana username must be a valid identifier
|
||||
$grafana_user = preg_replace('/[^a-zA-Z0-9._@-]/', '_', $username);
|
||||
|
||||
http_response_code(200);
|
||||
header('X-WEBAUTH-USER: ' . $grafana_user);
|
||||
header('Content-Type: text/plain');
|
||||
echo 'ok';
|
||||
53
monitoring/artc0/mysqld-exporter-docker.sh
Normal file
53
monitoring/artc0/mysqld-exporter-docker.sh
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
# Deploy mysqld_exporter as Docker container on artc0
|
||||
# Run once as root / sudo after creating the MariaDB monitoring user below.
|
||||
#
|
||||
# PREREQUISITE — run in mysql:
|
||||
# CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'ExporterPass2026!' WITH MAX_USER_CONNECTIONS 3;
|
||||
# GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
|
||||
# FLUSH PRIVILEGES;
|
||||
#
|
||||
# Then run this script.
|
||||
|
||||
set -e
|
||||
|
||||
CONTAINER_NAME="mysqld_exporter"
|
||||
CNF_FILE="/etc/mysqld-exporter.cnf"
|
||||
|
||||
# Write config file if not present
|
||||
if [ ! -f "$CNF_FILE" ]; then
|
||||
cat > "$CNF_FILE" << 'EOF'
|
||||
[client]
|
||||
user=exporter
|
||||
password=ExporterPass2026!
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
EOF
|
||||
chmod 644 "$CNF_FILE"
|
||||
fi
|
||||
|
||||
# Get socket GID to allow container user to access it
|
||||
SOCK_GID=$(stat -c '%g' /run/mysqld/mysqld.sock)
|
||||
|
||||
# Stop existing container if running
|
||||
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||
docker rm "$CONTAINER_NAME" 2>/dev/null || true
|
||||
|
||||
# Run with Unix socket mount — MariaDB uses skip-networking (no TCP)
|
||||
docker run -d \
|
||||
--name "$CONTAINER_NAME" \
|
||||
--restart unless-stopped \
|
||||
--user "65534:${SOCK_GID}" \
|
||||
-v "${CNF_FILE}:/etc/.my.cnf:ro" \
|
||||
-v "/run/mysqld/mysqld.sock:/run/mysqld/mysqld.sock:ro" \
|
||||
-p 9104:9104 \
|
||||
prom/mysqld-exporter:latest \
|
||||
--config.my-cnf=/etc/.my.cnf \
|
||||
--collect.info_schema.innodb_metrics \
|
||||
--collect.global_status \
|
||||
--collect.global_variables \
|
||||
--web.listen-address=":9104"
|
||||
|
||||
echo "mysqld_exporter started, listening on :9104"
|
||||
sleep 3
|
||||
docker logs "$CONTAINER_NAME" 2>&1 | tail -5
|
||||
curl -s http://localhost:9104/metrics | grep 'mysql_up'
|
||||
77
monitoring/artc0/nginx-monitor-location.conf
Normal file
77
monitoring/artc0/nginx-monitor-location.conf
Normal file
@@ -0,0 +1,77 @@
|
||||
# Grafana monitoring proxy — add inside the `server { listen 80; }` block in apps.conf
|
||||
# Place BEFORE the generic location /app/androidcast_project/ block.
|
||||
#
|
||||
# Access flow:
|
||||
# Browser → FE nginx (TLS) → artc0 BE nginx :80 → cast04:3000 (Grafana)
|
||||
# auth_request validates PHP session on each request.
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# ── Internal auth_request endpoint (not directly accessible) ────────────
|
||||
location = /app/androidcast_project/api/grafana-auth-check.php {
|
||||
internal;
|
||||
include fastcgi_params;
|
||||
fastcgi_pass unix:/run/php-fpm.socket;
|
||||
fastcgi_param SCRIPT_FILENAME /var/www/localhost/htdocs/apps/app/androidcast_project/api/grafana-auth-check.php;
|
||||
fastcgi_param SCRIPT_NAME /app/androidcast_project/api/grafana-auth-check.php;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
# Forward the original session cookie so the PHP script can read it
|
||||
fastcgi_param HTTP_COOKIE $http_cookie;
|
||||
}
|
||||
|
||||
# ── Redirect bare paths to trailing slash ────────────────────────────────
|
||||
location = /app/androidcast_project/monitor {
|
||||
return 301 /app/androidcast_project/monitor/;
|
||||
}
|
||||
|
||||
location = /app/androidcast_project/alertmanager {
|
||||
return 301 /app/androidcast_project/alertmanager/;
|
||||
}
|
||||
|
||||
# ── Alertmanager UI at cast04:9093 via auth_request ──────────────────────
|
||||
location /app/androidcast_project/alertmanager/ {
|
||||
auth_request /app/androidcast_project/api/grafana-auth-check.php;
|
||||
auth_request_set $grafana_user $upstream_http_x_webauth_user;
|
||||
error_page 401 = @monitor_login_redirect;
|
||||
|
||||
proxy_pass http://10.7.16.239:9093/;
|
||||
proxy_set_header Host $http_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_http_version 1.1;
|
||||
proxy_read_timeout 120;
|
||||
proxy_send_timeout 120;
|
||||
}
|
||||
|
||||
# ── Grafana at cast04:3000 via auth_request ───────────────────────────────
|
||||
location /app/androidcast_project/monitor/ {
|
||||
# Validate PHP session before allowing through
|
||||
auth_request /app/androidcast_project/api/grafana-auth-check.php;
|
||||
|
||||
# Capture username from auth response header and forward to Grafana
|
||||
auth_request_set $grafana_user $upstream_http_x_webauth_user;
|
||||
|
||||
# Redirect to login if not authenticated
|
||||
error_page 401 = @monitor_login_redirect;
|
||||
|
||||
proxy_pass http://10.7.16.239:3000/;
|
||||
proxy_set_header Host $http_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;
|
||||
# Pass authenticated user to Grafana auth proxy
|
||||
proxy_set_header X-WEBAUTH-USER $grafana_user;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_read_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
# WebSocket support (Grafana live)
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
}
|
||||
|
||||
# ── Login redirect for unauthenticated monitor access ────────────────────
|
||||
location @monitor_login_redirect {
|
||||
return 302 /app/androidcast_project/login?redirect=$request_uri;
|
||||
}
|
||||
Reference in New Issue
Block a user