Difference between revisions of "Vacm"
Line 20: | Line 20: | ||
ff.a0 == 11111111.10100000. which nicely covers up and including | ff.a0 == 11111111.10100000. which nicely covers up and including | ||
the row index, but lets the user vary the field of the row) | 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 <code>exclude</code> 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. |
Revision as of 16:13, 19 December 2006
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.