Network Address Translation (NAT) was developed as an interim strategy to address Transmission Control Protocol/Internet Protocol (TCP/IP) network address space depletion—one of the main drivers for the IPv6 protocol.
In 1994, K. Egevang and Paul Francis introduced NAT in RFC 1631. With NAT, it is possible to recycle address space—multiple hosts can use the same address space as long as they communicate over a unique address space. The Network Address Translator, a function within a router (or a firewall with routing capability) would perform the translation to the unique address space, usually on the border between the private portion of a network and the public Internet. In 1994, a “recyclable” address space was defined in RFC 1597, and was obsoleted by RFC 1918 in 1996. Dedicated for private use were one Class A network within 10/8, 16 Class B networks within 172.16/12, and 255 Class C networks within 192.168/16.
NAT is not just a method for fighting address space depletion. It was also quickly adopted by security engineers, who liked the idea that thousands of hosts were able to hide behind a single IP address by using NAT with Port Address Translation (PAT). This helps prevent simple port scanning and other attack techniques on those hosts, but you should not consider it as anything but a part of an overall security strategy.
There is another use for NAT that the inventors of NAT did not initially consider: the likelihood that two enterprises are using the same RFC 1918 address space. Instead of renaming hundreds or thousands of hosts, mutual address translation can help to solve this problem, at least temporarily, until hosts can be renumbered.
Although most firewall administrators are familiar with NAT, one particularly confusing issue is the meaning of the terms source and destination. A stateful firewall keeps state, as its name implies, which can be defined as the conditional status of the connection. This is well defined in TCP utilizing TCP flags, sequence numbers, and such; it is derived or observed for other Internet protocols such as the User Datagram Protocol (UDP). State is kept stored in a session table, which in turn keeps track of a flow. A flow is defined as traffic from a client to a server as well as traffic returning from the server to the client; therefore, a flow has two branches. So, when the server’s IP is 1.1.1.100
, this is the destination address for the branch from the client to the server, and it is the source address on the return path from the server to the client. In the world of stateful firewalls, we do not worry about the return path, as the firewall is figuring that out. NAT will work properly only if each branch of the flow goes through the same device. For example:
id 4032/s**,vsys 0,flag 08000000/8000/1001,policy 1,time 29, dip 0 module 0 if 2(nspflag 801a01):192.168.1.100/1024->1.1.1.100/80,6,000d60c5761b, sess token 4,vlan 0,tun 0,vsd 0,route 1 if 1(nspflag 801a00):192.168.1.100/1024>-1.1.1.100/80,6,00135f05e105, sess token 6,vlan 0,tun 0,vsd 0,route 132
In the preceding code, client 192.168.1.100
sends traffic from port 1024 to server 1.1. 1.100
on port 80, and the server answers with the exact mirror from IP 1.1.1.100
on port 80 to the client 192.168.1.100
on port 1024. The protocol number is 6, which is TCP. So, when we talk about source and destination for translation, we are talking about the initiating branch of the flow. The source address would be 192.168.1.100
and the destination address would be 1.1.1.100
. The source port would be 1024 and the destination port would be 80.
Source ports are almost always randomly chosen and ≥ 1024. While on the Internet, the source address could also be chosen out of a pool or a cluster of addresses. On the other hand, destination ports and addresses must be static and deterministic because this is where the client connects. The logic behind this is where traffic comes from is not as important as where traffic goes, in particular on the public Internet. Clients are usually anonymous, whereas servers need to be well known to be reachable. Therefore, the destination needs to be deterministic.
Table 8-1 shows that you match on the private portion and you translate to the public portion. In other words, you match on src-ip
and dst-ip
and in the service portion you match on src-port
and dst-port
. Each component can be translated.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
In ScreenOS, the different NAT elements are dynamic IP (DIP), mapped IP (MIP), virtual IP (VIP), and policy NAT-SRC and NAT-DST, as well as the legacy NAT mode. Before we dive deep into each NAT element, we will briefly explain what they are good for.
A DIP performs a source translation of the address and the port on the egress interface. The most common use for a DIP is to port-address-translate internal clients onto one public IP address. DIP and policy NAT-SRC are synonymous. DIPs are configured on an interface and in a policy.
A MIP is a bidirectional translation. It is applied as ingress and egress. A MIP is configured on an interface, and needs to be referenced in a policy for ingress traffic. It is automatically implied in an egress policy. Bidirectional means that it does both a source and a destination translation, depending on the initiating direction of a flow. MIPs do not support port translation. The most common use for a MIP is to translate a DMZ server to a public IP address.
A VIP is a port destination translation on the ingress interface. It is one way to perform “port forwarding” in ScreenOS. It is more or less the reverse of a DIP, with the exception that VIP translations are always static, whereas DIPs are commonly dynamic. Static means that IP Address A or Port A is always translated to IP Address B or Port B. In a dynamic translation, the target translation is chosen from a range of values. A VIP can translate both the IP address and the port. The most common use for a VIP is to map several DMZ intranet servers to a single public IP address on very small firewalls.
We already discussed that policy NAT-SRC is a synonym for DIP. On the other hand, policy NAT-DST was thought to be the successor to MIPs and VIPs. In contrast to a MIP, policy NAT-DST is unidirectional. Therefore, policy NAT-DST is more often used to replace a VIP than a MIP. Policy NAT-DST does address and port translation.
NAT mode is a legacy mode and has been largely replaced by the much more powerful DIPs. Although simple to implement, you should use it only on smaller, dualinterface firewalls.
NAT operations are supported in route mode but not in transparent mode, at least as of ScreenOS 6.1. Table 8-2 shows a summary of NAT methods.
Method |
Direction |
Scope |
src-ip |
dst-ip |
src-port |
dst-port |
MIP |
Outbound |
Network |
Static | |||
MIP |
Inbound |
Network |
Static | |||
NAT-DST |
Inbound |
Network |
Static |
Static | ||
VIP |
Inbound |
Host |
Static |
Static | ||
DIP dynamic |
Outbound |
Host |
Static |
Dynamic | ||
NAT mode |
Outbound |
Host |
Static |
Dynamic | ||
DIP pool dynamic |
Outbound |
Range |
Dynamic |
Dynamic | ||
DIP fixed |
Outbound |
Host |
Static | |||
DIP pool fixed |
Outbound |
Range |
Dynamic | |||
DIP pool dynamic sticky |
Outbound |
Range |
Dynamic, static per source |
Dynamic | ||
DIP pool fixed sticky |
Outbound |
Range |
Static random | |||
DIP shift |
Outbound |
Range |
Static | |||
Outbound |
Host |
Static |
Dynamic | |||
DIP dynamic inbound |
Inbound |
Host |
Static |
NAT can refer to both IP address translation and PAT, and in practice, PAT usually also involves IP address translation. Both transport layer protocols, UDP and TCP, utilize the concept of ports to connect applications via sockets to the network. NAT applies to the network layer, and therefore, you can use it with all transport layer protocols, including the Encapsulating Security Protocol (ESP). PAT, on the other hand, applies only to UDP and TCP. Does this mean we cannot use PAT with other protocols such as Generic Routing Encapsulation (GRE)? In general, the answer is “yes” for most NAT routers, but the answer is “it depends” for ScreenOS.
ScreenOS has application intelligence implemented via ALGs for many protocols. Instead of a portmap, the firewall may use the Call ID field in the GREv1 header as used by the Point-to-Point Tunneling Protocol (PPTP), or it may use the Security Parameters Index (SPI) field in the ESP header when multiplexing sessions with dynamic source port translation. Luckily, the use of other Layer 4 protocols is rare.
ALGs can also be useful for TCP and UDP traffic where the return branch is not an exact mirror of the initiating branch. Some applications, such as File Transfer Protocol (FTP) applications, have separate control and data channels, so while the client initiates the control channel to the server, the server may initiate a data channel to the client. Address and port information is communicated within the application. An ALG would tap into this connection and perform the correct translation deep in the application layer of the traffic stream. The ALG would reassemble packets, both whole and fragmented, into one data stream, and it would search for the right information and replace it in real time with the translation. All of this works in the background and makes the firewall work seamlessly with applications, which, in general, are not compatible with NAT or PAT. However, most of the applications that are commonly used on the Internet are NAT- or PAT-compatible.
NAT is one of the more complex elements to understand—not to configure—on ScreenOS. One reason for this is the way ScreenOS was developed; another is that ScreenOS is a dedicated security appliance that tightly interweaves security, routing, and switching.
One important difference between a router and a security appliance is that a router typically makes forwarding decisions for each packet, commonly only on the destination IP, whereas a security appliance makes one forwarding decision per flow. A flow is typically defined by source and destination IP addresses, as well as protocol source and destination ports, and its return path.
In ScreenOS, you can apply NAT on an interface, in a policy, or both. Both ingress and egress NATs exist. Egress NATs will be applied when a packet exits the firewall and ingress NATs will be applied when a packet enters the firewall. In ScreenOS, an egress NAT is always a source translation, whereas an ingress NAT is always a destination translation.
ScreenOS uses only two tables: a route lookup table and a rule lookup table. Rule lookup, NAT, and Quality of Service (QoS) are performed in the same rule in the policy table. Some other vendors use a different table for all three. Route lookup determines the ingress and egress interfaces and, therefore, the source and destination zones. Then ScreenOS performs a lookup on the rules that apply to that particular combination of zones. A match is performed on the source IP, destination IP, and service for the first packet of a flow. If a matching rule is found, everything in that rule will be applied.
With NAT, ScreenOS checks the rule to see whether the traffic is permitted or denied. If it is permitted, first ingress NAT is applied, and then egress NAT. Optionally, QoS can be applied as well. Unlike packet forwarders, flow forwarders apply a rule to both branches of a connection automatically: from the client to the server, and then from the return traffic from the server to the client (a packet forwarder would have its own set of rules for both branches).
When we talk about bidirectional application of a rule set in a packet forwarder, we’re talking about application to both branches of one flow. But when we talk about bidirectional application of a rule set in a flow forwarder, we’re talking about application from Host A to Host B and the return traffic for the same flow, as well as for a second connection, from Host B to Host A and its return traffic. These are two flows with four branches. In this case, Host A and Host B could be both client and server—for instance, a server for web browser clients, and a client, say, when it downloads a software patch from an FTP server.
Configure a DIP on the egress interface and reference the DIP in a policy:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/0 dip 4 1.1.1.1
Link the DIP to the policy:
set policy from Trust to Untrust any any any nat src dip-id 4 permit
The most common use for a DIP is to translate multiple inside hosts to a single public IP address. It’s similar to NAT mode, but it allows more complex mappings—in particular, to addresses other than that of the egress interface. DIP also allows PAT on any interface (also called policy NAT-SRC). In Table 8-3 you can see the hide NAT translation being configured in the preceding code.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
Any |
Any |
Any |
1.1.1.1 |
Original |
≥ 1024 |
Original |
A DIP represents the global portion of a source address translation. It is applied to the egress interface and is invoked within a policy:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/0 dip 4 1.1.1.1 set policy from Trust to Untrust any any any nat src dip-id 4 permit
DIP ID 4
and higher are custom-configurable. DIP ID 2
always refers to the IP address of the egress interface. (DIP ID 1
and DIP ID 3
are legacy values that are no longer used.)
If no DIP ID is configured within a policy, ID 2
is implied, and is a placeholder for the egress IP of any interface in any zone. This is similar to NAT mode.
set policy from Trust to Untrust any any any nat permit
Potentially, tens of thousands of sessions (or, with ScreenOS tracking, even hundreds of thousands) could be multiplexed over one public IP address—in this case, the hide NAT IP address 1.1.1.1
. In dynamic PAT mode, any source port would be translated, starting with port 1024 and counting up. For most applications, the source port does not matter.
If your hide NAT IP is in a different network from the interface on which the DIP lives, you need to configure an extended DIP. With an extended DIP you configure a pseudo IP on the interface so that the DIP is actually in the network with the interface:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 2.2.2.100/24 set interface ethernet0/0 ext ip 1.1.1.1/32 dip 4 1.1.1.1 set policy from Trust to Untrust any any any nat src dip-id 4 permit
However, with an extended DIP, routing from the neighboring device needs to be observed. The firewall would answer an Address Resolution Protocol (ARP) request from a DIP within the same network, but not for an extended DIP because this would make no sense. In the preceding output, the neighboring router with the interface IP address of 2.2.2.200
, for example, needs to route to 2.2.2.100
for the network 1.1.1.0/24
to hit the 1.1.1.1 DIP
.
Configure the DIP for hide NAT and to accept incoming VoIP calls:
set int e0/1 dip 4 1.1.1.100 incoming
Configure outbound and inbound policies:
set policy from Trust to Untrust any any SIP nat dip-id 4 permit set policy from Untrust to Trust any DIP(1.1.1.100) SIP permit
The problem with VoIP phones is that they need inbound and outbound connectivity because calls can be made from and to a phone. Because there may be many phones or not enough public IP addresses, it is not feasible to configure a static destination translation for each phone. Unfortunately, protocols capable of solving such a dilemma, such as the STUN protocol, are generally not compatible with stateful firewalls because they are exploiting a security weakness in simple NAT devices to open inbound pinholes. Table 8-4 details the hide NAT translation configured with the inbound
feature. You can see the two flows for outbound and inbound calls, with the second row being an inbound call. Notice that although hide NAT was configured (all phones hide behind the same IP of 1.1.1.100
) the firewall translates to the correct internal phone, in this case 192.168.1.1
.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
Any |
Any |
5060 |
1.1.1.100 |
Original |
≥ 1024 |
Original |
Any |
1.1.1.100 |
Any |
5060 |
Original |
192.168.1.1 |
Original |
Original |
In ScreenOS, application intelligence is built into the VoIP ALGs for the Session Initiation Protocol (SIP) and H.323, facilitating translation from the shared hide NAT address to the right internal phone. The ALG dynamically records phone IP addresses as it monitors initial REGISTER messages sent by internal phones to the SIP registrar. This information is used later for the reverse connection.
You can enable this feature by configuring an incoming DIP:
set int e0/1 dip 4 1.1.1.100 incoming set policy from Trust to Untrust any any SIP nat dip-id 4 permit set policy from Untrust to Trust any DIP(1.1.1.100) SIP permit
Alternatively, to configure a DIP you can use the IP of the interface instead:
set int e0/1 dip interface-ip incoming
The name of the DIP in the policy is DIP
(<publicIP
>); if the implicit DIP ID 2
is being referenced, hence the interface’s IP address itself, the syntax is DIP
(<interface
>).
set policy from Trust to Untrust any any SIP nat permit set policy from Untrust to Trust any DIP(ethernet0/0) SIP permit
Configure a DIP on the egress interface and reference the DIP with the fix-port
option:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/0 dip 4 1.1.1.1 fix-port
Reference the DIP in the policy:
set policy from Trust to Untrust any any any nat src dip-id 4 permit
Static address translation is often used in combination with policy NAT-DST (see Recipe 8.6). Notice that MIP also performs static address translation, which combines the function of a DIP (a NAT-SRC) and a NAT-DST. Table 8-5 details the static source NAT translation (the difference between Table 8-5 and Table 8-3 is that x-src-port
is not being translated in Table 8-5).
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
Any |
Any |
Any |
1.1.1.1 |
Original |
Original |
Original |
You configure static source NAT translation by adding the fix-port
keyword to the DIP. The rest of the configuration is similar to hide NAT (see Recipe 8.1):
set interface ethernet0/0 dip 4 1.1.1.1 fix-port set policy from Trust to Untrust any any any nat src dip-id 4 permit
Configure the DIP pool and switch off hide NAT:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/0 dip 4 1.1.1.1 1.1.1.99 fix-port
Configure the sticky allocation of IPs from the pool, and switch on pool allocation warnings:
set dip sticky set dip alarm-raise 90 alarm-clear 80
Link the DIP to a policy:
set policy from Trust to Untrust any any any nat src dip-id 4 permit
Although most protocols used today on the Internet are compatible with PAT, some external and many internal protocols are not. ScreenOS features application intelligence for many of the common protocols, such as FTP, SIP, MS-RPC (Remote Procedure Call), and Internet Key Exchange (IKE). ALGs look deep into the communication and replace translated IP addresses and port information within the application layer with the translated address. ALGs are switched on by default, and if they are invoked by a flow, they are listed in the session on the top, under application ID
. Note that not all ALGs exist to solve problems with NAT. For applications that are not compatible with hide NAT, you need to configure static source translation.
In such cases, it is cumbersome and may even be impossible to configure a DIP for each host. Instead, you can configure a DIP pool. As you are configuring a DIP pool because your applications are not compatible with hide NAT, you need to switch hide NAT off with the fix-port
option:
set interface ethernet0/0 dip 4 1.1.1.1 1.1.1.99 fix-port
Table 8-6 details the source pool translation. Source addresses are translated to a pool of public IP addresses, but the source port is usually not translated.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
Any |
Any |
Any |
Pool |
Original |
Original |
Original |
An inside host may spawn multiple sessions to the same server. The application may break when the host is translated to a different address for each session. You have to configure ScreenOS so that the same host is always translated to the same IP from the pool:
set dip sticky
With a DIP pool, each inside host connecting to the outside will reserve one IP in the pool for as long as a session is active. If all addresses from the DIP pool are exhausted, no further connections can be made (this can happen during virus activity, for example). In this case, you configure ScreenOS to send a log or trap when the pool reaches 90 percent (event log type 00102), and send a clear signal (event log type 00103) when the pool has 80 percent free resources again:
set dip alarm-raise 90 alarm-clear 80
The final step is to link the pool to the policy:
set policy from Trust to Untrust any any any nat src dip-id 4
permit
A DIP pool can span up to 10 /24
networks, but note that DIP pools cannot overlap with each other, the interface IP, or the pseudo ext-interface
IP. With ScreenOS 6.1 and later, it is also possible to configure up to three noncontiguous subnets in the pool.
Configure the DIP or DIP pools:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/1 zone Untrust set interface ethernet0/1 ip 2.2.2.100/24 set interface ethernet0/0 dip 4 1.1.1.1 set interface ethernet0/1 dip 5 2.2.2.2
Group the DIP into a DIP group:
set dip group 6 member 4 set dip group 6 member 5
Link the DIP group to a policy:
set policy from Trust to Untrust any any any nat src dip-id 6 permit
You may want to configure multiple DIPs in the same policy. One reason you may want to do this it that you have redundant egress interfaces, and dynamic routing decides which interface to use, so you configure a DIP for each redundant interface. Another reason is that you want to configure two DIP pools and link them to the same policy because, for instance, DIP pool addressing is not contiguous.
Unfortunately, you can link only one DIP ID to a policy. The solution is to configure a DIP group and link the DIP group to the policy instead:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/1 zone Untrust set interface ethernet0/1 ip 2.2.2.100/24 set interface ethernet0/0 dip 4 1.1.1.1 set interface ethernet0/1 dip 5 2.2.2.2 set dip group 6 member 4 set dip group 6 member 5 set policy from Trust to Untrust any any any nat src dip-id 6 permit
Configure the address object for the public address:
set address trust server-pub 1.1.1.100/32
Configure a route for the public address to point in the direction of the private address:
set interface ethernet0/0 zone trust set route 1.1.1.100/32 int e0/0
Configure the destination translation within a policy:
set policy from untrust to trust any server-pub any nat dst ip 192.168.1.100 permit
Policy NAT-DST was introduced with ScreenOS 5.0. It was designed to replace MIP and VIP. A very common reason why policy NAT-DST is preferred over a MIP is because a MIP supports a public address in a different network than that of the ingress interface only if the ingress interface is in the Untrust
zone. On all other zones, MIPs must be in the same network with the IP address of the interface on which they live. This limitation was lifted in ScreenOS 6.1. NAT-DST is not tied to an interface, and therefore, there is no such limitation. However, because MIP is so easy to understand and configure, NAT-DST is most often used for VIP-style configurations (see Recipe 8.7) or very controlled translations such as conditional translation (see Recipe 8.13). A policy NAT-DST is a static destination translation. The IP address, or the port, or both, can be translated.
Table 8-7 shows the destination NAT translation configuration.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
1.1.1.100 |
Any |
Any |
Original |
192.168.1.100 |
Original |
Original |
First, you need to configure an address object for the public portion of the translation:
set address trust server-pub 1.1.1.100/32
Then, you need to route the public IP address toward the private IP, typically toward the Trust
interface. This is important because NAT happens only after the policy check passes, and first the incoming packet needs to match a policy. Once this happens, the destination address of the packet is translated, and another route lookup for the private address follows. This is why the route for the public address does not have a gateway configured.
set interface ethernet0/0 zone trust set route 192.168.1.0/24 int e0/0 gateway 10.10.10.1 set route 1.1.1.100/32 int e0/0
Unlike with all the other NAT elements, there is no configuration on the interface. The configuration happens within the policy only. The client connects from the source zone; the server is located in the destination zone.
set policy from untrust to trust any server-pub any nat dst ip 192.168.1.100 permit
The preceding code will translate the server from its public IP address of 1.1.1.100
to the private IP address of 192.168.1.100
.
This essentially explains how a policy goes from the zone where the client is located to the zone where the server is located. A route for the public portion of the server has to follow to the zone where the server is located. There is one exception to this rule. When the public address of the server is in the same network with the IP of the ingress interface, you can optionally install an intra zone policy. This policy would go from the zone where the public address is located to the same zone. In this case, no route for the public address of the server is necessary because it automatically matches the network of the ingress interface. Here is a sample configuration in which the public address of the server is in the same network as the IP of the ingress interface:
set interface ethernet0/0 zone trust set interface ethernet0/1 zone untrust set interface ethernet0/1 ip 1.1.1.2/24 set arp nat-dst set address untrust server-pub 1.1.1.100/32 set policy from untrust to untrust any server-pub any nat dst ip 192.168.1.100 permit
In the preceding configuration, the client is sitting behind the Untrust
zone, but the server sits behind the Trust
zone. The public IP address of 1.1.1.100
is in the same network with the IP of 1.1.1.2/24
on ingress interface e0/1
. A route lookup of 1.1.1. 100
naturally would point back to the Untrust
zone. Notice the use of an additional command, set arp nat-dst
. This command turns on ARP replies for 1.1.1.100
.
Unlike with DIPs, MIPs, and VIPs, the firewall would not answer ARP requests for policy NAT-DST by default. In many cases, policy NAT-DST is used with public IP addresses, which are not in the same interface as the ingress interface. In this case, the neighboring router would not need ARP, but would need a route to the ingress interface.
You can configure this with a VIP:
set interface ethernet0/1 zone Untrust set interface ethernet0/1 ip 1.1.1.1/29 set service http-inst-a protocol tcp src 1024-65535 dst 8080-8080 set service http-inst-b protocol tcp src 1024-65535 dst 8081-8081 set interface ethernet0/1 vip 1.1.1.2 80 http-inst-a 192.168.1.100 set interface ethernet0/1 vip 1.1.1.3 80 http-inst-b 192.168.1.100 set policy id 1 from untrust to dmz any vip(1.1.1.2) http permit set policy id 1 set dst-address vip(1.1.1.3) exit
Or, you can configure it with policy NAT-DST:
set interface ethernet0/0 zone trust set arp NAT-DST set address untrust server-a-pub 1.1.1.2/32 set address untrust server-b-pub 1.1.1.3/32 set policy from untrust to untrust any server-a-pub http nat dst ip 192.168.1.100 port 8080 permit set policy from untrust to untrust any server-b-pub http nat dst ip 192.168.1.100 port 8081 permit
This shows how to translate port 80 on two different public IP addresses to two different daemon instances of the same internal server. The daemons are listening in port 8080 and port 8081. Basically, you have two web servers running on the same physical server, reachable via two different IP addresses. Table 8-8 details the destination PAT translation configuration.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
1.1.1.2 |
Any |
80 |
Original |
192.168.1.100 |
Original |
8080 |
Any |
1.1.1.3 |
Any |
80 |
Original |
192.168.1.100 |
Original |
8081 |
The original way to configure this was via a VIP. The new way to configure this is with policy NAT-DST. This example assumes that the public IPs are in the same network with the IP of the ingress interface, which is a requirement for a VIP but not for policy NAT-DST, as previously mentioned.
VIPs come with many caveats. The most important is that VIPs before ScreenOS 6.1 can exist only on interfaces in the Untrust
zone and must be in the same network with that interface. Policy NAT-DST offers much greater flexibility. But what a VIP can do and policy NAT-DST cannot do is to use the firewall’s own public IP address for translation:
set admin port 8080 set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.1/29 set interface ethernet0/0 vip untrust-ip 80 "HTTP" 192.168.2.100 set policy id 1 from untrust to trust any vip(ethernet0/0) HTTP permit
In ScreenOS 6.1 and later, the syntax changed because VIPs are now supported on interfaces in any zone:
set interface ethernet0/0 vip interface-ip 80 "HTTP" 192.168.2.100
Notice that the firewall also listens on port 80 for the WebUI and that this port needed to be moved. You can move all default sockets on the firewall:
set admin port <port> set ssl port <port> set admin telnet port <port> set admin ssh port <port> unset alg sip enable
Also note that when you want to translate many contiguous ports, such as the reverse-Telnet ports of aterminal server, a VIP has the multi-port
feature, whereas policy NAT-DST does not. You would have to write a rule for each translated port with policy NAT-DST:
set vip multi-port
With both methods, you can perform many different combinations of translations between port and address translation. You can hide several servers behind a single global address, and you can simulate two servers on the public side and translate them to the same server on the local side, as shown earlier. You can even translate different global addresses to the same socket on the same server, which is sometimes done during server migrations.
You want to allow a DMZ server inside the firewall full access to the Internet and any outside host access to a web server inside the firewall on the Trust
zone.
Configure a MIP on the Untrust
interface:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/0 mip 1.1.1.50 host 192.168.1.50
Configure inbound and outbound policies:
set address trust host-a-prv 192.168.1.50/32 set policy id 1 from Untrust to Trust any MIP(1.1.1.50) http permit set policy id 2 from Trust to Untrust host-a-prv any any permit
MIP is the most used NAT element in ScreenOS, more so than any other method. That’s because a MIP is straightforward to configure and easy to understand. A MIP is a one-to-one, bidirectional, static network address translation. It does not matter if the external host or the local host initiated the connection. The external host’s public IP address is mapped to a private IP address (or the other way around) and the ports remain the same (see Table 8-9).
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
1.1.1.50 |
Any |
Any |
Original |
192.168.1.50 |
Original |
Original |
192.168.1.50 |
Any |
Any |
Any |
1.1.1.50 |
Original |
Original |
Original |
This is easier because you do not have to worry whether the application is compatible with PAT. However, you need to make sure you have enough public IP address space.
First, configure the MIP:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/0 mip 1.1.1.50 host 192.168.1.50
The first policy performs an inbound destination translation, while the second policy performs an outbound source translation.
set policy id 1 from Untrust to Trust any MIP(1.1.1.50) http permit set address trust host-a-prv 192.168.1.50/32 set policy id 2 from Trust to Untrust host-a-prv any any permit
MIPs are usually used for destination address translation. A MIP is always configured on the ingress interface. Here, for instance, e0/0
is an Untrust
interface and 1.1.1.50
is a public IP address. 1.1.1.50
is translated to 192.168.1.50
. The MIP itself is referenced in the policy, with Untrust
being the source zone because the MIP was installed on an interface in the Untrust
zone. The destination zone specified in the policy does not matter because a MIP always lives in the Global
zone. The best practice is to use the zone behind which the private IP of the server lives, if possible.
As of ScreenOS 5.3, you can use MIPs in a multicell policy, and on those zones, multicell is not supported in the Global
zone.
Before ScreenOS 6.1, MIPs could be in a different network from the interface’s IP only on an interface in the Untrust
zone. (This is an important caveat, but it is the only caveat regarding MIPs.) You can configure a MIP that is in the same network with its interface on any interface in any zone. MIPs are most often used on the Untrust
zone. If you need to perform destination translation to an IP that is not in the same network as the ingress interface, use a policy NAT-DST translation (see Recipe 8.6) in combination with a DIP (see Recipe 8.3) if the reverse connection is desired as well.
You want to configure static address translation with multiple Virtual Routers (VRs). Such a design is also typical with Virtual System (VSYS; see Chapter 22).
You configure all MIPs on the same Untrust
interface, but specify different target VRs:
set interface ethernet0/0 mip 1.1.1.50 host 192.168.1.50 vr cage-a-vr set interface ethernet0/0 mip 1.1.1.51 host 192.168.1.50 vr cage-b-vr
Then, you link the MIP to policies:
set policy from Untrust to cage-a Any MIP(1.1.1.50) any permit set policy from Untrust to cage-b Any MIP(1.1.1.51) any permit
A VR is nothing more than a routing table. With other OSs, a VR is also often called a virtual route forwarding (VRF) instance. Because firewalls are often used as central protection devices for large data centers, ScreenOS has a user interface abstraction, called VSYS. A VSYS simulates a logical firewall on the user interface, and it will usually be configured with a VR. Several different VRs are also often used outside of VSYS to insulate routing domains.
Let’s consider a case where you have two cages in a collocation center that use the same IP address space of 192.168.1.0/24
. Both share the same Internet connection through the same firewall. Both have web servers in their cages, with the need for a translation to a public IP address.
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set zone cage-a vr cage-a-vr set interface ethernet0/1 zone cage-a set interface ethernet0/1 ip 192.168.1.1/24 set zone cage-b vr cage-b-vr set interface ethernet0/2 zone cage-b set interface ethernet0/2 ip 192.168.1.1/24 set interface ethernet0/0 mip 1.1.1.50 host 192.168.1.50 vr cage-a-vr set interface ethernet0/0 mip 1.1.1.51 host 192.168.1.50 vr cage-b-vr set policy from Untrust to cage-a Any MIP(1.1.1.50) any permit set policy from Untrust to cage-b Any MIP(1.1.1.51) any permit
Two public IP addresses are translated to the same network of 192.168.1.0/24;
however, the network lives on two different interfaces. In addition, the two servers even have the same private IP address. The vrouter
option helps to keep them apart. It says in which VR the private portion of the MIP should be sought. In our example, MIP(1.1.1.50)
, the private IP, is routed in VR cage-a-vr
and the MIP(1.1.1.51)
private IP is routed in VR cage-b-vr
. The default VR is the trust-vr
, unless configured differently. All zones are in the trust-vr
by default. Note that you must disable auto-route-export
in the individual VRs if you use the untrust-vr
in this model, as auto-route-export
would export all routes into the untrust-vr
automatically, and this could cause a conflict.
Configure a DIP shift:
set interface ethernet0/1 zone Untrust set interface ethernet0/1 ip 10.10.20.1/24 set interface ethernet0/1 dip 4 shift-from 192.168.1.50 to 10.10.20.50 10.10.20.150
Link the DIP shift to a policy:
set policy from Trust to Untrust any any any nat src dip-id 4 permit
You may want to perform a source translation from one network to another to avoid IP address conflicts between extranet partners. The solution is to configure a DIP shift. Table 8-10 details the source shift translation configuration.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
192.168.1.50 |
Any |
Any |
Any |
10.10.20.50 |
Original |
Original |
Original |
192.168.1.51 |
Any |
Any |
Any |
10.10.20.51 |
Original |
Original |
Original |
[…] |
Any |
Any |
Any |
[…] |
Original |
Original |
Original |
192.168.1.150 |
Any |
Any |
Any |
10.10.20.150 |
Original |
Original |
Original |
Any address starting from 192.168.1.50
and continuing to 192.168.1.150
would be translated to an address in the range of 10.10.20.50–10.10.20.150
. So, 192.168.1.50
would be translated to 10.10.20.50, 192.168.20.51
would be translated to 10.10.20.51
, and so on.
set interface ethernet0/1 zone Untrust set interface ethernet0/1 ip 10.10.20.1/24 set interface ethernet0/1 dip 4 shift-from 192.168.1.50 to 10.10.20.50 10.10.20.150 set policy from Trust to Untrust any any any nat src dip-id 4 permit
Outside of 192.168.1.50–192.168.1.150
, the policy would pass the traffic, but no translation would be applied. This is really useful if, for example, one side was to be translated to one-half the address space on the common network, and the other side offered services in the form of MIPs (see Recipe 8.8) to the upper portion of the address space.
set interface ethernet0/1 zone Untrust set interface ethernet0/1 ip 10.10.20.1/24 set interface ethernet0/1 dip 4 shift-from 192.168.1.50 to 10.10.20.100 10.10.20.200 set policy from Trust to Untrust any any any nat src dip-id 4 permit
DIP shift also supports unequal shifts, so it’s possible to shift 192.168.1.50 to 10.10.20.100
and 192.168.1.51
to 10.10.20.101
. Again, this would be useful if you wanted to double NAT to sites on one common network.
Shift source translation is often used in conjunction with MIP translation and destination translation (see Recipe 8.6).
Configure the local network that you want to translate:
set address trust server-net 10.10.20.128/25
Configure the shift translation within the policy:
set policy from untrust to trust any server-net any nat dst ip 192.168.1.0 192.168.1.127 permit
With a MIP, only a whole network can be translated, but with policy NAT-DST, the translation can be shifted, similar to a DIP shift (see Recipe 8.10). A common problem is a corporate network with address overlap. The best practice in this instance is to use a publicly owned address space for interorganizational traffic, guaranteeing uniqueness to the address space. But when it’s not feasible to assign a large enough public block, you can choose a private neutral network, with one-half of the network belonging to Organization A, and one-half belonging to Organization B. Translation commonly can be achieved with a series of MIPs, but policy NAT-DST with address shift is also a nice solution, in particular if the private address space is contiguous. It’s a special case, but not out of the realm of possibility. Table 8-11 details the destination shift translation configuration.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
10.10.20.128 |
Any |
Any |
Original |
192.168.1.0 |
Original |
Original |
Any |
10.10.20.129 |
Any |
Any |
Original |
192.168.1.1 |
Original |
Original |
Any |
[…] |
Any |
Any |
Original |
[…] |
Original |
Original |
Any |
10.10.20.255 |
Any |
Any |
Original |
192.168.1.128 |
Original |
Original |
The two organizations may decide on the common address space of 10.10.20.0/24
. Organization A gets 10.10.20.0/25
and Organization B gets 10.10.20.128/25
. So, for instance, when a client connects to 10.10.20.228
, it would be redirected to host 192.168.1.100
. In the same way, host 10.10.20.129
would be translated to 10.10. 20.128/25
. At Organization A, you could translate all of Organization B’s servers on the 192.168.1.128/25
DMZ with one simple command:
set address trust server-net 10.10.20.128/25 set route 10.10.20.128/25 interface e0/0 set policy from untrust to trust any server-net any nat dst ip 192.168.1.0 192.168.1.127 permit
Shift destination translation is often used in conjunction with DIP hide (see Recipe 8.1) or DIP shift translation (see Recipe 8.10).
Configure a MIP with a netmask
, describing the network:
set interface ethernet0/0 mip 1.1.1.0 host 192.168.2.0 netmask 255.255.255.0
Link the MIP to an inbound policy:
set policy from Untrust to Trust Any MIP(1.1.1.0/24) http permit
Also link the MIP to an outbound policy:
set address Trust 192.168.1.0/24 192.168.1.0 255.255.255.0 set policy from Trust to Untrust 192.168.1.0/24 Any Any permit
Instead of translating individual servers one by one, you can translate an entire network, which may be easier to configure than hundreds of individual NATs. Table 8-12 shows the destination shift translation of the bidirectional translation.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
Any |
1.1.1.0 |
Any |
Any |
Original |
192.168.2.0 |
Original |
Original |
Any |
1.1.1.1 |
Any |
Any |
Original |
192.168.2.1 |
Original |
Original |
Any |
[…] |
Any |
Any |
Original |
[…] |
Original |
Original |
Any |
1.1.1.255 |
Any |
Any |
Original |
192.168.2.255 |
Original |
Original |
Table 8-13 shows the source shift translation of the bidirectional translation.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
192.168.2.0 |
Any |
Any |
Any |
1.1.1.0 |
Original |
Original |
Original |
192.168.2.1 |
Any |
Any |
Any |
1.1.1.1 |
Original |
Original |
Original |
[…] |
[…] |
Any |
Any |
[…] |
[…] |
Original |
Original |
192.168.2.255 |
Any |
Any |
Any |
1.1.1.255 |
Original |
Original |
Original |
The resulting MIP object has the name format of MIP
(<publicnet/netmask
>). It translates 1.1.1.0/24
to 192.168.2.0/24
. Host 192.168.2.1
is translated to 1.1.1.1
, host 192.168.2.2
to 1.1.1.2
, and so on.
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 2.2.2.100/24 set interface ethernet0/0 mip 1.1.1.0 host 192.168.2.0 netmask 255.255.255.0 set policy from Untrust to Trust any MIP(1.1.1.0/24) http permit
Notice that the MIP is not in the network with the interface’s IP address. This has two implications: first, hosts on the Untrust
segment, 2.2.2.0/24
, need to have a route for destination 1.1.1.0/24
to point to firewall 2.2.2.100
. Second, such a configuration is supported only on an interface in the Untrust
zone, unless you use ScreenOS 6.1 or later.
A MIP is a bidirectional NAT translation, meaning that it performs destination and source translation. A MIP only needs to be linked in the policy in the function of a destination translation. The source translation part is always implicit. The outgoing policy shown here will automatically translate the 192.168.1.0/24
source IP address to 1.1.1.0/24
:
set policy from Untrust to Trust Any MIP(1.1.1.0/24) http permit set address Trust 192.168.1.0/24 192.168.1.0 255.255.255.0 set policy from Trust to Unrust 192.168.1.0/24 Any Any permit
The drawback of usinga MIP for this purpose is that you cannot translate outside of network boundaries. For instance, you cannot simply translate a range of hosts. Alternatives are policy NAT-DST (see Recipe 8.11) in combination with policy NAT-SRC (DIP) (see Recipe 8.10).
First, configure the source addresses for the condition:
set address untrust client-a 2.2.2.0/24 set address untrust client-b 3.3.3.0/24
Then, configure policy NAT-DST for the destination translation:
set address trust host-ab-pub 1.1.1.50/32 set route 1.1.1.50/32 interface e0/0 set policy from Untrust to Trust client-a host-ab-pub http nat dst ip 192.168.1.100 permit set policy from Untrust to Trust client-b host-ab-pub http nat dst ip 192.168.1.200 permit
Or, you can configure policy NAT-SRC (also called DIP) for source address translation:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/0 dip 4 1.1.1.1 set interface ethernet0/0 dip 5 1.1.1.2 set policy from Untrust to Trust client-a Any Any nat src dip-id 4 permit set policy from Untrust to Trust client-b Any Any nat src dip-id 5 permit
Because policy NAT-DST and NAT-SRC are unidirectional, you can also perform a translation depending on its origin.
Let’s say you have two clients in networks 2.2.2.0/24
and 3.3.3.0/24
. Depending on which client connects, you want to perform different destination or source translations. First, you configure address objects with the condition—the clients:
set address untrust client-a 2.2.2.0/24 set address untrust client-b 3.3.3.0/24
Then, you configure the destination translation, depending on the clients: for instance, when client-a
connects to the public IP of 1.1.1.50, client-a
is destination-translated to 192.168.1.100
, but when client-b
connects to the same public IP of 1.1.1.50, client-b
is destination-translated to 192.168.1.200
. This is called conditional NAT-ing, and you can use it for load-sharing of servers, or to make servers available to different interest groups. Table 8-14 shows conditional destination translation with NAT-DST, with the condition listed in the “src-ip” column.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
2.2.2.0/24 |
1.1.1.50 |
Any |
Any |
Original |
192.168.1.100 |
Original |
Original |
3.3.3.0/24 |
1.1.1.50 |
Any |
Any |
Original |
192.168.1.200 |
Original |
Original |
You configure two policies with NAT-DST, referencing the different clients for each translation:
set interface ethernet0/0 zone Trust set interface ethernet0/1 zone Untrust set address trust host-ab-pub 1.1.1.50/32 set route 1.1.1.50/32 interface e0/0 set policy from Untrust to Trust client-a host-ab-pub http nat dst ip 192.168.1.100 permit set policy from Untrust to Trust client-b host-ab-pub http nat dst ip 192.168.1.200 permit
Because NAT-SRC DIP translation is also unidirectional translation, you can also create conditional source translation. For instance, say you want different user groups to use different hide NATs. client-a
is source-translated to 1.1.1.1
, whereas client-b
is source-translated to 1.1.1.2
. Table 8-15 shows conditional source translation with DIPs. You’ll find the condition listed in the “src-ip” column.
Private or local portion |
Public or global portion | ||||||
src-ip |
dst-ip |
src-port |
dst-port |
x-src-ip |
x-dst-ip |
x-src-port |
x-dst-port |
2.2.2.0/24 |
Any |
Any |
Any |
1.1.1.1 |
Original |
≥ 1024 |
Original |
3.3.3.0/24 |
Any |
Any |
Any |
1.1.1.2 |
Original |
≥ 1024 |
Original |
First, configure two different DIPs, one for each client:
set interface ethernet0/0 zone Untrust set interface ethernet0/0 ip 1.1.1.100/24 set interface ethernet0/0 dip 4 1.1.1.1 set interface ethernet0/0 dip 5 1.1.1.2
Then, link the two different DIPs to two different policies, with the different clients in the policy’s source:
set policy from Untrust to Trust client-a Any Any nat src dip-id 4 permit set policy from Untrust to Trust client-b Any Any nat src dip-id 5 permit
Instead of using IP addresses as the condition, you could use a service. For instance, you could provide a public IP and NAT host connecting to the HyperText Transfer Protocol (HTTP) and MAIL, to two different internal servers:
set policy from Untrust to Trust Any host-ab-pub http nat dst ip 192.168.1.100 permit set policy from Untrust to Trust Any host-ab-pub mail nat dst ip 192.168.1.200 permit
Or, you could use two different hide NAT translations for HTTP and mail traffic:
set policy from Untrust to Trust Any Any http nat src dip-id 4 permit set policy from Untrust to Trust Any Any mail nat src dip-id 5 permit
One warning, however: conditional NATing makes for a very complex policy base. Design complexity invites errors during operation.
Configure the interfaces in a loopback-group
. Apply the DIP and MIP on the loop-back address instead of on the egress or ingress interface:
set interface ethernet0/0 zone Untrust set interface ethernet0/1 zone Untrust set interface loop.1 zone untrust set interface ethernet0/0 loopback-group loop.1 set interface ethernet0/1 loopback-group loop.1 set interface loop.1 ip 10.10.10.1/24 set interface loop.1 dip 4 10.10.10.100 set interface loop.1 mip 10.10.10.200 host 192.168.1.100 set policy from Trust to Untrust any any any nat dip-id 4 permit set policy from Untrust to Trust any MIP(10.10.10.200) any permit
This recipe represents a typical scenario in which you have several interfaces allocated for direct connection to wide area network (WAN) circuits or indirectly to WAN routers, or you have redundant interfaces in a dynamically routed environment.
This recipe works only if all the interfaces that share a DIP or a MIP are in the same zone because all members of a loopback-group
have to be in the same zone. An interface may be a member of only one loopback-group
. If all MIPs cannot be summarized into one network, all interfaces must be in the Untrust
zone because only Untrust
zone MIPs can be in a different network from their IP address on that interface unless you use ScreenOS 6.1 or later.
A loopback group is basically an interface template. Any DIP on the loopback interface is applied to the physical interface or subinterfaces in the group. DIPs are applied to the egress interface. For a MIP, which is applied ingress, you also can use a loopback group, but you do not have to. If you do not use a loopback group, basically two policy lookups occur: one from the ingress zone, which in our case is from the Untrust
zone to the zone the loopback interface is in (in this case, Untrust
again) and a second lookup from the zone the loopback interface is in, to the zone the egress interface is in, which in this case is Trust
.
set policy id 1 from "Untrust" to "Untrust" "Any" "Any" "ANY" permit set policy id 2 from "Untrust" to "Trust" "Any" "MIP(10.5.5.100)" "ANY" permit
When using a loopback-group
instead, you do not need policy id 1
. Only one policy lookup would take place.
You can view the members in a loopback-group
with the get interface
command on the loopback interface:
SSG140->get int loop.1
Interface loopback.1: description loopback.1 number 126, if_info 101816, if_index 1, mode route link upLoopback interface has 2 members: ethernet0/1; tunnel.1
vsys Root, zone Untrust, vr trust-vr admin mtu 1500, operating mtu 1500, default mtu 1500 *ip 10.5.5.1/24 *manage ip 10.5.5.1 pmtu-v4 disabled ping disabled, telnet disabled, SSH disabled, SNMP disabled web disabled, ident-reset disabled, SSL disabled OSPF disabled BGP disabled RIP disabled RIPng disabled mtrace disabled PIM: not configured IGMP not configured NHRP disabled
You want to secure a small office using a firewall without a DMZ (see Figure 8-1). On the Trust side, you are using a private network, and on the Untrust side, you receive a single public IP address dynamically from your service provider. No access is initiated from the outside to the inside.
Enable NAT mode on the Trust
interface:
set interface ethernet0/0 zone "Trust" set interface ethernet0/1 zone "Untrust" set interface ethernet0/0 ip 192.168.1.1/24 set interface ethernet0/0 nat set interface ethernet0/1 dhcp client enable set interface ethernet0/1 route
Configure a policy from Trust
to Untrust
without the nat
switch (because NAT mode was enabled on interface e0/0
):
set policy id 1 from "Trust" to "Untrust" "Any" "Any" "ANY" permit log
When you have a small firewall with two interfaces, with the user network on the Trust side and the Internet Service Provider (ISP) on the Untrust side, the interface in the Untrust
zone often receives its address dynamically from the service provider. (Commonly, in such a small-office environment, the public IP address is assigned via the Dynamic Host Configuration Protocol [DHCP], Point-to-Point Protocol [PPP], Point-to-Point Protocol over Ethernet [PPPoE], or Point-to-Point Protocol over ATM [PPPoA]; in this recipe, we’ll stick to DHCP.) The topology would look something similar to Figure 8-1.
The first step is to configure the interfaces. Switch the Trust
interface to NAT mode, and leave the Untrust
interface in route mode. No other zones, predefined or custom, can be used with NAT mode. NAT mode is not supported with interfaces in other zones, predefined or custom. This is actually the out-of-the-box default configuration for smaller firewalls.
set interface "ethernet0/0" zone "Trust" set interface "ethernet0/1" zone "Untrust" set interface ethernet0/0 ip 192.168.1.1/24 set interface ethernet0/0 nat set interface ethernet0/1 dhcp client enable set interface ethernet0/1 route
The second step is to configure an outbound policy. The source zone always needs to be Trust
, and the target zone can be either Untrust
or DMZ
, depending on where the translation occurs:
set policy id 1 from "Trust" to "Untrust" "Any" "Any" "ANY" permit log
Because NAT mode is really a legacy mode, do not configure it with firewalls with more than two interfaces or zones. NAT mode has many conditions, and a more flexible method of configuring PAT within a policy exists today (see Recipe 8.1). For smaller firewalls, however, it is a convenient and easy way to get a configuration going within a few commands.
This recipe works only if the default zones of Trust, Untrust
, and DMZ
are used. The alternative to NAT mode is route mode with policy NAT-SRC, which we showed in Recipe 8.1.
You are deploying a firewall with a DMZ for a small office (see Figure 8-2). Your provider is giving you one public static IP address. You want all hosts on the private network and the DMZ to have Internet access. In the DMZ, you have a web server and you want to remotely administer a Linux host via Secure Shell (SSH) from the Internet.
First, assign the interfaces into zones, configure the IP addresses, and put the interfaces into route mode:
set interface ethernet0/0 zone "Trust" set interface ethernet0/1 zone "Untrust" set interface ethernet0/2 zone "DMZ" set interface ethernet0/0 ip 192.168.1.1/24 set interface ethernet0/0 route set interface ethernet0/1 ip 1.1.1.100/24 set interface ethernet0/1 route set interface ethernet0/2 ip 192.168.2.1/24 set interface ethernet0/2 route set route 0.0.0.0/0 interface ethernet0/1 gateway 1.1.1.254
Then, because your provider is providing only one static IP address and you want to remotely access the hosts in the DMZ, you must reassign any ScreenOS management ports that may conflict with your static port translation:
set admin port 8080 set admin ssh port 2022
Now, configure a VIP for access to the DMZ servers from the Internet:
set interface ethernet0/1 vip untrust-ip 80 "HTTP" 192.168.2.100
Configure another VIP to administer the Linux host via SSH:
set interface ethernet0/1 vip untrust-ip 22 "SSH" 192.168.2.200
Next, configure a policy, referencing the VIP:
set policy id 4 from "Untrust" to "Global" "Any" "VIP(ethernet0/1)" "HTTP" permit log set policy id 4 set service "SSH" exit
Configure policy NAT-SRC for all outbound traffic:
set policy id 1 from "Trust" to "Untrust" "Any" "Any" "ANY" nat src permit log set policy id 2 from "DMZ" to "Untrust" "Any" "Any" "ANY" nat src permit log
You also likely will want to allow traffic from the Trust
zone to the DMZ
, without NAT:
set policy id 3 from "Trust" to "DMZ" "Any" "Any" "ANY" permit log
This recipe describes a typical small-office design with a private user network and a DMZ, as shown in Figure 8-2. All addressing is within the RFC 1918 space. The provider assigned only one static IP address. The user segment has the address space 192.168.1.0/24
; the DMZ has the address space 192.168.2.0/24
. Two servers live in the DMZ, one web server and one Linux server. The provider assigned the public IP address 1.1.1.100
. As an example, there is a random public host of 2.2.2.2
.
Your first step is to put the interfaces into zones and to configure IP addresses and routing. Notice that all interfaces are put in route mode. NAT mode is a legacy mode with a very narrowly defined function (see Recipe 8.21):
set interface ethernet0/0 zone "Trust" set interface ethernet0/1 zone "Untrust" set interface ethernet0/2 zone "DMZ" set interface ethernet0/0 ip 192.168.1.1/24 set interface ethernet0/0 route set interface ethernet0/1 ip 1.1.1.100/24 set interface ethernet0/1 route set interface ethernet0/2 ip 192.168.2.1/24 set interface ethernet0/2 route set route 0.0.0.0/0 interface ethernet0/1 gateway 1.1.1.254
Because you have only one public IP address available, and you want Internet users to have access to the hosts in the DMZ with the same ports that you use to manage the firewall, you must move the ScreenOS management ports to different ports. The first line in the following code snippet moves the port for the WebUI from 80/ tcp
to 8080/tcp
. The second line moves the SSH port from 22/tcp
to 2022/tcp
. If you want to move ScreenOS’s local management ports to another socket, you need to move them to a port number of 1024 or higher.
set admin port 8080 set admin ssh port 2022
Now, you can configure the VIPs on the interface in the Untrust
zone for Internet users to access the web server and Linux host. The Untrust
zone is the only zone on which VIPs are supported in current ScreenOS releases. In this example, you are going to translate 80/tcp
to the web server, and you will translate the SSH port (22/tcp)
to the Linux host. Notice that the VIP’s name is untrust-ip; untrust-ip
does not refer to the Untrust
zone, but rather to the interface in the Untrust
zone.
set interface ethernet0/1 vip untrust-ip 80 "HTTP" 192.168.2.100 set interface ethernet0/1 vip untrust-ip 22 "SSH" 192.168.2.200
You choose untrust-ip
, instead of an IP address such as the following:
set interface ethernet0/1 vip 1.1.1.50
80 "HTTP" 192.168.2.100
because you want to use the same IP address the public interface is in, as your provider gave you only one IP address. The untrust-ip
name reference works best when your public IP address is assigned dynamically.
Note that in ScreenOS 6.1 and later, the syntax changed because VIPs are now supported on interfaces in any zone:
set interface ethernet0/1 vip interface-ip 80 "HTTP" 192.168.2.100
A VIP with a dynamic IP address is not very useful because a VIP along with a policy makes internal servers available to the Internet; therefore, the VIP IP addresses need to be known. Use of the Dynamic Domain Name Service (DDNS) is one way to solve this problem (see Chapter 6).
At this point, the interfaces are in zones and they have IP addresses, the manage-ment ports have been moved, and the VIP translations have been configured. The last thing to do is to link the VIP in a policy:
set policy id 4 from "Untrust" to "Global" "Any" "VIP(ethernet0/1)" "HTTP" permit log set policy id 4 set service "SSH" exit
This takes care of client access from the Internet to servers on the Trust or DMZ side. Now, let’s look at how hosts from the inside connect to the outside.
Use the nat
statement within the policy to configure a dynamic PAT for inside hosts to the outside. With this option, the source IP is translated to the IP address of the egress interface, which in this case is the IP of the Untrust
interface. Source ports are translated from their original port number to a number higher than 1023. (There are options to translate to a different IP address and to a pool of addresses. For more on this, see Recipe 8.1 and Recipe 8.4.)
set policy id 1 from "Trust" to "Untrust" "Any" "Any" "ANY" nat src permit log set policy id 2 from "DMZ" to "Untrust" "Any" "Any" "ANY" nat src permit log
The last step is to allow traffic from the Trust
zone to the DMZ
, without NAT:
set policy id 3 from "Trust" to "DMZ" "Any" "Any" "ANY" permit log
You want to deploy a firewall for a large office with one or more DMZs, and you own a static public IP address space (see Figure 8-3).
Configure a DIP for an outbound connection of hosts from the Trust side to perform outbound PAT:
set interface ethernet0/1 dip 4 1.1.1.50 set policy id 1 from "Trust" to "Untrust" "Any" "Any" "ANY" nat src dip-id 4 permit
Then, configure a MIP for each server in the DMZ to perform bidirectional, one-to-one NAT:
set interface "ethernet0/1" mip 1.1.1.100 host 192.168.2.100 set interface "ethernet0/1" mip 1.2.2.100 host 192.168.2.200
Next, configure a policy for outside users to initiate an HTTP session to the two MIP hosts:
set policy id 2 from "Untrust" to "DMZ" "Any" "MIP(1.1.1.100)" "HTTP" permit set policy id 2 set dst-address "MIP(1.2.2.100)" exit
Configure one single policy for DMZ hosts to make outside connections (the MIP is implied as outbound):
set policy id 5 from "DMZ" to "Untrust" any any any permit log
Lastly, allow Trust side hosts to connect internally to DMZ servers:
set policy id 4 from "Trust" to "DMZ" "Any" "Any" "Any" permit
Note that the preceding examples serve to explain the framework of the recipe. Production policies are usually tighter and more customized.
In this recipe, we have one Trust
network and one DMZ
network, similar to the one shown in Figure 8-3. There could be multiple networks on the Trust or DMZ side, and there could be multiple DMZs.
There is a single default route to the ISP’s router:
set interface "ethernet0/0" zone "Trust" set interface "ethernet0/1" zone "Untrust" set interface "ethernet0/2" zone "DMZ" set interface ethernet0/0 ip 192.168.1.1/24 set interface ethernet0/0 route set interface ethernet0/1 ip 1.1.1.1/24 set interface ethernet0/1 route set interface ethernet0/2 ip 192.168.2.1/24 set interface ethernet0/2 route set route 0.0.0.0/0 interface ethernet0/1 gateway 1.1.1.254
Notice that you need to put all interfaces in route mode to switch the device from NAT mode to route mode. This is recommended with all larger firewalls and firewalls with more than two interfaces. All outbound Untrust traffic is port-address-translated to the address 1.1.1.50
with the help of a DIP:
set interface ethernet0/1 dip 4 1.1.1.50 1.1.1.50 set policy id 1 from "Trust" to "Untrust" "Any" "Any" "ANY" nat src dip-id 4 permit
The DIP is configured on egress interface e0/1
and is linked in the outbound policy 1, with DIP ID4
chosen. Note that the fix-port
option is not selected in this policy because it is used only when one host should be translated to one address. In this case, all inside hosts were hidden behind 1.1.1.50
; therefore, PAT is applied.
For the inbound traffic, you configure MIPs. In this recipe, assume that one MIP is in the same network with the interface’s IP address and one is not. If the MIP should be in a different network than the IP address on that interface, the interface must be in the Untrust
zone, unless you use ScreenOS 6.l or later.
set interface "ethernet0/1" mip 1.1.1.100 host 192.168.2.100 netmask 255.255.255.255 vr "trust-vr" set interface "ethernet0/1" mip 1.2.2.100 host 192.168.2.200 netmask 255.255.255.255 vr "trust-vr" set policy id 2 from "Untrust" to "Global" "Any" "MIP(1.1.1.100)" "HTTP" permit set policy id 3 from "Untrust" to "Global" "Any" "MIP(1.2.2.100)" "HTTP" permit
In some ScreenOS documentation, MIP rules have a different zone than the Global
zone, but the destination zone in a MIP rule really does not matter because internally, it will always be treated as Global
. In most instances, it might be better to use a different zone than Global
to group MIPs in a policy because the Global
zone does not support grouping or multicell. (Grouping of MIPs and VIPs is supported in ScreenOS 5.3.)
set policy id 2 from "Untrust" to "DMZ" "Any" "MIP(1.1.1.100)" "HTTP" permit log set policy id 2 set dst-address "MIP(1.2.2.100)" exit
The neighboring router will ARP for the first MIP, but will need a static route for the other MIP, which is not in the same network as the interface’s IP:
sbrunner@INET#run show route
inet.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 1.1.1.0/24 *[Direct/0] 00:01:37> via fxp0.0
1.1.1.254/32 *[Local/0] 00:01:37 Local via fxp0.01.2.2.0/24
*[Static/5] 00:01:37> to 1.1.1.1 via fxp0.0
In this recipe, assume that every server in the DMZ has a corresponding MIP. You do not have to configure a DIP for outbound connections because MIPs are bidirectional.
set policy id 5 from dmz to untrust any any any permit log
No address translation is performed for traffic between the Trust
and DMZ
zones. Trust servers can reach the private address:
set address "Trust" "192.168.1.100/32" 192.168.1.100/32 "Trust client prv" set address "DMZ" "192.168.2.100/32" 192.168.2.100/32 "DMZ server prv" set policy id 4 from "Trust" to "DMZ" "192.168.1.100/32" "192.168.2.100/32" "http" permit log
You want to resolve an IP address clash within an extranet by translating both sides to a neutral address space.
Configure policy NAT-SRC for the outbound traffic. Both clients and servers are source-port address-translated:
set interface ethernet0/0 ext ip 1.1.1.200 255.255.255.255 dip 4 1.1.1.200 set interface ethernet0/1 ext ip 1.1.1.100 255.255.255.255 dip 5 1.1.1.100
Then, configure policy NAT-DST to make servers available to clients:
set address "Inside" "1.1.1.1/32" 1.1.1.1 255.255.255.255 "Public server left" set address "Inside" "192.168.1.0/24" 192.168.1.0 255.255.255.0 "Left network" set address "Outside" "1.1.1.2/32" 1.1.1.2 255.255.255.255 "Public server right" set address "Outside" "192.168.2.0/24" 192.168.2.0 255.255.255.0 "Right network"
Finally, configure the policies:
set policy id 1 from "Inside" to "Outside" "192.168.1.0/24" "1.1.1.2/32" "ANY" nat src dip-id 5 dst ip 192.168.2.100 permit log set policy id 2 from "Outside" to "Inside" "192.168.2.0/24" "1.1.1.1/32" "ANY" nat src dip-id 4 dst ip 192.168.1.100 permit log
All of the originating addresses from either side will be hidden behind one port-address translated address. All of the destinations will be one-to-one statically translated.
This recipe assumes the topology shown in Figure 8-4; that is, you want to connect to a partner network, but neither of your internal address spaces is routable at either side (perhaps because both use the same IP address space or perhaps due to some administrative policy). Therefore, you want to translate your addresses and your partner’s addresses to a neutral space.
On the left side is network 192.168.1.0/24
with a bunch of clients, as well as one server with IP 192.168.1.100
. On the right side are a bunch of clients within the 192.168.2.0/24
network, and one server with the IP address of 192.168.2.100
. The goal is to allow clients to connect to a well-known IP address to reach the servers while hiding any originating addresses. For any connections from the left side, this includes all clients as well as servers, which would be acting as clients when originating a connection, and would hide behind IP address 1.1.1.100
. Any connection originating from the right side will hide behind IP address 1.1.1.200
. The external IP addresses are arbitrarily chosen and could be anything. The left server will be known to the right side under 1.1.1.1
, and the right server will be known to the left side under 1.1.1.2
.
Let’s first investigate how this looks from a routing perspective:
sbrunner@LEFT>show route
inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both1.1.1.2/32
*[Static/5] 01:11:12> to 10.1.1.1 via fxp0.0 1.1.1.200/32
*[Static/5] 00:00:04> to 10.1.1.1 via fxp0.0
10.1.1.0/24 *[Direct/0] 01:11:12 > via fxp0.0 10.1.1.2/32 *[Local/0] 01:11:12 Local via fxp0.0192.168.1.0/24
*[Direct/0] 00:00:18> via fxp1.0
192.168.1.1/32 *[Local/0] 00:00:44 Local via fxp1.0
On the left router, you route public IP address 1.1.1.2
of the right-side host 192.168.2.100
to the firewall. You also route the hide address of the ride-side host 1.1.1.200
to the firewall:
sbrunner@RIGHT>show route
inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both1.1.1.1/32
*[Static/5] 01:12:12> to 10.2.2.1 via fxp0.0 1.1.1.100/32
*[Static/5] 00:00:10> to 10.2.2.1 via fxp0.0
10.2.2.0/24 *[Direct/0] 01:12:12 > via fxp0.0 10.2.2.2/32 *[Local/0] 01:12:12 Local via fxp0.0192.168.2.0/24
*[Direct/0] 00:00:28 > via fxp1.0 192.168.2.1/32 *[Local/0] 00:00:54 Local via fxp1.0
On the right router, you route in reverse the public IP address of 1.1.1.1
of the left-side host 192.168.1.100
, as well as the hide address 1.1.1.100
, to the firewall.
Let’s see what happens on the firewall:
FIREWALL(trust-vr)->get route
H: Host C: Connected S: Static A: Auto-Exported I: Imported R: RIP P: Permanent D: Auto-Discovered N: NHRP iB: IBGP eB: EBGP O: OSPF E1: OSPF external type 1 E2: OSPF external type 2 trailing B: backup route Total 8/max entries ID IP-Prefix Interface Gateway P Pref Mtr Vsys -------------------------------------------------------------------- * 131.1.1.1/32 eth0/0
0.0.0.0 S 20 1 * 141.1.1.2/32 eth0/1
0.0.0.0 S 20 1 * 2 10.1.1.1/32 eth0/0 0.0.0.0 H 0 0 * 4 10.2.2.1/32 eth0/1 0.0.0.0 H 0 0 * 7192.168.2.0/24 eth0/1 10.2.2.2
S 20 1 * 6192.168.1.0/24 eth0/0 10.1.1.2
S 20 1 * 1 10.1.1.0/24 eth0/0 0.0.0.0 C 0 0 * 3 10.2.2.0/24 eth0/1 0.0.0.0 C 0 0
The interesting routes are the static routes. The Connected
and Host
routes are from the two interfaces e0/0
and e0/1
. There are two sets of static routes: one for the private IP address and one for the public IP address. The reason for the private networks is because the firewall needs to know the next hop for the clients and servers. The routes for the public portion are not that clear. These routes are actually needed for ScreenOS to find the destination zone before translation occurs to match the packet to a policy. The packets come in with a public destination address of 1.1.1.1
or 1.1.1.2
. The address translation is happening in the policy, so ScreenOS first needs to identify the ingress and egress zones to identify a matching policy. You need to point 1.1.1.2
toward e0/1
and 1.1.1.1
toward e0/0
. The gateway is irrelevant because these routes are not actually used for forwarding, just for identifying egress interfaces and, therefore, the egress zone.
The actual address translation is happening in the policy itself. The NAT-DST is happening first. The NAT-SRC is happening when the packet leaves the egress interface. DIP and policy NAT-SRC are synonyms. A DIP is always installed on the egress interface and is called within the policy:
set interface "ethernet0/0" zone "Inside" set interface "ethernet0/1" zone "Outside" set interface ethernet0/0 ip 10.1.1.1/24 set interface ethernet0/0 route set interface ethernet0/1 ip 10.2.2.1/24 set interface ethernet0/1 route set interface ethernet0/0 ext ip 1.1.1.200 255.255.255.255 dip 4 1.1.1.200 set interface ethernet0/1 ext ip 1.1.1.100 255.255.255.255 dip 5 1.1.1.100 set vrouter "trust-vr" set route 192.168.1.0/24 interface ethernet0/0 gateway 10.1.1.2 set route 192.168.2.0/24 interface ethernet0/1 gateway 10.2.2.2 set route 1.1.1.1/32 interface ethernet0/0 set route 1.1.1.2/32 interface ethernet0/1 exit
Interface e0/0
is in the custom zone Inside
and interface e0/1
is in the custom zone Outside
. The choice of zone doesn’t really matter and could be anything. Both interfaces are in route mode. The DIPs for the NAT-SRC are configured on their respective egress interfaces. 1.1.1.200
points toward the right side and 1.1.1.100
points toward the left side. Both DIPs live on extended interfaces because the DIPs are not in the same network as the interface itself. Both extended interface IPs happen to be identical with our DIP. The four routes have been configured as already discussed. Notice that the public IP addresses do not have a gateway configured to them, as they are only required for ScreenOS to resolve the egress interface, and therefore, the egress zone as mentioned.
Policies go in the initiating direction:
set address "Inside" "1.1.1.1/32" 1.1.1.1 255.255.255.255 "Public server left" set address "Inside" "192.168.1.0/24" 192.168.1.0 255.255.255.0 "Left network" set address "Outside" "1.1.1.2/32" 1.1.1.2 255.255.255.255 "Public server right" set address "Outside" "192.168.2.0/24" 192.168.2.0 255.255.255.0 "Right network" set policy id 1 from "Inside" to "Outside" "192.168.1.0/24" "1.1.1.2/32" "ANY" nat src dip-id 5 dst ip 192.168.2.100 permit log set policy id 2 from "Outside" to "Inside" "192.168.2.0/24" "1.1.1.1/32" "ANY" nat src dip-id 4 dst ip 192.168.1.100 permit log
In the policy, you need to name the private address of the hosts in the source portion: in our case, on the left side in network 192.168.1.0/24
, and on the right side in network 192.168.2.0/24
. Remember, this includes any client or server initiating a connection to the other side. In the destination portion, name the public address of the servers, which on the left side is 1.1.1.1
and on the right side is 1.1.1.2
. Policy ID1
captures any host from the 192.168.1.0/24
network making a connection to the server on the right side on its public IP 1.1.1.2
. Policy ID 2
covers just the opposite: any host on the right side making a connection to the server on the left side to its public IP 1.1.1.1
.
Unlike with MIPs, by default, ScreenOS does not answer ARPs for policy NAT-DST for IPs that are in the same network as the ingress interface. On neighboring routers, static ARP for those addresses needs to be configured. Also see Recipe 8.6.
You want to perform source and destination NAT on a policy-based virtual private network (VPN) tunnel.
Configure NAT on only one side of the tunnel. Starting on FW-A, first you must configure a tunnel interface and put the tunnel interface into a tunnel zone:
set interface "tunnel.1" zone "Untrust-Tun" set interface tunnel.1 ip 1.1.1.1/24
Then, configure the p1
and p2
of the VPN tunnel, binding the VPN tunnel to the same tunnel zone to which you were binding the tunnel interface. The tunnel zone connects a policy-based VPN to a tunnel interface.
set ike gateway "test-gw" address 10.4.4.1 Main outgoing-interface "ethernet0/1" preshare netscreensec-level standard set vpn "test-vpn" gateway "test-gw" no-replay tunnel idletime 0 sec-level standard set vpn "test-vpn" monitor set vpn "test-vpn" bind zone Untrust-Tun
Next, configure the DIP on the outgoing interface, which you configured in the ike gateway
statement. Then, configure the MIP on the tunnel interface:
set interface ethernet0/1 ext ip 1.1.1.150/32 dip 4 1.1.1.150 fix-port set interface tunnel.1 mip 1.1.1.100 host 192.168.1.
Configure the tunnel policy and reference the DIP and MIP:
set address "Trust" "192.168.1.0/24" 192.168.1.0 255.255.255.0 set address "Untrust" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set policy id 1 from "Trust" to "Untrust" "192.168.1.0/24" "192.168.2.0/24" "ANY" nat src dip-id 4 tunnel vpn "test-vpn" set policy id 2 from "Untrust" to "Trust" "192.168.2.0/24" "MIP(1.1.1.100)" "ANY" tunnel vpn "test-vpn"
Create a route for the remote network. This route does not need a next hop because it is used only to determine the egress zone:
set route 192.168.2.0/24 interface ethernet0/1
On the remote VPN device, the tunnel policies need to match. Note that the Security Association (SA) is derived from the tunnel policy; with NAT, the SA and therefore the tunnel policy will not be that obvious. SAs on both ends need to be mirror images. Here is the configuration for FW-B:
set address "Trust" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set address "Untrust" "1.1.1.100/32" 1.1.1.100 255.255.255.255 set address "Untrust" "1.1.1.150/32" 1.1.1.150 255.255.255.255 set policy id 1 from "Untrust" to "Trust" "1.1.1.150/32" "192.168.2.0/24" "ANY" tunnel vpn "test-vpn" set policy id 1 from "Trust" to "Untrust" "192.168.2.0/24" "1.1.1.100/32" "ANY" tunnel vpn "test-vpn"
The policy on the remote device now needs to have the DIP address in its source, and the MIP policy must have the public portion of the MIP in its destination. Both are regular address objects because NAT is occurring on the remote side on FW-A.
Also, set a route on FW-B for the remote network. Note that you must use the public address instead of the local address because DIPs and MIPs translate to the 1.1.1.0/24
network:
set route 1.1.1.0/24 interface ethernet0/0
ScreenOS’s NAT configuration options are limited with policy-based VPNs, but luckily, the two most important NAT methods, DIPs and MIPs, work. A DIP is configured to the outgoing interface as specified during the IKE gateway configuration. (Unfortunately, policy NAT-DST is not supported with policy-based VPN, and neither are VIPs.)
MIPs in connection with policy-based VPNs work only as a destination address translation. A DIP is required if a source address translation is required.
The difference between policy-based VPNs and route-based VPNs in the configuration is that route-based VPNs are bound to a tunnel interface:
set vpn <name> bind interface tun.1
Why are we creating a tunnel interface in this recipe, when we are using a policy-based VPN? If you bind a tunnel interface to a policy-based VPN tunnel, it will make it a route-based VPN. So, to accomplish the NATing, you will bind the policy-based VPN tunnel indirectly via a tunnel zone. A tunnel zone has a carrier zone, which must be identical to the zone of the outgoing interface. Both the tunnel interface and the VPN are bound to the same tunnel zone. The Untrust-Tun
is a predefined tunnel zone, living in the Untrust
carrier zone. The tunnel zone is basically the link between a tunnel interface, the outgoing interface, and the policy-based VPN.
Figure 8-5 shows a simple configuration for discussion purposes: a network on the local side with 192.168.1.100/24
, and a network on the remote side with 192.168.2.0/24
.
The left-side server with the IP of 192.168.1.100
is destination-address-translated with a MIP to 1.1.1.100
and source-address-translated with a DIP to 1.1.1.150
. On FW-A, you configure the following:
set interface "ethernet0/1" zone "Untrust"
set interface ethernet0/1 ip 10.3.3.2/24
set interface ethernet0/1 route
set interface "tunnel.1" zone "Untrust-Tun"
set interface tunnel.1 ip 1.1.1.1/24
set ike gateway "test-gw" address 10.4.4.1 Main outgoing-interface
"ethernet0/1" preshare netscreen sec-level standard
set vpn "test-vpn" gateway "test-gw" no-replay tunnel idletime 0
sec-level standard
set vpn "test-vpn" bind zone Untrust-Tun
The DIP is anchored on the outgoing interface, and the MIP on the tunnel interface. It is theoretically possible to anchor DIPs and MIPs on a loopback interface instead, but then the routing may become complicated and would create two policy lookups: one for the NAT portion, and one for the VPN. Tunnel zones make life easier. Tunnel zones also share some similarities with loopback groups.
set interface ethernet0/1 ext ip 1.1.1.150/32 dip 4 1.1.1.150 fix-port set interface "tunnel.1" mip 1.1.1.100 host 192.168.1.100
The difference between policy-based VPN and route-based VPN is the way the firewall determines which traffic goes into the tunnel and which traffic is accepted from the remote security gateway. The common method is to identify the VPN traffic by ACLs or policies. The policy is put in the direction from the zone behind which the client sits to the zone through which the remote security gateway can be reached with a “tunnel” action defined so that the firewall knows to encrypt the traffic with the associated VPN definition. With route-based VPN, protected traffic would be determined by regular routing into a tunnel interface, similar to a WAN link, and then securing that traffic with a traditional ACL or policy.
set address "Trust" "192.168.1.0/24" 192.168.1.0 255.255.255.0 set address "Untrust" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set policy id 1 from "Trust" to "Untrust" "192.168.1.0/24" "192.168.2.0/24" "ANY" nat src dip-id 4 tunnel vpn "test-vpn" set policy id 2 from "Untrust" to "Trust" "192.168.2.0/24" "MIP(1.1.1.100)" "ANY" tunnel vpn "test-vpn"
For the DIP policy shown in the preceding code snippet, you use the address objects to specify the source and destination of the protected traffic, as well as reference the DIP as NAT-SRC within the policy the same way you would for a nontunnel policy. Instead of configuring a custom DIP, you could use the implicit DIP ID 2
, a PAT to the egress interface’s IP, which in the case of policy-based VPN is the outgoing interface. As with the MIP policy, you define the MIP as the destination object.
For non-VPN traffic, policy ID 1
would activate the MIP instead of the DIP because a MIP has precedence over a DIP as a source address translation. However, a MIP in connection with a policy-based VPN works only as a destination address translation.
A policy will provide the src-ip, dst-ip
, and service
triple. These are used to create an SA. An SA identifies a VPN tunnel between two VPN gateways via the same src-ip, dst-ip
, and service
. Multiple SAs can exist, and therefore, multiple tunnels may exist, although here only a single tunnel was configured. In fact, a new tunnel will auto-matically be created with each tunnel policy. You can clearly see that each policy produced a pair of SAs:
FW-A-> get sa
total configured sa: 2
HEX ID Gateway Port Algorithm SPI Life:sec kb Sta PID vsys
00000002< 10.4.4.1 500 esp:3des/sha1 00000000 expir unlim I/I 2 0
00000002> 10.4.4.1 500 esp:3des/sha1 00000000 expir unlim I/I -1 0
00000004< 10.4.4.1 500 esp:3des/sha1 593ed0a8 2650 unlim A/U -1 0
00000004> 10.4.4.1 500 esp:3des/sha1 c6887a1c 2650 unlim A/U 1 0
Let’s look at the SAs that are derived from the policies on FW-A:
FW-A->get sa id 0x4
index 1, name test-vpn, peer gateway ip 10.4.4.1. vsys<Root> auto key. policy node, tunnel mode, policy id in:<-1> out:<1> vpngrp:<-1>. sa_list_nxt:<0x2>. tunnel id 4, peer id 0, NSRP Local. site-to-site. Local interface is ethernet0/1 <10.3.3.2>. esp, group 2, 3des encryption, sha1 authentication autokey, IN active, OUT active monitor<1>, latency: 0, availability: 100 DF bit: clear app_sa_flags: 0x4000e3proxy id: local 1.1.1.150/255.255.255.255, remote 192.168.2.0/255.255.255.0, proto 0, port 0
ike activity timestamp: 402397 nat-traversal map not available incoming: SPI 593ed0a8, flag 00004000, tunnel info 40000004, pipeline life 3600 sec, 2446 remain, 0 kb, 0 bytes remain anti-replay off, idle timeout value <0>, idled 1 seconds next pak sequence number: 0x0 outgoing: SPI c6887a1c, flag 00000000, tunnel info 40000004, pipeline life 3600 sec, 2446 remain, 0 kb, 0 bytes remain anti-replay off, idle timeout value <0>, idled 1 seconds next pak sequence number: 0x55c FW-A->get sa id 0x2
index 0, name test-vpn, peer gateway ip 10.4.4.1. vsys<Root> auto key. policy node, tunnel mode, policy id in:<2> out:<-1> vpngrp:<-1>. sa_list_nxt:<0xffffffff>. tunnel id 2, peer id 0, NSRP Local. site-to-site. Local interface is ethernet0/1 <10.3.3.2>. esp, group 2, 3des encryption, sha1 authentication autokey, IN inactive, OUT inactive monitor<1>, latency: 0, availability: 0 DF bit: clear app_sa_flags: 0x4000a0proxy id: local 1.1.1.100/255.255.255.255, remote 192.168.2.0/255.255.255.0, proto 0, port 0
ike activity timestamp: 0 nat-traversal map not available incoming: SPI 00000000, flag 00004000, tunnel info 40000002, pipeline life 0 sec, expired, 0 kb, 0 bytes remain anti-replay off, idle timeout value <0>, idled 1514 seconds next pak sequence number: 0x0 outgoing: SPI 00000000, flag 00000000, tunnel info 40000002, pipeline life 0 sec, expired, 0 kb, 0 bytes remain anti-replay off, idle timeout value <0>, idled 1514 seconds next pak sequence number: 0x0
Surprisingly, VPN tunnel 0x4
, which was derived from DIP policy ID 1
, shows us 1.1.1.150/32
in the source and the expected 192.168.2.0/24
in the destination. However, policy ID 1
goes clearly from 192.168.1.0/24
to 192.168.2.0/24
. If you look closely, you’ll see that 1.1.1.150/32
is identical to our DIP.
The same thing happens to VPN tunnel 0x2
, which was derived from policy ID 2
, referencing the MIP. This is the reason 1.1.1.100/32
is in the source, and not 192.168.1.0/24
, as might be expected. This is significant because SAs have to match on either end of the tunnel. On a side note, this is also why policy ID 2
is not configured with an src-address
of Any
, as often is done with regular MIP policies, because SAs need to tell traffic apart on either end clearly.
The policies on the remote site, FW-B, look like this:
set address "Trust" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set address "Untrust" "1.1.1.100/32" 1.1.1.100 255.255.255.255 set address "Untrust" "1.1.1.150/32" 1.1.1.150 255.255.255.255 set policy id 1 from "Untrust" to "Trust" "1.1.1.150/32" "192.168.2.0/24" "ANY" tunnel vpn "test-vpn" set policy id 1 from "Trust" to "Untrust" "192.168.2.0/24" "1.1.1.100/32" "ANY" tunnel vpn "test-vpn"
When you look at the remote site’s (FW-B’s) SAs, you can see that the SAs match the policy:
FW-B->get sa
total configured sa: 2 HEX ID Gateway Port Algorithm SPI Life:sec kb Sta PID vsys 00000003< 10.3.3.2 500 esp:3des/sha1 00000000 expir unlim I/I 2 0 00000003> 10.3.3.2 500 esp:3des/sha1 00000000 expir unlim I/I 1 0 00000004< 10.3.3.2 500 esp:3des/sha1 c6887a1c 1937 unlim A/U 3 0 00000004> 10.3.3.2 500 esp:3des/sha1 593ed0a8 1937 unlim A/U -1 0 FW-B->get sa id 0x4
index 1, name test-vpn, peer gateway ip 10.3.3.2. vsys<Root> auto key. policy node, tunnel mode, policy id in:<3> out:<-1> vpngrp:<-1>. sa_list_nxt:<3>. tunnel id 4, peer id 0, NSRP Local. site-to-site. Local interface is ethernet0/0 <10.4.4.1>. esp, group 2, 3des encryption, sha1 authentication autokey, IN active, OUT active monitor<1>, latency: 0, availability: 100 DF bit: clear app_sa_flags: 0x20e3proxy id: local 192.168.2.0/255.255.255.0, remote 1.1.1.150/255.255.255.255, proto 0, port 0
ike activity timestamp: 4004275 nat-traversal map not available incoming: SPI c6887a1c, flag 00004000, tunnel info 40000004, pipeline life 3600 sec, 1979 remain, 0 kb, 0 bytes remain anti-replay off, idle timeout value <0>, idled 1 seconds next pak sequence number: 0x0 outgoing: SPI 593ed0a8, flag 00000000, tunnel info 40000004, pipeline life 3600 sec, 1979 remain, 0 kb, 0 bytes remain anti-replay off, idle timeout value <0>, idled 1 seconds next pak sequence number: 0x788 FW-B->get sa id 0x3
index 0, name test-vpn, peer gateway ip 10.3.3.2. vsys<Root> auto key. policy node, tunnel mode, policy id in:<2> out:<1> vpngrp:<-1>. sa_list_nxt:<-1>. tunnel id 3, peer id 0, NSRP Local. site-to-site. Local interface is ethernet0/0 <10.4.4.1>. esp, group 2, 3des encryption, sha1 authentication autokey, IN inactive, OUT inactive monitor<1>, latency: 0, availability: 0 DF bit: clear app_sa_flags: 0x20a0proxy id: local 192.168.2.0/255.255.255.0, remote 1.1.1.100/255.255.255.255, proto 0, port 0
ike activity timestamp: 0 nat-traversal map not available incoming: SPI 00000000, flag 00004000, tunnel info 40000003, pipeline life 0 sec, expired, 0 kb, 0 bytes remain anti-replay off, idle timeout value <0>, idled 5586 seconds next pak sequence number: 0x0 outgoing: SPI 00000000, flag 00000000, tunnel info 40000003, pipeline life 0 sec, expired, 0 kb, 0 bytes remain anti-replay off, idle timeout value <0>, idled 5586 seconds next pak sequence number: 0x0
We’re not quite finished yet, because routes are needed on both sides so that the egress zone is determined to find the right tunnel policy. In most cases, you might create a default route through the outgoing interface to the Internet gateway router that would match both remote networks. If such a route does not exist, or there are internal routes that include the remote networks, you need to point out routes through the outgoing interface. Those routes do not need a next hop because they are not used for routing; they are used only to determine the egress zone so that the tunnel policy can be correctly found:
FW-A->set route 192.168.2.0/24 interface ethernet0/1
FW-B->set route 1.1.1.0/24 interface ethernet0/0
In the preceding code snippet, 192.168.2.0/24
is routed on FW-A to its outgoing interface e0/1
, and the public portion for the MIP and DIP, 1.1.1.0/24
, on FW-B is routed to its outgoing interface e0/0
. Routing is actually happening for the encapsulated and encrypted traffic. The source and destination IPs in the outer header of the ESP encrypted packet are identical to the IP of the outgoing interface. Any routers in between will need to be able to route the ESP encrypted packets; typically, they have public IP addresses.
An alternative to configuring NAT on policy-based VPN tunnels is to configure NAT on route-based VPN tunnels, even if the other side supports only policy-based VPN. Matching a policy-based tunnel with a route-based tunnel may require a complex configuration because you need to match the SA. With route-based VPN, SAs do not have significance and are therefore set to all zeros.
It is possible to manually configure the SA on a route-based tunnel for the purpose of matching a policy-based tunnel on the remote end. It may get complex if more than one SA is involved. When connecting a Juniper firewall with a third-party VPN device that does not support route-based VPN, choosing policy-based VPN will make the configuration a lot simpler. For configuring proxy IDs, see Recipe 8.20.
You can configure either a DIP or a MIP on the tunnel interface, or you can configure policy DST-NAT within a policy (VIPs are not supported on tunnel interfaces). In this example, we’ll use a DIP.
First, configure a tunnel interface and put it into a regular zone, as opposed to the tunnel zone we discussed in Recipe 8.19:
set zone name vpn set interface tunnel.1 zone "vpn" set interface tunnel.1 ip 1.1.1.2/24
Then, configure the p1
and p2
phases of the VPN tunnel and bind the VPN tunnel to the tunnel interface. The tunnel interface is the entry into the tunnel.
set ike gateway "test-gw" address 10.4.4.1 Main outgoing-interface "ethernet0/1" preshare netscreen sec-level standard set vpn "test-vpn" gateway "test-gw" no-replay tunnel idletime 0 sec-level standard set vpn "test-vpn" monitor set vpn "test-vpn" bind interface tunnel.1
Configure a DIP or a MIP on the tunnel interface:
set interface tunnel.1 dip 4 1.1.1.150 set interface tunnel.1 mip 1.1.1.100 host 192.168.1.100
Next, configure regular policies and reference the DIP and the MIP:
set address "Trust" "192.168.1.0/24" 192.168.1.0 255.255.255.0 set address "vpn" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set policy id 1 from "Trust" to "vpn" "192.168.1.0/24" "192.168.2.0/24" "ANY" nat src dip-id 4 permit set policy id 4 from "vpn" to "Trust" "192.168.2.0/24" "MIP(1.1.1.100)" "ANY" permit log
You could alternatively configure policy NAT-DST in the policy. The source and destination zones are identical because the public portion of the NAT-DST translation is in the same network with the tunnel zone. This is the same rule that applies for policy NAT-DST outside of VPN:
set address "vpn" "1.1.1.100/32" 1.1.1.100 255.255.255.255 set address "vpn" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set policy id 3 from "vpn" to "vpn" "192.168.2.0/24" "1.1.1.100/32" "ANY" nat dst ip 192.168.1.100 permit log
Create a route for the remote network. This route does not need a next hop because it is pointing into a point-to-point tunnel:
set route 192.168.2.0/24 interface tunnel.1
The policies do not need to match on the remote end, FW-B, unlike with policy-based routing. SAs are not derived from the policies with route-based tunnels. The pol-icy simply needs to permit the traffic from and into the zone of the tunnel interface:
set address "Trust" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set address "vpn" "192.168.1.0/24" 192.168.1.0 255.255.255.0 set address "vpn" "1.1.1.0/24" 1.1.1.0 255.255.255.0 set policy id 3 from "vpn" to "Trust" "1.1.1.0/24" "192.168.2.0/24" "ANY" permit log set policy id 4 from "Trust" to "vpn" "192.168.2.0/24" "1.1.1.0/24" "ANY" permit log
Also, set a route on FW-B for the local network. Take note to use the public address instead if you translate.
set route 192.168.1.0/24 interface tunnel.1 set route 1.1.1.0/24 interface tunnel.1
In general, NAT with route-based VPN tunnels works the same way as physical links. Apply the same settings you would otherwise apply to a physical or logical interface.
A route-based VPN does not identify traffic destined for the VPN by a policy. A route-based VPN is constructed between two security gateways and is anchored on tunnel interfaces. This makes the VPN look like a point-to-point or point-to-multipoint WAN link, similar to Frame Relay or Asynchronous Transfer Mode (ATM). Protected traffic is determined by routes into the tunnel interface instead of by policies. Take note that the action on the ScreenOS policy is now “permit” instead of “tunnel”.
This recipe uses the simple network topology shown in Figure 8-6 for discussion purposes: there is a network on the local side with 192.168.1.0/24
, and a network on the remote side with 192.168.2.0/24
.
On the left side is a server with IP 192.168.1.100
and with various address translation options, which are exclusive to each other. For example, you can source-address-translate 192.168.1.100
to 1.1.1.150
with a DIP, and you can source-and destination-address-translate between 192.168.1.100
and 1.1.1.100
with a MIP. Instead of usinga MIP, you can perform a destination translation with policy NAT-DST from 1.1.1.100
to 192.168.1.100
. First, the VPN is defined on FW-A:
set zone name vpn set interface tunnel.1 zone "vpn" set interface tunnel.1 ip 1.1.1.2/32 set ike gateway "test-gw" address 10.4.4.1 Main outgoing-interface "ethernet0/1" preshare netscreen sec-level standard set vpn "test-vpn" gateway "test-gw" no-replay tunnel idletime 0 sec-level standard set vpn "test-vpn" bind interface tunnel.1
You anchor DIPs and MIPs on the tunnel interface in the same way you anchor them on physical ingress and egress interfaces outside a route-based VPN. Note that a MIP is a bidirectional address translation and has precedence over a DIP.
set interface tunnel.1 dip 4 1.1.1.150 set interface tunnel.1 mip 1.1.1.100 host 192.168.1.100
With a route-based VPN there are no tunnel policies. Normally, tunnel policies are used to derive SAs for the different tunnels between two security gateways. With route-based VPN there is only one tunnel between two security gateways. SAs have no significance. However, permit policies are used to control the flow of traffic from the Trust
to the vpn
zone and vice versa.
set address "Trust" "192.168.1.0/24" 192.168.1.0 255.255.255.0 set address "vpn" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set address "vpn" "1.1.1.100/32" 1.1.1.100 255.255.255.255 set policy id 1 from "Trust" to "vpn" "192.168.1.0/24" "192.168.2.0/24" "ANY" nat src dip-id 4 permit set policy id 2 from "Trust" to "vpn" "192.168.1.0/24" "192.168.2.0/24" "ANY" permit log set policy id 4 from "vpn" to "Trust" "192.168.2.0/24" "MIP(1.1.1.100)" "ANY" permit log set policy id 3 from "vpn" to "vpn" "192.168.2.0/24" "1.1.1.100/32" "ANY" nat dst ip 192.168.1.100 permit log
As mentioned before, the three NAT policies are basically mutually exclusive to each other. The preceding code is just a textbook example to show how to configure the alternatives. Policy ID 2
matches the MIP in the function as a source address transla-tion where the MIP is implied. Notice the vpn
zone. The zone in the policy follows the ingress and egress interfaces, and the tunnel interface is nothing more than a regular interface in terms of creating policies or performing NAT. For the tunnel interface to be used by traffic, you have to establish routing. The easiest way to do this is via a static route (but dynamic routing could be used, too):
set route 192.168.2.0/24 interface tunnel.1
On the remote side, the tunnel interface is put into the vpn
custom zone. Policies therefore go from and to vpn
. An any-permit
policy in either direction would suffice. For demonstration purposes, those three policies match the three policies on the local gateway. Because a MIP is a bidirectional translation, the two policies ID 3
and ID 4
on the remote gateway, and ID 2
and ID 3
on the local gateway, would match depending on the initiating direction:
set address "Trust" "192.168.2.0/24" 192.168.2.0 255.255.255.0 set address "vpn" "192.168.1.0/24" 192.168.1.0 255.255.255.0 set address "vpn" "1.1.1.0/24" 1.1.1.0 255.255.255.0 set policy id 3 from "vpn" to "Trust" "1.1.1.0/24" "192.168.2.0/24" "ANY" permit log set policy id 4 from "Trust" to "vpn" "192.168.2.0/24" "1.1.1.0/24" "ANY" permit log
Lastly, route the private and public networks, if you translate, into the tunnel interface so that the tunnel encrypts the traffic:
set route 192.168.1.0/24 interface tunnel.1 set route 1.1.1.0/24 interface tunnel.1
Note that you can fake SAs for the sake of connecting to a policy-based VPN on the remote end. If you do that, make sure the SAs match on either end. Do not change them unless it is warranted.
set vpn test-vpn proxy-id local-ip 192.168.1.0/24 remote-ip 192.168.2.0/24 any
Use get sa id
<idx>
to check for the appropriate SAs on either end. You only need to change the SA on a route-based tunnel when the remote end is a policy-based VPN gateway, for instance, because you are connecting to a security gateway from a different vendor. On a route-based VPN, the SA consists of all zeros by default.
For configuration verification use the following command:
get config | incl "int.* nat"
For troubleshooting use the following commands:
debug flow basic get session
Whereas you can switch ScreenOS from route mode to transparent mode by attaching at least one interface to an L2 zone, you can switch ScreenOS from route mode to NAT mode by placing the Trust
interface into NAT mode. NAT mode has relevance only to an interface in the Trust
zone, although it may be configured on any interface, which can be confusing.
set interface e1 zone trust set interface e1 nat set interface e2 zone dmz set interface e2 route set interface e3 zone untrust set interface e3 route
In other words, you need to check whether at least one interface in the Trust
zone is in NAT mode:
NS-5GT-> get config | incl "int.* nat"
set interface wireless2 nat
set interface loopback.1 nat
The following conditions exist:
NAT mode has an effect only on interfaces in the Trust
zone.
If all zones are in the trust-vr
, which is the default, NAT mode enables PAT to the egress interface IP of interfaces in the Untrust
or DMZ
zone, regardless of whether those interfaces are in NAT or ROUTE mode. It has no effect on any flows into or out of custom zones regardless of the zone membership of the ingress or egress interfaces and their mode settings.
If the Trust
zone is in the trust-vr
, NAT mode enables PAT to all other zones in the untrust-vr
, regardless of the zone membership of the egress interface and its mode setting.
Unlike with NAT routers, traffic in the reverse is passed without translation. The implicit deny rule would deny traffic from Untrust
to Trust
by default. A VIP or MIP on the interface in the Untrust
zone would provide reverse translations for servers.
You can overwrite the default behavior of NAT mode with a MIP with an actual translation or a null translation.
In most cases, it is easier to use a DIP instead. Make it a habit to switch all interfaces to ROUTE mode, with the exception of the special case for the NAT mode of a two-interface firewall, which uses the default zones Trust
and Untrust
. This avoids unexpected confusions later on.
You can troubleshoot any flow issues on the firewall with debug flow basic
. Use the set ffilter
command to narrow your output. NAT mode uses the implicit DIP ID 2
, similar to what would occur if you had used the nat
keyword within a policy. The DIP ID 2
is always identical to the IP of the egress interface. In the following example, the inside address 192.168.97.128
with src-port 2258
is translated to the public address 70.112.81.130
with src-port 1577
. Notice that the ALG HTTP is involved.
NS-5GT->get db stream
****** 612755.0: <Trust/ethernet1> packet received [52]****** ipid = 24289(5ee1), @0277f134 packet passed sanity check. ethernet1:192.168.97.128/2258
->209.85.237.104/80,6<Root> no session found flow_first_sanity_check: in <ethernet1>, out <N/A> [ Dest] 1.route 192.168.97.128->0.0.0.0, to ethernet1 chose interface ethernet1 as incoming nat if. flow_first_routing: in <ethernet1>, out <N/A> search route to (ethernet1, 192.168.97.128->209.85.237.104) in vr trust-vr for vsd-0/flag-0/ifp-null [ Dest] 36.route 209.85.237.104->70.112.80.1, to ethernet3 routed (x_dst_ip 209.85.237.104) from ethernet1 (ethernet1 in 0) to ethernet3 policy search from zone 2-> zone 1 policy_flow_search policy search nat_crt from zone 2-> zone 1 RPC Mapping Table search returned 0 matched service(s) for (vsys Root, ip 209.85.237.104, port 80, proto 6) No SW RPC rule match, search HW rulePermitted by policy 101 dip id = 2, 192.168.97.128/2258->70.112.81.130/1577
choose interface ethernet3 as outgoing phy if no loop on ifp ethernet3.session application type 6, name HTTP
, nas_id 0, timeout 300sec service lookup identified service 6. flow_first_final_check: in <ethernet1>, out <ethernet3> existing vector list 90b-3d4c4c0. Session (id:4029) created for first pak 90b flow_first_install_session======> route to 70.112.80.1 arp entry found for 70.112.80.1 nsp2 wing prepared, ready cache mac in the session make_nsp_ready_no_resolve() search route to (ethernet3, 209.85.237.104->192.168.97.128) in vr trust-vr for vsd-0/flag-3000/ifp-ethernet1 [ Dest] 1.route 192.168.97.128->192.168.97.128, to ethernet1 route to 192.168.97.128 idp flow creation is successful. flow got session.flow session id 4029
flow_idp_client_vector: in <ethernet1>, out <ethernet3> av/uf/voip checking. tcp seq check. Got syn, 192.168.97.128(2258)->209.85.237.104(80), nspflag 0x801e01, 0x800e00 flow_idp_server_vector: in <ethernet1>, out <ethernet3> search route to (null, 0.0.0.0->209.85.237.104) in vr trust-vr for vsd-0/flag-1000/ifp-vlan1 no route to (0.0.0.0->209.85.237.104) in vr trust-vr/0 flow_send_vector_, vid = 0, is_layer2_if=0 send packet to traffic shaping queue. flow_ip_send: 5ee1:70.112.81.130->209.85.237.104,6 => ethernet3(52) flag 0x20000, vlan 0 pak has mac Send to ethernet3 (66)
NAT mode automatically assigns a DIP ID 2
. The session id 4029
that corresponds with the preceding debug flow output is as follows:
NS-5GT->get session id 4029
id 4029(00000fbd), flag 08000000/8100/1001, vsys id 0(Root)policy id 101, application id 6, dip id 2
, state 0 di enabled current timeout 10, max timeout 10 (second) status normal, start time 613454, duration 4 session id mask 0, app value 0 ethernet1(vsd 0):192.168.97.128/2258
->209.85.237.104/80, protocol 6 session token 4 route 1 gtwy 208.111.159.61, mac 00155830c7b7, nsptn info 0, pmtu 1500 flag 801801, diff 0/0 port seq 0, subif 0, cookie 0, fin seq 2204825601, fin state 1 ethernet3(vsd 0):70.112.81.130/1577
->209.85.237.104/80, protocol 6 session token 6 route 36 gtwy 70.112.80.1, mac 00135f05e105, nsptn info 0, pmtu 1500 mac 00135f05e105, nsptn info 0 flag 801800, diff 0/0 port seq 0, subif 0, cookie 0, fin seq 1456248245, fin state 2
The application ID refers to an ALG. Application ID 6 stands for HTTP. The HTTP ALG does not deal with NAT, but when, for example, you would place a SIP VoIP call, you would see that application ID 63 is in the session.
For configuration verification use these commands:
get dip get config | include dip get interface <int> dip [ detail ]
For troubleshooting use the following commands:
debug flow basic get session debug dip all
You can review DIP configuration with several commands. get dip
gives a good overview of all the DIPs configured on the device. In particular, it shows in a nice summary which interface the DIP lives in and what type of a DIP it is. The Dip Low
column lists the first IP in a DIP pool
and the Dip High
column shows the last IP in a DIP pool
. It also shows whether DIP stickiness or an alarm is configured.
SSG140-> get dip
Dip Id Dip Low Dip High Interface Attribute
4 10.10.10.50 10.10.10.150 ethernet0/0 ip-shift
Port-xlated dip stickness on
DIP pool utilization alarm: enabled, raise threshold 90%, clear threshold 80%
If you want to check on a specific configuration syntax, get config | include dip
will show all the DIP-related configuration parameters. The pipe character feeds into a regular expression of which dip
is the pattern. Patterns can be more detailed. For instance, get config | include "policy .*dip"
will only show policies with a configured DIP; get config | include "int .*dip"
will only show the DIP configuration on interfaces.
SSG140-> get config | include dip
set interface ethernet0/1 dip 5 10.10.20.100 10.10.20.150
set interface ethernet0/1 dip 6 10.10.20.151 10.10.20.151
set dip sticky
set dip alarm-raise 90 alarm-clear 80
set policy from "Trust" to "Untrust" "Any" "Any" "ANY" nat src dip-id 5 permit
get interface
<int>
dip [detail]
gives the most detailed information. The output also shows the size of the DIP pool, and how many addresses are already allocated. The detail
configuration option in particular is helpful with DIP pool and DIP shift to show the exact scope and translation. The dynamic-ip
column shows the DIP pool and the host-ip
column shows the translation from DIP shift. The port-x
column also shows whether you do dynamic port translation.
SSG140->get int e0/0 dip
id = 4: ip range 10.10.10.50 ~ 10.10.10.150; (ip-shift) - available 100, active 0, inactive 0 SSG140->get int e0/1 dip
id = 5: ip range 10.10.20.100 ~ 10.10.20.150; (port-xlate) - available 51, active 0, inactive 0 id = 6: ip range 10.10.20.151 ~ 10.10.20.151; (port-xlate) - available 1, active 0, inactive 0 SSG140->get int e0/0 dip detail
dynamic-ip port-x id host-ip 10.10.10.50 No 4 192.168.1.50 10.10.10.51 No 4 192.168.1.51 10.10.10.52 No 4 192.168.1.52 10.10.10.53 No 4 192.168.1.53 10.10.10.54 No 4 192.168.1.54 [...]
Troubleshooting DIP problems is straightforward. As with anything that goes through the firewall, debug flow basic
will show what is going on. Use the set ffilter
command to narrow your output. In the following example, the DIP ID 5
is used to translate the inside address 192.168.1.100
to the outside address 10.10.20.102
. Notice that no ALG is involved in this flow. This is an ICMP ping.
SSG140->get db stream
****** 03919.0: <Trust/ethernet0/0> packet received [84]****** ipid = 15784(3da8), @1d56b914 packet passed sanity check. ethernet0/0:192.168.1.100/2785
->10.10.20.1/7436,1(8/0)<Root> no session found flow_first_sanity_check: in <ethernet0/0>, out <N/A> chose interface ethernet0/0 as incoming nat if. flow_first_routing: in <ethernet0/0>, out <N/A> search route to (ethernet0/0, 192.168.1.100->10.10.20.1) in vr trust-vr for vsd-0/flag-0/ifp-null [ Dest] 3.route 10.10.20.1->10.10.20.1, to ethernet0/1 routed (x_dst_ip 10.10.20.1) from ethernet0/0 (ethernet0/0 in 0) to ethernet0/1 policy search from zone 2-> zone 1 policy_flow_search policy search nat_crt from zone 2-> zone 1 RPC Mapping Table search returned 0 matched service(s) for (vsys Root, ip 10.10.20.1, port 55101, proto 1) No SW RPC rule match, search HW rulePermitted by policy 1 dip id = 5, 192.168.1.100/2785->10.10.20.102/3058
choose interface ethernet0/1 as outgoing phy if no loop on ifp ethernet0/1session application type 0, name None
, nas_id 0, timeout 60sec service lookup identified service 0 flow_first_final_check: in <ethernet0/0>, out <ethernet0/1> existing vector list 1-4faf434. Session (id:56062) created for first pak 1 flow_first_install_session======> route to 10.10.20.1 arp entry found for 10.10.20.1 ifp2 ethernet0/1, out_ifp ethernet0/1, flag 00800800, tunnel ffffffff, rc 1 outgoing wing prepared, ready handle cleartext reverse route search route to (ethernet0/1, 10.10.20.1->192.168.1.100) in vr trust-vr for vsd-0/flag-3000/ifp-ethernet0/0 [ Dest] 5.route 192.168.1.100->10.10.10.1, to ethernet0/0 route to 10.10.10.1 arp entry found for 10.10.10.1 ifp2 ethernet0/0, out_ifp ethernet0/0, flag 00800801, tunnel ffffffff, rc 1 flow got session.flow session id 56062
post addr xlation: 10.10.20.102->10.10.20.1. flow_send_vector_, vid = 0, is_layer2_if=0
A common error with DIPs is packet dropped, dip alloc failed
, which you can see in the output of debug flow basic
. Most of the time, this error means a matching DIP may exist but it is on the wrong interface, perhaps because the routing is different than intended or because the DIP was attached to the ingress interface instead of the egress interface. Remember the simple rule: source translation is applied to the packet on egress interfaces, whereas destination translation is applied to the packet on ingress interfaces. Another reason this error message might occur is because the DIP pool was exhausted as it was being scoped too small, or maybe because you are experiencing scans from malware. Review your screen settings—in particular, the flood control and session limiters.
A DIP is part of asession table; you also can see the translation in the session table with get session:
SSG140-> get session
alloc 1/max 56064, alloc failed 0, mcast alloc 0, di alloc failed 0 total reserved 0, free sessions in shared pool 56063id 56062
/s**,vsys 0,flag 00000010/0000/0001,policy 1,time 1, dip 5 module 0 if 0(nspflag 800801):192.168.1.100/1918
->10.10.20.1/7436,1, 000585c189d0, sess token 4,vlan 0,tun 0,vsd 0,route 5 if 5(nspflag 800800):10.10.20.102/2189
<-10.10.20.1/7436,1, 000585cf38f0, sess token 6,vlan 0,tun 0,vsd 0,route 3
debug dip all
could deliver valuable information about internal DIP allocation:
SSG140->get db stream Get DIP
[Root][ethernet0/1](5): host(192.168.1.100), port(0), ifp_ip(10.10.20.2), desired(0.0.0.0) --Got Sticky DIP [Root][ethernet0/1](5): 10.10.20.102/2152Release DIP
[Root]: did=5 host=192.168.1.100 dip=10.10.20.102 pport=2152, dst=10.10.20.1 flag=0x80
The maximum number of DIPs is restricted for all platforms. On ScreenOS 6.0 and later, the maximum number of DIPs is 1,021, and for ScreenOS 5.4 and earlier, it is 252. The limit is per VR, and you can configure up to 65,536 over all VRs. The total number of DIP sessions is also limited, and you can review it with get sys-cfg | include "port node"
. Depending on the platform, it can be up to the maximum session count because some platforms can translate more than one src-ip
to a dynamically allocated port so that you can get a multiple of 65,536 sessions per DIP IP. Keep in mind that normally, only a small fraction of sessions will be DIP sessions on a gateway firewall.
For configuration verification use this command:
get config | incl "policy .*nat dst"
For troubleshooting use the following commands:
debug flow basic get session debug nat all
There is no specific get
command to check with policy NAT-DST, because everything is configured in a policy. Use the pipe and regular expression match get config |incl "policy.*nat dst"
to display the commands with NAT-DST:
SSG140-> get config | incl "policy .*nat dst"
set policy id 1 from "Untrust" to "Trust" "Any" "server-prv" "SSH" nat dst ip
192.168.1.100 port 23 permit
You can troubleshoot with debug flow basic
. Use the set ffilter
command to narrow your output. You can clearly see the route lookup for the public IP address, which is in the same network as the ingress zone. You can also clearly see the xlate
(translation) and where the private portion is routed out. In this example, address 10.10.20.100
is translated to address 192.168.1.100
. Also, notice how routing occurs. The first route lookup occurs for 10.10.20.100
; after the session is permitted, a second route lookup for 192.168.1.100
occurs:
SSG140->get db stream
****** 12125.0: <Untrust/ethernet0/1> packet received [60]****** ipid = 13240(33b8), @1d55e114 packet passed sanity check. ethernet0/1:10.10.20.1/1649->10.10.20.100/23
,6<Root> no session found flow_first_sanity_check: in <ethernet0/1>, out <N/A> chose interface ethernet0/1 as incoming nat if. flow_first_routing: in <ethernet0/1>, out <N/A>search route to (ethernet0/1, 10.10.20.1->10.10.20.100) in vr trust-vr for vsd-0/flag-0/ifp-null [ Dest] 3.route 10.10.20.100->10.10.20.100, to ethernet0/1
routed (x_dst_ip 10.10.20.100
) from ethernet0/1 (ethernet0/1 in 0) to ethernet0/1policy search from zone 1-> zone 1
policy_flow_search policy search nat_crt from zone 1-> zone 1 RPC Mapping Table search returned 0 matched service(s) for (vsys Root, ip 10.10.20.100, port 23, proto 6) No SW RPC rule match, search HW rule Permitted by policy 1DST xlate: 10.10.20.100(23) to 192.168.1.100(23)
search route to (ethernet0/1, 10.10.20.1->192.168.1.100) in vr trust-vr for vsd-0/flag-0/ifp-null [ Dest] 7.route 192.168.1.100->10.10.10.1, to ethernet0/0routed (192.168.1.100) from ethernet0/1 (ethernet0/1 in 0) to ethernet0/1
No src xlate choose interface ethernet0/0 as outgoing phy if no loop on ifp ethernet0/0. session application type 10, name None, nas_id 0, timeout 1800sec ALG vector is not attached service lookup identified service 0. flow_first_final_check: in <ethernet0/1>, out <ethernet0/0> existing vector list 113-2b59bf4. Session (id:56062) created for first pak 113 flow_first_install_session======>route to 10.10.10.1
arp entry found for 10.10.10.1 ifp2 ethernet0/0, out_ifp ethernet0/0, flag 00800800, tunnel ffffffff, rc 1 outgoing wing prepared, ready handle cleartext reverse route search route to (ethernet0/0, 192.168.1.100->10.10.20.1) in vr trust-vr for vsd-0/flag-3000/ifp-ethernet0/1[ Dest] 3.route 10.10.20.1->10.10.20.1, to ethernet0/1
route to 10.10.20.1 arp entry found for 10.10.20.1 ifp2 ethernet0/1, out_ifp ethernet0/1, flag 00800801, tunnel ffffffff, rc 1 flow got session.flow session id 56062
tcp seq check. Got syn, 10.10.20.1(1649)->10.10.20.100(23), nspflag 0x801801, 0x800800 post addr xlation: 10.10.20.1->192.168.1.100. flow_send_vector_, vid = 0, is_layer2_if=0
The session id 56062
that corresponds with the preceding debug flow output is as follows:
SSG140->get session id 56062
id 56062(0000dafe), flag 0c000000/0000/0001, vsys id 0(Root) policy id 1,application id 0
, dip id 0, state 0 current timeout 1760, max timeout 1800 (second) status normal, start time 12125, duration 0 session id mask 0, app value 0 ethernet0/1(vsd 0): 10.10.20.1/1649->10.10.20.100/23
, protocol 6 session token 6 route 3 gtwy 10.10.20.100, mac 000585cf38f0, nsptn info 0, pmtu 1500 flag 801801, diff 0/0 port seq 0, subif 0, cookie 0, fin seq 0, fin state 0 ethernet0/0(vsd 0): 10.10.20.1/1649<-192.168.1.100/23
, protocol 6 session token 4 route 7 gtwy 10.10.10.1, mac 000585c189d0, nsptn info 0, pmtu 1500 mac 000585c189d0, nsptn info 0 flag 801800, diff 0/0 port seq 0, subif 0, cookie 0, fin seq 0, fin state 0 The session table shows us more clarity.
debug nat all
shows you what is going on. The following is an example of debug output after we translate port 22 to port 23 but do not translate the IP address:
SSG140->get db stream
## 2000-03-19 15:41:19 : search gate for if Untrust:10.10.20.1->192.168.1. 100,3748,22,6 ## 2000-03-19 15:41:19 : in nat_search_hole, no gate found ++(5/0)nsp add(0x3a2af68): 10.10.20.1/3748->192.168.1.100/22
,6, 10, 0x200a801 ## 2000-03-19 15:41:19 : hash add 5(11697): 10.10.20.1/3748->192.168.1.100/22 ++(0/0)nsp add(0x3a2afc0):192.168.1.100/23
->10.10.20.1/3748,6, 10, 0x800800 ## 2000-03-19 15:41:19 : hash add 0(9102): 192.168.1.100/23-> 10.10.20.1/3748
Most problems with policy NAT-DST are caused by wrong routes to the public IP address. Remember that these routes need to follow the policy, and that the destination zone is equal to the ingress zone or must be the zone where the server is located. The route for the public IP needs to follow this rule. Also, ARP requests are answered only when set arp nat-dst
is switched on, and when the public IP is in the same network as the ingress interface, and an intra-zone policy is configured; hence, ingress and egress zones are identical.
For configuration verification use these commands:
get vip get vip <vip> port-status get vip <vip> port <port> get vip server get config | include vip
For troubleshooting use the following commands:
debug flow basic get session debug vip basic
You can verify VIP configuration with several commands. A good command to start with is get vip
. If the VIP is attached to the interface itself instead of to a dedicated IP address, this IP may change. (To make the service available despite a dynamic IP address assignment, DDNS can be configured.) The first column is the global port, and the local port is referenced via a service object. The second column shows the interface on which the VIP lives. This interface must be in the Untrust
zone for ScreenOS 6.0 and earlier versions. The third column shows the global and local destination ports of the VIP. The last column shows the local IP address of the VIP as well as its local port. Notice the (OK)
in the last column, which shows the status of the local server:
FIREWALL-> get vip
Virtual IP Interface Port Service Server/Port
1.1.1.100 ethernet0/1 80 HTTP 192.168.2.100/80(OK)
1.1.1.100 ethernet0/1 23 SSH 192.168.2.200/22(OK)
1.1.1.100 ethernet0/1 22 SSH 192.168.2.200/22(OK)
The command get vip
also has several options. For example, get vip
<vip>
port-status
is a useful command to see all the port mappings with the multi-port
option. The first column describes the global port and the second the local port. The third column describes the Internet protocol, which can be a bit surprising, but VIPs can be used with TCP as well as UDP (most other transport layer protocols do not use the concept ofports). The last column again describes the local port, but this time via the service object, which was used in the VIP definition on the interface. In the following code, you can see that the service object termsrv-32
spawns multiple translations. This is because termsrv-32
references a range of ports and set vip multi-port
is enabled:
FIREWALL-> get vip 1.1.1.100 port-status Virtual IP : 1.1.1.100 Port Allocation : 32 of 64 Virtual Port -> Port | Protocol Id | Service Name 2032 -> 2032 | 6 | termsrv-32 2031 -> 2031 | 6 | termsrv-32 2030 -> 2030 | 6 | termsrv-32 [...] 2001 -> 2001 | 6 | termsrv-32
The get vip
<vip>
port
<port>
command shows the same information for a specific global port. The virtual port is the global port, shown in the last line of the following example with its local translation. The server is the local IP, whereas the VIP is identified by its global IP:
FIREWALL-> get vip 1.1.1.100 port 23
Virtual IP : 1.1.1.100
Virtual Port : 23
Service : SSH
Server : 192.168.2.200(OK)
Virtual Port : 23 -> 22
The last command option is server
. This gives a brief overview of all private IP addresses of servers and their health status:
FIREWALL-> get vip server
VIP server table:
0: 192.168.1.100, state = ALIVE
1: 10.10.20.250, state = DOWN
Often, it is useful to list all configuration lines that touch the VIP configuration. You can see that this command simply matches on the regular expression vip
. For instance, in the following example, the last line shows that VIP(10.10.20.251)
was configured in a multicell, but it does not show set policy id x
, so you can only guess which rule this was in. Different patterns may garner narrower results, such as get config | include "int.*vip"
or get config | include "policy.*vip"
.
SSG140-> get config | include vip
set interface ethernet0/1 vip 10.10.20.250 81 "HTTP" 10.10.20.250
set interface ethernet0/1 vip 10.10.20.251 82 "HTTP" 192.168.1.100
set policy id 2 from "Trust" to "Untrust" "Any" "VIP(10.10.20.250)" "HTTP" permit
set dst-address "VIP(10.10.20.251)"
You can troubleshoot any flow issues on the firewall with debug flow basic
. (Use the set ffilter
command to narrow your output.) The output is a little disappointing because you will not find a reference for the VIP explicitly. You can only find some hints:
SSG140->get db stream
****** 27708.0: <Untrust/ethernet0/1> packet received [60]****** ipid = 13154(3362), @1d5e4114 packet passed sanity check. ethernet0/1:10.10.20.1/2639->10.10.20.100/2323
,6<Root> no session found flow_first_sanity_check: in <ethernet0/1>, out <N/A>chose interface ethernet0/1 as incoming nat if.
flow_first_routing: in <ethernet0/1>, out <N/A> search route to (ethernet0/1, 10.10.20.1->192.168.1.100) in vr trust -vr for vsd-0/flag-0/ifp-null [ Dest] 5.route 192.168.1.100->10.10.10.1, to ethernet0/0 routed (x_dst_ip 192.168.1.100
) from ethernet0/1 (ethernet0/1 in 0) to ethernet0/0 policy search from zone 1-> zone 2 policy_flow_search policy search nat_crt from zone 1-> zone 10 RPC Mapping Table search returned 0 matched service(s) for (vsys Root, ip 10.10.20.100, port 2323, proto 6) No SW RPC rule match, search HW rulePermitted by policy 1
No src xlate choose interface ethernet0/0 as outgoing phy if no loop on ifp ethernet0/0. session application type 10, name None, nas_id 0, timeout 1800sec ALG vector is not attached service lookup identified service 0. flow_first_final_check: in <ethernet0/1>, out <ethernet0/0> existing vector list 113-2b59c24. Session (id:56053) created for first pak 113 flow_first_install_session======> route to 10.10.10.1 arp entry found for 10.10.10.1 ifp2 ethernet0/0, out_ifp ethernet0/0, flag 00800800, tunnel ffffffff, rc 1 outgoing wing prepared, ready handle cleartext reverse route search route to (ethernet0/0, 192.168.1.100->10.10.20.1) in vr trust-vr for vsd-0/flag-3000/ifp-ethernet0/1 [ Dest] 3.route 10.10.20.1->10.10.20.1, to ethernet0/1 route to 10.10.20.1 arp entry found for 10.10.20.1 ifp2 ethernet0/1, out_ifp ethernet0/1, flag 00800801, tunnel ffffffff, rc 1 flow got session.flow session id 56053
tcp seq check. Got syn, 10.10.20.1(2639)->10.10.20.100(2323), nspflag 0x801801,0x800800post addr xlation: 10.10.20.1->192.168.1.100.
flow_send_vector_, vid = 0, is_layer2_if=0
A better place to look for the success of our VIP is the session table. Although the session table does not contain an explicit reference for the VIP, you can see clearly that 10.10.20.100
was translated into 192.168.1.100
, and that port 2323 was translated into port 23:
SSG140->get session id 56053
id 56053(0000daf5), flag 0c000000/0000/0001, vsys id 0(Root) policy id 1,application id 0
, dip id 0, state 0 current timeout 1510, max timeout 1800 (second) status normal, start time 27708, duration 0 session id mask 0, app value 0 ethernet0/1(vsd 0): 10.10.20.1/2639->10.10.20.100/2323
, protocol 6 session token 6 route 3 gtwy 10.10.20.100, mac 000585cf38f0, nsptn info 0, pmtu 1500 flag 801801, diff 0/0 port seq 0, subif 0, cookie 0, fin seq 0, fin state 0 ethernet0/0(vsd 0): 10.10.20.1/2639<-192.168.1.100/23
, protocol 6 session token 4 route 5 gtwy 10.10.10.1, mac 000585c189d0, nsptn info 0, pmtu 1500 mac 000585c189d0, nsptn info 0 flag 801800, diff 0/0 port seq 0, subif 0, cookie 0, fin seq 0, fin state 0
If the output from debug flow basic
and get session
is not enough, you can also use debug vip basic
. Notice that server health is being checked (via a ping) before the session is created:
SSG140->get db stream
## 2000-03-14 11:25:44 : ethernet0/1 get v service 10.10.20.1-> 10.10.20.100:2323 ## 2000-03-14 11:25:44 :found a vip for 10.10.20.100 on ethernet0/1 interface
## 2000-03-14 11:25:44 : vport = 3e10ec0,10.10.20.100:2323 ## 2000-03-14 11:25:44 : in request: 10.10.20.1->10.10.20.100:2323 ## 2000-03-14 11:25:44 : --- server state: ---- ## 2000-03-14 11:25:44 : -1 192.168.1.100 ## 2000-03-14 11:25:44 :alive
. ## 2000-03-14 11:25:44 :allocated server ip:port = 192.168.1.100:23
## 2000-03-14 11:25:44 : Found VIP for session (port: 1022)
For configuration verification use these commands:
get mip get config | include mip
For troubleshooting use the following commands:
debug flow basic get session debug mip all
Verifying MIPs is easy. The get mip
command lists all MIPs configured on the system. The Map IP
column is the public IP, the Host IP
column is the private IP, the Interface
column lists the interface on which the MIP was configured, and the VRouter
column lists the target VR in which the private IP is sought:
SSG140-> get mip
Total MIPs under Root configured:1 Max:1500.
--------------------------------------------------------------------
Map IP Host IP Interface VRouter
--------------------------------------------------------------------
192.168.1.0/24 192.168.2.0 ethernet0/1 trust-vr
1.1.1.100/32 192.168.3.100 ethernet0/1 trust-vr
An easy way to see where a MIP touches a configuration is with get config | include mip
, where mip
is a regular expression filter to the configuration display. In some cases, it may be more useful to download the configuration to a local computer and to search it with an editor because typical configurations often have from hundreds to thousands of MIPs configured.
SSG140-> get config | include mip
set interface "ethernet0/1" mip 10.10.20.100 host 192.168.1.100
netmask 255.255.255.255 vr "trust-vr"
set policy id 1 from "Untrust" to "Trust" "Any" "MIP(10.10.20.100)" "ANY" permit
Flow debugging with debug flow basic
shows what is going on and helps to trouble-shoot a connection. Use the set ffilter
command to narrow your output. There is no explicit mention of the MIP, but there are a lot ofhints. You can clearly see the translation: address 10.10.20.100
is translated to address 192.168.1.100
.
SSG140->get db stream
****** 34911.0: <Untrust/ethernet0/1> packet received [60]****** ipid = 13330(3412), @1d501914 packet passed sanity check. ethernet0/1:10.10.20.1/4255->10.10.20.100/23,6
<Root> no session found flow_first_sanity_check: in <ethernet0/1>, out <N/A>chose interface ethernet0/1 as incoming nat if
. flow_first_routing: in <ethernet0/1>, out <N/A> search route to (ethernet0/1, 10.10.20.1->192.168.1.100
) in vr trust-vr for vsd-0/flag-0/ifp-null [ Dest] 5.route 192.168.1.100->10.10.10.1, to ethernet0/0 routed (x_dst_ip 192.168.1.100) from ethernet0/1 (ethernet0/1 in 0) to ethernet0/0 policy search from zone 1-> zone 2 policy_flow_search policy search nat_crt from zone 1-> zone 10 RPC Mapping Table search returned 0 matched service(s) for (vsys Root, ip 10.10.20.100, port 23, proto 6) No SW RPC rule match, search HW rulePermitted by policy 1
No src xlate choose interface ethernet0/0 as outgoing phy if no loop on ifp ethernet0/0. session application type 10, name None, nas_id 0, timeout 1800sec ALG vector is not attached service lookup identified service 0. flow_first_final_check: in <ethernet0/1>, out <ethernet0/0> existing vector list 113-2b59c24. Session (id:56057) created for first pak 113 flow_first_install_session======> route to 10.10.10.1 arp entry found for 10.10.10.1 ifp2 ethernet0/0, out_ifp ethernet0/0, flag 00800800, tunnel ffffffff, rc 1 outgoing wing prepared, ready handle cleartext reverse route search route to (ethernet0/0, 192.168.1.100->10.10.20.1) in vr trust-vr for vsd-0/flag-3000/ifp-ethernet0/1 [ Dest] 3.route 10.10.20.1->10.10.20.1, to ethernet0/1 route to 10.10.20.1 arp entry found for 10.10.20.1 ifp2 ethernet0/1, out_ifp ethernet0/1, flag 00800801, tunnel ffffffff, rc 1 flow got session.flow session id 56057
tcp seq check. Got syn, 10.10.20.1(4255)->10.10.20.100(23), nspflag 0x801801, 0x800800post addr xlation: 10.10.20.1->192.168.1.100
. flow_send_vector_, vid = 0, is_layer2_if=0
You also can see the translation in session id 56057
:
SSG140->get session id 56057
id 56057(0000daf9), flag 0c000000/0000/0001, vsys id 0(Root) policy id 1,application id 0
, dip id 0, state 0 current timeout 1590, max timeout 1800 (second) status normal, start time 34911, duration 0 session id mask 0, app value 0 ethernet0/1(vsd 0): 10.10.20.1/4255->10.10.20.100
/23, protocol 6 session token 6 route 3 gtwy 10.10.20.100, mac 000585cf38f0, nsptn info 0, pmtu 1500 flag 801801, diff 0/0 port seq 0, subif 0, cookie 0, fin seq 0, fin state 0 ethernet0/0(vsd 0): 10.10.20.1/4255<-192.168.1.100
/23, protocol 6 session token 4 route 5 gtwy 10.10.10.1, mac 000585c189d0, nsptn info 0, pmtu 1500 mac 000585c189d0, nsptn info 0 flag 801800, diff 0/0 port seq 0, subif 0, cookie 0, fin seq 0, fin state 0
Remember that a MIP is a bidirectional address translation. Therefore, a MIP performs destination translation as well as source translation, which you will see in the output from debug flow basic
as well as get session
. (The preceding example is a destination translation.)
debug mip all
shows you the same in a simple line:
SSG140->get db stream
## 2000-03-14 13:21:25 : IPv4 to IPv4: v410.10.20.100 -> v4 192.168.1.100
MIPs introduce very little overhead in the device, mainly in a small amount of time spent on the first packet when the session is established.