見出し画像

TWSNMP FCの改善:パスワードリセット対応完了、sFlow対応の途中

今朝は4時半に自力で起きました。助手の猫さんは、昨夜、かみさんといっしょに遅くまで起きていたようで、かみさんの隣に寝ていました。私が開発に集中している5時過ぎに騒いで、かみさんを起こしたらしく寝室から締め出されていました。窓辺においた、新しい猫ベッドで寝ていました。

sFlowのGO言語パッケージも使えるようになったのでTWSNMP FC組み込みたいところですが、先にパスワードリセット機能を作りました。
起動パラメータに

  -resetPassword
    	Reset user:password to twsnmp:twsnmp

を追加して、指定すれば、ユーザー名とパスワードをデフォルト値に戻します。

sFlowの対応ですが、EVE-NGのテスト環境に設置したvyOSとFortiGateからsFlowを送信して対応するサンプルの種類を考えました。
受信するテストプログラムは

package main

import (
	"bytes"
	"fmt"
	"log"
	"net"
	"os"
	"strings"

	"github.com/Cistern/sflow"
	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
)

func main() {
	conn, err := net.ListenPacket("udp", ":6343")
	if err != nil {
		log.Fatalln(err)
	}
	defer conn.Close()
	data := make([]byte, 1500)
	for {
		l, ra, err := conn.ReadFrom(data)
		if err != nil {
			log.Fatalln(err)
		}
		r := bytes.NewReader(data[:l])
		d := sflow.NewDecoder(r)
		dg, err := d.Decode()
		if err != nil {
			log.Println(err)
			continue
		}
		log.Printf("rs=%s", ra)
		for _, sample := range dg.Samples {
			// Sample is an interface type
			switch s := sample.(type) {
			case *sflow.CounterSample:
				for _, record := range s.Records {
					switch csr := record.(type) {
					case sflow.HostDiskCounters:
						log.Printf("%+v", csr)
					case sflow.HostCPUCounters:
						log.Printf("%+v", csr)
					case sflow.HostMemoryCounters:
						log.Printf("%+v", csr)
					case sflow.HostNetCounters:
						log.Printf("%+v", csr)
					case sflow.GenericInterfaceCounters:
						log.Printf("%+v", csr)
					default:
						log.Fatalf("unknown counter sample %v", csr)
					}
				}
			case *sflow.FlowSample:
				{
					for _, record := range s.Records {
						switch fsr := record.(type) {
						case sflow.RawPacketFlow:
							packet := gopacket.NewPacket(fsr.Header, layers.LayerTypeEthernet, gopacket.Default)
							log.Printf("%+v", packet)
						}
					}
				}
			case *sflow.EventDiscardedPacket:
				{
					log.Printf("reason=%d", s.Reason)
					for _, record := range s.Records {
						switch fsr := record.(type) {
						case sflow.RawPacketFlow:
							packet := gopacket.NewPacket(fsr.Header, layers.LayerTypeEthernet, gopacket.Default)
							log.Printf("%+v", packet)
						}
					}
					os.WriteFile("event_discarded_packet.dump", data[:l], 0660)
					for _, d := range data[:l] {
						fmt.Printf("0x%02x,", d)
					}
				}

			default:
				log.Fatalf("unknown sample =%+v", sample)
			}
		}
	}
}

のような感じです。受信できるデータを観測しました。

  • Ethernetのパケットヘッダサンプル(vyOS/FortiGate)

  • インターフェイスの通信量(vyOS/FortiGate)

  • CPU使用率(vyOSのみ)

  • メモリー使用率(vyOSのみ)

  • ディスク使用率(vyOSのみ)

  • 破棄したパケットのサンプル(vyOSのみ)

のようなデータが取得できました。これを元に対応する項目を考えて

Ethernetのパケットヘッダを送信するFlowサンプルはとインターフェイスの通信量を表すCounterサンプルはどちらでもあるので、対応しようと思います。(マインドマップの★のアイコンの項目です。)

という方針で、作り始めました。設定画面


と受信する処理を作ったところで時間切れです。

明日に続く


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