mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 00:45:19 +00:00
14729 smtp settings validation for TLS (#15029)
This commit is contained in:
parent
4194c44131
commit
0557f10ac5
7
.github/workflows/test-go.yaml
vendored
7
.github/workflows/test-go.yaml
vendored
@ -61,7 +61,12 @@ jobs:
|
||||
# Pre-starting dependencies here means they are ready to go when we need them.
|
||||
- name: Start Infra Dependencies
|
||||
# Use & to background this
|
||||
run: FLEET_MYSQL_IMAGE=${{ matrix.mysql }} docker-compose -f docker-compose.yml -f docker-compose-redis-cluster.yml up -d mysql_test redis redis-cluster-1 redis-cluster-2 redis-cluster-3 redis-cluster-4 redis-cluster-5 redis-cluster-6 redis-cluster-setup minio saml_idp mailhog mailpit &
|
||||
run: FLEET_MYSQL_IMAGE=${{ matrix.mysql }} docker-compose -f docker-compose.yml -f docker-compose-redis-cluster.yml up -d mysql_test redis redis-cluster-1 redis-cluster-2 redis-cluster-3 redis-cluster-4 redis-cluster-5 redis-cluster-6 redis-cluster-setup minio saml_idp mailhog mailpit smtp4dev_test &
|
||||
|
||||
- name: Add TLS certificate for SMTP Tests
|
||||
run: |
|
||||
sudo cp tools/smtp4dev/fleet.crt /usr/local/share/ca-certificates/
|
||||
sudo update-ca-certificates
|
||||
|
||||
# It seems faster not to cache Go dependencies
|
||||
- name: Install Go Dependencies
|
||||
|
2
changes/14629-smtp-validation-fix
Normal file
2
changes/14629-smtp-validation-fix
Normal file
@ -0,0 +1,2 @@
|
||||
- Fixed: SMTP configuration was failing validation when attempting to send a test email to an SMTP server
|
||||
that only supports TLS
|
@ -76,6 +76,19 @@ services:
|
||||
"--smtp-auth-allow-insecure=true"
|
||||
]
|
||||
|
||||
# SMTP server with TLS
|
||||
smtp4dev_test:
|
||||
image: rnwood/smtp4dev:v3
|
||||
ports:
|
||||
- "8028:80"
|
||||
- "1027:25"
|
||||
volumes:
|
||||
- ./tools/smtp4dev:/certs
|
||||
environment:
|
||||
- ServerOptions__TlsMode=ImplicitTls
|
||||
- ServerOptions__TlsCertificate=/certs/fleet.crt
|
||||
- ServerOptions__TlsCertificatePrivateKey=/certs/fleet.key
|
||||
|
||||
redis:
|
||||
image: redis:5
|
||||
ports:
|
||||
|
@ -171,7 +171,17 @@ func (m mailService) sendMail(e fleet.Email, msg []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
client, err := dialTimeout(smtpHost)
|
||||
tlsConfig := &tls.Config{
|
||||
ServerName: e.SMTPSettings.SMTPServer,
|
||||
InsecureSkipVerify: !e.SMTPSettings.SMTPVerifySSLCerts,
|
||||
}
|
||||
|
||||
var client *smtp.Client
|
||||
if e.SMTPSettings.SMTPEnableTLS {
|
||||
client, err = dialTimeout(smtpHost, tlsConfig)
|
||||
} else {
|
||||
client, err = dialTimeout(smtpHost, nil)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not dial smtp host: %w", err)
|
||||
}
|
||||
@ -179,11 +189,7 @@ func (m mailService) sendMail(e fleet.Email, msg []byte) error {
|
||||
|
||||
if e.SMTPSettings.SMTPEnableStartTLS {
|
||||
if ok, _ := client.Extension("STARTTLS"); ok {
|
||||
config := &tls.Config{
|
||||
ServerName: e.SMTPSettings.SMTPServer,
|
||||
InsecureSkipVerify: !e.SMTPSettings.SMTPVerifySSLCerts,
|
||||
}
|
||||
if err = client.StartTLS(config); err != nil {
|
||||
if err = client.StartTLS(tlsConfig); err != nil {
|
||||
return fmt.Errorf("startTLS error: %w", err)
|
||||
}
|
||||
}
|
||||
@ -221,9 +227,11 @@ func (m mailService) sendMail(e fleet.Email, msg []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
const dialTimeoutDuration = 28 * time.Second
|
||||
|
||||
// dialTimeout sets a timeout on net.Dial to prevent email from attempting to
|
||||
// send indefinitely.
|
||||
func dialTimeout(addr string) (client *smtp.Client, err error) {
|
||||
func dialTimeout(addr string, tlsConfig *tls.Config) (client *smtp.Client, err error) {
|
||||
// Ensure that errors are always returned after at least 5s to
|
||||
// eliminate (some) timing attacks (in which a malicious user tries to
|
||||
// port scan using the email functionality in Fleet)
|
||||
@ -235,7 +243,13 @@ func dialTimeout(addr string) (client *smtp.Client, err error) {
|
||||
}
|
||||
}()
|
||||
|
||||
conn, err := net.DialTimeout("tcp", addr, 28*time.Second)
|
||||
var conn net.Conn
|
||||
if tlsConfig == nil {
|
||||
conn, err = net.DialTimeout("tcp", addr, dialTimeoutDuration)
|
||||
} else {
|
||||
conn, err = tls.DialWithDialer(&net.Dialer{Timeout: dialTimeoutDuration}, "tcp", addr, tlsConfig)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("dialing with timeout: %w", err)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ var testFunctions = [...]func(*testing.T, fleet.MailService){
|
||||
testSMTPPlainAuth,
|
||||
testSMTPPlainAuthInvalidCreds,
|
||||
testSMTPSkipVerify,
|
||||
testSMTPNoAuth,
|
||||
testSMTPNoAuthWithTLS,
|
||||
testMailTest,
|
||||
}
|
||||
|
||||
@ -47,9 +47,9 @@ func testSMTPPlainAuth(t *testing.T, mailer fleet.MailService) {
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPEnableTLS: false,
|
||||
SMTPVerifySSLCerts: false,
|
||||
SMTPEnableStartTLS: false,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
@ -73,9 +73,9 @@ func testSMTPPlainAuthInvalidCreds(t *testing.T, mailer fleet.MailService) {
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "wrong",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPEnableTLS: false,
|
||||
SMTPVerifySSLCerts: false,
|
||||
SMTPEnableStartTLS: false,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
@ -102,7 +102,7 @@ func testSMTPSkipVerify(t *testing.T, mailer fleet.MailService) {
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: false,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1025,
|
||||
SMTPPort: 1027,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
@ -115,7 +115,7 @@ func testSMTPSkipVerify(t *testing.T, mailer fleet.MailService) {
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func testSMTPNoAuth(t *testing.T, mailer fleet.MailService) {
|
||||
func testSMTPNoAuthWithTLS(t *testing.T, mailer fleet.MailService) {
|
||||
mail := fleet.Email{
|
||||
Subject: "no auth",
|
||||
To: []string{"bob@foo.com"},
|
||||
@ -124,7 +124,8 @@ func testSMTPNoAuth(t *testing.T, mailer fleet.MailService) {
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameNone,
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPPort: 1025,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1027,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
@ -145,11 +146,12 @@ func testMailTest(t *testing.T, mailer fleet.MailService) {
|
||||
SMTPConfigured: true,
|
||||
SMTPAuthenticationType: fleet.AuthTypeNameUserNamePassword,
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPUserName: "foo",
|
||||
SMTPPassword: "bar",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPPort: 1026,
|
||||
SMTPEnableStartTLS: true,
|
||||
SMTPPort: 1027,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "test@example.com",
|
||||
},
|
||||
|
@ -59,8 +59,8 @@ func TestMailService(t *testing.T) {
|
||||
SMTPAuthenticationMethod: fleet.AuthMethodNamePlain,
|
||||
SMTPUserName: "mailpit-username",
|
||||
SMTPPassword: "mailpit-password",
|
||||
SMTPEnableTLS: true,
|
||||
SMTPVerifySSLCerts: true,
|
||||
SMTPEnableTLS: false,
|
||||
SMTPVerifySSLCerts: false,
|
||||
SMTPPort: 1026,
|
||||
SMTPServer: "localhost",
|
||||
SMTPSenderAddress: "foobar@example.com",
|
||||
@ -103,8 +103,8 @@ func TestMailService(t *testing.T) {
|
||||
"authentication_method": "authmethod_plain",
|
||||
"user_name": "mailpit-username",
|
||||
"password": "mailpit-password",
|
||||
"enable_ssl_tls": true,
|
||||
"verify_ssl_certs": true,
|
||||
"enable_ssl_tls": false,
|
||||
"verify_ssl_certs": false,
|
||||
"port": 1026,
|
||||
"server": "127.0.0.1",
|
||||
"sender_address": "foobar_updated@example.com"
|
||||
|
29
tools/smtp4dev/fleet.crt
Normal file
29
tools/smtp4dev/fleet.crt
Normal file
@ -0,0 +1,29 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIE5jCCAs6gAwIBAgIJAKq0+FAVArUhMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
|
||||
BAMMCkZsZWV0IFRlc3QwHhcNMjAxMDE1MTg1ODE5WhcNMzAwNzE1MTg1ODE5WjAV
|
||||
MRMwEQYDVQQDDApGbGVldCBUZXN0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||
CgKCAgEAttQ62lpMq48/XjQFxYg47D2fgKgTBMjDNSfCt9VpqE3xPnybmWo8VZtk
|
||||
jmrFM50IhagyYSjvl9iqdrnsl3ZV8KYbWEy6849zDYF1SudmC7/pJyH7QvpKgL7V
|
||||
4McM62jM905hyFy9KZTAlFiaeezWSWJre7kHsK2u5tsqS6ElatEZmF59sInixaRw
|
||||
RqVxOhtDm7Sl1c5xKWM6phWoJfykspFpu5J6N2jRQXCfzBYoQWN76OohGouit/BQ
|
||||
C1xvm+f7wgGZgbbfDjUoHAe9Yhd3XzZsYTgMDt/SRJRDnxFZwo8BAkY9yJm7f3dQ
|
||||
AEhgJ66KbyoxITdgma1hgmeWibZY4hVymcRxB1B3RNN2at19RNy2J+brMxlG0KZk
|
||||
nD77EqidrwLAlYcdeU3yLjt0vYPxT+RW7l1jiZlVi/oaykAmVfOhWnTnTwbsYs7O
|
||||
UMyMyYHQECEs98ex7wrjThIBJScqhsSN1ipAxr5RgaDr+U5IR+tLhMewBy8So+nf
|
||||
2YuMhLfkCgoY80ELhz5F8avts5hksB0hqnNYr+Nlwm6eXqEPZSzFJmdc1IbmWzq2
|
||||
7UH1OQmBFF2qr2j/8dcM+oPNgjrEEQjtyW0S4j2PhjSEbINgcwu0AaABssLI80Vm
|
||||
Gp1TjUGA92rMwIjlAtcUUB5FOKSS8vAXb1VcDWMkybh9sHj4Z0ECAwEAAaM5MDcw
|
||||
NQYDVR0RBC4wLIIJbG9jYWxob3N0ghRob3N0LmRvY2tlci5pbnRlcm5hbIIJMTI3
|
||||
LjAuMC4xMA0GCSqGSIb3DQEBCwUAA4ICAQBZOY++LNRTVG8XlQGVlOloEKA2WY3P
|
||||
gXKJLSM7xWSxj2co0v+noyhoInHT7ysub8en59Et+vN53/0OobxNIdEKDUdqs38R
|
||||
F++Oy6s/MhFHSo87F06t+W91/60ub4iFRHfev1qeNFV6Yzv9sFJ5LpXLFk+qVDb8
|
||||
pPyFFE1bXjctDPjD5gUj+Y34XikVKzMb7xddWCNs34v1KCaCBW7kkfefxiZiDR6g
|
||||
lCEkDzp6xaLS898oCbfFakjr4bvOgBP1IqXLIDLPMhivaxNAooHTtu/3ezp7puix
|
||||
TSDkjlkStDtEFw/wjyaMcEkk51Gs1ponBbADLRxQ50AHDWk/4vy8GcIVc6CdVEOA
|
||||
Zw12FN06C4Jviiiv6uCXZ6iZ+V+pjGiGmSNYF+kruUs8BfrJIB89lqxpdQ4Kx01j
|
||||
AuSFvjRRvIPmvApSdKEjLcY3AYRivXsB/hASMBbjh/p1f/JzSJdxoqSvONhNQJuh
|
||||
+wcdNVQhGAv3kkLn/HMHTBl2Ur+9tQaJrnR1tWl1IzwLRJIi0Soyp/q5ZjQyFglj
|
||||
32xW83DZhtpQ2SI1QGy4AvWIPnGHZhMfav02KnKRhZdOMW4oekXRMrwiyXCqIazc
|
||||
xXzAlCq8dHdP2Y9uvfFxVFyE+uSfkcPxX+DG/ZnpgCS27oKA/qLCybJamlqtveNs
|
||||
RSjNe5qwGi0ifA==
|
||||
-----END CERTIFICATE-----
|
52
tools/smtp4dev/fleet.key
Normal file
52
tools/smtp4dev/fleet.key
Normal file
@ -0,0 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
mWZen+G8ANnds10V7TmcpoaPSSoJMF0=
|
||||
-----END PRIVATE KEY-----
|
Loading…
Reference in New Issue
Block a user