179 lines
7.3 KiB
Bash
Executable File
179 lines
7.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ==============================================================================
|
|
# ISPConfig Proxy Sync Script - Version 3.35 (Safe Lock & Auto-Subdomain)
|
|
# ==============================================================================
|
|
|
|
LOCKFILE="/tmp/restart.syncproxy.lock"
|
|
|
|
# Sichern gegen Mehrfachstart
|
|
lockfile -r 0 "$LOCKFILE" || exit 1
|
|
|
|
# TRAP: Stellt sicher, dass das Lockfile bei JEDEM Beenden gelöscht wird
|
|
trap 'rm -f "$LOCKFILE"' EXIT
|
|
|
|
# --- KONFIGURATION ---
|
|
CONF_FILE="/usr/local/bin/sync-ispconfig-proxy.conf"
|
|
SERVER_LIST="/usr/local/bin/proxy_based_server.conf"
|
|
LAST_ID_FILE="/var/local/sync-ispconfig-last-id"
|
|
|
|
# --- GLOBALE VARIABLEN ---
|
|
TARGET_DOMAIN=""
|
|
FORCE_ALL=false
|
|
RENEW_CERT=false
|
|
TEST_MODE=false
|
|
DEBUG_MODE=false
|
|
UPDATE_LAST_ID=false
|
|
PROCESSED_DOMAINS=" "
|
|
|
|
# --- FUNKTIONEN ---
|
|
|
|
load_config() {
|
|
[ -f "$CONF_FILE" ] && source "$CONF_FILE" || { echo "Fehler: $CONF_FILE fehlt"; exit 1; }
|
|
}
|
|
|
|
parse_params() {
|
|
for arg in "$@"; do
|
|
case $arg in
|
|
test) TEST_MODE=true ;;
|
|
-debug) DEBUG_MODE=true ;;
|
|
force) FORCE_ALL=true ;;
|
|
renew|repair) RENEW_CERT=true ;;
|
|
*) TARGET_DOMAIN="$arg" ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
get_server_array() {
|
|
sed -n "/^\[server\]/,/^\[/p" "$SERVER_LIST" | grep -v '^\[' | grep -v '^#' | sed '/^$/d' | tr -d '\r' | xargs
|
|
}
|
|
|
|
write_nginx_config() {
|
|
local domain=$1
|
|
local target_ip=$2
|
|
local redirect_path=$3
|
|
local sub_type=$4 # Feld 'subdomain' aus ISPConfig
|
|
local cert_dir="/root/.acme.sh/${domain}_ecc"
|
|
local config_path="$NGINX_CONF_DIR/${domain}.conf"
|
|
|
|
# Server-Namen nur um www erweitern, wenn subdomain auf 'www' steht
|
|
local s_names="$domain"
|
|
[[ "$sub_type" == "www" ]] && s_names="$domain www.$domain"
|
|
|
|
local ssl_block=""
|
|
local if_ssl=""
|
|
|
|
if [ -f "$cert_dir/fullchain.cer" ]; then
|
|
if_ssl="if (\$scheme != \"https\") { return 301 https://\$host\$request_uri; }"
|
|
ssl_block="listen 443 ssl http2; listen [::]:443 ssl http2;
|
|
ssl_certificate $cert_dir/fullchain.cer;
|
|
ssl_certificate_key $cert_dir/${domain}.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_prefer_server_ciphers off;
|
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;"
|
|
fi
|
|
|
|
local proxy_settings="
|
|
proxy_set_header Host \$host;
|
|
proxy_set_header X-Real-IP \$remote_addr;
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
proxy_buffer_size 128k;
|
|
proxy_buffers 4 256k;
|
|
proxy_busy_buffers_size 256k;
|
|
proxy_read_timeout 90;"
|
|
|
|
local local_root=""
|
|
[ -d "/var/www/${domain}/web" ] && local_root="root /var/www/${domain}/web/; index index.php index.html;"
|
|
|
|
local path_block=""
|
|
[[ "$redirect_path" == /* && "$redirect_path" != "/urldummy/" ]] && path_block="location ${redirect_path} { $if_ssl proxy_pass http://[$target_ip]:80${redirect_path}; $proxy_settings proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection \"upgrade\"; }"
|
|
|
|
cat <<EOF > "$config_path"
|
|
server {
|
|
$ssl_block
|
|
listen 80; listen [::]:80;
|
|
server_name $s_names;
|
|
$local_root
|
|
location /.well-known/acme-challenge/ { root /var/www/html; }
|
|
$if_ssl
|
|
$path_block
|
|
location / {
|
|
$( [ -n "$local_root" ] && echo "try_files \$uri \$uri/ @proxy;" || echo "proxy_pass http://[$target_ip]:80;" )
|
|
$( [ -n "$local_root" ] || echo "$proxy_settings" )
|
|
}
|
|
$( [ -n "$local_root" ] && echo "location @proxy { proxy_pass http://[$target_ip]:80; $proxy_settings }")
|
|
}
|
|
EOF
|
|
}
|
|
|
|
main() {
|
|
parse_params "$@"
|
|
load_config
|
|
local servers=$(get_server_array)
|
|
local last_id=$(cat "$LAST_ID_FILE" 2>/dev/null || echo 0)
|
|
local global_filter=""
|
|
|
|
if [ -n "$TARGET_DOMAIN" ]; then
|
|
global_filter="AND (wd.domain = '${TARGET_DOMAIN}' OR parent.domain = '${TARGET_DOMAIN}')"
|
|
elif [ "$FORCE_ALL" = false ] && [ "$TEST_MODE" = false ]; then
|
|
# Nutzt dbidx für ISPConfig 3.3.0p3
|
|
local raw_ids=$(mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" -Bse "SELECT DISTINCT dbidx FROM sys_datalog WHERE dbtable = 'web_domain' AND datalog_id > $last_id;" 2>/dev/null)
|
|
[ $? -ne 0 ] && { echo "FEHLER: SQL-Abfrage fehlgeschlagen." >&2; exit 1; }
|
|
|
|
local changed_ids=$(echo "$raw_ids" | grep -oE '[0-9]+')
|
|
if [ -z "$changed_ids" ]; then exit 0; fi
|
|
|
|
global_filter="AND wd.domain_id IN ($(echo "$changed_ids" | paste -sd "," -))"
|
|
UPDATE_LAST_ID=true
|
|
else
|
|
UPDATE_LAST_ID=true
|
|
fi
|
|
|
|
for CURRENT_SERVER in $servers; do
|
|
echo "=== Server: $CURRENT_SERVER ==="
|
|
local sql_query="SELECT CONCAT_WS('|', wd.domain, IF(wd.ipv6_address != '', wd.ipv6_address, parent.ipv6_address), IFNULL(wd.redirect_path, ''), IFNULL(wd.subdomain, ''), wd.active)
|
|
FROM web_domain wd JOIN server s ON wd.server_id = s.server_id LEFT JOIN web_domain parent ON wd.parent_domain_id = parent.domain_id
|
|
WHERE TRIM(s.server_name) = TRIM('$CURRENT_SERVER') AND wd.type IN ('vhost', 'alias', 'vhostalias', 'subdomain', 'vhostsubdomain') $global_filter ORDER BY wd.domain_id ASC;"
|
|
|
|
[ "$DEBUG_MODE" = true ] && echo "[DEBUG] Query: $sql_query"
|
|
local sql_result=$(mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" -N -B -e "$sql_query")
|
|
|
|
while read -r row; do
|
|
[ -z "$row" ] && continue
|
|
local domain=$(echo "$row" | cut -d'|' -f1)
|
|
local target_ip=$(echo "$row" | cut -d'|' -f2)
|
|
local redirect_path=$(echo "$row" | cut -d'|' -f3)
|
|
local sub_type=$(echo "$row" | cut -d'|' -f4)
|
|
local is_active=$(echo "$row" | cut -d'|' -f5)
|
|
|
|
[[ "$is_active" != "y" || "$PROCESSED_DOMAINS" == *" $domain "* || "$redirect_path" == "/urldummy/" ]] && continue
|
|
[[ "$target_ip" == *"222:1808"* || "$target_ip" == *"113"* ]] && target_ip="2a01:4f8:130:516e::113"
|
|
[ -z "$target_ip" ] && continue
|
|
|
|
echo " [OK] $domain -> $target_ip"
|
|
if [ "$TEST_MODE" = false ]; then
|
|
write_nginx_config "$domain" "$target_ip" "$redirect_path" "$sub_type"
|
|
nginx -t >/dev/null 2>&1 && systemctl reload nginx
|
|
|
|
local cert_dir="/root/.acme.sh/${domain}_ecc"
|
|
if [ ! -f "$cert_dir/fullchain.cer" ] || [ "$RENEW_CERT" = true ]; then
|
|
local acme_cmd="/root/.acme.sh/acme.sh --issue -d $domain"
|
|
[[ "$sub_type" == "www" ]] && acme_cmd="$acme_cmd -d www.$domain"
|
|
$acme_cmd -w /var/www/html --server letsencrypt --ecc --force
|
|
|
|
[ -f "$cert_dir/fullchain.cer" ] && write_nginx_config "$domain" "$target_ip" "$redirect_path" "$sub_type"
|
|
fi
|
|
PROCESSED_DOMAINS="${PROCESSED_DOMAINS}${domain} "
|
|
fi
|
|
done <<< "$sql_result"
|
|
done
|
|
|
|
if [ "$TEST_MODE" = false ]; then
|
|
nginx -t && systemctl reload nginx
|
|
[ "$UPDATE_LAST_ID" = true ] && mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" -Bse "SELECT MAX(datalog_id) FROM sys_datalog;" > "$LAST_ID_FILE"
|
|
fi
|
|
}
|
|
|
|
main "$@"
|