Generating a Server Host Table File cp3

Generating a Server Host Table File

Problem

You want to build a detailed host file containing the IP addresses and interface names of all of your routers.

Solution

The Perl script in Example 2-4, host.pl, builds a detailed host table that includes all of the IP addresses on each router in a list of devices. The script is written in Perl and requires NET-SNMP to extract data from the router list. No arguments are expected or required.

Example 2-4. host.pl

#!/usr/local/bin/perl
#
# host.pl -- a script to build a detailed host file from
# information gathered from a router list.
#
#Set behavour
$workingdir="/home/cisco/net";
$snmpro="ORARO";
#
$rtrlist="$workingdir/RTR_LIST";
$snmpwalk="/usr/local/bin/snmpwalk -v 1 -c $snmpro";
$snmpget="/usr/local/bin/snmpget -v 1 -c $snmpro";
open (RTR, "$rtrlist") || die "Can't open $rtrlist file";
open (RESULT, ">$workingdir/RESULT") || die "Can't open RESULT file";
while () {
chomp($rtr="$_");
@ifIndex=\Q$snmpwalk $rtr ipAdEntIfIndex\Q;
@ipAddress=\Q$snmpwalk $rtr ipAdEntAddr\Q;
$rtr1=\Q$snmpget $rtr .1.3.6.1.4.1.9.2.1.3.0\Q;
chomp(($foo, $RTR) = split (/"/, $rtr1));
$arraynum=0;
for $ifnumber (@ifIndex) {
chomp(($foo, $ifnum) = split(/= /, $ifnumber));
$ifDescription=\Q$snmpget $rtr ifName.$ifnum\Q;
chomp(($foo, $ipaddr) = split(/: /, $ipAddress[$arraynum]));
chomp(($foo, $ifdes) = split(/= /, $ifDescription));
$name="$RTR-$ifdes";
#$name=~s/\//-/;
if ( $ifdes eq "Lo0" ) { $name=$RTR };
print RESULT "$ipaddr\t\t$name\n";
$arraynum++;
}
}
close(RTR);
close(RESULT);

Discussion

Most organizations manually build a host table for their management server(s) with a single IP entry per router, usually the loopback IP address. This script automatically builds a host file that contains all known IP addresses for each router.

Here is an example of the output from the host.pl script:

10.1.1.1                miami-Se0/0
10.2.2.2 miami
172.20.6.8 miami-Se0/2
172.22.1.4 miami-Fa1/0
172.25.1.8 miami-Et0/0
10.1.1.2 toronto-Se0/1
172.20.1.1 toronto-Se0/0.2
172.22.1.1 toronto-Fa0/1
172.25.1.5 toronto-Fa0/0.1
172.25.2.1 toronto-Se0/0.1
172.25.25.1 toronto
172.25.26.5 toronto-Lo1
10.1.99.55 detroit-BR0
172.25.3.7 detroit-Et0
172.25.25.6 detroit
172.20.1.2 boston-Se0.1
172.20.10.1 boston-Et0
172.20.100.1 boston

This output is in the format required for a Unix /etc/hosts file. The script extracts the IP address information via SNMP, and then associates each address with the related router name and interface. The script also automatically creates a primary host entry for each router using the address of the loopback0 interface, but with no interface information in the hostname. So, in this example, you can reach the router located in Boston with hostname boston rather than the less intuitive boston-Lo0.

Having a detailed host file is useful for many reasons. Sometimes the router will send a message to your server, either using SNMP or Syslog, and use the IP address of the interface instead of a main loopback interface. Also, having a detailed host file makes the output of a traceroute much easier to understand:

Freebsd% traceroute miami
traceroute to miami (10.2.2.2), 64 hops max, 52 byte packets
1 detroit-Et0 (172.25.3.7) 2.263 ms 2.210 ms 2.178 ms
2 toronto-Fa0/0.1 (172.25.1.5) 3.042 ms 3.060 ms 3.846 ms
3 boston-Se0.1 (172.20.1.2) 8.234 ms 8.245 ms 8.145 ms
4 miami-Se0/2 (172.20.6.8) 9.893 ms 9.893 ms 9.432 ms
Freebsd%

This makes it much easier to decipher the path between the management station and the Miami router. Not only can we tell which routers lie along the path, but we can also clearly see which interfaces a packet sent along this path will use.

The script does not update the /etc/hosts file directly. You may need to manually import the script's output file into your system's /etc/hosts file. However, you can make this task easier by building a master file containing your normal host information and concatenating this master file together with the script output. This way you could even use the cron utility to automatically run this script and create a new up-to-date host file on a nightly basis.

Before the script will work, you must modify two variables. The $workingdir variable must be set to the directory that you will launch the script from. The $snmpro variable must be set to your SNMP read-only community string. The script assumes that you use the same read-only community string on all of your routers.

The script reads through a router list, and queries each device in sequence. It expects to find this list in a file called RTR_LIST in the working directory. The list can contain router names or IP addresses, with one entry per router, and one router per line. The script will extract the hostname directly from the router, so you should also ensure that all of your routers are configured with unique hostnames. The results of the script are stored in a file called RESULT, contained in the working directory.

As a final note, we should mention that this script can generate hostnames that do not confirm to RFC 952, "DOD INTERNET HOST TABLE SPECIFICATION," which defines the official rules for hostnames. This is because the script can create hostnames with a "/" character in them, such as miami-Se0/2. This may cause problems for some applications, particularly if they use URL format addressing. For example, a query to http://miami-Se0/2 will clearly cause problems because the last character, 2, will be interpreted as a filename. However, most common applications, such as ping and Telnet, will accept this hostname without any complaints.

If you are a purist, or if you have applications that complain about these hostnames, we've included a line in the script that you can use to convert all of the slashes, "/", to dashes, "-". This line is currently commented out, but you can invoke it by simply removing the comment character, "#", to change this line:

#$name=~s/\//-/;

to this:

$name=~s/\//-/;

See Also

Generating a Report of ARP Table Information

Generating a Report of ARP Table Information

Problem

You need to extract the ARP table from one of your routers to determine the MAC address associated with a particular IP address or the IP address for a particular MAC address.

Solution

The script in Example 2-3, arpt.pl, extracts the ARP table for a specified router or IP address and displays the results to standard output. The script expects to find a hostname or IP address of a router on the command line.

Example 2-3. arpt.pl

#!/usr/local/bin/perl
#
# arpt.pl -- a script to extract the ARP cache from a router.
#
#Set behavour
$snmpro="ORARO";
#
$snmpwalk="/usr/local/bin/snmpwalk -v 1 -c $snmpro";
$snmpget="/usr/local/bin/snmpget -v 1 -c $snmpro";
chomp ($rtr=$ARGV[0]);
if ( $rtr eq "" ) {die "$0: Must specify a router \n"};
@iftable=\Q$snmpwalk $rtr ifDescr\Q;
for $ifnum (@iftable) {
chomp (($intno, $intname) = split (/ = /, $ifnum));
$intno=~s/.*ifDescr\.//;
$intname=~s/"//gi;
$arpint{$intno}=$intname;
}
printf ("%-22.22s %-10.10s %-25.25s\n", Address, MAC, Interface);
@atTable=\Q$snmpwalk $rtr .1.3.6.1.2.1.3.1.1.1\Q;
for $atnum (@atTable) {
chomp (($atip, $atint) = split (/ = /, $atnum));
$atip =~ s/.*atIfIndex\.[0-9]+\.1\.//;
$atphys=\Q$snmpget $rtr atPhysAddress.$atint.1.$atip\Q;
chomp(($foo, $phys) = split(/: /, $atphys));
$phys=~s/ /-/gi; chop ($phys);
$phys=~tr/A-Z/a-z/;
$int=$arpint{$atint};
printf ("%-15.15s %17.17s %-25.25s\n", $atip, $phys, $int);
}

Discussion

The arpt.pl script extracts the ARP table from a specific router using SNMP and displays it to standard output. The script requires Perl and NET-SNMP, and it expects to find both in the /usr/local/bin directory. For more information on Perl or NET-SNMP, please see Appendix A.

Before using the script, you need to set the SNMP read-only community string, which is contained in the variable $snmpro:

Freebsd% ./arpt.pl toronto
Address MAC Interface
172.22.1.1 00-01-96-70-b7-81 FastEthernet0/1
172.22.1.2 00-01-96-70-b7-81 FastEthernet0/1
172.22.1.3 00-01-96-70-b7-81 FastEthernet0/1
172.25.1.1 00-10-4b-09-57-00 FastEthernet0/0.1
172.25.1.5 00-01-96-70-b7-80 FastEthernet0/0.1
172.25.1.7 00-00-0c-92-bc-6a FastEthernet0/0.1
172.25.1.254 00-00-0c-07-ac-01 FastEthernet0/0.1
172.16.2.1 00-01-96-70-b7-80 FastEthernet0/0.2
172.16.2.22 00-00-0c-07-ac-00 FastEthernet0/0.2
Freebsd%

The script creates a simple report, including the IP address, MAC address, and interface name of each ARP entry. You can then use a search utility of some kind to locate specific devices by its IP or MAC address. For example, on a Unix server, you could pipe the output to the grep command, as follows:

Freebsd% ./arpt.pl toronto | grep 172.25.1.5
172.25.1.5 00-01-96-70-b7-80 FastEthernet0/0.1
Freebsd%

The ARP tables on large routers can be quite large, which can make locating a single ARP entry difficult. This script allows you to track down a particular device remotely. You could also use the grep utility to find the IP address of a particular known MAC address:

Freebsd% ./arpt.pl toronto | grep 00-10-4b-09-57-15
172.25.1.3 00-10-4b-09-57-15 FastEthernet0/0.1
Freebsd%

This script only queries open standard SNMP MIBS, so you can use it to extract ARP table information from almost any SNMP enabled device, even nonCisco equipment.

See Also

Generating a Report of Routing Table Information

Generating a Report of Routing Table Information

Problem

You need to extract the IP routing table from one of your routers.

Solution

The script in Example 2-2, rt.pl, uses SNMP to extract the routing table from a specified router, and displays this information to standard output (STDOUT). The script expects to find a hostname or IP address of a router on the command line.

Example 2-2. rt.pl

#!/usr/bin/perl
#
# rt.pl -- a script to extract the routing table
# from a router.
#
#Set behavior
$snmpro="ORARO";
#
$x=0;
$snmpwalk="/usr/local/bin/snmpwalk -v 1 -c $snmpro";
$snmpget="/usr/local/bin/snmpget -v 1 -c $snmpro";
chomp ($rtr=$ARGV[0]);
if ( $rtr eq "" ) {die "$0: Must specify a router\n"};
print "Destination\tMask\t\tNexthop";
print "\t\t Proto\tInterface\n";
@iftable=\Q$snmpwalk $rtr ifDescr\Q;
for $ifnum (@iftable) {
chomp (($intno, $intname) = split (/ = /, $ifnum));
$intno=~s/.*ifDescr\.//;
$intname=~s/"//gi;
$int{$intno}=$intname;
}
@ipRouteDest=\Q$snmpwalk $rtr ipRouteDest\Q;
@ipRouteMask=\Q$snmpwalk $rtr ipRouteMask\Q;
@ipRouteNextHop=\Q$snmpwalk $rtr ipRouteNextHop\Q;
@ipRouteProto=\Q$snmpwalk $rtr ipRouteProto\Q;
@ipRouteIfIndex=\Q$snmpwalk $rtr ipRouteIfIndex\Q;
#@ipRouteMetric1=\Q$snmpwalk $rtr ipRouteMetric1\Q;
for $intnum (@ipRouteIfIndex) {
chomp (($foo, $int) = split (/= /, $intnum));
chomp (($foo, $dest) = split (/: /, @ipRouteDest[$x]));
chomp (($foo, $mask) = split (/: /, @ipRouteMask[$x]));
chomp (($foo, $nhop) = split (/: /, @ipRouteNextHop[$x]));
chomp (($foo, $prot) = split (/= /, @ipRouteProto[$x]));
#chomp (($foo, $metr) = split (/= /, @ipRouteMetric1[$x]));
$int1 = $int{$int};
if ($int1 eq '') {$int1="Local"};
$prot=~s/\(.*//; $prot=~s/ciscoIgrp/\(e\)igrp/;
printf ("%-15s %-15s %-15s %7s %-25s\n",$dest, $mask, $nhop, $prot, $int1);
$x++
}

Discussion

The rt.pl script is written in Perl and uses NET-SNMP to extract the routing table information via SNMP. It expects to find both Perl and NET-SNMP in the /usr/local/bin directory. For more information on Perl or NET-SNMP, please see Appendix A.

Before using the script, you must define the variable $snmpro to contain the SNMP read-only community string for the router:

Freebsd% ./rt.pl toronto
Destination Mask Nexthop Proto Interface
10.1.1.0 255.255.255.252 172.25.1.5 ospf Ethernet0
10.2.2.2 255.255.255.255 172.25.1.5 ospf Ethernet0
172.16.2.0 255.255.255.0 172.25.1.5 ospf Ethernet0
172.20.0.0 255.255.0.0 172.25.1.5 local Local
172.20.1.0 255.255.255.252 172.25.1.5 ospf Ethernet0
172.20.10.0 255.255.255.0 172.25.1.5 ospf Ethernet0
172.20.100.1 255.255.255.255 172.25.1.5 ospf Ethernet0
172.22.0.0 255.255.0.0 172.25.1.5 (e)igrp Ethernet0
172.22.1.0 255.255.255.0 172.25.1.5 ospf Ethernet0
172.25.1.0 255.255.255.0 172.25.1.7 local Ethernet0
172.25.2.0 255.255.255.252 172.25.1.5 (e)igrp Ethernet0
172.25.25.1 255.255.255.255 172.25.1.5 (e)igrp Ethernet0
172.25.25.6 255.255.255.255 172.25.25.6 local Loopback0
172.25.26.4 255.255.255.252 172.25.1.5 (e)igrp Ethernet0
172.25.26.5 255.255.255.255 172.25.1.5 ospf Ethernet0
Freebsd%

The output from the script is relatively straightforward, except for static routes and directly connected routes, which require a little explanation.

For static routes, the output shows a value of local in the protocol field, and an interface name of Local. Directly connected routes also appear as local protocol information, but the interface name is the real interface associated with this route.

For example, the route 172.20.0.0 255.255.0.0 is a static route:

172.20.0.0      255.255.0.0     172.25.1.5        local Local                    

And 172.25.1.0 255.255.255.0 is a directly connected route:

172.25.1.0      255.255.255.0   172.25.1.7        local Ethernet0                

Since this script queries only open standard SNMP MIB values, you can use it to extract IP route information from most any SNMP-enabled device, including nonCisco equipment.

See Also

Generating a Report of Interface Information

Generating a Report of Interface Information
Problem
You want to build a spreadsheet of active IP subnets for your network.

Solution
Keeping track of assigned IP subnets on a network is a vitally important, but often tedious, task. In large organizations, it can be extremely difficult to maintain accurate and up-to-date addressing information. The Perl script in Example 2-1 uses SNMP to automatically gather current IP subnet information directly from the routers themselves. The script creates an output file in CSV format so you can easily import the information into a spreadsheet.

Example 2-1. netstat.pl
#!/usr/local/bin/perl
#
# netstat.pl -- a script to build a detailed IP interface
# listing directly from a list of routers.
#
#Set behavour
$workingdir="/home/cisco/net";
$snmpro="ORARO";
#
$rtrlist="$workingdir/RTR_LIST";
$snmpwalk="/usr/local/bin/snmpwalk -v 1 -c $snmpro";
$snmpget="/usr/local/bin/snmpget -v 1 -c $snmpro";
open (RTR, "$rtrlist") || die "Can't open $rtrlist file";
open (CSV, ">$workingdir/RESULT.csv") || die "Can't open RESULT.csv file";
while () {
chomp($rtr="$_");
@ifIndex=\Q$snmpwalk $rtr .1.3.6.1.2.1.4.20.1.2\Q;
@ipAddress=\Q$snmpwalk $rtr .1.3.6.1.2.1.4.20.1.1\Q;
@ipMask=\Q$snmpwalk $rtr .1.3.6.1.2.1.4.20.1.3\Q;
$arraynum=0;
print CSV "\n$rtr\n";
print CSV "Interface, IP-Address, Mask, MTU, Speed, Admin, Operational\n";
for $ifnumber (@ifIndex) {
chomp(($foo, $ifnum) = split(/= /, $ifnumber));
$ifDescription=\Q$snmpget $rtr ifDescr.$ifnum\Q;
$ifMTU=\Q$snmpget $rtr ifMtu.$ifnum\Q;
$ifSpeed=\Q$snmpget $rtr ifSpeed.$ifnum\Q;
$ifAdminstatus=\Q$snmpget $rtr ifAdminStatus.$ifnum\Q;
$ifOperstatus=\Q$snmpget $rtr ifOperStatus.$ifnum\Q;
chomp(($foo, $ipaddr) = split(/: /, $ipAddress[$arraynum]));
chomp(($foo, $mask) = split(/: /, $ipMask[$arraynum]));
chomp(($foo, $ifdes, $foo) = split(/"/, $ifDescription));
chomp(($foo, $mtu) = split (/= /, $ifMTU));
chomp(($foo, $speed) = split (/: /, $ifSpeed));
chomp(($foo, $admin) = split (/= /, $ifAdminstatus));
chomp(($foo, $oper) = split (/= /, $ifOperstatus));
if ( $speed > 3194967295 ) { $speed = 0 };
$admin =~ s/\(.*\)//;
$oper =~ s/\(.*\)//;
if ( $oper eq "dormant" ) { $oper = "up(spoofing)"};
$speed = $speed/1000;
if ( $speed > 1000) {
$speed = $speed/1000;
$speed =~ s/$/ Mb\/s/;
}
else {
$speed =~ s/$/ Kb\/s/;
}
print CSV "$ifdes,$ipaddr,$mask,$mtu,$speed,$admin,$oper\n";
$arraynum++;
}
}
close(RTR);
close(CSV);




Discussion
The netstat.pl script uses SNMP to gather IP subnet information from a list of routers. This ensures that the information is accurate and current. The script gathers all of the pertinent information about each router's IP interfaces and outputs this information as a CSV file.

The netstat.pl script requires Perl and NET-SNMP and expects to find both in the /usr/local/bin directory. For more information on Perl or NET-SNMP, please see Appendix A. If you keep these programs in a different location, you will need to modify the script appropriately.

Before using the script, you must define two variables, $workingdir and $snmpro. The $workingdir variable must contain the name of directory where you will store the script and its input and output files. The variable, $snmpro must contain the SNMP read-only community string for your routers. The script assumes that the same community string is valid on all devices.

The script systematically queries each router in a list, one after another. It expects to find this list in a file called RTR_LIST, located in the working directory. This router list should contain a single router name or IP address on each line with no comments or other information included. The results of the script will be stored in a file called RESULT.csv, also located in the working directory.

You can then import the RESULT.csv file into a spreadsheet. The results will look similar to the example report shown in Table 2-3.

Table 2-3. An example output of the netstat.pl script Detroit
Interface IP-Address Mask MTU Speed Admin Oper
Serial0/0 10.1.1.1 255.255.255.252 1,500 768 Kb/s up up
Loopback0 10.2.2.2 255.255.255.252 1,514 0 Kb/s up up
FastEthernet1/0 172.22.1.4 255.255.255.0 1,500 100 Mb/s up up
Ethernet0/0 172.25.1.8 255.255.255.0 1500 10Mb/s down down
BRI0 10.1.99.55 255.255.255.0 1500 64 Kb/s down down
Ethernet0 172.25.1.7 255.255.255.0 1500 10 Mb/s up up
Loopback0 172.25.25.6 255.255.255.255 1514 0 Mb/s up up
Boston
Interface IP-Address Mask MTU Speed Admin Oper
Serial0.1 172.20.1.2 255.255.255.252 0 28 Kb/s up up
Ethernet0 172.20.10.1 255.255.255.0 1500 10 Mb/s up up
Loopback0 172.20.100.1 255.255.255.255 1514 0 Mb/s up up




The script captures information about every interface that has been configured with an IP address. This includes interfaces that are administratively or operationally down, loopback interfaces, HSRP addresses, and IP unnumbered interfaces. The script will not display any interfaces or sub interfaces that are not configured for IP.

As a side benefit, this script uses only open standard SNMP MIBs. So you can use it to extract IP interface information from almost any SNMP-enabled device, including nonCisco equipment.

See Also

Creating Exception Dump Files

Creating Exception Dump Files

Problem

Your router is having serious problems and you need to create an exception dump to forward to Cisco's TAC.

Solution

To create an exception dump of a router's memory after a failure, you need to configure the exception dump command, as well as telling the router how automatically transfer this information to a server:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#ip ftp source-interface Loopback0
Router1(config)#ip ftp username ijbrown
Router1(config)#ip ftp password ijpassword
Router1(config)#exception protocol ftp
Router1(config)#exception region-size 65536
Router1(config)#exception dump 172.25.1.3
Router1(config)#end
Router1#

Discussion

This is the one recipe in this book that we hope none of our readers ever need to use. The main reason for creating an exception dump of your router memory contents is to help Cisco's TAC in diagnosing catastrophic software problems with one of your routers. When you have these types of extreme problems, however, the TAC will often ask to do an exception dump on the router. So we have included this recipe so that you'll know what to do if it ever becomes necessary.

An exception dump is a snapshot of the router's memory contents taken just before a software error forces the router to reload. The router has to transfer this information to a server because it is too much information to store in nonvolatile storage.

The dump actually creates two files, one of the main system memory and one of the IO memory. The software engineers at Cisco can then use these two files to figure out what caused the software failure and hopefully create a fix for the next IOS release.

By default, the router will use TFTP to transfer the dump files. However, we strongly recommend using FTP instead. If your router has more than 16 MB of memory, most TFTP applications will fail, so FTP is the only option. FTP is much more reliable than TFTP, and you don't want to have to repeat the process if the TAC tells you that the file was corrupted during transfer. Our example shows how to configure a router to use FTP to transfer the exception dump files from the router to the server. For more information on configuring the router to use FTP, please see Recipe 1.14.

Exception dumps are prone to fail because the router doesn't attempt them until it has suffered a serious software failure. This software failure could corrupt your router's memory, making any further processing impossible, even creating the exception dump. You can greatly increase the chances of a successful exception dump by dedicating a small amount of memory to serve as a backup memory pool in case the main memory becomes corrupted:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#exception region-size 65536
Router1(config)#end
Router1#

You can define how much memory the router should dedicate to creating exception dumps. The default is 16,384 bytes, but we recommend increasing this to the maximum value of 65,536 bytes. This will greatly increase the chances of a successful exception dump.

By default, the router creates two exception dump files named hostname-core and hostname-coreiomem. In our example, the router name is Router1, so the two files created will be called Router1-core and Router1-coreiomem. You can change the default naming convention of the core files with the exception core-file command:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#exception core-file router5 compress
Router1(config)#end
Router1#

You will notice that we have included the optional keyword called compress in this command. This option instructs the router to compress the core files before transferring them to the server. You can then uncompress the files on the server with the Unix uncompress command. We actually don't recommend using this feature, though, because it adds an extra CPU and memory load to a router that is already in trouble. Furthermore, we have found that this option doesn't seem to shrink the files enough to be useful. In some cases, it even causes the main core file to grow larger.

On the server side, you need to ensure that you have enough disk space to hold the two dump files. The size of these files will vary from router to router, depending on the amount of memory they contain. Expect the dump files to equal the total amount of memory installed in the router.

You can force the router to perform a core dump of its normal memory with the write core command. This command provides an excellent way to test whether everything is configured correctly before a catastrophic failure forces the real dump:

Router1#write core
Remote host [172.25.1.3]?
Base name of core files to write [Router1-core]?
Writing Router1-coreiomem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Writing Router1-core !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Router1#

When we display these files on the server, you can see that their combined sizes are 48 MB:

Freebsd% ls -la
drwxr-xr-x 3 ijbrown ijbrown 512 Feb 1 13:50 ./
drwxr-xr-x 5 root wheel 512 Feb 4 2002 ../
-rw-r--r-- 1 ijbrown ijbrown 46137344 Feb 1 13:54 Router1-core
-rw-r--r-- 1 ijbrown ijbrown 4194304 Feb 1 13:52 Router1-coreiomem
Freebsd%

To increase the chances of success, use a server that is as close as possible to the router. Time is of the essence during the creation of an exception dump, so forcing a router to write its core across a slow and congested WAN link decreases your chances of success.

See Also

Displaying Historical CPU Values

Displaying Historical CPU Values

Problem

You want to display the router's historical CPU utilization values.

Solution

To display the router's historical CPU values, use the show processes cpu history command:

Router# show processes cpu history

Router 03:48:18 PM Monday Apr 17 2006 EDT


555559999999999999999
5 444449999999999999999
100 ******************
90 ******************
80 ******************
70 ******************
60 ******************
50 ***********************
40 ***********************
30 ***********************
20 ***********************
10 * ***********************
0....5....1....1....2....2....3....3....4....4....5....5....
0 5 0 5 0 5 0 5 0 5
CPU% per second (last 60 seconds)

99 1 9999
99 1 4 9999
100 ** ***#*#
90 ** **##*#
80 #* *###*#
70 #* *###*#
60 #* *###*#
50 #* *#####
40 #* *#####
30 #* ######
20 ## ######
10 ## * ######
0....5....1....1....2....2....3....3....4....4....5....5....
0 5 0 5 0 5 0 5 0 5
CPU% per minute (last 60 minutes)
* = maximum CPU% # = average CPU%
11
9111 111 121 1 121 131009 111111 11 112 1111 12 21 1111 1 11 2221
9113776097349362207994009990236246707314992025700880288101471605900356
100 * ***
90 * ***
80 * ***
70 * ***
60 * ***
50 * ***
40 * * ***
30 * * *** *
20 * ** ** * ** *** * * * * * * * **** *
10 #***********************************************************************
0....5....1....1....2....2....3....3....4....4....5....5....6....6....7.
0 5 0 5 0 5 0 5 0 5 0 5 0
CPU% per hour (last 72 hours)
* = maximum CPU% # = average CPU%

Router#

Cisco added the history keyword to the show processes cpu command in 12.2(2)T. The history keyword displays the historical CPU values in graph form consisting of three panes: one second, one minute, and one hour increments. In total, the router keeps 72 hours worth of historical CPU values.

Discussion

Traditionally, the router would only display up to 5 minutes worth of CPU utilization history via the show processes cpu command. With the introduction of the history keyword, the router maintains 72 hours worth of CPU utilization history.

Initially the graph output of this command can be confusing, but once you understand the layout and calculations behind the three graphs, you will find the output to be quite efficient.

The top-most graph is the one second pane, which graphs the real-time CPU utilization once a second. As with all three graphs, the most recent statistics appear at the left side of the graph and gradually move to the right as they age out. In all, the router displays 60 one second snapshots of the router CPU utilization before moving to the next graph down.

The middle graph displays the one-minute CPU utilization average as well as the peak CPU value reached during that minute. The average utilization is graphed using the "#" symbol and the peak utilization during the minute is graphed using the "*" symbol. More about the graphing symbols shortly. The number at the top of each column indicates the actual peak reached during the minute. It's important to point out that the peak value may have been reached once or multiple times during the minute.

The bottom graph displays the CPU average and peak utilization values reached during the hour. This graph maintains 72 values, or 3 days worth of data, before the router refreshes the data. Values older than this 72 hour limit are lost forever.

Let's take a closer look at the graphic representation of the CPU data and explain how the graphs are displayed:

               CPU% per second (last 60 seconds)

99 1 9999
98 1 4 9999
100 ** ***#*#
90 ** **##*#
80 #* *###*#
70 #* *###*#
60 #* *###*#
50 #* *#####
40 #* *#####
30 #* ######
20 ## ######
10 ## * ######
0....5....1....1....2....2....3....3....4....4....5....5....
0 5 0 5 0 5 0 5 0 5
CPU% per minute (last 60 minutes)
* = maximum CPU% # = average CPU%

In this example, we've displayed only the middle graph, the one minute interval graph, for demonstration purposes. The numbers at the far left of the graph indicate CPU utilization and the numbers across the bottom of the graph indicate time, in minutes. As we mentioned earlier, the value at the left-most column is the most recent data, and it gradually moves to the right each minute.

At the top of the left-most column is a number written vertically, indicating the true peak value during the one minute interval. In this case, the peak CPU utilization was 99 percent. The text-based graph also represents the peak utilization using the " *" symbol.

On the same column, the average CPU utilization for the minute is graphed using the " #" symbol. Keep in mind that the graph is plus or minus 5 percent accurate, meaning in this example the average utilization for the minute was between 75 percent and 84 percent.

We would like to be able to offer useful rules of thumb about what CPU utilization values are acceptable and what values start to cause network perfomance problems. Unfortunately, this isn't really possible. How well your router copes with a high CPU utilization depends on many factors, including the specific hardware platform, the use of routing optimizations like CEF, and most importantly, on what specifically is causing the high CPU load. For example, high-end modular routers like the 7600 distribute most routine packet-forwarding fuctions to the media modules. So a high CPU load may not have an effect on real network performance. The best advice we can offer is to watch your routers and try to establish a rough baseline for what CPU load values are normal.

The history keyword allows you to quickly glance at the 3 graphs and get a good overall understanding of the CPU utilization over the past 72 hours. Sometimes a five-minute average just isn't sufficient to understand the health of the router's CPU. You will find this command very useful.

Scheduling of Router Commands

Scheduling of Router Commands

Problem

You want to issue a command for the router to execute at regularly scheduled times.

Solution

Use the router's Kron facility to execute commands at regularly scheduled intervals:

Router#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#kron policy-list OREILLY
Router(config-kron-policy)#cli write memory
Router(config-kron-policy)#exit
Router(config)#kron occurrence DAILYat5 at 17:00 recurring
Router(config-kron-occurrence)#policy-list OREILLY
Router(config-kron-occurrence)#end
Router#

Cisco first introduced the Kron facility in IOS Version 12.3(1).

It is highly recommended that you configure the router with an accurate time source such as NTP or SNTP before configuring the Kron facilities, as it requires an accurate clock to work correctly. See Chapter 14 for more information on NTP and SNTP.


Discussion

The Cisco Kron facility is similar to the Unix Cron facility in that it allows you to schedule commands to be executed at regular intervals. In essence, it allows you to automate certain administrative functions that the router administrator would otherwise have to perform manually. Of course the major advantage is that once configured correctly, the Kron facility issues the commands at the exact time required and without the chance of typos. In addition, it does not require the administrator be present when the commands are run, which is important, especially in organizations with large numbers of routers.

Let's take a closer look at the configuration of the Kron facility. In the example provided, we have configured the Kron facility to automatically save the configuration to NVRAM each day at 17:00 (5:00PM). First, we configured the kron policy-list and named it "OREILLY" and included the single CLI command "write memory." We then configured the kron occurrence named "DAILYat5" and set the launch time to 17:00. The keyword recurring is required to ensure that the Kron occurrence launches each day as opposed to a single instance. Once the Kron occurrence was configured, then we defined which Kron policies where to be invoked. Note that you can launch more than one Kron policy per occurrence, as shown in the next example:

Router#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#kron occurrence DAILYat5 at 17:00 recurring
Router(config-kron-occurrence)#policy-list OREILLY
Router(config-kron-occurrence)#policy-list TEST
Router(config-kron-occurrence)#end
Router#

In this example, we have configured two Kron policies to launch via the same Kron occurrence. This means that each day at 17:00 the router will launch both policies.

As with the Unix Cron facility, you can schedule Kron occurrences to run every minute of the hour, once a year, or anywhere in between. To schedule a Kron occurrence to launch every hour, use the in keyword in conjunction with the recurring keyword:

Router#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#kron occurrence Hourly in 60 recurring
Router(config-kron-occurrence)#policy-list TEST
Router(config-kron-occurrence)#end
Router#

The Kron facility will now launch the Kron occurrence "Hourly" every 60 minutes. To launch a Kron facility once a year, use the following configuration:

Router#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#kron occurrence Yearly at 00:00 Jan 1 recurring
Router(config-kron-occurrence)#policy-list TEST
Router(config-kron-occurrence)#end
Router#

Unfortunately, there are some rather annoying limitations to the Kron facility. First of all, only EXEC level commands can be issued by the Kron facility, meaning that no configuration-based commands can be issued. Second, the Kron facility won't work with interactive-based EXEC commands, meaning commands that prompt you to verify the command. For instance, in the initial example we issued the CLI command write memory instead of copy running-config startup-config because the write command does not prompt to verify the action whereas the copy command does.

Some potentially useful uses for the Kron facility are saving the configuration to NVRAM, disabling all debug commands, clearing a particular interface, issuing a ping command to keep up a tunnel, etc.

You can view the scheduled Kron occurrences by using the show kron schedule command:

Core#show kron schedule
Kron Occurrence Schedule
DAILYat5 inactive, will run again in 0 days 05:40:54 at 17:00 on

Core#

You can see that the router will launch the Kron occurrence "DAILYat5" in 5 hours and 40 minutes.

See Also

Specifying a Router Reload Time

Specifying a Router Reload Time

Problem

You want to set the router to automatically reload at a specified time.

Solution

You can set the router to reload after waiting a particular length of time with the reload in command:

Router1#reload in 20
Reload scheduled for 11:33:53 EST Sat Feb 1 2003 (in 20 minutes)
Proceed with reload? [confirm]
Router1#

The reload at command lets you specify a particular time and date when you want the router to reload:

Router1#reload at 14:00 Feb 2 
Reload scheduled for 14:00:00 EST Sun Feb 2 2003 (in 26 hours and 44 minutes)
Proceed with reload? [confirm]
Router1#

If you set the router to reload at a specific time and date, then we highly recommend using an accurate time source to ensure that the router reloads when you think it will. For more information on time and time sources, please see Chapter 14.

Discussion

Usually, when you reload a router, you want it to do so immediately. However, it can also be quite useful to specify a particular time to reload. For instance, reloading is the only way to fix badly fragmented memory on a router. But you almost certainly don't want to reload during production hours. This feature thus allows you to instruct the router to reload at a safe low-traffic time, such as the middle of the night.

Another excellent reason for using this delayed reload feature is to avoid locking yourself out of a router while making possibly dangerous configuration changes. There are many types of configurations changes, such as changes to access lists or routing configuration in particular, that can isolate a router and prevent you from getting back in to fix the problem. But before you make the changes, you can instruct the router to reload itself in, say, 15 minutes. If you lock yourself out of the router, you won't be able to save the running configuration to NVRAM. So when the router reloads, it will come up with the previous configuration. The bad configuration change will be miraculously undone.

And if it turns out that the new configuration is good, you can simply save it to NVRAM and cancel the reload. We show how to cancel a scheduled reload in a moment.

The reload in command also allows you to specify a reason for the reload:

Router1#reload in 1:20 IOS Upgrade
Reload scheduled for 12:37:45 EST Sat Feb 1 2003 (in 1 hour and 20 minutes)
Reload reason: IOS Upgrade
Proceed with reload? [confirm]
Router1#

The command interprets any text that you enter after the reload time as the reason for reloading. Starting in IOS Version 12.2, the router records a log message whenever you issue the reload command. Included in this message are the time that the reload was requested, the reload time, the username of the person who requested it, and the reload reason:

Feb  1 11:17:47: %SYS-5-SCHEDULED_RELOAD: Reload requested for 12:37:45 EST Sat Feb 1 2003 at 11:17:45 EST Sat Feb 1 2003 by ijbrown on vty0 (172.25.1.1). Reload Reason: IOS Upgrade.

You can also include a reason with the reload at command:

Router1#reload at 23:20 Feb 15 IOS Upgrade
Reload scheduled for 23:20:00 EST Sat Feb 15 2003 (in 124 hours and 48 minutes)
Reload reason: IOS Upgrade
Proceed with reload? [confirm]
Router1#

The show reload command displays information on any impending reloads:

Router1#show reload
Reload scheduled for 12:37:45 EST Sat Feb 1 2003 (in 1 hour and 19 minutes) by ijbrown on vty0 (172.25.1.1)
Reload reason: IOS Upgrade
Router1#

You can cancel a scheduled reload with the reload cancel command:

Router1#reload cancel
Router1#

***
*** --- SHUTDOWN ABORTED ---
***

When you cancel a reload like this, the router will send a system broadcast message notifying any active users that the reload has been canceled. Starting with IOS Version 12.2, the router also creates a logging message indicating that someone has canceled a scheduled reload:

Feb  1 11:19:10: %SYS-5-SCHEDULED_RELOAD_CANCELLED:  Scheduled reload cancelled at 11:19:10 EST Sat Feb 1 2003
Router1#

If you have scheduled a reload, the router will periodically send broadcast notices to all active users as a reminder. By default, the router will send these messages 1 hour before reload, 30 minutes before, 5 minutes before, and 1 minute before reload. You can cancel the reload at any time, up until the router actually shuts itself down:

Router1#


***
*** --- SHUTDOWN in 1:00:00 ---
***


***
*** --- SHUTDOWN in 0:30:00 ---
***


***
*** --- SHUTDOWN in 0:05:00 ---
***


***
*** --- SHUTDOWN in 0:01:00 ---
***
Connection closed by foreign host.

See Also

Disabling Domain Name Lookups

Disabling Domain Name Lookups

Problem

You want to prevent your router from trying to connect to your typing errors.

Solution

To prevent the router from attempting to resolve typing errors, use the no ip domain-lookup command:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#no ip domain-lookup
Router1(config)#end
Router1#

You can also prevent the router from trying to resolve typing errors on routers that use DNS by changing the default EXEC behavior for unknown commands:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#line vty 0 4
Router1(config-line)#transport preferred none
Router1(config-line)#end
Router1#

Discussion

As we mentioned in Recipe 2.11, routers attempts to resolve all hostnames by using DNS by default. Unfortunately, if you don't configure a valid DNS nameserver, the router sends these queries to the local broadcast IP address, 255.255.255.255. Querying a nonexistent nameserver is not only unproductive, but it can also be quite time consuming if it happens in an interactive session, since the router will not return the EXEC prompt until the query times out. This can be quite frustrating because, by default, the router will interpret any unknown command as a hostname that you want to connect to. So it will attempt to resolve any typing mistakes you enter on the command line:

Router1#pnig
Translating "pnig"...domain server (255.255.255.255)

Translating "pnig"...domain server (255.255.255.255)
(255.255.255.255)
Translating "pnig"...domain server (255.255.255.255)
% Unknown command or computer name, or unable to find computer address
Router1#

As you can see, we accidentally mistyped the command ping. The router did not know this command, so it assumed that it must be the name of a foreign host and attempted to resolve it. Everybody who has used a Cisco router for more than a few minutes is familiar with this problem, compounding the annoyance of a typing error with having to wait several seconds for the name query to time out.

One easy way to prevent this from happening is to disable DNS lookups, as we did in our first example:

Router1(config)#no ip domain-lookup 

This is an effective solution if we don't need to use DNS services on the router. With name resolution disabled, the router will still interpret our typing mistakes as names of foreign hosts, but it will try to resolve these names only from the static host entries, which don't need to time out:

Router1#pnig
Translating "pnig"
% Unknown command or computer name, or unable to find computer address
Router1#

The net result is that the router will return your prompt immediately and allow you to enter the command you intended to type.

Routers that are properly configured to use DNS services, as in Recipe 2.11, also will attempt to resolve your typing errors by default. In this case, there is a real server to respond to the request and definitively state that there is no such host, so the delay is somewhat shorter. The router will attempt to query each of the configured nameservers in order until it receives a response or gives up trying:

Router1#pnig
Translating "pnig"...domain server (172.25.1.1) (10.1.20.5)
% Unrecognized host or address, or protocol not running.

Router1#

This is still an extremely inefficient way of handling typing errors, though. And if you need to use DNS, the solution in our first example is not practical. So we have to attack the problem from a different angle.

The router attempts to resolve typo errors because, by default, every VTY line has preferred transport method of Telnet. This means that you can initiate a Telnet session by typing a hostname at the prompt. You don't need to explicitly issue the telnet command. Therefore, when we type in "pnig", the router interprets it as "telnet pnig". However, we can instead set the preferred transport method to be "none" so the router won't try to connect to a remote device unless we explicitly issue the Telnet command:

Router1(config)#line vty 0 4
Router1(config-line)#transport preferred none

This avoids the problem by preventing the router from misinterpreting our typos as hostnames in the first place:

Router1#pnig
^
% Invalid input detected at '^' marker.

Router1#

As you can see, the router now interprets the typing error as an invalid command rather than a hostname. We recommend using this solution to the problem because it doesn't prevent you from using DNS.

See Also

Enabling Domain Name Services

Enabling Domain Name Services

Problem

You want to configure your router to use DNS to resolve hostnames.

Solution

To configure the router to use DNS to resolve hostnames, you need to specify a domain name and at least one nameserver:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#ip domain-lookup
Router1(config)#ip domain-name oreilly.com
Router1(config)#ip name-server 172.25.1.1
Router1(config)#ip name-server 10.1.20.5
Router1(config)#end
Router1#

Starting in IOS Version 12.2, Cisco changed the command syntax from ip domain-lookup to ip domain lookup. They also changed the command syntax from ip domain-name to ip domain name. The new IOS software still accepts previous versions of the commands.


Discussion

As we mentioned in Recipe 2.10, you can configure your router to use Domain Name Service (DNS) to resolve hostnames. In fact, Cisco routers have DNS name resolution enabled by default. However, since there is no default nameserver, the router will attempt to use the local broadcast address, 255.255.255.255, until you explicitly configure a proper nameserver. This means that the ip domain-lookup configuration command in the example is necessary only if someone has explicitly disabled DNS on the router.

After you configure the router with a valid nameserver, you can access any hostname that is known by your DNS server. For example, our DNS server exchanges information with the public Internet, so we can ping the Cisco web page by name:

Router1#ping www.cisco.com
Translating "www.cisco.com"...domain server (172.25.1.1) [OK]

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 198.133.219.25, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 80/91/104 ms
Router1#

You can see in this output that the router sent a DNS query to the nameserver, 172. 25.1.1, and asked it to translate the hostname www.cisco.com. The server responded with an IP address of 198.133.219.25. The router then behaved as if we had simply asked it to ping this destination IP address instead of the hostname.

In this example, we configure multiple nameservers:

Router1(config)#ip name-server 172.25.1.1
Router1(config)#ip name-server 10.1.20.5

The router will send its queries to these servers in the order that we entered them. For example, suppose we tried to ping a factitious host, cookbook.oreilly.com:

Router1#ping cookbook.oreilly.com
Translating "cookbook.oreilly.com"...domain server (172.25.1.1)(10.1.20.5)
% Unrecognized host or address, or protocol not running.

Router1#

As you can see, the router sent this query first to the nameserver at 172.25.1.1. When this device was unable to resolve the name, the router resorted to the second nameserver, 10.1.20.5. Ultimately the query failed because the hostname doesn't exist.

You can view the DNS configuration parameters with the show hosts command:

Router1#show hosts
Default domain is oreilly.com
Name/address lookup uses domain service
Name servers are 172.25.1.1, 10.1.20.5

Host Port Flags Age Type Address(es)
www.cisco.com None (temp, OK) 0 IP 198.133.219.25
Router1#

This command displays the domain name, the nameservers (in their order of preference), as well recently resolved hostnames. The router keeps a name cache of recently resolved names to prevent unnecessary DNS lookups on successive attempts to the same host. The difference between these dynamically learned hosts and the statically configured ones that we saw last chapter is that the router will automatically flush the dynamic entries from the cache after a period of time. This time period is actually specified by the DNS server separately for each hostname, so you cannot change it on the router.

The ip domain-name command allows you to specify your network's domain name:

Router1(config)#ip domain-name oreilly.com

When you configure a domain name like this, you can work with just the local hostname instead of the Fully Qualified Domain Name (FQDN). For example, you could type mail instead of mail.oreilly.com, and the router would resolve it correctly.

Some organization use more than one domain name. You can configure the router to use multiple domain names by including several ip domain-list commands in the configuration. For example, we can configure the router to use a second registered domain name, ora.com:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#ip domain-list ora.com
Router1(config)#ip domain-list oreilly.com
Router1(config)#end
Router1#

If no domain list is present but you do have a domain name, the router will use the domain name. However, as soon as you configure a domain list, the router will ignore the domain name. This is why we had to include the original domain name, oreilly.com, in the domain-list example.

Again, the order of the domain-list entries is important because this is how the router will build the FQDN it uses for its queries. For example, if you sent a query for the host named mail, the router would correctly find it in either domain. But if there was a host named mail in both domains, then the router would connect to mail.ora.com instead of mail.oreilly.com because the domain list specifies ora.com before oreilly.com. This doesn't prevent you from connecting to mail.oreilly.com; but you would have to specify the full name, rather than just mail.

The show hosts command output includes the domain list:

Router1#show hosts
Default domain is oreilly.com
Domain list: ora.com, oreilly.com
Name/address lookup uses domain service
Name servers are 172.25.1.1, 172.25.1.3, 10.1.20.5

Host Port Flags Age Type Address(es)
www.cisco.com None (temp, OK) 0 IP 198.133.219.25
freebsd None (perm, OK) 0 IP 172.25.1.1
Router1#

See Also

Using Static Hostname Tables

Using Static Hostname Tables

Problem

You want to create a static host lookup table on the router.

Solution

The ip host command lets you configure static host entries in the router:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#ip host freebsd 172.25.1.1
Router1(config)#ip host router2 10.1.1.1 172.22.1.4
Router1(config)#end
Router1#

Discussion

Many router commands will accept a hostname in place of an IP address. This helps make the configuration files more readable because it is much easier for humans to work with device names than IP addresses. However, the router still needs to have a way of translating these names into the IP addresses that it prefers to work with. Cisco supports two methods for resolving hostnames into IP addresses. You can either use static host entries, as we do in this recipe, or DNS, as we do in the next recipe.

Static host entries are strictly local to the router. The router does not share this information with other routers or other devices. And unlike DNS, static host entries are not dependent on any external services such as nameservers. If you have both DNS and static host definitions, the router will prefer the static entries. This allows you to override the normal DNS if you don't want to use it.

The biggest problem with static entries is, quite simply, that they are static. So they don't respond to IP address changes without manual intervention. The biggest advantage to static entries is that being static, they don't depend on the reliability of any external servers. If you tie some critical function to a hostname instead of an IP address, you don't want that function to go away just because the DNS server became temporarily unreachable.

For this reason, if you use hostnames in your router configuration instead of IP addresses, we strongly recommend using static host entries rather than DNS.

In the example, the host called router2 has more than one IP address:

Router1(config)#ip host router2 10.1.1.1 172.22.1.4

When you associate multiple addresses with a single hostname like this, the router will attempt to connect to each address in the specified order. When building a static host entry for a neighboring router, you may wish to start with the loopback IP address, followed by its other, reachable IP addresses.

The ip host command also accepts a port number, which is the TCP port that the router will connect to when you use Telnet to connect to the specified hostname. By default, the telnet command will initiate a connection to TCP port 23. In the following example, we will define a host named mail, and instruct the router to use port 25 (SMTP) when making connections to this device:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#ip host mail 25 172.25.1.1
Router1(config)#end
Router1#

Then Telnet to this hostname connects to the SMTP process on the device:

Router1#telnet mail
Trying mail (172.25.1.1, 25)... Open
220 freebsd.oreilly.com ESMTP Postfix
quit
221 Bye

[Connection to mail closed by foreign host]
Router1#

Notice that the router connected directly to the host's mail port, port 25. You can override the defined host port at the command prompt by including the required port number at the end of the telnet command:

Router1#telnet mail 25

You can use the show hosts command to get a complete list of all of the static host definitions:

Router1#show hosts
Default domain is not set
Name/address lookup uses static mappings

Host Port Flags Age Type Address(es)
freebsd None (perm, OK) 0 IP 172.25.1.1
router2 None (perm, OK) 0 IP 10.1.1.1
172.22.1.4
mail 25 (perm, OK) 0 IP 172.25.1.1
Router1#

See Also

Enabling Secure HTTP (HTTPS) Access to a Router

Enabling Secure HTTP (HTTPS) Access to a Router

Problem

You want to configure and monitor your router using an encrypted browser interface.

Solution

To enable secure HTTP (HTTPS) access to a router, use the ip http secure-server command:

Core#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Core(config)#ip http secure-server
Core(config)#end
Core#

Cisco introduced secure HTTP access feature in IOS Version 12.2(14)S.

Discussion

The Secure HTTP feature provides you with a secure and encrypted method to access the router via a web browser using Secure Sockets Layer and Transport Layer Security. This prevents HTTP sessions from being intercepted or attacked.

By default, the router creates a self-signed digital certificate that is required for secure access. The router adds the digital certificate to its configuration:

Router2#show running-config | section crypto
crypto pki trustpoint TP-self-signed-2618906780
enrollment selfsigned
subject-name cn=IOS-Self-Signed-Certificate-2618906780
revocation-check none
rsakeypair TP-self-signed-2618906780
crypto pki certificate chain TP-self-signed-2618906780
certificate self-signed 01
3082024B 308201B4 A0030201 02020101 300D0609 2A864886 F70D0101 04050030
31312F30 2D060355 04031326 494F532D 53656C66 2D536967 6E65642D 43657274
69666963 6174652D 32363138 39303637 3830301E 170D3036 30313235 31373031
32345A17 0D323030 31303130 30303030 305A3031 312F302D 06035504 03132649
4F532D53 656C662D 5369676E 65642D43 65727469 66696361 74652D32 36313839
30363738 3030819F 300D0609 2A864886 F70D0101 01050003 818D0030 81890281
8100E12C BF2F0F2D 3FA6AAEC 6538D47B FF4A4129 2BE28AFE F1880962 659D06DC
82992F38 4DDBC544 A071D74F AF503DC7 14C0EF28 7D03D6BA 4AD3D122 184034FF
FBDE5616 0246528A 83B8E0BA 70C2FC46 605DA522 BC85B1F3 AD47E133 6C2CE562
669048DB 7378B44A 5999D087 CDA95F74 9E073880 975FEA58 8B0B75EA AA62F996
CDEB0203 010001A3 73307130 0F060355 1D130101 FF040530 030101FF 301E0603
551D1104 17301582 13526F75 74657232 2E696A62 726F776E 2E636F6D 301F0603
551D2304 18301680 1475B543 CAC80FB1 63018DD7 4A81D46A 03DF023B 35301D06
03551D0E 04160414 75B543CA C80FB163 018DD74A 81D46A03 DF023B35 300D0609
2A864886 F70D0101 04050003 81810070 5D025E22 B4120D0A BD1D2E33 904B198F
D9E57BB0 55C90C11 8882A727 9DC42D5F 86619446 1AF7BA53 5DDEDCB5 3B32B70D
0AFCBCE0 77EC5A50 B0428E89 656C641B F2A6A0E9 CEA331EE 9404F527 40BD66FB
D30791B9 92BAB053 465FB50C 8C7D8B74 9926ED58 5881A515 7199D397 B69D385F
329EC47B 9850E063 B4AC318D 76DC9D
quit
Router2#

If this command doesn't show any self-signed certificates, you can generate them using the command crypto key generate rsa. We disscuss this command in more detail in Recipe 3.20.

It is a good idea to explicitly disable the HTTP server to ensure that only encrypted HTTP sessions are permitted once secure HTTP is enabled. To do so, use the no ip http server command to disable the HTTP server:

Router2#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router2(config)#ip http secure-server
Router2(config)#no ip http server
Router2(config)#end
Router2#

By default, the secure HTTP server uses port 443. To change the secure server port, use the following command:

Router2#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router2(config)#ip http secure-port 8080
Router2(config)#end
Router2#

In this example, we changed the secure HTTP port from 443, the default, to port 8080. You can set the secure port to most any unused port number; however, the HTTP and secure HTTP servers cannot be configured to use the same port.

If you do change the secure HTTP port number, then you need to explicitly specify the new port number in the browser's URL. For example: https://router1.oreilly.com:8080, where 8080 is the new port number of the secure server.


To view the secure HTTP configuration status, use the show ip server command:

Router2#show ip http server secure status
HTTP secure server status: Enabled
HTTP secure server port: 8080
HTTP secure server ciphersuite: 3des-ede-cbc-sha des-cbc-sha rc4-128-md5 rc4-128-sha
HTTP secure server client authentication: Disabled
HTTP secure server trustpoint:
HTTP secure server active session modules: ALL
Router2#

As you can see from the output of the show command, the secure server is enabled and is configured to use port 8080. Also, notice that client authentication is currently disabled. Secure HTTP client authentication is enabled by using the same method as the HTTP server. See Recipe 2.8 for more information on enabling HTTP authentication.

See Also

Enabling HTTP Access to a Router

Enabling HTTP Access to a Router

Problem

You want to configure and monitor your router using a browser interface.

Solution

Cisco includes an HTTP server in the IOS. You can enable this feature on a router, and then use any standard web browser to access the router instead of Telnet:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#access-list 75 permit 172.25.1.1
Router1(config)#access-list 75 deny any
Router1(config)#ip http server
Router1(config)#ip http access-class 75
Router1(config)#end
Router1#

Discussion

After configuring this feature on a router, you can then connect to the router from a standard web browser. For example, using the Lynx text-based web browser, the router's home page looks like this:

                                                          Router1 Home Page

Cisco Systems

Accessing Cisco 2621 "Router1"

Telnet - to the router.

Show interfaces - display the status of the interfaces.
Show diagnostic log - display the diagnostic log.
Monitor the router - HTML access to the command line interface at
level 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

Connectivity test - ping the nameserver.

Show tech-support - display information commonly needed by tech
support.

QoS Device Manager - Configure and monitor QoS through the web
interface.
________________________________________________________________ _

Help resources

1. CCO at www.cisco.com - Cisco Connection Online, including the
Technical Assistance Center (TAC).
2. tac@cisco.com - e-mail the TAC.
3. 1-800-553-2447 or +1-408-526-7209 - phone the TAC.
4. cs-html@cisco.com - e-mail the HTML interface development group.

The highlighted words are links that allow you to execute IOS EXEC commands. For example, the Show interfaces link will run the show interfaces command and display the result on your browser. You can even use this interface to configure the router. If you select one of the command-line interface level options, it will give you access to all of the EXEC commands at the corresponding authorization level. Please refer to Chapter 3 for more information about these user authorization levels.

This option for accessing a router has been available since IOS level 11.2. However, there was an extremely serious bug in the feature that was fixed in IOS level 12.1(5). This bug would cause the router to crash if the user issued a relatively simple typographical error. If a Telnet user types a question mark as part of a command, the router will respond with a list of valid options for this command. However, including a question mark in a URL would cause the router to crash. So since even a legitimate user could easily make this mistake, we strongly recommend against using the feature in any IOS levels before 12.1(5).

In more recent IOS versions, this web interface is no more or less secure than Telnet access to the router's EXEC command-line interface. You still need to supply the same valid user authentication information to connect using a browser that you would need to connect with Telnet. In Chapters 3 and 4 we will discuss different authentication methods, such as AAA, that you can use with Telnet. These methods are also all available with HTTP, and you can configure the one you want using the authentication keyword. For example, you can configure the HTTP server to use AAA authentication as follows:

Router1(config)#ip http authentication aaa

You can even restrict which devices are permitted to access the router's web interface using the access-class keyword. In the example, we have told the router to restrict access to the router's web server based on access-list number 75, which allows only one workstation IP address:

Router1(config)#access-list 75 permit 172.25.1.1
Router1(config)#access-list 75 deny any
Router1(config)#ip http access-class 75

If you are concerned about security of the HTTP protocol, but you still want the convenience of a web interface, you can opt instead for HTTPS. We discuss HTTPS in Recipe 2.9.

We find that the Telnet command-line interface is much easier to use than the web interface. The only really compelling use for this option that we have encountered is to allow first level technical staff access to basic commands, such as show interfaces.

See Also

Using the Small Servers

Using the Small Servers

Problem

You want to enable or disable router services like finger, echo, and chargen.

Solution

The finger application provides a remote way of seeing who is logged into the router. You can enable it with the ip finger global configuration command:

Router1#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#ip finger
Router1#

Every Cisco router also has a set of small TCP and UDP server applications that are sometimes useful for test purposes:

Router1#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#service tcp-small-servers
Router1(config)#service udp-small-servers
Router1(config)#end
Router1#

Discussion

The finger command is a simple utility that allows you to do the equivalent of a show users command on a remote router. Unix computers generally have a standard finger program that you can run as follows:

Freebsd% finger @Router1
[Router1]

Line User Host(s) Idle Location
66 vty 0 kdooley idle 00:22:47 freebsd
67 vty 1 ijbrown idle 1d07h freebsd
* 68 vty 2 idle 00:00:00 freebsd

Interface User Mode Idle Peer Address

Freebsd%

But you can also use the Telnet program, and connect to TCP port 79 to access the finger server as well. You can do this from another router, for example:

Router2#telnet 10.1.1.2 finger
Trying 10.1.1.2, 79 ... Open

Line User Host(s) Idle Location
66 vty 0 kdooley idle 00:24:14 freebsd
67 vty 1 ijbrown idle 1d07h freebsd
* 67 vty 1 idle 00:00:00 10.2.2.2

Interface User Mode Idle Peer Address


[Connection to 10.1.1.2 closed by foreign host]
Router2#

Notice that in both cases the output includes not only the active users, but also the finger process itself, which is indicated as the line with the asterisk.

The finger protocol is defined in RFC 1288. It is disabled by default on Cisco routers. While this can be convenient to see who is logged in to a remote router without having to log in to check, it also can represent a serious security problem. Not only does it display a set of valid login IDs, which can be used to focus an attack, but it consumes a VTY line on the router, which can prevent legitimate access if done persistently. The finger protocol also has a checkered history. A bug in the original finger implementation was one of the methods used by the first great viral attack to shut down large sections of the Internet (the infamous Morris Worm).

For all of these reasons, we strongly recommend you keep this protocol disabled on all of your routers. If it has been enabled for any reason, you can disable it as follows:

Router1(config)#no ip finger

We should also note in passing that the ip finger command replaces the earlier service finger command, which you will find in many references:

Router1(config)#service finger

If you use this deprecated version of the command, the router will automatically replace it with the newer command.

Cisco routers also support a set of simple TCP and UDP applications that are relatively common standards for IP devices. In IOS levels 12.0 and higher, the TCP and UDP small servers are disabled by default, and you must enable them if you wish to use them. In earlier IOS levels, they are enabled by default.

In general, we find that the small servers are only marginally useful, and we recommend disabling them when you are not actively using them for testing purposes. These servers listen for incoming packets from any source. There have been network denial of service attacks based on these servers. Usually the attacks simply exploit the fact that the TCP servers in particular will accept a connection from any device that requests one. If a hostile user sends a stream of TCP SYN packets to one of these ports, the router will have to respond to it and devote internal resources to keeping the session active. This can use up router resources.

The UDP servers are also potentially dangerous because a hostile user can spoof the source address in the packet to force your router to send a barrage of response packets to a third party. A similar attack could potentially be launched using the TCP servers, because the router will respond to any TCP SYN packet with a SYN ACK. Another network device could find itself unable to cope with receiving a barrage of unsolicited SYN ACK packets.

Therefore, we recommend disabling these services except when you specifically need to use one of them:

Router1(config)#no service tcp-small-servers
Router1(config)#no service udp-small-servers

However, with these cautions, the small servers do have legitimate uses.

The TCP and UDP small servers are shown in Table 2-2. The router implements both TCP and UDP based versions of each of these server functions, on the same port numbers. These are all well-known ports and commonly implemented applications. They are usually used for testing purposes.

Table 2-2. TCP and UDP small servers
Port number Common name RFC Description
7 Echo RFC 862 The server process responds to any client input by sending back the identical input.
9 Discard RFC 863 The server process discards any data sent by the client.
13 Daytime RFC 867 The server responds with the current time and date, and then closes the session.
19 Chargen RFC 864 The server sends a constant stream of ASCII characters to the client.


The easiest way to explain what these functions do is to simply try them. The TCP versions are easier to demonstrate because you can use the standard Telnet application, and just tell it to connect to a different TCP port number.

The echo function just responds to whatever you type by sending back the same data:

Freebsd% telnet Router1 echo
Trying 172.25.25.1...
Connected to Router1.
Escape character is '^]'.
It gives a very echo to the seat where love is thron'd
It gives a very echo to the seat where love is thron'd
^]
telnet> quit
Connection closed.
Freebsd%

In its UDP version, the echo function merely copies the data segment of the packet and returns it to the sender.

The discard function is considerably less useful. The TCP version allows the client to establish a TCP session with the server, and then ignores everything you send it:

Freebsd% telnet Router1 discard
Trying 172.25.25.1...
Connected to Router1.
Escape character is '^]'.
Go off; I discard you: let me enjoy my private; go off.
^]
telnet> quit
Connection closed.
Freebsd%

The UDP version of this application listens for packets on UDP port number 9 and ignores them. It doesn't respond in any way to these packets.

The TCP version of the daytime server accepts a connection request, then immediately sends a packet containing the current time and date in ASCII format, and disconnects the session:

Freebsd% telnet Router1 daytime
Trying 172.25.25.1...
Connected to Router1.
Escape character is '^]'.
Sunday, January 5, 2003 17:41:21-EST
Connection closed by foreign host.
Freebsd%

The UDP daytime server listens on UDP port number 13 and responds with a single packet containing the same ASCII time data as the TCP version. The daytime server is marginally useful for checking a clock, but other applications such as NTP are much more robust if you actually want to configure a reliable time service. We discuss NTP in Chapter 14.

The Character Generation ( chargen) function is probably the most useful of the TCP small servers. As soon as you make a connection to this port number, the router will start sending a continuous stream of data back to the client. We have often used this feature as a sort of poor man's traffic generator to investigate network loading issues:

Freebsd% telnet Router1 chargen
Trying 172.25.25.1...
Connected to Router1.
Escape character is '^]'.
!"#$%&'( )*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\Qabcdefg
!"#$%&'( )*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\Qabcdefgh
"#$%&'( )*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\Qabcdefghi
#$%&'( )*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\Qabcdefghij
$%&'( )*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\Qabcdefghijk
%&'( )*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\Qabcdefghijkl

^]
telnet> quit
Connection closed.
Freebsd%

The UDP version of the chargen server listens for a UDP packet on the well-known port number 19, and then generates a single response packet back to the sender. This response packet contains a random number between 0 and 512 bytes of arbitrary character data.

See Also

Disabling the Cisco Discovery Protocol

Disabling the Cisco Discovery Protocol

Problem

You don't want to allow adjacent devices to gain information about this router for security reasons.

Solution

You can disable CDP on a single interface by using the command no cdp enable interface configuration command:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#cdp run
Router1(config)#interface FastEthernet0/0
Router1(config-if)#no cdp enable
Router1(config-if)#end
Router1#

And you can disable all CDP on the router with the global configuration command, no cdp run:

Router1#configure terminal 
Enter configuration commands, one per line. End with CNTL/Z.
Router1(config)#no cdp run
Router1(config)#end
Router1#

Discussion

CDP can be an extremely useful feature because it tells you so much information about all of your neighboring devices. However, this can also represent a serious security problem. CDP packets are not encrypted in any way, so if somebody can just capture the CDP packets from a network segment as they pass between the routers, they can easily deduce a lot about your network architecture. And if they can get access to the router either via Telnet or SNMP, they can use the CDP tables to discover the entire topology of your network at Layer 2 and 3, including all IOS levels, router and switch model types, and IP addressing. If somebody was armed with this information and a Cisco bug list, they could launch a very effective attack against your network.

For this reason, many network engineers choose to disable CDP throughout their networks. In general, if you need to disable CDP for security reasons, you should probably disable it globally on the whole router, rather than on individual interfaces. If you disable CDP on a single interface, you will only prevent people from intercepting the CDP advertisement packets. But the CDP table information is easily accessible through Telnet and SNMP, so valuable topology information is still vulnerable to probing.

We would like to clarify that the security risk is that somebody will launch a deliberate and focused attack against your network either from the inside or from a directly connected network. We strongly recommend disabling CDP on any routers that connect to external networks, particularly the public Internet. However, for purely internal networks, it is important to remember that you would be protecting yourself against people who are already physically connected to the network in some way. At this point, you must balance the obvious usefulness of CDP against the risk of attack from people who probably have legitimate access to the network. Whether you disable CDP or not in this situation depends on how much you can trust your legitimate users not to launch a deliberate internal attack.

See Also