0a18b94d84
- Flask + SQLite web app with user authentication - Zone management: create/delete zones, edit raw zone files - Record management: add/delete A/AAAA/CNAME/MX/TXT/NS/PTR/SRV/CAA records - Service control: start/stop/restart/reload BIND via systemctl/rndc - Configuration editor: edit named.conf.options/local with syntax validation - DNS query testing: online dig tool - Audit log: all operations logged with user/timestamp - BIND9 backend, listening on port 53
124 lines
5.8 KiB
HTML
124 lines
5.8 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{{ zone.name }} - DNS{% endblock %}
|
|
{% block content %}
|
|
<div class="page-header">
|
|
<div>
|
|
<h1>{{ zone.name }}</h1>
|
|
<div class="zone-meta">
|
|
<span class="badge badge-{{ zone.type }}">{{ zone.type }}</span>
|
|
<span class="text-mono text-sm">{{ zone.filename }}</span>
|
|
<span class="text-muted text-sm">共 {{ records|length }} 条记录</span>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<a href="{{ url_for('zone_raw', zone_name=zone.name) }}" class="btn btn-info btn-sm">📝 原始文件</a>
|
|
<form method="POST" action="{{ url_for('zone_delete', zone_name=zone.name) }}" style="display:inline" onsubmit="return confirm('确定删除域名 {{ zone.name }} 及所有记录?')">
|
|
<button type="submit" class="btn btn-danger btn-sm">🗑 删除域名</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
{% if soa %}
|
|
<div class="card">
|
|
<div class="card-header"><h2>SOA 记录</h2></div>
|
|
<div class="card-body">
|
|
<table class="table table-compact">
|
|
<tr>
|
|
<td class="text-muted">主 NS</td><td class="text-mono">{{ soa.raw.split()[0] if soa.raw else '-' }}</td>
|
|
<td class="text-muted">管理员</td><td class="text-mono">{{ soa.raw.split()[1] if soa.raw and soa.raw.split()|length > 1 else '-' }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Serial</td><td class="text-mono">{{ soa.raw.split()[2] if soa.raw and soa.raw.split()|length > 2 else '-' }}</td>
|
|
<td class="text-muted">Refresh</td><td class="text-mono">{{ soa.raw.split()[3] if soa.raw and soa.raw.split()|length > 3 else '-' }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Retry</td><td class="text-mono">{{ soa.raw.split()[4] if soa.raw and soa.raw.split()|length > 4 else '-' }}</td>
|
|
<td class="text-muted">Expire</td><td class="text-mono">{{ soa.raw.split()[5] if soa.raw and soa.raw.split()|length > 5 else '-' }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="text-muted">Min TTL</td><td class="text-mono">{{ soa.raw.split()[6] if soa.raw and soa.raw.split()|length > 6 else '-' }}</td>
|
|
<td colspan="2"></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2>DNS 记录</h2>
|
|
<button type="button" class="btn btn-primary btn-sm" onclick="document.getElementById('addRecordForm').style.display='block'">+ 添加记录</button>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="addRecordForm" style="display:none" class="record-form-wrap">
|
|
<form method="POST" action="{{ url_for('record_add', zone_name=zone.name) }}" class="record-form">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>名称</label>
|
|
<input type="text" name="name" placeholder="@ 或 www" style="width:150px">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>TTL</label>
|
|
<input type="text" name="ttl" placeholder="留空=默认" style="width:100px">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>类型</label>
|
|
<select name="type" id="recordType" style="width:100px">
|
|
{% for t in record_types %}
|
|
<option value="{{ t }}">{{ t }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="form-group" style="flex:1">
|
|
<label>数据</label>
|
|
<input type="text" name="data" placeholder="如 192.168.1.1 或 target.example.com." style="width:100%">
|
|
</div>
|
|
<div class="form-group form-actions-vertical">
|
|
<button type="submit" class="btn btn-primary btn-sm">添加</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-hints">
|
|
<p>A: IPv4地址 | AAAA: IPv6地址 | CNAME: 别名(以.结尾) | MX: 优先级 目标(以.结尾)</p>
|
|
<p>TXT: 文本 | NS: NS服务器(以.结尾) | PTR: 反向解析(以.结尾) | SRV: 优先级 权重 端口 目标</p>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
{% if records %}
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>名称</th>
|
|
<th>TTL</th>
|
|
<th>类型</th>
|
|
<th>数据</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for r in records %}
|
|
<tr>
|
|
<td class="text-muted">{{ loop.index0 }}</td>
|
|
<td class="text-mono">{{ r.name }}</td>
|
|
<td class="text-mono text-muted">{{ r.ttl }}</td>
|
|
<td><span class="badge badge-{{ r.type }}">{{ r.type }}</span></td>
|
|
<td class="text-mono">{{ r.data }}</td>
|
|
<td>
|
|
<form method="POST" action="{{ url_for('record_delete', zone_name=zone.name, idx=loop.index0) }}" style="display:inline" onsubmit="return confirm('确定删除 {{ r.name }} {{ r.type }} {{ r.data }}?')">
|
|
<button type="submit" class="btn-sm btn-danger">删除</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}
|
|
<div class="empty-state">
|
|
<p>此域名还没有记录</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|