From 3a805b8bda5f66b778067982d5a70a24d20531cf Mon Sep 17 00:00:00 2001 From: "l.kirchner" Date: Sun, 7 Jun 2026 21:21:05 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Add=20network=20profiles=20file=20(VLAN=20t?= =?UTF-8?q?ag=20=E2=86=92=20DNS=20servers)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Data file mapping a VLAN tag to its DNS servers and subnet, so build.func can set the right resolvers from the tag entered at install time — even with DHCP. New networks are a one-line addition here. --- lib/networks.conf | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 lib/networks.conf diff --git a/lib/networks.conf b/lib/networks.conf new file mode 100644 index 0000000..ceca92d --- /dev/null +++ b/lib/networks.conf @@ -0,0 +1,19 @@ +# lib/networks.conf — network profiles for proxmox-scripts +# +# Maps a VLAN tag to the DNS servers that network uses, so every LXC gets the +# right resolvers automatically — even when it pulls its IP via DHCP. This is +# looked up by lib/build.func from the VLAN tag entered during installation. +# +# To add a network, add one line. Columns are whitespace-separated: +# +# tag VLAN tag entered at install time. Use "none" for the untagged +# network (i.e. when the VLAN prompt is left empty). +# subnet CIDR of the network. Informational — shown during install. +# dns DNS servers, comma-separated (no spaces). +# +# Precedence note: an explicit NAMESERVER=... passed via env always wins over +# the profile. The profile only fills in DNS when none was given by hand. +# +# tag subnet dns +none 192.168.0.0/24 192.168.0.4,192.168.0.5 +20 10.11.20.0/24 10.11.20.44,10.11.20.55 -- 2.54.0 From 953ef3001ea8019cdf25f8d072da236f68bd4a5e Mon Sep 17 00:00:00 2001 From: "l.kirchner" Date: Sun, 7 Jun 2026 21:22:19 +0200 Subject: [PATCH 2/2] build.func: set DNS from VLAN tag via network profile (incl. DHCP) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds apply_network_profile(), which looks up DNS servers for the entered VLAN tag in lib/networks.conf and sets --nameserver accordingly — even when IP is DHCP. Precedence: explicit env NAMESERVER > profile > static prompt > inherit. Comma-separated DNS is normalised to spaces for pct. --- lib/build.func | 56 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/lib/build.func b/lib/build.func index 37f9e70..880d7ec 100644 --- a/lib/build.func +++ b/lib/build.func @@ -36,6 +36,12 @@ DEFAULT_ROOTFS_STORAGE="${DEFAULT_ROOTFS_STORAGE:-local-lvm}" DEFAULT_TEMPLATE_PATTERN="${DEFAULT_TEMPLATE_PATTERN:-debian-12-standard}" DEFAULT_NAMESERVER="${DEFAULT_NAMESERVER:-}" +# Network profiles: map a VLAN tag → DNS servers (+ subnet), maintained in +# lib/networks.conf so adding a network is a one-line change. Applied even for +# DHCP, so every container gets the right resolvers for its VLAN. +NET_PROFILES_URL="${NET_PROFILES_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/lib/networks.conf}" +# Set NET_PROFILES_FILE to a local path to use that instead of the remote file. + # ── error trap ─────────────────────────────────────────────────────────────── _on_error() { local exit_code=$? @@ -63,6 +69,34 @@ show_header() { echo } +# ── network profiles ───────────────────────────────────────────────────────── +# Look up DNS servers for the chosen VLAN tag from lib/networks.conf. +# Sets PROFILE_DNS (space-separated, ready for pct --nameserver) and +# PROFILE_SUBNET. Both stay empty if there's no matching profile. +apply_network_profile() { + PROFILE_DNS=""; PROFILE_SUBNET="" + local key="${VLAN_TAG:-}"; [[ -z "$key" ]] && key="none" + + local data="" + if [[ -n "${NET_PROFILES_FILE:-}" && -r "${NET_PROFILES_FILE:-}" ]]; then + data=$(cat "$NET_PROFILES_FILE") + else + data=$(curl -fsSL "$NET_PROFILES_URL" 2>/dev/null) || data="" + fi + [[ -n "$data" ]] || { msg_warn "Could not load network profiles ($NET_PROFILES_URL)"; return 0; } + + local t s d _rest + while read -r t s d _rest; do + [[ -z "$t" || "$t" == \#* ]] && continue # skip blanks/comments + if [[ "$t" == "$key" ]]; then + PROFILE_SUBNET="$s" + PROFILE_DNS="${d//,/ }" # pct wants space-separated + return 0 + fi + done <<< "$data" + return 0 +} + # ── prompts ────────────────────────────────────────────────────────────────── # Each prompt is skipped if the corresponding variable is already set in env. # VLAN_TAG and NAMESERVER use ${VAR+x} so that explicitly setting them to "" @@ -113,12 +147,24 @@ prompt_lxc_config() { if [[ "$IPCFG" != "dhcp" && -z "$GATEWAY" ]]; then read -rp "Gateway: " GATEWAY fi - # DNS: only meaningful for static IPs (DHCP gets DNS from the lease). - # Default suggestion is the gateway, which doubles as DNS in most homelabs. - if [[ "$IPCFG" != "dhcp" && -z "${NAMESERVER+x}" ]]; then + # DNS is driven by the VLAN tag via the network profile (lib/networks.conf), + # so the right resolvers get set even with DHCP. Precedence: + # 1. explicit NAMESERVER from env (even "" = inherit) → respected as-is + # 2. profile match for this VLAN tag → use its DNS + # 3. static IP, no profile → ask + # 4. DHCP, no profile → inherit from host + apply_network_profile + if [[ -n "${NAMESERVER+x}" ]]; then + : # explicit override from env, leave untouched + elif [[ -n "$PROFILE_DNS" ]]; then + NAMESERVER="$PROFILE_DNS" + msg_info "DNS for VLAN ${VLAN_TAG:-none} (${PROFILE_SUBNET:-?}): $NAMESERVER" + elif [[ "$IPCFG" != "dhcp" ]]; then local default_ns="${DEFAULT_NAMESERVER:-$GATEWAY}" read -rp "DNS server [$default_ns] (empty = inherit from PVE host): " NAMESERVER NAMESERVER="${NAMESERVER:-$default_ns}" + else + msg_warn "No network profile for VLAN ${VLAN_TAG:-none}; DHCP DNS will be inherited." fi } @@ -165,11 +211,11 @@ create_lxc() { --ostype debian --password "$ROOT_PASSWORD" ) - [[ -n "${NAMESERVER:-}" ]] && pct_args+=(--nameserver "$NAMESERVER") + [[ -n "${NAMESERVER:-}" ]] && pct_args+=(--nameserver "${NAMESERVER//,/ }") msg_info "Creating unprivileged LXC $CTID ($CT_HOSTNAME)..." msg_info " net0: $net_opts" - [[ -n "${NAMESERVER:-}" ]] && msg_info " dns: $NAMESERVER" + [[ -n "${NAMESERVER:-}" ]] && msg_info " dns: ${NAMESERVER//,/ }" pct create "${pct_args[@]}" msg_ok "LXC $CTID created" -- 2.54.0