From 8ce6fc0db55ce551d22b7c460b5533bc031fe67c Mon Sep 17 00:00:00 2001 From: Peter Krawczyk Date: Fri, 22 Aug 2025 00:04:03 -0400 Subject: [PATCH] Chore: Set HELO/EHLO hostname when connecting to external SMTP server (#556) When a message is forwarded or released, Mailpit introduces itself as `localhost` to the upstream server. This happens because `net/smtp` forces the value to be `localhost` if `client.Hello` is not called. This is explicitly documented at https://pkg.go.dev/net/smtp#Client.Hello Therefore, both `internal/smtpd/relay.go` (`createRelaySMTPClient`) and `internal/smtpd/forward.go` (`createForwardingSMTPClient`) should either call `client.Hello(os.Hostname())` or create a config (perhaps `config.HeloHostname`) and use `client.Hello()` with that value immediately before returning from either of those functions. (The HELO/EHLO command comes after TLS negotiation but before any other SMTP commands.) This commit does the former. Without this feature, Mailpit cannot be used in combination with Google Workspace's SMTP Relay functionality, as it rejects any connection that identifies itself as `localhost`. Relates to #146 --- internal/smtpd/forward.go | 8 ++++++++ internal/smtpd/relay.go | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/internal/smtpd/forward.go b/internal/smtpd/forward.go index 7f7978c..98fe9cf 100644 --- a/internal/smtpd/forward.go +++ b/internal/smtpd/forward.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "fmt" "net/smtp" + "os" "strings" "github.com/axllent/mailpit/config" @@ -60,6 +61,13 @@ func createForwardingSMTPClient(config config.SMTPForwardConfigStruct, addr stri } } + // Set the hostname for HELO/EHLO + if hostname, err := os.Hostname(); err == nil { + if err := client.Hello(hostname); err != nil { + return nil, fmt.Errorf("error saying HELO/EHLO to %s: %v", addr, err) + } + } + // Note: The caller is responsible for closing the client return client, nil } diff --git a/internal/smtpd/relay.go b/internal/smtpd/relay.go index 66c2829..5e94b0a 100644 --- a/internal/smtpd/relay.go +++ b/internal/smtpd/relay.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "net/smtp" + "os" "strings" "github.com/axllent/mailpit/config" @@ -94,6 +95,13 @@ func createRelaySMTPClient(config config.SMTPRelayConfigStruct, addr string) (*s } } + // Set the hostname for HELO/EHLO + if hostname, err := os.Hostname(); err == nil { + if err := client.Hello(hostname); err != nil { + return nil, fmt.Errorf("error saying HELO/EHLO to %s: %v", addr, err) + } + } + // Note: The caller is responsible for closing the client return client, nil }