Syntactically, the following set of statements is valid (at least as of 8.3):
interface Ethernet0/0 nameif OUTSIDE ip address 192.0.2.1 255.255.255.0 interface Ethernet0/1 nameif INSIDE ip address 10.1.1.1 255.255.255.0 object network O_N_EXAMPLE1 host 10.1.1.2 object network O_N_EXAMPLE2 host 10.1.1.3 object service O_S_EXAMPLE1 service tcp destination eq 60001 object service O_S_EXAMPLE2 service tcp destination eq 60002 object-group network OG_N_EXAMPLEHOSTS network-object object O_N_EXAMPLE1 network-object object O_N_EXAMPLE2 nat (OUTSIDE,INSIDE) source static any any destination static interface OG_N_EXAMPLEHOSTS service O_S_EXAMPLE1 O_S_EXAMPLE2 nat (INSIDE,OUTSIDE) after-auto source dynamic any interface
nat statement is fairly obvious -- it simply translates everything outbound to the WAN IP, in a typical hide-NAT/LAN-to-WAN scenario.
However, the first
nat defines a (probably invalid) rule directing any inbound request for the WAN IP over TCP/60001 to be sent to either of 192.0.2.1:60002 or 192.0.2.2:60002.
The ASA command-line lets you enter it without error.
packet-tracer doesn't balk at it (at least, assuming an
packet-tracer input OUTSIDE tcp 192.0.2.100 12345 192.0.2.1 60001"succeeds", in that it says the final action is to allow, and along the way it untranslates to 10.1.1.2 and identifies the output interface as
packet-tracer input INSIDE tcp 10.1.1.1 60002 192.0.2.1 60002"succeeds", in that it says the final action is to allow, and along the way it translates to 192.0.2.1, but does not indicate the ouput interface.
What it does not do (and what I think might have been the original intent) is distribute between the two target IPs, nor track which of the two hosts is up and establish a translation to an available node. I don't believe that ASA has any function for that (although I'm happy to be proved wrong!) beyond tracked routes, which are more to do with outbound, LAN-to-multi-WAN traffic.
In practice I expect it accepts the inbound and drops the reply traffic, resulting in a failed TCP handshake.
I note that splitting the
nat statement into two statements results in an ovelap [sic] warning:
# nat (OUTSIDE,INSIDE) source static any any destination static interface O_N_EXAMPLE1 service O_S_EXAMPLE1 O_S_EXAMPLE2 # nat (OUTSIDE,INSIDE) source static any any destination static interface O_N_EXAMPLE2 service O_S_EXAMPLE1 O_S_EXAMPLE2 WARNING: mapped-address 192.0.2.2/60002-0 ovelap with existing static NAT.
So I wonder, how does the ASA interpret that first
nat statement and, in particular, under what circumstances would it actually attempt to translate to 10.1.1.3?
I understand what would happen if the NAT was a
destination static between two
object objects (a simple translation from the first to the second) or even two
object-group objects with the same number of
network-object entries (a one-to-one translation from the nth entry in the first group to the nth entry in the second group), but not in this case, with a one-to-many definition.
Does it just translate between the interface address and the first
network-object, dicarding the second? Or does it work something out with regards to available ephemeral ports (e.g. the first 64K connections go to 192.0.2.1 and the second go to 192.0.2.2)? Does it duplicate the traffic to both? Or something else entirely?