Sep 292012
 

Just like previously, please read the disclaimerbefore proceeding; I ain’t no CCIE! Several points before diving off into the configuration :-

  1. Somewhat surprisingly, the most difficult part of getting IPv6 up and running was not the configuration nor the process of switching ISP to one that supported native IPv6. The most difficult part was acquiring a version of IOS that was not riddled with bugs related to (I think) running IPv6 over PPP. If you are undertaking this task, I would suggest making sure you have a very recent version of IOS – the one I am now running was released in July 2012.
  2. If you need a UK ISP that supports IPv6 for customers, I would suggest AAISP.
  3. Throughout this document, I am using the IPv6 documentation network 2001:db8/32, or more specifically 2001:db8:face/48. That doesn’t guarantee that I know what I’m talking about, but at least it doesn’t guarantee that I know nothing … as would be the case if I were using some random real IPv6 address.
  4. None of the following should interfere with anything you might be doing with IPv4. With the exception of times when I reloaded the router out of frustration, and occasionally to load a new firmware, my IPv4 connectivity was up and running continuously.

Before starting you need an IPv6 address to configure; unless you have a large internal network it doesn’t make sense to start playing with a ULA address. So get an allocation from your ISP. If you have a half-reasonable ISP, they will allocate you something like 2001:db8:face/48 which will give you 65536 different subnets to play with – perhaps slightlyover the top for a home network! To start with, you need to configure the router itself to enable IPv6 :-

ipv6 source-route
ipv6 general-prefix MYISP 2001:db8:face::/48
ipv6 unicast-routing
ipv6 cef

This basically enables IPv6 routing (with no routing protocols – only static and learnt routes) and configures a “general prefix” with the network details of what your ISP has provided you with. This can be used later to configure addresses in a way that means that changing ISP isn’t quite so painful, and in a way that is less error prone – typing in IPv6 addresses is a lot more prone to typos than IPv4 addresses. Once that is done, it is time to look at IPv6 security … normally people suggest getting everything working first, but as I am more of a security geek than a networking geek, I would suggest security comes first. This is not a great deal different to IPv4 security except that forgetting about NAT makes things simpler :-

ipv6 inspect routing-header
ipv6 inspect name ipv6-allowed-out icmp
ipv6 inspect name ipv6-allowed-out tcp
ipv6 inspect name ipv6-allowed-out udp
ipv6 inspect name ipv6-allowed-out ftp

This basically defines what traffic is allowed out (assuming it’s applied appropriately to an interface). Nothing really odd here … basically everything is allowed out, and I ask the router to inspect for routing information that might be available. The next bit is the incoming ACL :-

ipv6 access-list access-to-servers
 permit icmp any any
 permit tcp any host 2001:db8:face:f00d::c0:ffee eq 22
 deny ipv6 any any log

Several key points about this ACL :-

  1. All IPv6 ACLs are “extended”.
  2. All IPv6 ACLs are named rather than numbered.
  3. The ICMP bit looks a little permissive, but ICMP is very much more required for a functioning IPv6 network than an IPv4 network. It can be tuned down somewhat, but you need ICMP for your network to work.
  4. The rule that allows access to my server on port 22 does not allow the use of the previously defined general-prefix. Come on Cisco, do the right thing here!

And another ACL for access to the router’s SSH port :-

ipv6 access-list authorised-v6
 permit ipv6 2001:db8:face::/48 any
 deny ipv6 any any

And we might as well apply that last ACL right away :-

line vty 0 4
  ipv6 access-class authorised-v6 in

Now we have the basics ready, we can start to configure interfaces. Before you start, it is worth figuring out what network addresses to use. IPv6 does of course allow the possibility of using wildly inappropriate hexspell words as network address, or you could be very sensible and come up with an appropriate allocation scheme.  For larger networks, it is well worth reserving a large swathe of networks (such as 0000-7ffff) for someone to come along later to create a “better” scheme … as somebody who has dealt with a large IPv4 network where the original allocation scheme was somewhat suboptimal, I firmly believe that later network administrators should have the freedom to change the scheme in the light of more experience. You will often encounter the assumption that the host part of a network is always 64 bits (or the network mask is always /64). Whilst this is not a requirement at all, there are popular features of IPv6 that only work on a network that size such as address auto-configuration (SLAAC). In practice this means that you should always create networks with a /64 netmask, unless you have a very good reason not to (for instance when configuring statically configured links between routers). Even if you have no intention of allowing address auto-configuration. As a minimum, you will need two networks – one for the external interface, and one for the internal interface(s). As you may have guessed, we have already specified what the internal network is: 2001:db8:face:f00d/64, and I will use 2001:db8:face:1ced/64as the external interface. The first interface to configure is the internal network :-

interface Vlan101
 ipv6 address MYISP 0:0:0:F00D::1/64
 ipv6 enable 
 ipv6 nd prefix 2001:db8:face:f00d::1/61
 ipv6 nd router-preference High

The command to give the network and the interface an address requires a little explanation. First of all, we’re lucky enough to be able to use the “general-prefix” that we defined earlier. This “general-prefix” is merged with the unusual looking address that follows it :-

MYISP general-prefix 2001 db8 face
Address to merge 0 0 0 F00D::1/64
Result 2001 db8 face F00D::1/64

This provides the interface with an address. The next command simply enables IPv6 on the interface. The ipv6 nd prefix command tells the router what “prefix” to advertise to clients wishing to autoconfigure (using SLAAC).

As an aside, the whole topic of managing IPv6 addresses on clients is worth an article on its own – auto-configuration sounds like a good option (and indeed may be a good choice), but there are situations where you would prefer to not allow auto-configuration. And not all clients work equally well with all options.

The next command (ipv6 nd router-preference High) is a weak attempt to guard against false Router Advertisement messages – advertising this router as a High preference one may prioritise it’s use over any other mysterious routers that appear on this network. In practice, it is necessary to block RA messages from non-router ports using a switch feature such as ipv6 nd raguard. Once this interface is configured, you may well start to see IPv6 hosts with the command show ipv6 neighbours. And onto the configuration of the outside interface :-

interface Dialer0
 ipv6 address MYISP ::1ced:0:0:0:1/64
 ipv6 enable
 no ipv6 nd ra suppress
 ipv6 inspect ipv6-allowed-out out
 ipv6 traffic-filter access-to-servers in
 ipv6 virtual-reassembly in

This starts off in much the same way as the previous interface configuration, but in this case I also :-

  1. Explicitly enable RA messages on the interface with no ipv6 nd ra suppress. This is to ensure that the RA messages get out to the ISP’s router on the “other end”.
  2. Uses ipv6 inspect ipv6-allowed-out out so that IPv6 traffic is allowed out (and any associated packets are allowed back in again!).
  3. Uses ipv6 traffic-filter access-to-servers in to allow any unsolicited IPv6 traffic necessary in.
  4. Uses ipv6 virtual-reassembly in to use Cisco’s VFR feature to protect against fragmentation attacks.

Note that I have statically configured the address on this interface. Some ISPs require this, and some require that the interface is set to auto-configuration (ipv6 address autoconfig or ipv6 address dhcp). The last step is to configure a default route :-

ipv6 route ::/0 Dialer0

Some misconceptions I’ve come across through googling for tips and assistance :-

  1. There are plenty of examples which show internal interfaces configured with ipv6 nd prefix XXX in addition to the interface address. As far as I can see (and as demonstrated by my home network actually networking), there is no need to specify this prefix unless you are advertising multiple prefixes on an interface, or doing something even stranger.
  2. Examples often include ipv6 nd ra interval ${some-value}, which as far as I can see is somewhat unnecessary except that the default value of 200s means that connected hosts may take a while to spot the router.
  3. There are plenty of examples for setting up IPv6 with a tunnel within IPv4 where the IPv6 MTU is set to some value lower than the default such as ipv6 mtu 1280. Tuning the MTU for native IPv6 should not be necessary, and even if it is, the right value would be somewhat higher.

And of course, if anyone believes I’ve done something wrong, please let me know!

Jan 192011
 

This is probably of less interest than most of my blog postings about Cisco routers, as it concerns something less commonly configured in the way I have done it – specifically a WAN link with a single IPv4 address and NATting to that address. However writing up my notes here is convenient to me, so you’ll have to put up with it. It is also very definitely worth bearing in mind the disclaimer here.

Basic NAT

First of all the “outside” interface needs to be configured as such from the NAT point of view :-

router#configure terminal
router(config)#interface fastethernet 4
router(config-if)#ip nat outside

This marks the interface in a way that lets the router know how addresses need to be NATted. Of course it is also necessary to configure the “inside” interfaces too :-

router#configure terminal
router(config)#interface vlan 101
router(config-if)#ip nat inside

And repeat for each VLAN of course.

In most instructions you will see that it is normal to create a pool of addresses for use by NAT which is perfectly valid for a number of addresses to NAT to, and even when there is a single address. But there is an easier way … NAT to the address of the interface.

router#configure terminal
router(config)#ip nat inside source list 7 interface FasterEthernet4 overload

The next task is to specify an access list to match the addresses that need to be NATted.

router#configure terminal
router(config)#access-list 7 permit 10.0.0.0 /8

Port Forwarding or Static NAT (for Servers)


If you run your own servers you will need to arrange for incoming connections to certain tcp or udp ports to be ‘forwarded’ to a specified address. This is known in the domestic router scene as “port forwarding” which is as good a term for anything – given that the concept of NAT is fundamentally broken.

This is done quite simply by the following :-

router#configure terminal
router(config)#ip nat inside source static tcp 10.0.0.14 80 interface FastEthernet4 80

This of course says that there should be a static rule to map tcp/80 (http for the web) on the server with the address 10.0.0.14 to tcp/80 on the ‘outside’.

A Basic Firewall

Next task is to bring up the WAN connection to check it works ? Not at all; whilst it may be somewhat unhelpful to connect things up after having made multiple changes, it is important to have some kind of firewall running. If you happen to have the IOS firewall feature, there is little point in bothering with the ordinary ACL feature – it sucks in comparison.

But strangely it seems we do need a basic ACL in place to :-

  1. Allow server traffic into the network.
  2. Deny all other traffic.
  3. And to allow the inspect engine to extend the ACL to allow session specific rules.
router#configure terminal
router(config)#ip access-list extended AllowIn
router(config-ext-nacl)#permit tcp any any eq www
router(config-ext-nacl)#deny ip any any log DenyIn

The use of a named ACL here is to allow for greater self-documentation – it is easier to see what an ACL should be used for when it is named. This becomes more important the more ACLs are in use.

We then need to create a set of inspect rules to allow traffic out. This is a very open set of rules, and will dynamically create temporary rules to allow the inbound replies to the allowed outbound traffic. The ordering of this is very important as we need to most specific inspections first – so “inspect tcp”, etc should appear at the end.

router(config)#ip inspect name allow-out bittorrent
router(config)#ip inspect name allow-out ftp
router(config)#ip inspect name allow-out ftps
router(config)#ip inspect name allow-out gnutella
router(config)#ip inspect name allow-out h323
router(config)#ip inspect name allow-out http audit-trail on
router(config)#ip inspect name allow-out https audit-trail on
router(config)#ip inspect name allow-out icmp router-traffic
router(config)#ip inspect name allow-out tcp
router(config)#ip inspect name allow-out udp

The ‘router-traffic’ on the icmp rule is to allow the router to send ICMP traffic to the outside interface and for it to be inspected. For some strange reason, Cisco configured the default to not allow it – leading to any number of network administrators having a nasty panic attack. Perhaps Cisco have a nasty sense of humour?

Next, because it’s fun to see what people may be doing, we need to log whatever the inspection engine drops :-

router(config)#ip inspect log drop-pkt

Finally we apply the new rules to the WAN interface :-

router#(config)#interface fastethernet 4
router#(config-if)#ip access-group AllowIn in
router#(config-if)#ip inspect allow-out out
router#(config-if)#end

This just touches on the capabilities of firewalling with a Cisco and is well worth checking in greater depth. For instance, it is clearly possible to inspect incoming traffic as well as outgoing traffic, but if you do the obvious you end up with a non-working firewall

Bringing Up The WAN

Fortunately I am in the situation where my ADSL line is bridged to Ethernet using an ADSL ‘modem’ so that I merely have to configure the external WAN interface on my router with an external address, a netmask, etc. This is so trivial it seems strange to include it here, but …

router#configure terminal
router(config)#interface FastEthernet4
router(config-if)#ip address 192.168.1.1 255.255.248.0
router(config-if)#ip nat outside
router(config-if)#ip virtual-reassembly
router(config-if)#duplex auto
router(config-if)#speed auto
router(config-if)#end

Perhaps the only oddity there is the use of ‘ip virtual-reassembly’ which is essentially used to protect the router (and in effect the rest of the network) from fragmented packet attacks. And if you prefer to leave CDP enabled, you may also want to stop that on the external interface with “no cdp enable” as well.

Jan 112011
 

First of all, read the disclaimer.

This section is all about small changes that are not important or tricky enough for a blog posting on their own. As such it is likely to grow as I encounter things.

Turning Off Spanning Tree

STP is kind of a noisy protocol, and on small and simple networks it probably is not really needed. To make packet sniffing easier, it may be worth turning off the protocol on all the interfaces … or VLANs :-

router# configure terminal
router(config)#no spanning tree vlan 101
router(config)#no spanning tree vlan 102

Turning Off Cisco Discovery Protocol

For security reasons, or simply because it is unnecessary noise on a network with very little in the way of Cisco devices, you may want to turn off CDP :-

router#configure terminal
router(config)#no cdp run

Autotuning Buffers

According to the documents out there, there is a dark and mysterious art of tuning buffers to optimise performance of your routers. It also says that it isn’t recommended in most situations which must disappoint aspiring übergeeks. However what is less often said is that there is a little option to instruct the router to automatically tune the buffers for optimal performance.

It is likely that it will not make a dramatic improvement, but it is worth turning on :-

router#configure terminal
router(config)#buffers tune automatic

Warm Reboots

Normally when a Cisco router reboots it goes through the whole process of starting up as if it were just powered on (a cold start). This can take quite some time so any option to speed it up is worth considering. Turns out that there is such an option, which instructs the router “just” to reload IOS and restart that way.

It takes effect under two conditions – when the router restarts because of a fault, or when you restart the router manually with the “warm” option (reload warm). To enable this simply turn it on with :-

router#configure terminal
router(config)#warm-reboot
Jan 092011
 

First of all, please read the disclaimer.

This section is all about maintaining some level of revision control on the configuration file that configures the Cisco router. This is obviously coloured by my prejudices which include using Subversion as a revision control package. You might like this or might not, but you may wish to consider it if you have not encountered something like Subversion before as being able to travel backwards in time through previous versions of your router’s (or anything else) configuration can come in very handy.

You may be thinking that you can do this already with a backup mechanism whereby you can restore previous versions of the configuration from tape, and undoubtedly thinking that in practice you don’t use it. Indeed I have found that even with very convenient access to the restoration mechanism, restoring files from tape is just too much work to do for anything less than serious – certainly trivial questions like “why did we turn on ‘warm-reboot’ and when?’ just don’t get answered. However they can and do get answered when using a revision control mechanism.

There is also the built-in archiving mechanism on the router itself, which is an option. However this option does not quite match Subversion for convenience, features, and indeed efficiency. But if you choose the archiving option, at least use an archive location not on the router itself!

The section on turning on warm rebooting has been moved to a new “tweaks” blog posting.

Copying Configuration Files

To make use of any Unix tools such as Subversion, we need a mechanism to copy files from the Cisco router to the Unix machine (and visa-versa). My chosen method is SSH (and “SCP”) although there are many other possibilities including the traditional option of TFTP. However using something a little less 1980s such as SSH is worth considering.

Before attempting to copy any configuration anywhere, we need a few details :-

  1. The name of the server providing the SSH service. In the example below, the server is called “hemp-chocolate” (and is in the same DNS domain as the router).
  2. The username on that SSH server which is roocfg in the example below.
  3. And finally the password for that user account.

To copy the configuration :-

router#copy startup-config scp://roocfg@hemp-chocolate/router.cfg
Address of name of remote host [cotton]?
Destination username [roocfg]?
Destination filename [router.cfg]?
Writing router.cfg
Password:
! Sink: C0644 3255 router.cfg
3255 bytes copied in 3.400 secs (957 bytes/sec)

Anyone surprised at the use of host names in the command above should be aware that my router quite happily uses the DNS.

There is a chance you may get a “protocol error” when performing that copy. This may be due to the ssh server and client not supporting a common set of ciphers; it seems that Cisco supports a limited set of ciphers. When this interacts with a server that supports a different limited set of ciphers (certain unsupported versions of Solaris), you may have issues. In which case switching to the real openssh software package (see OpenCSW) solves the problem.

Preparing The Repository

The first task is to create the repository – assuming you have already installed Subversion of course! The following instructions assume that the place in the filesystem for all repositories is /repositories.

# svnadmin create /repositories/router-configuration
# chown -R roocfg /repositories/router-configuration

The permissions changes are my way of ensuring that the user:roocfg will be able to use Subversion without permissions problems. There are different ways to handle this, but this one works for me. After creating the repository, the next task is to check out a working copy of the repository which we will use to copy configuration files into.

To do this, we switch to the user:roocfg, check out a working copy, move all of the contents of the new subdirectory into the user’s home directory, and check in the first version of the configuration file.

# su - roocfg
$ svn co file:///repositories/router-configuration
Checked out revision 0.
$ mv router-configuration/.svn .
$ rm -rf router-configuration
$ svn status
?       .bashrc
?       .sh_history
?       router.cfg
?       .subversion
?       .profile
$ svn add router.cfg
A         router.cfg
$ svn commit

The commit command drops you into an editor to write details of what you are committing. These details are important for future reference in the sense they describe the change you are making. Subversion can show you the actual differences between two different versions; the log entry that you write when committing a change tells you why the change was made – or perhaps logs a change control system ticket to refer back to.

At this point we can commit a change to the Subversion repository by :-

  1. Copying the configuration to the repository server.
  2. Logging into that account and committing a new version to the repository with an appropriate comment.

This is of course a manual process so is not ideal. When it should be done is up to you, but during pre-production, it is useful to commit a change at every significant milestone … but not every tiny tweak. Whereas in production, every change should be committed so it can be reverted.

Final Word

Not!

There is plenty more that could be done here, which I may return to in the future.

  1. It would be nice if the router were to automatically copy the configuration to the repository server in case someone forgets to perform the manual process. If the repository were reachable via TFTP, this could be setup with the router’s Kron facility, but a different method will be necessary for an SCP reachable repository.
  2. We need to be able to use the contents of the repository to configure the router. This is possible in various ways, but which one works best ?
Jan 052011
 

Firstly I will point out that this series of blog entries has nothing to do with Apple’s OSX operating system build for the iPhone retrospectively named iOS; these are about a far older operating system from Cisco that runs on most of their routers and switches – IOS. They are intended as ‘aide memoires’ for myself – a crusty old Unix geek who wanted to find out about this IOS stuff when he finally got sick and tired of consumer grade routers.

The router I’m using for all of this is a Cisco 881W running IOS version 15. This is a ridiculously overpowered router for a domestic broadband connection, but it does have lots of interesting stuff to play with.

Now to the disclaimer part – I’m no CCIE; I’m a Unix geek and whilst I have considerable experience with networking, it has all been with networking services such as DNS and DHCP. So anything you find here could well be done better in a different way. Or perhaps I’ve encountered a feature that shouldn’t be used just yet, or perhaps I’ve found something in my ignorance that could actually be useful!