使用snmp4j

时间:2015-06-04 08:33:15

标签: java snmp snmp4j

我正在编写一个SNMP v3陷阱/使用snmp4j通知发件人进行身份验证,但我很惊讶,即使身份验证失败,也能正确确认通知。我还使用snmp4j开发了陷阱接收器来帮助我调试。

我注意到了几个意想不到的情况:

第一种情况:使用Auth / NoPriv发送带有未知用户名或密码错误的INFORM => INFORM未被确认,只是没有响应,发件人必须等待超时。然而,在接收器端,会触发AuthenticationFailureEvent,但我原本预计snmp4j会对发送者做出错误响应。未调用重写方法 processPdu 。我想这可能取决于接收器实现,还是有一个标准的行为?

第二种情况:使用现有用户名发送INFORM但没有密码(使用NoAuth / NoPriv),而在接收方配置了密码=> INFORM通过RESPONSE确认,没有任何错误,我的陷阱接收器甚至没有按原样触发AuthenticationFailureEvent。 我希望接收方拒绝该请求,如果它是未经身份验证的。我忘了初始化一些东西吗?我无法想象snmp4j中存在这样一个安全漏洞。

我用来初始化接收器的代码:(我不会在这里显示重写的方法 processPdu authenticationFailure

EmbeddedSNMPReceiver(final int port, final Optional<UsmUser> user) throws IOException {
    final MessageDispatcherImpl dispatcher = new MessageDispatcherImpl();
    dispatcher.addAuthenticationFailureListener(this);
    final UdpAddress listenAddress = new UdpAddress("localhost/" + port);
    final TransportMapping transport = new DefaultUdpTransportMapping(listenAddress);
    SecurityProtocols.getInstance().addDefaultProtocols();
    final USM usm = new USM(SecurityProtocols.getInstance(), new OctetString("RECEIVER"), 0);
    snmp = new Snmp(dispatcher, transport);

    snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
    snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
    snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3(usm));
    SecurityModels.getInstance().addSecurityModel(usm);
    if (user.isPresent()) {
        snmp.getUSM().addUser(user.get().getSecurityName(), user.get());
    }

    snmp.addCommandResponder(this);
    snmp.listen();
}

public static void main(String[] args) {
    // FOR DEBUG
    try {
        final OctetString octUsername = new OctetString("zaza");
        final OID userAuthOID = AuthSHA.ID;
        final OctetString octUserPassphrase = new OctetString("12345678");
        final UsmUser user = new UsmUser(octUsername, userAuthOID, octUserPassphrase, null, null);
        final EmbeddedSNMPReceiver server = new EmbeddedSNMPReceiver(1099, Optional.of(user));
        Thread.sleep(500000);
        server.stop();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
PS:澄清一下,我在一个单独的过程中启动接收器而不是发送者,以避免snmp4j状态性/单身的问题......

1 个答案:

答案 0 :(得分:0)

您可能会仔细阅读RFC 3414第4节,看看您是否实际上达到了发现过程的预期行为。

1st不应该承认,它遵循v1和v2c惯例。

如果回复消息是REPORT,则预计

第二。