Back to Blog
β˜…β˜…β˜†IntermediateπŸ” Network Security
Palo AltoCisco ASAMigrationNGFWFirewallSecurity

Migrating from Cisco ASA to Palo Alto NGFW: A Step-by-Step Field Guide

March 4, 2026Β·18 min read

Overview

Migrating from Cisco ASA to Palo Alto is one of the most common firewall replacement projects in enterprise networks today. The challenge isn't just technical β€” it's doing it without impacting production. This guide covers the full migration lifecycle: pre-migration audit, policy translation, NAT, VPN cutover, and post-migration validation.






// ASA β†’ Palo Alto Migration β€” Before & After
Internet Cisco ASAACL-based Core SWLegacy Internet Palo Alto NGFWZone-based Core SWSame HW β†’CutoverBEFOREAFTERACL-based, no App visibilityApp-ID, URL filtering, Threat preventionCisco ASA β€” EOL/EOSPA-Series β€” PAN-OS

Phase 1 β€” Pre-Migration Audit on the ASA

Before touching the Palo Alto, fully document the existing ASA configuration.

Export ASA running config

bash
! Save full running config to TFTPASA# copy running-config tftp://10.10.10.50/asa-backup.cfg! Or display and capture to clipboardASA# more system:running-config

Audit what needs to migrate

bash
! Count access rulesASA# show access-list | count permitASA# show access-list | count deny! View NAT rulesASA# show nat detail! View existing VPNsASA# show crypto isakmp saASA# show vpn-sessiondb summary! View routingASA# show routeASA# show bgp summary! View current interface layoutASA# show interface ip briefASA# show nameif

Document everything before you touch the PA. Screenshot show conn count during peak hours β€” this tells you expected session volume for capacity planning.


Phase 2 β€” Expedition Migration Tool (Automated Approach)

Palo Alto's Expedition (formerly the Migration Tool) is a free VM-based appliance that parses an ASA running config and auto-converts objects, NAT rules, and security policies into PAN-OS format. On a large firewall with thousands of rules it can save days of manual work. On a simple firewall it is still useful for catching object naming inconsistencies you would otherwise miss.

Expedition does not replace review. Treat its output as a first draft, not a finished config. Plan 2–4 hours of post-conversion cleanup regardless of firewall size.

2.1 β€” Deploy the Expedition VM

Expedition is distributed as an OVA. It requires an Ubuntu 20.04-based VM with at least 4 vCPUs, 8 GB RAM, and 100 GB disk. You access it entirely through a browser.

# Download from Palo Alto support portal (login required)
# support.paloaltonetworks.com β†’ Software Downloads β†’ Expedition
# Download: Expedition-1.x.x.ova

# Deploy in VMware ESXi or Workstation β€” import the OVA
# Power on and note the IP shown on the console (DHCP by default)
# Or assign static IP via console:
ubuntu@expedition:~$ sudo nano /etc/netplan/00-installer-config.yaml
# Set your static IP, gateway, DNS
ubuntu@expedition:~$ sudo netplan apply

# Access Expedition web UI
# https://<expedition-ip>  (self-signed cert β€” accept the warning)
# Default credentials: admin / paloalto
# Change the password immediately on first login

2.2 β€” Prepare the ASA Config Export

Expedition needs the full ASA running config as a plain text file. Capture it cleanly β€” partial configs cause incomplete migrations.

# On the ASA β€” disable paging and capture everything
ASA# terminal pager 0
ASA# show running-config

# Copy the full output to a .txt or .cfg file on your workstation
# Filename example: asa-fw01-running.cfg

# Also export the object-group and access-list detail for cross-reference
ASA# show object-group
ASA# show access-list
ASA# show nat detail
ASA# show route

# Export to TFTP if you want a clean file without terminal artifacts
ASA# copy running-config tftp://192.168.1.10/asa-fw01-running.cfg

2.3 β€” Create a Project and Import the ASA Config

# In the Expedition web UI:
# 1. Click "Projects" β†’ "Add Project"
#    Name: ASA-Migration-FW01
#    Description: ASA FW01 to PA-3220 migration
#    Click Create

# 2. Inside the project β†’ "Devices" β†’ "Add Device"
#    Source Vendor: Cisco
#    Source OS: ASA (select version β€” e.g. 9.x)
#    Device Name: ASA-FW01

# 3. Upload config file
#    Click the device β†’ "Import Configuration"
#    Upload: asa-fw01-running.cfg
#    Expedition parses and validates the file
#    Any parse errors appear here β€” fix them in the config file if needed

2.4 β€” Run the Migration

# In the project β†’ "Migration" tab
# Source device: ASA-FW01
# Target PAN-OS version: match your PA hardware (e.g. PAN-OS 10.2)
# Target device type: Panorama or standalone firewall

# Migration options to configure:
#   Zone mapping β€” define which ASA interface maps to which PA zone
#   Example: outside (ASA) β†’ untrust (PA)
#            inside  (ASA) β†’ trust   (PA)
#            dmz     (ASA) β†’ dmz     (PA)

# Click "Migrate" β€” Expedition processes the config
# A progress bar shows: Objects β†’ NAT β†’ Security Policies β†’ Routes
# Typical time: 30 seconds to 5 minutes depending on config size

# After completion β€” review the Migration Report
# The report shows:
#   - Objects converted successfully
#   - Rules converted successfully
#   - Items that could not be converted (requires manual action)
#   - Warnings (shadowed rules, any/any rules, etc.)

2.5 β€” Review and Clean Up in Expedition

Before exporting, use Expedition's built-in analysis tools to clean up the converted policy. This is where the real value is β€” Expedition can find problems in your existing ASA config that you did not know about.

# Policy Optimiser β€” finds redundant and shadowed rules
# In project β†’ "Policy" β†’ "Optimisation"
#
# Run: "Shadowed Rules" analysis
#   Shows rules that are never hit because an earlier rule matches first
#   Action: delete or reorder shadowed rules
#
# Run: "Unused Objects" analysis
#   Address and service objects referenced by no rule
#   Action: delete to keep the object database clean
#
# Run: "Rule Usage" (requires log import β€” optional)
#   Import ASA syslog or ASDM CSV export to identify never-hit rules
#   Action: candidates for removal after stakeholder sign-off

# Check App-ID conversion
# Expedition maps port-based ASA rules to PA App-ID equivalents
# Example: tcp/443 β†’ ssl  |  tcp/80 β†’ web-browsing  |  tcp/25 β†’ smtp
# Review each mapping carefully — not all port→app translations are correct
# Rules with unusual ports will remain port-based β€” convert manually if needed

# Check NAT rules
# ASA NAT order (section 1 / section 2 / section 3) maps to PA NAT rule order
# Verify: static NAT, dynamic PAT, NAT exemptions all appear correctly
# PA evaluates NAT top-to-bottom β€” order matters, same as ASA

2.6 β€” What Expedition Converts Well vs. What Needs Manual Work

Config ElementExpedition ResultAction Required
Network objects and groupsβœ… Converts cleanly to PA address objects and groupsReview naming β€” PA uses flat namespace, long names may truncate
Service objects and groupsβœ… Converts to PA service objectsVerify port ranges and protocol types
Standard ACL-based permit/deny rulesβœ… Converts to security policies with zones from your mappingCheck rule order and shadowing via optimiser
Port-based App-ID mapping⚠️ Best-effort β€” common ports mapped, unusual ports left as-isReview each App-ID suggestion before accepting; test in lab
Static NAT (1:1)βœ… Converts to PA static NAT rulesVerify bi-directional flag setting matches ASA behaviour
Dynamic PAT (overload)βœ… Converts to PA dynamic IP and port NATConfirm interface-based vs. IP-based PAT
NAT exemptions (no-nat)⚠️ Often converts but verify each onePA uses a "No NAT" rule type β€” confirm exemptions are present
Crypto maps / site-to-site VPN❌ Not converted β€” must be rebuilt manuallyUse Phase 6 of this guide for manual IPSec config
AnyConnect / remote access VPN❌ Not convertedRebuild as GlobalProtect gateway and portal
User-based ACLs (identity firewall)⚠️ Partial β€” objects created but user-ID not linkedConfigure User-ID agent and re-map to PA user-based policies
QoS policies❌ Not convertedRebuild as PA QoS policy if required
Routing config (static routes)βœ… Converts to PA virtual router static routesVerify next-hop and interface references match PA interface names

2.7 β€” Export and Import to Panorama or PA Firewall

# Export from Expedition
# In project β†’ "Export" β†’ choose target:
#   "PAN-OS Configuration" β€” produces a candidate config XML
#   "Panorama Device Group + Template" β€” recommended for Panorama-managed PAs

# Download the exported XML file

# Option A: Import directly to a standalone PA firewall
# PA WebUI β†’ Device β†’ Setup β†’ Operations β†’ Import Named Configuration Snapshot
# Upload the XML β†’ then Load Named Configuration β†’ Commit
# WARNING: this replaces the candidate config β€” do on a fresh or lab PA only

# Option B: Import to Panorama
# Panorama β†’ Device Groups β†’ Import
# Expedition's Panorama export creates device group objects and policies
# Review in Panorama before pushing to managed firewalls

# Option C: API push (advanced β€” Expedition can push directly)
# In Expedition β†’ "Target Devices" β†’ add your PA firewall with API key
# Expedition pushes the converted config via PAN-OS API
# Still commits to candidate config only β€” you do a final review and commit

2.8 β€” Post-Import Validation in PAN-OS

After importing the Expedition config, validate it in the PA before any cutover.

# In PA WebUI β€” Objects β†’ Addresses
# Verify: object count matches ASA object-group count (roughly)
# Look for: objects named "migration_*" β€” Expedition prefix for auto-created objects

# Policies β†’ Security
# Sort by "Hit Count" if pushing to an existing device β€” new rules show 0
# Check: no rules with "any" in both source and destination zone + any application
# Verify: deny rules are present (ASA implicit deny becomes an explicit deny-all)

# Policies β†’ NAT
# Verify rule count and order matches your ASA NAT table
# Test each NAT rule with the PA CLI:
admin@PA# test nat-policy-match source 10.1.1.50 destination 8.8.8.8 destination-port 80 protocol 6 from trust to untrust
# Shows which NAT rule would match β€” compare against ASA nat translation output

# Test security policy match
admin@PA# test security-policy-match source 10.1.1.50 destination 8.8.8.8 destination-port 443 protocol 6 from trust to untrust application ssl
# Shows which security rule would match and the action (allow/deny)

# Validate config (catches missing references, zone errors)
admin@PA# validate full
# Must return: "Configuration is valid" before committing

Phase 3 β€” Interface and Zone Mapping

ASA uses security levels (0-100). Palo Alto uses named zones. You must redesign this.

ASA security levels β†’ PA zones

bash
ASA Interface       Security Level    PA Zone----------------------------------------------------inside              100               trustdmz                 50                dmzoutside             0                 untrustmanagement          100               mgmtvpn-tunnel          (varies)          vpn

PA interface configuration

bash
# Set interface types in Panorama/GUI:# Network > Interfaces > Ethernet# Or via CLI:set network interface ethernet ethernet1/1 layer3 ip 203.0.113.2/30set network interface ethernet ethernet1/1 layer3 ipv6 neighbor-discovery router-advertisement enable noset zone untrust network layer3 ethernet1/1set network interface ethernet ethernet1/2 layer3 ip 10.10.10.1/24set zone trust network layer3 ethernet1/2set network interface ethernet ethernet1/3 layer3 ip 172.16.50.1/24set zone dmz network layer3 ethernet1/3

Phase 4 β€” Security Policy Translation

ASA ACLs become PA security policies. The logic is similar but the structure is different.

ASA ACL example

cisco
! ASA β€” allow web traffic from inside to DMZaccess-list INSIDE-OUT extended permit tcp 10.10.10.0 255.255.255.0 172.16.50.0 255.255.255.0 eq 80access-list INSIDE-OUT extended permit tcp 10.10.10.0 255.255.255.0 172.16.50.0 255.255.255.0 eq 443access-group INSIDE-OUT in interface inside

Equivalent PA security policy

bash
# In Panorama: Policies > Security > Add# Rule name: Allow-Inside-to-DMZ-Web# Source zone: trust# Source address: 10.10.10.0/24# Destination zone: dmz# Destination address: 172.16.50.0/24# Application: web-browsing, ssl# Service: application-default# Action: Allow# Via CLI (set format):set rulebase security rules Allow-Inside-to-DMZ-Web from trustset rulebase security rules Allow-Inside-to-DMZ-Web to dmzset rulebase security rules Allow-Inside-to-DMZ-Web source 10.10.10.0/24set rulebase security rules Allow-Inside-to-DMZ-Web destination 172.16.50.0/24set rulebase security rules Allow-Inside-to-DMZ-Web application [web-browsing ssl]set rulebase security rules Allow-Inside-to-DMZ-Web service application-defaultset rulebase security rules Allow-Inside-to-DMZ-Web action allow

App-ID vs port-based: PA uses App-ID by default. If migrating port-based ASA rules, use service: <port> instead of application-default initially, then gradually convert to App-ID after validation.


Phase 5 β€” NAT Policy Migration

ASA NAT and PA NAT have different ordering logic. This is the most error-prone part.

ASA NAT types β†’ PA equivalents

bash
ASA NAT Type          PA Equivalent-------------------------------------Static NAT            Static NAT (DNAT)Dynamic PAT           Dynamic IP and Port (SNAT)NAT exemption         No-NAT rule (bi-directional)Twice NAT             Source + Destination NAT

ASA PAT rule

cisco
! ASA β€” PAT all inside traffic to outside interface IPnat (inside,outside) dynamic interface

Equivalent PA NAT rule

bash
# Panorama: Policies > NAT > Add# Rule: PAT-Inside-to-Outside# Source zone: trust# Destination zone: untrust# Source address: 10.10.10.0/24# NAT Type: Dynamic IP and Port# Translated Source: Interface Address (ethernet1/1)# Via CLI:set rulebase nat rules PAT-Inside-to-Outside source-translation dynamic-ip-and-port interface-addressset rulebase nat rules PAT-Inside-to-Outside from trustset rulebase nat rules PAT-Inside-to-Outside to untrustset rulebase nat rules PAT-Inside-to-Outside source 10.10.10.0/24

NAT exemption for VPN traffic

bash
# No-NAT rule must be ABOVE the PAT rule# Rule: No-NAT-VPN# Source: 10.10.10.0/24# Destination: 10.20.20.0/24 (remote VPN subnet)# Action: No Source Translationset rulebase nat rules No-NAT-VPN source-translation noneset rulebase nat rules No-NAT-VPN from trustset rulebase nat rules No-NAT-VPN to untrustset rulebase nat rules No-NAT-VPN source 10.10.10.0/24set rulebase nat rules No-NAT-VPN destination 10.20.20.0/24

Phase 6 β€” VPN Migration (Site-to-Site IPSec)

ASA site-to-site VPN β†’ PA IPSec tunnel

bash
# Step 1: Create IKE Crypto Profile (matches ASA Phase 1)# Panorama: Network > IKE Crypto > Add# Name: IKE-PROFILE-ASA-COMPAT# DH Group: group14# Authentication: sha256# Encryption: aes-256# Lifetime: 28800 seconds# Step 2: Create IKE Gateway# Network > IKE Gateways > Add# Name: GW-TO-REMOTE-SITE# Version: IKEv1 (match ASA)# Interface: ethernet1/1# Peer IP: <remote-peer-ip># Pre-shared key: <same key as ASA># IKE Crypto Profile: IKE-PROFILE-ASA-COMPAT# Step 3: Create IPSec Crypto Profile (matches ASA Phase 2)# Network > IPSec Crypto > Add# Name: IPSEC-PROFILE-ASA-COMPAT# Protocol: ESP# Encryption: aes-256# Authentication: sha256# DH Group: group14 (if PFS enabled on ASA)# Lifetime: 3600 seconds# Step 4: Create IPSec Tunnel# Network > IPSec Tunnels > Add# Name: TUNNEL-TO-REMOTE# Tunnel Interface: tunnel.1# IKE Gateway: GW-TO-REMOTE-SITE# IPSec Crypto Profile: IPSEC-PROFILE-ASA-COMPAT# Step 5: Add Proxy IDs (required when connecting to ASA)# Network > IPSec Tunnels > [tunnel] > Proxy IDs# Local: 10.10.10.0/24# Remote: 10.20.20.0/24# Protocol: any

Critical: PA requires explicit Proxy IDs when the peer is a Cisco ASA. Without them, Phase 2 will fail with INVALID_ID_INFORMATION.


Phase 7 β€” Cutover Procedure

Recommended cutover sequence

bash
# 1. Pre-cutover β€” run PA in tap mode alongside ASA (passive monitoring, no blocking)#    Network > Interfaces > set to Tap mode#    Monitor traffic for 1-2 weeks, fix policy gaps# 2. Maintenance window β€” cutover steps:# a. Take final ASA backupASA# copy running-config tftp://10.10.10.50/asa-pre-cutover.cfg# b. Commit final PA configadmin@PA> commit# c. Cable swap β€” move WAN and LAN cables from ASA to PA#    WAN: ISP uplink -> PA ethernet1/1#    LAN: Core switch uplink -> PA ethernet1/2# d. Update default gateway on core switch to PA inside IP! On core switchip route 0.0.0.0 0.0.0.0 10.10.10.1    ! PA inside IP, was ASA inside IP# e. Verify traffic passingadmin@PA> show session alladmin@PA> show counter global filter severity drop# f. Keep ASA physically connected but powered off for 48 hours (rollback option)

Phase 8 β€” Post-Migration Validation

bash
# Check active sessionsadmin@PA> show session alladmin@PA> show session info# Check drop counters β€” investigate anything above zeroadmin@PA> show counter global filter severity drop delta yes# Check security policy hit countsadmin@PA> show running security-policy# Check NAT translationsadmin@PA> show running nat-policy# Check VPN tunnelsadmin@PA> show vpn ike-saadmin@PA> show vpn ipsec-sa# Check routing tableadmin@PA> show routing route# Check interface statsadmin@PA> show interface ethernet1/1# Verify threat logs in Monitor tab# Monitor > Logs > Threat β€” should be minimal on day 1# Monitor > Logs > Traffic β€” should match expected flow patterns# Test key applications from each zoneadmin@PA> test security-policy-match source 10.10.10.10 destination 8.8.8.8 protocol 6 destination-port 443 from trust to untrust

Common Migration Mistakes

Mistake Impact Prevention
Not adding Proxy IDs for site-to-site VPNsPhase 2 fails immediatelyAlways add Proxy IDs when peer is ASA/non-PA
NAT exemption below PAT ruleVPN traffic gets NATtedPut No-NAT rule above all PAT rules
Using port-based rules everywhereMisses App-ID security valueMigrate port-based first, convert to App-ID over 30 days
Skipping tap mode validationPolicy gaps cause outages at cutoverAlways run tap mode for at least 1 week
Not matching IKE/IPSec proposals exactlyVPN tunnels won't come upCopy proposal values exactly from ASA config
Forgetting intrazone rulesTraffic within same zone blockedPA blocks intrazone by default β€” add explicit allow if needed