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
great work. thanks.
ReplyDeleteHi Jeff,
ReplyDeleteI'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