#!/usr/bin/env bash # UFW на бэкенде: сервисный порт только с HAProxy (+ admin/extra). # # cp backend-ufw.env.example /etc/haproxy/security/backend-ufw.env # ./backend-ufw-from-haproxy.sh --apply set -Eeuo pipefail ENV_FILE="${BACKEND_UFW_ENV:-/etc/haproxy/security/backend-ufw.env}" APPLY=0 die() { echo "error: $*" >&2; exit 1; } log() { echo "[*] $*"; } while [[ $# -gt 0 ]]; do case "$1" in --apply) APPLY=1; shift ;; --env-file) ENV_FILE=$2; shift 2 ;; -h | --help) echo "Usage: $0 [--apply] [--env-file PATH]" exit 0 ;; *) die "unknown option: $1" ;; esac done [[ -f $ENV_FILE ]] || die "missing env: $ENV_FILE" # shellcheck source=/dev/null source "$ENV_FILE" HAPROXY_IP=${HAPROXY_IP:-192.168.160.117} BACKEND_PORT=${BACKEND_PORT:-} ADMIN_ALLOWED=${ADMIN_ALLOWED:-} EXTRA_ALLOWED=${EXTRA_ALLOWED:-} UFW_EXTRA_SERVICES=${UFW_EXTRA_SERVICES:-} UFW_IPV6=${UFW_IPV6:-no} [[ -n $BACKEND_PORT ]] || die "BACKEND_PORT required" command -v ufw >/dev/null 2>&1 || die "ufw not installed" run() { log "$*" [[ $APPLY -eq 1 ]] && "$@" } [[ $APPLY -eq 0 ]] && echo "=== DRY-RUN (pass --apply) ===" if [[ $APPLY -eq 1 ]]; then sed -i "s/^IPV6=.*/IPV6=${UFW_IPV6}/" /etc/default/ufw 2>/dev/null || true fi run ufw --force reset run ufw default deny incoming run ufw default allow outgoing run ufw allow from "$HAPROXY_IP" to any port "$BACKEND_PORT" proto tcp comment 'haproxy' for cidr in $EXTRA_ALLOWED; do [[ -z $cidr ]] && continue run ufw allow from "$cidr" to any port "$BACKEND_PORT" proto tcp comment 'extra' done for cidr in $ADMIN_ALLOWED; do [[ -z $cidr ]] && continue run ufw allow from "$cidr" to any port 22 proto tcp comment 'admin ssh' for svc in $UFW_EXTRA_SERVICES; do [[ -z $svc ]] && continue run ufw allow from "$cidr" to any port "$svc" comment 'admin extra' done done if [[ $APPLY -eq 1 ]]; then ufw --force enable ufw status verbose log "done port=$BACKEND_PORT haproxy=$HAPROXY_IP" else echo "=== end dry-run ===" fi