Support TLS in TCP connectionst
authorhudashot <anarranaya@yandex.com>
Sun, 14 Feb 2016 21:53:32 +0000 (21:53 +0000)
committerhudashot <anarranaya@yandex.com>
Sun, 28 Feb 2016 18:52:19 +0000 (18:52 +0000)
This depends on prometheus/common#31

README.md
blackbox.yml
http.go
main.go
tcp.go
tls.go [new file with mode: 0644]

index 7b698f08b145a8aba2c11a77bd81e7d3c8ed6382..5bd0278ce4197f14b89266c0281e7f80945cd030 100644 (file)
--- a/README.md
+++ b/README.md
@@ -39,6 +39,14 @@ modules:
   tcp_connect:
     prober: tcp
     timeout: 5s
+  pop3s_banner:
+    prober: tcp
+    tcp:
+      query_response:
+      - expect: "^+OK"
+      tls: true
+      tls_config:
+        insecure_skip_verify: false
   ssh_banner:
     prober: tcp
     timeout: 5s
index 09d132374cc44f9e1416c75713b0c1fade239484..985b38bc6347fa3e15625a11d8e8778a72406fc9 100644 (file)
@@ -11,6 +11,14 @@ modules:
   tcp_connect:
     prober: tcp
     timeout: 5s
+  pop3s_banner:
+    prober: tcp
+    tcp:
+      query_response:
+      - expect: "^+OK"
+      tls: true
+      tls_config:
+        insecure_skip_verify: false
   icmp:
     prober: icmp
     timeout: 5s
diff --git a/http.go b/http.go
index a4ee69ff90e3b4e81c70b7c15c98f3aa6c356a1a..7253d5dde657db8894dee83ecbfad75644f1dc60 100644 (file)
--- a/http.go
+++ b/http.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-       "crypto/tls"
        "errors"
        "fmt"
        "io"
@@ -9,7 +8,6 @@ import (
        "net/http"
        "regexp"
        "strings"
-       "time"
 
        "github.com/prometheus/log"
 )
@@ -43,16 +41,6 @@ func matchRegularExpressions(reader io.Reader, config HTTPProbe) bool {
        return true
 }
 
-func getEarliestCertExpiry(state *tls.ConnectionState) time.Time {
-       earliest := time.Time{}
-       for _, cert := range state.PeerCertificates {
-               if (earliest.IsZero() || cert.NotAfter.Before(earliest)) && !cert.NotAfter.IsZero() {
-                       earliest = cert.NotAfter
-               }
-       }
-       return earliest
-}
-
 func probeHTTP(target string, w http.ResponseWriter, module Module) (success bool) {
        var isSSL, redirects int
        config := module.HTTP
diff --git a/main.go b/main.go
index 7ffdc1949f9006605e680dd727af564d42f3ce30..b41678b5400955d306025278638e6a435042bee6 100644 (file)
--- a/main.go
+++ b/main.go
@@ -10,6 +10,7 @@ import (
        "gopkg.in/yaml.v2"
 
        "github.com/prometheus/client_golang/prometheus"
+       "github.com/prometheus/common/config"
        "github.com/prometheus/log"
 )
 
@@ -45,7 +46,9 @@ type QueryResponse struct {
 }
 
 type TCPProbe struct {
-       QueryResponse []QueryResponse `yaml:"query_response"`
+       QueryResponse []QueryResponse  `yaml:"query_response"`
+       TLS           bool             `yaml:"tls"`
+       TLSConfig     config.TLSConfig `yaml:"tls_config"`
 }
 
 type ICMPProbe struct {
diff --git a/tcp.go b/tcp.go
index ff8950dee201183503381e005b639236106065df..8942b1b6924b019b2a9bcdf3ecc02f3e674a6d17 100644 (file)
--- a/tcp.go
+++ b/tcp.go
@@ -2,6 +2,7 @@ package main
 
 import (
        "bufio"
+       "crypto/tls"
        "fmt"
        "net"
        "net/http"
@@ -11,19 +12,37 @@ import (
        "github.com/prometheus/log"
 )
 
+func dialTCP(target string, module Module) (net.Conn, error) {
+       dialer := &net.Dialer{Timeout: module.Timeout}
+       if !module.TCP.TLS {
+               return dialer.Dial("tcp", target)
+       }
+       config, err := module.TCP.TLSConfig.GenerateConfig()
+       if err != nil {
+               return nil, err
+       }
+       return tls.DialWithDialer(dialer, "tcp", target, config)
+}
+
 func probeTCP(target string, w http.ResponseWriter, module Module) bool {
        deadline := time.Now().Add(module.Timeout)
-       conn, err := net.DialTimeout("tcp", target, module.Timeout)
+       conn, err := dialTCP(target, module)
        if err != nil {
                return false
        }
        defer conn.Close()
+
        // Set a deadline to prevent the following code from blocking forever.
        // If a deadline cannot be set, better fail the probe by returning an error
        // now rather than blocking forever.
        if err := conn.SetDeadline(deadline); err != nil {
                return false
        }
+       if module.TCP.TLS {
+               state := conn.(*tls.Conn).ConnectionState()
+               fmt.Fprintf(w, "probe_ssl_earliest_cert_expiry %f\n",
+                       float64(getEarliestCertExpiry(&state).UnixNano())/1e9)
+       }
        scanner := bufio.NewScanner(conn)
        for _, qr := range module.TCP.QueryResponse {
                log.Debugf("Processing query response entry %+v", qr)
diff --git a/tls.go b/tls.go
new file mode 100644 (file)
index 0000000..2002454
--- /dev/null
+++ b/tls.go
@@ -0,0 +1,16 @@
+package main
+
+import (
+       "crypto/tls"
+       "time"
+)
+
+func getEarliestCertExpiry(state *tls.ConnectionState) time.Time {
+       earliest := time.Time{}
+       for _, cert := range state.PeerCertificates {
+               if (earliest.IsZero() || cert.NotAfter.Before(earliest)) && !cert.NotAfter.IsZero() {
+                       earliest = cert.NotAfter
+               }
+       }
+       return earliest
+}