简体   繁体   中英

SNMP4J Client gives "Unsupported security level"

I'm about to implement a Client/Agent setup in order to learn using SNMP. I want to establish a secure and encrypted communication using SNMPv3 and authPriv as security level.
Here's my setup:

Agent
The Agent is running on Ubuntu (within a Docker image). To set it up, I followed this tutorial .
My /etc/snmp/snmpd.conf looks like this:

agentAddress udp:161
...
createUser authOnlyUser MD5 "test1234"
createUser authPrivUser SHA "test1234" DES
createUser internalUser MD5 "test1234"
...
rouser authOnlyUser
rwuser authPrivUser authPriv

SNMP is running on port 161 , which is forwarded to port 1025 by Docker.

Client
I could ensure that my Agent is working properly using

  1. snmpget on the same machine (Ubuntu, within Docker):
    snmpget -v3 -a SHA -A test1234 -X test1234 -l authPriv -u authPrivUser localhost 1.3.6.1.2.1.1.1.0
  2. snmpget from a remote machine (Debian):
    snmpget -v3 -u authPrivUser -X test1234 -A test1234 -l authPriv -x DES -a SHA <HOST-IP>:1025 1.3.6.1.2.1.1.1.0
  3. Using SNMP-Tester .

In all three cases I get the expected value for the given OID:
Linux 9b98a8808b1a 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 .

Now I wanted to implement a Client with Java, using the latest version 3.2.2 of snmp4j . This is what I have implemented:

public class SNMPTestClient {

    public static void main(String[] args) throws Exception {
        // enable logging
        ConsoleLogFactory consoleLogFactory = new ConsoleLogFactory();
        consoleLogFactory.getRootLogger().setLogLevel(LogLevel.DEBUG);
        LogFactory.setLogFactory(consoleLogFactory);

        TransportMapping<? extends Address> transport = new DefaultUdpTransportMapping();
        Snmp snmp = new Snmp(transport);

        // create and add user security model
        OctetString localEngineId = new OctetString(MPv3.createLocalEngineID());
        USM usm = new USM(SecurityProtocols.getInstance(), localEngineId, 0);
        SecurityModels.getInstance().addSecurityModel(usm);

        // user credentials
        OctetString securityName = new OctetString("authPrivUser");
        OctetString authPassphrase = new OctetString("test1234");
        OctetString privPassphrase = new OctetString("test1234");
        OID authProtocol = AuthSHA.ID;
        OID privProtocol = PrivDES.ID;

        UsmUser usmUser = new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, privPassphrase);
        snmp.getUSM().addUser(securityName, usmUser);

        // create target
        UserTarget target = new UserTarget();
        target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
        target.setSecurityName(securityName);
        target.setAddress(GenericAddress.parse("udp:127.0.0.1/1025"));
        target.setVersion(SnmpConstants.version3);
        target.setRetries(3);
        target.setTimeout(10000);

        transport.listen();

        ScopedPDU pdu = new ScopedPDU();
        pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.1.0")));
        pdu.setType(PDU.GET);
        ResponseEvent event = snmp.send(pdu, target);
        if (event != null) {
            System.out.println(event.getUserObject());
            System.out.println(event.getError());
            System.out.println(event.getPeerAddress());
            PDU responsePDU = event.getResponse();
            System.out.println(responsePDU.getErrorStatus());
            System.out.println(responsePDU.getErrorIndex());
            if (responsePDU.getErrorStatus() == PDU.noError) {
                for (int k = 0; k < responsePDU.size(); k++) {
                    VariableBinding vb = responsePDU.get(k);
                    if (vb != null) {
                        System.out.println(vb.getOid() + "-" + vb.getVariable().toString());
                    }
                }
            } else {
                System.out.println("SNMP Error:" + responsePDU.getErrorStatusText());
            }
        } else {
            System.out.println("SNMP send unsuccessful.");
        }
    }
}

As you can see I'm using the same credentials and protocols like mentioned above. But when I run it I receive the following Exception:
org.snmp4j.MessageException: Message processing model 3 returned error: Unsupported security level

What am I doing wrong here? As the user authPrivUser is configured to use the authPriv security level on the Agent's side and I'm also setting the level to AUTH_PRIV within the client and pass the correct credentials, I don't know why this exception is thrown.

Thanks in advance for any support and hints!

EDIT
I figured out that the code I posted above does work using SNMP4J v2.7.0. Any version >=3.0.0 throws error Unsupported security level . Unfortunately, using an old version from Nov. 2018 cannot be the solution...

In SNMP4J 3.x the security protocol AuthSHA (and AuthMD5 ) are no longer added by default to the static SecurityProtocols instance because they are now considered as unsafe.

You can add it again by calling:

SecurityProtocols.addAuthenticationProtocol(new AuthSHA());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM