feat: setup-bind.sh one-shot initialization script
新增 scripts/setup-bind.sh,自动探测 Debian/Ubuntu vs RHEL/CentOS 布局(不靠 OS 名 if-elif,靠 /etc/bind vs /etc/named.conf 文件存在性), 执行 5 步: 1. 装 bind 包(如未装) 2. 建 zone 目录、设 bind:named 所有权 + 2770 3. 建 named.conf.local 空文件、640 4. 确保 named.conf 包含 named.conf.local(如未包含则追加) 5. systemctl restart named 幂等:每步都先检查当前状态,已配置项跳过、避免破坏现有内容。 支持 --dry-run 模式打印将执行的命令而不真做,便于先审核。 README '安装 Web 应用' 步骤增加 dry-run + 真跑的两行示例。 测试:dev (Debian 12) --dry-run 通过,正确检测 Debian 布局、跳过 已配置步骤。
This commit is contained in:
@@ -164,6 +164,17 @@ systemctl restart named
|
|||||||
git clone ssh://git@git.cnbugs.com:10022/AI-Agent/dns-service.git
|
git clone ssh://git@git.cnbugs.com:10022/AI-Agent/dns-service.git
|
||||||
cd dns-service
|
cd dns-service
|
||||||
|
|
||||||
|
# 一键初始化 BIND(自动识别 Debian/Ubuntu vs RHEL/CentOS):
|
||||||
|
# - 装 bind 包
|
||||||
|
# - 建 zone 目录、设权限
|
||||||
|
# - 建 named.conf.local、确保被主配置 include
|
||||||
|
# - 重启 named
|
||||||
|
# 默认是干跑模式,先看清楚会做什么:
|
||||||
|
sudo bash scripts/setup-bind.sh --dry-run
|
||||||
|
|
||||||
|
# 确认无误后真跑:
|
||||||
|
sudo bash scripts/setup-bind.sh
|
||||||
|
|
||||||
# 安装 Python 依赖
|
# 安装 Python 依赖
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
|||||||
Executable
+183
@@ -0,0 +1,183 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# setup-bind.sh — initialize BIND for the DNS Web Manager
|
||||||
|
#
|
||||||
|
# Detects BIND layout (Debian/Ubuntu vs RHEL/CentOS/Rocky) by checking which
|
||||||
|
# files exist, then ensures:
|
||||||
|
# - bind package installed
|
||||||
|
# - zone directory exists with correct ownership
|
||||||
|
# - named.conf.local is included from named.conf
|
||||||
|
# - /etc/named.conf.local (or /etc/bind/named.conf.local) exists & writable
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# sudo bash scripts/setup-bind.sh # actually run all steps
|
||||||
|
# sudo bash scripts/setup-bind.sh --dry-run # print what would run, don't execute
|
||||||
|
#
|
||||||
|
# Idempotent: safe to run multiple times. Existing configs are preserved;
|
||||||
|
# named.conf.local is only created if missing.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DRY_RUN=0
|
||||||
|
if [[ "${1:-}" == "--dry-run" ]]; then
|
||||||
|
DRY_RUN=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ─── helpers ────────────────────────────────────────────────────────────────
|
||||||
|
log() { printf '\033[1;34m[setup-bind]\033[0m %s\n' "$*"; }
|
||||||
|
warn() { printf '\033[1;33m[setup-bind]\033[0m %s\n' "$*" >&2; }
|
||||||
|
err() { printf '\033[1;31m[setup-bind]\033[0m %s\n' "$*" >&2; }
|
||||||
|
|
||||||
|
run() {
|
||||||
|
if [[ $DRY_RUN -eq 1 ]]; then
|
||||||
|
printf ' [DRY-RUN] %s\n' "$*"
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
must_be_root() {
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
err "Must run as root (use sudo)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── detect BIND layout ─────────────────────────────────────────────────────
|
||||||
|
# Logic mirrors app.py's auto-detection: prefer RHEL paths when both exist.
|
||||||
|
detect_layout() {
|
||||||
|
if [[ -d /etc/bind ]]; then
|
||||||
|
# Debian/Ubuntu bind9 — /etc/bind exists
|
||||||
|
BIND_USER="bind"
|
||||||
|
BIND_GROUP="bind"
|
||||||
|
ZONES_DIR="/etc/bind/zones"
|
||||||
|
NAMED_CONF="/etc/bind/named.conf"
|
||||||
|
NAMED_CONF_LOCAL="/etc/bind/named.conf.local"
|
||||||
|
PKG_MANAGER="apt-get"
|
||||||
|
PKG_INSTALL=(apt-get install -y bind9 bind9utils dnsutils)
|
||||||
|
SERVICE_NAME="named"
|
||||||
|
elif [[ -f /etc/named.conf ]]; then
|
||||||
|
# RHEL/CentOS/Rocky bind — /etc/named.conf exists, /etc/bind usually doesn't
|
||||||
|
BIND_USER="named"
|
||||||
|
BIND_GROUP="named"
|
||||||
|
ZONES_DIR="/var/named"
|
||||||
|
NAMED_CONF="/etc/named.conf"
|
||||||
|
NAMED_CONF_LOCAL="/etc/named.conf.local"
|
||||||
|
PKG_MANAGER="yum"
|
||||||
|
PKG_INSTALL=(yum install -y bind bind-utils)
|
||||||
|
SERVICE_NAME="named"
|
||||||
|
else
|
||||||
|
# No BIND config found at all — assume Debian (most common for fresh installs)
|
||||||
|
# and let the package install create the structure.
|
||||||
|
BIND_USER="bind"
|
||||||
|
BIND_GROUP="bind"
|
||||||
|
ZONES_DIR="/etc/bind/zones"
|
||||||
|
NAMED_CONF="/etc/bind/named.conf"
|
||||||
|
NAMED_CONF_LOCAL="/etc/bind/named.conf.local"
|
||||||
|
PKG_MANAGER="apt-get"
|
||||||
|
PKG_INSTALL=(apt-get install -y bind9 bind9utils dnsutils)
|
||||||
|
SERVICE_NAME="named"
|
||||||
|
warn "No BIND config detected; defaulting to Debian/Ubuntu layout"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Detected layout:"
|
||||||
|
log " bind user/group : $BIND_USER:$BIND_GROUP"
|
||||||
|
log " zones dir : $ZONES_DIR"
|
||||||
|
log " named.conf : $NAMED_CONF"
|
||||||
|
log " named.conf.local: $NAMED_CONF_LOCAL"
|
||||||
|
log " pkg manager : $PKG_MANAGER"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── steps ──────────────────────────────────────────────────────────────────
|
||||||
|
install_bind() {
|
||||||
|
log "Step 1: ensure BIND package is installed"
|
||||||
|
if command -v named >/dev/null 2>&1; then
|
||||||
|
log " named already installed: $(named -v 2>&1 | head -1)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
warn " named not found; installing via $PKG_MANAGER"
|
||||||
|
run "${PKG_INSTALL[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_zones_dir() {
|
||||||
|
log "Step 2: ensure zones directory exists with correct ownership"
|
||||||
|
if [[ ! -d "$ZONES_DIR" ]]; then
|
||||||
|
log " $ZONES_DIR does not exist; creating"
|
||||||
|
run mkdir -p "$ZONES_DIR"
|
||||||
|
else
|
||||||
|
log " $ZONES_DIR already exists"
|
||||||
|
fi
|
||||||
|
# group-writable + setgid so future files inherit the group
|
||||||
|
run chown "$BIND_USER:$BIND_GROUP" "$ZONES_DIR"
|
||||||
|
run chmod 2770 "$ZONES_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_named_conf_local() {
|
||||||
|
log "Step 3: ensure named.conf.local exists and is writable by web"
|
||||||
|
if [[ ! -f "$NAMED_CONF_LOCAL" ]]; then
|
||||||
|
log " $NAMED_CONF_LOCAL does not exist; creating empty file"
|
||||||
|
run touch "$NAMED_CONF_LOCAL"
|
||||||
|
run chown "root:$BIND_GROUP" "$NAMED_CONF_LOCAL"
|
||||||
|
run chmod 640 "$NAMED_CONF_LOCAL"
|
||||||
|
else
|
||||||
|
log " $NAMED_CONF_LOCAL already exists; preserving"
|
||||||
|
# Don't change ownership if file already has content — it may be managed
|
||||||
|
# by someone else. Just make sure web process can write to it.
|
||||||
|
run chmod 644 "$NAMED_CONF_LOCAL"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_include_in_named_conf() {
|
||||||
|
log "Step 4: ensure named.conf includes named.conf.local"
|
||||||
|
if [[ ! -f "$NAMED_CONF" ]]; then
|
||||||
|
warn " $NAMED_CONF not found; skipping include check (bind not configured?)"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if grep -qF "$NAMED_CONF_LOCAL" "$NAMED_CONF"; then
|
||||||
|
log " $NAMED_CONF already includes $NAMED_CONF_LOCAL"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
warn " $NAMED_CONF does NOT include $NAMED_CONF_LOCAL — appending"
|
||||||
|
if [[ $DRY_RUN -eq 1 ]]; then
|
||||||
|
printf ' [DRY-RUN] echo "include \\"%s\\";" >> %s\n' "$NAMED_CONF_LOCAL" "$NAMED_CONF"
|
||||||
|
else
|
||||||
|
printf '\ninclude "%s";\n' "$NAMED_CONF_LOCAL" >> "$NAMED_CONF"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
restart_named() {
|
||||||
|
log "Step 5: restart named so include takes effect"
|
||||||
|
if ! systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||||
|
warn " $SERVICE_NAME not running; skipping restart"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ $DRY_RUN -eq 1 ]]; then
|
||||||
|
printf ' [DRY-RUN] systemctl restart %s\n' "$SERVICE_NAME"
|
||||||
|
else
|
||||||
|
run systemctl restart "$SERVICE_NAME"
|
||||||
|
sleep 1
|
||||||
|
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||||
|
log " $SERVICE_NAME is active"
|
||||||
|
else
|
||||||
|
err " $SERVICE_NAME failed to start; check 'journalctl -xe -u $SERVICE_NAME'"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ─── main ───────────────────────────────────────────────────────────────────
|
||||||
|
main() {
|
||||||
|
must_be_root
|
||||||
|
detect_layout
|
||||||
|
if [[ $DRY_RUN -eq 1 ]]; then
|
||||||
|
log "DRY-RUN mode: no changes will be made"
|
||||||
|
fi
|
||||||
|
install_bind
|
||||||
|
ensure_zones_dir
|
||||||
|
ensure_named_conf_local
|
||||||
|
ensure_include_in_named_conf
|
||||||
|
restart_named
|
||||||
|
log "Done. Verify with:"
|
||||||
|
log " named-checkconf"
|
||||||
|
log " rndc status | grep 'number of zones'"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Reference in New Issue
Block a user