diff --git a/.gitignore b/.gitignore index c7d3413..2c11dc4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # IDEs .idea +.vscode # artifacts target diff --git a/README.md b/README.md index 22a3e81..22e198e 100755 --- a/README.md +++ b/README.md @@ -87,6 +87,9 @@ Per-VDOM: * `fortigate_system_sdn_connector_last_update_seconds` * _User/Fsso_ * `fortigate_user_fsso_info` + * _User/Firewall_ + * `fortigate_user_firewall_duration_seconds` + * `fortigate_user_firewall_traffic_bytes` * _VPN/Ssl/Connections_ * `fortigate_vpn_connections` * `fortigate_vpn_users` diff --git a/docker-compose.yml b/docker-compose.yml index 6dabbb0..a484323 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,5 +6,6 @@ services: ports: - 9710:9710 volumes: - - /path/to/fortigate-key.yaml:/config/fortigate-key.yaml + - ./fortigate-key.yaml:/config/fortigate-key.yaml restart: unless-stopped + command: ["-auth-file", "/config/fortigate-key.yaml", "-insecure"] \ No newline at end of file diff --git a/fortigate-key.yaml b/fortigate-key.yaml new file mode 100644 index 0000000..780b117 --- /dev/null +++ b/fortigate-key.yaml @@ -0,0 +1,7 @@ +"https://hk-tel-fw-lo.hessenkom.net:7443": + token: dqwds6t6jhbwcHrkf6H09GymhrNqf8 + # If you have a smaller fortigate unit you might want + # to exclude sensors as they do not have any + probes: + exclude: + - System/SensorInfo \ No newline at end of file diff --git a/pkg/probe/probe.go b/pkg/probe/probe.go index c79a7f6..fb52a50 100644 --- a/pkg/probe/probe.go +++ b/pkg/probe/probe.go @@ -138,6 +138,7 @@ func (p *ProbeCollector) Probe(ctx context.Context, target map[string]string, hc {"System/Status", probeSystemStatus}, {"System/VDOMResources", probeSystemVDOMResources}, {"System/HAChecksum", probeSystemHAChecksum}, + {"User/Firewall", probeUserFirewall}, {"User/Fsso", probeUserFsso}, {"VPN/IPSec", probeVPNIPSec}, {"VPN/Ssl/Connections", probeVPNSsl}, diff --git a/pkg/probe/testdata/user-firewall.jsonnet b/pkg/probe/testdata/user-firewall.jsonnet new file mode 100644 index 0000000..8bd64b7 --- /dev/null +++ b/pkg/probe/testdata/user-firewall.jsonnet @@ -0,0 +1,49 @@ +# api/v2/monitor/user/firewall +[ + { + "http_method":"GET", + "results":[ + { + "type":"auth_logon", + "id":0, + "duration_secs":21476, + "auth_type":3, + "ipaddr":"192.168.24.18", + "src_type":"ip4", + "expiry_secs":7196, + "traffic_vol_bytes":908744605, + "method":"Firewall" + }, + { + "type":"auth_logon", + "id":0, + "duration_secs":6366, + "auth_type":3, + "ipaddr":"192.168.24.25", + "src_type":"ip4", + "expiry_secs":7168, + "traffic_vol_bytes":1738875, + "method":"Firewall" + }, + { + "type":"auth_logon", + "id":0, + "duration_secs":39266, + "auth_type":3, + "ipaddr":"192.168.27.150", + "src_type":"ip4", + "expiry_secs":4717, + "traffic_vol_bytes":79707852, + "method":"Firewall" + } + ], + "vdom":"VD_ES-WIFI", + "path":"user", + "name":"firewall", + "action":"", + "status":"success", + "serial":"ABCDxxxEFGH", + "version":"v7.0.12", + "build":523 + } +] \ No newline at end of file diff --git a/pkg/probe/user_firewall.go b/pkg/probe/user_firewall.go new file mode 100644 index 0000000..cc3beb8 --- /dev/null +++ b/pkg/probe/user_firewall.go @@ -0,0 +1,68 @@ +package probe + +import ( + "log" + "github.com/bluecmd/fortigate_exporter/pkg/http" + "github.com/prometheus/client_golang/prometheus" +) + +type UserFirewallResult struct { + Type string `json:"type"` + ID int `json:"id"` + DurationSecs int `json:"duration_secs"` + AuthType int `json:"auth_type"` + IPAddr string `json:"ipaddr"` + SrcType string `json:"src_type"` + ExpirySecs int `json:"expiry_secs"` + TrafficVolBytes int64 `json:"traffic_vol_bytes"` + Method string `json:"method"` +} + +type UserFirewall struct { + HttpMethod string `json:"http_method"` + Results []UserFirewallResult `json:"results"` + VDOM string `json:"vdom"` + Path string `json:"path"` + Name string `json:"name"` + Action string `json:"action"` + Status string `json:"status"` + Serial string `json:"serial"` + Version string `json:"version"` + Build int `json:"build"` +} + + +func probeUserFirewall(c http.FortiHTTP, meta *TargetMetadata) ([]prometheus.Metric, bool) { + var ( + userFirewallDuration = prometheus.NewDesc( + "fortigate_user_firewall_duration_seconds", + "Duration of user firewall activity in seconds", + []string{"vdom", "ipaddr", "method", "type"}, nil, + ) + userFirewallTraffic = prometheus.NewDesc( + "fortigate_user_firewall_traffic_bytes", + "Traffic volume in bytes for user firewall activity", + []string{"vdom", "ipaddr", "method", "type"}, nil, + ) + ) + + var res []UserFirewall + if err := c.Get("/api/v2/monitor/user/firewall", "vdom=*", &res); err != nil { + log.Printf("Error: %v", err) + return nil, false + } + + metrics := []prometheus.Metric{} + for _, fw := range res { + for _, r := range fw.Results { + metrics = append(metrics, prometheus.MustNewConstMetric( + userFirewallDuration, prometheus.GaugeValue, float64(r.DurationSecs), fw.VDOM, r.IPAddr, r.Method, r.Type, + )) + metrics = append(metrics, prometheus.MustNewConstMetric( + userFirewallTraffic, prometheus.GaugeValue, float64(r.TrafficVolBytes), fw.VDOM, r.IPAddr, r.Method, r.Type, + )) + } + } + + return metrics, true +} diff --git a/pkg/probe/user_firewall_test.go b/pkg/probe/user_firewall_test.go new file mode 100644 index 0000000..530a6e3 --- /dev/null +++ b/pkg/probe/user_firewall_test.go @@ -0,0 +1,36 @@ +package probe + +import ( + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil" +) + +func TestUserFirewall(t *testing.T) { + c := newFakeClient() + c.prepare("/api/v2/monitor/user/firewall", "testdata/user-firewall.jsonnet") + r := prometheus.NewPedanticRegistry() + if !testProbe(probeUserFirewall, c, r) { + t.Errorf("probeUserFirewall() returned non-success") + } + + em := ` + # HELP fortigate_user_firewall_duration_seconds Duration of user firewall activity in seconds + # TYPE fortigate_user_firewall_duration_seconds gauge + fortigate_user_firewall_duration_seconds{ipaddr="192.168.24.18",method="Firewall",type="auth_logon",vdom="VD_ES-WIFI"} 21476 + fortigate_user_firewall_duration_seconds{ipaddr="192.168.24.25",method="Firewall",type="auth_logon",vdom="VD_ES-WIFI"} 6366 + fortigate_user_firewall_duration_seconds{ipaddr="192.168.27.150",method="Firewall",type="auth_logon",vdom="VD_ES-WIFI"} 39266 + # HELP fortigate_user_firewall_traffic_bytes Traffic volume in bytes for user firewall activity + # TYPE fortigate_user_firewall_traffic_bytes gauge + fortigate_user_firewall_traffic_bytes{ipaddr="192.168.24.18",method="Firewall",type="auth_logon",vdom="VD_ES-WIFI"} 908744605 + fortigate_user_firewall_traffic_bytes{ipaddr="192.168.24.25",method="Firewall",type="auth_logon",vdom="VD_ES-WIFI"} 1738875 + fortigate_user_firewall_traffic_bytes{ipaddr="192.168.27.150",method="Firewall",type="auth_logon",vdom="VD_ES-WIFI"} 79707852 + ` + + + if err := testutil.GatherAndCompare(r, strings.NewReader(em)); err != nil { + t.Fatalf("metric compare: err %v", err) + } +}