From 16f6bbb5211f6ae9beebd85fabc3278c8130ab07 Mon Sep 17 00:00:00 2001 From: Femi Omojola Date: Thu, 13 Oct 2022 00:40:53 -0400 Subject: [PATCH 1/6] Support for configuring all command line flags via environment variable, and force-enabling the LOGIN mechanism --- main.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 10797a6..f337f9b 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,8 @@ import ( "os" "regexp" "strings" + "strconv" + "log" "github.com/blueimp/aws-smtp-relay/internal/auth" "github.com/blueimp/aws-smtp-relay/internal/relay" @@ -16,19 +18,19 @@ import ( ) var ( - addr = flag.String("a", ":1025", "TCP listen address") - name = flag.String("n", "AWS SMTP Relay", "SMTP service name") - host = flag.String("h", "", "Server hostname") - certFile = flag.String("c", "", "TLS cert file") - keyFile = flag.String("k", "", "TLS key file") - startTLS = flag.Bool("s", false, "Require TLS via STARTTLS extension") - onlyTLS = flag.Bool("t", false, "Listen for incoming TLS connections only") - relayAPI = flag.String("r", "ses", "Relay API to use (ses|pinpoint)") - setName = flag.String("e", "", "Amazon SES Configuration Set Name") - ips = flag.String("i", "", "Allowed client IPs (comma-separated)") - user = flag.String("u", "", "Authentication username") - allowFrom = flag.String("l", "", "Allowed sender emails regular expression") - denyTo = flag.String("d", "", "Denied recipient emails regular expression") + addr = flag.String("a", LookupEnvOrString("LISTEN_ADDRESS", ":1025"), "TCP listen address") + name = flag.String("n", LookupEnvOrString("SMTP_SERVICE_NAME", "AWS SMTP Relay"), "SMTP service name") + host = flag.String("h", LookupEnvOrString("HOSTNAME", ""), "Server hostname") + certFile = flag.String("c", LookupEnvOrString("CERT_FILE", ""), "TLS cert file") + keyFile = flag.String("k", LookupEnvOrString("KEY_FILE", ""), "TLS key file") + startTLS = flag.Bool("s", LookupEnvOrBool("REQUIRE_STARTTLS", false), "Require TLS via STARTTLS extension") + onlyTLS = flag.Bool("t", LookupEnvOrBool("REQUIRE_TLS", false), "Listen for incoming TLS connections only") + relayAPI = flag.String("r", LookupEnvOrString("RELAY_API", "ses"), "Relay API to use (ses|pinpoint)") + setName = flag.String("e", LookupEnvOrString("SES_CONFIGURATION_SET_NAME", ""), "Amazon SES Configuration Set Name") + ips = flag.String("i", LookupEnvOrString("ALLOWED_IPS", ""), "Allowed client IPs (comma-separated)") + user = flag.String("u", LookupEnvOrString("AUTH_USERNAME", ""), "Authentication username") + allowFrom = flag.String("l", LookupEnvOrString("ALLOWED_SENDERS_REGEX", ""), "Allowed sender emails regular expression") + denyTo = flag.String("d", LookupEnvOrString("DENIED_SENDERS_REGEX", ""), "Denied recipient emails regular expression") ) var ipMap map[string]bool @@ -41,6 +43,18 @@ func server() (srv *smtpd.Server, err error) { if *user != "" && len(bcryptHash) > 0 && len(password) == 0 { authMechs["CRAM-MD5"] = false } + + // force-enable the login mechanism: only needed if there is no external routing and TLS is not configured + if LookupEnvOrString("ENABLE_LOGIN", "") == "true" { + authMechs["LOGIN"] = true + } + + version := LookupEnvOrString("GIT_REV", "") + if version == "" { + log.Printf("Listening on %v\r\n", *addr) + }else{ + log.Printf("(Revision: %s) Listening on %v\r\n", version, *addr) + } srv = &smtpd.Server{ Addr: *addr, Handler: relayClient.Send, @@ -98,6 +112,38 @@ func configure() error { return nil } +// returns the value of an environment variable or the default value +func LookupEnvOrString(key string, defaultVal string) string { + if val, ok := os.LookupEnv(key); ok { + return val + } + return defaultVal +} + +func LookupEnvOrInt(key string, defaultVal int) int { + if val, ok := os.LookupEnv(key); ok { + v, err := strconv.Atoi(val) + if err != nil { + log.Fatalf("LookupEnvOrInt[%s]: %v", key, err) + } + return v + } + return defaultVal +} + +func LookupEnvOrBool(key string, defaultVal bool) bool { + if val, ok := os.LookupEnv(key); ok { + val = strings.ToLower(val) + if val == "true" { + return true + }else if val == "false" { + return false + } + log.Fatalf("LookupEnvOrBool[%s]: invalid value %v", key, val) + } + return defaultVal +} + func main() { flag.Parse() var srv *smtpd.Server From 0dd45cb82131b42ea91b6ccb406f9ff4af50fa4b Mon Sep 17 00:00:00 2001 From: fomojola Date: Mon, 27 Feb 2023 10:29:43 -0500 Subject: [PATCH 2/6] Update main.go Changed the denyTo environment variable. --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index f337f9b..9e9fd30 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,7 @@ var ( ips = flag.String("i", LookupEnvOrString("ALLOWED_IPS", ""), "Allowed client IPs (comma-separated)") user = flag.String("u", LookupEnvOrString("AUTH_USERNAME", ""), "Authentication username") allowFrom = flag.String("l", LookupEnvOrString("ALLOWED_SENDERS_REGEX", ""), "Allowed sender emails regular expression") - denyTo = flag.String("d", LookupEnvOrString("DENIED_SENDERS_REGEX", ""), "Denied recipient emails regular expression") + denyTo = flag.String("d", LookupEnvOrString("DENIED_RECIPIENTS_REGEX", ""), "Denied recipient emails regular expression") ) var ipMap map[string]bool From e24b9e5f93416eaafe6d81a3a0ce2e56e0566fa8 Mon Sep 17 00:00:00 2001 From: Femi Omojola Date: Tue, 16 May 2023 10:04:33 -0400 Subject: [PATCH 3/6] Switching the user to 1001 and exposing port 587 --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f0b2d58..70c82cf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,5 +16,6 @@ RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /bin/aws-smtp-relay FROM scratch COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=build /bin/aws-smtp-relay /bin/ -USER 65534 +USER 1001 +EXPOSE 587 ENTRYPOINT ["aws-smtp-relay"] From 2e6e7804f3b510f53bcbeddd757623c24f93ee5a Mon Sep 17 00:00:00 2001 From: Femi Omojola Date: Tue, 16 May 2023 11:46:38 -0400 Subject: [PATCH 4/6] Removed the expose --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 70c82cf..682bac5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,8 +14,7 @@ COPY . . RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /bin/aws-smtp-relay FROM scratch -COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=build /bin/aws-smtp-relay /bin/ +COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ USER 1001 -EXPOSE 587 ENTRYPOINT ["aws-smtp-relay"] From f7b128deae1df2b5f667145324ebaaff68163b1a Mon Sep 17 00:00:00 2001 From: Femi Omojola Date: Fri, 19 May 2023 23:31:44 -0400 Subject: [PATCH 5/6] minor bug fix --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 9e9fd30..1980c07 100644 --- a/main.go +++ b/main.go @@ -23,7 +23,7 @@ var ( host = flag.String("h", LookupEnvOrString("HOSTNAME", ""), "Server hostname") certFile = flag.String("c", LookupEnvOrString("CERT_FILE", ""), "TLS cert file") keyFile = flag.String("k", LookupEnvOrString("KEY_FILE", ""), "TLS key file") - startTLS = flag.Bool("s", LookupEnvOrBool("REQUIRE_STARTTLS", false), "Require TLS via STARTTLS extension") + startTLS = flag.Bool("s", LookupEnvOrBool("REQUIRE_STARTTLS", false), "Require TLS via STARTTLS extension (TCP PASSTHROUGH)") onlyTLS = flag.Bool("t", LookupEnvOrBool("REQUIRE_TLS", false), "Listen for incoming TLS connections only") relayAPI = flag.String("r", LookupEnvOrString("RELAY_API", "ses"), "Relay API to use (ses|pinpoint)") setName = flag.String("e", LookupEnvOrString("SES_CONFIGURATION_SET_NAME", ""), "Amazon SES Configuration Set Name") From 3d9aa16842bac4ab3efaa1b0b2e2cf67900f07a9 Mon Sep 17 00:00:00 2001 From: Femi Omojola Date: Sat, 20 May 2023 00:09:22 -0400 Subject: [PATCH 6/6] Minor rev --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 1980c07..fce1b41 100644 --- a/main.go +++ b/main.go @@ -24,7 +24,7 @@ var ( certFile = flag.String("c", LookupEnvOrString("CERT_FILE", ""), "TLS cert file") keyFile = flag.String("k", LookupEnvOrString("KEY_FILE", ""), "TLS key file") startTLS = flag.Bool("s", LookupEnvOrBool("REQUIRE_STARTTLS", false), "Require TLS via STARTTLS extension (TCP PASSTHROUGH)") - onlyTLS = flag.Bool("t", LookupEnvOrBool("REQUIRE_TLS", false), "Listen for incoming TLS connections only") + onlyTLS = flag.Bool("t", LookupEnvOrBool("REQUIRE_TLS", false), "Listen for incoming TLS connections only (false by default)") relayAPI = flag.String("r", LookupEnvOrString("RELAY_API", "ses"), "Relay API to use (ses|pinpoint)") setName = flag.String("e", LookupEnvOrString("SES_CONFIGURATION_SET_NAME", ""), "Amazon SES Configuration Set Name") ips = flag.String("i", LookupEnvOrString("ALLOWED_IPS", ""), "Allowed client IPs (comma-separated)")