見出し画像

TWSNMPをSNMPv3に対応する

TWSNMPをSNMPv3に対応した時の話を書いておきます。梅雨入りして外は雨が激しく降っています。猫はソファーに吐いてしまったのでキーボードから離れて寝ています。あと、久しぶりに浦和レッズの練習試合をライブ中継で観ることができました。

SNMPパッケージのおさらい

TWSNMPではSNMP対応のためGO言語の

というパッケージを使用しています。exampleのフォルダにSNMPv3対応のサンプルプログラムが公開されています。これを参考にすれば比較的簡単にSNMPv3に対応できました。

SNMPv3対応のための設定項目

まず、ドキュメント

とサンプルコードでSNMPv3でアクセスするための設定を眺めてみます。

		Version:       g.Version3,
		SecurityModel: g.UserSecurityModel,
		MsgFlags:      g.AuthPriv,
		SecurityParameters: &g.UsmSecurityParameters{UserName: "user",
			AuthenticationProtocol:   g.SHA,
			AuthenticationPassphrase: "password",
			PrivacyProtocol:          g.AES,
			PrivacyPassphrase:        "password",
		},

設定するパラメータは、

Version
SNMPのバージョンです。当然V3に設定します。
SecurityModel
セキュリティーモデルです。これはユーザーベースセキュリティーモデルしか使われていないのでこの設定でよいです。
MsgFlags
この設定は、認証と暗号化に関する設定です。
 *認証のみ
 *認証と暗号化
が選択できます。(暗号化だけは意味がないのでありません。)
UserName
SNMPv3でアクセスする時にユーザー名です。
AuthenticationProtocol
認証のための設定です。MD5とSHA1が選択できます。
AuthenticationPassphrase
認証のためのパスワードです。
PrivacyProtocol
暗号化のための設定です。DESとAESが選択できます。
PrivacyPassphrase
暗号化のためのパスワードです。

です。この内容をよく考えて実際に設定できる項目は、

画像1

SNMPモードは、

画像2

のような選択項目にしました。作る側の論理だと考えられるすべての組み合わせを設定できるようにしたほうがよいと思うかもしれませんが、使う側で考えると「じゃどれがお勧め」という感じだと思ったのでお勧めの選択だけにしました。

SNMPv3でMIB取得する

ポーリング、自動発見、MIBブラウザーのMIBアクセスをSNMPv3に対応することを考えます。もともとのソースコードは

	agent := &gosnmp.GoSNMP{
		Target:             n.IP,
		Port:               161,
		Transport:          "udp",
		Community:          n.Community,
		Version:            gosnmp.Version2c,
		Timeout:            time.Duration(p.Timeout) * time.Second,
		Retries:            p.Retry,
		ExponentialTimeout: true,
		MaxOids:            gosnmp.MaxOids,
	}
  err := agent.Connect()

のようになっていました。 agent.Connect()の前に

	if n.SnmpMode != "" {
		agent.Version = gosnmp.Version3
		agent.SecurityModel = gosnmp.UserSecurityModel
		if n.SnmpMode == "v3auth" {
			agent.MsgFlags = gosnmp.AuthNoPriv
			agent.SecurityParameters = &gosnmp.UsmSecurityParameters{
				UserName:                 n.User,
				AuthenticationProtocol:   gosnmp.SHA,
				AuthenticationPassphrase: n.Password,
			}
		} else {
			agent.MsgFlags = gosnmp.AuthPriv
			agent.SecurityParameters = &gosnmp.UsmSecurityParameters{
				UserName:                 n.User,
				AuthenticationProtocol:   gosnmp.SHA,
				AuthenticationPassphrase: n.Password,
				PrivacyProtocol:          gosnmp.AES,
				PrivacyPassphrase:        n.Password,
			}
		}
	}

を挿入すればSNMPv3に対応できました。n.Userとかが設定した値です。

SNMPv3のTRAPを受信する

TRAPの受信も修正しないとSNMPv3のTRAPは受信できません。これも比較的簡単に修正できました。

	tl := gosnmp.NewTrapListener()
	tl.OnNewTrap = func(s *gosnmp.SnmpPacket, u *net.UDPAddr) {
      |
    }

だったものを

	tl := gosnmp.NewTrapListener()
	if mapConf.SnmpMode != "" {
		tl.Params = &gosnmp.GoSNMP{}
		tl.Params.Version = gosnmp.Version3
		tl.Params.SecurityModel = gosnmp.UserSecurityModel
		if mapConf.SnmpMode == "v3auth" {
			tl.Params.MsgFlags = gosnmp.AuthNoPriv
			tl.Params.SecurityParameters = &gosnmp.UsmSecurityParameters{
				UserName:                 mapConf.User,
				AuthenticationProtocol:   gosnmp.SHA,
				AuthenticationPassphrase: mapConf.Password,
			}
		} else {
			tl.Params.MsgFlags = gosnmp.AuthPriv
			tl.Params.SecurityParameters = &gosnmp.UsmSecurityParameters{
				UserName:                 mapConf.User,
				AuthenticationProtocol:   gosnmp.SHA,
				AuthenticationPassphrase: mapConf.Password,
				PrivacyProtocol:          gosnmp.AES,
				PrivacyPassphrase:        mapConf.Password,
			}
		}
	}
	tl.OnNewTrap = func(s *gosnmp.SnmpPacket, u *net.UDPAddr) {
    |
  }

のようにSNMPv3のための設定する部分を挿入しました。思っていたより簡単に修正できました。

SNMPv3のセキュリティーについて思うこと

SNMPのセキュリティーには面白歴史があります。最初のSNMPv1はCommunityという文字列を合言葉としてマネージャとエージェントで共有するという簡単セキュリティーしかありませんでした。今、思うとかなり怖いことです。それではいけないとSNMPv2でセキュリティーを強化した仕様の検討が始まりました。これはSNMPのメーリングリスト上で大喧嘩が行われる。プロトコル戦争に発展しました。結局、セキュリティーに関する仕様はまとまらずにSNMPv1と同じCommunityを使うSNMPv2cだけ残りました。戦争の原因は実際に使う時に難しすぎて使えないということだったと思います。この戦争は、25年以上前でした。私もちょっとだけ巻き込まれました。
その後、仕切り直しでSNMPv3の仕様が決められました。セキュリティー機能も搭載されました。使っている暗号技術は当時としては良かったのですが今となっては、ちょっと心配なものです。認証に使うMD5やSHA1などのハッシュ関数や暗号に使うDESやAES128は今では推奨されていません。Ciscoなどは独自の仕様で暗号方式を拡張していたりします。
でも、今はSNMP自体のセキュリティー機能よりも別の通信技術(VPN、FWなど)でセキュリティーを確保できるので、SNMPの仕様を拡張する必要はないと私は思っています。




開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。