Files
squid-manager/templates/config_ssl_bump.html
T
Hermes Agent 4a1d949e41 feat: 完整 Squid Web Manager 平台 - P0-P3 全功能
完整 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
2026-07-15 10:19:21 +08:00

207 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}SSL Bump - Squid Manager{% endblock %}
{% block content %}
<div class="page-header">
<h1>🔐 SSL Bump (HTTPS 透明代理)</h1>
<div class="page-actions">
<button onclick="document.getElementById('add-form').style.display='block'" class="btn btn-primary btn-small"> 添加规则</button>
<button onclick="document.getElementById('cert-form').style.display='block'" class="btn btn-secondary btn-small">🪪 生成自签 CA</button>
</div>
</div>
<div class="card" style="border-left: 4px solid #d33; background: #fff8f8;">
<h3 class="card-title" style="color:#c0392b;">⚠️ 风险与合规提示</h3>
<ul>
<li><b>中间人攻击:</b> 启用 <code>bump</code> 后代理会解密所有 HTTPS 流量,浏览器看到的是代理签名的证书而非真实证书。</li>
<li><b>私钥泄露风险:</b> 必须在受信环境运行;一旦 CA 私钥泄露,所有用它签名的中间证书都可以伪造。</li>
<li><b>用户信任:</b> 客户端必须安装并信任你生成的 CA;否则会看到证书错误。</li>
<li><b>审计/合规:</b> 许多司法管辖区要求告知用户并获取同意;请提前与法务/合规团队沟通。</li>
<li><b>替代方案:</b> 如果只是需要域名过滤,优先用 <code>splice</code> (不解密) + SNI 嗅探;只有需要看 payload 时再用 <code>bump</code></li>
</ul>
</div>
<div class="card">
<h3 class="card-title">📋 默认规则示例</h3>
<pre class="code-block"><code>{{ default_example|e }}</code></pre>
<p class="meta-text">规则按顺序匹配,首条命中即停止。建议先用 <code>splice</code> 放通全部,排查没问题后再加 <code>peek</code>/<code>bump</code></p>
</div>
<div class="card" id="add-form" style="display:none;">
<h3 class="card-title">添加新 SSL Bump 规则</h3>
<form method="post" class="inline-form">
<input type="hidden" name="_csrf" value="{{ csrf_token() }}">
<input type="hidden" name="action" value="add">
<div class="filter-grid">
<div class="form-group">
<label>动作 (action)</label>
<select name="action_type" class="form-input">
{% for a in actions %}
<option value="{{ a }}" {% if a == 'peek' %}selected{% endif %}>{{ a }}</option>
{% endfor %}
</select>
</div>
<div class="form-group" style="grid-column: span 2;">
<label>ACL 列表 <span class="hint">(空格分隔,支持 <code>!aclname</code> 取反,如 <code>!localhost trusted_net</code>)</span></label>
<input type="text" name="acls" class="form-input" placeholder="step1 all">
</div>
<div class="form-group" style="grid-column: span 3;">
<label>备注</label>
<input type="text" name="comment" class="form-input" placeholder="示例: 缺省放行">
</div>
</div>
<details class="hint" style="margin-top: 0.5em;">
<summary>📚 动作含义</summary>
<ul style="margin-top: 0.5em;">
<li><code>peek</code> - 在 SslBump1 解密 client hello,只读 SNI/ALPN,不解后续</li>
<li><code>splice</code> - TCP 直通隧道,不解密 (性能最好,几乎无开销)</li>
<li><code>bump</code> - 完整解密,代理签发证书,可看明文 (最慢/最重)</li>
<li><code>terminate</code> - 主动关闭连接 (用于阻断)</li>
<li><code>client-first</code> / <code>server-first</code> - 控制 TLS 握手方向</li>
<li><code>none</code> - 显式禁用 (用于在内层 step 关闭默认行为)</li>
</ul>
</details>
<div class="form-actions">
<button type="submit" class="btn btn-primary">添加</button>
<button type="button" onclick="document.getElementById('add-form').style.display='none'" class="btn btn-secondary">取消</button>
</div>
</form>
</div>
<div class="card">
<p class="card-desc">当前共 <b>{{ rules | length }}</b> 条 SSL Bump 规则。按表从上到下顺序匹配,首条命中即终止。</p>
<p class="meta-text">可用 ACL:
{% for name in acls_by_name.keys() %}
<code>{{ name }}</code>{% if not loop.last %} · {% endif %}
{% else %}
<em>暂无 ACL,请先在「ACL 规则表」页面创建。</em>
{% endfor %}
</p>
<form method="post">
<input type="hidden" name="_csrf" value="{{ csrf_token() }}">
<input type="hidden" name="action" value="save">
<div class="table-scroll">
<table class="data-table rules-table">
<thead>
<tr>
<th style="width:60px;">#</th>
<th style="width:160px;">动作</th>
<th>ACL</th>
<th>备注</th>
<th style="width:80px;">操作</th>
</tr>
</thead>
<tbody>
{% for r in rules %}
<tr>
<td>{{ loop.index }}
<input type="hidden" name="id[]" value="{{ loop.index }}">
</td>
<td>
<select name="action_type[]" class="form-input">
{% for a in actions %}
<option value="{{ a }}" {% if r.action == a %}selected{% endif %}>{{ a }}</option>
{% endfor %}
</select>
</td>
<td><input type="text" name="acls[]" value="{{ r.acls | join(' ') }}" class="form-input" placeholder="!localhost trusted_net"></td>
<td><input type="text" name="comment[]" value="{{ r.comment }}" class="form-input"></td>
<td>
<button type="button" class="btn btn-danger btn-tiny" onclick="this.closest('tr').remove()">删除</button>
</td>
</tr>
{% endfor %}
{% if not rules %}
<tr><td colspan="5" class="empty-row">暂无规则。点击"添加规则"开始,或先在下方配置 sslcrtd / sslproxy_ca_* 再添加 peek/splice 规则。</td></tr>
{% endif %}
</tbody>
</table>
</div>
{% if rules %}
<div class="form-actions">
<button type="submit" class="btn btn-primary">💾 保存所有规则与 SSL 设置</button>
</div>
{% endif %}
</form>
</div>
<div class="card">
<h3 class="card-title">🗄️ SSL 数据库与 CA 证书设置</h3>
<p class="meta-text">
这些是让 SSL Bump 真正起作用的底层配置。
<b>sslcrtd_program</b> + <b>sslcrtd_children</b> 控制 on-the-fly 自签证书生成器;
<b>sslproxy_ca_certfile</b> + <b>sslproxy_ca_keyfile</b> 指向你用作 CA 的证书与私钥。
</p>
<form method="post">
<input type="hidden" name="_csrf" value="{{ csrf_token() }}">
<input type="hidden" name="action" value="save">
<div class="filter-grid">
<div class="form-group" style="grid-column: span 3;">
<label>sslcrtd_program <span class="hint">(完整命令行: 可执行文件 + 参数,空格分隔)</span></label>
<input type="text" name="sslcrtd_program" class="form-input"
value="{{ simple.sslcrtd_program }}"
placeholder="security_file_certgen -s /var/lib/squid/ssl_db -M 4 MB">
</div>
<div class="form-group" style="grid-column: span 3;">
<label>sslcrtd_children <span class="hint">(空格分隔,如 <code>5 startup=1 idle=1</code>)</span></label>
<input type="text" name="sslcrtd_children" class="form-input"
value="{{ simple.sslcrtd_children }}"
placeholder="5 startup=1 idle=1">
</div>
<div class="form-group" style="grid-column: span 3;">
<label>sslproxy_ca_certfile <span class="hint">(CA 证书路径,绝对路径)</span></label>
<input type="text" name="sslproxy_ca_certfile" class="form-input"
value="{{ simple.sslproxy_ca_certfile }}"
placeholder="/etc/squid/bump_ca.crt">
</div>
<div class="form-group" style="grid-column: span 3;">
<label>sslproxy_ca_keyfile <span class="hint">(CA 私钥路径,绝对路径)</span></label>
<input type="text" name="sslproxy_ca_keyfile" class="form-input"
value="{{ simple.sslproxy_ca_keyfile }}"
placeholder="/etc/squid/bump_ca.key">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">💾 保存 SSL 数据库与 CA 设置</button>
</div>
</form>
</div>
<div class="card" id="cert-form" style="display:none;">
<h3 class="card-title">🪪 生成 SSL Bump 自签 CA (便利工具)</h3>
<p class="meta-text">
一键生成自签 CA 证书到 <code>ssl_certs/</code>。生成后请将证书安装到所有需要被 SSL Bump 的客户端的"受信任的根证书颁发机构"。
<b>注意:</b> 不要复用生产 CA 私钥。
</p>
<form method="post">
<input type="hidden" name="_csrf" value="{{ csrf_token() }}">
<input type="hidden" name="action" value="generate-cert">
<div class="filter-grid">
<div class="form-group">
<label>Common Name (CN)</label>
<input type="text" name="common_name" class="form-input" value="Squid Bump CA" placeholder="Squid Bump CA">
</div>
<div class="form-group">
<label>有效期 (天)</label>
<input type="number" name="days" class="form-input" value="3650" min="1" max="36500">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">🪪 生成</button>
<button type="button" onclick="document.getElementById('cert-form').style.display='none'" class="btn btn-secondary">取消</button>
</div>
</form>
</div>
<div class="card">
<h3 class="card-title">📖 参考</h3>
<ul>
<li><code>peek</code>: 解密 client hello 拿到 SNI/ALPN,然后视后续 step 再决定;不让代理完整解密流量。</li>
<li><code>splice</code>: 直接把 TCP 流透传给 origin,不解密;性能最佳,适合大批流量。</li>
<li><code>bump</code>: 完整解密 TLS,代理用 sslproxy_ca_certfile 签发 leaf cert;</li>
<li><code>terminate</code>: 客户端 TCP 被代理关闭 (用于拒绝)。</li>
<li>ACL 列表里用 <code>!</code> 取反,多个 ACL 之间为 AND (全部满足)。</li>
<li>常见配套: <code>acl step1 at_step SslBump1</code> + <code>ssl_bump peek step1</code> 然后 <code>ssl_bump splice all</code></li>
</ul>
</div>
{% endblock %}