InnerhalbNach weiteren Dokumenten suchenSupport-Ressourcen | Dieses Buch im PDF-Format herunterladen (1891 KB)
Chapter 16 Creating an SNMP AgentUsing the Java Dynamic Management Kit (Java DMK), you can create an agent application that is both an SNMP agent and a normal Java Management Extensions (JMX) agent. SNMP MIBs can be represented as MBeans and the SNMP protocol adaptor exposes them to SNMP managers. Only MBeans derived from MIBs can be managed through the SNMP protocol adaptor, but other managers can view and access them through other protocols. The mibgen tool provided generates the code for MBeans that represent a MIB. Groups and table entries are represented as MBean instances that expose the SNMP variables through their attributes. The mibgen tool creates skeleton getters and setters that only read or write internal variables. To expose the behavior of your host machine or device, you need to implement the code that accesses the host- or device-specific functionality. There are two SNMP protocol adaptors in the Java DMK 5.1.
The program listings in this tutorial show only functional code: comments and output statements have been modified or removed for space considerations. However, all management functionality has been retained for the various demonstrations. The complete source code is available in the current/Snmp/Agent example directory located in the main examplesDir (see “Directories and Classpath” in the Preface). This chapter covers the following topics:
16.1 MIB Development ProcessHere we describe the process for making MIBs manageable through the SNMP protocol adaptor of the Java DMK. In our example, we demonstrate this process on a subset of the MIB-II defined by RFC 1213. Once you have defined the MIB you want to manage in your SNMP agent you need to generate its MBean representation using the mibgen tool. This tool generates MBeans that represent the whole MIB, each of its groups and nested groups, and each of its table entries. This command-line tool and its output are fully described in the Java Dynamic Management Kit 5.1 Tools Reference Guide. The mibgen tool only generates the MBean structure to represent the MIB, it is up to the developer to implement the MIB functionality inside the generated classes. Our example gives only a simple implementation of the MIB-II for demonstration purposes. However, this shows you the way to extend the generated classes to provide your own implementation. The mibgen tool handles all three SNMP protocols identically, and the MIBs implemented are entirely protocol neutral. Consequently, code generated by mibgen for previous versions works perfectly in the SNMPv3 framework. 16.1.1 Generating MIB MBeansTo run the mibgen tool for our example, go to the examplesDir/current/Snmp/Agent directory and type the following command:
This generates the following files in the current directory:
The MBean with the name of the MIB is a central administrative class for managing the other MBeans that represent the MIB groups and table entries. All of the other MBeans contain the SNMP variables as attributes of their management interface. The mibgen tool generates standard MBeans for the MIB, so attributes are implemented with individual getter and setter methods. These MBeans are just skeletons, meaning that the attribute implementations only return a default value. You must implement the getters and setters of the attributes to read and write data with the correct semantic meaning of the SNMP variable. Because SNMP does not support actions in MIBs, the only operations in these MBeans are checkers associated with the SNMP “Set” request in writeable variables. Again, these are skeleton methods that you must implement to do the checks that you require before the corresponding “Set” operation. You can add operations and expose them in the MBean interface, but the SNMP manager cannot access them. However, other managers can call these operations if they are connected through another protocol. 16.1.2 Implementing the MIBOur example only implements a fraction of the attributes, those that are used in this tutorial. The others are simply initialized with a plausible value. Using DEFVAL statements in our MIB, we could force mibgen to generate MBeans with user-defined default values for attributes. As this is not done in our example, mibgen provides a plausible default value according to the variable type. Our implementations of MIB behavior are contained in the classes with the Impl suffix. These implementation classes extend those that are generated by mibgen so that we can regenerate them without overwriting our customizations. Here is a summary of the implementation shown in the agent example:
The SnmpImpl.java and SystemImpl.java files provide code that you can reuse when you need to implement these common SNMP groups. 16.1.3 Compiling the MBeans and AgentsCompile all the classes in the examplesDir/current/Snmp/Agent directory. The classpath must contain the current directory (.):
We are now ready to look at the implementation of SNMPv1/v2 and SNMPv3 agents and run the example applications. 16.2 SNMP Protocol AdaptorOnce your MIBs are implemented as MBeans, your agent application needs an SNMP protocol adaptor to function as an SNMP agent. Because the SNMP adaptor is also an MBean, it can be created and started dynamically in your agent by a connected manager, or through the HTML adaptor. Since Java DMK 5.1, the performance of the SNMP protocol adaptor has been improved by the addition of multithread support. The following SNMPv1/v2 Agent example launches the protocol adaptor for SNMPv1/v2 agents, through the code of the agent application. Example 16–1 SNMPv1/v2 Agent Application
The following SNMPv3 AgentV3 example launches the protocol adaptor for SNMPv3 agents, in the same way as in the SNMPv1/v2 Agent example. This example creates a simple SNMPv3 agent, without encryption. See "Security Mechanisms in the SNMP Toolkit" for details of how to implement SNMPv3 agents with encryption. Example 16–2 SNMPv3 AgentV3 Application
16.2.1 Starting the SNMP AdaptorWe start the SNMP adaptor in the same way that we start the HTML adaptor. First we create a meaningful object name for its MBean, then we instantiate the class with a constructor enabling us to specify a non-default port, we register the MBean with the MBean server, and we start the adaptor to make it active. By default, the SNMP protocol adaptor uses the standard SNMP port 161. Because other applications might be using this port on a host, our simple agent, and all the other examples in this section, use port 8085. When we connect to this agent, our SNMP manager must specify this non-standard port number. Note – On certain platforms, applications also require superuser privileges to assign the default SNMP port 161. If your SNMP adaptor uses this port, its agent application must be started with superuser privileges. 16.2.2 Creating MIB MBeansOur agent application creates and manages one MIB, our subset of MIB-II. To do so, it instantiates the corresponding RFC1213_MIB MBean that was generated by the mibgen tool (see 16.1 MIB Development Process). We give it a meaningful object name and then we register it in the MBean server. The registration process enables the MBean to instantiate and register other MBeans that represent the groups of the MIB and the entries of its tables. The set of all these MBeans at the end of registration makes up the MBean representation of the MIB. If an SNMP manager later adds entries to a table, the MIB implementation registers the new entry MBean into the MBean server as well. If you do not want to expose a MIB through the MBean server, you do not have to register it. However, you still need to create all of its other MBean objects so that the SNMP adaptor can access all of its groups and table entries. The generated code provides the init method in the main MBean of the MIB. Calling this method creates all necessary MBean objects without registering them in the MBean server. 16.2.3 Binding the MIB MBeansThe SNMP adaptors do not interact with MBeans in the same way as the other connectors and adaptors. Because the SNMP data model relies on MIBs, only MBeans representing MIBs can be managed through SNMP. The SNMP adaptor does not interact with MBeans of a MIB through the MBean server, they must be explicitly bound to the instance of the SNMP adaptor. After a MIB is instantiated, you must add the MIB to the SNMP adaptor by calling the setSnmpAdaptor method. In the binding process, the SNMP adaptor obtains the root OID of the MIB. The adaptor uses this OID to determine which variables are implemented in the MIB's corresponding MBeans. Even though the SNMP adaptors can be registered in the MBean server, the adaptor only makes MIBs visible to SNMP managers. Other MBeans in the agent cannot be accessed or even represented in the SNMP protocol. The SNMP manager is limited by its protocol: it cannot take full advantage of a Java dynamic management agent through the basic MIBs, and it does not have access to any other MBeans. In an advanced management solution, you could write a special MIB and implement it so that operations on its variables actually interact with the MBean server. This is left as an exercise for the reader. 16.2.4 MIB ScopingIn the SnmpV3AdaptorServer, it is possible to specify a scope, or context name, when registering a MIB. Conceptually, there is one instance of the global OID tree per scope. If you do not specify a context name when registering a MIB, the MIB is registered in the default scope. You can thus register SnmpProxy objects in any default or specific scope. Routing and MIB overlapping is handled in the same way in any scope. When an incoming request is received, the SnmpV3AdaptorServer first determines the scope of that request. Only the SNMP agents that have been registered in that scope are triggered by that request. If the incoming request is an SNMPv3 request, the scope is identified by the context name specified in the request protocol data unit (PDU). If no context name is specified, the scope of that request is the default scope. If the incoming request is an SNMPv1 or v2 request, the scope of the request is the default scope, unless mapping community strings to context names is enabled in the adaptor. To register a MIB in a specific context, call the following method: myMib.setSnmpAdaptor(myAdaptor, "myContext") This method only works for adaptors that have been registered with an MBean server. 16.2.5 Accessing a MIB MBeanOnce the MBean representing a MIB has been instantiated and bound to one of the two SNMP adaptors, it is accessible through that SNMP adaptor. SNMP managers can send requests to operate on the contents of the MIB. The SNMP adaptor interprets the SNMP management requests, performs the operation on the corresponding MBean and returns the SNMP response to the manager. One SNMP protocol adaptor is compatible with SNMPv1 and SNMPv2c, and the other is compatible with these two protocols as well as SNMPv3. The advantage of having an SNMP agent “inside” a Java dynamic management agent is that you can use the other communications protocols to interact with MIBs and manage the SNMP adaptor. Because both the registered MIBs and the adaptor are MBeans, they are exposed for management. In our simple agent, the MIB was registered, and you can view its MBeans in a web browser through the HTML protocol adaptor. If our agent were to include other connectors, management applications could connect to the agent and also manage the MIB and the SNMP adaptor. A non-SNMP manager could instantiate new MIB objects, bind them to the SNMP adaptor and operate on the exposed attributes and operations of the MIB. Non-SNMP managers can operate on the variables of a MIB, getting and setting values, regardless of any SNMP manager that might also be accessing them through the SNMP adaptor. When dealing with a table, however, they cannot create new table entry MBeans without adding them to the table. For example, in the InterfacesImpl.java class, we called the addEntry method of the IfTable object before registering the entry MBeans with the MBean server. This ensures that the new entries are visible when an SNMP manager accesses the table. In order for a non-SNMP manager to create a table entry, you must customize the table's group MBean to expose this functionality. Briefly, you would need to write a new method that instantiates and initializes the entry's MBean, adds the MBean to the table object, and registers the entry MBean in the MBean server. Advanced customization such as this is not covered in our examples. In general, the designer of the agent and management applications is responsible for all coherency issues when accessing MIBs concurrently through different protocols and when adding table entries. 16.2.6 Managing the SNMP AdaptorsNon-SNMP managers can also control the SNMP agent through the MBean of the SNMP adaptors. Like the other communications MBeans, the port and other attributes can be modified when the SNMP adaptor is stopped. You can also get information about its state, and stop or restart it to control when it is online. These administrative attributes and operations are defined in the CommunicatorServerMBean interface. The SNMPv1v/2 adaptor server implements the SnmpAdaptorServerMBean interface to define its operating information. The SNMPv3 adaptor server implements a similar interface called SnmpV3AdaptorServerMBean. The SNMP protocols define certain variables that SNMP agents must expose about their current state. For example, the SNMP adaptor provides methods for getSnmpInPkts and getSnmpOutBadValues. Non-SNMP managers can read these variables as attributes of the SNMP adaptor MBean. The SNMP adaptors also expose other operating information that is unavailable to SNMP managers. For example, the ActiveClientCount and ServedClientCount read-only attributes report on SNMP manager connections to this agent. The read-write BufferSize attribute enables you to change the size of the message buffer, but only when the adaptor is not online. The adaptor MBean also exposes operations for sending traps or implementing your own security (see 19.2.1 Enabling User-Based Access Control). To Run the SNMPv1/v2 Agent Example
16.2.7 Configuring SNMPv3 Security for AgentsBefore you run the SNMPv3 agent examples, you require some information about how SNMPv3 security is configured. Below are brief descriptions of the SNMPv3 security files that provide you with the information you need to run the SNMPv3 examples in this chapter. Full descriptions of the SNMPv3 security mechanisms are given in 19.3 SNMPv3 User-Based Security Model. The SNMPv3 security mechanisms are defined in two text files:
The files used by the SNMPv3 agent examples are provided in the examplesDir/current/Snmp/Agent directory. These files are used by the examples in the subsequent sections of this chapter. Example 16–3 A jdmk.security File for an SNMPv3 AgentThe jdmk.security identifies the SNMP engine, authorized user and the security settings for the SNMPv3 session: #Local engine ID localEngineID=0x8000002a05819dcb6e00001f95 #Number of boots localEngineBoots=0 #User and security configuration userEntry=localEngineID,defaultUser,,usmHMACMD5AuthProtocol,mypasswd The local engine ID and the number of times that engine will boot are read by the agent when it is created. The authorized users and the security levels for the SNMP session are defined by the userEntry. This particular jdmk.security file defines a user that implements authentication, but not privacy. Consequently, the settings are as follows:
Note – User-based access control is not used by the examples in this chapter, so we do not examine the jdmk.uacl file here. See Chapter 19, Security Mechanisms in the SNMP Toolkit to find out how to implement user-based access control. To Run the SMNPv3 AgentV3 Example
16.3 Sending TrapsAgents can send unsolicited event reports to management applications by using traps. The SNMP protocol adaptor can send v1, v2 and v3 traps, the differences being in the format of the corresponding PDU. Traps in the SNMP specification are not acknowledged by the management application, so agents do not know if traps are received. However, under SNMPv2 and v3, acknowledgements can be sent in the form of informs. Inform requests are acknowledged event reports, they are sent by entities acting in a manager role, according to RFC 1905. In the Java DMK, both the SNMP adaptor and the classes of the SNMP manager API can send inform requests. Manager-to-manager inform requests are described in 17.3 Inform Requests. Agent-to-manager inform requests are demonstrated by the applications in the current/Snmp/Inform/ example directory located in the main examplesDir directory. In this example, we demonstrate how our simple SNMP agent application can send traps. The class IfEntryImpl in the example directory extends the IfEntry class generated by mibgen to provide a method that switches the IfOperStatus variable and sends a trap. Before sending the trap, the example establishes whether the agent is an SNMPv1/v2 agent or SNMPv3, and sends a trap accordingly. This is an example of customization of the generated code: an agent-side entity switches the operation status, the MIB variable is updated and a trap is sent to SNMP managers. Example 16–4 Sending a Trap in the IfEntryImpl Class
As the sendTrap method runs in a different thread, it needs to get a reference to the SNMP adaptor instance. Here we call the static methods of our different possible agent implementations. This code is specific to these agents and is only an example of how to retrieve this information. As shown in the above example, SNMPv1 traps are always sent, regardless of the version of SNMP of the agent. An SNMPv3 trap is sent only when the agent is an SNMPv3 agent. To simulate a live operation status, we invent the LinkTrapGenerator class that switches the status periodically. It is an MBean that contains a thread that loops endlessly. The interval period between traps and the number of the table entry can be modified through the MBean's attributes. Example 16–5 Thread of the Link Trap Generator
To run the trap generator, the example application instantiates and registers a LinkTrapGenerator MBean. During its registration, this MBean starts the thread, sending a trap every two seconds by default. Example 16–6 Starting the Trap Generator Example
16.3.1 Specifying the Trap DestinationThere are several methods in the SNMP protocol adaptor for sending traps to remote managers. They differ in their method signatures, depending upon whether or not you need to specify the destination host. When no host is specified, the SNMP protocol adaptor relies on the trap group definition in IP-based access control lists (InetAddressAcl), as described below. In all cases, traps are sent to the port specified by the current value of the TrapPort attribute on the SnmpAdaptorServer or SnmpV3AdaptorServer MBean. In our simple agent, we set the trap port to 8086, but this can be changed at any time by a custom MIB implementation or a management application. Although SNMPv3 implements user-based access control for other types of requests, traps and informs are always sent using InetAddressAcl, in all versions of SNMP. 16.3.1.1 Using an InetAddressAcl Trap GroupThe methods below were used in Example 16–4 to send SNMPv1 and v3 traps. They are presented here with their SNMPv2 equivalent (see the Javadoc API for a description of the parameters).
Using these methods, you must first define the trap group in an InetAddressAcl. See 19.1 IP-Based Access Control Lists for a formal definition of the trap group and instructions for defining the InetAddressAcl file when starting the agent. By default, these lists are file-based, but you can implement other mechanisms, as described in 19.1.3 Custom Access Control. In this example, we provide the following template file. Example 16–7 Trap Group of the jdmk.acl File
The trap group lists all the hosts to which the SNMP protocol adaptor sends every trap. A community definition associates a community name with a list of hosts specified either by one of the following identifiers:
All hosts in a community definition receive the trap in a PDU identified by the community name. Note – Because access control and trap recipients share the same file, you must fully define the access control when you want to send traps using the InetAddressAcl mechanism. Given this definition, traps are sent to a host called yourmanager, and the community string of the trap PDU would contain the value public. By adding community definitions to this file, you can specify all hosts that will receive traps along with the community string for each host or group of hosts. Note – SNMPv3 does not use the community string to identify destinations. Only use the manager's IP address when creating an SNMPv3 trap group, or the contextName to define the scope of the requests sent. If the InetAddressAcl file is not defined, or if the trap group is empty, the default behavior of these methods is to send a trap only to the local host. 16.3.1.2 Specifying the Hostname DirectlyThe other methods of the SNMP protocol adaptor, one for each trap version, enable you to send a trap to a specified recipient:
In the first two cases, these methods take an address and a community string, in addition to the version-specific trap information. The address is an InetAddress object that is usually instantiated by its static methods getLocalHost or getByName. The second method returns a valid InetAddress object when given a string representing a hostname or IP address. The cs parameter is the community string, a name that the agent and manager exchange to help identify one another. The string given is used as the community when sending the trap PDU. The SNMPv3 method also takes an InetAddress, but does not use the community string. Only use the manager's IP address when creating an SNMPv3 trap group, or the contextName to define the scope of the requests sent. Either one of these methods sends a trap to a single manager using a single community string. The InetAddressAcl trap group mechanism is better suited to sending traps to multiple managers, though it requires you to set up a trap group. Note that even if a trap group is in use, the two methods above only send one trap to the specified host address. 16.3.2 Traps in the Agent and AgentV3 ExamplesBefore starting the SNMP agent again, edit the jdmk.acl file to replace the occurrences of yourmanager with the name of a host running an SNMP manager. You can start the example SNMPv3 agent by replacing Agent with AgentV3. Start the agent, specifying the InetAddressAcl file as a property:
In these commands, nbTraps is the number of traps that the agent sends. Set it to a small integer to avoid too much output. If you omit this parameter, traps are sent continuously. If you do not have an SNMP manager or a second host, do not copy the InetAddressAcl file or specify it as a property. In the absence of the trap-community definitions, the traps are addressed to the trap port on the local host. And even if no manager is running, we can still see the agent sending the traps. See 17.1.4 SNMP Trap Handler for details about receiving traps. To Interact With the Trap Generator
The LinkTrapGenerator MBean is not manageable through the SNMP adaptor because it is not part of any MIB. It is an example of another MBean providing some control of the SNMP agent, and this control can be exercised by other managers connecting through other protocols. This shows that designing an SNMP agent application involves both the implementation of the MIB functionality and, if desired, the implementation of other dynamic controls afforded by the JMX architecture and the services of Java DMK. 16.4 Standalone SNMP AgentsThe design of the SNMP protocol adaptors and of the MBeans generated by mibgen give you the option of creating an SNMP agent that is not a Java dynamic management agent. This standalone agent has no MBean server and thus no possibility of being managed other than through the SNMP protocol. The application must instantiate all MIBs that the SNMP agent needs, as it is impossible to create them through another manager. The advantage of a standalone agent is the reduced size of the application, in terms of memory usage. This applies to all three versions of SNMP. Example 16–8 StandAloneSnmpAgent Example
As this example demonstrates, the standalone agent uses exactly the same MIB MBeans, with the same customization, as our other agents. However, instead of registering them in the MBean server, they are only instantiated. And whereas the registration process creates all subordinate MBeans of the MIB, now we must call its init method explicitly. The init method performs the same function as the preRegister method, only it does not register the MBean with the MBean server. Each of the group MBeans then has two constructors, one with and one without a reference to the MBean server. When table entries are added dynamically, the corresponding object only registers the new entry's MBean if the MBean server reference is non-null; that is, only if the MBean is not instantiated in a standalone agent. The mibgen tool automatically generates both the pre-registration methods and the init methods in the MIB MBeans. Therefore, no special action is necessary to use them in either a regular agent or a standalone agent. If you use a standalone agent for memory considerations, you can remove the registration process from the generated MBean and only customize the init process. Example 16–9 Customizations in the Generated RFC1213_MIB_Impl.java File
After the MIB is initialized, it only needs to be bound to the SNMP adaptor, as in the other agents; except that in the standalone case, we use the setSnmpAdaptor method which takes a direct reference to the SNMP adaptor instead of an object name. That is all you need to do when programing a standalone SNMP agent. You can subclass the MIB and override the group MBean factory method to instantiate your own customized MBean class, replacing for instance new Interfaces() with new InterfacesImpl(), as shown in the code example. 16.4.1 Running the Standalone Agent ExampleTo Run the Standalone Agent Example
16.5 Multiple AgentsIt is possible to create multiple SNMP agents in the Java virtual machine (JVM). A multiple agent is an agent that instantiates more than one SNMP adaptor server. This enables you to create multiple SNMP MIBs using that agent, with each MIB having its own individual security configuration. The main advantage of this is to reduce the burden on the JVM. You can create multiple agents using all three versions of SNMP. However, the multiple agent demonstrated in the following example is an SNMPv3 agent that creates and registers two SNMP adaptor servers in the MBean server. Registration in the MBean server enables the MIBs generated to be managed through the HTML adaptor. Example 16–10 MultipleAgentV3 Example
This example creates an MBean server as normal, and creates and registers an HTML adaptor in the MBean server, again in the same way as was done in the simple agent example. However, MultipleAgentV3 then creates and registers two SNMP adaptor servers in the MBean server. The two SNMP adaptors are bound to non-standard SNMP ports, in this case ports 8085 and 8087. Each adaptor generates MIBs from its own security file, enabling you to have different, and remotely updatable, security configurations for each SNMP adaptor server. The first SNMP adaptor server, snmpAdaptor1, gets its security configuration from the security file jdmk.security when the agent is started. The second SNMP adaptor server, snmpAdaptor2, gets its security configuration from a second security file, jdmk2.security, using the params.setSecurityFile method. You can consult jdmk2.security in the examplesDir/current/Snmp/Agent directory. Both these security files implement authentication without privacy. The coherency of the jdmk.security file is not preserved if you use the same file for more than one adaptor server. 16.5.1 Running the SNMPv3 MultipleAgentV3 ExampleIn the same way as for the SNMPv3 agent example, AgentV3, you must point the multiple agent application to the security configuration file when you instantiate the multiple agent. This is only the case for the first of the SNMP adaptor servers created by your multiple agent application. All adaptor servers created subsequently by the multiple agent are directed to their corresponding security files in the code of the multiple agent application, when that adaptor server is instantiated. You must call the MultipleAgentV3 application inside its directory and make sure that the two security configuration files are present in the same directory. To Run the SNMPv3 MultipleAgentV3 Example |
||||||||||||||||