Dealing with Identity NAT on ASA: pre and post 8.3 configuration models

Continuing our series of articles about Network Address Translation (NAT) on Cisco ASA, we will now examine the behavior of Identity NAT.

When the nat-control model is in place (for ASA releases older than 8.3), an explicit answer regarding NAT must be provided to the ASA algorithm, even if this answer is do not translate ( “no nat“). Among the NAT exemption techniques supported by ASA, there is one called Identity NAT, which is typically used when most of the addresses are being translated and you need to avoid translation for just a specific set of hosts.

Starting on 8.3 version,  there is no such concept of nat-control, meaning that NAT Exemption is not necessary anymore and the nat 0 (nat zero) configurations are completely banned.

The reference topology shown in the figure was conceived to illustrate NAT Exemption syntaxes for both the current and old (pre 8.3) models. In our environment, hosts belonging to the 10.10.10.128/26 subnet are excluded from translation rules, irrespectively of the destination being accessed. Although the intention here is to keep some source addresses from being translated, the behaviors of the configurations are slightly different:

  • The nat zero construction that refers directly to the IP address (instead of an ACL) is unidirectional in essence and is not suited for address publishing. This means that the 10.10.10.128/26 stations will be able to start outbound connections but will not be accessible from the out interface (even if you configure a permission within an ACL).
  • Identity Static (static from X to X) is bidirectional and, as such, may be used for address publishing. (You will still need to add a permission so that the real address can be reached from the out interface).
  • The NAT flags are distinct: both options have the identity flag set but nat zero is deemed dynamic. (And that reinforces its unidirectional nature).

Identity NAT on ASA: configuration models

** Notes:

  • Considering that we are dealing with a source-only translation rule, we employed Object NAT for the 8.3 case. By revisiting the previous posts on the NAT series, can you build an equivalent configuration with Manual NAT ?
  • The show commands registered in the figure help characterize that NAT exemption is in place. Can you explain that ?

** Related Posts

2 Comments

Filed under English, Firewalls, Security

2 responses to “Dealing with Identity NAT on ASA: pre and post 8.3 configuration models

  1. Mikis

    Hello Alexandre

    First of all, congratulations for you ‘Firewalls’ book.
    I am trying to understand the internal order of operations on ASA and I hope you can provide some clarification.
    In the following lab topology, I have static (pre-8.3) NAT configured on ASA:

    R1 – 100.0.101.0/24 – inside ASA outside – 100.0.12.0/24 – R2

    R1 100.0.101.1 is NATed to 100.0.12.1 and an ACL is applied to the outside interface (e0/1):
    static (inside,outside) 100.0.12.1 100.0.101.1

    e0/0 = inside (100.0.101.10)
    e0/1 = outside (100.0.12.10)
    An ACL is applied on the OUTSIDE interface inbound permitting R2 to reach R1:
    access-list OUTSIDE_IN permit tcp host 100.0.12.2 host 100.0.12.1
    access-group OUTSIDE_IN in interface outside

    When R2 is trying to access R1 it uses the 100.0.12.1 as destination (the Mapped IP)

    The packet-tracer shows:
    1. UN-NAT
    2. ACL
    3. NAT (rpf-check)
    4. NAT (host limits)

    The questions are:
    If the UN-NAT is happening before the ACL check, how the ACL matches the traffic since in the ACL we have as destination the NATed IP? Can we assume that the Packet-Tracer output is a bit misleading and UN-NAT is happening after the ACL check? What about the post-8.3 NAT where we use the real IP in the ACL? Did Cisco changed the internal order of operations on ASA?

    Phase: 2
    Type: UN-NAT
    Subtype: static
    Result: ALLOW
    Config:
    static (inside,outside) 100.0.12.1 100.0.101.1 netmask 255.255.255.255
    match ip inside host 100.0.101.1 outside any
    static translation to 100.0.12.1
    translate_hits = 0, untranslate_hits = 2
    Additional Information:
    NAT divert to egress interface inside
    Untranslate 100.0.12.1/0 to 100.0.101.1/0 using netmask 255.255.255.255

    Phase: 3
    Type: ACCESS-LIST
    Subtype: log
    Result: ALLOW
    Config:
    access-group OUTSIDE_IN in interface outside
    access-list OUTSIDE_IN extended permit tcp host 100.0.12.2 host 100.0.12.1
    Additional Information:

    Phase: 4
    Type: IP-OPTIONS
    Subtype:
    Result: ALLOW
    Config:
    Additional Information:
    Phase: 5
    Type: NAT
    Subtype: rpf-check
    Result: ALLOW
    Config:
    static (inside,outside) 100.0.12.1 100.0.101.1 netmask 255.255.255.255
    match ip inside host 100.0.101.1 outside any
    static translation to 100.0.12.1
    translate_hits = 0, untranslate_hits = 2
    Additional Information:

    Phase: 6
    Type: NAT
    Subtype: host-limits
    Result: ALLOW
    Config:
    static (inside,outside) 100.0.12.1 100.0.101.1 netmask 255.255.255.255
    match ip inside host 100.0.101.1 outside any
    static translation to 100.0.12.1
    translate_hits = 0, untranslate_hits = 2

    Thank you in advance

    • Alexandre M. S. P. Moraes

      Hi Mikis,

      When you create a static NAT entry, the translation is placed immediately in the “xlate” table (irrespectively of
      having any associated connection). Notice that in your example you are creating a source-only translation in the outbound direction
      but your connection happens on the inbound. (That’s whay you have the UN-NAT event on packet tracer: you are using that rule in the
      reverse direction). Please observe that you have another phase on packet-tracer (NAT rpf-check), which verifies the consistency of published address
      versus ACL.

      I did some testing with 8.3:

      object network CUCM1
      host 172.17.11.120
      object network CUCM1-EXT
      host 10.97.25.120
      nat (dmz1,external) source static CUCM1 CUCM1-EXT dns

      test 1 (accessing the mapped address 10.97.25.120) in the inbound direction (external to dmz1), UN-NAT happens, ACL permits the traffic and RPF-check succeeds.
      test 2 (accessing the real address) in the inbound direction, RPF check fails and packet is dropped.

      I recommend you to take a look at the examples below and try to reproduce this in your lab. Besides that, I think it would be nice if you could repeat your
      simulation with the real address to see the behavior…
      I hope this helps.

      Regards,
      Alexandre

      test 1: accessing the published address (10.97.25.120) in the inbound direction

      ASA1# packet-tracer input external tcp 72.72.72.72 5000 10.97.25.120 https

      Phase: 1
      Type: ACCESS-LIST
      Subtype:
      Result: ALLOW
      Config:
      Implicit Rule
      Additional Information:
      MAC Access list

      Phase: 2
      Type: UN-NAT
      Subtype: static
      Result: ALLOW
      Config:
      nat (dmz1,external) source static CUCM1 CUCM1-EXT dns
      Additional Information:
      NAT divert to egress interface dmz1
      Untranslate 10.97.25.120/443 to 172.17.11.120/443

      Phase: 3
      Type: ACCESS-LIST
      Subtype: log
      Result: ALLOW
      Config:
      access-group EXTERNAL in interface external
      access-list EXTERNAL extended permit object-group OUT1-SVCS1 object-group CISCO-NETS object-group TFTP-HOSTS
      ! […] output suppressed
      object-group network TFTP-HOSTS
      network-object host 172.17.11.120
      Additional Information:

      ! […] output suppressed

      Phase: 8
      Type: FLOW-CREATION
      Subtype:
      Result: ALLOW
      Config:
      Additional Information:
      New flow created with id 152058, packet dispatched to next module
      ———————————————————————-
      test 2: building a packet tracer simulation using the real address 172.17.11.120 in the inbound direction

      ASA1# packet-tracer input external tcp 72.72.72.72 5000 172.17.11.120 https

      Phase: 1
      Type: ROUTE-LOOKUP
      Subtype: input
      Result: ALLOW
      Config:
      Additional Information:
      in 172.17.11.0 255.255.255.0 dmz1

      Phase: 2
      Type: ACCESS-LIST
      Subtype: log
      Result: ALLOW
      Config:
      access-group EXTERNAL in interface external
      access-list EXTERNAL extended permit object-group OUT1-SVCS1 object-group CISCO-NETS object-group TFTP-HOSTS
      ! […] output suppressed
      object-group network TFTP-HOSTS
      network-object host 172.17.11.120
      Additional Information:
      ! […] output suppressed
      Phase: 5
      Type: NAT
      Subtype: rpf-check
      Result: DROP
      Config:
      nat (dmz1,external) source static CUCM1 CUCM1-EXT dns
      Additional Information:

      Result:
      input-interface: external
      input-status: up
      input-line-status: up
      output-interface: dmz1
      output-status: up
      output-line-status: up
      Action: drop
      Drop-reason: (acl-drop) Flow is denied by configured rule

Leave a comment