################################################################ ### HMN SLOT LOADER INSPECT ################################################################ INSTANCE=mgts-main MODE=READ_ONLY REMOTE_CHANGES=NO ################################################################ ### SLOT LOADER INVENTORY ################################################################ --- /root/hmn/hmn-load-vpn-slot.sh --- -rwxr-xr-x 1 root root 5125 Jun 3 16:20 /root/hmn/hmn-load-vpn-slot.sh sha256 f6171e7f682e5dc422a9e56c449b7413ea9225c23adef7b07d0802ed8bf93872 /root/hmn/hmn-load-vpn-slot.sh --- /root/hmn/hmn-load-vpn-test.sh --- -rwxr-xr-x 1 root root 4949 Jun 3 16:20 /root/hmn/hmn-load-vpn-test.sh sha256 7407dea5a482e3b872a9d580ab54de238cb33b5331107eca59105fe3eb52c62a /root/hmn/hmn-load-vpn-test.sh --- /root/hmn/hmn-load-vpn-user.sh --- -rwxr-xr-x 1 root root 7032 Jul 6 14:24 /root/hmn/hmn-load-vpn-user.sh sha256 aaa86624aa5d4ea969053dc42ea386602bd4a0deddef8c13352205161e57f82f /root/hmn/hmn-load-vpn-user.sh --- /root/hmn/hmn-refill-slot.sh --- -rwxr-xr-x 1 root root 6084 Jun 3 16:20 /root/hmn/hmn-refill-slot.sh sha256 992b8075c9a5acbcd5c0f98feb03650acc7a211f9cc19afb9fd82ffc529bb053 /root/hmn/hmn-refill-slot.sh rc=0 ################################################################ ### SANITIZED hmn-load-vpn-slot.sh ################################################################ ### FILE /root/hmn/hmn-load-vpn-slot.sh 1 #!/bin/ash 2 3 set -eu 4 5 SLOT="${1:-}" 6 CONF="${2:-}" 7 ACTION="${3:-}" 8 9 case "$SLOT" in 10 vpn1|vpn2) ;; 11 *) 12 echo "ERROR: slot должен быть vpn1 или vpn2" 13 echo "Использование:" 14 echo " /root/hmn/hmn-load-vpn-slot.sh vpn2 /path/to/config.conf" 15 echo " /root/hmn/hmn-load-vpn-slot.sh vpn2 /path/to/config.conf up" 16 exit 1 17 ;; 18 esac 19 20 if [ -z "$CONF" ] || [ ! -f "$CONF" ]; then 21 echo "ERROR: не найден config:" 22 echo " $CONF" 23 exit 1 24 fi 25 26 ACTIVE="$(ip route show table 200 | awk '/^default dev /{print $3; exit}')" 27 28 if [ "$SLOT" = "$ACTIVE" ] && [ "${HMN_ALLOW_ACTIVE_RELOAD:-0}" != "1" ]; then 29 echo "ERROR: refusing to reload active slot: $SLOT" 30 echo "Current table 200 active slot: $ACTIVE" 31 echo 32 echo "Для blue/green сначала грузи конфиг в неактивный слот." 33 echo "Если очень надо принудительно:" 34 echo " HMN_ALLOW_ACTIVE_RELOAD=1 /root/hmn/hmn-load-vpn-slot.sh $SLOT $CONF" 35 exit 1 36 fi 37 38 getv() { 39 KEY="$1" 40 awk -v key="$KEY" ' 41 { 42 sub(/\r$/, "", $0) 43 } 44 $0 ~ "^[[:space:]]*" key "[[:space:]]*=" { 45 sub(/^[^=]*=[[:space:]]*/, "", $0) 46 sub(/[[:space:]]*$/, "", $0) 47 print $0 48 exit 49 } 50 ' "$CONF" 51 } 52 53 PRIVATE_KEY=[REDACTED_PRIVATE_KEY] PrivateKey)" 54 ADDRESS="$(getv Address)" 55 DNS="$(getv DNS)" 56 JC="$(getv Jc)" 57 JMIN="$(getv Jmin)" 58 JMAX="$(getv Jmax)" 59 S1="$(getv S1)" 60 S2="$(getv S2)" 61 H1="$(getv H1)" 62 H2="$(getv H2)" 63 H3="$(getv H3)" 64 H4="$(getv H4)" 65 66 PUBLIC_KEY=[REDACTED_PUBLIC_KEY] PublicKey)" 67 ALLOWED_IPS="$(getv AllowedIPs)" 68 ENDPOINT="$(getv Endpoint)" 69 KEEPALIVE="$(getv PersistentKeepalive)" 70 71 ENDPOINT_HOST="${ENDPOINT%:*}" 72 ENDPOINT_PORT="${ENDPOINT##*:}" 73 74 if [ -z "$PRIVATE_KEY" ] || [ -z "$ADDRESS" ] || [ -z "$PUBLIC_KEY" ] || [ -z "$ENDPOINT_HOST" ] || [ -z "$ENDPOINT_PORT" ]; then 75 echo "ERROR: конфиг не удалось распарсить." 76 echo "CONF=$CONF" 77 echo "Address=$ADDRESS" 78 echo "PrivateKey=[REDACTED_PRIVATE_KEY] 79 echo "PublicKey=[REDACTED_PUBLIC_KEY] 80 echo "Endpoint=$ENDPOINT" 81 exit 1 82 fi 83 84 TS="$(date +%Y%m%d-%H%M%S)" 85 BACKUP="/root/hmn/backups/network-before-load-${SLOT}-$TS" 86 87 mkdir -p /root/hmn/backups 88 chmod 700 /root/hmn /root/hmn/backups 89 90 cp /etc/config/network "$BACKUP" 91 chmod 600 "$BACKUP" 92 93 echo "Backup:" 94 echo " $BACKUP" 95 echo 96 echo "Loading into slot:" 97 echo " slot: $SLOT" 98 echo " config: $CONF" 99 echo " endpoint: $ENDPOINT" 100 echo " address: $ADDRESS" 101 echo " active table 200 before load: ${ACTIVE:-none}" 102 echo 103 104 ifdown "$SLOT" 2>/dev/null || true 105 106 uci -q delete network."$SLOT" || true 107 108 while :; do 109 SEC="$(uci -q show network | sed -n "s/^\(network\.@amneziawg_${SLOT}\[[0-9][0-9]*\]\)=amneziawg_${SLOT}$/\1/p" | head -n 1)" 110 [ -n "$SEC" ] || break 111 uci -q delete "$SEC" 112 done 113 114 uci set network."$SLOT"='interface' 115 uci set network."$SLOT".proto='amneziawg' 116 uci set network."$SLOT".private_key=[REDACTED_PRIVATE_KEY] 117 uci set network."$SLOT".awg_jc="$JC" 118 uci set network."$SLOT".awg_jmin="$JMIN" 119 uci set network."$SLOT".awg_jmax="$JMAX" 120 uci set network."$SLOT".awg_s1="$S1" 121 uci set network."$SLOT".awg_s2="$S2" 122 uci set network."$SLOT".awg_h1="$H1" 123 uci set network."$SLOT".awg_h2="$H2" 124 uci set network."$SLOT".awg_h3="$H3" 125 uci set network."$SLOT".awg_h4="$H4" 126 127 uci set network."$SLOT".auto='0' 128 uci set network."$SLOT".disabled='0' 129 uci set network."$SLOT".delegate='0' 130 uci set network."$SLOT".peerdns='0' 131 uci set network."$SLOT".defaultroute='0' 132 133 uci add_list network."$SLOT".addresses="$ADDRESS" 134 135 if [ -n "${DNS:-}" ]; then 136 OLDIFS="$IFS" 137 IFS=',' 138 for D in $DNS; do 139 D="$(echo "$D" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')" 140 [ -n "$D" ] && uci add_list network."$SLOT".dns="$D" 141 done 142 IFS="$OLDIFS" 143 fi 144 145 PEER="$(uci add network "amneziawg_${SLOT}")" 146 uci set network."$PEER".description="$(basename "$CONF")" 147 uci set network."$PEER".public_key=[REDACTED_PUBLIC_KEY] 148 149 OLDIFS="$IFS" 150 IFS=',' 151 for A in ${ALLOWED_IPS:-0.0.0.0/0}; do 152 A="$(echo "$A" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')" 153 [ -n "$A" ] && uci add_list network."$PEER".allowed_ips="$A" 154 done 155 IFS="$OLDIFS" 156 157 uci set network."$PEER".route_allowed_ips='0' 158 uci set network."$PEER".persistent_keepalive="${KEEPALIVE:-25}" 159 uci set network."$PEER".endpoint_host="$ENDPOINT_HOST" 160 uci set network."$PEER".endpoint_port="$ENDPOINT_PORT" 161 162 uci set network."$SLOT".hmn_role='active_spare_slot' 163 uci set network."$SLOT".hmn_source_config="$CONF" 164 uci set network."$SLOT".hmn_loaded_at="$(date -Iseconds)" 165 uci set network."$SLOT".hmn_endpoint="$ENDPOINT" 166 167 uci commit network 168 169 echo "Loaded. Slot is still down unless ACTION=up." 170 echo 171 uci show network."$SLOT" | sed "s/private_key=[REDACTED_PRIVATE_KEY] 172 echo 173 uci show network | grep -E "=amneziawg_${SLOT}|@amneziawg_${SLOT}.*description|@amneziawg_${SLOT}.*allowed_ips|@amneziawg_${SLOT}.*route_allowed_ips|@amneziawg_${SLOT}.*endpoint_host|@amneziawg_${SLOT}.*endpoint_port|@amneziawg_${SLOT}.*persistent_keepalive" 174 175 echo 176 echo "table 200 after load:" 177 ip route show table 200 178 179 if [ "$ACTION" = "up" ]; then 180 echo 181 echo "Bringing $SLOT up..." 182 ifup "$SLOT" 183 sleep 10 184 /usr/bin/amneziawg show "$SLOT" 2>/dev/null || true 185 fi rc=0 ################################################################ ### LOADER CAPABILITY GREP ################################################################ === slot restrictions / uci / reload / ifup lines === 5:SLOT="${1:-}" 9:case "$SLOT" in 10: vpn1|vpn2) ;; 12: echo "ERROR: slot должен быть vpn1 или vpn2" 14: echo " /root/hmn/hmn-load-vpn-slot.sh vpn2 /path/to/config.conf" 15: echo " /root/hmn/hmn-load-vpn-slot.sh vpn2 /path/to/config.conf up" 26:ACTIVE="$(ip route show table 200 | awk '/^default dev /{print $3; exit}')" 28:if [ "$SLOT" = "$ACTIVE" ] && [ "${HMN_ALLOW_ACTIVE_RELOAD:-0}" != "1" ]; then 29: echo "ERROR: refusing to reload active slot: $SLOT" 30: echo "Current table 200 active slot: $ACTIVE" 34: echo " HMN_ALLOW_ACTIVE_RELOAD=1 /root/hmn/hmn-load-vpn-slot.sh $SLOT $CONF" 85:BACKUP="/root/hmn/backups/network-before-load-${SLOT}-$TS" 96:echo "Loading into slot:" 97:echo " slot: $SLOT" 101:echo " active table 200 before load: ${ACTIVE:-none}" 104:ifdown "$SLOT" 2>/dev/null || true 106:uci -q delete network."$SLOT" || true 109: SEC="$(uci -q show network | sed -n "s/^\(network\.@amneziawg_${SLOT}\[[0-9][0-9]*\]\)=amneziawg_${SLOT}$/\1/p" | head -n 1)" 114:uci set network."$SLOT"='interface' 115:uci set network."$SLOT".proto='amneziawg' 116:uci set network."$SLOT".private_key=[REDACTED_PRIVATE_KEY] 117:uci set network."$SLOT".awg_jc="$JC" 118:uci set network."$SLOT".awg_jmin="$JMIN" 119:uci set network."$SLOT".awg_jmax="$JMAX" 120:uci set network."$SLOT".awg_s1="$S1" 121:uci set network."$SLOT".awg_s2="$S2" 122:uci set network."$SLOT".awg_h1="$H1" 123:uci set network."$SLOT".awg_h2="$H2" 124:uci set network."$SLOT".awg_h3="$H3" 125:uci set network."$SLOT".awg_h4="$H4" 127:uci set network."$SLOT".auto='0' 128:uci set network."$SLOT".disabled='0' 129:uci set network."$SLOT".delegate='0' 130:uci set network."$SLOT".peerdns='0' 131:uci set network."$SLOT".defaultroute='0' 133:uci add_list network."$SLOT".addresses="$ADDRESS" 140: [ -n "$D" ] && uci add_list network."$SLOT".dns="$D" 145:PEER="$(uci add network "amneziawg_${SLOT}")" 146:uci set network."$PEER".description="$(basename "$CONF")" 147:uci set network."$PEER".public_key=[REDACTED_PUBLIC_KEY] 153: [ -n "$A" ] && uci add_list network."$PEER".allowed_ips="$A" 157:uci set network."$PEER".route_allowed_ips='0' 158:uci set network."$PEER".persistent_keepalive="${KEEPALIVE:-25}" 159:uci set network."$PEER".endpoint_host="$ENDPOINT_HOST" 160:uci set network."$PEER".endpoint_port="$ENDPOINT_PORT" 162:uci set network."$SLOT".hmn_role='active_spare_slot' 163:uci set network."$SLOT".hmn_source_config="$CONF" 164:uci set network."$SLOT".hmn_loaded_at="$(date -Iseconds)" 165:uci set network."$SLOT".hmn_endpoint="$ENDPOINT" 167:uci commit network 169:echo "Loaded. Slot is still down unless ACTION=up." 171:uci show network."$SLOT" | sed "s/private_key=[REDACTED_PRIVATE_KEY] 173:uci show network | grep -E "=amneziawg_${SLOT}|@amneziawg_${SLOT}.*description|@amneziawg_${SLOT}.*allowed_ips|@amneziawg_${SLOT}.*route_allowed_ips|@amneziawg_${SLOT}.*endpoint_host|@amneziawg_${SLOT}.*endpoint_port|@amneziawg_${SLOT}.*persistent_keepalive" 176:echo "table 200 after load:" 177:ip route show table 200 181: echo "Bringing $SLOT up..." 182: ifup "$SLOT" 184: /usr/bin/amneziawg show "$SLOT" 2>/dev/null || true rc=0 ################################################################ ### MINIMAL DRY PARSE OF FUTURE CANDIDATE CONFIGS, NO KEY VALUES ################################################################ --- 150-NL-Netherlands-Amsterdam-R5-178.215.227.13-awg1.conf --- Address=10.91.235.78/32 PrivateKey=[REDACTED] DNS=1.1.1.1 Jc=3 Jmin=50 Jmax=100 S1=92 S2=90 H1=1128827374 H2=1959569870 H3=96441901 H4=2091878015 PublicKey=[REDACTED] AllowedIPs=0.0.0.0/0 Endpoint=178.215.227.13:44408 PersistentKeepalive=25 --- 128-LV-Latvia-Riga-S1-192.121.163.235-awg1.conf --- Address=10.86.111.229/32 PrivateKey=[REDACTED] DNS=1.1.1.1 Jc=3 Jmin=50 Jmax=100 S1=107 S2=122 H1=711662706 H2=1180552356 H3=1975038815 H4=1815189548 PublicKey=[REDACTED] AllowedIPs=0.0.0.0/0 Endpoint=192.121.163.235:42530 PersistentKeepalive=28 --- 075-NL-Netherlands-Amsterdam-H13-95.211.68.119-awg1.conf --- Address=10.104.58.24/32 PrivateKey=[REDACTED] DNS=1.1.1.1 Jc=3 Jmin=50 Jmax=100 S1=55 S2=43 H1=424258794 H2=1552734037 H3=136716108 H4=329527368 PublicKey=[REDACTED] AllowedIPs=0.0.0.0/0 Endpoint=95.211.68.119:45176 PersistentKeepalive=25 --- 072-NL-Netherlands-Amsterdam-S8-78.31.250.16-awg1.conf --- Address=10.103.120.171/32 PrivateKey=[REDACTED] DNS=1.1.1.1 Jc=3 Jmin=50 Jmax=100 S1=132 S2=22 H1=1314107157 H2=894303025 H3=687987321 H4=1498765620 PublicKey=[REDACTED] AllowedIPs=0.0.0.0/0 Endpoint=78.31.250.16:41729 PersistentKeepalive=26 --- 049-DE-Germany-Berlin-S7-157.173.27.69-awg1.conf --- Address=10.97.189.145/32 PrivateKey=[REDACTED] DNS=1.1.1.1 Jc=3 Jmin=50 Jmax=100 S1=41 S2=126 H1=794003863 H2=1904928317 H3=51857443 H4=1575935704 PublicKey=[REDACTED] AllowedIPs=0.0.0.0/0 Endpoint=157.173.27.69:41797 PersistentKeepalive=24 rc=0 ################################################################ ### CURRENT SAFE RUNTIME STATE ################################################################ === interfaces === lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 95.165.105.4/20 fe80::be24:11ff:fe42:83cf/64 eth1 UP 10.200.0.2/24 fe80::be24:11ff:fe09:4e2c/64 eth2 UP 10.71.100.2/24 fe80::be24:11ff:fe4d:7a71/64 eth3 UP 10.201.0.2/24 fe80::be24:11ff:fec8:2ee1/64 vpn1 UNKNOWN 10.91.233.132/32 === rules === 0: from all lookup local 10019: from all iif eth1 lookup 200 10020: from 10.200.0.0/24 lookup 200 32766: from all lookup main 32767: from all lookup default === tables 200-205 === TABLE 200 default dev vpn1 scope link 10.200.0.0/24 dev eth1 scope link src 10.200.0.2 10.201.0.0/24 dev eth3 scope link src 10.201.0.2 TABLE 201 TABLE 202 TABLE 203 TABLE 204 TABLE 205 === firewall vpn_out === firewall.@zone[3].name='vpn_in' firewall.@zone[3].network='vpn_in' firewall.@zone[4].name='vpn_out' firewall.@zone[4].network='vpn1' 'vpn2' 'vpn_user' firewall.@rule[7].name='Allow-ICMP-from-vpn_in-to-router' firewall.@rule[7].src='vpn_in' firewall.@forwarding[0]=forwarding firewall.@forwarding[0].src='direct_in' firewall.@forwarding[0].dest='wan' firewall.@forwarding[1]=forwarding firewall.@forwarding[1].src='vpn_in' firewall.@forwarding[1].dest='vpn_out' firewall.@forwarding[2]=forwarding firewall.@forwarding[2].src='vpn_in' firewall.@forwarding[2].dest='wan' rc=0 ################################################################ ### ASSESSMENT ################################################################ No changes applied. Decision after this report: - if hmn-load-vpn-slot.sh is generic and safe, reuse it for future vpn3-vpn5 load package - if it is hard-coded to vpn1/vpn2/table200, write a new minimal generic loader based on hmn-load-vpn-test/user UCI pattern