#!/bin/bash # Deploy the Proxmox datacenter-level firewall from # config/pve-firewall/cluster.fw.example, with the management CIDR filled # in, and enable it. Default-deny inbound; allow SSH/8006 from mgmt only. # # Idempotent - safe to re-run. Run as root on the PVE host. # # Usage: MGMT_CIDR=192.168.2.0/24 ./deploy-firewall.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=lib/common.sh source "${SCRIPT_DIR}/lib/common.sh" require_root if [ -z "${MGMT_CIDR:-}" ]; then echo "MGMT_CIDR is not set. Example: MGMT_CIDR=192.168.2.0/24 $0" >&2 exit 1 fi if ! [[ "$MGMT_CIDR" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$ ]]; then echo "MGMT_CIDR '${MGMT_CIDR}' doesn't look like a CIDR (e.g. 192.168.2.0/24)." >&2 exit 1 fi TEMPLATE="${SCRIPT_DIR}/../config/pve-firewall/cluster.fw.example" if [ ! -f "$TEMPLATE" ]; then echo "Template not found: $TEMPLATE" >&2 exit 1 fi # Corosync/Ceph rules stay commented placeholders until Stage 2 (cluster); # only the mgmt IPSET is real for a single Stage 1 node. mkdir -p /etc/pve/firewall write_if_changed "/etc/pve/firewall/cluster.fw" "$(sed "s||${MGMT_CIDR}|" "$TEMPLATE")" echo "Validating ruleset..." pve-firewall compile echo "Restarting pve-firewall..." pve-firewall restart sleep 1 pve-firewall status echo echo "Firewall enabled. SSH (22) and the web UI (8006) are now only reachable" echo "from ${MGMT_CIDR}. If your current SSH session is NOT from that range," echo "reconnect and verify access before closing this session."