はじめに
前回までの記事
でgosnmpパッケージのサンプルプログラムについて紹介しました。
これまでの説明は、デフォルトのSNMPv2cによる通信でした。
セキュリティーを重視する人は認証や暗号化に対応したSNMPv3で通信したいと思っているでしょう。そこで、今回は、このサンプルプログラムをSNMPv3対応にする方法を説明します。
SNMPv3対応
SNMPv3対応に変更したソースコードは
package main
import (
"fmt"
"log"
g "github.com/gosnmp/gosnmp"
mibdb "github.com/twsnmp/go-mibdb"
)
func main() {
m, err := mibdb.NewMIBDB("./mib.txt")
if err != nil {
fmt.Printf("NewMIBDB failed err=%v", err)
return
}
// Default is a pointer to a GoSNMP struct that contains sensible defaults
// eg port 161, community public, etc
g.Default.Target = "192.168.1.210"
// g.Default.Community = "public"
// g.Default.Port = 161
+ g.Default.Version = g.Version3
+ g.Default.SecurityModel = g.UserSecurityModel
+ g.Default.MsgFlags = g.AuthPriv
+ g.Default.SecurityParameters = &g.UsmSecurityParameters{UserName: "user_name",
+ AuthenticationProtocol: g.SHA,
+ AuthenticationPassphrase: "sha_pass",
+ PrivacyProtocol: g.AES,
+ PrivacyPassphrase: "aes_pass",
+ }
err = g.Default.Connect()
if err != nil {
log.Fatalf("Connect() err: %v", err)
}
defer g.Default.Conn.Close()
// oids := []string{"1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.7.0"}
oids := []string{m.NameToOID("sysContact.0"), m.NameToOID("sysServices.0")}
result, err2 := g.Default.Get(oids) // Get() accepts up to g.MAX_OIDS
if err2 != nil {
log.Fatalf("Get() err: %v", err2)
}
for i, variable := range result.Variables {
// fmt.Printf("%d: oid: %s", i, variable.Name)
fmt.Printf("%d: oid: %s name:%s = ", i, variable.Name, m.OIDToName(variable.Name))
// the Value of each variable returned by Get() implements
// interface{}. You could do a type switch...
switch variable.Type {
case g.OctetString:
bytes := variable.Value.([]byte)
fmt.Printf("string: %s\n", string(bytes))
default:
// ... or often you're just interested in numeric values.
// ToBigInt() will return the Value as a BigInt, for plugging
// into your calculations.
fmt.Printf("number: %d\n", g.ToBigInt(variable.Value))
}
}
}
9行加えただけです。
変更のポイント
バージョンの指定
SNMPv3の指定は
g.Default.Version = g.Version3
の行です。
他に以下のバージョンが指定できます。
// SnmpVersion 1, 2c and 3 implemented
const (
Version1 SnmpVersion = 0x0
Version2c SnmpVersion = 0x1
Version3 SnmpVersion = 0x3
)
デフォルトはVersion2c
です。
セキュリティーモデル
セキュリティーモデルは
g.Default.SecurityModel = g.UserSecurityModel
です。ユーザーベースセキュリティーモデルしか選択肢はありません。
メッセージフラグ
認証と暗号化の設定フラグは
g.Default.MsgFlags = g.AuthPriv
メッセージフラグは他に、
// Possible values of SnmpV3MsgFlags
const (
NoAuthNoPriv SnmpV3MsgFlags = 0x0 // No authentication, and no privacy
AuthNoPriv SnmpV3MsgFlags = 0x1 // Authentication and no privacy
AuthPriv SnmpV3MsgFlags = 0x3 // Authentication and privacy
Reportable SnmpV3MsgFlags = 0x4 // Report PDU must be sent.
)
のように定義されています。認証の有無、暗号化の有無の組み合わせだけ使います。Reportable
は、使ったことがありません。(今度調べます。)
セキュリティーパラメータ
認証や暗号化のパラメータは
g.Default.SecurityParameters = &g.UsmSecurityParameters{UserName: "user_name",
AuthenticationProtocol: g.SHA,
AuthenticationPassphrase: "sha_pass",
PrivacyProtocol: g.AES,
PrivacyPassphrase: "aes_pass",
}
ユーザー名、認証の方式(HASHアルゴリズム)、認証のパスワード、暗号化のアルゴリズム、暗号のアルゴリズムを指定します。
NET-SNMPのSNMPv3エージェントでテストする
SNMPv3エージェントの起動
の記事の通りにSNMPエージェントを設定すれば、SNMPv3で通信できます。
テスト結果
SNMPv3のエージェントを先の手順で起動して、そのアドレスを指定すれば、
$go run main.go
0: oid: .1.3.6.1.2.1.1.4.0 name:sysContact.0 = string: twsnmp@gmail.com
1: oid: .1.3.6.1.2.1.1.7.0 name:sysServices.0 = number: 72
のようになります。
余談
SNMPv3の認証、暗号化などについては
に詳しく書きました。