ASA

Cisco ASA Packet Capture from CLI

Cisco ASA Packet Capture from CLI
In: ASA

Packet capture from the Cisco ASA CLI is the highest-resolution diagnostic tool you have. When show conn, show xlate, and packet-tracer all agree the firewall should pass a flow but the application still does not work, capture is what proves whether the packet actually arrived, what its headers looked like, and where on the data plane it was discarded. This article walks through the four capture modes you will use most on a production ASA - interface raw-data, ASP-drop, type-asp-all, and match-filter captures - using real output from the live ASAv 9.23(1) in the PingLabz ASA reference lab. Every byte below came off the device.

If you are diagnosing an inbound flow that is being denied, start with ACL troubleshooting on Cisco ASA and then use captures to confirm. If a flow is allowed by ACL but still failing, run packet-tracer first to find the dropping phase, then add a capture on the dropping interface to see the packet itself.

When You Reach for Capture

Captures answer the questions packet-tracer cannot. Packet-tracer is a synthetic walk: you tell the ASA what the packet would look like and it tells you what would happen. A capture proves what the packet ACTUALLY looks like - the exact source port, the TTL, the TCP flags, the payload. The four scenarios where you want a capture, not a packet-tracer:

  • The application is failing intermittently. You need real timing and sequence numbers, not a synthetic test.
  • The application is failing in a way that depends on TCP state (a SYN that never gets a SYN-ACK, a RST in the middle of a session). Packet-tracer cannot model state.
  • You suspect the packet is being modified somewhere - by NAT, by inspection, by a service module - and you need to see the bytes on each side.
  • The flow is being silently dropped and packet-tracer says ALLOW. The drop is happening on the data path due to runtime state (no adjacency, asp drop, MTU, queue full) that packet-tracer does not check.

The Four Capture Types You Need

Capture typeWhat it seesUse when
type raw-data (default) on an interfaceEvery packet matching the filter as it ingresses or egresses that named interfaceYou want to confirm a packet arrived (or left), and inspect its headers
type asp-drop <reason>Every packet that hit the data path and was dropped for the named reason (or all reasons)You suspect a silent drop in the accelerated security path
type isakmpIKE/IKEv2 control-plane packets only, decodedVPN Phase 1 troubleshooting (see IPsec phase troubleshooting)
type webvpn user <user>WebVPN / clientless / AnyConnect SSL traffic for a specific userAnyConnect login or portal failures

Most production work is the first two: an interface raw-data capture to see real traffic, and an asp-drop capture to find what is being silently discarded.

Raw-Data Capture on an Interface

The basic syntax is:

capture <name> interface <interface-name> [match <protocol> <src> <dst> [eq <port>]]

From the lab, here are the four captures we have running on ASA-PERIM:

ASA-PERIM# show capture
capture INSIDE-CAP type raw-data interface inside [Capturing - 0 bytes]
  match tcp any host 8.8.8.8 eq www
capture OUTSIDE-CAP type raw-data interface outside [Capturing - 22108 bytes]
  match icmp any any
capture ASP-DROP type asp-drop acl-drop [Capturing - 47062 bytes]
capture ASP-ALL type asp-drop all [Capturing - 52332 bytes]
capture OUTSIDE-WEB-CAP type raw-data interface outside [Capturing - 0 bytes]
  match tcp any host 203.0.113.2 eq https

Three things to read out of that:

  • OUTSIDE-CAP has 22 KB of matching traffic. ICMP is flowing through outside, as expected from the inside-router pings.
  • INSIDE-CAP shows 0 bytes. That is not a bug - it is the answer. The TCP/80 traffic the filter is looking for never crossed the inside interface, which immediately tells you to look upstream.
  • ASP-DROP at 47 KB is the most useful diagnostic in this list. Something is being dropped silently on this firewall, and the next subsection shows exactly what.

Reading the Capture Buffer

To list the captured packets:

ASA-PERIM# show capture OUTSIDE-CAP packet-number 1
210 packets captured

   1: 01:48:21.437736       10.10.100.1 > 8.8.8.8 icmp: echo request
1 packet shown

ASA-PERIM# show capture OUTSIDE-CAP packet-number 2
210 packets captured

   2: 01:48:21.440071       8.8.8.8 > 10.10.100.1 icmp: echo reply
1 packet shown

That is the standard tcpdump-style summary: timestamp, source, destination, protocol, summary. Even at this resolution we can confirm the round-trip - request at .437736 followed by reply at .440071, about 2.3 ms - and that the source IP is 10.10.100.1 (the inside-router loopback being used as a probe source).

To see the actual bytes on the wire, append dump:

ASA-PERIM# show capture OUTSIDE-CAP packet-number 5 dump
219 packets captured

   5: 01:48:25.450522       10.10.100.1 > 8.8.8.8 icmp: echo request
0x0000   aabb cc00 0a00 5254 0023 7ba9 0800 4500   ......RT.#{...E.
0x0010   0064 0035 0000 ff01 3d49 0a0a 6401 0808   .d.5....=I..d...
0x0020   0808 0800 314d 0008 0002 0000 0000 017a   ....1M.........z
0x0030   4b79 abcd abcd abcd abcd abcd abcd abcd   Ky..............
0x0040   abcd abcd abcd abcd abcd abcd abcd abcd   ................
0x0050   abcd abcd abcd abcd abcd abcd abcd abcd   ................
0x0060   abcd abcd abcd abcd abcd abcd abcd abcd   ................
0x0070   abcd                                      ..
1 packet shown

Walk the bytes if you do not trust the summary line. Bytes 0x0E onward are the IP header: 4500 is version-4-header-length-5-DSCP-0, then 0064 is total length 100, ff01 is TTL 255 protocol 1 (ICMP), 0a0a 6401 is 10.10.100.1, 0808 0808 is 8.8.8.8. The ICMP payload is the abcd... pattern that IOS pings use as filler. This is exactly the level of detail you need when you suspect NAT is or is not happening: you can read the source and destination IPs out of the on-the-wire bytes.

ASP-Drop Captures: The Silent-Drop Diagnostic

The ASA's accelerated security path (ASP) drops packets for many reasons that never produce a syslog. Some common ones - acl-drop, no-adjacency, tcp-not-syn, no-route - account for a large fraction of "the firewall is broken" tickets that turn out to be perfectly correct ASA behavior on a misconfigured upstream device. To see them, capture by reason:

capture ASP-DROP type asp-drop acl-drop
capture ASP-ALL type asp-drop all

The first capture only stores ACL-drops. The second stores every dropped packet with its drop reason. From the lab, here are real packets out of the ACL-drop capture:

ASA-PERIM# show capture ASP-DROP packet-number 100
342 packets captured

 100: 01:55:07.071498       203.0.113.1.58279 > 198.51.100.10.1967:  udp 52 Drop-reason: (acl-drop) Flow is denied by configured rule, Drop-location: frame snp_classify_table_lookup:6044 flow (NA)/NA
1 packet shown

ASA-PERIM# show capture ASP-DROP packet-number 150
342 packets captured

 150: 01:56:21.388590       203.0.113.1 > 203.0.113.2 icmp: 8.8.8.8 udp port 1967 unreachable Drop-reason: (acl-drop) Flow is denied by configured rule, Drop-location: frame snp_classify_table_lookup:6044 flow (NA)/NA
1 packet shown

Read those carefully. The first one is an unsolicited UDP/1967 packet from ISP-RTR (203.0.113.1) to the public-NAT IP 198.51.100.10. The OUTSIDE_IN ACL has no permit for UDP/1967 to that host, so it hits the implicit deny and shows up here. That is not a bug - it is the firewall correctly enforcing policy - but it is the kind of drop you would otherwise have no visibility into.

The second packet is more interesting: an ICMP port-unreachable message from ISP-RTR being dropped on its way back to the ASA's outside interface. That is a return-traffic asymmetry: the ASA's outbound flow created an embedded port-unreachable, but the return path does not have a matching connection state, so the ASA classifies the response as unsolicited and drops it. You can spend hours staring at "why is the application slow" and miss this; one ASP-drop capture spells it out.

Match Filters: Catch What You Want, Skip What You Don't

An interface capture without a match clause grabs every frame on the interface, fills the buffer fast, and is hard to read. Filter aggressively:

! Specific TCP destination
capture INSIDE-CAP interface inside match tcp any host 192.168.50.10 eq 443

! ICMP both directions
capture OUTSIDE-CAP interface outside match icmp any any

! VPN-only encapsulated traffic
capture VPN-CAP interface outside match esp host 203.0.113.6 host 203.0.113.2

! UDP from one source
capture DNS-CAP interface inside match udp host 10.10.0.50 any eq 53

The grammar is the same as an extended ACL: protocol src-address [src-port] dst-address [dst-port]. The first match argument is the protocol; tcp and udp let you specify ports, icmp and esp do not. Use host x.x.x.x for a single IP, x.x.x.x y.y.y.y for a subnet (with mask, not wildcard), and any for everything.

Buffer Sizing and Circular Buffers

The default capture buffer is 524288 bytes (512 KB). On a busy interface that fills in seconds, then stops capturing - so by the time you look, the relevant packet is gone. Size the buffer for how long you need to wait:

capture LONG-CAP interface outside match icmp any any buffer 5000000 circular-buffer

buffer 5000000 sets a 5 MB buffer. circular-buffer tells the capture to overwrite the oldest entries when the buffer is full instead of stopping. With those two options on a moderate-traffic interface you can typically capture for a few minutes before old data rolls off, which is enough for any reactive diagnostic.

For an asp-drop capture, leave the buffer at default. Drops are sparse compared to interface traffic, and a 512 KB buffer holds tens of thousands of dropped packets.

Exporting the Buffer

For long captures, or anything you want to analyze in Wireshark, export the buffer as a pcap:

ASA-PERIM# copy /pcap capture:OUTSIDE-CAP tftp://10.10.0.5/outside-cap.pcap

You can also pull it via HTTPS through a browser at https://<asa-mgmt-ip>/admin/capture/<capture-name>/pcap if you have HTTPS management enabled. Once it lands in Wireshark the full TLS-style decode tree is yours, with NAT translation visible as a difference between the inside-leg and outside-leg captures of the same flow.

Stopping and Removing a Capture

Captures use CPU. They are usually trivial - an asp-drop capture is essentially free - but a heavily-matched interface capture on a busy ASA can produce noticeable load. Stop and remove a capture when you are done:

ASA-PERIM# no capture INSIDE-CAP
ASA-PERIM# no capture OUTSIDE-CAP

You can also pause without deleting - useful when you want to look at the buffer without it changing under you - via capture <name> stop, then resume with no capture <name> stop. This is the safer option during a live diagnostic.

A Real-World Diagnostic Flow

The pattern that solves most "this is not working" tickets in under five minutes:

  1. Run packet-tracer input <interface> <protocol> <src> <sport> <dst> <dport>. If it says Action: drop, the answer is in the dropping phase. Stop here and fix.
  2. If packet-tracer says Action: allow, set up two interface captures: one on the ingress interface, one on the egress interface, both filtered to the flow in question.
  3. Run capture ASP-ALL type asp-drop all in parallel. Keep buffer at default.
  4. Drive real application traffic. Wait until it fails.
  5. Compare the three captures. If the ingress capture shows the packet but the egress does not, look at show capture ASP-ALL for the drop reason. If the egress capture shows the packet but the application is still failing, the problem is downstream of the ASA.
  6. Stop and remove all three captures with no capture.

That progression - tracer first, captures second, asp-drop alongside - turns the ASA from a black box into a glass box. Combined with the asp-drop counter article for understanding what each drop reason means, and the conn / xlate article for the runtime state captures live alongside, you have the full diagnostic toolkit.

Key Takeaways

Captures are the difference between a guess and a proof. Use a type raw-data capture on the suspect interface with a tight match filter to confirm a packet arrived, and use a type asp-drop all capture in parallel to see what is being silently dropped on the data path. Read the buffer with show capture <name> packet-number N [dump] for byte-level detail, export to pcap for deep analysis, and remember to remove the capture when you are done. The full Cisco ASA reference cluster has the rest of the operational toolkit: asp-drop counter meanings, conn and xlate troubleshooting, and common outage scenarios that capture is the fastest path through.

Written by
More from Ping Labz
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.