#!/bin/bash
set -euo pipefail
stamp="$(date +%Y%m%d_%H%M%S)"
backup="/root/wpmm-backups/auto-bclass-block-$stamp"
mkdir -p "$backup"
cp -a /usr/local/sbin/wpmm-watchdog "$backup/wpmm-watchdog"
cp -a /etc/wpmm-watchdog.json "$backup/wpmm-watchdog.json"
cp -a /etc/systemd/system/wpmm-watchdog.timer "$backup/wpmm-watchdog.timer"
if [ -f /etc/csf/csf.deny ]; then cp -a /etc/csf/csf.deny "$backup/csf.deny"; fi
if [ -f /etc/csf/csf.allow ]; then cp -a /etc/csf/csf.allow "$backup/csf.allow"; fi
rollback() {
cp -a "$backup/wpmm-watchdog" /usr/local/sbin/wpmm-watchdog
cp -a "$backup/wpmm-watchdog.json" /etc/wpmm-watchdog.json
cp -a "$backup/wpmm-watchdog.timer" /etc/systemd/system/wpmm-watchdog.timer
if [ -f "$backup/csf.deny" ]; then cp -a "$backup/csf.deny" /etc/csf/csf.deny; fi
if [ -f "$backup/csf.allow" ]; then cp -a "$backup/csf.allow" /etc/csf/csf.allow; fi
systemctl daemon-reload >/dev/null 2>&1 || true
}
trap rollback ERR
install -o root -g root -m 0755 /tmp/wpmm-watchdog.autoblock /usr/local/sbin/wpmm-watchdog
install -o root -g root -m 0644 /tmp/wpmm-watchdog.timer.autoblock /etc/systemd/system/wpmm-watchdog.timer
python3 -m py_compile /usr/local/sbin/wpmm-watchdog
python3 - <<'PY'
import json, os
path='/etc/wpmm-watchdog.json'
with open(path,encoding='utf-8') as f: data=json.load(f)
required={
'172.96.184.87':'Hawk 中控主機',
'139.162.96.131':'總公司發文/數據收集主機',
'172.233.84.207':'備用數據收集主機',
'42.71.16.140':'目前管理 IP',
'114.41.0.27':'公司先前 IP',
'1.168.188.194':'公司先前 IP',
'127.0.0.1':'本機回環',
'::1':'本機回環',
}
ips=[]
for value in list(data.get('connection_whitelist_ips',[]))+list(required):
value=str(value).strip()
if value and value not in ips: ips.append(value)
labels=dict(data.get('connection_whitelist_labels',{}))
for key,value in required.items(): labels.setdefault(key,value)
data['connection_whitelist_ips']=ips
data['connection_whitelist_labels']=labels
data['auto_block_bclass_enabled']=True
data['auto_block_bclass_threshold']=20
data['auto_block_max_cclass_per_run']=128
data['auto_block_established_ports']=[111,2049]
temp=path+'.wpmm.tmp'
with open(temp,'w',encoding='utf-8') as f:
json.dump(data,f,ensure_ascii=False,indent=2); f.flush(); os.fsync(f.fileno())
os.chmod(temp,0o600)
os.replace(temp,path)
PY
if command -v csf >/dev/null 2>&1; then
for ip in 172.96.184.87 139.162.96.131 172.233.84.207 42.71.16.140 114.41.0.27 1.168.188.194; do
grep -Eq "^[[:space:]]*${ip//./\\.}([[:space:]#]|$)" /etc/csf/csf.allow 2>/dev/null || echo "$ip # wp-MM-System protected source" >> /etc/csf/csf.allow
done
csf -r >/dev/null
elif command -v wpmm-firewall >/dev/null 2>&1; then
wpmm-firewall restore >/dev/null
fi
systemctl daemon-reload
systemctl enable --now wpmm-watchdog.timer >/dev/null
systemctl restart wpmm-watchdog.timer
systemctl start wpmm-watchdog.service
systemctl is-active wpmm-watchdog.timer
python3 - <<'PY'
import json
d=json.load(open('/etc/wpmm-watchdog.json'))
assert d.get('auto_block_bclass_enabled') is True
assert d.get('auto_block_bclass_threshold') == 20
s=json.load(open('/var/lib/wpmm-watchdog/state.json'))
r=s.get('last_auto_block',{})
print(json.dumps({'enabled':r.get('enabled'),'threshold':r.get('threshold'),'firewall_backend':r.get('firewall_backend'),'matched_groups':r.get('matched_groups',[]),'blocked':r.get('blocked',[]),'skipped_protected':r.get('skipped_protected',[]),'errors':r.get('errors',[])},ensure_ascii=False))
PY
trap - ERR
echo "backup=$backup"