# DNS Web Manager 基于 BIND9 的 DNS 服务器 Web 管理界面,使用 Flask + SQLite 构建。 ## 功能概览 | 功能 | 说明 | |------|------| | 仪表盘 | BIND 服务状态、域名/记录统计、服务控制(启动/停止/重启/重载) | | 域名管理 | 创建/删除 Zone(支持 master/slave)、查看 Zone 详情、编辑原始 zone 文件 | | 记录管理 | 添加/删除 DNS 记录(A、AAAA、CNAME、MX、TXT、NS、PTR、SRV、CAA) | | DNS 查询 | 在线 dig 测试,支持所有记录类型 | | 配置管理 | 在线编辑 `named.conf.options` 和 `named.conf.local`,带语法校验 | | 操作日志 | 全部操作的审计日志,支持分页 | | 用户认证 | 登录/登出/修改密码 | ## 截图 ### 仪表盘 - BIND 服务状态卡片(运行状态、开机自启) - 域名数量、记录总数统计 - 服务控制按钮(启动/停止/重启/重载) - 域名概览表格 - 最近操作日志 ### 域名管理 - 域名列表(域名、类型、Zone 文件、记录数) - 创建域名表单(域名、类型、NS 服务器、管理员邮箱) - Zone 详情页:SOA 信息、记录列表、添加记录表单、原始文件编辑 ### DNS 查询 - 输入域名 + 记录类型 + DNS 服务器,执行 dig 查询 - 显示完整 dig 输出 ## 技术栈 - **DNS 服务器**: BIND 9.18+(named) - **Web 框架**: Flask 3.0 - **数据库**: SQLite(用户认证 + 审计日志) - **前端**: Jinja2 模板 + 原生 CSS(无前端框架依赖) - **WSGI 服务器**: Gunicorn ## 目录结构 ``` dns-service/ ├── app.py # Flask 应用主文件(路由、模型、BIND 操作) ├── wsgi.py # Gunicorn 入口 ├── init_db.py # 数据库初始化脚本 ├── requirements.txt # Python 依赖 ├── README.md ├── templates/ # Jinja2 模板 │ ├── base.html # 布局模板(导航栏 + 页脚) │ ├── login.html # 登录页 │ ├── dashboard.html # 仪表盘 │ ├── zones.html # 域名列表 │ ├── zone_form.html # 创建域名表单 │ ├── zone_detail.html # Zone 详情 + 记录管理 │ ├── zone_raw.html # 原始 Zone 文件编辑 │ ├── query.html # DNS 查询测试 │ ├── config.html # BIND 配置管理 │ ├── logs.html # 操作日志 │ ├── change_password.html │ └── error.html # 错误页 ├── static/ │ └── style.css # 全部样式 └── instance/ # SQLite 数据库(运行时生成) └── dns_web.db ``` ## BIND 配置文件 | 文件 | 用途 | 路径 | |------|------|------| | `named.conf` | 主配置 | `/etc/bind/named.conf` | | `named.conf.options` | 全局选项(监听端口、转发器、查询权限) | `/etc/bind/named.conf.options` | | `named.conf.local` | Zone 声明(由 Web UI 自动管理) | `/etc/bind/named.conf.local` | | zone files | DNS 记录文件 | `/etc/bind/zones/db.*` | ## 安装部署 ### 1. 安装 BIND9 ```bash apt-get update apt-get install -y bind9 bind9utils dnsutils ``` ### 2. 配置 BIND ```bash # 创建 zone 文件目录 mkdir -p /etc/bind/zones chown bind:bind /etc/bind/zones # named.conf.options(监听 53 端口) cat > /etc/bind/named.conf.options << 'EOF' options { directory "/var/cache/bind"; listen-on port 53 { any; }; listen-on-v6 { none; }; forwarders { 8.8.8.8; 8.8.4.4; }; allow-query { any; }; allow-recursion { 127.0.0.0/8; 10.168.1.0/24; }; dnssec-validation auto; auth-nxdomain no; }; EOF # named.conf(包含 options + local + default-zones) cat > /etc/bind/named.conf << 'EOF' include "/etc/bind/named.conf.options"; include "/etc/bind/named.conf.local"; include "/etc/bind/named.conf.default-zones"; EOF # named.conf.local(空,由 Web UI 自动填充) cat > /etc/bind/named.conf.local << 'EOF' // Local zone configurations - managed by DNS Web UI EOF # 启动 BIND systemctl enable named systemctl start named ``` ### 3. 安装 Web 应用 ```bash git clone ssh://git@git.cnbugs.com:10022/AI-Agent/dns-service.git cd dns-service # 安装 Python 依赖 pip install -r requirements.txt # 创建数据库目录 mkdir -p instance # 初始化数据库(创建默认 admin/admin 账号) python3 init_db.py # 启动(开发模式) python3 app.py ``` ### 4. 生产部署(Gunicorn + Systemd) ```bash # 创建 systemd 服务 cat > /etc/systemd/system/dns-web.service << 'EOF' [Unit] Description=DNS Web Manager After=network.target named.service [Service] Type=notify User=root WorkingDirectory=/root/dns-service ExecStart=/usr/local/bin/gunicorn --workers 2 --bind 0.0.0.0:5300 wsgi:app Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable dns-web systemctl start dns-web ``` ## 使用说明 ### 登录 - 访问 `http://<服务器IP>:5300` - 默认账号: `admin` / 密码: `admin` - 首次登录后请修改密码 ### 创建域名 1. 进入「域名管理」→「+ 添加域名」 2. 填写域名(如 `example.com`)、选择类型(master/slave) 3. 可选填写 NS 服务器和管理员邮箱(留空则自动生成) 4. 点击「创建域名」 ### 添加 DNS 记录 1. 进入域名详情页 2. 点击「+ 添加记录」 3. 填写记录名称、类型、TTL、数据 4. 点击「添加」 **记录类型说明:** | 类型 | 数据格式 | 示例 | |------|----------|------| | A | IPv4 地址 | `10.168.1.100` | | AAAA | IPv6 地址 | `2001:db8::1` | | CNAME | 别名(FQDN,以 `.` 结尾) | `www.example.com.` | | MX | 优先级 + 邮件服务器(FQDN) | `10 mail.example.com.` | | TXT | 文本内容 | `"v=spf1 ~all"` | | NS | NS 服务器(FQDN) | `ns1.example.com.` | | PTR | 反向解析目标(FQDN) | `host.example.com.` | | SRV | 优先级 权重 端口 目标 | `10 5 5060 sip.example.com.` | ### DNS 查询测试 1. 进入「DNS 查询」页面 2. 输入域名和记录类型 3. DNS 服务器留空默认查询本地 BIND(127.0.0.1:53) 4. 点击「查询」查看结果 ### 配置管理 1. 进入「配置管理」页面 2. 可在线编辑 `named.conf.options`(监听端口、转发器等) 3. 可在线编辑 `named.conf.local`(Zone 声明) 4. 保存时自动执行 `named-checkconf` 校验,通过后自动 `rndc reload` ### 服务控制 在「仪表盘」页面可控制 BIND 服务: - **启动** - `systemctl start named` - **停止** - `systemctl stop named` - **重启** - `systemctl restart named` - **重载配置** - `rndc reload`(不中断服务,热加载 zone 变更) ## 注意事项 1. **权限要求**: Web 应用需要 root 权限运行(用于操作 BIND 配置文件和 systemctl 命令) 2. **端口冲突**: 如果 53 端口被其他服务占用(如 dnsmasq),需先停掉对应服务 3. **Zone 文件权限**: zone 文件需要 `bind:bind` 所有权,Web UI 自动设置 4. **Serial 自动递增**: 每次添加/删除记录时,SOA Serial 自动递增(YYYYMMDDNN 格式) 5. **配置备份**: 编辑配置文件时自动创建 `.bak` 备份 ## API 接口 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/status` | 获取 BIND 服务状态(需登录) | ## License MIT