浏览代码

updated the ipset startup script
the name of the DB server variable in the initial backend config has been changed to DBHOST
fixed the update procedure - only installed components are updated, not the entire backend.

Roman Dmitriev 2 周之前
父节点
当前提交
7b62040d44
共有 3 个文件被更改,包括 212 次插入101 次删除
  1. 183 73
      docs/systemd/init.d/ipset
  2. 26 15
      install-eye.sh
  3. 3 13
      scripts/cfg/config.sample

+ 183 - 73
docs/systemd/init.d/ipset

@@ -1,95 +1,205 @@
-#! /bin/bash
-
-#
+#!/bin/bash
 ### BEGIN INIT INFO
-# Provides: ipset
-# Required-Start: $local_fs $network $remote_fs $syslog
-# Required-Stop: $local_fs $network $remote_fs $syslog
-# Default-Start:  2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: start and stop the ipset lists
-# Description: start and stop the ipset lists
+# Provides:          ipset
+# Required-Start:    $local_fs $network
+# Required-Stop:     $local_fs
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Atomic restore/swap of ipset from /etc/ipset.d/*.conf
 ### END INIT INFO
 
+IPSET='/sbin/ipset'
+IPSET_DIR='/etc/ipset.d'
+[ -x "$IPSET" ] || exit 1
+
+# LSB logging (if not available, define simple ones)
 if [ -r "/lib/lsb/init-functions" ]; then
-        . /lib/lsb/init-functions
+    . /lib/lsb/init-functions
 else
-        log_success_msg() {
-                echo "$@"
-        }
-        log_warning_msg() {
-                echo "$@" >&2
-        }
-        log_failure_msg() {
-                echo "$@" >&2
-        }
+    log_success_msg() { echo "[ OK ] $*"; }
+    log_failure_msg() { echo "[FAIL] $*" >&2; }
+    log_warning_msg() { echo "[WARN] $*" >&2; }
 fi
 
+# Get base set name from .conf file (filename without .conf)
+get_set_name() {
+    local conf="$1"
+    basename "$conf" .conf
+}
 
-IPSET='/sbin/ipset'
-IPSET_DIR='/etc/ipset.d'
+# Create temporary file with swapped set name (name -> name_new)
+create_temp_ipset_file() {
+    local name="$1"
+    local conf="$IPSET_DIR/$name.conf"
+    local tmpfile="$IPSET_DIR/$name.ipset"
 
-# if the ip configuration utility isn't around we can't function.
-[ -x ${IPSET} ] || exit 1
+    # Replace all occurrences of 'name' as a whole word with 'name_new'
+    # This handles lines: "create name hash:ip ..." -> "create name_new hash:ip ..."
+    # and "add name 1.2.3.4 ..." -> "add name_new 1.2.3.4 ..."
+    sed -E "
+        s/^([[:space:]]*)(create|add)[[:space:]]+$name([[:space:]]|$)/\1\2 ${name}_new\3/g;
+        s/^([[:space:]]*)(create|add)[[:space:]]+$name([[:space:]]|$)/\1\2 ${name}_new\3/g
+    " "$conf" > "$tmpfile"
 
-stop_ipset() {
-ls -x -1 "${IPSET_DIR}/"*.conf | while read IPSET_FILE; do
-ipset_name=`grep -P "^create\s+(\S+)\s+" "${IPSET_FILE}"  | awk '{ print $2 }' | sed 's/_new//'`
-[ -z "${ipset_name}" ] && continue
-echo -n $"Destroy ${ipset_name} ipset"
-${IPSET} destroy ${ipset_name} >/dev/null 2>&1
-echo
-done
-return 0
+    echo "$tmpfile"
 }
 
-start_ipset() {
-ls -x -1 "${IPSET_DIR}/"*.conf | while read IPSET_FILE; do
-ipset_name=`grep -P "^create\s+(\S+)\s+" "${IPSET_FILE}"  | awk '{ print $2 }' | sed 's/_new//'`
-if [ ! -e "${IPSET_DIR}/${ipset_name}.ipset" ]; then
-    cat "${IPSET_FILE}" | sed 's/_new//' >"${IPSET_DIR}/${ipset_name}.ipset"
+# Load entries into a set from a file (which may be a full ipset save format)
+load_from_file() {
+    local setname="$1"
+    local file="$2"
+    "$IPSET" restore -! < "$file" 2>/dev/null
+}
+
+# Atomically replace live set with new configuration
+replace_atomic() {
+    local name="$1"
+    local conf="$IPSET_DIR/$name.conf"
+    local tmpfile
+
+    # 1. Create temporary ipset file with name_new
+    tmpfile=$(create_temp_ipset_file "$name")
+    if [ ! -s "$tmpfile" ]; then
+        log_failure_msg "Failed to create temporary ipset file for $name"
+        rm -f "$tmpfile"
+        return 1
+    fi
+
+    # 2. Create temporary ipset set (if already exists, destroy it first)
+    if "$IPSET" list "${name}_new" &>/dev/null; then
+        "$IPSET" destroy "${name}_new" 2>/dev/null
+    fi
+    # Extract type from conf to create empty set (necessary before restore)
+    local type=$(sed -n -E 's/^create\s+'"$name"'\s+(\S+).*/\1/p' "$conf" | head -1)
+    if [ -z "$type" ]; then
+        log_failure_msg "Cannot determine type for $name from $conf"
+        rm -f "$tmpfile"
+        return 1
+    fi
+    if ! "$IPSET" create "${name}_new" "$type" comment 2>/dev/null; then
+        log_failure_msg "Cannot create temporary set ${name}_new"
+        rm -f "$tmpfile"
+        return 1
+    fi
+
+    # 3. Load data into temporary set
+    if ! load_from_file "${name}_new" "$tmpfile"; then
+        log_failure_msg "Failed to load data into ${name}_new"
+        "$IPSET" destroy "${name}_new" 2>/dev/null
+        rm -f "$tmpfile"
+        return 1
+    fi
+
+    # 4. Atomic swap
+    if ! "$IPSET" swap "${name}_new" "$name"; then
+        log_failure_msg "Atomic swap failed for $name"
+        "$IPSET" destroy "${name}_new" 2>/dev/null
+        rm -f "$tmpfile"
+        return 1
     fi
-echo -n $"Load ${ipset_name} ipset"
-${IPSET} restore -file "${IPSET_DIR}/${ipset_name}.ipset" >/dev/null 2>&1
-echo
-done
-return 0
+
+    # 5. Destroy old set (now named _new) and remove temp file
+    "$IPSET" destroy "${name}_new" 2>/dev/null
+    rm -f "$tmpfile"
+    log_success_msg "Atomically replaced ipset $name"
+    return 0
+}
+
+# Simple restore (when set does not exist)
+restore_simple() {
+    local name="$1"
+    local conf="$IPSET_DIR/$name.conf"
+    if "$IPSET" restore -! < "$conf" 2>/dev/null; then
+        log_success_msg "Restored ipset $name from $conf"
+        return 0
+    else
+        log_failure_msg "Failed to restore $name from $conf"
+        return 1
+    fi
+}
+
+start_ipset() {
+    local ret=0
+    for conf in "$IPSET_DIR"/*.conf; do
+        [ -f "$conf" ] || continue
+        name=$(get_set_name "$conf")
+        [ -z "$name" ] && continue
+
+        if "$IPSET" list "$name" &>/dev/null; then
+            # Set already exists → atomic replace
+            replace_atomic "$name" || ret=1
+        else
+            # Set does not exist → simple restore
+            restore_simple "$name" || ret=1
+        fi
+    done
+    return $ret
+}
+
+stop_ipset() {
+    local ret=0
+    for conf in "$IPSET_DIR"/*.conf; do
+        [ -f "$conf" ] || continue
+        name=$(get_set_name "$conf")
+        [ -z "$name" ] && continue
+        if "$IPSET" list "$name" &>/dev/null; then
+            "$IPSET" destroy "$name" 2>/dev/null || ret=1
+            log_success_msg "Destroyed $name"
+        fi
+        # Also clean any leftover temporary sets
+        if "$IPSET" list "${name}_new" &>/dev/null; then
+            "$IPSET" destroy "${name}_new" 2>/dev/null
+            log_success_msg "Destroyed leftover ${name}_new"
+        fi
+        # Remove any stray .ipset temp files (if left)
+        rm -f "$IPSET_DIR/$name.ipset"
+    done
+    return $ret
 }
 
 save_ipset() {
-ls -x -1 "${IPSET_DIR}/"*.conf | while read IPSET_FILE; do
-ipset_name=`grep -P "^create\s+(\S+)\s+" "${IPSET_FILE}"  | awk '{ print $2 }' | sed 's/_new//'`
-[ -z "${ipset_name}" ] && continue
-echo -n $"Save ${ipset_name} ipset"
-${IPSET} save ${ipset_name} -file "${IPSET_DIR}/${ipset_name}.ipset" >/dev/null 2>&1
-echo
-done
-return 0
+    local ret=0
+    for name in $(ipset list -n); do
+        [ -z "$name" ] && continue
+        conf="$IPSET_DIR/$name"
+        if "$IPSET" save "$name" > "$conf.tmp" 2>/dev/null; then
+                mv "$conf.tmp" "$conf.conf"
+                log_success_msg "Saved $name to $conf.conf"
+            else
+                rm -f "$conf.tmp"
+                log_failure_msg "Failed to save $name"
+                ret=1
+            fi
+    done
+    return $ret
+}
+
+status_ipset() {
+    local ret=0
+    for conf in "$IPSET_DIR"/*.conf; do
+        [ -f "$conf" ] || continue
+        name=$(get_set_name "$conf")
+        [ -z "$name" ] && continue
+        if "$IPSET" list "$name" &>/dev/null; then
+            echo "$name loaded"
+        else
+            echo "$name NOT loaded"
+            ret=1
+        fi
+    done
+    return $ret
 }
 
-# See how we were called.
 case "$1" in
-  start)
-        start_ipset
-        RET=$?
-        ;;
-  stop)
-        stop_ipset
-        RET=$?
-        ;;
-  save)
-        save_ipset
-        RET=$?
-        ;;
-  restart|reload)
-        stop_ipset
-        start_ipset
-        RET=$?
-        ;;
-  *)
-        echo $"Usage: $0 {start|stop|restart|reload}"
+    start)   start_ipset ;;
+    stop)    stop_ipset ;;
+    restart) stop_ipset; start_ipset ;;
+    reload)  stop_ipset; start_ipset ;;
+    save)    save_ipset ;;
+    status)  status_ipset ;;
+    *)
+        echo "Usage: $0 {start|stop|restart|reload|save|status}"
         exit 1
 esac
 
-exit ${RET}
-
+exit $?

+ 26 - 15
install-eye.sh

@@ -641,18 +641,17 @@ upgrade_source_code() {
     if [[ "$INSTALL_TYPE" == "full" || "$INSTALL_TYPE" == "backend" ]]; then
         print_info "Updating backend scripts..."
         mkdir -p /opt/Eye/scripts/{cfg,log}
-        rsync -a --exclude cfg/ scripts/  /opt/Eye/scripts/
-        rsync -ar scripts/eyelib/   /opt/Eye/scripts/eyelib/
+        rsync -lpt scripts/ /opt/Eye/scripts/
+        rsync -a scripts/eyelib/   /opt/Eye/scripts/eyelib/
         # Обновляем только если каталог уже установлен
-        [[ -d /opt/Eye/scripts/updates ]] && rsync -ar scripts/updates/ /opt/Eye/scripts/updates/
-        [[ -d /opt/Eye/scripts/utils   ]] && rsync -ar scripts/utils/   /opt/Eye/scripts/utils/
+        [[ -d /opt/Eye/scripts/updates ]] && rsync -a scripts/updates/ /opt/Eye/scripts/updates/
+        [[ -d /opt/Eye/scripts/utils   ]] && rsync -a scripts/utils/   /opt/Eye/scripts/utils/
 
         chmod 750 /opt/Eye/scripts
         chmod 770 /opt/Eye/scripts/log
         chown -R eye:eye /opt/Eye/scripts
 
-        declare -a SERVICES
-        SERVICES=(
+        declare -a SERVICES=(
             dhcp-log.service
             dhcp-log-truncate.service
             eye-statd.service
@@ -661,20 +660,32 @@ upgrade_source_code() {
         )
 
         SYSTEMD_CHANGED=0
-        declare -a RESTART_SERVICES
-        RESTART_SERVICES=()
+        declare -a RESTART_SERVICES=()
+
         for svc in "${SERVICES[@]}"; do
+
+            if ! systemctl is-enabled --quiet "$svc" 2>/dev/null; then
+                print_info "SKIP $svc: not enabled/installed in systemd"
+                continue
+            fi
+
             SRC="/opt/Eye/docs/systemd/$svc"
+            [[ -f "$SRC" ]] || { print_info "SKIP $svc: source file missing"; continue; }
+
             DST="/etc/systemd/system/$svc"
-            if [[ -f "$SRC" && -f "$DST" ]]; then
-                if ! cmp -s "$SRC" "$DST"; then
-                    print_info "Updating $svc"
-                    cp "$SRC" "$DST"
-                    SYSTEMD_CHANGED=1
-                    RESTART_SERVICES+=("$svc")
-                fi
+
+            if [[ ! -f "$DST" ]] || ! cmp -s "$SRC" "$DST"; then
+                print_info "Updating $svc"
+                cp -f "$SRC" "$DST"
+                chmod 644 "$DST"
+                SYSTEMD_CHANGED=1
+                RESTART_SERVICES+=("$svc")
+                print_info "COPIED $SRC -> $DST"
+            else
+                print_info "SKIP $svc: file identical"
             fi
         done
+
         if [[ $SYSTEMD_CHANGED -eq 1 ]]; then
             systemctl daemon-reload
             for svc in "${RESTART_SERVICES[@]}"; do

+ 3 - 13
scripts/cfg/config.sample

@@ -11,16 +11,12 @@ admin_email=admin@example.com
 from_addr=admin@example.com
 
 #database - change it!!!
-DBSERVER=localhost
+DBHOST=localhost
 DBTYPE=db_type
 DBUSER=db_user
 DBNAME=db_name
 DBPASS=db_password
 
-#login for windows AD
-#domain_auth=EXAMPLE\roman%password
-#winexe=/usr/bin/winexe
-
 #fping
 fping=/sbin/fping
 
@@ -28,10 +24,8 @@ fping=/sbin/fping
 MYSQL=/usr/bin/mysql
 
 #log file owners
-#user=nagios
-#group=nagios
-user=www-data
-group=www-data
+user=eye
+group=eye
 
 #nagios settings
 nagios_dir=/etc/nagios4
@@ -41,7 +35,3 @@ nagios_event_socket=/var/spool/nagios4/hoststate.socket
 #crypt config - 8/16/24 char and equal length
 encryption_key=!!!CHANGE_ME!!!!
 encryption_iv=0123456789012345
-
-#api_base=http://127.0.0.1/api.php
-#api_key=<USER_KEY>
-#api_login=<USER_LOGIN>