TAGS: |

A Cisco IOS Template With Commands & Explanations: Expecting The Same Result

Charles Galler

We have all heard that the definition of insanity is doing the same thing over and over and expecting a different result. Some people harness this philosophy while others try to see if they can break it. I believe you need to harness it to build your networks.

Over the years, I have collected a set of basic commands that get applied to every device I install or bring up to standard. (It also helps with my OCD.) A template is great to give to a new engineer to use to deploy a new switch or router because you can expect certain configurations to be set when you access that new device. Using a template also helps me make sure I didn’t forget anything. However, using a template that someone else created without understanding what each command does is not what an engineer should do. Today, I will lay out a number of configuration items in my template, what they do, and why they are in my template. These command are usually pasted into the device one section at a time.

Note: Also in my template I use variables named %VARIABLE% to be able to search for them in the template and use scripts to generate large quantities of configurations.

Time

Let’s start at the beginning with time.

ntp server %NTPSERVER1%
ntp server %NTPSERVER2%
ntp update-calendar

It is critical for troubleshooting to make sure your logs are timestamped with accurate time to correlate events. If I have an internal NTP server, then I use it, otherwise I will pull two or three from pool.ntp.org. You can do a DNS lookup on pool.ntp.org to get several IP addresses of NTP servers. I usually use at least two, and sometimes three. I will also usually set a couple core devices to pull from the public NTP servers and then everything else to pull time from the core devices. On routers, you need to make sure you update the hardware clock with the ‘ntp update-calendar’ command. Switches will ignore this command.

Logging

logging buffered 500000
logging rate-limit 10 except critical
no logging console
logging %LOG_SERVER%

Since we set the time for logging in particular, it is only natural to move on to logging next. I limit the buffer size so that when I display the logs I am not going through pages and pages of old log information. On the device I really only want to see what is currently logged. I also rate-limit the messages because too many can be too much as well. However, if they are critical or higher, it will avoid the rate-limiting. I turn off console logging as I don’t want someone to connect to the device and get log messages about what is going on in the network. This is more of a security thing, especially if you can’t physically control the access to the devices. And last, I send my logs to a syslog server. If you don’t have one, I highly recommend you get one.

Services

service password-encryption
service tcp-keepalives-in
service tcp-keepalives-out
service timestamps debug datetime msec localtime show-timezone
service timestamps log datetime msec localtime show-timezone
service sequence-numbers
no service tcp-small-servers
no service udp-small-servers

Of course, enabling password encryption is a must. The TCP keepalives in/out are to generate keepalive messages on TCP sessions to and from the device that an administrator initiates. This helps disconnect a lost/hung session. I enable detailed timestamps on my logs, both logs and debugs. If they are going back to a central log server, then this can help see what happens first. The sequence numbers are great when you are working with another engineer to diagnose the problem. You can say, look at line number XXX and you are both looking at the same log message. Lastly I disable the small servers (discard, echo, chargen). These are services you don’t normally need, so why even have them running?

IP Tweaks

no ip source-route
no ip finger
ip routing
ip cef
ip dhcp database flash:dhcp_bindings
ip tcp synwait-time 10

I have never had a need to do source routing, and this is enabled by default these days, so I disable it. Finger is a service that no one uses and could give an attacker more information about your network. I make sure IP routing is enabled. If it is a Layer 2 switch, then it ignores this command. I also make sure CEF is enabled. In some clean-up projects, I have seen CEF disabled and no one can explain why, so now it is just part of my standard config. Running DHCP on a router is good for small remote offices, but if the router reboots, it loses all of the DHCP bindings. The ‘ip dhcp database’ command tells the router to save those bindings to flash so that if it reboots it can pick back up where it left off. The ‘synwait-time’ is the amount of time that the device will wait for a TCP connection to establish. The default is 30 seconds and I think that is just far too long to wait. A reduced timer can also help the device to withstand DoS attacks.

no ip domain-lookup
ip domain name %DOMAINNAME%
ip name-server %NAMESERVER1%
ip name-server %NAMESERVER2%
ip subnet-zero
ip classless

Yes, I typically configure a DNS domain name and DNS servers, but them disable DNS lookups. If you want to use DNS lookups I would recommend using the ‘transport preferred none’ command on your console and VTY lines to stop the automatic telnet function of syntax errors in exec mode. I configure the device with the DNS information so that when I really do need to use DNS lookups from the device I can simply enable that function temporarily. IP subnet-zero allows using the ‘0’ subnet for addresses. Older devices would not do that unless you had this command and now it is just a part of my template. The ip classless disables the classful routing. This is legacy and is usually enabled by default these days, but I have it in my template as a reminder and for clean-up projects.

Source Interface

ip telnet source-interface %SOURCE%
ip ftp source-interface %SOURCE%
ip tftp source-interface %SOURCE%
ip ssh source-interface %SOURCE%
snmp-server trap-source %SOURCE%
ip tacacs source-interface %SOURCE%
ip radius source-interface %SOURCE%
ntp source %SOURCE%
logging source-interface %SOURCE%

I like to make sure I know what source address the services on the device is using, so I source all requests from either a loopback on a Layer 3 device or the management IP address on a Layer 2 device. I use the same source address for everything on that device. This is also a good place to comment on what the variable in my template is good for. Just do a find/replace for “%SOURCE%” and you update all of these lines in one go.

Device Management & Security

ip ssh authentication-retries 3
ip ssh version 2
crypto key generate rsa general-purpose modulus 1024
no ip http server
no ip http secure-server

VTY access typically gives you three tries to login, but here I want to define it and make sure it is three for SSH. Also, I make sure I am running SSH version 2. I always have the command to generate a crypto key. For me, a missing crypto key is the biggest issue where someone has tried to configure SSH, but can’t get it to work. I use 1024 key size because in my clean-up projects some older devices don’t support anything larger. If you can use 2048, then I would suggest doing so. And finally, I disable all web server services. I don’t use them and haven’t seen anyone use them. If you need them for some wild reason, you can always re-enable them as you need.

ip access-list standard REMOTE_ACCESS
 permit X.X.X.X X.X.X.X
 deny   any log
ip access-list standard SNMP_RO_IN
 permit x.x.x.x x.x.x.x
 deny   any log
ip access-list standard SNMP_RW_IN
 permit y.y.y.y y.y.y.y
 deny   any log

These are the three basic ACLs that I always configure. For remote access, at a minimum I put in whatever RFC1918 addresses are in use on the internal network if I can’t be more specific. For SNMP, I only enter the few systems that really need to access SNMP – usually a management station or two and then maybe the subnet that the network administrators live on. We will apply these shortly.

snmp-server community %SNMPREAD% RO SNMP_RO_IN
snmp-server community %SNMPWRITE% RW SNMP_RW_IN
snmp-server ifindex persist
snmp-server location %LOCATION%
snmp-server contact %CONTACT%
snmp-server chassis-id %HOSTNAME%
snmp-server enable traps snmp authentication linkdown linkup coldstart warmstart
snmp-server enable traps tty
snmp-server enable traps envmon fan shutdown supply temperature status
snmp-server enable traps config
snmp-server enable traps entity
snmp-server host %SNMP_SERVER% %SNMP_TRAP_STR%

Here, we create the SNMP community strings for Read-Only and Read-Write communities. If I don’t have a reason to use Read-Write, then I won’t even configure it. At the end of the command, you can see I apply the ACLs from above. The ‘ifindex persist’ forces the device to use the same SNMP interface index numbers no matter what other interfaces are added or removed from the device. This helps the monitoring system keep track of the interfaces. If I can define the location and contact name, I do. That’s not critical, but just something nice. The chassis-id I always name with the device’s hostname. Lastly, there are some basic traps I enable and send them to the SNMP trap collector. If there is no trap collector, then I don’t enable them.

banner login ~

This device is owned by %COMPANY%. Only authorized users are allowed
to connect to or use this device. If you are not authorized, disconnect
immediately. Expect no privacy when using this device. All access and use
may be monitored and/or recorded. Monitoring and/or recording may be
turned over to the appropriate authorities. Any unauthorized use may be
prosecuted to the full extent of the law. Use of the system implies consent
to the previously mentioned conditions.

~

This is the standard default banner message that I use. I do include the blank lines above and below, as it makes it a little easier to read when displayed. Some organizations don’t like to put their name in the banner; others do.

line console 0
logging synchronous
exec-timeout 15 0
usb-inactivity-timeout 15
exec prompt timestamp
transport preferred none

line vty 0 15
logging synchronous
exec-timeout 15 0
exec prompt timestamp
transport input ssh
transport preferred none
access-class REMOTE_ACCESS in

And lastly, the “line” paragraphs. The ‘logging synchronous’ helps keep the log messages to the terminal and the prompt separated so that I can see what I am typing. ‘Exec-timeout’ disconnects the session after 15 minutes. On the console, the ‘usb-inactivity-timeout’ is the timeout session for the USB console ports that are showing up on some new devices. I love the ‘exec prompt timestamp’ command. It will display the CPU utilization and the current device time when you enter command from exec mode. This is very helpful when troubleshooting issues or documenting what you are doing in the CLI. The ‘transport preferred none’ disables the automatic telnet functionality from exec mode. So if you mistype something in exec mode, it doesn’t try to telnet to that device or start a DNS lookup. On the VTY lines, I only enable SSH. Doing this disables telnet. For those devices that can’t do SSH, I would also include telnet. And last, but not least, here on the VTY lines I use the access-class to restrict what IPs can connect to this device with the ACL from above.

 

Wow, that was a lot and I haven’t covered AAA, aliases, archive, routing protocols, interface configs, etc. I will leave those for another post. Feel free to use these as a start for your own template or to update your existing one. Just remember – you need to know what they do and use at your own risk. Please give me some feedback as to what you may use in your own templates. Share and enjoy!