diff --git a/host/config/config-snmpv3.yaml b/host/config/config-snmpv3.yaml new file mode 100644 index 0000000..3fb1ffb --- /dev/null +++ b/host/config/config-snmpv3.yaml @@ -0,0 +1,24 @@ +host.system: snmp_host + +instances: + - snmp.host: udp:9.30.78.59/161 + poll.interval: 25 + callback.interval: 30 + otel.backend.url: http://127.0.0.1:4317 + #otel.backend.using.http: true + #otel.backend.url: http://9.112.252.66:4318/v1/metrics + #host.name: stantest0.fyre.ibm.com + #os.type: linux + #community: public + #retries: 3 + #timeout: 1000 + version: 3 + securityLevel: 3 + securityName: linuser + authPassword: linuserpass + privacyPassword: linprivpass + #AuthSHA: 1.3.6.1.6.3.10.1.1.3 + authType: 1.3.6.1.6.3.10.1.1.3 + #PrivDES: 1.3.6.1.6.3.10.1.2.2 + privacyType: 1.3.6.1.6.3.10.1.2.2 + diff --git a/host/libs/simp-snmp-0.1.2.jar b/host/libs/simp-snmp-0.1.2.jar index ea03454..5ef7788 100644 Binary files a/host/libs/simp-snmp-0.1.2.jar and b/host/libs/simp-snmp-0.1.2.jar differ diff --git a/host/src/main/java/com/instana/dc/host/impl/snmphost/SnmpHostDc.java b/host/src/main/java/com/instana/dc/host/impl/snmphost/SnmpHostDc.java index be3c2ce..afb510d 100644 --- a/host/src/main/java/com/instana/dc/host/impl/snmphost/SnmpHostDc.java +++ b/host/src/main/java/com/instana/dc/host/impl/snmphost/SnmpHostDc.java @@ -45,8 +45,11 @@ public SnmpHostDc(Map properties, String hostSystem) throws IOEx option.setTimeout((Integer) properties.getOrDefault("timeout", 450)); option.setVersion((Integer) properties.getOrDefault("version", SnmpConstants.version2c)); //1 option.setSecurityLevel((Integer) properties.getOrDefault("securityLevel", SecurityLevel.NOAUTH_NOPRIV)); //1 + option.setSecurityName((String) properties.get("securityName")); option.setAuthPassword((String) properties.get("authPassword")); option.setPrivacyPassword((String) properties.get("privacyPassword")); + option.setAuthType((String) properties.get("authType")); + option.setPrivacyType((String) properties.get("privacyType")); simpSnmp = new SimpSnmp(snmpHost, option); Map result = simpSnmp.queryScalarOids(Oid.HOST_NAME, Oid.OS_TYPE); diff --git a/host/src/main/java/com/instana/dc/host/impl/snmphost/SnmpHostUtil.java b/host/src/main/java/com/instana/dc/host/impl/snmphost/SnmpHostUtil.java index c2040a2..9b5fecc 100644 --- a/host/src/main/java/com/instana/dc/host/impl/snmphost/SnmpHostUtil.java +++ b/host/src/main/java/com/instana/dc/host/impl/snmphost/SnmpHostUtil.java @@ -5,11 +5,9 @@ package com.instana.dc.host.impl.snmphost; import com.instana.dc.SimpleQueryResult; -import com.instana.dc.host.HostDcUtil; import com.instana.simpsnmp.SnmpValue; import org.snmp4j.smi.OID; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SimpSnmp.java b/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SimpSnmp.java index 87e118b..b14bd40 100644 --- a/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SimpSnmp.java +++ b/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SimpSnmp.java @@ -33,37 +33,57 @@ public class SimpSnmp implements Closeable { private final SnmpOption option; public SimpSnmp(String endpoint, SnmpOption option) throws IOException { - String securityName = "MD5DES"; + String securityName = option.getSecurityName(); this.endpoint = endpoint; this.option = option; - if (option.getVersion() == SnmpConstants.version3) { - myTarget = new UserTarget<>(); - myTarget.setSecurityLevel(option.getSecurityLevel()); - myTarget.setSecurityName(new OctetString(securityName)); - } else { - myTarget = new CommunityTarget<>(); - ((CommunityTarget) myTarget).setCommunity(new OctetString(option.getCommunity())); - } - - Address deviceAdd = GenericAddress.parse(this.endpoint); - myTarget.setAddress(deviceAdd); - myTarget.setRetries(option.getRetries()); - myTarget.setTimeout(option.getTimeout()); - myTarget.setVersion(option.getVersion()); transport = new DefaultUdpTransportMapping(); protocol = new Snmp(transport); if (option.getVersion() == SnmpConstants.version3) { if (option.getSecurityLevel() != SecurityLevel.NOAUTH_NOPRIV) { - USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0); + SecurityProtocols sp= new SecurityProtocols(SecurityProtocols.SecurityProtocolSet.maxCompatibility); + /*sp.addDefaultProtocols(); + sp.addAuthenticationProtocol(new AuthSHA()); + sp.addAuthenticationProtocol(new AuthMD5()); + sp.addAuthenticationProtocol(new AuthHMAC128SHA224()); + sp.addAuthenticationProtocol(new AuthHMAC192SHA256()); + sp.addAuthenticationProtocol(new AuthHMAC256SHA384()); + sp.addAuthenticationProtocol(new AuthHMAC384SHA512()); + sp.addPrivacyProtocol(new PrivDES()); + sp.addPrivacyProtocol(new Priv3DES()); + sp.addPrivacyProtocol(new PrivAES128()); + sp.addPrivacyProtocol(new PrivAES192()); + sp.addPrivacyProtocol(new PrivAES256());*/ + USM usm = new USM(sp, new OctetString(MPv3.createLocalEngineID()), 0); SecurityModels.getInstance().addSecurityModel(usm); + transport.listen(); protocol.getUSM().addUser(new UsmUser( - new OctetString(securityName), AuthMD5.ID, - new OctetString(option.getAuthPassword()), PrivDES.ID, + new OctetString(securityName), new OID(option.getAuthType()), + new OctetString(option.getAuthPassword()), new OID(option.getPrivacyType()), new OctetString(option.getPrivacyPassword()))); } + } else { + transport.listen(); + } + + if (option.getVersion() != SnmpConstants.version3) { + myTarget = new CommunityTarget<>(); + ((CommunityTarget) myTarget).setCommunity(new OctetString(option.getCommunity())); + + myTarget.setAddress(GenericAddress.parse(this.endpoint)); + myTarget.setRetries(option.getRetries()); + myTarget.setTimeout(option.getTimeout()); + myTarget.setVersion(option.getVersion()); + } else { + myTarget = new UserTarget<>(); + myTarget.setSecurityLevel(option.getSecurityLevel()); + myTarget.setSecurityName(new OctetString(securityName)); + + myTarget.setAddress(GenericAddress.parse(this.endpoint)); + myTarget.setRetries(option.getRetries()); + myTarget.setTimeout(option.getTimeout()); + myTarget.setVersion(option.getVersion()); } - transport.listen(); } public SimpSnmp(String endpoint) throws IOException { @@ -91,7 +111,12 @@ public void close() throws IOException { } public Map queryScalarOids(List oids) throws IOException { - PDU request = new PDU(); + PDU request; + if (option.getVersion() < SnmpConstants.version3) { + request = new PDU(); + } else { + request = new ScopedPDU(); + } request.setType(PDU.GET); for (OID oid : oids) { request.add(new VariableBinding(oid)); diff --git a/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SimpSnmpTst.java b/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SimpSnmpTst.java new file mode 100644 index 0000000..852e740 --- /dev/null +++ b/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SimpSnmpTst.java @@ -0,0 +1,59 @@ +package com.instana.simpsnmp; + +import org.snmp4j.PDU; +import org.snmp4j.Snmp; +import org.snmp4j.Target; +import org.snmp4j.fluent.SnmpBuilder; +import org.snmp4j.fluent.SnmpCompletableFuture; +import org.snmp4j.fluent.TargetBuilder; +import org.snmp4j.mp.SnmpConstants; +import org.snmp4j.security.SecurityLevel; +import org.snmp4j.security.SecurityProtocols; +import org.snmp4j.smi.Address; +import org.snmp4j.smi.GenericAddress; +import org.snmp4j.smi.OID; +import org.snmp4j.smi.VariableBinding; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ExecutionException; + +public class SimpSnmpTst { + public static void main(String[] args) throws IOException, ExecutionException { + SnmpBuilder snmpBuilder = new SnmpBuilder(); + Snmp snmp = snmpBuilder.udp().securityProtocols( + SecurityProtocols.SecurityProtocolSet.maxCompatibility).v3().usm().build(); + + Address targetAddress = GenericAddress.parse("udp:9.30.78.59/161"); + byte[] targetEngineID = snmp.discoverAuthoritativeEngineID(targetAddress, 1000); + + if (targetEngineID != null) { + TargetBuilder targetBuilder = snmpBuilder.target(targetAddress); + + Target target = targetBuilder + .user("linuser", targetEngineID) + .auth(TargetBuilder.AuthProtocol.sha1).authPassphrase("linuserpass") + .priv(TargetBuilder.PrivProtocol.des).privPassphrase("linprivpass") + .done() + .timeout(1500).retries(2) + .build(); + target.setVersion(SnmpConstants.version3); + target.setSecurityLevel(SecurityLevel.AUTH_PRIV); + + PDU pdu = targetBuilder.pdu().type(PDU.GET).contextName("").build(); + pdu.add(new VariableBinding(new OID(".1.3.6.1.2.1.1.1.0"))); + + SnmpCompletableFuture snmpRequestFuture = SnmpCompletableFuture.send(snmp, target, pdu); + try { + List vbs = snmpRequestFuture.get().getAll(); + System.out.println("Received: " + snmpRequestFuture.getResponseEvent().getResponse()); + } catch (ExecutionException | InterruptedException ex) { + System.err.println("Request failed: " + ex.getCause().getMessage()); + } + } else { + System.err.println("Timeout on engine ID discovery for " + targetAddress + ", GET not sent."); + } + snmp.close(); + + } +} diff --git a/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SnmpOption.java b/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SnmpOption.java index 909fd81..6980bcc 100644 --- a/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SnmpOption.java +++ b/internal/simp-snmp/src/main/java/com/instana/simpsnmp/SnmpOption.java @@ -15,6 +15,9 @@ public class SnmpOption { private int securityLevel; private String authPassword; private String privacyPassword; + private String securityName; + private String authType; + private String privacyType; public SnmpOption() { this.community = "public"; @@ -53,7 +56,11 @@ public int getVersion() { } public void setVersion(int version) { - this.version = version; + if (version == SnmpConstants.version3) { + this.version = SnmpConstants.version3; + } else { + this.version = SnmpConstants.version2c; + } } public int getSecurityLevel() { @@ -61,7 +68,11 @@ public int getSecurityLevel() { } public void setSecurityLevel(int securityLevel) { - this.securityLevel = securityLevel; + if (securityLevel < SecurityLevel.NOAUTH_NOPRIV || securityLevel > SecurityLevel.AUTH_PRIV) { + this.securityLevel = SecurityLevel.NOAUTH_NOPRIV; + } else { + this.securityLevel = securityLevel; + } } public String getAuthPassword() { @@ -79,4 +90,28 @@ public String getPrivacyPassword() { public void setPrivacyPassword(String privacyPassword) { this.privacyPassword = privacyPassword; } + + public String getSecurityName() { + return securityName; + } + + public void setSecurityName(String securityName) { + this.securityName = securityName; + } + + public String getAuthType() { + return authType; + } + + public void setAuthType(String authType) { + this.authType = authType; + } + + public String getPrivacyType() { + return privacyType; + } + + public void setPrivacyType(String privacyType) { + this.privacyType = privacyType; + } }