4a1d949e41
完整 Web 管理平台,涵盖: P0 生产加固: - 会话超时(空闲+绝对) + CSRF 防护 + 登录失败限流 - HTTPS/TLS 证书管理(自签生成/上传/删除/过期提醒) - SSL Bump (HTTPS 透明代理) 可视化配置 - 配置文件 diff 预览 + 二次确认才写入 - 服务控制二次确认 + 操作期间按钮锁定 P1 运维能力: - 日志轮转管理(logrotate) + 日志状态监控 - 告警规则(5xx/命中率/磁盘/客户端流量) - 多 Squid 实例管理 + 一键切换 - squidclient mgr 实时性能指标 - 流量异常检测(突增/大文件/高频小包/新客户端) P2 日志分析增强: - 日志持久化到 SQLite + 历史时间范围查询 - 导出 CSV/JSON(日志/KPI/异常/审计) - GeoIP 地图(Leaflet + ip-api.com 离线可选 GeoLite2) - 每客户端 24h 趋势图 - 自定义 Squid logformat 解析器 P3 体验锦上添花: - 暗/亮主题切换(cookie 持久化) - WebSSH 终端(xterm.js + paramiko) - 完整审计日志 + 用户管理 技术栈: Flask 3.0 + SQLAlchemy 2.0 + SQLite + Chart.js + Leaflet 总代码量: ~16500 行 (15 Python 模块 + 34 模板 + CSS) 路由数: 73
216 lines
12 KiB
HTML
216 lines
12 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}主配置 - Squid Manager{% endblock %}
|
|
{% block content %}
|
|
<div class="page-header">
|
|
<h1>⚙️ 主配置</h1>
|
|
<div class="page-actions">
|
|
<span class="meta-text">配置文件: <code>{{ squid_conf_path }}</code></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<form method="post">
|
|
<input type="hidden" name="_csrf" value="{{ csrf_token() }}">
|
|
<div class="config-section">
|
|
<h3 class="config-section-title">🌐 网络 (Network)</h3>
|
|
<div class="filter-grid">
|
|
<div class="form-group">
|
|
<label>http_port <span class="hint">HTTP 代理监听端口</span></label>
|
|
<input type="text" name="http_port" value="{{ simple.http_port }}" class="form-input" placeholder="3128">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>https_port <span class="hint">HTTPS 监听 (用于 SSL Bump)</span></label>
|
|
<input type="text" name="https_port" value="{{ simple.https_port }}" class="form-input" placeholder="留空则不启用">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>icp_port <span class="hint">ICP 协议端口 (邻居间)</span></label>
|
|
<input type="text" name="icp_port" value="{{ simple.icp_port }}" class="form-input" placeholder="3130">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>snmp_port <span class="hint">SNMP 监控端口</span></label>
|
|
<input type="text" name="snmp_port" value="{{ simple.snmp_port }}" class="form-input" placeholder="留空则不启用">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>visible_hostname <span class="hint">对外显示的主机名</span></label>
|
|
<input type="text" name="visible_hostname" value="{{ simple.visible_hostname }}" class="form-input" placeholder="proxy.example.com">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>unique_hostname <span class="hint">多实例区分 (可选)</span></label>
|
|
<input type="text" name="unique_hostname" value="{{ simple.unique_hostname }}" class="form-input">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-section">
|
|
<h3 class="config-section-title">💾 缓存 (Cache)</h3>
|
|
<div class="filter-grid">
|
|
<div class="form-group">
|
|
<label>cache_mem <span class="hint">内存缓存大小</span></label>
|
|
<input type="text" name="cache_mem" value="{{ simple.cache_mem }}" class="form-input" placeholder="256 MB">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>maximum_object_size <span class="hint">最大对象大小</span></label>
|
|
<input type="text" name="maximum_object_size" value="{{ simple.maximum_object_size }}" class="form-input" placeholder="4096 KB">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>minimum_object_size</label>
|
|
<input type="text" name="minimum_object_size" value="{{ simple.minimum_object_size }}" class="form-input" placeholder="0 KB">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>maximum_object_size_in_memory</label>
|
|
<input type="text" name="maximum_object_size_in_memory" value="{{ simple.maximum_object_size_in_memory }}" class="form-input" placeholder="512 KB">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>cache_replacement_policy</label>
|
|
<select name="cache_replacement_policy" class="form-input">
|
|
{% for p in ['lru','heap GDSF','heap LFUDA','heap LRU'] %}
|
|
<option value="{{ p }}" {% if simple.cache_replacement_policy == p %}selected{% endif %}>{{ p }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>memory_replacement_policy</label>
|
|
<select name="memory_replacement_policy" class="form-input">
|
|
{% for p in ['lru','heap GDSF','heap LFUDA','heap LRU'] %}
|
|
<option value="{{ p }}" {% if simple.memory_replacement_policy == p %}selected{% endif %}>{{ p }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>cache_swap_low <span class="hint">%</span></label>
|
|
<input type="number" name="cache_swap_low" value="{{ simple.cache_swap_low }}" class="form-input" placeholder="90">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>cache_swap_high <span class="hint">%</span></label>
|
|
<input type="number" name="cache_swap_high" value="{{ simple.cache_swap_high }}" class="form-input" placeholder="95">
|
|
</div>
|
|
</div>
|
|
<p class="meta-text">磁盘缓存目录 (cache_dir) 在 <a href="{{ url_for('config_cache') }}">缓存目录</a> 页面配置</p>
|
|
</div>
|
|
|
|
<div class="config-section">
|
|
<h3 class="config-section-title">📝 日志 (Logging)</h3>
|
|
<div class="filter-grid">
|
|
<div class="form-group">
|
|
<label>access_log <span class="hint">访问日志路径</span></label>
|
|
<input type="text" name="access_log" value="{{ simple.access_log }}" class="form-input" placeholder="/var/log/squid/access.log">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>cache_log <span class="hint">缓存日志</span></label>
|
|
<input type="text" name="cache_log" value="{{ simple.cache_log }}" class="form-input" placeholder="/var/log/squid/cache.log">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>cache_store_log</label>
|
|
<input type="text" name="cache_store_log" value="{{ simple.cache_store_log }}" class="form-input" placeholder="/var/log/squid/store.log 或留空">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>pid_filename</label>
|
|
<input type="text" name="pid_filename" value="{{ simple.pid_filename }}" class="form-input" placeholder="/var/run/squid.pid">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>logformat <span class="hint">自定义格式</span></label>
|
|
<input type="text" name="logformat" value="{{ simple.logformat }}" class="form-input" placeholder="留空使用默认">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>debug_options <span class="hint">ALL,1 / section,level</span></label>
|
|
<input type="text" name="debug_options" value="{{ simple.debug_options }}" class="form-input" placeholder="ALL,1">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>log_ip_on_direct</label>
|
|
<select name="log_ip_on_direct" class="form-input">
|
|
<option value="on" {% if simple.log_ip_on_direct == 'on' %}selected{% endif %}>on</option>
|
|
<option value="off" {% if simple.log_ip_on_direct == 'off' %}selected{% endif %}>off</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>buffered_logs</label>
|
|
<select name="buffered_logs" class="form-input">
|
|
<option value="on" {% if simple.buffered_logs == 'on' %}selected{% endif %}>on</option>
|
|
<option value="off" {% if simple.buffered_logs == 'off' %}selected{% endif %}>off</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-section">
|
|
<h3 class="config-section-title">🌍 DNS</h3>
|
|
<div class="filter-grid">
|
|
<div class="form-group">
|
|
<label>dns_nameservers <span class="hint">DNS 服务器 (空格分隔)</span></label>
|
|
<input type="text" name="dns_nameservers" value="{{ simple.dns_nameservers }}" class="form-input" placeholder="8.8.8.8 1.1.1.1">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>dns_timeout</label>
|
|
<input type="text" name="dns_timeout" value="{{ simple.dns_timeout }}" class="form-input" placeholder="30 seconds">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>hosts_file</label>
|
|
<input type="text" name="hosts_file" value="{{ simple.hosts_file }}" class="form-input" placeholder="/etc/hosts">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>dns_defnames</label>
|
|
<select name="dns_defnames" class="form-input">
|
|
<option value="off" {% if simple.dns_defnames == 'off' %}selected{% endif %}>off</option>
|
|
<option value="on" {% if simple.dns_defnames == 'on' %}selected{% endif %}>on</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-section">
|
|
<h3 class="config-section-title">⏱️ 超时 (Timeouts)</h3>
|
|
<div class="filter-grid">
|
|
<div class="form-group">
|
|
<label>connect_timeout</label>
|
|
<input type="text" name="connect_timeout" value="{{ simple.connect_timeout }}" class="form-input" placeholder="60 seconds">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>read_timeout</label>
|
|
<input type="text" name="read_timeout" value="{{ simple.read_timeout }}" class="form-input" placeholder="15 minutes">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>client_lifetime</label>
|
|
<input type="text" name="client_lifetime" value="{{ simple.client_lifetime }}" class="form-input" placeholder="1 day">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>shutdown_lifetime</label>
|
|
<input type="text" name="shutdown_lifetime" value="{{ simple.shutdown_lifetime }}" class="form-input" placeholder="30 seconds">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-section">
|
|
<h3 class="config-section-title">🛠️ 管理 (Admin)</h3>
|
|
<div class="filter-grid">
|
|
<div class="form-group">
|
|
<label>cache_mgr <span class="hint">管理员邮箱</span></label>
|
|
<input type="text" name="cache_mgr" value="{{ simple.cache_mgr }}" class="form-input" placeholder="root">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>err_html_language</label>
|
|
<input type="text" name="err_html_language" value="{{ simple.err_html_language }}" class="form-input" placeholder="en">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>ftp_user</label>
|
|
<input type="text" name="ftp_user" value="{{ simple.ftp_user }}" class="form-input" placeholder="Squid@">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="config-section">
|
|
<h3 class="config-section-title">📝 原始附加指令</h3>
|
|
<p class="meta-text">此处填写本页未涵盖的额外指令 (每行一条,会原样写入 squid.conf 末尾)。</p>
|
|
<div class="form-group">
|
|
<textarea name="raw_extra" rows="5" class="form-input monospace" placeholder="# 例如 forward_timeout 4 minutes
|
|
# maximum_single_addr_connections 16"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button type="submit" class="btn btn-primary">💾 保存并校验</button>
|
|
<a href="{{ url_for('config_raw') }}" class="btn btn-secondary">📝 原始编辑</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
{% endblock %}
|