Tools · Network tools · 14 / 24
Zeek: what a defender reads in conn.log
conn.log is one row per connection. The defender looks at who started it, who answered, the state, the history letters, and which side sent the application bytes.
The columns that carry the story
id.orig_h and id.orig_p are the originator, the side Zeek treated as starting the connection. id.resp_h and id.resp_p are the responder. proto is tcp, udp, or icmp. service is the application protocol Zeek recognized, such as dns, http, or ssl, and it stays unset when Zeek did not recognize one. A dash in a TSV log means no value.
duration is seconds. orig_bytes and resp_bytes count application data, not IP headers. A large orig_bytes with a tiny resp_bytes means the originator sent a lot and received little. conn_state is Zeek's summary of how the connection ended. history is a string of letters for what each side sent.
States and history letters
S0 means Zeek saw an attempt and no reply. S1 means the connection was established and the capture did not include a normal termination. SF means a normal establishment and a normal termination. REJ means the attempt was rejected. RSTO means the originator aborted an established connection with a RST. RSTR means the responder sent a RST. OTH means Zeek saw traffic in the middle, with no SYN in the file.
History letters are uppercase for the originator and lowercase for the responder. s is a SYN, h is a SYN-ACK, a is a pure ACK, d is data, f is a FIN, r is a RST. A clean web session often looks like ShADadFf: originator SYN, responder SYN-ACK, originator ACK, data both ways, FIN both ways. A one-sided attempt looks like S. You quote the state and the history together. Either one alone drops detail.
- Many S0 rows from one originator to many responder ports are a fan-out. File the host and the time. The capture is the evidence.
- A single S0 to a host the runbook says is up may be a return path this sensor could not see.
- SF with a long duration and odd byte counts is a session to review, not an alert by itself.
- service ssl plus an empty http.log means the application data was not cleartext HTTP.
A worked defensive case
conn.log for the lab hour shows one SF row from 10.8.0.20 to 10.8.0.40 port 443, service ssl, history starting ShA, and a modest byte count. It also shows dozens of S0 rows from 10.8.0.20 to 10.8.0.40 across many responder ports, history S, duration unset, all within a few seconds. The lab owner recognizes a misconfigured inventory job they had pointed at the whole port range.
You write two notes. The 443 row matches the hang ticket: the session was established, so the path is not the silent-filter story. The S0 fan-out is the inventory job, which they disable, and they add a watch for a repeat of one originator and many S0 ports. You do not describe how to reproduce the fan-out. The log already happened.
Where this is documented
Conn::Info in the Zeek script reference defines conn_state, history, orig_bytes, and the address columns. The history table in that reference is the authority for the letters. Uppercase is the originator.
Use a host-only lab network, or a capture the owner already handed you. These commands read that file or record a single lab host. They are not a scan of the public internet.
Commands
zeek-cut -m ts uid id.orig_h id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state history < /lab/zeek/conn.log
jq -c 'select(.conn_state == "S0") | {ts, uid, orig: ."id.orig_h", resp: ."id.resp_h", port: ."id.resp_p"}' /lab/zeek-json/conn.logDiagram
Two conn.log shapes in the same hour
What each state supports
State. S0, history S, duration empty, many responder ports.
Reading. This sensor saw attempts and no handshake.
Ticket. Name the originator and the window. Confirm the job with the owner.
State. SF or S1, history starting ShA, service ssl, bytes in both columns.
Reading. The handshake was established. Application bytes moved.
Ticket. The hang is an application question. Pair the uid with the service log.
Check yourself
1. A row shows conn_state S0 and history S from 10.8.0.20 to 10.8.0.40 port 22. What did Zeek see?
2. In history ShADadFf, what does the first capital S mean?
3. orig_bytes is 8000000 and resp_bytes is 400 on an SF row. What is the direction of the application data?