Security Policies, Traffic Translation, and Validation
This chapter covers the end-to-end implementation and validation of an Inbound Destination Network Address Translation (DNAT / Port Forwarding) rule and corresponding Security Policies on a Palo Alto Networks VM-Series firewall. Using an intentionally vulnerable target application—OWASP Juice Shop deployed inside a Docker container on an AWS EC2 instance—we analyze how PAN-OS matches security policies to translated traffic, how to troubleshoot TCP resets and incomplete sessions via the Traffic Monitor, and how to safely expose internal containerized services over non-standard public ports.
1. Problem Statement: Secure Inbound Service Exposure
Organizations often possess a limited pool of routable public IPv4 addresses, frequently exposing multiple distinct internal services through a single public IP. Exposing an internal service involves two distinct enforcement mechanisms inside the Palo Alto firewall:
- Address & Port Translation (NAT Policy): Rewriting the destination IP from the firewall’s external public interface to the internal server’s private IP, and optionally translating the destination port (e.g., public port
8888to container application port3000). - Traffic Authorization (Security Policy Rule): Evaluating whether the traffic should be permitted, inspected by App-ID, and scanned by Content-ID security profiles.
A common architectural trap in PAN-OS configuration lies in understanding the order of operations between NAT evaluation, zone assignment, and security policy lookup. Misconfigurations typically lead to silent packet drops, application-level TCP resets (TCP reset from server), or session timeouts.
2. Architectural Model & Traffic Flow
The environment consists of an external client communicating across the public Internet to a Palo Alto Networks firewall running in AWS, which guards an internal network segment hosting a containerized OWASP Juice Shop instance.
3. The PAN-OS NAT Rule vs. Security Policy Paradigm
A foundational concept of PAN-OS is that Security Policies reference Pre-NAT IP addresses but Post-NAT Security Zones.
When crafting rules for inbound traffic:
- Destination Zone in Security Policy: Must be set to the Post-NAT Zone (the zone where the internal destination host actually resides, e.g.,
TrustorDMZ). - Destination Address in Security Policy: Must be set to the Pre-NAT IP (the original public destination IP targeted by the client).
- Service in Security Policy: Must reflect the port expected by the security rule engine depending on service object specifications.
Note: Confusing this rule by placing the private IP into the destination field of the Security Policy is the single most common reason inbound DNAT fails on Palo Alto firewalls.
4. Defining Network Objects and Services
To maintain modularity and avoid hardcoding IP addresses and ports across multiple policy sets, address and service objects must be created prior to drafting translation rules.
Service and Address Object Configuration
PAN-OS CLI Object Definitions
set address srv-host-juiceshop ip-netmask 10.0.1.50/32
set address srv-pub-firewall ip-netmask 203.0.113.15/32
set service obj-srv-tcp-8888 protocol tcp port 8888
set service obj-srv-tcp-3000 protocol tcp port 3000
5. Host-Side Deployment: Dockerizing OWASP Juice Shop
Before testing traffic through the firewall, the target service must be running and bound properly on the destination server. In an AWS EC2 Linux AMI, Docker is deployed and the container is initiated.
# Update local packages and install Docker runtime
sudo yum update -y
sudo amazon-linux-extras install docker -y
sudo systemctl enable --now docker
# Add administrative user to docker group
sudo usermod -a -G docker ec2-user
# Pull and run OWASP Juice Shop container
# Option A: Map public listener port 8888 directly to container 3000
docker run -d --name juiceshop -p 8888:3000 bkimminich/juice-shop
# Option B: Run container directly on port 3000 (firewall handles port translation)
# docker run -d --name juiceshop -p 3000:3000 bkimminich/juice-shop
Verify the local listener is up on the Linux instance:
# Verify listening ports
sudo ss -tulpn | grep -E '8888|3000'
6. Configuring Inbound Destination NAT (DNAT)
The Destination NAT rule intercepts traffic bound for the public IP on port 8888 and rewrites the packet headers so it can be routed across internal segments.
Port Forwarding Scenarios
Two design choices exist for port routing:
- Firewall Performs Port Translation: The firewall receives port
8888and translates both the IP (to10.0.1.50) and the Port (to3000). - Host Performs Port Translation: The firewall translates only the Destination IP (to
10.0.1.50), maintaining port8888. The Docker daemon on the host handles forwarding8888 -> 3000.
PAN-OS Configuration Commands (Destination NAT)
set rulebase nat rules "Inbound-JuiceShop-NAT" from Untrust
set rulebase nat rules "Inbound-JuiceShop-NAT" to Untrust
set rulebase nat rules "Inbound-JuiceShop-NAT" source any
set rulebase nat rules "Inbound-JuiceShop-NAT" destination srv-pub-firewall
set rulebase nat rules "Inbound-JuiceShop-NAT" service obj-srv-tcp-8888
set rulebase nat rules "Inbound-JuiceShop-NAT" destination-translation translated-address srv-host-juiceshop
# Optional port translation (if host listens only on 3000):
# set rulebase nat rules "Inbound-JuiceShop-NAT" destination-translation translated-port 3000
7. Security Policy Rule Implementation
Once the packet passes the NAT pre-processing engine, the firewall evaluates the rulebase to authorize the traffic.
PAN-OS Security Policy Rule Parameters
set rulebase security rules "Permit-Inbound-JuiceShop" from Untrust
set rulebase security rules "Permit-Inbound-JuiceShop" to Trust
set rulebase security rules "Permit-Inbound-JuiceShop" source any
set rulebase security rules "Permit-Inbound-JuiceShop" destination srv-pub-firewall
set rulebase security rules "Permit-Inbound-JuiceShop" application [ web-browsing ssl ]
set rulebase security rules "Permit-Inbound-JuiceShop" service obj-srv-tcp-8888
set rulebase security rules "Permit-Inbound-JuiceShop" action allow
set rulebase security rules "Permit-Inbound-JuiceShop" log-end yes
Security Policy Matching Summary
8. Live Troubleshooting and Log Analysis
During verification, web browsers targeting http://<Public-IP>:8888 may encounter connection errors. PAN-OS exposes granular session states through its Monitor tab and CLI session tables.
Investigating "TCP Reset from Server" (tcp-rst-from-server)
If the traffic log reads tcp-rst-from-server, it confirms that:
- The Palo Alto firewall successfully matched the NAT policy.
- The firewall permitted the traffic via the Security Policy.
- The firewall translated and forwarded the SYN packet to the internal host.
- The internal host generated an immediate TCP RST.
Root Cause & Resolution
A TCP reset typically occurs when:
- The firewall translates the port to
3000, but Docker is bound exclusively to host port8888(docker run -p 8888:3000). - The firewall keeps the port as
8888, but the Docker container was deployed directly on host port3000(docker run -p 3000:3000).
To fix this discrepancy, either align Docker to bind to the host port the firewall forwards to, or adjust the firewall's translated-port setting to match Docker's host port.
CLI Session Inspection
# Check active sessions filtered by application or port
show session all filter service 8888
# Detailed view of a specific session ID
show session id <SESSION_ID>
9. Configuration Commit and Verification Flow
10. Summary and Key Takeaways
- Pre-NAT vs. Post-NAT Logic: PAN-OS Security Policies require matching the Pre-NAT Destination IP address combined with the Post-NAT Destination Zone.
- Port Mapping Alignment: Port translation must match between the firewall's
translated-portsetting and the host's runtime binding (such as Docker's-phost port mapping). - Decoupled Troubleshooting: A
tcp-rst-from-serverlog entry confirms that both NAT and Security Policies functioned properly on the firewall; the issue lies on the downstream host or port configuration. - Session Analysis via Logs: Monitoring session attributes such as
session end reason(tcp-rst-from-server,incomplete,aged-out) allows rapid isolation between firewall drops and server-side connection resets. - Service Objects for Non-Standard Ports: Custom application ports (e.g.,
8888) must be explicitly defined as Service objects and mapped in both the NAT and Security rules. - Multi-Service Single IP Architecture: A single public IP address can host distinct external services (e.g., SSH on port
22and Juice Shop on port8888) using distinct Port-Forwarding / Destination NAT rules.