AWS Infrastructure and Application Deployment with Docker
This chapter details the deployment and integration of an AWS-hosted Linux workload behind a Palo Alto Networks Next-Generation Firewall (NGFW). It covers the allocation and association of secondary Elastic IPs (EIPs), the role of AWS Transit Gateway in hub-and-spoke topologies, host-level provisioning and containerization using Docker to host the OWASP Juice Shop application, and the mechanics of inbound Destination NAT (DNAT) paired with Palo Alto Security Policies.
1. Architectural Foundations: Hub-and-Spoke with Transit Gateway
In enterprise cloud deployments on AWS, routing between multiple Virtual Private Clouds (VPCs) and the external internet requires a centralized inspection point. A naive architecture interconnects individual VPCs using VPC Peering, which creates an unmanageable mesh network as the infrastructure scales.
To maintain centralized traffic inspection, a hub-and-spoke architecture is employed:
The AWS Transit Gateway (TGW) acts as a high-throughput, managed central router. Spokes attach to the Transit Gateway via VPC attachments. Route tables associated with each subnet explicitly route outbound traffic toward the Transit Gateway, which directs traffic through the Palo Alto NGFW for stateful Layer 7 inspection before egressing to the internet or crossing into another VPC.
2. Public IP Addressing: Elastic IP Allocation and Association
To expose internal services through an edge firewall, public addressing must be managed at the cloud provider layer.
The Dual Elastic IP Requirement
A single Palo Alto NGFW appliance requires multiple independent Elastic IP (EIP) allocations:
- Management Interface EIP: Dedicated solely to administrator access (HTTPS web interface and SSH) within an isolated management subnet.
- Dataplane Untrust Interface EIP: Bound to the external data interface (
eth1/1) processing transit, application inbound, and outbound traffic.
AWS 1:1 NAT Abstraction
AWS does not route the public Elastic IP directly onto the operating system interface. Instead, AWS operates an automated, stateful 1:1 Network Address Translation boundary at the hypervisor layer:
- The Elastic IP sits at the edge of the Internet Gateway (IGW).
- AWS automatically translates the public EIP to the primary or secondary private IP address assigned to the Elastic Network Interface (ENI).
- The Palo Alto firewall dataplane interface only ever sees the private IP address assigned to its subnet as the interface address, requiring specialized consideration when building Inbound NAT rules.
Note on AWS Billing Mechanics: Historically, idle unattached Elastic IPs incurred charges while attached instances were free. Current AWS billing policies enforce a persistent hourly charge for all allocated Elastic IP addresses, regardless of whether they are actively attached or processing traffic.
3. Workload Provisioning: EC2 Compute Selection and Outbound Connectivity
The backend application host is deployed as an Amazon EC2 instance within the private spoke subnet.
Compute Sizing Trade-Offs
For lightweight containerized testing and microservices, instances are selected according to strict workload requirements:
A t3.micro instance provides sufficient system memory to run the Docker daemon alongside node-based container workloads like OWASP Juice Shop without triggering out-of-memory (OOM) kernel panics.
Outbound NAT Requirement
Before any packages can be installed on the EC2 workload, it requires outbound internet connectivity to retrieve packages from regional repositories. Because the instance resides in a private subnet without a direct public IPv4 address:
- The EC2 instance sends an egress packet targeting
yumrepositories. - The packet routes through the Transit Gateway to the Palo Alto NGFW inside interface.
- The firewall performs Source NAT (SNAT), replacing the private EC2 IP with the dataplane outside interface's address.
- Traffic routes to the internet via the Internet Gateway.
4. Host Preparation and Docker Daemon Configuration
Once outbound connectivity is validated, the EC2 instance must be updated and configured with the container runtime. The host operating system uses the package manager to fetch the container runtime.
Package Updating and Runtime Installation
Connect to the EC2 instance via the previously established management/SSH pathway:
# Update repository metadata and system packages
sudo yum update -y
# Install Docker engine
sudo yum install docker -y
# Enable and initialize the Docker system daemon
sudo systemctl start docker
sudo systemctl enable docker
Non-Root Daemon Privileges
By default, the Docker daemon binds to a Unix socket owned by root. Running every Docker command with sudo introduces configuration drift and permission issues. To enable standard user execution:
# Add the default ec2-user to the docker group
sudo usermod -aG docker ec2-user
Operational Insight: Group membership updates require a new login shell session to regenerate user authorization tokens. If you do not disconnect and re-authenticate via SSH, subsequent commands that do not use
sudowill fail with a socket permission denied error (Got permission denied while trying to connect to the Docker daemon socket). To bypass re-logging in during setup, prepend administrative execution withsudo.
5. Containerizing Application Workloads: OWASP Juice Shop
The chosen target workload is OWASP Juice Shop, an intentionally vulnerable web application built on Node.js, Express, and SQLite.
Pulling and Running the Container
The container image is fetched directly from Docker Hub and mapped to host listening ports:
# Pull the latest OWASP Juice Shop image
sudo docker pull bkimminich/juice-shop
# Run container detached with explicit port mapping
# Syntax: -p <Host_Port>:<Container_Internal_Port>
sudo docker run -d --name juice-shop -p 8888:3000 bkimminich/juice-shop
Verify that the container process is running and bound to the host network stack:
sudo docker ps
The output confirms that container port 3000 is mapped to host port 8888:
6. Palo Alto NGFW Policy Architecture: NAT vs. Security Rules
Configuring inbound access to private workloads on a Palo Alto NGFW requires configuring two separate policy engines: the NAT Policy Engine and the Security Policy Engine.
Mental Model: The Order of Policy Operations
Unlike traditional stateful firewalls that process NAT and Access Control Lists (ACLs) sequentially under identical parameters, Palo Alto decouples address translation from authorization lookup.
Essential Rule Matrix for Inbound DNAT
7. Configuring Custom Service Objects and Inbound Policies
When traffic arrives on non-standard destination ports (e.g., external port 1234 or 2222), the firewall requires custom Service Objects to classify Layer 4 transport constraints before evaluating App-ID.
Creating the Service Object
- Navigate to Objects > Services.
- Click Add to define the external entry port:
- Name:
service-tcp-1234 - Protocol:
TCP - Port:
1234
- Name:
Defining the Inbound NAT Policy (DNAT)
- Navigate to Policies > NAT and click Add:
- Original Packet:
- Source Zone:
Untrust - Destination Zone:
Untrust - Destination Interface: Data Outside Interface
- Service:
service-tcp-1234 - Destination Address: Public Dataplane IP
- Source Zone:
- Translated Packet:
- Destination Address Translation:
Static IPorDynamic IP/Port - Translated Address:
10.0.2.50(Private IP of the EC2 Instance) - Translated Port:
8888(Port exposed on the Docker host)
- Destination Address Translation:
- Original Packet:
Defining the Security Policy
- Navigate to Policies > Security and click Add (or clone the existing inbound SSH rule):
- Source Tab:
- Source Zone:
Untrust - Source Address:
any
- Source Zone:
- Destination Tab:
- Destination Zone:
Trust(The final landing zone determined after route lookup) - Destination Address: Public Dataplane IP (The pre-NAT original destination)
- Destination Zone:
- Application Tab:
- Add App-IDs:
web-browsing,ssl
- Add App-IDs:
- Service/URL Category Tab:
- Service:
service-tcp-1234(Matches the ingress port specified in the initial packet)
- Service:
- Action Tab:
- Action:
Allow - Log Setting:
Log at Session End
- Action:
- Source Tab:
8. Verification, Flow Tracing, and Common Pitfalls
End-to-End Traffic Flow Walkthrough
Common Configuration Pitfalls
-
Destination Zone Confusion in Security Rules: A frequent misconfiguration is setting the Security Policy Destination Zone to
Untrustbecause that is where the physical packet arrives. The security policy lookup occurs after the NAT policy identifies the target destination, meaning the Destination Zone must be the post-NAT zone (e.g.,Trust). -
Destination Address Pre-NAT vs. Post-NAT: The Destination Address field in the Security Policy must remain the pre-NAT destination IP address (the external address targeted by the client), not the translated internal private IP address.
-
Service Object Mismatch vs. App-ID: When forwarding non-standard ports, configuring the Security Policy service as
application-defaultwill drop packets. The firewall checks Layer 4 criteria before App-ID signatures can be identified during the initial 3-way handshake. A custom service object (e.g.,service-tcp-1234) must be explicitly declared in the Security Policy. -
EC2 Security Group Encapsulation: AWS Security Groups act as stateful firewalls directly at the EC2 instance ENI. Even if the Palo Alto firewall allows traffic, the backend EC2 Security Group must explicitly permit ingress TCP traffic on port
8888originating from the firewall's egress subnet.
Summary and Key Takeaways
- Dual Elastic IP Deployment: Palo Alto deployments in AWS require separate EIP allocations for management access and dataplane ingress/egress.
- AWS 1:1 NAT Boundary: AWS performs an automated 1:1 NAT translation between assigned Elastic IPs and the instance's private ENI addresses before traffic hits the firewall interface.
- Transit Gateway Topologies: Transit Gateways centralize traffic routing between multiple Spoke VPCs and inspect cross-zone/internet-bound traffic through the firewall.
- Outbound NAT Dependency: Backend compute instances in private subnets rely on Source NAT (SNAT) through the firewall to retrieve operating system packages and container images.
- Container Isolation: Docker allows workloads to run in isolated user spaces, mapping custom host ports (e.g.,
8888) down to internal microservice application ports (e.g.,3000). - Palo Alto Decoupled Policy Engine: Inbound Destination NAT requires two distinct rules: a NAT Policy specifying the translation parameters and a Security Policy permitting the traffic flow.
- Security Policy Inversion Rules: On a Palo Alto firewall, security rules enforcing Destination NAT must match the Post-NAT Destination Zone (e.g.,
Trust) alongside the Pre-NAT Destination IP and incoming Port/Service Object.