From 9298988287e13e218748f38f79e5fc38e18b4db6 Mon Sep 17 00:00:00 2001 From: sberk42 Date: Thu, 11 Jun 2020 13:43:29 +0200 Subject: [PATCH] initial version, with environment variables and https support --- Dockerfile | 12 --- README.md | 157 ++++++++------------------------------- fritzbox_upnp/service.go | 13 +++- main.go | 30 +++++--- 4 files changed, 59 insertions(+), 153 deletions(-) delete mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 0ecff0c..0000000 --- a/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM golang:1.8-alpine - -ADD . $GOPATH/src/github.com/ndecker/fritzbox_exporter - -RUN apk add --no-cache git -RUN go get -v github.com/ndecker/fritzbox_exporter - -EXPOSE 9133 - -ENTRYPOINT ["fritzbox_exporter"] -CMD [""] - diff --git a/README.md b/README.md index 14cb820..a72b368 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,25 @@ This exporter exports some variables from an [AVM Fritzbox](http://avm.de/produkte/fritzbox/) to prometheus. -This exporter is tested with a Fritzbox 7490 and 7390 with software version 06.51. +This exporter is tested with a Fritzbox 7590 software version 07.12. + +This is a fork from: +https://github.com/123Haynes/fritzbox_exporter +which is forked from: +https://github.com/ndecker/fritzbox_exporter + +The goal of the fork is: + - allow passing of username / password using evironment variable - done + - use https instead of http for communitcation with fritz.box - done + - move config of metrics to be exported to config file rather then code + - add config for additional metrics to collect (especially from TR-064 API) + - create a grafana dashboard consing the additional metrics + ## Building - go get github.com/ndecker/fritzbox_exporter/ - cd $GOPATH/src/github.com/ndecker/fritzbox_exporter + go get github.com/sberk42/fritzbox_exporter/ + cd $GOPATH/src/github.com/sberk42/fritzbox_exporter go install ## Running @@ -21,137 +34,27 @@ Usage: $GOPATH/bin/fritzbox_exporter -h Usage of ./fritzbox_exporter: - -gateway-address string - The hostname or IP of the FRITZ!Box (default "fritz.box") - -gateway-port int - The port of the FRITZ!Box UPnP service (default 49000) + -gateway-url string + The URL of the FRITZ!Box (default "https://fritz.box:49443") -listen-address string - The address to listen on for HTTP requests. (default ":9133") + The address to listen on for HTTP requests. (default "127.0.0.1:9042") + -password string + The password for the FRITZ!Box UPnP service -test - print all available metrics to stdout + print all available metrics to stdout + -username string + The user for the FRITZ!Box UPnP service -## Exported metrics + The password (needed for metrics from TR-064 API) can be passed over environment variables to test in shell: + read -rs PASSWORD && ./fritzbox_exporter -username -test; unset PASSWORD -These metrics are exported: - - # HELP fritzbox_exporter_collect_errors Number of collection errors. - # TYPE fritzbox_exporter_collect_errors counter - fritzbox_exporter_collect_errors 0 - # HELP gateway_wan_bytes_received bytes received on gateway WAN interface - # TYPE gateway_wan_bytes_received counter - gateway_wan_bytes_received{gateway="fritz.box"} 5.037749914e+09 - # HELP gateway_wan_bytes_sent bytes sent on gateway WAN interface - # TYPE gateway_wan_bytes_sent counter - gateway_wan_bytes_sent{gateway="fritz.box"} 2.55707479e+08 - # HELP gateway_wan_connection_status WAN connection status (Connected = 1) - # TYPE gateway_wan_connection_status gauge - gateway_wan_connection_status{gateway="fritz.box"} 1 - # HELP gateway_wan_connection_uptime_seconds WAN connection uptime - # TYPE gateway_wan_connection_uptime_seconds gauge - gateway_wan_connection_uptime_seconds{gateway="fritz.box"} 65259 - # HELP gateway_wan_layer1_downstream_max_bitrate Layer1 downstream max bitrate - # TYPE gateway_wan_layer1_downstream_max_bitrate gauge - gateway_wan_layer1_downstream_max_bitrate{gateway="fritz.box"} 1.286e+07 - # HELP gateway_wan_layer1_link_status Status of physical link (Up = 1) - # TYPE gateway_wan_layer1_link_status gauge - gateway_wan_layer1_link_status{gateway="fritz.box"} 1 - # HELP gateway_wan_layer1_upstream_max_bitrate Layer1 upstream max bitrate - # TYPE gateway_wan_layer1_upstream_max_bitrate gauge - gateway_wan_layer1_upstream_max_bitrate{gateway="fritz.box"} 1.148e+06 - # HELP gateway_wan_packets_received packets received on gateway WAN interface - # TYPE gateway_wan_packets_received counter - gateway_wan_packets_received{gateway="fritz.box"} 1.346625e+06 - # HELP gateway_wan_packets_sent packets sent on gateway WAN interface - # TYPE gateway_wan_packets_sent counter - gateway_wan_packets_sent{gateway="fritz.box"} 3.05051e+06 +## Exported metrics +start exporter and run +curl -s http://127.0.0.1:9042/metrics ## Output of -test The exporter prints all available Variables to stdout when called with the -test option. -These values are determined by parsing all services from http://fritz.box:49000/igddesc.xml - - Name: urn:schemas-any-com:service:Any:1 - WANDevice - FRITZ!Box 7490: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 - GetCommonLinkProperties - WANAccessType: DSL - Layer1UpstreamMaxBitRate: 1148000 - Layer1DownstreamMaxBitRate: 12860000 - PhysicalLinkStatus: Up - GetTotalBytesSent - TotalBytesSent: 255710914 - GetTotalBytesReceived - TotalBytesReceived: 5037753042 - GetTotalPacketsSent - TotalPacketsSent: 3050536 - GetTotalPacketsReceived - TotalPacketsReceived: 1346651 - GetAddonInfos - ByteSendRate: 0 - ByteReceiveRate: 0 - PacketSendRate: 0 - PacketReceiveRate: 0 - TotalBytesSent: 255710914 - TotalBytesReceived: 5037753042 - AutoDisconnectTime: 0 - IdleDisconnectTime: 10 - DNSServer1: 1.1.1.1 - DNSServer2: 2.2.2.2 - VoipDNSServer1: 1.1.1.1 - VoipDNSServer2: 2.2.2.2 - UpnpControlEnabled: false - RoutedBridgedModeBoth: 1 - WANConnectionDevice - FRITZ!Box 7490: urn:schemas-upnp-org:service:WANDSLLinkConfig:1 - GetDSLLinkInfo - LinkType: PPPoE - LinkStatus: Up - GetModulationType - ModulationType: ADSL G.lite - GetDestinationAddress - DestinationAddress: NONE - GetATMEncapsulation - ATMEncapsulation: LLC - GetFCSPreserved - FCSPreserved: true - GetAutoConfig - AutoConfig: true - WANConnectionDevice - FRITZ!Box 7490: urn:schemas-upnp-org:service:WANIPConnection:1 - X_AVM_DE_GetDNSServer - IPv4DNSServer1: 1.1.1.1 - IPv4DNSServer2: 2.2.2.2 - GetAutoDisconnectTime - AutoDisconnectTime: 0 - GetIdleDisconnectTime - IdleDisconnectTime: 0 - X_AVM_DE_GetExternalIPv6Address - ExternalIPv6Address: - PrefixLength: 0 - ValidLifetime: 0 - PreferedLifetime: 0 - GetNATRSIPStatus - RSIPAvailable: false - NATEnabled: true - GetExternalIPAddress - ExternalIPAddress: 1.1.1.1 - X_AVM_DE_GetIPv6Prefix - IPv6Prefix: - PrefixLength: 0 - ValidLifetime: 0 - PreferedLifetime: 0 - X_AVM_DE_GetIPv6DNSServer - IPv6DNSServer1: - ValidLifetime1: 2002000000 - IPv6DNSServer2: - ValidLifetime2: 199800000 - GetConnectionTypeInfo - ConnectionType: IP_Routed - PossibleConnectionTypes: IP_Routed - GetStatusInfo - ConnectionStatus: Connected - LastConnectionError: ERROR_NONE - Uptime: 65386 - WANConnectionDevice - FRITZ!Box 7490: urn:schemas-upnp-org:service:WANIPv6FirewallControl:1 - GetFirewallStatus - FirewallEnabled: true - InboundPinholeAllowed: false +These values are determined by parsing all services from http://fritz.box:49000/igddesc.xml and http://fritzbox:49000/tr64desc.xml (for TR64 username and password is needed!!!) diff --git a/fritzbox_upnp/service.go b/fritzbox_upnp/service.go index 889d5fa..163dd38 100644 --- a/fritzbox_upnp/service.go +++ b/fritzbox_upnp/service.go @@ -23,6 +23,7 @@ import ( "io" "log" "net/http" + "crypto/tls" "strconv" "strings" @@ -328,9 +329,15 @@ func convertResult(val string, arg *Argument) (interface{}, error) { } // Load the services tree from an device. -func LoadServices(device string, port uint16, username string, password string) (*Root, error) { +func LoadServices(baseurl string, username string, password string) (*Root, error) { + + if strings.HasPrefix(baseurl, "https://") { + // disable certificate validation, since fritz.box uses self signed cert + http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + var root = &Root{ - BaseUrl: fmt.Sprintf("http://%s:%d", device, port), + BaseUrl: baseurl, Username: username, Password: password, } @@ -341,7 +348,7 @@ func LoadServices(device string, port uint16, username string, password string) } var rootTr64 = &Root{ - BaseUrl: fmt.Sprintf("http://%s:%d", device, port), + BaseUrl: baseurl, Username: username, Password: password, } diff --git a/main.go b/main.go index 68f859e..c21a426 100644 --- a/main.go +++ b/main.go @@ -15,26 +15,26 @@ package main // limitations under the License. import ( - "flag" "fmt" "log" + "net/url" "net/http" "sync" "time" + "github.com/namsral/flag" "github.com/prometheus/client_golang/prometheus" - upnp "github.com/ndecker/fritzbox_exporter/fritzbox_upnp" + upnp "github.com/sberk42/fritzbox_exporter/fritzbox_upnp" ) const serviceLoadRetryTime = 1 * time.Minute var ( flag_test = flag.Bool("test", false, "print all available metrics to stdout") - flag_addr = flag.String("listen-address", ":9133", "The address to listen on for HTTP requests.") + flag_addr = flag.String("listen-address", "127.0.0.1:9042", "The address to listen on for HTTP requests.") - flag_gateway_address = flag.String("gateway-address", "fritz.box", "The hostname or IP of the FRITZ!Box") - flag_gateway_port = flag.Int("gateway-port", 49000, "The port of the FRITZ!Box UPnP service") + flag_gateway_url = flag.String("gateway-url", "https://fritz.box:49443", "The URL of the FRITZ!Box") flag_gateway_username = flag.String("username", "", "The user for the FRITZ!Box UPnP service") flag_gateway_password = flag.String("password", "", "The password for the FRITZ!Box UPnP service") ) @@ -182,8 +182,8 @@ var metrics = []*Metric{ } type FritzboxCollector struct { + Url string Gateway string - Port uint16 Username string Password string @@ -194,7 +194,7 @@ type FritzboxCollector struct { // LoadServices tries to load the service information. Retries until success. func (fc *FritzboxCollector) LoadServices() { for { - root, err := upnp.LoadServices(fc.Gateway, fc.Port, fc.Username, fc.Password) + root, err := upnp.LoadServices(fc.Url, fc.Username, fc.Password) if err != nil { fmt.Printf("cannot load services: %s\n", err) @@ -296,12 +296,14 @@ func (fc *FritzboxCollector) Collect(ch chan<- prometheus.Metric) { } func test() { - root, err := upnp.LoadServices(*flag_gateway_address, uint16(*flag_gateway_port), *flag_gateway_username, *flag_gateway_password) + root, err := upnp.LoadServices(*flag_gateway_url, *flag_gateway_username, *flag_gateway_password) if err != nil { panic(err) } - for _, s := range root.Services { + for k, s := range root.Services { + fmt.Printf("Name: %s\n", k) + for _, a := range s.Actions { if !a.IsGetOnly() { continue @@ -324,14 +326,20 @@ func test() { func main() { flag.Parse() + u, err := url.Parse(*flag_gateway_url) + if err != nil { + fmt.Errorf("invalid URL", err) + return + } + if *flag_test { test() return } collector := &FritzboxCollector{ - Gateway: *flag_gateway_address, - Port: uint16(*flag_gateway_port), + Url: *flag_gateway_url, + Gateway: u.Hostname(), Username: *flag_gateway_username, Password: *flag_gateway_password, }