After covering a number of topics under Context Based Access Control (CBAC), in this tutorial we are going to cover another useful feature of CBAC, namely Port to Application Mapping (PAM).

As per the OSI (Open System Interconnection) model, every single server application is assigned a TCP or UDP port number where a client application is supposed to find it listening and ready to serve client requests. For example, for a secure shell (SSH) session to be established between two hosts (an SSH client and an SSH server), the SSH client has to know the IP address and the port number where the SSH server is found and the SSH server has to be located at the said IP address and port number ready (started) and listening for incoming client requests. By default the SSH server listens for incoming connections on TCP port 22.

Other applications and protocols like HTTP, SMTP, FTP, and telnet are by default listening respectively on port 80, 25, 21, and 23. These are the most known and easily remembered along with HTTPs (443) and DNS (53). The reason why these are by default configured to listen on those ports is that there is a range of port numbers that IANA has assigned to specific protocols/applications. These port numbers are reserved for those applications and client applications by default connect to those port numbers when no other port number is specified at application launch. For example, telnet-ing a remote host with the command “telnet x.x.x.x” where x.x.x.x is the IP address of the remote host will let the telnet application/command assume the destination port is 23. The same is valid for an SSH connection started without specifying a port value at the command line. Issuing the command “SSH –l user x.x.x.x” will have the SSH client assume the destination port is 22.

As found in the “Cisco IOS Security Configuration Guide Release 12.4” document, the table named “System-Defined Port Mapping” below shows us the most common application names and their well-known or registered port numbers. A more exhaustive list of well-known or registered port numbers can be found at

By default, on Cisco routers, the Port to Application Mapping is contained in the PAM table. The PAM table lists both system-defined port mappings (well-known or registered port numbers) and user-defined port mappings.

User-defined port mappings exist because on many occasions administrators have their own reasons to run servers on non-default ports and therefore have to manually define port mappings whereby well-known applications are mapped to specific chosen ports that are different from the well-known ports as they were assigned by the IANA. A system administrator may choose for example to serve the web pages on port 8000 and 8080 additionally to the traditional port 80. This may happen if for example the system administrator is running multiple different web servers on the same hardware server. The system administrator may still be running one single web server on the hardware server and chose to have it listening on a different port number.

When user-defined port to application mappings are introduced in a network scene where Context Based Access Control is in action or is planned to be implemented, proper configuration needs to be put in place to have inspection operations happening on the right port numbers so as not to have, for example, an inspection engine inspecting traffic flow on port 80 when the system administrator has deliberately moved the HTTP server from port 80 to port 8000. The inspection engine, in that case, would be “barking at the wrong tree” and the CBAC feature would not work because the “lawful” return traffic would not cross the IOS firewall since port 8000 was not inspected in the first place.


The topology in place for this tutorial is presented in the map below:

To achieve this topology we have integrated GNS3 with another virtualization platform, namely Oracle VM VirtualBox, to build the FreeBSD-10.2 server. This server will be running the Apache web server and an SSH server. The Apache web server will be a minimal barebones web server with the famous “It works!” page. Another necessary integration to GNS3 we had to make is the integration of the Windows 7 host laptop running the GNS3 platform. The settings integrating these two hosts (FreeBSD-10.2 and Windows 7) to GNS3 are beyond the scope of this tutorial, which is focused on Port to Application Mapping and Context Based Access Control, but may be a subject of a separate tutorial.

The segment between the Windows 7 host and the CBAC-PAM router is with the CBAC-PAM router at and the Windows 7 host at

The segment between the CBAC-PAM router and the FreeBSD-10.2 server is with CBAC-PAM router at and the FreeBSD-10.2 server at

We will start with the usual IP connectivity tests from one end to the other.

Once we successfully started the FreeBSD server:

We can see that the Windows 7 host can reach the FreeBSD server with ping:

And tracert tests:

Pointing the web browser at the server at gives us the expected web page:

The SSH connection to on the default port 22:

Works perfectly!

We could start over the tests the other way round but the results are obvious.

CBAC Configuration

Let us assume the topology presented above represents an actual situation at ACME Ltd. where the FreeBSD server is seated in the DMZ segment of the ACME Ltd. network. The CBAC-PAM router is the internet router connecting the ACME Ltd. network to the Internet and the Windows 7 host is a generic client that is allowed to reach the FreeBSD server on HTTP and SSH ports. The FreeBSD server is not allowed to access the Internet (any necessary updates or upgrades will be made with other media like pen drives, CD/DVD-ROM, etc.). Other segments of the ACME Ltd. network are not shown in this topology because they are not necessary to the illustration of our subject matter: PAM on CBAC.

Note that the rules in the section above are relevant to this test environment only and that your mileage may vary depending on the situation you have at hand.

We are now going to configure CBAC to implement these rules.

Step 1

As in previous tutorials, let’s start with the access control list. This will be the blocking access control list against any traffic that is not recognized as a returning flow of a previously inspected flow. It will be applied to the DMZ interface of the CBAC-PAM router (FE0/0) in the incoming direction.

The log option will allow us to see the output logs on the console.

Let us apply this blocking access control list on the DMZ interface (FE 0/0) of the CBAC router:

Upon this command execution, the Windows 7 host can no longer tracert the FreeBSD server.

The CBAC-PAM router now shows that it is dropping the ICMP replies in their return path thanks to the access control list in place.

The same failure happens to ping test:

This is because of the same access control list denying everything.

The HTTP connection is now displaying a “connection timeout” page:

And the logs show it to:

Even SSH connectivity is no longer working:

Step 2

Creating and applying inspect rules on the DMZ interface (FE 0/0) in the outgoing direction will restore connectivity for specific chosen traffic.

Let’s create inspect rule:

And apply it to the DMZ interface (FE 0/0) of the CBAC-PAM router in the outgoing direction.

Now that traffic inspection for HTTP has been configured and applied to the DMZ interface in the outgoing direction, the web browser on Windows 7 can display the web page again:

The inspect rule to re-establish SSH connectivity follows:

We re-establish ICMP connectivity by including ICMP in the list of inspected protocols:

Now the ping tests work again because inspecting ICMP traffic opens gates for returning traceroute replies flows.

In previous CBAC tutorials [“CISCO IOS FIREWALL (STATEFUL) – Context-Based Access Control (CBAC) – Part II“.], the traceroute source was a Cisco router and inspecting ICMP didn’t allow these ICMP replies through because the traceroute probes were in TCP and the inspection engine denied the replies because it was seeing TCP probes and ICMP replies. In our case, the Windows 7 host is now sending ICMP probes and the ICMP replies are recognized by the inspection engine as matching the probes and therefore the tracert command is successful.

For now, the Windows 7 host can do ping and tracert tests to the FreeBSD server again. The same goes for browsing and SSH-ing into the server.

Port to Application Mapping

In the previous section we configured the Context Based Access Control feature to inspect traffic and dynamically create temporary access control lists that allow returning flows of the specific inspected traffic and block everything else not explicitly allowed. The commands to set up the inspect rules did mention the protocol/application to inspect as you can see below:

Because the router had a system-defined PAM table listing applications and their ports, the router knew how to find out which port number to inspect. In this example, the router knows through the system-defined PAM table that HTTP listens on port number 80. If the system administrator chooses to move the Apache server to port 8000, let’s say, the router will keep inspecting port 80 while informed users will be trying to connect to port 8000 ( therefore their returning traffic will be rejected by the CBAC router because it is a return traffic for an un-inspected port.

The following shows the administrator of the FreeBSD server moving the Apache server from port 80 to port 8000:

Suddenly, the Windows 7 host can’t find the HTTP server on port 80:

Connecting to times out because the inspection engine doesn’t know port 8000 to be carrying HTTP traffic as by default port 80 carries HTTP.

The CBAC-PAM router’s logs show that return traffic from port 8000 was denied by the inspection engine.

That’s because the engine inspected HTTP on port 80 and sees return traffic for port 8000 as an unsolicited traffic.

To fix this we are going to indicate port 8000 as a valid port for HTTP traffic.

The following show command shows that 8000 and 80 are now recognized as HTTP ports.

It is advised not to map an application to a port already paired with another application on the PAM table by a system-defined mapping. Trying to map HTTP to any port lower than 1024 will yield an error message.

A single application/protocol can well be mapped to several consecutive ports.

We can also get specific and allow these ports only in their TCP occurrence since we know that HTTP used TCP as the transport protocol.

If at the same time the Apache web server on the FreeBSD server is configured with the same ports listening for connections:

The web browser on the Windows 7 host will be able to access the same web page through six different ports:

Port 80 [default]

Port 8000

Port 8001

Port 8002

Port 8003

Port 8004

The port to application mapping we have configured at this point in time is a blanket mapping whatever the destination server. This means that if, for example, there are four servers behind the CBAC-PAM router, the latter will apply the same inspection rules to the same ports on all flows going to all four servers. The CBAC-PAM router will be assuming that on all four servers HTTP is on the same ports.

We can however use access control lists to map specific ports to specific applications on specific hosts for a more granular mapping.

The HTTP server can be on port 8000 on the IP address and on port 8100 on the IP address The inspection engine then needs to be configured accordingly. For that we use access control lists to segregate which server the rule applies to.


An access control list to select server

And a port-map command to bind port 8000 to HTTP:

The same is repeated for server

As seen in previous sections, when access control lists are not used to select individual hosts, the mapping is somehow a blanket mapping and no application can be mapped to a well-known port number like 53 [DNS].

On the contrary, when access control lists are used to distinguish specific hosts, an application can be mapped to a well-known port like 53 since this mapping will stay local to a specific host as opposed to a blanket mapping as seen earlier.

The above command, combined with the two previous above, will ensure that HTTP can also be found on port 53 that was reserved for DNS. This implies that on the specific host, port 53 is now booked for HTTP and if ever a DNS server was to be run on that IP address, it will have to listen on a different port.

As this tutorial draws to an end, I can’t help but point out how adding this access control list feature to the port-map command takes the PAM feature to a whole new level of granularity.