This repository has been archived by the owner on Mar 27, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 140
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes: netdata/netdata#5631
- Loading branch information
Showing
10 changed files
with
469 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,3 +31,4 @@ modules: | |
# solr: yes | ||
# springboot2: yes | ||
# web_log: yes | ||
# x509check: yes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
# netdata go.d.plugin configuration for x509check | ||
# | ||
# This file is in YaML format. Generally the format is: | ||
# | ||
# name: value | ||
# | ||
# There are 2 sections: | ||
# - GLOBAL | ||
# - JOBS | ||
# | ||
# | ||
# [ GLOBAL ] | ||
# These variables set the defaults for all JOBs, however each JOB may define its own, overriding the defaults. | ||
# | ||
# The GLOBAL section format: | ||
# param1: value1 | ||
# param2: value2 | ||
# | ||
# Currently supported global parameters: | ||
# - update_every | ||
# Data collection frequency in seconds. Default: 1. | ||
# | ||
# - autodetection_retry | ||
# Re-check interval in seconds. Attempts to start the job are made once every interval. | ||
# Zero means not to schedule re-check. Default: 0. | ||
# | ||
# | ||
# [ JOBS ] | ||
# JOBS allow you to collect values from multiple sources. | ||
# Each source will have its own set of charts. | ||
# | ||
# IMPORTANT: | ||
# - Parameter 'name' is mandatory. | ||
# - Jobs with the same name are mutually exclusive. Only one of them will be allowed running at any time. | ||
# | ||
# This allows autodetection to try several alternatives and pick the one that works. | ||
# Any number of jobs is supported. | ||
# | ||
# The JOBS section format: | ||
# | ||
# jobs: | ||
# - name: job1 | ||
# param1: value1 | ||
# param2: value2 | ||
# | ||
# - name: job2 | ||
# param1: value1 | ||
# param2: value2 | ||
# | ||
# - name: job2 | ||
# param1: value1 | ||
# | ||
# | ||
# [ List of JOB specific parameters ]: | ||
# - source | ||
# Certificate source. Allowed schemes: https, tcp, tcp4, tcp6, udp, udp4, udp6. | ||
# Syntax: | ||
# source: https://example.org:443 | ||
# | ||
# - days_until_expiration_warning | ||
# Number of days before the alarm status is warning. | ||
# Syntax: | ||
# days_until_expiration_warning: 30 | ||
# | ||
# - days_until_expiration_critical | ||
# Number of days before the alarm status is critical. | ||
# Syntax: | ||
# days_until_expiration_critical: 15 | ||
# | ||
# - timeout | ||
# SSL connection timeout. | ||
# Syntax: | ||
# timeout: 3 | ||
# | ||
# - tls_skip_verify | ||
# Whether to skip verifying server's certificate chain and hostname. | ||
# Syntax: | ||
# tls_skip_verify: yes/no | ||
# | ||
# - tls_ca | ||
# Certificate authority that client use when verifying server certificates. | ||
# Syntax: | ||
# tls_ca: path/to/ca.pem | ||
# | ||
# - tls_cert | ||
# Client tls certificate. | ||
# Syntax: | ||
# tls_cert: path/to/cert.pem | ||
# | ||
# - tls_key | ||
# Client tls key. | ||
# Syntax: | ||
# tls_key: path/to/key.pem | ||
# | ||
# | ||
# [ JOB defaults ]: | ||
# days_until_expiration_warning: 14 | ||
# days_until_expiration_critical: 7 | ||
# timeout: 2 | ||
# tls_skip_verify: no | ||
# | ||
# | ||
# [ JOB mandatory parameters ]: | ||
# - name | ||
# - source | ||
# | ||
# ------------------------------------------------MODULE-CONFIGURATION-------------------------------------------------- | ||
# [ GLOBAL ] | ||
# update_every: 60 | ||
# autodetection_retry: 0 | ||
# | ||
# | ||
# [ JOBS ] | ||
# jobs: | ||
# - name: example_org | ||
# source: https://example.org:443 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# x509 certificate expiry check | ||
|
||
Checks the time until a x509 certificate expires. | ||
|
||
It produces the following charts: | ||
|
||
1. **Time Until Certificate Expiration** in seconds | ||
* time | ||
|
||
### configuration | ||
|
||
For all available options and defaults please see module [configuration file](https://github.com/netdata/go.d.plugin/blob/master/config/go.d/x509.conf). | ||
___ | ||
|
||
```yaml | ||
update_every : 60 | ||
|
||
jobs: | ||
- name: example_org | ||
source: https://example.org:443 | ||
|
||
- name: my_site_org | ||
source: https://my_site_org:443 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package x509check | ||
|
||
import ( | ||
"crypto/tls" | ||
"crypto/x509" | ||
"encoding/pem" | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
"net" | ||
"net/url" | ||
"time" | ||
|
||
"github.com/netdata/go.d.plugin/pkg/web" | ||
) | ||
|
||
var supportedSchemes = []string{ | ||
//"file", | ||
"https", | ||
"tcp", | ||
"tcp4", | ||
"tcp6", | ||
"udp", | ||
"udp4", | ||
"udp6", | ||
} | ||
|
||
func newCertGetter(config Config) (certGetter, error) { | ||
if config.Source == "" { | ||
return nil, errors.New("'source' parameter is mandatory, but it's not set") | ||
} | ||
|
||
u, err := url.Parse(config.Source) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("error on parsing source : %v", err) | ||
} | ||
|
||
switch u.Scheme { | ||
// TODO: not tested | ||
//case "file": | ||
// return newFileCertGetter(u.Path), nil | ||
case "https": | ||
u.Scheme = "tcp" | ||
fallthrough | ||
case "udp", "udp4", "udp6", "tcp", "tcp4", "tcp6": | ||
tlsCfg, err := web.NewTLSConfig(config.ClientTLSConfig) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("error on creating tls config : %v", err) | ||
} | ||
|
||
if tlsCfg == nil { | ||
tlsCfg = &tls.Config{} | ||
} | ||
|
||
tlsCfg.ServerName = u.Hostname() | ||
|
||
return newURLCertGetter(u, tlsCfg, config.Timeout.Duration), nil | ||
} | ||
|
||
return nil, fmt.Errorf("unsupported scheme in '%s', supported schemes : %v", u, supportedSchemes) | ||
} | ||
|
||
type certGetter interface { | ||
getCert() ([]*x509.Certificate, error) | ||
} | ||
|
||
func newFileCertGetter(path string) *fileCertGetter { | ||
return &fileCertGetter{path: path} | ||
} | ||
|
||
type fileCertGetter struct { | ||
path string | ||
} | ||
|
||
func (fg fileCertGetter) getCert() ([]*x509.Certificate, error) { | ||
content, err := ioutil.ReadFile(fg.path) | ||
if err != nil { | ||
return nil, fmt.Errorf("error on reading '%s' : %v", fg.path, err) | ||
} | ||
|
||
block, _ := pem.Decode(content) | ||
if block == nil { | ||
return nil, fmt.Errorf("error on decoding '%s' : %v", fg.path, err) | ||
} | ||
|
||
cert, err := x509.ParseCertificate(block.Bytes) | ||
if err != nil { | ||
return nil, fmt.Errorf("error on parsing certigicate '%s' : %v", fg.path, err) | ||
} | ||
|
||
return []*x509.Certificate{cert}, nil | ||
} | ||
|
||
func newURLCertGetter(url *url.URL, tlsCfg *tls.Config, timeout time.Duration) *urlCertGetter { | ||
return &urlCertGetter{ | ||
url: url, | ||
tlsCfg: tlsCfg, | ||
timeout: timeout, | ||
} | ||
} | ||
|
||
type urlCertGetter struct { | ||
url *url.URL | ||
tlsCfg *tls.Config | ||
timeout time.Duration | ||
} | ||
|
||
func (ug urlCertGetter) getCert() ([]*x509.Certificate, error) { | ||
ipConn, err := net.DialTimeout(ug.url.Scheme, ug.url.Host, ug.timeout) | ||
if err != nil { | ||
return nil, fmt.Errorf("error on dial to '%s' : %v", ug.url, err) | ||
} | ||
|
||
defer ipConn.Close() | ||
|
||
conn := tls.Client(ipConn, ug.tlsCfg.Clone()) | ||
|
||
defer conn.Close() | ||
|
||
if err := conn.Handshake(); err != nil { | ||
return nil, fmt.Errorf("error on ssl handshake with '%s' : %v", ug.url, err) | ||
} | ||
|
||
certs := conn.ConnectionState().PeerCertificates | ||
|
||
return certs, nil | ||
} |
Oops, something went wrong.