#!/usr/bin/env bash # ----------------------------------------------------------------- # Proxmox Add-IPs (LXC + VMs → Tags) # ----------------------------------------------------------------- # © 2021-2025 community-scripts ORG # Author: MickLesk (CanbiZ) # License: MIT # ----------------------------------------------------------------- APP="Proxmox Add-IPs" FILE_PATH="/usr/local/bin/prx-add-ips" CONF_DIR="/opt/prx-add-ips" CONF_FILE="$CONF_DIR/prx-add-ips.conf" set -Eeuo pipefail # --- Farben (optional) --- YW="\033[33m" GN="\033[1;92m" RD="\033[01;31m" CL="\033[m" msg() { [[ "${USE_COLOR:-true}" == "true" ]] && echo -e "$@" || echo -e "$(echo "$@" | sed -E 's/\x1B\[[0-9;]*[JKmsu]//g')"; } msg_info() { msg "${YW}➜ $1${CL}"; } msg_ok() { msg "${GN}✔ $1${CL}"; } msg_error() { msg "${RD}✖ $1${CL}"; } # ----------------------------------------------------------------- # Installation # ----------------------------------------------------------------- if [[ -f "$FILE_PATH" ]]; then msg_info "$APP already installed at $FILE_PATH" exit 0 fi msg_info "Installing dependencies" apt-get update -qq apt-get install -y jq ipcalc net-tools >/dev/null msg_ok "Dependencies installed" mkdir -p "$CONF_DIR" # ----------------------------------------------------------------- # Config # ----------------------------------------------------------------- if [[ ! -f "$CONF_FILE" ]]; then cat <"$CONF_FILE" # prx-add-ips.conf – configuration for Proxmox Add-IPs # Allowed CIDRs CIDR_LIST=( 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12 ) # Main loop interval in seconds LOOP_INTERVAL=60 # Use colored output? (true/false) USE_COLOR=true EOF msg_ok "Default config written to $CONF_FILE" else msg_info "Config $CONF_FILE already exists" fi # ----------------------------------------------------------------- # Main Script # ----------------------------------------------------------------- cat <<"EOF" >"$FILE_PATH" #!/usr/bin/env bash set -Eeuo pipefail CONFIG_FILE="/opt/prx-add-ips/prx-add-ips.conf" [[ -f "$CONFIG_FILE" ]] && source "$CONFIG_FILE" YW="\033[33m"; GN="\033[1;92m"; RD="\033[01;31m"; CL="\033[m" msg() { [[ "${USE_COLOR:-true}" == "true" ]] && echo -e "$@" || echo -e "$(echo "$@" | sed -E 's/\x1B\[[0-9;]*[JKmsu]//g')"; } msg_info() { msg "${YW}➜ $1${CL}"; } msg_ok() { msg "${GN}✔ $1${CL}"; } msg_error(){ msg "${RD}✖ $1${CL}"; } is_valid_ipv4() { local ip=$1 [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1 for part in ${ip//./ }; do ((part >= 0 && part <= 255)) || return 1 done return 0 } ip_in_cidrs() { local ip="$1" for cidr in "${CIDR_LIST[@]}"; do ipcalc -nb "$cidr" "$ip" &>/dev/null && return 0 done return 1 } set_tags() { local vmid="$1" kind="$2"; shift 2 local ips=("$@") # aktuelle Tags holen local existing_tags=() mapfile -t existing_tags < <($kind config "$vmid" | awk '/tags:/{$1=""; print}' | tr ';' '\n') local existing_ips=() local non_ip_tags=() for t in "${existing_tags[@]}"; do if is_valid_ipv4 "$t"; then existing_ips+=("$t") else non_ip_tags+=("$t") fi done local new_tags=("${non_ip_tags[@]}" "${ips[@]}") new_tags=($(printf "%s\n" "${new_tags[@]}" | sort -u)) if [[ "$(printf "%s\n" "${existing_ips[@]}" | sort -u)" != "$(printf "%s\n" "${ips[@]}" | sort -u)" ]]; then msg_info "$kind $vmid → updating tags to ${new_tags[*]}" $kind set "$vmid" -tags "$(IFS=';'; echo "${new_tags[*]}")" else msg_info "$kind $vmid → no IP change" fi } update_lxc_iptags() { for vmid in $(pct list | awk 'NR>1 {print $1}'); do local ips=() for ip in $(lxc-info -n "$vmid" -iH 2>/dev/null); do is_valid_ipv4 "$ip" && ip_in_cidrs "$ip" && ips+=("$ip") done [[ ${#ips[@]} -gt 0 ]] && set_tags "$vmid" pct "${ips[@]}" done } update_vm_iptags() { for vmid in $(qm list | awk 'NR>1 {print $1}'); do if qm agent "$vmid" ping &>/dev/null; then local ips=() mapfile -t ips < <(qm agent "$vmid" network-get-interfaces \ | jq -r '.[]?."ip-addresses"[]?."ip-address" | select(test("^[0-9]+\\."))') local filtered=() for ip in "${ips[@]}"; do is_valid_ipv4 "$ip" && ip_in_cidrs "$ip" && filtered+=("$ip") done [[ ${#filtered[@]} -gt 0 ]] && set_tags "$vmid" qm "${filtered[@]}" fi done } while true; do update_lxc_iptags update_vm_iptags sleep "${LOOP_INTERVAL:-60}" done EOF chmod +x "$FILE_PATH" msg_ok "Main script installed to $FILE_PATH" # ----------------------------------------------------------------- # Systemd Service # ----------------------------------------------------------------- SERVICE="/etc/systemd/system/prx-add-ips.service" if [[ ! -f "$SERVICE" ]]; then cat <"$SERVICE" [Unit] Description=Proxmox Add-IPs (LXC + VM) After=network.target [Service] Type=simple ExecStart=$FILE_PATH Restart=always [Install] WantedBy=multi-user.target EOF msg_ok "Service created" fi systemctl daemon-reload systemctl enable -q --now prx-add-ips.service msg_ok "$APP service started"