From 05d46d2cf68835a098022057e720ddd3137d7aae Mon Sep 17 00:00:00 2001 From: Xore Date: Thu, 10 Sep 2026 19:38:34 +0200 Subject: [PATCH] fix(tanner): recreate snare state files on start so restarts survive init's chown (#3160) Root cause: honeypot-init's chown re-arms the ownership trap by changing /opt/snare directory and snare.pid/err/log files to the snare user. DAC_OVERRIDE is deliberately absent from tanner's capabilities, so snare cannot recreate these files once ownership changes. On restart, snare fails to write state files and cannot initialize cleanly. Fix: Add rm -f for snare.pid, snare.err, snare.log in the entrypoint shell before exec'ing snare-entry.sh. This ensures snare creates fresh state files owned by the snare user on every start, surviving the init chown without capability widening. Live verification: restarts=0, HTTP 200, re-armed-trap restart completed cleanly. Closes #3160 --- arcane/home/honeypot-tanner/compose.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/arcane/home/honeypot-tanner/compose.yml b/arcane/home/honeypot-tanner/compose.yml index d594b747d..790066ea6 100644 --- a/arcane/home/honeypot-tanner/compose.yml +++ b/arcane/home/honeypot-tanner/compose.yml @@ -247,8 +247,26 @@ services: # SNARE drops privileges at startup (setgid/setuid), which is why the # otherwise-empty set the other tanner services use makes it exit with # PermissionError: [Errno 1] Operation not permitted before it binds. - # SETUID+SETGID is the measured minimum; CHOWN and DAC_OVERRIDE were - # tested on top and changed nothing, so they are not granted. + # SETUID+SETGID is the measured minimum. + # + # #3160: the earlier note here ("CHOWN and DAC_OVERRIDE were tested on + # top and changed nothing") was wrong -- that measurement predates + # snare.pid existing on disk. Root without CAP_DAC_OVERRIDE cannot + # truncate-open an *existing* file it does not own; the dir's own mode + # (0757) only gates create/unlink, not truncating a file someone else + # owns -- confirmed live by reproducing the EACCES with capsh under + # this exact cap set. The owning uid flips each stack start: snare's + # own prior run leaves these files root:root, then honeypot-init's + # `chown -R 65534:65534 .../logs/snare` (see honeypot-init compose) + # re-owns them to nobody before snare's next start -- either way the + # file is 0644 (other=read only) and snare starts as root, so it hits + # the same EACCES regardless of which non-root uid currently owns the + # file. Same trap hits snare.err and snare.log (opened next, same + # pre-drop root context) -- confirmed by clearing each in turn and + # watching the next one fail. Adding DAC_OVERRIDE would fix it too but + # widens what a network-exposed honeypot can do as root; instead the + # entrypoint below removes its own state files before each start, so + # SNARE always creates them fresh. cap_drop: - ALL cap_add: @@ -269,6 +287,7 @@ services: - -c - > until [ -f /markers/snare-clone.done ] && [ -f /markers/log-init.done ]; do sleep 3; done; + rm -f /opt/snare/snare.pid /opt/snare/snare.err /opt/snare/snare.log; exec /usr/local/bin/snare-entry.sh ports: - ${HP_BIND:-10.8.0.2}:19082:8080