Files
clownfischserver/scripts/clownfischserver-homeip-updater.sh
T
root f2fdf95897 v0.5.0: Add RBAC auth, LLM router, audit logging, output sanitization
- New: auth.py – Role-based access (operator/approver/viewer)
- New: llm_router.py – Configurable primary/fallback provider chain
- New: audit_log.py + audit_query.py – DSGVO-compliant audit trail
- New: sanitize_output() – masks secrets in bot responses
- Updated: bot.py – Integrated auth guards, router, audit logging
- Updated: ollama_client.py – Router-compatible interface
- Updated: CLOWNFISCHSERVER.md – Documentation updated
- Updated: README.md – Documentation updated
2026-06-26 20:41:35 +02:00

175 lines
4.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# =============================================================================
# 🐠 CLOWNFISCHSERVER – HomeIP Auto-Update
# Purpose: Auto-update firewall rule for dynamic home IP (myfritz.net)
# Runs: Every 5 minutes (via cron)
# Author: Mehlzoerwer-Claude
# License: GPL-3.0
# =============================================================================
set -e
# --- Configuration ---
INSTALL_DIR="/opt/clownfischserver"
ENV_FILE="$INSTALL_DIR/config/.env"
STATE_FILE="/var/lib/clownfischserver-homeip-state"
LOG_FILE="/var/log/clownfischserver-homeip-updater.log"
SSH_PORT=22
# --- Helpers ---
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
}
# --- Load .env ---
load_env() {
if [ ! -f "$ENV_FILE" ]; then
log "ERROR: .env not found at $ENV_FILE"
exit 1
fi
# Load and trim CRLF/LF
MYFRITZ_DOMAIN=$(grep "^CLOWNFISCHSERVER_HOME_IP_DOMAIN=" "$ENV_FILE" | cut -d= -f2 | tr -d '\r\n')
if [ -z "$MYFRITZ_DOMAIN" ]; then
log "ERROR: CLOWNFISCHSERVER_HOME_IP_DOMAIN not set in .env"
exit 1
fi
}
# --- Detect Firewall ---
detect_firewall() {
if systemctl is-active --quiet ufw; then
echo "ufw"
elif systemctl is-active --quiet firewalld; then
echo "firewalld"
elif command -v iptables &>/dev/null; then
echo "iptables"
else
log "ERROR: No firewall detected (ufw/firewalld/iptables)"
exit 1
fi
}
# --- Resolve DNS with fallbacks ---
resolve_ip() {
local domain="$1"
# Try dig first
if command -v dig &>/dev/null; then
IP=$(dig +short "$domain" A | grep -oE '^[0-9.]+$' | head -1)
[ -n "$IP" ] && echo "$IP" && return 0
fi
# Try nslookup
if command -v nslookup &>/dev/null; then
IP=$(nslookup "$domain" 2>/dev/null | grep "Address:" | tail -1 | awk '{print $2}' | grep -oE '^[0-9.]+$')
[ -n "$IP" ] && echo "$IP" && return 0
fi
# Try getent
if command -v getent &>/dev/null; then
IP=$(getent hosts "$domain" | awk '{print $1}' | grep -oE '^[0-9.]+$' | head -1)
[ -n "$IP" ] && echo "$IP" && return 0
fi
log "ERROR: Could not resolve $domain"
return 1
}
# --- Load previous state ---
load_state() {
if [ -f "$STATE_FILE" ]; then
PREVIOUS_IP=$(cat "$STATE_FILE" | grep "^IP=" | cut -d= -f2)
echo "$PREVIOUS_IP"
else
echo ""
fi
}
# --- Save state ---
save_state() {
local ip="$1"
echo "IP=$ip" > "$STATE_FILE"
chmod 600 "$STATE_FILE"
}
# --- UFW Functions ---
ufw_add_rule() {
local ip="$1"
ufw allow from "$ip" to any port "$SSH_PORT" comment "clownfisch-homeip" >/dev/null 2>&1
log "UFW: Added rule for $ip:$SSH_PORT"
}
ufw_remove_rule() {
local ip="$1"
echo "y" | ufw delete allow from "$ip" to any port "$SSH_PORT" >/dev/null 2>&1
log "UFW: Deleted rule for $ip"
}
# --- Firewalld Functions ---
firewalld_add_rule() {
local ip="$1"
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='$ip' port protocol='tcp' port='$SSH_PORT' accept" >/dev/null 2>&1
firewall-cmd --reload >/dev/null 2>&1
log "firewalld: Added rule for $ip:$SSH_PORT"
}
firewalld_remove_rule() {
local ip="$1"
firewall-cmd --permanent --remove-rich-rule="rule family='ipv4' source address='$ip' port protocol='tcp' port='$SSH_PORT' accept" >/dev/null 2>&1
firewall-cmd --reload >/dev/null 2>&1
log "firewalld: Deleted rule for $ip"
}
# --- iptables Functions ---
iptables_add_rule() {
local ip="$1"
iptables -I INPUT -s "$ip" -p tcp --dport "$SSH_PORT" -j ACCEPT
log "iptables: Added rule for $ip:$SSH_PORT"
}
iptables_remove_rule() {
local ip="$1"
iptables -D INPUT -s "$ip" -p tcp --dport "$SSH_PORT" -j ACCEPT 2>/dev/null || true
log "iptables: Deleted rule for $ip"
}
# --- Main ---
main() {
log "=== HomeIP Auto-Update started ==="
load_env
FIREWALL=$(detect_firewall)
NEW_IP=$(resolve_ip "$MYFRITZ_DOMAIN") || exit 1
PREVIOUS_IP=$(load_state)
if [ "$NEW_IP" = "$PREVIOUS_IP" ]; then
log "No change: $NEW_IP (same as previous)"
exit 0
fi
log "IP change detected: $PREVIOUS_IP → $NEW_IP (firewall: $FIREWALL)"
# Remove old rule
if [ -n "$PREVIOUS_IP" ]; then
case "$FIREWALL" in
ufw) ufw_remove_rule "$PREVIOUS_IP" ;;
firewalld) firewalld_remove_rule "$PREVIOUS_IP" ;;
iptables) iptables_remove_rule "$PREVIOUS_IP" ;;
esac
fi
# Add new rule
case "$FIREWALL" in
ufw) ufw_add_rule "$NEW_IP" ;;
firewalld) firewalld_add_rule "$NEW_IP" ;;
iptables) iptables_add_rule "$NEW_IP" ;;
esac
# Save state
save_state "$NEW_IP"
log "=== HomeIP Auto-Update completed successfully ==="
}
main "$@"