Saturday, April 13, 2013

Privilege & Role Based CLI

Lacking an ACS server, IOS gives us two options for controlling what users can do. 

The simpler, but less scalable of the two uses the familiar privilege levels.
The concept is easy, assign certain commands to certain privilege levels, then assign those levels to a user.

By default, only three of the 16 levels are in use.
Privilege 0 - access to almost nothing
Privilege 1 - Access to basic non-configuration commands, commonly known as "user exec"
Privilege 15 - Access to everything, commonly known as "privilege exec"

The leaves 2-14 for customization!

Every level has access to all the commands available underneath it.
So if I assign commands to level 10, level 11 will also have access to them.

Let's assign some basic commands to level 7.
We'd like it to be able to debug rip and show running config.

privilege exec level 7 debug ip rip
privilege exec level 7 show running-config
username basic privilege 7 password basic

Before we test it, let's look at the actual config we got.

privilege exec level 7 show running-config
privilege exec level 7 show
privilege exec level 7 debug ip rip
privilege exec level 7 debug ip
privilege exec level 7 debug

You'll see that there is some basic hierarchy involved here.  Allowing a longer command automatically includes the ones precluding it.

Now let's telnet in as user "basic" and see what we have.

Trying 192.168.0.1 ... Open

User Access Verification

Username: basic
Password:

R1#
R1#sh run
Building configuration...
Current configuration : 57 bytes
!
boot-start-marker
boot-end-marker
!
end

Not much config there - that's because we can only see what we're given access to, which is nothing presently.

R1#debug ip rip
RIP protocol debugging is on
R1#undebug ip rip
    ^
% Invalid input detected at '^' marker.

Debug yes, undebug no.
Don't forget to include all your relevant commands!

That covers the basics.  Let's look at the tricky stuff.

What I found to be the most confusing aspect was it's lack of better hierarchy.  If you type:

privilege ?

  RITE-profile                    Router IP traffic export profile command mode
  RMI-Node-Config                 Resource Policy Node Config mode
  RMI-Resource-Group              Resource Group Config mode
  RMI-Resource-Manager            Resource Manager Config mode
  RMI-Resource-Policy             Resource Policy Config mode
  SASL-profile                    SASL profile configuration mode
  aaa-attr-list                   AAA attribute list config mode
  aaa-user                        AAA user definition
  accept-dialin                   VPDN group accept dialin configuration mode
  accept-dialout                  VPDN group accept dialout configuration mode
  acct_mlist                      AAA accounting methodlist definitions
  address-family                  Address Family configuration mode

.... I'm going to stop it there - mid-way through "A" - because there are 270 items on this list as of 12.4(15)T.  v15.0 has over 370!

There are three you're going to use all the time:

privilege exec
privilege configure
privilege interface

exec controls exec commands, configure controls what can be done inside "configure terminal", and interface controls what can be done on interfaces.

Now it's beyond me why they didn't stagger it a bit more.  I would've written it more along the lines:

privilege exec [configure] [configure interface] etc... instead, we end up with all these top-level commands that are hard to figure out.  So, for example, if you wanted to be able to be able to have a user do nothing but "shut" and "no shut" interfaces, you'd have to:

privilege exec level 7 configure terminal
  Give access from exec mode into configure mode

privilege configure level 7 interface
  ...Once in configure mode, give access to the interfaces

privilege interface level 7 shutdown
  ...Allow shutdown inside an interface 

privilege interface level 7 no shutdown
  ...Allow no shutdown inside an interface

Let's look at an oddity before we move on to more advanced topics.

First, you'll notice my comment above about interface regarding "give access to the interfaces".  That's right, you can't give access to just Fa0/0, or Lo0, etc, with the privilege command.  Check it out:

R1(config)#privilege configure level 7 interface fa0/0

The command takes, but if you look at the config:

R1#sh run | i priv
privilege interface level 7 shutdown
privilege interface level 7 no shutdown
privilege interface level 7 no
privilege configure level 7 interface
privilege exec level 7 configure terminal
privilege exec level 7 configure

notice it's still just "interface".  You can get all interfaces:

R4(config)#int lo0
R4(config-if)#int lo1
R4(config-if)#
*Mar  1 00:19:13.563: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback0, changed state to up
*Mar  1 00:19:15.723: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback1, changed state to up
R4(config-if)#int fa0/1
R4(config-if)#

You can correct this by using Role Based CLI, which we'll cover further down. 

How's about if you wanted to create a privilege with all the subcommands?  The usage feels a little awkward.  Let's say you wanted to allow all interface-level commands.  The natural feeling option would be to use privilege interface all for this, but in fact the proper usage is:

privilege configure all level 7 interface

Another example is giving access to all router subcommands.  If you wanted to do just one at a time, you'd:

privilege configure level 7 router
privilege router level 7 network
privilege router level 7 redistribute

(on a side note, note this gives you access to run "network" and "redistribute" on all router processes - bgp, rip, ospf, eigrp, etc - and there's no way to make that more granular)

If we wanted all network commands in one stroke, all we'd need is:

privilege configure all level 7 router

There are tons of options to explore under "privilege", but exploring them all would take me weeks.  Let's look at a particularly interesting couple I stumbled across.  How's about being able to limit the modifications made inside an access list? 

Introducing ipsnacl and ipenacl. 

Let's create a user that can only create permits inside standard acls, and denies inside extended ACLs:

username bonkers privilege 5 password bonkers
privilege exec level 5 configure terminal
privilege configure level 5 ip access-list
privilege configure level 5 ip access-list extended
privilege configure level 5 ip access-list standard
privilege ipenacl level 5 deny
privilege ipsnacl level 5 permit

Now for the testing...

R1(config)#ip access-list standard standardacl
R1(config-std-nacl)#permit 1.1.1.1 255.255.255.255
R1(config-std-nacl)#deny 2.2.2.2 255.255.255.255
                      ^en
% Invalid input detected at '^' marker.
R1(config-std-nacl)#ip access-list ext extendedacl
R3(config-ext-nacl)#permit ip 1.1.1.1 255.255.255.255 2.2.2.2 255.255.255.255
                    ^
% Invalid input detected at '^' marker.
R3(config-ext-nacl)#deny ip 2.2.2.2 255.255.255.255 3.3.3.3 255.255.255.255

Don't ask me why you'd ever want to do this in production, but it is the tricky kind of stuff - for easy points - that shows up on the lab exam.

One last thing worth mentioning with privilege.  It's likely you'd just set the privilege by user, the way I've been doing it, but you can actually just give someone privilege 1 and then have them enable to the correct level.  For example:

R1(config)#username generic password generic
R1(config)#enable secret level 5 level5pw

telnetting in...

User Access Verification

Username: generic
Password:
R3>
R3>enable 5
Password: (input not seen)
R3#
R3#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R3(config)#ip access standard 5
R3(config-std-nacl)#?
Standard Access List configuration commands:
  <1-2147483647>  Sequence Number
  default         Set a command to its defaults
  exit            Exit from access-list configuration mode
  no              Negate a command or set its defaults
  permit          Specify packets to forward

Notice deny is missing; this is the same level 5 we just setup.

Now let's move on to Role Based CLI or Role Based Access Control.  If you've got the command syntax down from the privilege method, this method is a piece of cake to pick up.

The big difference is it's hierarchical, although the command allowing is still just as wonky as it is with privilege.

First and foremost, you have to enable AAA:

aaa new-model

you must have a "root" enable password:

enable secret cisco

Note this is just your ordinary enable password, but you'll see why we call it root in a bit.
Next you have to enable views:

enable view  ! note this is a privilege exec command
Password: (root enable password)
R3#
*Mar  1 00:04:52.167: %PARSER-6-VIEW_SWITCH: successfully set to view 'root'.

Now let's create a custom view for our noc/tier 1 support users:

parser view noc
 secret nocpw
 commands exec include undebug ip rip
 commands exec include show running-config
 commands exec include debug ip rip

Just for reference, note what IOS expands this to:

parser view noc
 secret 5 $1$.QL0$ozHC3EZxIwetfJMKjiZNc.
 commands exec include undebug ip rip
 commands exec include undebug ip
 commands exec include undebug
 commands exec include show running-config
 commands exec include show
 commands exec include debug ip rip
 commands exec include debug ip
 commands exec include debug

Let's try applying this to a user:

username nocuser view noc password nocuser

telnetting in...

Trying 192.168.0.1 ... Open

User Access Verification
Username: nocuser
Password:

R3>

User exec?  That's not very helpful.  If you were to type "enable", you'd have to have the root password, and that would get you full access.  You could enable just your view, if you have the password:

R3>enable view noc
Password:

R3#

but that's still not ideal, because you could've just created a privilege 1 user and have had him do that regardless.  The trick to fixing this problem lies mostly in AAA :

aaa authorization exec default local

But that's not all, it turns out the user has to have an appropriate privilege level as well:

username nocuser view noc privilege 15 password nocuser

telnetting back in...

Trying 192.168.0.1 ... Open

User Access Verification

Username: nocuser
Password:

R3#

There we go... let's check out our command availability:

R3#conf t
    ^
% Invalid input detected at '^' marker.

R3#sh run
Building configuration...
Current configuration : 19 bytes
!
!
end

R3#debug ip rip
RIP protocol debugging is on
R3#undebug ip rip
RIP protocol debugging is off
R3#

That's about what we expected to see.  The "show run" is kind of useless because this user can't configure anything, but that's what we asked IOS to do, and it did it.

Now let's create a view for a basic BGP admin.

parser view bgp
 secret bgppw
 commands exec include configure terminal
 commands configure include router bgp
 commands router include network
 commands router include neighbor
 username bgpadmin privilege 15 view bgp secret bgppw

If we telnet in, we'll see we can create a BGP process:

router bgp 100
 network 4.4.4.4
 neighbor 5.5.5.5
% Incomplete command.
 neighbor 5.5.5.5 ?
  version  Set the BGP version to match a neighbor

...but there's some problems.

Specifically, we can't create commands inherent to using neighbor or network.  Neighbor can't have an AS-number set, and network can't use the mask command. Let's go fix it.

parser view bgp
 secret bgppw
 commands exec include configure terminal
 commands configure include router bgp
 commands router include all network
 commands router include all neighbor

Meanwhile, back on our telnet session...

router bgp 100
 network 4.4.4.4 mask 255.255.255.255
 neighbor 5.5.5.5 remote-as 77

There we go.  Now let's look at our config.

R1#sh run | s router bgp
      ^
% Invalid input detected at '^' marker.

Uh-oh.  We didn't trust this guy much either, he can't see the running config.
Let's make a boss account that has the privilege of both the noc and the bgp tech.

parser view boss superview
 secret important
 view noc
 view bgp

username boss privilege 15 view boss secret important

superviews are aggregate views that include other views.  Let's test it out by telnetting in.

User Access Verification

Username: boss
Password:

R3#sh run
Building configuration...
Current configuration : 122 bytes
!
!
router bgp 100
 network 4.4.4.4
 network 4.4.4.4 mask 255.255.255.255
 neighbor 5.5.5.5 remote-as 77
!
!
end

Now we have the show running-config from the NOC and the BGP privileges of the BGP tech.

I mentioned earlier in the article that granular per-interface control couldn't be granted with privilege, but that it could be done with the role-based method.  Let's take a look at that.  How's about a user that works on Ethernet cabling and should have the ability to shut/no shut physical Ethernet interfaces, but we don't want him creating loopbacks or messing with WAN links.

parser view layer1
 secret layer1
 commands interface include shutdown
 commands interface include no shutdown
 commands exec include configure terminal
 commands configure include interface
 commands configure include interface FastEthernet0/0
 commands configure include interface FastEthernet0/1
username layer1tech privilege 15 view layer1 secret cableguy

telnetting in....

User Access Verification

Username: layer1tech
Password:

R3#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R3(config)#int fa0/0
R3(config-if)#no shut
R3(config-if)#int fa0/1
R3(config-if)#no shut
R3(config-if)#int lo0
                    ^
% Invalid input detected at '^' marker.
R3(config)#int lo1
                 ^
% Invalid input detected at '^' marker.
R3(config)#int serial1/1
               ^
% Invalid input detected at '^' marker.

We see he can get to only the appropriate interfaces.

How's about a view that can get to everything in configuration mode except the routing processes?:

parser view manycommands
 secret miniadmin
 commands configure exclude router
 commands exec include all configure terminal
 commands exec include configure

Of important note, the "exclude" appears to have some bugs in 12.4(15)T.  I had to enter this about three times to get it to stick.  It kept telling me that the command I was trying to exclude was already listed as an include.  I'd blank my config and start over, and it would still tell me the same thing, even if I entered it first.  Hopefully this won't be on the lab exam, because it seems pretty flaky.  Do note, however, that I did get this config working & tested.

Let's go back to our earlier noc view.  Let's be sure no other views can debug ip rip, that's just for the noc.

parser view noc
 commands exec include-exclusive debug ip rip

R1(config)#parser view noc2
R1(config-view)#secret noc2
R1(config-view)#commands exec include debug ip rip
% Command present in 'include-exclusive' mode

...now it can't be added to "noc2".

Cheers,

Jeff

2 comments:

  1. Hi Jeff,
    I've been trying to use a parser view so that:
    1) a script can add a 'permit' line to a ext ACL
    2) later the script goes and removes that 'permit' line from the ext ACL
    Sometimes 2) works and sometimes it doesn't (probably after a router restart).
    My config:
    commands ipenacl include permit tcp any any
    commands ipenacl include permit tcp any
    commands ipenacl include permit tcp
    commands ipenacl include permit
    commands ipenacl include no (this is the line that doesn't stick)

    Any ideas?
    Cheers

    ReplyDelete