Vacm

From Net-SNMP Wiki
Revision as of 16:13, 19 December 2006 by Rstory (Talk | contribs)

Jump to: navigation, search

Restricting access to a particular index (row) in a Table

Using the view directive in snmpd.conf, one can limit users to a single row in a table. To do this , the optional mask parameter is specified. Here is an excerpt from the man page:

      view NAME TYPE SUBTREE [MASK]
             The defines the named view. TYPE is either included
             or  excluded.   MASK is a list of hex octets, sepa-
             rated by '.' or ':'.  The MASK defaults to "ff"  if
             not specified.

             The  reason  for the mask is, that it allows you to
             control access to one row in a table,  in  a  rela-
             tively  simple  way.  As  an example, as an ISP you
             might consider giving each customer access  to  his
             or her own interface:

             view cust1 included interfaces.ifTable.ifEntry.ifIndex.1 ff.a0
             view cust2 included interfaces.ifTable.ifEntry.ifIndex.2 ff.a0

             (interfaces.ifTable.ifEntry.ifIndex.1 == .1.3.6.1.2.1.2.2.1.1.1,
             ff.a0 == 11111111.10100000. which nicely covers up and including
             the row index, but lets the user vary the field of the row)

So, to be a little more visual about it:

.1.3.6.1.2.1.2.2.1.1.1 == interfaces.ifTable.ifEntry.ifIndex.1 
 1 1 1 1 1 1 1 1 1 0 1 (00000) == (ff.a0)
               ^ ^ ^ ^
               | | | |-- the index
               | | |---- the column
               | |------ ifEntry
               |-------- ifTable

So each bit in the mask indicates if the corresponding OID must match or not. In the above example, all parts of the OID except the colum must match. So this view allows access to any column of the first row in the ifTable. So, paired with an exclude row for the ifTable, only row 1 would be accessible to the user.

Now, to bring it all together with the other access control directives. Assuming 2 customers, and each is only connected to a specific interface (eg customer 1 is connected to eth0 and customer 2 is connected to eth1):

####
# First, map the community name (COMMUNITY) into a security name
# (local and mynetwork, depending on where the request is coming
# from):

#       sec.name  source          community
com2sec local     localhost       secret42
com2sec cust1_sec 192.168.1.0/24  public
com2sec cust2_sec 192.168.2.0/24  public

####
# Second, map the security names into group names:

#               sec.model  sec.name
group MyRWGroup v1         local
group MyRWGroup v2c        local

group cust1_grp v1         cust1_sec
group cust1_grp v2c        cust1_sec

group cust2_grp v1         cust2_sec
group cust2_grp v2c        cust2_sec

####
# Third, create a view for us to let the groups have rights to:

#           incl/excl subtree                              mask
view all    included  .1

view cust1_v excluded  .1
view cust1_v included  sysUpTime.0
view cust1_v included  interfaces.ifTable.ifEntry.ifIndex.1 ff.a0

view cust2_v excluded  .1
view cust2_v included  sysUpTime.0
view cust2_v included  interfaces.ifTable.ifEntry.ifIndex.2 ff.a0

####
# Finally, grant the groups access to their views:

#                context sec.model sec.level match  read     write  notif
access MyRWGroup ""      any       noauth    exact  all      all    none
access cust1_grp ""      any       noauth    exact  cust1_v  none   none
access cust2_grp ""      any       noauth    exact  cust2_v  none   none

It is important to note that this works because the customers are on different networks. If all the customers are on the same network, then it is important to note that sniffing network traffic could expose one customer's "community string" to another customer, allowing the second customer to view the first customers interface statistics via SNMP. In this case, you would want to use the encryption capabilities offered by SNMPv3 usm users, instead of SNMPv1 and SNMPv2 community strings.