feat: listen-on and recursion toggles in upstream DNS form

Web 端 '上游 DNS 转发' 卡片新增两个字段:

1. Listen-on (IPv4) 53 端口 — textarea,每行一个 CIDR/IP/ACL 名。
   留空 = any(任意来源)。对应 BIND 指令 listen-on port 53 { ... };。
2. Recursion — yes/no 下拉,控制本 DNS 是否代客户端去外网递归。
   内网递归服务器选 yes;纯权威服务器选 no。

修了一个 regex bug:之前 _replace_or_append_option 用 \\b(?!\\-) 做
lookahead 但没用 lookbehind,导致在内容含 allow-recursion 时匹配
recursion 时也会匹配到 allow- 后面的 recursion,把 allow-recursion
破坏。改为 (?<!\\w)(?<!\\-)keyword\\b(?!\\w)(?!\\-) 双向拒绝,
确保 keyword 必须是独立单词,不能是其它带连字符 directive 的子串。

测试覆盖:
- parse listen-on (IPv4 list)
- parse recursion (yes/no/default)
- 完整 round-trip:5 个字段同时更新,allow-recursion / listen-on-v6
  等未触及的 directives 正确保留
This commit is contained in:
Hermes
2026-07-24 18:13:00 +08:00
parent 9b1679bbd0
commit e0bb10bfab
2 changed files with 78 additions and 9 deletions
+20 -1
View File
@@ -59,10 +59,29 @@
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="listen_on_v4">
<strong>Listen-on (IPv4) 53 端口</strong>
<span class="text-muted text-sm">允许哪些客户端查询本 DNS。每行一个 CIDR / IP / ACL 名。留空 = <code>any</code>(任意来源)。</span>
</label>
<textarea name="listen_on_v4" id="listen_on_v4" class="code-editor" rows="4" spellcheck="false"
placeholder="any&#10;或具体网段,如:&#10;192.168.1.0/24&#10;10.0.0.0/8">{% for net in listen_on_v4 %}{{ net }}
{% endfor %}</textarea>
</div>
<div class="form-group">
<label for="recursion_toggle">
<strong>Recursion (递归查询)</strong>
<span class="text-muted text-sm">是否允许本 DNS 代客户端去外网查询。内网递归服务器选 <code>yes</code>;纯权威服务器选 <code>no</code></span>
</label>
<select name="recursion_toggle" id="recursion_toggle" class="form-control">
<option value="yes" {% if recursion_value == 'yes' %}selected{% endif %}>yes(允许递归)</option>
<option value="no" {% if recursion_value == 'no' %}selected{% endif %}>no(仅权威应答,不递归)</option>
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">💾 保存并重载</button>
<span class="text-muted text-sm" style="margin-left: 12px;">
此处改 forwarders / allow-recursion / dnssec-validation;其它 options 字段请用下方文本编辑器。
此处改 forwarders / allow-recursion / dnssec-validation / listen-on / recursion;其它字段请用下方文本编辑器。
</span>
</div>
</form>