Initial commit: SSL proxy / firewall appliance
Flask WebUI behind nginx reverse proxy with zone-based firewall, DHCP, WireGuard, and ACME certificate management.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Dashboard - Vacuum Wall{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1>Dashboard</h1>
|
||||
<div class="subtitle">System overview and status</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-grid">
|
||||
<div class="stat-card">
|
||||
<div class="label">Zones</div>
|
||||
<div class="value">{{ zones|default([])|length }}</div>
|
||||
<div class="meta">Firewalld zones configured</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="label">Proxy Domains</div>
|
||||
<div class="value">{{ domains|default([])|length }}</div>
|
||||
<div class="meta">SSL-terminated backends</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="label">Certificates</div>
|
||||
<div class="value">{{ certs|default([])|length }}</div>
|
||||
{% set expired = certs|selectattr('expired')|list|default([])|length %}
|
||||
{% set expiring = certs|selectattr('days_remaining','le',30)|rejectattr('expired')|list|default([])|length %}
|
||||
<div class="meta">
|
||||
{% if expired > 0 %}<span style="color:var(--danger)">{{ expired }} expired</span>. {% endif %}
|
||||
{% if expiring > 0 %}<span style="color:var(--warning)">{{ expiring }} expiring soon</span>.{% endif %}
|
||||
{% if expired == 0 and expiring == 0 %}All valid{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="label">WireGuard</div>
|
||||
<div class="value" style="font-size:20px;">
|
||||
<span class="status-dot {{ 'status-up' if (wg_status is defined and wg_status.get('state') == 'up') else 'status-down' }}"></span>
|
||||
{{ 'UP' if (wg_status is defined and wg_status.get('state') == 'up') else 'DOWN' }}
|
||||
</div>
|
||||
<div class="meta">Tunnel state</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="label">Active Leases</div>
|
||||
<div class="value">{{ leases|default([])|length }}</div>
|
||||
<div class="meta">DHCP clients connected</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-title">Services</div>
|
||||
|
||||
<div class="card-grid">
|
||||
{% for svc_name, svc in (services or {}).items() %}
|
||||
<div class="stat-card">
|
||||
<div class="label">{{ svc_name }}</div>
|
||||
<div class="value" style="font-size:16px;">
|
||||
<span class="status-dot {{ 'status-up' if svc.get('running') else 'status-down' }}"></span>
|
||||
{{ 'Running' if svc.get('running') else 'Stopped' }}
|
||||
</div>
|
||||
<div class="meta">
|
||||
{% if svc.get('pid') %}PID {{ svc.pid }}{% endif %}
|
||||
{% if svc.get('since') %} · {{ svc.since }}{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if not (services or {}) %}
|
||||
<div class="stat-card">
|
||||
<div class="label">Firewalld</div>
|
||||
<div class="value" style="font-size:16px;">
|
||||
<span class="status-dot status-up"></span>Running
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="label">Dnsmasq</div>
|
||||
<div class="value" style="font-size:16px;">
|
||||
<span class="status-dot status-up"></span>Running
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="label">Nginx</div>
|
||||
<div class="value" style="font-size:16px;">
|
||||
<span class="status-dot status-up"></span>Running
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="label">wg0</div>
|
||||
<div class="value" style="font-size:16px;">
|
||||
<span class="status-dot {{ 'status-up' if (wg_status is defined and wg_status.get('state') == 'up') else 'status-down' }}"></span>
|
||||
{{ 'Up' if (wg_status is defined and wg_status.get('state') == 'up') else 'Down' }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% set warnings = [] %}
|
||||
{% if certs is defined %}
|
||||
{% for cert in certs %}
|
||||
{% if cert.get('expired') %}
|
||||
{% set _ = warnings.append("Certificate for " + cert.get('domain', 'unknown') + " has expired") %}
|
||||
{% elif cert.get('days_remaining') is not none and cert.days_remaining <= 30 %}
|
||||
{% set _ = warnings.append("Certificate for " + cert.get('domain', 'unknown') + " expires in " + cert.days_remaining|string + " days") %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if warnings|length > 0 or (services is defined) %}
|
||||
<div class="section-title">Warnings & Activity</div>
|
||||
|
||||
<div class="card">
|
||||
{% if warnings|length > 0 %}
|
||||
<ul class="service-list">
|
||||
{% for w in warnings %}
|
||||
<li>
|
||||
<span class="status-dot status-pending"></span>
|
||||
<span class="svc-name">{{ w }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if not warnings and not (services or {}) %}
|
||||
<div class="text-muted text-sm">No warnings</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user