1414# THRESHOLD seconds since last knock before alerting (default: 1200 = 20 min)
1515# ALERT_COOLDOWN seconds before re-alerting same issue (default: 1800 = 30 min)
1616# CENTRAL_MODE set to "true" instead of using --central flag
17+ # COMPOSE_PROJECT Docker Compose project name (default: knock-knock)
1718
1819NTFY_TOPIC=" ${NTFY_TOPIC:- your-private-topic-change-me} "
1920THRESHOLD=" ${THRESHOLD:- 1200} "
@@ -26,80 +27,119 @@ CENTRAL_MODE="${CENTRAL_MODE:-false}"
2627# Remote servers to check in central mode (space-separated)
2728REMOTE_SERVERS=" ${REMOTE_SERVERS:- knock-knock.net} "
2829
30+ # === AUTO-DETECT DEPLOYMENT MODE ===
31+
32+ COMPOSE_PROJECT=" ${COMPOSE_PROJECT:- knock-knock} "
33+
34+ if systemctl list-unit-files knock-monitor.service & > /dev/null | grep -q knock-monitor; then
35+ MODE=systemd
36+ elif docker compose ls 2> /dev/null | grep -q " $COMPOSE_PROJECT " ; then
37+ MODE=docker
38+ else
39+ MODE=unknown
40+ fi
41+
2942# === FUNCTIONS ===
3043
44+ redis_cmd () {
45+ if [ " $MODE " = " docker" ]; then
46+ docker exec " ${COMPOSE_PROJECT} -redis-1" redis-cli " $@ " 2> /dev/null
47+ else
48+ redis-cli " $@ " 2> /dev/null
49+ fi
50+ }
51+
3152alert () {
32- local tag=" $1 "
33- local msg=" $2 "
34- local tags=" ${3:- warning} "
35- local cooldown_key=" knock:alerted:${tag} "
36- local alerted=$( redis-cli GET " $cooldown_key " 2> /dev/null )
37- if [ -z " $alerted " ]; then
38- curl -s -X POST " https://ntfy.sh/${NTFY_TOPIC} " \
39- -H " Title: Knock-Knock Alert (${HOSTNAME} )" \
40- -H " Priority: urgent" \
41- -H " Tags: ${tags} " \
42- -d " $msg " > /dev/null 2>&1
43- redis-cli SET " $cooldown_key " 1 EX " $ALERT_COOLDOWN " > /dev/null 2>&1
44- fi
53+ local tag=" $1 "
54+ local msg=" $2 "
55+ local tags=" ${3:- warning} "
56+ local cooldown_key=" knock:alerted:${tag} "
57+ local alerted=$( redis_cmd GET " $cooldown_key " )
58+ if [ -z " $alerted " ]; then
59+ curl -s -X POST " https://ntfy.sh/${NTFY_TOPIC} " \
60+ -H " Title: Knock-Knock Alert (${HOSTNAME} )" \
61+ -H " Priority: urgent" \
62+ -H " Tags: ${tags} " \
63+ -d " $msg " > /dev/null 2>&1
64+ redis_cmd SET " $cooldown_key " 1 EX " $ALERT_COOLDOWN " > /dev/null 2>&1
65+ fi
4566}
4667
4768clear_alert () {
48- local tag=" $1 "
49- local msg=" $2 "
50- local cooldown_key=" knock:alerted:${tag} "
51- if [ -n " $( redis-cli GET " $cooldown_key " 2> /dev/null ) " ]; then
52- curl -s -X POST " https://ntfy.sh/${NTFY_TOPIC} " \
53- -H " Title: Knock-Knock Recovered (${HOSTNAME} )" \
54- -H " Priority: default" \
55- -H " Tags: white_check_mark" \
56- -d " $msg " > /dev/null 2>&1
57- fi
58- redis-cli DEL " $cooldown_key " > /dev/null 2>&1
69+ local tag=" $1 "
70+ local msg=" $2 "
71+ local cooldown_key=" knock:alerted:${tag} "
72+ if [ -n " $( redis_cmd GET " $cooldown_key " ) " ]; then
73+ curl -s -X POST " https://ntfy.sh/${NTFY_TOPIC} " \
74+ -H " Title: Knock-Knock Recovered (${HOSTNAME} )" \
75+ -H " Priority: default" \
76+ -H " Tags: white_check_mark" \
77+ -d " $msg " > /dev/null 2>&1
78+ fi
79+ redis_cmd DEL " $cooldown_key " > /dev/null 2>&1
5980}
6081
6182# === LOCAL CHECKS ===
6283
6384# Check Redis
64- if ! redis-cli PING > /dev/null 2>&1 ; then
65- curl -s -X POST " https://ntfy.sh/${NTFY_TOPIC} " \
66- -H " Title: Knock-Knock Alert (${HOSTNAME} )" \
67- -H " Priority: urgent" \
68- -H " Tags: rotating_light" \
69- -d " Redis is down on ${HOSTNAME} " > /dev/null 2>&1
70- exit 1
85+ if ! redis_cmd PING > /dev/null 2>&1 ; then
86+ curl -s -X POST " https://ntfy.sh/${NTFY_TOPIC} " \
87+ -H " Title: Knock-Knock Alert (${HOSTNAME} )" \
88+ -H " Priority: urgent" \
89+ -H " Tags: rotating_light" \
90+ -d " Redis is down on ${HOSTNAME} " > /dev/null 2>&1
91+ exit 1
7192fi
7293
7394# Check services
74- for svc in knock-monitor knock-web; do
75- if ! systemctl is-active --quiet " $svc " ; then
76- alert " $svc " " ${svc} is not running on ${HOSTNAME} " " rotating_light"
77- else
78- clear_alert " $svc " " ${svc} is back on ${HOSTNAME} "
79- fi
80- done
95+ if [ " $MODE " = " systemd" ]; then
96+ for svc in knock-monitor knock-web; do
97+ if ! systemctl is-active --quiet " $svc " ; then
98+ alert " $svc " " ${svc} is not running on ${HOSTNAME} " " rotating_light"
99+ else
100+ clear_alert " $svc " " ${svc} is back on ${HOSTNAME} "
101+ fi
102+ done
103+ elif [ " $MODE " = " docker" ]; then
104+ for ctr in honeypot-monitor web; do
105+ full=" ${COMPOSE_PROJECT} -${ctr} -1"
106+ status=$( docker inspect --format=' {{.State.Status}}' " $full " 2> /dev/null)
107+ if [ " $status " != " running" ]; then
108+ alert " $ctr " " ${full} is not running on ${HOSTNAME} (status: ${status:- not found} )" " rotating_light"
109+ else
110+ clear_alert " $ctr " " ${full} is back on ${HOSTNAME} "
111+ fi
112+ done
113+ else
114+ curl -s -X POST " https://ntfy.sh/${NTFY_TOPIC} " \
115+ -H " Title: Knock-Knock Alert (${HOSTNAME} )" \
116+ -H " Priority: urgent" \
117+ -H " Tags: rotating_light" \
118+ -d " Could not detect deployment mode on ${HOSTNAME} (neither systemd nor Docker found)" > /dev/null 2>&1
119+ exit 1
120+ fi
81121
82122# Check knock flow
83- last=$( redis-cli GET knock:last_time 2> /dev/null )
123+ last=$( redis_cmd GET knock:last_time)
84124if [ -n " $last " ]; then
85- now=$( date +%s)
86- age=$(( now - last ))
87- if [ " $age " -gt " $THRESHOLD " ]; then
88- mins=$(( age / 60 ))
89- alert " stale" " No knocks for ${mins} min on ${HOSTNAME} (monitor may be stuck)"
90- else
91- clear_alert " stale" " Knocks are flowing again on ${HOSTNAME} "
92- fi
125+ now=$( date +%s)
126+ age=$(( now - last ))
127+ if [ " $age " -gt " $THRESHOLD " ]; then
128+ mins=$(( age / 60 ))
129+ alert " stale" " No knocks for ${mins} min on ${HOSTNAME} (monitor may be stuck)"
130+ else
131+ clear_alert " stale" " Knocks are flowing again on ${HOSTNAME} "
132+ fi
93133fi
94134
95135# === CENTRAL MODE: CHECK REMOTE SERVERS ===
96136
97137if [ " $CENTRAL_MODE " = " true" ]; then
98- for server in $REMOTE_SERVERS ; do
99- if ! curl -sf --max-time 10 " https://${server} /" > /dev/null 2>&1 ; then
100- alert " down:${server} " " ${server} is not responding (checked by ${HOSTNAME} )" " rotating_light"
101- else
102- clear_alert " down:${server} " " ${server} is back online"
103- fi
104- done
138+ for server in $REMOTE_SERVERS ; do
139+ if ! curl -sf --max-time 10 " https://${server} /" > /dev/null 2>&1 ; then
140+ alert " down:${server} " " ${server} is not responding (checked by ${HOSTNAME} )" " rotating_light"
141+ else
142+ clear_alert " down:${server} " " ${server} is back online"
143+ fi
144+ done
105145fi
0 commit comments