From 903fe1704a57454f552d8185c55e9740fc292e58 Mon Sep 17 00:00:00 2001 From: Hermes Date: Fri, 24 Jul 2026 17:44:38 +0800 Subject: [PATCH] fix: ensure zone directory exists before writing; cross-distro chown fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新装机器上添加域名报 500:FileNotFoundError '/etc/bind/zones/db..com'。 根因是创建 zone 时直接 open() 写文件,没先 makedirs,目录不存在 就直接抛 FileNotFoundError。 修法: 1. 写 zone 文件前 os.makedirs(BIND_ZONES_DIR, exist_ok=True), PermissionError 时返回用户友好提示而不是 500。 2. 把所有 chown bind:bind 改成 'chown bind:bind 2>/dev/null || chown named:named 2>/dev/null',覆盖 RHEL/CentOS 上 bind 用户 不存在的场景,避免 chown 报错污染日志。 影响范围:zone_create(创建)、record_edit/delete(修改/删除记录)、 zone_raw_edit(原始文件编辑)四处写文件路径。 --- app.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index afa2e57..c87fc6c 100644 --- a/app.py +++ b/app.py @@ -471,8 +471,8 @@ def append_record_to_file(filepath, name, ttl, rtype, data): with open(filepath, 'w') as f: f.write(content) - run_cmd(f"chown bind:bind {filepath}") - + run_cmd(f"chown bind:bind {filepath} 2>/dev/null || chown named:named {filepath} 2>/dev/null") + run_cmd(f"chmod 644 {filepath}") return True, "OK" @@ -541,8 +541,8 @@ def delete_record_from_file(filepath, zone_name, idx): with open(filepath, 'w') as f: f.write(content) - run_cmd(f"chown bind:bind {filepath}") - + run_cmd(f"chown bind:bind {filepath} 2>/dev/null || chown named:named {filepath} 2>/dev/null") + run_cmd(f"chmod 644 {filepath}") return True, f'{deleted["name"]} {deleted["type"]} {deleted["data"]}', "OK" @@ -774,9 +774,16 @@ def zone_create(): """ # Write zone file + try: + os.makedirs(BIND_ZONES_DIR, exist_ok=True) + except PermissionError as e: + flash(f"无法创建 zone 目录 {BIND_ZONES_DIR}(权限不足):{e}", "error") + return render_template("zone_form.html") with open(zone_file, 'w') as f: f.write(zone_content) - run_cmd(f"chown bind:bind {zone_file}") + # BIND runs as user 'bind' (Debian/Ubuntu) or 'named' (RHEL/CentOS). + # Try Debian first; fall back to RHEL. + run_cmd(f"chown bind:bind {zone_file} 2>/dev/null || chown named:named {zone_file} 2>/dev/null") run_cmd(f"chmod 644 {zone_file}") # Validate zone @@ -877,8 +884,8 @@ def zone_raw(zone_name): # Write with open(zone["file"], 'w') as f: f.write(content) - run_cmd(f"chown bind:bind {zone['file']}") - run_cmd(f"rm -f /tmp/zone_check.tmp") + run_cmd(f"chown bind:bind {zone['file']} 2>/dev/null || chown named:named {zone['file']} 2>/dev/null") + run_cmd(f"chmod 644 {zone['file']}") bind_reload()