ASA

Cisco ASA Object Groups: Network, Service, and Protocol

Cisco ASA Object Groups: Network, Service, and Protocol
In: ASA, Fundamentals

Object groups are the difference between an ACL you can read and one you cannot. Without them, an ACL that permits HTTP, HTTPS, and SSH from three jump-host source addresses to four DMZ servers takes 36 lines. With them, the same intent collapses to one. They also unlock a NAT configuration model where an inside subnet, a DMZ host, and an outside translation pool are first-class named objects you can reference everywhere by name. This article covers the four object-group types on the Cisco ASA, how they nest, and the actual show output from the lab's running OUTSIDE_IN ACL and NAT pool.

Object groups belong to the Cisco ASA Fundamentals tier. Once they click, the rest of the platform feels less arbitrary because every ACL, NAT rule, and policy-map starts referencing the same named building blocks.

Objects vs Object Groups

The ASA has two related but distinct ideas:

ConstructHoldsCreated withReferenced from
ObjectOne thing: one host, one subnet, one range, one service port, one FQDNobject network NAME or object service NAMEACLs, NAT rules, policy-maps
Object groupA list of things, optionally a list of other groupsobject-group network NAME, object-group service NAME, etc.ACLs, NAT rules (some), policy-maps

Single objects are useful for NAT (one host on the inside translates to one address on the outside) and as readable handles for one specific endpoint. Object groups are useful when you have collections (three jump-host source IPs, four DMZ servers, the standard "web ports" set of 80 and 443).

The Four Object Group Types

Each type wraps a specific kind of value.

TypeHoldsUsed in
object-group network NAMEIPv4/IPv6 hosts, subnets, ranges, FQDNs, and other network groupsACL source/destination, NAT real/mapped, AAA target, route-map match
object-group service NAMETCP/UDP port lists (single, range), or unified protocol+port pairs (TCP/80 + UDP/53)ACL service field, NAT service translation, inspection class-maps
object-group protocol NAMEIP protocol numbers/names (tcp, udp, icmp, gre, esp, 50)ACL protocol field
object-group icmp-type NAMEICMP type codes (echo, echo-reply, time-exceeded, unreachable)ACL ICMP type field

Network and service groups are 95% of what you use. Protocol and ICMP-type groups are useful but situational.

Network Object Groups

A network group is a list of network endpoints. Each entry is one of: a host, a subnet, a range, an FQDN, or another network group (nesting).

ASA-PERIM(config)# object-group network ADMIN-JUMP-HOSTS
ASA-PERIM(config-network-object-group)#  description Permanent admin jump hosts
ASA-PERIM(config-network-object-group)#  network-object host 10.10.0.50
ASA-PERIM(config-network-object-group)#  network-object host 10.10.0.51
ASA-PERIM(config-network-object-group)#  network-object host 10.10.0.52
ASA-PERIM(config-network-object-group)#  network-object 10.99.0.0 255.255.255.0
ASA-PERIM(config-network-object-group)#  group-object PARTNER-MGMT

The last line is nesting: PARTNER-MGMT is presumably another object-group network defined elsewhere, and its members get folded into ADMIN-JUMP-HOSTS. Nesting is one level deep and resolves at compile time, so there is no runtime cost.

FQDN entries are also supported and resolve at intervals (default every 60 seconds):

ASA-PERIM(config)# object-group network EXTERNAL-VENDORS
ASA-PERIM(config-network-object-group)#  network-object fqdn updates.vendor-a.com
ASA-PERIM(config-network-object-group)#  network-object fqdn licensing.vendor-b.com

FQDN-based ACLs are very useful for outbound-allowlists ("this server can only reach these specific cloud APIs") but require functioning DNS on the ASA, which means a working dns server-group DefaultDNS with reachable resolvers and a sane dns name-server list.

Service Object Groups

The modern syntax is unified service groups, which include the protocol in each entry:

ASA-PERIM(config)# object-group service WEB-PORTS
ASA-PERIM(config-service-object-group)#  service-object tcp eq 80
ASA-PERIM(config-service-object-group)#  service-object tcp eq 443
ASA-PERIM(config-service-object-group)#  service-object tcp eq 8080
ASA-PERIM(config-service-object-group)#  service-object tcp eq 8443

Used in an ACL:

access-list OUTSIDE_IN extended permit object-group WEB-PORTS any object-group DMZ-WEB-FARM

That single ACL line expands internally to four (one per port) and the ASA reports each line in show access-list with its own hit counter.

The legacy syntax is protocol-locked service groups, where the protocol is declared at the top:

ASA-PERIM(config)# object-group service WEB-TCP-LEGACY tcp
ASA-PERIM(config-service-object-group)#  port-object eq 80
ASA-PERIM(config-service-object-group)#  port-object eq 443
ASA-PERIM(config-service-object-group)#  port-object range 8000 8100

Both forms still work. The unified syntax is more flexible (you can mix TCP and UDP in one group) and is what the configuration generator uses by default for new groups created via ASDM. Use the unified form for new work.

Protocol and ICMP-Type Groups

Less common but useful. Protocol groups simplify rules that need to allow several IP protocols between the same source and destination:

ASA-PERIM(config)# object-group protocol IPSEC-PROTOS
ASA-PERIM(config-protocol-object-group)#  protocol-object esp
ASA-PERIM(config-protocol-object-group)#  protocol-object ah
ASA-PERIM(config-protocol-object-group)#  protocol-object udp
ASA-PERIM(config-protocol-object-group)#  protocol-object 50

ICMP-type groups are how you write ACLs that allow only specific ICMP message types (the safe-by-default approach instead of permit icmp any any):

ASA-PERIM(config)# object-group icmp-type SAFE-ICMP
ASA-PERIM(config-icmp-object-group)#  icmp-object echo-reply
ASA-PERIM(config-icmp-object-group)#  icmp-object time-exceeded
ASA-PERIM(config-icmp-object-group)#  icmp-object unreachable

Used in:

access-list OUTSIDE_IN extended permit icmp any any object-group SAFE-ICMP

This permits the diagnostic ICMP types that traceroute and PMTU discovery need, without permitting the rest. A nice middle ground between "all ICMP" and "no ICMP."

Real Lab: How Objects and Groups Wire Together in an ACL

From the lab's ASA-PERIM, this is the running OUTSIDE_IN ACL after the changes from Sessions 1 and 2:

ASA-PERIM# show access-list OUTSIDE_IN | begin OUTSIDE_IN
access-list OUTSIDE_IN; 5 elements; name hash: 0xe01d8199
access-list OUTSIDE_IN line 1 extended deny tcp host 198.51.100.99 any (hitcnt=1) (Last Hit=00:01:09 UTC May 10 2026)
access-list OUTSIDE_IN line 2 extended permit tcp any object DMZ-WEB eq www (hitcnt=1) (Last Hit=23:27:41 UTC May 9 2026)
access-list OUTSIDE_IN line 3 extended permit tcp any object DMZ-WEB eq https (hitcnt=2) (Last Hit=00:01:09 UTC May 10 2026)
access-list OUTSIDE_IN line 4 extended permit icmp any object DMZ-WEB (hitcnt=2) (Last Hit=01:55:20 UTC May 10 2026)
access-list OUTSIDE_IN line 5 extended deny ip any any log informational interval 300 (hitcnt=59) (Last Hit=01:55:47 UTC May 10 2026)

Notice that object DMZ-WEB appears as the destination on lines 2, 3, and 4. DMZ-WEB is a single network object (not a group), defined elsewhere as:

ASA-PERIM(config)# show running-config object id DMZ-WEB
object network DMZ-WEB
 host 192.168.50.10
 nat (dmz,outside) static 198.51.100.10

One object definition does double duty: it gives the ACL a readable name for the DMZ web server, AND defines the static NAT that publishes 192.168.50.10 to the outside as 198.51.100.10. Change the IP in one place and both the ACL and the NAT rule follow.

Real Lab: Auto NAT With Network Objects

Auto NAT (also called Object NAT) is configured inside an object network definition. The Section 2 NAT block from show nat detail:

ASA-PERIM# show nat detail | begin Auto NAT
Auto NAT Policies (Section 2)
1 (dmz) to (outside) source static DMZ-WEB 198.51.100.10
    translate_hits = 87, untranslate_hits = 134
    Source - Origin: 192.168.50.10/32, Translated: 198.51.100.10/32
2 (inside) to (outside) source dynamic INSIDE-TRANSIT interface
    translate_hits = 0, untranslate_hits = 0
    Source - Origin: 10.10.0.0/24, Translated: 203.0.113.2/30
3 (inside) to (outside) source dynamic INSIDE-NET interface
    translate_hits = 4521, untranslate_hits = 0
    Source - Origin: 10.10.10.0/24, Translated: 203.0.113.2/30

Three rules, all defined inside three object network blocks (DMZ-WEB, INSIDE-TRANSIT, INSIDE-NET). Auto NAT auto-orders by specificity, so the /32 host (DMZ-WEB) sits at line 1 even though it was configured later. INSIDE-NET racked up 4,521 forward translations (real-world inside hosts hitting the internet via PAT to the outside interface). DMZ-WEB has more reverse than forward hits because it is a public-facing server (more inbound flows opened from the internet than outbound flows initiated by the server itself).

The Built-In Service Objects

The ASA ships with a long list of named ports you can use as keywords without defining your own. www, https, ssh, smtp, domain, snmp, tftp, ntp, and dozens more all parse as themselves. access-list OUTSIDE_IN extended permit tcp any object DMZ-WEB eq www uses www as a built-in alias for port 80; you do not need to define a WWW object.

For ports the ASA does not have a name for, use the number: eq 8443, range 5060 5061, gt 1024. The full list of built-in names is in the ? output for access-list ... eq.

Object Groups Make ACLs Readable Six Months Later

Compare two ways of writing the same intent. Without object groups:

access-list OUTSIDE_IN extended permit tcp host 10.10.0.50 host 192.168.50.10 eq 80
access-list OUTSIDE_IN extended permit tcp host 10.10.0.50 host 192.168.50.10 eq 443
access-list OUTSIDE_IN extended permit tcp host 10.10.0.50 host 192.168.50.10 eq 22
access-list OUTSIDE_IN extended permit tcp host 10.10.0.50 host 192.168.50.20 eq 80
access-list OUTSIDE_IN extended permit tcp host 10.10.0.50 host 192.168.50.20 eq 443
access-list OUTSIDE_IN extended permit tcp host 10.10.0.50 host 192.168.50.20 eq 22
access-list OUTSIDE_IN extended permit tcp host 10.10.0.51 host 192.168.50.10 eq 80
... [repeat for each src x dst x port]

With object groups:

object-group network ADMIN-JUMP
 network-object host 10.10.0.50
 network-object host 10.10.0.51
 network-object host 10.10.0.52
object-group network DMZ-SERVERS
 network-object host 192.168.50.10
 network-object host 192.168.50.20
object-group service ADMIN-PORTS
 service-object tcp eq 22
 service-object tcp eq 80
 service-object tcp eq 443
!
access-list OUTSIDE_IN extended permit object-group ADMIN-PORTS object-group ADMIN-JUMP object-group DMZ-SERVERS

One ACL line, with the intent ("admins reach DMZ servers on admin ports") visible at first read. Adding a fourth jump host means one new network-object line; the ACL itself never changes. This is also the version that survives an audit: the auditor looks at OUTSIDE_IN and sees one rule, not 18.

Verify Object Groups

The ASA expands object groups internally. show access-list shows you both the compact form and the expanded form:

ASA-PERIM# show access-list OUTSIDE_IN | begin OUTSIDE_IN
access-list OUTSIDE_IN; 9 elements; name hash: 0xe01d8199
  alert-interval 300
access-list OUTSIDE_IN line 1 extended permit object-group ADMIN-PORTS object-group ADMIN-JUMP object-group DMZ-SERVERS (hitcnt=44)
access-list OUTSIDE_IN line 1 extended permit tcp host 10.10.0.50 host 192.168.50.10 eq 22 (hitcnt=12)
access-list OUTSIDE_IN line 1 extended permit tcp host 10.10.0.50 host 192.168.50.10 eq 80 (hitcnt=8)
access-list OUTSIDE_IN line 1 extended permit tcp host 10.10.0.50 host 192.168.50.10 eq 443 (hitcnt=10)
... [continues for each src x dst x port]

The compact form (the first line at "line 1") shows the ACL the way you wrote it. The expanded entries beneath show every src/dst/port permutation with its individual hit counter, which is how you tell whether a specific permutation is being used.

Inspect a single group with:

ASA-PERIM# show running-config object-group id ADMIN-JUMP
object-group network ADMIN-JUMP
 description Permanent admin jump hosts
 network-object host 10.10.0.50
 network-object host 10.10.0.51
 network-object host 10.10.0.52

Or list every group with show running-config object-group (no id).

Renaming and Removing Objects Safely

Renaming an object is not a single command. The ASA's rename object works at the object level but not for object groups; the safe procedure for either is: create the new name, switch references, then delete the old.

Removing a group is rejected if anything still references it:

ASA-PERIM(config)# no object-group network ADMIN-JUMP
ERROR: removing object-group (ADMIN-JUMP) not allowed, it is being used.

To find every reference, ironically use the same show running-config | include ADMIN-JUMP grep, which finds the ACL and NAT lines that point at it. Update those first, then the delete succeeds.

Key Takeaways

Network and service object groups collapse repetitive ACLs into single readable lines and let one named object do double duty for both ACL and NAT. The four group types (network, service, protocol, icmp-type) cover almost everything you need; nesting is supported one level. Use the unified service-object syntax for new work because it lets you mix TCP and UDP in one group.

The lab's OUTSIDE_IN ACL and Auto NAT pool both reference the same DMZ-WEB object: change the IP in one place, both follow. That single principle is what makes object-driven ASA configurations maintainable years after the engineer who built them has left.

Next in this cluster: Cisco ASA Initial Setup from CLI, the day-0 bootstrap that gets a fresh ASA from "out of the box" to "passing traffic." For the broader picture, the Cisco ASA pillar has the full reading order. For deeper ACL and NAT walkthroughs, see ACL configuration and NAT explained.

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.