feat(inputs.x509_cert): add smtp protocol (#11271)

Co-authored-by: dreiekk <dreiekk@users.noreply.github.com>
This commit is contained in:
skillor 2022-06-15 18:46:26 +02:00 committed by GitHub
parent 72e91baeac
commit 05285a1fdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 5 deletions

View File

@ -1,7 +1,7 @@
# x509 Certificate Input Plugin # x509 Certificate Input Plugin
This plugin provides information about X509 certificate accessible via local This plugin provides information about X509 certificate accessible via local
file or network connection. file, tcp, udp, https or smtp protocol.
When using a UDP address as a certificate source, the server must support When using a UDP address as a certificate source, the server must support
[DTLS](https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security). [DTLS](https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security).
@ -14,7 +14,8 @@ When using a UDP address as a certificate source, the server must support
## List certificate sources, support wildcard expands for files ## List certificate sources, support wildcard expands for files
## Prefix your entry with 'file://' if you intend to use relative paths ## Prefix your entry with 'file://' if you intend to use relative paths
sources = ["tcp://example.org:443", "https://influxdata.com:443", sources = ["tcp://example.org:443", "https://influxdata.com:443",
"udp://127.0.0.1:4433", "/etc/ssl/certs/ssl-cert-snakeoil.pem", "smtp://mail.localhost:25", "udp://127.0.0.1:4433",
"/etc/ssl/certs/ssl-cert-snakeoil.pem",
"/etc/mycerts/*.mydomain.org.pem", "file:///path/to/*.pem"] "/etc/mycerts/*.mydomain.org.pem", "file:///path/to/*.pem"]
## Timeout for SSL connection ## Timeout for SSL connection

View File

@ -3,7 +3,8 @@
## List certificate sources, support wildcard expands for files ## List certificate sources, support wildcard expands for files
## Prefix your entry with 'file://' if you intend to use relative paths ## Prefix your entry with 'file://' if you intend to use relative paths
sources = ["tcp://example.org:443", "https://influxdata.com:443", sources = ["tcp://example.org:443", "https://influxdata.com:443",
"udp://127.0.0.1:4433", "/etc/ssl/certs/ssl-cert-snakeoil.pem", "smtp://mail.localhost:25", "udp://127.0.0.1:4433",
"/etc/ssl/certs/ssl-cert-snakeoil.pem",
"/etc/mycerts/*.mydomain.org.pem", "file:///path/to/*.pem"] "/etc/mycerts/*.mydomain.org.pem", "file:///path/to/*.pem"]
## Timeout for SSL connection ## Timeout for SSL connection

View File

@ -10,6 +10,7 @@ import (
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"net" "net"
"net/smtp"
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
@ -176,6 +177,53 @@ func (c *X509Cert) getCert(u *url.URL, timeout time.Duration) ([]*x509.Certifica
} }
content = rest content = rest
} }
return certs, nil
case "smtp":
ipConn, err := net.DialTimeout("tcp", u.Host, timeout)
if err != nil {
return nil, err
}
defer ipConn.Close()
serverName, err := c.serverName(u)
if err != nil {
return nil, err
}
c.tlsCfg.ServerName = serverName
c.tlsCfg.InsecureSkipVerify = true
smtpConn, err := smtp.NewClient(ipConn, u.Host)
if err != nil {
return nil, err
}
err = smtpConn.Hello(c.tlsCfg.ServerName)
if err != nil {
return nil, err
}
id, err := smtpConn.Text.Cmd("STARTTLS")
if err != nil {
return nil, err
}
smtpConn.Text.StartResponse(id)
defer smtpConn.Text.EndResponse(id)
_, _, err = smtpConn.Text.ReadResponse(220)
if err != nil {
return nil, fmt.Errorf("did not get 220 after STARTTLS: %s", err.Error())
}
tlsConn := tls.Client(ipConn, c.tlsCfg)
defer tlsConn.Close()
hsErr := tlsConn.Handshake()
if hsErr != nil {
return nil, hsErr
}
certs := tlsConn.ConnectionState().PeerCertificates
return certs, nil return certs, nil
default: default:
return nil, fmt.Errorf("unsupported scheme '%s' in location %s", u.Scheme, u.String()) return nil, fmt.Errorf("unsupported scheme '%s' in location %s", u.Scheme, u.String())

View File

@ -355,12 +355,12 @@ func TestGatherCertMustNotTimeout(t *testing.T) {
func TestSourcesToURLs(t *testing.T) { func TestSourcesToURLs(t *testing.T) {
m := &X509Cert{ m := &X509Cert{
Sources: []string{"https://www.influxdata.com:443", "tcp://influxdata.com:443", "file:///dummy_test_path_file.pem", "/tmp/dummy_test_path_glob*.pem"}, Sources: []string{"https://www.influxdata.com:443", "tcp://influxdata.com:443", "smtp://influxdata.com:25", "file:///dummy_test_path_file.pem", "/tmp/dummy_test_path_glob*.pem"},
} }
require.NoError(t, m.Init()) require.NoError(t, m.Init())
require.Equal(t, len(m.globpaths), 2) require.Equal(t, len(m.globpaths), 2)
require.Equal(t, len(m.locations), 2) require.Equal(t, len(m.locations), 3)
} }
func TestServerName(t *testing.T) { func TestServerName(t *testing.T) {