-
Notifications
You must be signed in to change notification settings - Fork 2
Vacm
The View Access Control Model is one of the more complex configuration options that Net-SNMP offers.
The Access Control section of the snmp.conf manual page talks about VACM setup, and has the most current information. Check there first.
A user-contributed image and text-representation of the relationships can be found on the VACM tutorial page.
We also provide this handy diagram showing how include/exclude functions overlay each other within a "fake" mib tree:
none
In response to the "arrgh, this is too complex for my poor little
brain!" types of messages we get about configuring access control, you
can avoid it if your needs are simple. So, if you just want to give a
user read or write access to the entire MIB tree, you can use the ro
and rw
configuration options, which specify read-only (ro) or
read-write (rw) access.
These directives allow access for community based requests, optionally restricted to a particular range of source IP addresses, and/or a specific OID. See the snmpd.conf man page for detail, but the general form is:
rocommunity COMMUNITY [SOURCE [OID]]
rwcommunity COMMUNITY [SOURCE [OID]]
rocommunity6 COMMUNITY [SOURCE [OID]]
rwcommunity6 COMMUNITY [SOURCE [OID]]
With version 5.3 and above, this directive can also restrict access to a named view, using the syntax
rocommunity COMMUNITY SOURCE -V VIEW
rwcommunity COMMUNITY SOURCE -V VIEW
rocommunity6 COMMUNITY SOURCE -V VIEW
rwcommunity6 COMMUNITY SOURCE -V VIEW
These directives allow access for SNMPv3 users, optionally requiring a certain access level and restricting the user to a specific OID. See the snmpd.conf man page for detail, but the general form is:
rouser USER [noauth|auth|priv [OID]]
rwuser USER [noauth|auth|priv [OID]]
With version 5.3 and above, this directive can also restrict access to a named view, using the syntax
rouser USER noauth|auth|priv -V NAME
rwuser USER noauth|auth|priv -V NAME
Here are some examples of more complex configurations, include supporting different views for a SNMPv3 user based on their security level.
####
# 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 custom_sec 192.168.1.0/24 public
####
# Second, map the security names into group names:
# sec.model sec.name
group custom_grp v1 custom_sec
group custom_grp v2c custom_sec
group incremental usm myuser # SNMPv3 username == sec.name
####
# Third, create a view for us to let the groups have rights to:
# incl/excl subtree mask
view all included .1
view custom_v excluded .1
view custom_v included sysUpTime.0
view custom_v included interfaces.ifTable
view mini_view excluded .1 80
view mini_view included sysUpTime.0
view if_view excluded .1 80
view if_view included sysUpTime.0
view if_view included ifTable
####
# 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 custom_grp "" any noauth exact cust1_v none none
access incremental "" usm noauth exact mini_view none none
access incremental "" usm auth exact if_view none none
access incremental "" usm priv exact all_view none none
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)
Note: The mask seperator character can be "." or ":".
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.
SNMPv3 'contexts' can be emulated for SNMPv1 and SNMPv2 communities, as explained on this page for configuring multiple proxies.