T Techclick ← Juniper SRX hub
Juniper SRX · Junos flow · Session factory · Interactive lesson

SRX is a flow session factory. First packet prints the ticket.

The ticket says “HTTPS is broken — add a permit.” The last engineer already stacked one. On the dummy lab the session is Valid, Policy name: allow-app/4, In 12 packets, Out 0. Permit is not a SYN-ACK. This lesson is the official factory: first packet walks zone → dest NAT → policy → source NAT → session table. Later packets of the same flow ride the fast path.

20 min read · L2 primary · Quiz at end · Dummy lab only · Blog 2 · Evidence desk

After this page you can

Quick answer

An SRX is a stateful flow session factory. The first packet of a new flow has no session yet. Junos looks it up on source/destination address and port, protocol, and a unique token for the zone and virtual router. Miss → first-packet processing (screens, dest NAT, route, from-zone/to-zone policy, source NAT, then session create). Hit → fast-path processing. Success is a Valid session whose In and Out packet counters both increment — not a permit line in the book.

Say this out loud

I do not start with another permit. I ask whether a session formed, which from-zone/to-zone context ran, which policy the first packet matched, whether dest NAT rewrote before that lookup, and whether Out packets increment. Permit with Out 0 is a printed ticket with a dead return half.

1. Why permit is not a session

Every other blog starts with “write a from-zone to-zone policy.” That is why students freeze when the policy already says permit and the browser still spins. The real object is the flow session. A policy is only the hiring decision the factory makes on packet one. NAT, screens, AppID, and cluster membership are stamps on that ticket — not twelve extra products.

Official flow model: Junos treats a stream of related packets as one flow. Characteristics — which policy, whether NAT applies, whether an ALG is needed — are assessed for the first packet of that flow and cached. A session stores those measures, the state of the flow, and the resources (NAT ports, ALG gates) the rest of the packets will reuse.

Hero · the factory floor
Teaches: an SRX manufactures a session table of active flows; later packets hit that table, they are not re-hired by policy
Notice: the box does not “allow a packet.” It tries to manufacture a two-way session and then reuse that ticket.

What the ticket asked

“Firewall is blocking finance HTTPS.” That sentence is a hypothesis. The factory may already have permitted the flow and printed a dead ticket — Valid, named policy, Out still zero.

What you prove first

Identity of the box, then whether a two-way session exists, then which policy the first packet matched. The evidence desk is the night-shift version of this order.

The lie every L1 repeats

“The policy is permit, so the firewall is fine — we need a wider rule.” A permit only means the factory was willing to print the ticket. If the reverse half never arrives, widening the rule just prints more dead tickets.

2. Mental model — ticket plus factory stations

Hold four parts. Interviews fail when people mix them.

1. The ticket is the session

Two halves. In is the incoming (forward) flow. Out is the reverse flow. Official field names on show security flow session. State Valid means the slot is live. It does not mean the application answered.

2. The doorway is the zone

A zone is a collection of interfaces that define a security boundary. Incoming zone = the interface the packet arrived on. Outgoing zone = the forwarding lookup. That pair is the policy context.

3. The hiring manager is policy

Each from-zone / to-zone context is its own ordered list. First match wins. Permit, deny, or reject. Return packets of this session do not need a second permit. A new connection started from the other side does.

4. Proof is the session table

show security flow session is the live table. J-Web Monitor → Security → Flow Session is the same table in a browser. Syslog RT_FLOW_SESSION_* is history. A commit is only a recipe.

Path · first packet vs later packets
Teaches: the session-exists diamond splits first-packet processing from later-packet fast path
Notice: the diamond is not permit/deny. It is “does this flow already have a session?”
Flow 1 · one ticket, two halves, one policy name
Session 1042 · two flows, one first-packet match Client 10.10.8.22 trust Server 198.51.100.80 In · 12 pkts / 1880 B · 51901 → 443 Out · 0 pkts / 0 B · this is the dead half Zone stamp from-zone / to-zone trust → untrust Policy stamp first packet matched allow-app / 4 NAT stamp source NAT after permit Out dest 203.0.113.20 Dest NAT + route decide the to-zone. Policy prints the ticket. Source NAT rewrites the return. Session table is where you read the finished ticket. Out 0 is isolate, not another permit.

Read the solid arrow first (In). If the dashed return stays empty, do not add a rule. Re-read stations before you touch the policy book.

Pre-train three words before J-Web. An interface starts in the null zone and will not pass transit traffic until you bind it. Official: “By default, interfaces are in the null zone. The interfaces will not pass traffic until they have been assigned to a zone.” host-inbound-traffic is traffic to the SRX itself (SSH, ping, J-Web) and is dropped unless you enable it — it is not a transit policy. A screen is a zone option (SYN flood, land, ping-of-death), not a then permit line.

junos-https is a predefined application: TCP destination port 443. It is not “whatever SaaS speaks HTTPS.” Dynamic application / AppID is a different object on the policy. If the ticket is “only port 443,” this match is correct. If the ticket is “only Salesforce,” you need application identification, not this alias.

3. First-packet processing vs fast path

The first packet of a new flow has no session yet. Junos tries to match it to an existing session on six official criteria: source address, destination address, source port, destination port, protocol, and a unique token from a given zone and virtual router. Miss → first-packet processing, also called session setup. Hit → fast-path processing. That is why “I added a permit” sometimes does nothing until the old session dies.

Flow 2 · official first-packet order (student labels)
Ingress → session lookup → first-packet or fast path 1 Ingress parse · zone Session? 6 keys no FIRST-PACKET — print a new ticket first packet of this flow Screens zone option Static / dest NAT before route Route lookup to-zone Policy context from → to Source NAT after permit Session allocate FAST PATH — later packets of the same flow screens · TCP checks · cached NAT / ALG / IPsec · then forward. Policy is not re-hired. yes → skip setup Official facts students invert 1. Static NAT, then dest NAT, then route, then security policy, then reverse-static, then source NAT. 2. Policy and service lookup use the translated destination port after dest NAT. 3. Incoming zone = ingress interface. Outgoing zone = forwarding lookup. That pair is the context. 4. Policy name on the session is the policy the first packet matched — cached for the rest of the flow. 5. Session lookup includes a unique token for zone and virtual router. Same IPs, different zone = different job. Source: Traffic Processing on SRX Series Firewalls Overview · NAT Overview (rule processing order) Default branch policy: trust→untrust allow · untrust→trust deny. Intra-zone still needs a policy.

Read left → right, then the green fast-path bar. Decision diamond = “session already exists?” Dest NAT sits before policy on purpose.

Official NAT rule processing — quote this in an interview

During first-packet processing for a flow, NAT rules are applied in this order: (1) static NAT, (2) destination NAT, (3) route lookup, (4) security policy lookup, (5) reverse mapping of static NAT, (6) source NAT. Static and destination NAT run before route and policy. Source NAT runs after. Source: Junos OS NAT Overview, “Understanding NAT Rule Sets and Rules.”

#1 student trap — dest NAT after policy

Students coming from vendors that match policy on pre-NAT addresses write the security destination as the public VIP and then wonder why the context never hits. On SRX, dest NAT rewrites first. The policy destination must be the translated (real) address. Juniper states that SRX devices perform policy lookup and service lookup based on the translated destination port.

4. How to choose the next station

You are not choosing a product. You are choosing which factory station to inspect next. Dummy outputs live on the evidence desk.

You seeChooseDo not use whenProof you were right
Session Valid, named policy, Out Pkts 0 show arp no-resolve, then route and source NAT. Isolate the return. You stack a second permit in the same context. Out Pkts increment, or you name Incomplete ARP / missing reverse route.
No session after a VLAN / cutover show security zones — redraw interface → zone. Null zone drops transit. You edit the old trust→untrust rule first. Ingress IF is in the from-zone you think you edited.
Empty table after a power event show chassis cluster status — name RG0 and RG1 primaries separately. You assume “node0 is primary” covers the data plane. You are on the RG1+ primary, then the session command is re-run.
Policy uses junos-https Treat it as predefined TCP/443. Enough for “port 443 only.” You claim it is the SaaS AppID. Application on the session is the predefined service, not a dynamic name.
Server must start a new connection back Write a second policy in the reverse context. You expect the stateful return of this session to cover a new SYN. A new Session ID appears for the reverse 5-tuple.
SSH to the box fails; transit is fine Zone host-inbound-traffic system-services (ssh, ping, https). You add a transit permit from-zone to-zone. Management session reaches the RE. Transit policy is unchanged.
Dest NAT works in the NAT table, policy misses Rewrite the policy destination to the post-DNAT address. You match the public VIP as if policy ran first. First packet creates a session whose Policy name is the intended rule.
Need PAT so the server can answer Source NAT rule-set from zone / to zone, action interface (egress IP + PAT). You hide NAT inside the security policy the way some vendors do. Out dest is the interface address; show security nat source rule hits increment.
Stateful return vs reverse policy

To allow A→B you configure a policy from zone A to zone B. Return packets of that session ride the session table on the fast path. A new connection started from B to A needs a second policy. Juniper states this as two unidirectional policies, one per direction of new traffic. Source: Security Policies Overview.

5. Runbook Side A → B → C

Lab values only. Hostname srx-lab, model srx380, Junos 23.4R2.13. User 10.10.8.22 on ge-0/0/1.0 (zone trust) to SaaS 198.51.100.80:443 on ge-0/0/0.0 (zone untrust). Interface source NAT to 203.0.113.20. Policy allow-app / id 4. Session ID 1042. Addresses are RFC 5737 / RFC 1918. Confirm live syntax on the installed Junos train before you type on a customer box. Primary source for each block is named.

Side A — bind the doorway (zones)

Primary source: Junos OS Security Zones + J-Web “Add a Zone.” Interfaces are the doorway. Until ge-0/0/1.0 is in trust and ge-0/0/0.0 is in untrust, no transit policy can see the packet. Default: interfaces sit in the null zone.

  1. Bind untrust the same way

    Zone untrust, interface ge-0/0/0.0. Enable only the host services you intend. Factory-default branch boxes (SRX300/320/340/345/380 and kin) allow trust→untrust and deny untrust→trust — do not assume that after the first commit. Source: Security Policies Overview, platform-specific factory-default policy.

  2. Give the box a way out

    A default route toward the untrust next hop is what makes the to-zone untrust. Incoming zone is the ingress interface. Outgoing zone is the forwarding lookup. Same IPs with no route out of untrust never reach the trust→untrust context.

  3. Prove the map

    Operational: show security zones. If the packet ingresses an interface that is not in the from-zone you edited, the context never runs. Dummy lab output is on the evidence desk.

Lab CLI · zones — not a live tenant
set security zones security-zone trust interfaces ge-0/0/1.0
set security zones security-zone trust host-inbound-traffic system-services ping
set security zones security-zone trust host-inbound-traffic system-services ssh
set security zones security-zone untrust interfaces ge-0/0/0.0
set routing-options static route 0.0.0.0/0 next-hop 198.51.100.1

Side B — print the ticket (policy + source NAT)

Primary source: Security Policies Overview + J-Web “Add a Rule to a Security Policy” + NAT Overview. Policy is the permit to create a session. Source NAT is the rewrite so the server can answer. They are separate hierarchies on SRX — unlike some vendors that NAT inside the rule.

  1. CLI equivalent (lab)

    Lab CLI · security policy — not a live tenant
    set security policies from-zone trust to-zone untrust policy allow-app match source-address finance-net
    set security policies from-zone trust to-zone untrust policy allow-app match destination-address any
    set security policies from-zone trust to-zone untrust policy allow-app match application junos-https
    set security policies from-zone trust to-zone untrust policy allow-app then permit
    set security policies from-zone trust to-zone untrust policy allow-app then log session-init
    set security policies from-zone trust to-zone untrust policy allow-app then log session-close

    Each context is its own ordered list. First match wins. If there is no matching policy, the packet is dropped. Put allow-app above any catch-all. Source: Configuring Security Policies.

  2. Source NAT — interface PAT

    Source NAT is a separate hierarchy. Official interface NAT: translate the original source IP to the egress interface IP; port address translation is always performed. Lab rule-set TRUST-TO-UNTRUST, rule PAT-OUT, from zone trust, to zone untrust, source 10.10.8.0/24, action interface.

    Lab CLI · source NAT
    set security nat source rule-set TRUST-TO-UNTRUST from zone trust
    set security nat source rule-set TRUST-TO-UNTRUST to zone untrust
    set security nat source rule-set TRUST-TO-UNTRUST rule PAT-OUT match source-address 10.10.8.0/24
    set security nat source rule-set TRUST-TO-UNTRUST rule PAT-OUT then source-nat interface

    Source NAT rule-set matching prefers more specific from/to (interface beats zone beats routing-instance). You cannot specify the same source and destination conditions on two source NAT rule-sets. Source: NAT Overview · Source NAT.

  3. Commit, then do not celebrate

    A green commit means the recipe printed. It does not mean finance HTTPS answered. If a session for this 5-tuple already exists, later packets stay on the fast path until the slot times out or you clear it in a change window. Side C is the proof.

junos-https is not AppID

junos-https is a predefined policy application: TCP destination port 443. Dynamic applications on the J-Web rule (Any / Specific / None) are the AppID object. Logging service-name="junos-https" on a session only proves the port match, not that Salesforce was identified. Source: Predefined Policy Applications · Add a Rule (Services vs Dynamic applications).

Side C — prove the two-way session

Primary source: show security flow session Output Fields + J-Web “Monitoring Flow Session Statistics.” Official: Policy name is the name and ID of the policy that the first packet of the session matched. In is the incoming flow. Out is the reverse flow.

  1. Baseline the box

    show version — quote hostname srx-lab, model srx380, Junos 23.4R2.13. If logical-systems or tenants exist, say so before any flow output. Half of “it doesn’t match the doc” is a different train. Half of empty session tables is the wrong cluster node.

  2. Click finance HTTPS, then open the live table

    show security flow session destination-prefix 198.51.100.80 or J-Web Monitor → Security → Flow Session (high-end platforms also label this Flow Session Statistics). This is not a syslog page. Filter source 10.10.8.22 and dest port 443.

  3. Read the stamps on the row

    You need State Valid, Policy name allow-app/4, In packets incrementing on ge-0/0/1.0, Out packets incrementing on ge-0/0/0.0. Copy the Session ID. Out destination 203.0.113.20 is the PAT’d source — interface NAT already happened.

  4. If Out is zero, do not add a rule

    Next: show arp no-resolve, show route 198.51.100.80, show security nat source rule all. Proof of a two-way session is Out packets incrementing, not another commit. That isolate path is the evidence desk.

Proof · session-table cockpit
Teaches: operators prove a live two-way session from In and Out counters, not from a permit action
Notice: juniors stare at Action = permit. Seniors stare at Session ID, Policy name, and Out Pkts.
Live session — dummy lab, not a customer firewall
user@srx-lab> show security flow session destination-prefix 198.51.100.80
Session ID: 1042, Policy name: allow-app/4, Timeout: 1800, Valid
  In: 10.10.8.22/51901 --> 198.51.100.80/443;tcp, Conn Tag: 0x0, If: ge-0/0/1.0, Pkts: 12, Bytes: 1880
  Out: 198.51.100.80/443 --> 203.0.113.20/18422;tcp, If: ge-0/0/0.0, Pkts: 0, Bytes: 0
Total sessions: 1
Green success on this runbook

Predicted context = trust→untrust. Live Policy name = allow-app/4. State Valid. In Pkts > 0 and Out Pkts > 0. Interfaces match the zone map. ARP complete for the egress next hop. The user can finish the same finance HTTPS click. Permit with Out 0 is not success. The stock dummy lab is the failure case — keep it that way until you can say why.

6. Runtime — old slots, screens, RG0 vs RG1

After the first packet creates the session, later packets take the fast path. Official fast-path: the SPU applies configured screens, performs TCP checks, applies cached flow services (NAT, ALG, IPsec), then prepares the packet for forwarding (filters, shaping, scheduling) and transmits it. Policy is not re-evaluated. That is why a newly committed permit does not touch an existing 5-tuple until timeout or clear security flow session in a change window.

Screens still apply on the zone during fast-path. A session can match allow-app and still die on an ids-option (SYN flood, land, ping-of-death). Quote the screen. Do not argue the policy hit-count. Source: Traffic Processing — Understanding Fast-Path Processing.

If you change source NAT, remember the documented refresh: when interface NAT is configured and the interface IP changes, sessions set up with that NAT are refreshed and new sessions are set up with the new address. Verify with the same show security flow session command. Source: Monitoring Security Flow Sessions.

A chassis cluster is two copies of the factory. RG0 is created at cluster init and owns the Routing Engine. Preemption cannot be enabled on RG0; a manual failover restarts RE processes and can drop routing state. RG1+ owns reth child links and the data-plane sessions that belong to that group. The two primaries can sit on different nodes. If you SSH to node0 because “it is primary” and RG1 is primary on node1, show security flow session on node0 is the wrong factory. Pair show chassis cluster status with the session command; on a live cluster add node primary or a node-id. Source: Chassis Cluster Redundancy Groups.

Logging is not free. Session log is enabled in the flow code. Juniper documents that enabling both session-init and session-close degrades performance further than init alone. Use both when you need the create and the close reason; do not leave them on every catch-all as a reflex. Source: Security Policies Overview.

7. Traps + session-table proof

SymptomLooks likeActuallyFirst move
Permit + spinning browser Missing rule 0 Out — return path / NAT / ARP / server Session ID + In/Out, then ARP / route
Added a permit, nothing changed Commit failed Old session on the fast path Wait timeout or clear the session in a window
No session after a VLAN cutover Policy text still “correct” Ingress IF left the from-zone (or still null) show security zones interface list
Empty table after a power event Policies vanished You are on the RE primary, not the data primary Name RG0 and RG1+ Status separately
Dest NAT hits, policy misses NAT is broken Policy destination is the pre-DNAT VIP Match the translated (real) address
junos-https permit, wrong SaaS still flows AppID failed Predefined TCP/443 is not a brand filter Dynamic application, not this alias
SSH to the box fails; users browse Need a transit permit host-inbound-traffic not enabled Zone system-services ssh / https
Permit matched, session dies anyway Need a wider rule Zone screen / ALG / NAT pool exhaustion Quote the screen or NAT hits — not another permit
Manual RG0 failover as a test Harmless HA drill RE process restart, routing churn Use RG1 for data tests; RG0 only with change-control
Proof checklist — finance HTTPS is actually working
Interview close you can steal

An SRX is a flow session factory between zones. The first packet of a new flow walks first-packet processing: incoming zone, dest NAT, route, from-zone/to-zone policy, source NAT, then the session table. Later packets ride the fast path. I prove the ticket with show security flow session: Session ID, Policy name of the first-packet match, In and Out both incrementing. Permit without Out is not success.

Related: The evidence desk — first tool + proof field · Flow session troubleshooting · Architecture and zones · Security policies and AppID · NAT, VPN, screens · Juniper SRX hub

Knowledge check

Six judgment questions. Map each miss back to the section named in the reason.

Q1

You committed a new permit. The user is still failing on the same 5-tuple. Best explanation?

Correct: c. Later packets ride the session. Wait for timeout or clear the session in a change window. Re-read First-packet processing vs fast path.
Q2

What is an SRX from the factory-floor view?

Correct: b. One session, several stations. Policy is the hiring decision on packet one. Re-read Mental model.
Q3

Session 1042 shows Policy name allow-app/4, Valid, In 12 packets, Out 0. What do you do first?

Correct: a. Permit without Out is a printed ticket with a dead return half, not a missing rule. Re-read Why permit is not a session and Side C.
Q4

During first-packet processing for a flow, Junos applies NAT and policy in which official order?

Correct: d. NAT Overview: static NAT → dest NAT → route → policy → reverse-static → source NAT. Policy uses the translated destination. Re-read First-packet processing vs fast path.
Q5

What does Junos use to decide whether a packet already has a session?

Correct: b. Official first-packet match criteria, Traffic Processing on SRX Series Firewalls Overview. Same IPs in a different zone/VR are a different factory job. Re-read First-packet processing vs fast path.
Q6

What proves finance HTTPS is actually working in the session table?

Correct: c. The session table is the live ticket. Syslog is history. Commit is a recipe. Re-read Side C and the proof checklist.

Sources

Related: Blog 2 · Evidence desk · Flow session troubleshooting · Architecture and zones · Security policies and AppID · Juniper SRX hub · Dummy lab

Every CLI block on this page is fictional lab data paired with the evidence desk (client 10.10.8.22:51901, dest 198.51.100.80:443, PAT 203.0.113.20, Session ID 1042). Nothing is sent to a live tenant or device.