前言
网上关于V3加密认证的例子不多,尤其是认证和加密的,很多都是发送trap的例子,很少有接收trap的例子。
虽然是V3,但也支持V1V2,只需要打开相关注释就行。
网上没有认证且加密成功的例子,下面的例子都能测试通。
现在贴出来,希望对大家有用。
消息接收类
package org.apache.flume.test.v3;
import org.snmp4j.*;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
import java.util.Vector;
public class MultiThreadedTrapReceiver implements CommandResponder {
private String username1 = "nmsAdminNaNp";
private String username2 = "nmsAdmin2ANp";
private String username3 = "nmsAdmin3ap";
private String authPassword = "nmsAuthKey";
private String privPassword = "nmsPrivKey";
private MultiThreadedMessageDispatcher dispatcher;
private Snmp snmp = null;
private Address listenAddress;
private ThreadPool threadPool;
public MultiThreadedTrapReceiver() {
// BasicConfigurator.configure();
}
private void init() throws Exception {
/*threadPool = ThreadPool.create("Trap", 2);
dispatcher = new MultiThreadedMessageDispatcher(threadPool,
new MessageDispatcherImpl());
listenAddress = GenericAddress.parse(System.getProperty(
"snmp4j.listenAddress", "udp:10.195.88.96/162")); // 本地IP与监听端口
TransportMapping transport;
// 对TCP与UDP协议进行处理
if (listenAddress instanceof UdpAddress) {
transport = new DefaultUdpTransportMapping(
(UdpAddress) listenAddress);
} else {
transport = new DefaultTcpTransportMapping(
(TcpAddress) listenAddress);
}
snmp = new Snmp(dispatcher, transport);
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
UsmUser usmUser = new UsmUser(new OctetString(username), AuthMD5.ID,
new OctetString(authPassword), Priv3DES.ID,
new OctetString(privPassword));
USM usm = new USM(SecurityProtocols.getInstance().addDefaultProtocols(), new OctetString(MPv3
.createLocalEngineID()), 0);
usm.addUser(usmUser);
SecurityModels.getInstance().addSecurityModel(usm);
snmp.listen();
//add the enginID in the trap
//OctetString engineID = new OctetString(MPv3.createLocalEngineID());
byte[] enginId = "TEO_ID".getBytes();
OctetString engineID = new OctetString(enginId);
//create and add the userSecurityModel
USM usm = new USM(SecurityProtocols.getInstance(),engineID, 0);
SecurityModels.getInstance().addSecurityModel(usm);
//add the securityProtocols,you can skip it if your users are noAuthNoPriv
SecurityProtocols.getInstance().addDefaultProtocols();
//create and add the user
UsmUser usmUser = new UsmUser(new OctetString(username), AuthMD5.ID,
new OctetString(authPassword), Priv3DES.ID,
new OctetString(privPassword));
usm.addUser(usmUser);
//snmp.getUSM().addUser(usmUser);
snmp.listen();
*/
/*******************************************使用处*************************************************/
//创建接收SnmpTrap的线程池,参数: 线程名称及线程数
threadPool = ThreadPool.create("Trap", 2);
dispatcher = new MultiThreadedMessageDispatcher(threadPool,
new MessageDispatcherImpl());
//监听端的 ip地址 和 监听端口号
listenAddress = GenericAddress.parse(System.getProperty(
"snmp4j.listenAddress", "udp:127.0.0.1/161"));
TransportMapping transport;
if (listenAddress instanceof UdpAddress) {
transport = new DefaultUdpTransportMapping((UdpAddress)listenAddress);
}else{
transport = new DefaultTcpTransportMapping((TcpAddress) listenAddress);
}
snmp = new Snmp(dispatcher, transport);
// snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
// snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
//MPv3.setEnterpriseID(35904);
byte[] enginId = "JL-CC-SNL".getBytes();
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(
MPv3.createLocalEngineID()
// enginId
),0);
SecurityModels.getInstance().addSecurityModel(usm);
// 添加安全协议,如果没有发过来的消息没有身份认证,可以跳过此段代码
// add all security protocols
SecurityProtocols.getInstance().addDefaultProtocols();
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());//此处必须添加
// 创建和添加用户
OctetString userName1 = new OctetString(username1);
OctetString userName2 = new OctetString(username2);
OctetString userName3 = new OctetString(username3);
OctetString authPass = new OctetString(authPassword);
OctetString privPass = new OctetString(privPassword);
/*UsmUser usmUser1 = new UsmUser(
new OctetString("nmsAdmin"),
AuthSHA.ID, new OctetString("nmsAuthKey"),
PrivAES256.ID, new OctetString("nmsPrivKey"));*/
UsmUser usmUser1 = new UsmUser(userName1, AuthMD5.ID, authPass, Priv3DES.ID, privPass);
UsmUser usmUser2 = new UsmUser(userName2, AuthMD5.ID, authPass, Priv3DES.ID, privPass);
UsmUser usmUser3 = new UsmUser(userName3, AuthMD5.ID, authPass, Priv3DES.ID, privPass);
//因为接受的Trap可能来自不同的主机,主机的Snmp v3加密认证密码都不一样,所以根据加密的名称,来添加认证信息UsmUser。
//添加了加密认证信息的便可以接收来自发送端的信息。
// UsmUserEntry userEnty1 = new UsmUserEntry(userName1,new OctetString(enginId),usmUser1);
// UsmUserEntry userEnty2 = new UsmUserEntry(userName2,usmUser2);
// UsmUserTable userTable = snmp.getUSM().getUserTable();
// 添加其他用户
// userTable.addUser(userEnty1);
// userTable.addUser(userEnty2);
//开启Snmp监听,可以接收来自Trap端的信息。+
usm.addUser(userName1,new OctetString(enginId),usmUser1);
usm.addUser(userName2,new OctetString(enginId),usmUser2);
usm.addUser(userName3,new OctetString(enginId),usmUser3);
snmp.listen();
/* UsmUserTable userTable = snmp.getUSM().getUserTable();
userTable.addUser(userEnty1);
userTable.addUser(userEnty2);*/
/********************************************************************************************/
}
public void run() {
try {
init();
snmp.addCommandResponder(this);
System.out.println("开始监听Trap信息!");
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 实现CommandResponder的processPdu方法, 用于处理传入的请求、PDU等信息
* 当接收到trap时,会自动进入这个方法
*
* @param respEvnt
*/
public void processPdu(CommandResponderEvent respEvnt) {
// 解析Response
if (respEvnt != null && respEvnt.getPDU() != null) {
@SuppressWarnings("unchecked")
Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getPDU().getVariableBindings();
for (int i = 0; i < recVBs.size(); i++) {
VariableBinding recVB = recVBs.elementAt(i);
System.out.println(recVB.getOid() + " : " + recVB.getVariable());
}
}
}
//开启监控的main方法。
public static void main(String[] args) {
MultiThreadedTrapReceiver multithreadedtrapreceiver = new MultiThreadedTrapReceiver();
multithreadedtrapreceiver.run();
}
}
消息发送类
package org.apache.flume.test.v3;
import java.io.IOException;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.PDUv1;
import org.snmp4j.SNMP4JSettings;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.Priv3DES;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import java.io.IOException;
public class SnmpTrapSender {
private Snmp snmp = null;
private Address targetAddress = null;
private TransportMapping transport = null;
//UsmUser 的userName
private String username1 = "nmsAdminNaNp";
private String username2 = "nmsAdmin2ANp";
private String username3 = "nmsAdmin3ap";
//认证协议的密码 如MD5
private String authPassword = "nmsAuthKey";
//加密协议密码 如 DES AES
private String privPassword = "nmsPrivKey";
public static void main(String[] args) {
SnmpTrapSender poc = new SnmpTrapSender();
try {
poc.init();
poc.sendV1Trap();
poc.sendV2cTrap();
poc.sendV3TrapNoAuthNoPriv();
poc.sendV3AUTH_NOPRIV();
poc.sendV3Auth();
poc.sendV3AUTH_PRIV();
} catch (IOException e) {
e.printStackTrace();
}
}
public void init() throws IOException {
//目标主机的ip地址 和 端口号
targetAddress = GenericAddress.parse("udp:127.0.0.1/161");
transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
transport.listen();
}
/**
* Snmp V1 测试发送Trap
* @return
* @throws IOException
*/
public ResponseEvent sendV1Trap() throws IOException {
PDUv1 pdu = new PDUv1();
VariableBinding v = new VariableBinding();
v.setOid(SnmpConstants.sysName);
v.setVariable(new OctetString("Snmp Trap V1 Test"));
pdu.add(v);
pdu.setType(PDU.V1TRAP);
// set target
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setAddress(targetAddress);
// retry times when commuication error
target.setRetries(2);
// timeout
target.setTimeout(1500);
target.setVersion(SnmpConstants.version1);
// send pdu, return response
return snmp.send(pdu, target);
}
/**
* Snmp V2c 测试发送Trap
* @return
* @throws IOException
*/
public ResponseEvent sendV2cTrap() throws IOException {
PDU pdu = new PDU();
VariableBinding v = new VariableBinding();
v.setOid(SnmpConstants.sysName);
v.setVariable(new OctetString("Snmp Trap V2 Test"));
pdu.add(v);
pdu.setType(PDU.TRAP);
// set target
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setAddress(targetAddress);
// retry times when commuication error
target.setRetries(2);
target.setTimeout(1500);
target.setVersion(SnmpConstants.version2c);
// send pdu, return response
return snmp.send(pdu, target);
}
/**
* SnmpV3 不带认证加密协议.
* @return
* @throws IOException
*/
public ResponseEvent sendV3TrapNoAuthNoPriv() throws IOException {
SNMP4JSettings.setExtensibilityEnabled(true);
SecurityProtocols.getInstance().addDefaultProtocols();
UserTarget target = new UserTarget();
target.setVersion(SnmpConstants.version3);
try {
transport = new DefaultUdpTransportMapping();
} catch (IOException e1) {
e1.printStackTrace();
}
byte[] enginId = "JL-CC-SNL".getBytes();
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(
enginId), 500);
SecurityModels secModels = SecurityModels.getInstance();
if (snmp.getUSM() == null) {
secModels.addSecurityModel(usm);
}
target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV);
target.setAddress(targetAddress);
ScopedPDU pdu = new ScopedPDU();
pdu.setType(PDU.NOTIFICATION);
VariableBinding v = new VariableBinding();
v.setOid(SnmpConstants.sysName);
v.setVariable(new OctetString("Snmp Trap V3 Test sendV3Trap NoAuthNoPriv"));
pdu.add(v);
snmp.setLocalEngine(enginId, 500, 1);
return snmp.send(pdu, target);
}
/**
* @return
* @throws IOException
*/
public ResponseEvent sendV3Auth() throws IOException {
SNMP4JSettings.setExtensibilityEnabled(true);
SecurityProtocols.getInstance().addDefaultProtocols();
UserTarget target = new UserTarget();
target.setSecurityName(new OctetString(username3));
target.setVersion(SnmpConstants.version3);
try {
transport = new DefaultUdpTransportMapping();
} catch (IOException e1) {
e1.printStackTrace();
}
byte[] enginId = "JL-CC-SNL".getBytes();
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(
enginId
// MPv3.createLocalEngineID()
), 500);
SecurityModels secModels = SecurityModels.getInstance();
synchronized (secModels) {
if (snmp.getUSM() == null) {
secModels.addSecurityModel(usm);
}
snmp.getUSM().addUser(
new OctetString(username3),
new OctetString(enginId),
new UsmUser(new OctetString(username3), AuthMD5.ID,
new OctetString(authPassword), Priv3DES.ID,
new OctetString(privPassword)));
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
// target.setAuthoritativeEngineID(enginId);
target.setAddress(targetAddress);
ScopedPDU pdu = new ScopedPDU();
pdu.setType(PDU.NOTIFICATION);
VariableBinding v = new VariableBinding();
v.setOid(SnmpConstants.sysName);
v.setVariable(new OctetString("Snmp Trap V3 Test sendV3Auth"));
System.out.println("Snmp Trap V3 Test sendV3Auth");
pdu.add(v);
snmp.setLocalEngine(enginId, 500, 1);
ResponseEvent send = snmp.send(pdu, target);
//System.out.println(send.getError());
return send;
}
}
/**
* 测试SnmpV3 带认证协议,无加密协议
* @return
* @throws IOException
*/
public ResponseEvent sendV3AUTH_NOPRIV() throws IOException{
OctetString userName2 = new OctetString(username2);
OctetString authPass = new OctetString(authPassword);
OctetString authPass2 = new OctetString("authPassword2");
OctetString privPass = new OctetString(privPassword);
TransportMapping transport;
transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
//MPv3.setEnterpriseID(35904);
byte[] enginId = "JL-CC-SNL".getBytes();
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(
// MPv3.createLocalEngineID()
enginId
), 500);
SecurityModels.getInstance().addSecurityModel(usm);
UserTarget target = new UserTarget();
SecurityModels secModels = SecurityModels.getInstance();
synchronized (secModels) {
if (snmp.getUSM() == null) {
secModels.addSecurityModel(usm);
}
/*snmp.getUSM().addUser(
new OctetString(username),
new OctetString(enginId),
new UsmUser(new OctetString(username), AuthMD5.ID,
new OctetString(authPassword), Priv3DES.ID,
new OctetString(privPassword)));*/
// add user to the USM
snmp.getUSM().addUser(userName2,new OctetString(enginId),
new UsmUser(userName2,AuthMD5.ID,authPass,Priv3DES.ID,privPass)
);
target.setAddress(targetAddress);
target.setRetries(2);
target.setTimeout(3000);
target.setVersion(SnmpConstants.version3);
target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV);
target.setSecurityName(userName2);
ScopedPDU pdu = new ScopedPDU();
pdu.setType(PDU.NOTIFICATION);
VariableBinding v = new VariableBinding();
v.setOid(SnmpConstants.sysName);
v.setVariable(new OctetString("Snmp Trap V3 Test sendV3 AUTH_NOPRIV----------"));
System.out.println("Snmp Trap V3 Test sendV3 AUTH_NOPRIV");
pdu.add(v);
snmp.setLocalEngine(enginId, 500, 1);
ResponseEvent send = snmp.send(pdu, target);
//System.out.println(send.getError());
return send;
}
}
/**
* 测试SnmpV3 带认证协议,加密协议
* @return
* @throws IOException
*/
public ResponseEvent sendV3AUTH_PRIV() throws IOException{
OctetString userName3 = new OctetString(username3);
OctetString authPass = new OctetString(authPassword);
OctetString privPass = new OctetString(privPassword);
TransportMapping transport;
transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
//MPv3.setEnterpriseID(35904);
USM usm = new USM(SecurityProtocols.getInstance(),
new OctetString(MPv3.createLocalEngineID()), 500);
SecurityModels.getInstance().addSecurityModel(usm);
UserTarget target = new UserTarget();
byte[] enginId = "JL-CC-SNL".getBytes();
SecurityModels secModels = SecurityModels.getInstance();
synchronized (secModels) {
if (snmp.getUSM() == null) {
secModels.addSecurityModel(usm);
}
/*snmp.getUSM().addUser(
new OctetString(username),
new OctetString(enginId),
new UsmUser(new OctetString(username), AuthMD5.ID,
new OctetString(authPassword), Priv3DES.ID,
new OctetString(privPassword)));*/
// add user to the USM
snmp.getUSM().addUser(userName3,new OctetString(enginId),
new UsmUser(userName3,AuthMD5.ID,authPass,Priv3DES.ID,privPass)
);
target.setAddress(targetAddress);
target.setRetries(2);
target.setTimeout(3000);
target.setVersion(SnmpConstants.version3);
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(userName3);
ScopedPDU pdu = new ScopedPDU();
pdu.setType(PDU.NOTIFICATION);
VariableBinding v = new VariableBinding();
v.setOid(SnmpConstants.sysName);
v.setVariable(new OctetString("Snmp Trap V3 Test sendV3 AUTH_PRIV----------"));
System.out.println("Snmp Trap V3 Test sendV3 AUTH_PRIV");
pdu.add(v);
snmp.setLocalEngine(enginId, 500, 1);
ResponseEvent send = snmp.send(pdu, target);
//System.out.println(send.getError());
return send;
}
}
}
测试结果
开始监听Trap信息!
1.3.6.1.2.1.1.5.0 : Snmp Trap V3 Test sendV3Trap NoAuthNoPriv
1.3.6.1.2.1.1.5.0 : Snmp Trap V3 Test sendV3 AUTH_NOPRIV----------
1.3.6.1.2.1.1.5.0 : Snmp Trap V3 Test sendV3 AUTH_PRIV----------
1.3.6.1.2.1.1.5.0 : Snmp Trap V3 Test sendV3Auth
1.3.6.1.2.1.1.5.0 : Snmp Trap V3 Test sendV3Trap NoAuthNoPriv