skip to content

An inline IPS restarts while an intruder's session is open -- what can it judge about that flow when it returns?

level: middleimportance: should knowfreq 46%

answer

  1. state is built from the first packet
  2. no handshake, no first request
  3. reassembly has no anchor to hang on
  4. adopt blind or cut and break things
  5. the pre-window session is the one that survives

basics

~20 s

Very little. It rejoins mid-stream with no handshake, no first request and no reassembly state, so it sees packets from a conversation it never saw begin. Its midstream policy decides whether to pass that flow blind or cut it.

solid answer

~50 s

An inline engine's judgment is built from the start of a connection: the handshake fixes direction and sequence baseline, the first request or TLS ClientHello carries the name and the method, and stream reassembly is anchored on those offsets. A restart destroys all of it for connections already open, so the engine starts seeing acknowledgements in the middle of streams it never observed beginning. Engines therefore have an explicit midstream policy: adopt such flows and evaluate whatever bytes remain -- with no reassembly anchor, so every rule keyed on the request can never match -- or drop them so clients reconnect and are judged from the first packet. Dropping is the honest choice and it is also the one that kills long-lived sessions at a branch with nobody on site. An intruder's tunnel opened before the window is exactly the flow that survives, unjudged, for the rest of its life.

code

text · 9 lines
text
Flow A  10.14.3.22:51844 -> 203.0.113.9:443   (opened before the restart)
  first packet seen : ACK, payload 517 bytes   <- no SYN, no SYN/ACK observed
  TLS ClientHello   : crossed before the restart, never seen
  reassembly        : empty, stream offsets unknown
  ...
Flow B  10.14.3.31:52012 -> 198.51.100.4:443  (opened after the restart)
  first packet seen : SYN                       <- full handshake observed
  TLS ClientHello   : seen, SNI and ALPN parsed
  reassembly        : anchored

go deeper

for a junior

Know that an inline engine builds its understanding of a connection from the beginning, and that a restart loses that per-connection context even though the rules themselves come back intact.

for a middle

Explain exactly what is missing on an adopted flow -- handshake, sequence baseline, first request or ClientHello, reassembly anchor -- and why that makes a whole class of rules unable to fire rather than merely less likely to.

for a senior

Show judgment on adopt-versus-drop per segment by reconnection cost, and be able to produce afterwards a list of the flows that were adopted mid-stream and therefore never judged.

for a principal

Frame it as a standing exception the estate carries: who accepts cut sessions at which sites, and how the unjudged-flow list is reported rather than quietly forgotten after each window.

## What an inline engine holds per flow When a connection starts through an inline box, the engine builds state that everything afterwards depends on: - the five-tuple and the direction of each side, learned from the handshake; - the TCP sequence baseline, so it can tell an in-window segment from a spurious one and can order what it receives; - reassembly buffers anchored on those offsets, so a request split across segments can be evaluated as one thing rather than as fragments; - protocol parser state -- this stream is HTTP and here is the request line; this stream is TLS and here is the ClientHello, its SNI and the negotiated ALPN; - decisions already taken about the flow, which later rules build on. ## What a restart destroys, and what it does not A restart does **not** lose the rule set, the configuration or the box's identity. Those reload intact, which is exactly why the wrong answer is so easy to give: engineers say 'it comes back and resumes inspecting', and in a narrow sense it does -- packets reach rules again. What is gone is the **per-flow** state above, and it cannot be recovered, because the bytes that would have built it already crossed the wire and will never be sent again on that connection. So for a flow that was open across the window, the engine's first observation is something like an acknowledgement in the middle of a stream: no SYN, no ClientHello, no request line, empty reassembly, unknown offsets. ## Adopt or drop That leaves a policy choice with two honest options and no third: **Adopt.** Track the flow from wherever you joined it and evaluate the remaining bytes. Cheap for availability -- nothing breaks -- but a large class of rules is now structurally unable to fire, because they key on bytes that already crossed. A quiet flow is not a clean flow; it is an unexamined one. Adoption also forces the engine to relax its sequence checking, since it never saw the baseline, and that relaxation is itself a place where injection and desynchronisation tricks live. **Drop.** Cut every flow you cannot judge from the start. Clients reconnect and the new connections are inspected properly. Correct, and expensive in exactly the wrong place: at a branch with no local hands, the sessions that survive a maintenance window are the long ones -- a file transfer, a till or database link, an operator's remote session -- and cutting them turns a silent security decision into a support call. The useful refinement is to make the choice per segment rather than per box, on reconnection cost. Where clients reconnect for free, drop. Where a cut costs a business flow, adopt -- and record which flows you adopted, so that afterwards you can name them as unjudged rather than assume them clean. ## Why this is the intruder's window, not just an inconvenience An adversary who is already inside is holding long-lived connections, because that is what interactive access and a command channel look like. Those are precisely the flows that survive a reboot and get adopted. The result is uncomfortable and worth saying plainly in an interview: the traffic most likely to matter is the traffic least likely to be judged after the box comes back. The engine did not fail; it was simply never shown the beginning. There is a second-order version too. An intruder who knows a window is coming has no need to do anything clever: existing sessions carry them through it, and anything new they start inside the window crosses a closed relay with nothing evaluating it at all. ## What you can still say Upstream flow records still exist for the whole period. They carry the five-tuple, packet and byte counts and timestamps, and no payload, so they let you list the connections that spanned the window and how much moved on each -- never what moved. Combining that list with the engine's own view of which flows it adopted mid-stream is the closest thing to an honest account of what was never judged. ## The interview answer in one line The engine comes back with rules but without context, and context is what most rules match on. Decide in advance whether you would rather be blind or break connections, decide it per segment, and be able to say which flows you were blind to.

  • Why can a rule keyed on the first request or the TLS ClientHello never match an adopted flow?
    Because those bytes crossed while the engine was down and are not re-sent on an established connection. The parser has no anchor and no way to ask for them, so the rule is not disabled -- it is structurally unable to match. That is why a silent adopted flow tells you nothing about whether it was clean.
  • How would you decide adopt-versus-drop per segment rather than for the whole box?
    By reconnection cost and by what the segment carries. Guest wifi and ordinary web clients reconnect for free, so drop and get proper inspection back immediately. A till link, a database replica or a long transfer costs a business flow and a phone call, so adopt -- and log which flows were adopted so they can be listed as unjudged afterwards rather than assumed fine.
  • What does adopting a midstream flow do to the engine's TCP sequence checking?
    It has to accept segments whose baseline it never observed, so it infers or relaxes the acceptable window. That relaxation is a genuine weakness: it is where midstream injection and desynchronisation tricks live. It is another argument for dropping wherever reconnection is cheap, and for treating adopted flows as a bounded, temporary exception.

saying these in an interview costs you the question

  • Says the engine resumes inspecting exactly where it left off
  • Assumes first-request signatures still match adopted flows
  • Thinks the engine can ask for the handshake to be resent
  • Treats a silent adopted flow as evidence it was clean
  • Believes a restart also loses the rule set

context