Přeskočit na obsah

Honeypot experiment

2026-08-22-srv3-webtrap-https-tls-accept-hang

Za měsíc provozu se rozbilo několik věcí – něco rozbil agent, něco poskytovatel a něco operátor. Každý incident má vlastní rozbor s časovou osou, příčinou a tím, co se ztratilo.

Rozbor aktualizován: 2. 10. 2026 20:00:00 UTC+02:00

Nahlásit problém
Zpět na přehled incidentů

Přehled incidentu #


Chybí data Závažnost: vážná Způsobil: agent vyřešeno
Označení
2026-08-22-srv3-webtrap-https-tls-accept-hang
Začátek
22. 8. 2026 15:40:00 UTC
Zjištěno
24. 8. 2026 18:45:00 UTC (za 2 d 3 h)
Začalo se řešit
24. 8. 2026 18:50:26 UTC (5 min po zjištění)
Vyřešeno
24. 8. 2026 18:51:21 UTC
Délka
2 d 3 h
Příčina
blocking_tls_handshake_in_accept_loop doložená
Kdo si všiml
agent
Dotčené servery
srv3
Dopad
sběr dat, dostupnost
Zásahů operátora
0
Otevřených otázek
5
  • do zjištění
  • do začátku řešení
  • do vyřešení
Začátek 15:40Vyřešeno 18:51Zjištěno 18:45 (za 2 d 3 h)Začalo se řešit 18:50 (5 min po zjištění)

Dopad na honeypoty a data #


Reakce agentů

Server Reakce
srv3 zasáhl

Díry v datech

OdDoDélkaServeryProud datObnovitelnéObnoveno
22. 8. 2026 15:40:00 UTC24. 8. 2026 18:51:21 UTC2 d 3 hsrv3webtrap-https (443/tcp)neneobnoveno

Díry odsud se automaticky propisují do seznamu na stránce Omezení

Historie změn rozboru #


Rozbor se nepřepisuje potichu: každá jeho změna je zapsaná v sekci Změny

Rozbor se od zveřejnění neměnil.

Rozbor #


Dostupné jazyky rozboru: čeština

HTTPS senzor webtrap zablokovaný nedokončeným TLS handshakem (51 hodin bez dat)

Všechny časy jsou v UTC. Rozbor slučuje záznamy tří relací agenta (kontroly č. 2, 5 a závěrečná kontrola 11. 9.). Značky zdroje: [VIDĚL] doslova v záznamu · [ODVOZENO] závěr z viděného · [NEJISTÉ] jen přibližně nebo nedohledatelné

1. Shrnutí

Webový honeypot webtrap běžel ve dvou kontejnerech se společným skriptem /srv/honeypot/webtrap/webtrap.py a společným výstupem webtrap.jsonl: webtrap-http na portu 80 a webtrap-https na portu 443. HTTPS instance obalovala TLS kontextem přímo naslouchající socket, takže se handshake odehrával uvnitř accept() v hlavním vlákně a bez časového limitu. 2026-08-22 v 15:40Z se připojil klient 65.87.7.99:51740, handshake nedokončil a spojení nechal otevřené; tím hlavní vlákno zablokoval a senzor přestal přijímat kohokoli dalšího. [VIDĚL]

Stav trval do zásahu agenta 24. 8. v 18:51Z, přibližně 51 hodin, a za tu dobu nevznikla jediná HTTPS událost. Kontejner celou dobu běžel a docker ps hlásil Up; protože HTTP a HTTPS zapisují do jednoho souboru, nezestárl ani log. Port 80 fungoval normálně. Data z portu 443 za toto okno nejsou obnovitelná: útočníci nedostali odpověď, takže žádná komunikace neproběhla, a pcap z té doby zachytil jen pakety pokusů o spojení, navíc oříznuté na 256 B. Oprava přesunula handshake do vlákna spojení s timeoutem 60 s, začala logovat TLS metadata a neúspěšné handshaky a zvedla strop těla požadavku z 8 KiB na 256 KiB, čímž se k 24. 8. 18:51Z mění schéma dat. Stav na konci experimentu: vyřešeno; senzor byl živý do konce běhu (poslední událost 11. 9. 17:37:32Z).

2. Časová osa

Čas (UTC)KomponentaCo se staloZdroj
2026-08-22T00:42:34Zwebtrap-httpsVytvořen kontejner s vadným kódem[VIDĚL] docker inspect
2026-08-22T11:26:32Zwebtrap-httpsPoslední TLS událost před výpadkem — vlastní test agenta z 169.58.205.217[VIDĚL] webtrap.jsonl-20260822.gz
2026-08-22T11:35:46Zwebtrap-httpsStart kontejneru po rebootu serveru[VIDĚL] StartedAt
2026-08-22T11:37ZlogrotateRotace webtrap.jsonl[VIDĚL] mtime (CEST)
~2026-08-22T11:37Z–15:40Zwebtrap-httpsŽádná TLS událost; nelze rozhodnout, zda senzor fungoval a jen nepřišel provoz[NEJISTÉ]
2026-08-22T15:40Zwebtrap-httpsOtevřen deskriptor fd 4 — spojení z 65.87.7.99:51740, ESTAB až do kontroly; accept() zablokován[VIDĚL] ls -l /proc/<pid>/fd (CEST) + ss
2026-08-22T22:00ZlogrotateRotace → webtrap.jsonl-20260823, v něm 0 TLS záznamů[VIDĚL]
2026-08-24T18:38ZagentZačátek kontroly č. 2[VIDĚL] CHANGELOG
2026-08-24T~18:45Zagent1007 false v poli tls, sonda https: 000 8.000950s[VIDĚL], čas [ODVOZENO]
2026-08-24T~18:46Zagent/proc/<pid>/fd, nsenter … ss — blokující spojení a fronta CLOSE-WAIT[VIDĚL]
2026-08-24T~18:49ZagentZáloha webtrap.py.bak-20260824, zápis opravené verze, kontrola syntaxe[VIDĚL]
2026-08-24T18:50:26Zwebtrap-testOprava ověřena v dočasném kontejneru na 10.222.0.98:8443[VIDĚL]
2026-08-24T18:51:12Zwebtrap-https, webtrap-httpdocker restart -t 5 webtrap-https webtrap-http, start hlásí timeout=60s body_cap=262144[VIDĚL], vteřina [ODVOZENO]
2026-08-24T18:51:21Zwebtrap-httpsPrvní TLS událost po opravě (vlastní sonda z 169.58.205.217)[VIDĚL]
2026-08-24T~18:54Zhp-watchdogPřidána sonda probe_https každých 30 min nezávisle na stáří logu[VIDĚL]
2026-08-24T19:14:56Zwebtrap-httpsPrvní reálný externí TLS klient (147.185.132.120, UNSUPPORTED_PROTOCOL)[VIDĚL]
2026-09-04T18:12Zwebtrap-httpsUp 10 days — od opravy bez restartu[VIDĚL]
2026-09-11T17:37:32ZwebtrapPoslední zaznamenaná událost, senzor živý do konce běhu[VIDĚL]

Nesrovnalosti: časy deskriptorů a souborů z ls jsou v CEST a byly převedeny; ts v webtrap.jsonl je v UTC s +00:00. Čas restartu 18:51:12Z je odvozen z Up 9 seconds a z první události 18:51:21Z. Hranice 15:40Z, kterou uvádí HANDOVER, je nezávisle potvrzená časem otevření fd 4 („Aug 22 17:40" CEST).

3. Příčina

webtrap.py obaloval TLS kontextem rovnou naslouchající socket (httpd.socket = ctx.wrap_socket(...))
  └─ SSLSocket.accept() provádí handshake sám, uvnitř hlavního vlákna, bez timeoutu
       └─ ThreadingHTTPServer nestihl vlákno pro spojení vůbec vytvořit
            └─ klient 65.87.7.99, který se připojil a ClientHello neposlal, zablokoval accept() natrvalo
                 ├─ žádné další spojení nebylo přijato (Threads: 1)
                 ├─ další klienti zůstali ve frontě jádra ve stavu CLOSE-WAIT s nepřečtenými bajty
                 └─ 51 hodin bez jediné HTTPS události

Příčina je doložená zněním původního kódu, stavem procesu (jediné vlákno, stav S, wchan = wait_woken), tím, že blokující fd 4 drží přímo hlavní proces, a neúspěšnou sondou zvenčí. Oprava byla ověřena experimentem: tichý klient drží spojení 14 s a souběžný HTTPS požadavek přesto dostane odpověď za 0,014 s. [VIDĚL] Šlo o konstrukční chybu přítomnou od nasazení; že se projevila až po ~15 hodinách provozu, byla náhoda. Zda klient 65.87.7.99 jednal záměrně, nevím. [ODVOZENO]

Proč to nezachytila ochrana

  • Watchdog kontroloval jen stav kontejneru (docker inspect -f '{{.State.Status}}'). Kontejner běžel, takže state.jsonl má u všech 1103 záznamů z té doby "actions":"none". [VIDĚL]
  • Sdílený log zakryl výpadek. HTTP i HTTPS píšou do webtrap.jsonl; provoz na portu 80 soubor držel čerstvý, takže by nezabrala ani kontrola stáří logu. Ze stejného důvodu výpadek neukáže ani zpětné hodinové pokrytí (webtrap=22 hodin za 23. 8.). [VIDĚL]
  • Mezi 22. 8. 15:40Z a 24. 8. 18:38Z neproběhla žádná kontrola. Délku výpadku určil rozestup kontrol, ne doba detekce. [VIDĚL] CHANGELOG

Oprava watchdogu přidala nepodmíněnou HTTPS sondu každých 30 minut. Z incidentu vzniklo i pravidlo v kontrolním seznamu HANDOVERu: „Živost senzorů NEsuď jen z docker ps". [VIDĚL]

4. Dopad a díry v datech

Co vypadlo

  • HTTPS senzor (port 443) od 2026-08-22T15:40Z do 2026-08-24T18:51:21Z. [VIDĚL] nula záznamů s tls=true v aktuálním i rotovaném souboru, neúspěšná sonda zvenčí.
  • Data z nejméně šesti spojení, která jádro přijalo a nechalo nepřečtená ve frontě (Recv-Q 129–1484 B). [VIDĚL]

Co nevypadlo

  • webtrap-http (port 80) — 1007 záznamů s tls=false v aktuálním souboru, mezi nimi reálné útoky. [VIDĚL]
  • Cowrie, dionaea, sink — logy ve stejném období rostly. [VIDĚL]
  • TCP stopa pokusů o spojení na 443 — pcap běžel od 22. 8. ~11:35Z (soubory hp.pcap00–hp.pcap05, ponechané), ale se snaplenem 256 B. [VIDĚL] Starší úvaha, že pcap z tohoto okna byl přepsán ring bufferem, se nepotvrdila (viz 2026-08-22-srv3-pcap-ring-buffer-snaplen).
  • Řídicí kanál a přeposílání syslogu. [VIDĚL]

Díry a vady v datech

Soubor / streamPoleOdDoCharakterNenávratné?Kde jsou data kompletní
webtrap.jsonl, záznamy s tls: truevšechna2026-08-22T15:40Z2026-08-24T18:51:21Zchybíanonikde; TCP úroveň v hp.pcap00–hp.pcap05 (256 B na paket)
webtrap.jsonl, záznamy s tls: truevšechna~2026-08-22T11:37Z2026-08-22T15:40Zneprůkazné — nevím, zda výpadek, nebo absence provozunevímhp.pcap00 (spojení na 443 a zda server odpovídal)
fronta jádra na 443 (≥ 6 spojení)payload2026-08-22T15:40Z2026-08-24T18:51:12Zchybí (nikdy nepřečteno)anopcap — šifrované a oříznuté
webtrap.jsonl (port 443)tls_info, události tls_handshake_failed~2026-08-22T00:42Z2026-08-24T18:51:12Zpole neexistovalaano—
webtrap.jsonl (oba porty)tělo požadavku~2026-08-22T00:42Z2026-08-24T18:51:12Zuseknuto na 8 KiB (body_txt[:8192])anonikde
webtrap.jsonl (oba porty)tls_info, event, body2026-08-24T18:51:12Zkonec běhuzměna schématu: nový typ tls_handshake_failed (bez method, path, headers, body), strop těla 256 KiBne—
webtrap.jsonlpath = /hp-watchdog-probe, UA hp-watchdog2026-08-24T~18:54Zkonec běhuvlastní provoz — sonda watchdogu každých 30 minne (odfiltrovat)—

Jak incident poznat v datech

  • Mezi 2026-08-22T11:26:32Z a 2026-08-24T18:51:21Z neexistuje v webtrap.jsonl žádný záznam s "tls": true, zatímco záznamy s "tls": false plynule pokračují. Nejjednodušší marker; mezera v souboru jako celku vidět není.
  • Hranice opravy: první záznam s klíčem tls_info (18:51:21Z, src_ip 169.58.205.217) a první "event": "tls_handshake_failed" (19:14:56Z).
  • V pcapu za dobu výpadku: spojení na 443, která projdou handshakem TCP a nedostanou aplikační odpověď.

Jak s tím zacházet při zpracování

  1. Interval 2026-08-22T15:40Z–2026-08-24T18:51:21Z vyloučit ze všech statistik HTTPS a ze srovnání HTTP vs. HTTPS přes celý běh. Nula zde neznamená nula pokusů.
  2. Úsek ~11:37Z–15:40Z 22. 8. označit jako neprůkazný, ne jako doloženou nulu.
  3. Počítat se dvěma schématy před a po 18:51:12Z. Po opravě přibyla kategorie tls_handshake_failed; srovnání počtů na 443 bez jejího odečtení nadhodnotí nárůst.
  4. Statistiky TLS (SNI, verze, šifry) počítat až od 18:51:21Z. Chybějící tls_info u starších záznamů je vlastnost senzoru, ne klienta.
  5. Délky a obsah těl požadavků rozdělit podle stropu 8 KiB / 256 KiB.
  6. Odfiltrovat path = /hp-watchdog-probe a vlastní sondy z 169.58.205.217 (22. 8. 11:26:32Z, 24. 8. 18:51:21Z).
  7. Objem pokusů během výpadku lze odhadnout jen z pcapu (počet TCP spojení na 443 a jejich zdroje).

Záznam do seznamu omezení datasetu

Senzor HTTPS (port 443) byl od 22. 8. 2026 15:40 UTC do 24. 8. 2026 18:51 UTC zablokovaný nedokončeným TLS handshakem jednoho klienta a v tomto okně nezaznamenal žádný požadavek; absence HTTPS událostí zde neznamená absenci provozu a data nejsou obnovitelná. Záznamy webtrapu pořízené před 24. 8. 2026 18:51 UTC navíc nemají TLS metadata, neobsahují neúspěšné handshaky a mají těla požadavků useknutá na 8 KiB.

5. Reakce agentů

Senzor i vadný kód napsal agent při nasazení. Při kontrole č. 1 (22. 8. kolem 11:26Z) HTTPS ověřil a dostal odpověď; zaseknutí přišlo o čtyři hodiny později. Při kontrole č. 2 si agent vypsal poměr hodnot tls ve výstupním souboru, zjistil nulu a šel do hloubky: sonda zvenčí, výpis deskriptorů, ss v síťovém jmenném prostoru kontejneru. Rozhodl se neřešit to restartem, který by pomohl jen do příštího takového klienta, ale přepsat obsluhu. Opravu ověřil v dočasném kontejneru na neveřejném portu dřív, než ji pustil do ostrého provozu, a restartoval i webtrap-http, aby obě instance běžely na stejné verzi.

  • 2026-08-24T~18:45Z — jq -r '.tls' webtrap.jsonl | sort | uniq -c → 1007 false — jen čtení [VIDĚL]
  • 2026-08-24T~18:45Z — curl -sk -m 8 … https://169.58.205.217/ → https: 000 8.000950s — čtení, vytvořilo testovací spojení [VIDĚL]
  • 2026-08-24T~18:46Z — docker logs --tail 30 webtrap-https, ls -l /proc/$pid/fd, nsenter -t $pid -n ss -tnp — jen čtení [VIDĚL]
  • 2026-08-24T~18:49Z — cp -a webtrap.py webtrap.py.bak-20260824 + zápis nové verze + python3 -m py_compile v hostiteli i v python:3.11-slim — měnilo soubor [VIDĚL]
  • 2026-08-24T18:50:26Z — docker run -d --name webtrap-test --network hpnet --ip 10.222.0.98 -e WEBTRAP_PORT=8443 …, testy, docker rm -f webtrap-test — měnilo dočasně, mimo veřejné porty a mimo datový adresář [VIDĚL]
  • 2026-08-24T18:51:12Z — docker restart -t 5 webtrap-https webtrap-http — měnilo [VIDĚL]
  • 2026-08-24T~18:54Z — do watchdogu přidána probe_https každých 30 min — měnilo [VIDĚL]
  • 2026-09-04 a 2026-09-11 — kontrola, že senzor běží a loguje — jen čtení [VIDĚL]

6. Zásahy operátora

Žádné.

7. Otevřené otázky

OtázkaKde to ověřit v archivu
Byl senzor mrtvý už mezi 11:37Z a 15:40Z 22. 8., nebo jen nepřišel HTTPS provoz?hp.pcap00 — spojení na 443 v tomto okně a zda na ně server odpovídal
Kolik klientů se za 51 hodin pokusilo připojit na 443 a kdo to byl?hp.pcap00–hp.pcap05, TCP konverzace na 443 mezi 2026-08-22T15:40Z a 2026-08-24T18:51Z
Co poslal klient 65.87.7.99, který senzor zablokoval?hp.pcap00/hp.pcap01, filtr host 65.87.7.99 and port 443 kolem 2026-08-22T15:40Z
Zasekl se senzor i dřív, 22. 8. před rebootem serveru?webtrap.jsonl-20260822.gz — rozložení záznamů s tls=true před 11:35Z
U kolika požadavků se projevil strop 8 KiB?webtrap.jsonl před 2026-08-24T18:51Z, těla dlouhá přesně 8192 znaků

8. Důkazy

Původní obsluha TLS (pořízeno 2026-08-24 kolem 18:44Z):

def main():
    httpd = ThreadingHTTPServer(("0.0.0.0", PORT), H)
    if USE_TLS:
        ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        ctx.load_cert_chain(CERT)
        httpd.socket = ctx.wrap_socket(httpd.socket, server_side=True)

Nula TLS záznamů a sonda zvenčí (~18:45Z):

=== tls true vs false counts (current file)
   1007 false
https: 000 8.000950s
https: FAIL
http: 200 0.002349s

Stav procesu a blokující deskriptor (časy v CEST; fd 4 = 15:40Z):

wait_woken
state=S
lrwx------ 1 root root 64 Aug 22 13:35 3 -> socket:[17387]
lrwx------ 1 root root 64 Aug 22 17:40 4 -> socket:[56863]

Fronta spojení v síťovém jmenném prostoru kontejneru:

State      Recv-Q Send-Q Local Address:Port    Peer Address:Port Process
ESTAB      0      0        10.222.0.21:443       65.87.7.99:51740 users:(("python3",pid=2236,fd=4))
CLOSE-WAIT 1482   0        10.222.0.21:443    118.193.77.58:45320
CLOSE-WAIT 1480   0        10.222.0.21:443  151.145.196.242:52472
CLOSE-WAIT 208    0        10.222.0.21:443   198.235.24.217:64732
CLOSE-WAIT 1484   0        10.222.0.21:443   198.235.24.217:58664
CLOSE-WAIT 129    0        10.222.0.21:443   124.221.217.82:50572
CLOSE-WAIT 129    0        10.222.0.21:443   124.221.217.82:40070

Ověření opravy v dočasném kontejneru:

--- silent client for 14s (timeout is 8s)
https during silent client: 200 in 0.013667s

Stav po restartu v ostrém provozu:

webtrap listening on 443 tls=True timeout=60s body_cap=262144
webtrap listening on 80 tls=False timeout=60s body_cap=262144
https: 200 0.007601s
http: 200 0.002472s

Popis v HANDOVER.md, sekce 3 (přečteno 2026-09-11T17:40:58Z):

- webtrap-https: do 24. 8. dělal TLS handshake v accept smyčce bez timeoutu -> jeden tichý klient ho
  zablokoval na 51 h (22. 8. 15:40Z – 24. 8. 18:51Z, 0 HTTPS dat). Opraveno v kódu; watchdog navíc HTTPS
  sonduje každých 30 min bez ohledu na log.

9. Souvislosti

Související incidenty

  • 2026-08-24-srv3-dionaea-mongod-parser-freeze — jiná příčina, stejný vzorec „kontejner běží, senzor mlčí"; nalezeno v téže kontrole č. 2, oba incidenty vedly k přepsání watchdogu na liveness sondy.
  • 2026-08-22-srv3-pcap-ring-buffer-snaplen — pcap je jediná náhrada za chybějící HTTPS data, ale v tomto období jen s 256 B na paket.
  • 2026-08-22-srv3-syslog-message-size-truncation — zvýšení stropu těla na 256 KiB v rámci opravy zvýšilo počet zpráv useknutých v syslogu.

Co s incidentem nesouvisí

  • Restart webtrap-http 18:51:12Z — HTTP fungovalo, restart jen sjednotil verzi skriptu (výpadek v řádu sekund).
  • Skenery ve frontě CLOSE-WAIT — běžný provoz, ne příčina; příčinou bylo jediné spojení z 65.87.7.99.
  • Starší kopie /srv/honeypot/app/webtrap.py — v provozu se nepoužívá, neplést s aktivním skriptem.

10. Poučení

  • Senzor může být mrtvý, i když proces žije, port je otevřený a TCP spojení se naváže. Rozdíl pozná jen sonda, která položí službě otázku a ověří odpověď.
  • U honeypotu je každá operace bez časového limitu místo, kde ho zastaví jediné spojení. ssl.wrap_socket nad naslouchajícím socketem takové místo vyrábí, protože přesouvá handshake do přijímací smyčky. Útočník k tomu nepotřebuje úmysl — stačí sonda, která otevře spojení a odejde.
  • Dvě služby zapisující do jednoho souboru znemožňují poznat výpadek jedné z nich podle stáří výstupu — a znemožňují to i zpětně. Oddělené soubory nebo samostatná sonda pro každou službu.
  • U experimentu s řídkým dohledem omezuje délku výpadku jen automatická kontrola mezi lidskými kontrolami, a ta musí testovat službu, ne proces.