Junos SRX Security Policies in Real Life: Why Traffic Doesn't Match

Everything configured. Policy created. Commit complete. Traffic doesn’t flow. Or flows to the wrong place. Or NAT doesn’t apply. Welcome to SRX troubleshooting.

SRX security processing has a specific order. Understanding that order — and knowing where to look when things break — separates frustrating hours from quick fixes.

How SRX Actually Processes Traffic

Packet arrives
Interface → Security Zone lookup
Route lookup (egress interface/zone)
Security Policy evaluation (from-zone → to-zone)
NAT processing (if matched)
Forward packet

The critical insight: zone is determined by interface, policy is matched by zone pair. If your zones are wrong, your policy will never match.

The Zone Chain

┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Interface │ ──→ │ Zone │ ──→ │ Policy │
│ ge-0/0/1 │ │ trust │ │ trust→untrust│
└─────────────┘ └─────────────┘ └─────────────┘

Traffic from ge-0/0/1 (trust zone) going to ge-0/0/0 (untrust zone) needs a policy from trust to untrust. Simple concept, endless misconfigurations.

Top 5 Reasons “Policy Not Hit”

1. Zone Mismatch

The most common issue. Traffic enters through one interface but policy expects a different zone.

Terminal window
# Check interface zone assignment
show security zones
# Output:
# Security zone: trust
# Interfaces bound: 1
# ge-0/0/1.0
# Security zone: untrust
# Interfaces bound: 1
# ge-0/0/0.0

Fix pattern: Verify source and destination zones match your policy exactly.

Terminal window
# See which zone traffic is hitting
show security flow session source-prefix 192.168.1.0/24
# Check policy for that zone pair
show security policies from-zone trust to-zone untrust

2. Address Book Scope

Address book entries are zone-scoped by default. Address defined in zone A is invisible to policies involving zone B.

Terminal window
# Wrong: Address in wrong zone's address book
set security zones security-zone untrust address-book address internal-server 10.0.1.100/32
# Policy from trust→untrust can't see this address!

Fix pattern: Use global address book for addresses used across zones.

Terminal window
# Correct: Global address book
set security address-book global address internal-server 10.0.1.100/32
set security address-book global address-set servers address internal-server
# Now usable in any policy
set security policies from-zone trust to-zone untrust policy allow-server match destination-address internal-server

3. Application/ALG Issues

Application identification can prevent matches. ALG (Application Layer Gateway) can modify packets unexpectedly.

Terminal window
# Policy expects specific application
set security policies from-zone trust to-zone untrust policy web-traffic match application junos-http
# But traffic is HTTPS on non-standard port - doesn't match junos-http

Fix pattern: Use application sets or any for troubleshooting, then narrow down.

Terminal window
# Debug: What application is SRX seeing?
show security flow session extensive
# Look for "Application:" field
# Session ID: 12345, Application: junos-https, ...
# For non-standard ports
set applications application custom-https protocol tcp destination-port 8443
set security policies from-zone trust to-zone untrust policy web-traffic match application custom-https

4. Routing Instance Issues

Traffic in a routing instance may not hit policies as expected. VRF leaking adds complexity.

Terminal window
# Traffic in VRF but policy in main instance
show route table CUSTOMER-VRF 10.0.0.0/24
# Check session table for routing-instance
show security flow session routing-instance CUSTOMER-VRF

Fix pattern: Ensure policy exists for the routing instance context.

Terminal window
# Policy must reference correct zones
# Zones are global, but routing affects egress interface selection
show security zones security-zone trust interfaces
# Verify interface is in expected routing instance

5. NAT Order Confusion

Source NAT happens after policy match. Destination NAT happens before. This ordering causes endless confusion.

Inbound traffic:
1. Destination NAT (change dest IP)
2. Route lookup (with new dest)
3. Policy match (with original source, NAT'd destination)
4. Source NAT (if configured)
Outbound traffic:
1. Route lookup
2. Policy match (original IPs)
3. Source NAT

Fix pattern: For destination NAT, policy must match the post-NAT destination.

Terminal window
# Destination NAT: public 203.0.113.10 → private 10.0.1.100
set security nat destination pool server-pool address 10.0.1.100/32
set security nat destination rule-set inbound rule to-server match destination-address 203.0.113.10/32
set security nat destination rule-set inbound rule to-server then destination-nat pool server-pool
# Policy must match the NAT'd destination (10.0.1.100), not public IP!
set security policies from-zone untrust to-zone trust policy allow-server match destination-address 10.0.1.100/32

Debug Workflow

Step 1: Session Table

First, check if session exists:

Terminal window
show security flow session
# Filter by IP
show security flow session source-prefix 192.168.1.100/32
show security flow session destination-prefix 10.0.1.100/32
# Extensive output shows policy that matched
show security flow session extensive

Session exists? Check which policy matched. No session? Traffic isn’t flowing or policy is denying.

Step 2: Policy Hit Counters

Terminal window
# Show all policies with hit counts
show security policies hit-count
# Output:
# Logical system: root-logical-system
# Index From zone To zone Name Policy count
# 1 trust untrust allow-web 12543
# 2 trust untrust allow-dns 3421
# 3 trust untrust deny-all 89
# Zero hits on your policy? It's not matching.

Clear and retest:

Terminal window
# Clear counters
clear security policies hit-count
# Generate test traffic, then check again
show security policies hit-count

Step 3: Flow Trace

The nuclear option. Enables detailed logging of packet processing.

Terminal window
# Enable traceoptions
set security flow traceoptions file flow-trace
set security flow traceoptions file size 10m
set security flow traceoptions flag basic-datapath
set security flow traceoptions packet-filter my-filter source-prefix 192.168.1.100/32
commit
# Generate traffic, then view trace
show log flow-trace
# CRITICAL: Disable when done (performance impact!)
delete security flow traceoptions
commit

Reading Flow Trace Output

flow_process_pkt: received packet on ge-0/0/1.0, src 192.168.1.100, dst 8.8.8.8
flow_first_policy_search: policy search from zone trust to zone untrust
flow_first_policy_search: policy found: allow-web
flow_first_routing_lookup: dst 8.8.8.8, ifl 72 (ge-0/0/0.0)
flow_first_install_session: session installed successfully

Key lines to watch:

  • policy search from zone X to zone Y — confirms zone pair
  • policy found: <name> — which policy matched
  • policy search: no policy match — the dreaded no-match

Common Fix Patterns

Pattern 1: “Any” Debugging

When nothing works, start with wide-open policy to confirm traffic flow:

Terminal window
# Temporary debug policy (REMOVE AFTER!)
set security policies from-zone trust to-zone untrust policy DEBUG-ALLOW match source-address any
set security policies from-zone trust to-zone untrust policy DEBUG-ALLOW match destination-address any
set security policies from-zone trust to-zone untrust policy DEBUG-ALLOW match application any
set security policies from-zone trust to-zone untrust policy DEBUG-ALLOW then permit
insert security policies from-zone trust to-zone untrust policy DEBUG-ALLOW before policy <first-policy>
commit
# Traffic works? Problem is in policy specifics.
# Traffic fails? Problem is zones, routing, or NAT.

Pattern 2: Explicit Logging

Enable session logs to see what’s happening:

Terminal window
# Log at session init and close
set security policies from-zone trust to-zone untrust policy allow-web then log session-init
set security policies from-zone trust to-zone untrust policy allow-web then log session-close
commit
# View logs
show log messages | match RT_FLOW

Pattern 3: Policy Order Audit

Policies evaluate top-to-bottom. First match wins.

Terminal window
# See policy order
show security policies from-zone trust to-zone untrust
# Check if broad policy is shadowing specific one
# Policy "deny-all" at position 3 will never be reached if "permit-any" is at position 2

Reorder if needed:

Terminal window
# Move policy
insert security policies from-zone trust to-zone untrust policy specific-rule before policy broad-rule

Pattern 4: Global Policy Check

Don’t forget global policies — they apply across all zone pairs:

Terminal window
show security policies global
# Global policy might be permitting/denying before zone policy is evaluated

NAT Debugging

Source NAT Not Working

Terminal window
# Check NAT rule hit counts
show security nat source rule all
# Verify pool has addresses
show security nat source pool all
# Check if NAT is actually translating
show security flow session extensive | match "NAT"
# Look for: "In: ... NAT: ... Out: ..."

Destination NAT Not Working

Terminal window
# Check destination NAT rules
show security nat destination rule all
# Remember: policy must match POST-NAT destination!
# If NAT changes 203.0.113.10 → 10.0.1.100
# Policy destination-address must be 10.0.1.100

Verification Commands Summary

Terminal window
# Zone verification
show security zones
show interfaces terse | match "ge-"
# Policy verification
show security policies from-zone X to-zone Y
show security policies hit-count
show security policies detail
# Session verification
show security flow session
show security flow session extensive
show security flow session count
# NAT verification
show security nat source rule all
show security nat destination rule all
show security nat source summary
show security nat destination summary
# Address book verification
show security address-book global
show security zones security-zone <zone> address-book
# Flow trace (use carefully)
show log flow-trace

The Lesson

SRX policy debugging follows a predictable pattern:

  1. Verify zones first — most issues are zone mismatches
  2. Check session table — does traffic create a session?
  3. Look at hit counters — which policy is matching (or not)?
  4. Use flow trace last — performance impact, use surgically

The processing order matters:

  • Destination NAT → Routing → Policy → Source NAT
  • Policy matches on post-DNAT, pre-SNAT addresses

When stuck, simplify: broad “any” policy to confirm flow, then narrow down. Log everything. Read the trace output carefully.

SRX is powerful but unforgiving. Understanding the flow means faster troubleshooting.