465 lines
22 KiB
HTML
465 lines
22 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% set active_page = "index" %}
|
|
|
|
{% block title %}HAProxy • Configuration{% endblock %}
|
|
|
|
{% block breadcrumb %}Configuration{% endblock %}
|
|
|
|
{% block content %}
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-md-3">
|
|
<div class="card text-center shadow-sm">
|
|
<div class="card-body">
|
|
<h5 class="card-title text-primary">{{ frontend_count|default(0) }}</h5>
|
|
<p class="card-text"><i class="bi bi-diagram-2"></i> Frontends</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card text-center shadow-sm">
|
|
<div class="card-body">
|
|
<h5 class="card-title text-success">{{ backend_count|default(0) }}</h5>
|
|
<p class="card-text"><i class="bi bi-hdd-rack"></i> Backends</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card text-center shadow-sm">
|
|
<div class="card-body">
|
|
<h5 class="card-title text-warning">{{ acl_count|default(0) }}</h5>
|
|
<p class="card-text"><i class="bi bi-shield"></i> ACLs</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card text-center shadow-sm">
|
|
<div class="card-body">
|
|
<h5 class="card-title text-info">L7: {{ layer7_count|default(0) }} / L4: {{ layer4_count|default(0) }}</h5>
|
|
<p class="card-text"><i class="bi bi-layers"></i> Layers</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if message %}
|
|
<div class="alert alert-{{ message_type|default('info') }} alert-dismissible fade show" role="alert">
|
|
<i class="bi bi-{% if message_type == 'success' %}check-circle{% elif message_type == 'danger' %}exclamation-circle{% else %}info-circle{% endif %} me-2"></i>
|
|
{{ message }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<form method="post" class="needs-validation">
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header bg-primary text-white">
|
|
<h5 class="mb-0"><i class="bi bi-plus-circle me-2"></i>Add New Configuration</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
|
|
<!-- FRONTEND SECTION -->
|
|
<h6 class="text-primary mb-3"><i class="bi bi-hdd-network me-2"></i>Frontend</h6>
|
|
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-4">
|
|
<label for="frontend_name" class="form-label">Frontend Name</label>
|
|
<input type="text" class="form-control" id="frontend_name" name="frontend_name"
|
|
placeholder="e.g. fe_web" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label for="frontend_ip" class="form-label">IP Address (bind)</label>
|
|
<input type="text" class="form-control" id="frontend_ip" name="frontend_ip"
|
|
placeholder="0.0.0.0" value="0.0.0.0" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label for="frontend_port" class="form-label">Port</label>
|
|
<input type="number" class="form-control" id="frontend_port" name="frontend_port"
|
|
placeholder="80" min="1" max="65535" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-6">
|
|
<label for="protocol" class="form-label">Protocol</label>
|
|
<select class="form-select" id="protocol" name="protocol" required>
|
|
<option value="http">HTTP</option>
|
|
<option value="tcp">TCP</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label for="lb_method" class="form-label">Load Balancing Method</label>
|
|
<select class="form-select" id="lb_method" name="lb_method" required>
|
|
<option value="roundrobin">Round Robin</option>
|
|
<option value="leastconn">Least Connections</option>
|
|
<option value="source">Source IP Hash</option>
|
|
<option value="uri">URI Hash</option>
|
|
<option value="static-rr">Static Round Robin (WRR)</option>
|
|
<option value="no-lb">No Load Balancing (single host)</option>
|
|
</select>
|
|
<div class="form-text">Choose load balancing algorithm or simple single host</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-12">
|
|
<label for="frontend_hostname" class="form-label">Frontend Hostname (Domain)</label>
|
|
<input type="text" class="form-control" id="frontend_hostname" name="frontend_hostname"
|
|
placeholder="e.g. hosts.h.linuxiarz.pl" required>
|
|
<div class="form-text">Domain name for the ACL rule - traffic will be matched by Host header</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- SSL Section -->
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-12">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" id="ssl_checkbox" name="ssl_checkbox">
|
|
<label class="form-check-label" for="ssl_checkbox">
|
|
<i class="bi bi-lock me-1"></i>Use SSL (HTTPS)
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3 mb-3 d-none" id="ssl_fields">
|
|
<div class="col-md-12">
|
|
<label for="ssl_cert_path" class="form-label">SSL Certificate Path</label>
|
|
<small>Upload certs in /ssl/</small>
|
|
<input type="text" class="form-control" id="ssl_cert_path" name="ssl_cert_path"
|
|
value="/app/ssl/haproxy-configurator.pem">
|
|
<div class="form-text">Full path to .pem file</div>
|
|
</div>
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="ssl_redirect_checkbox"
|
|
name="ssl_redirect_checkbox">
|
|
<label class="form-check-label" for="ssl_redirect_checkbox">
|
|
Redirect HTTP to HTTPS
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<!-- BACKEND SECTION -->
|
|
<h6 class="text-primary mb-3"><i class="bi bi-hdd-rack me-2"></i>Backend</h6>
|
|
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-12">
|
|
<label for="backend_name" class="form-label">Backend Name</label>
|
|
<input type="text" class="form-control" id="backend_name" name="backend_name"
|
|
placeholder="e.g. be_web" required>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Backend servers -->
|
|
<div class="mb-3">
|
|
<label class="form-label">Backend Servers</label>
|
|
<div id="backend_servers_container">
|
|
<div class="row g-3 backend-server-row">
|
|
<div class="col-md-3">
|
|
<input type="text" class="form-control" name="backend_server_names[]"
|
|
placeholder="server1" value="server1" required>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<input type="text" class="form-control" name="backend_server_ips[]"
|
|
placeholder="192.168.1.10" required>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<input type="number" class="form-control" name="backend_server_ports[]"
|
|
placeholder="80" min="1" max="65535" required>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<input type="number" class="form-control" name="backend_server_maxconns[]"
|
|
placeholder="100">
|
|
</div>
|
|
<div class="col-md-1">
|
|
<button type="button" class="btn btn-danger btn-sm w-100 remove-server" style="visibility: hidden;">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button type="button" class="btn btn-secondary btn-sm mt-2" id="add_backend_btn">
|
|
<i class="bi bi-plus-lg me-1"></i>Add Server
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Health Check -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="health_check" name="health_check">
|
|
<label class="form-check-label" for="health_check">
|
|
<i class="bi bi-heart-pulse me-1"></i>Enable Health Check
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12 d-none" id="health_check_fields">
|
|
<label for="health_check_link" class="form-label">Health Check Path</label>
|
|
<input type="text" class="form-control" id="health_check_link" name="health_check_link"
|
|
value="/" placeholder="/">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3 mb-3" style="display: none;" id="tcp_health_check">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="health_check2" name="health_check2">
|
|
<label class="form-check-label" for="health_check2">
|
|
<i class="bi bi-heart-pulse me-1"></i>Enable TCP Health Check
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sticky Session -->
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="sticky_session" name="sticky_session">
|
|
<label class="form-check-label" for="sticky_session">
|
|
<i class="bi bi-pin-angle me-1"></i>Sticky Session
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-12 d-none" id="sticky_fields">
|
|
<select class="form-select" id="sticky_session_type" name="sticky_session_type">
|
|
<option value="cookie">Cookie-based</option>
|
|
<option value="source">Source IP-based</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<!-- HEADERS & SECURITY SECTION -->
|
|
<h6 class="text-primary mb-3"><i class="bi bi-shield-lock me-2"></i>Headers & Security</h6>
|
|
|
|
<!-- Custom Headers -->
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="add_header" name="add_header">
|
|
<label class="form-check-label" for="add_header">
|
|
<i class="bi bi-tag me-1"></i>Add Custom Header
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 d-none" id="header_fields">
|
|
<input type="text" class="form-control" id="header_name" name="header_name"
|
|
placeholder="e.g. X-Custom-Header">
|
|
</div>
|
|
<div class="col-md-6 d-none" id="header_fields">
|
|
<input type="text" class="form-control" id="header_value" name="header_value"
|
|
placeholder="e.g. custom-value">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Server Header Removal -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="del_server_header"
|
|
name="del_server_header">
|
|
<label class="form-check-label" for="del_server_header">
|
|
<i class="bi bi-shield-lock me-1"></i>Hide Server Header
|
|
</label>
|
|
<div class="form-text small">
|
|
Adds: <code>http-response del-header Server</code> (security)
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Forward For -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="forward_for_check"
|
|
name="forward_for_check" checked>
|
|
<label class="form-check-label" for="forward_for_check">
|
|
<i class="bi bi-arrow-right me-1"></i>Forward For (X-Forwarded-For)
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<!-- PROTECTION SECTION -->
|
|
<h6 class="text-primary mb-3"><i class="bi bi-bug me-2"></i>Protection</h6>
|
|
|
|
<!-- DOS Protection -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="add_dos" name="add_dos">
|
|
<label class="form-check-label" for="add_dos">
|
|
<i class="bi bi-exclamation-triangle me-1"></i>DOS/DDoS Protection
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 d-none" id="dos_fields">
|
|
<label for="ban_duration" class="form-label">Ban Duration</label>
|
|
<input type="text" class="form-control" id="ban_duration" name="ban_duration"
|
|
value="30m" placeholder="30m">
|
|
<div class="form-text">e.g. 30m, 1h, 24h</div>
|
|
</div>
|
|
<div class="col-md-6 d-none" id="dos_fields">
|
|
<label for="limit_requests" class="form-label">Request Limit (per min)</label>
|
|
<input type="number" class="form-control" id="limit_requests" name="limit_requests"
|
|
value="100" min="1">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SQL Injection -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="sql_injection_check"
|
|
name="sql_injection_check">
|
|
<label class="form-check-label" for="sql_injection_check">
|
|
<i class="bi bi-database-exclamation me-1"></i>SQL Injection Protection
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- XSS -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="xss_check" name="xss_check">
|
|
<label class="form-check-label" for="xss_check">
|
|
<i class="bi bi-code-slash me-1"></i>XSS Protection
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Remote Uploads -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="remote_uploads_check"
|
|
name="remote_uploads_check">
|
|
<label class="form-check-label" for="remote_uploads_check">
|
|
<i class="bi bi-cloud-upload me-1"></i>Block Remote Uploads
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Webshells -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="webshells_check"
|
|
name="webshells_check">
|
|
<label class="form-check-label" for="webshells_check">
|
|
<i class="bi bi-shield-exclamation me-1"></i>Block Webshells
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<!-- ACL SECTION -->
|
|
<h6 class="text-primary mb-3"><i class="bi bi-diagram-3 me-2"></i>ACL & Routing</h6>
|
|
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="add_acl" name="add_acl">
|
|
<label class="form-check-label" for="add_acl">
|
|
<i class="bi bi-shuffle me-1"></i>Add ACL
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 d-none" id="acl_fields">
|
|
<input type="text" class="form-control" id="acl" name="acl" placeholder="acl_name">
|
|
</div>
|
|
<div class="col-md-4 d-none" id="acl_fields">
|
|
<select class="form-select" id="acl_action" name="acl_action">
|
|
<option value="hdr">Header</option>
|
|
<option value="path">Path</option>
|
|
<option value="src">Source IP</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4 d-none" id="acl_fields">
|
|
<input type="text" class="form-control" id="backend_name_acl" name="backend_name_acl"
|
|
placeholder="backend_name">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Path-based routing -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="add_path_based" name="add_path_based">
|
|
<label class="form-check-label" for="add_path_based">
|
|
<i class="bi bi-arrow-repeat me-1"></i>Path-based Redirect
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 d-none" id="base_redirect_fields">
|
|
<input type="text" class="form-control" id="redirect_domain_name" name="redirect_domain_name"
|
|
placeholder="domain.com">
|
|
</div>
|
|
<div class="col-md-4 d-none" id="base_redirect_fields">
|
|
<input type="text" class="form-control" id="root_redirect" name="root_redirect"
|
|
placeholder="/">
|
|
</div>
|
|
<div class="col-md-4 d-none" id="base_redirect_fields">
|
|
<input type="text" class="form-control" id="redirect_to" name="redirect_to"
|
|
placeholder="https://example.com">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Forbidden paths -->
|
|
<div class="row g-3 mb-3 http-only">
|
|
<div class="col-md-12">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="add_acl_path" name="add_acl_path">
|
|
<label class="form-check-label" for="add_acl_path">
|
|
<i class="bi bi-ban me-1"></i>Block Paths
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 d-none" id="forbidden_fields">
|
|
<input type="text" class="form-control" id="forbidden_name" name="forbidden_name"
|
|
placeholder="forbidden_acl">
|
|
</div>
|
|
<div class="col-md-4 d-none" id="forbidden_fields">
|
|
<input type="text" class="form-control" id="allowed_ip" name="allowed_ip"
|
|
placeholder="192.168.1.0/24">
|
|
</div>
|
|
<div class="col-md-4 d-none" id="forbidden_fields">
|
|
<input type="text" class="form-control" id="forbidden_path" name="forbidden_path"
|
|
placeholder="/admin">
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<!-- SUBMIT BUTTON -->
|
|
<div class="d-grid gap-2">
|
|
<button type="submit" class="btn btn-primary btn-lg">
|
|
<i class="bi bi-check-circle me-2"></i>Save Configuration
|
|
</button>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<script src="{{ url_for('static', filename='js/index.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/form.js') }}"></script>
|
|
|
|
{% endblock %}
|