Browse Source

Implement multiple listeners and improve documentation in ini file

Bernhard Froehlich 6 years ago
parent
commit
5da54ccf31
2 changed files with 65 additions and 16 deletions
  1. 36 12
      main.go
  2. 29 4
      smtp-proxy.ini

+ 36 - 12
main.go

@@ -6,6 +6,8 @@ import (
 	"fmt"
 	"log"
 	"net/smtp"
+	"strings"
+	"time"
 
 	"github.com/chrj/smtpd"
 	"github.com/vharitonsky/iniflags"
@@ -14,12 +16,11 @@ import (
 var (
 	hostName   = flag.String("hostname", "localhost.localdomain", "Server hostname")
 	welcomeMsg = flag.String("welcome_msg", "", "Welcome message for SMTP session")
-	localHost  = flag.String("local_host", "localhost", "Address to listen for incoming SMTP")
-	localPort  = flag.Int("local_port", 25, "Port to listen")
-	localForceTLS = flag.Bool("local_forcetls", false, "Force STARTTLS (needs local_cert and local_key)")
+	listen     = flag.String("listen", "127.0.0.1:25 [::1]:25", "Address and port to listen for incoming SMTP")
 	localCert  = flag.String("local_cert", "", "SSL certificate for STARTTLS/TLS")
 	localKey   = flag.String("local_key", "", "SSL private key for STARTTLS/TLS")
-	remoteHost = flag.String("remote_host", "smtp.gmail.com", "Outgoing SMTP host")
+	localForceTLS = flag.Bool("local_forcetls", false, "Force STARTTLS (needs local_cert and local_key)")
+	remoteHost = flag.String("remote_host", "smtp.gmail.com", "Outgoing SMTP server")
 	remotePort = flag.Int("remote_port", 587, "Outgoing SMTP port")
 	remoteUser = flag.String("remote_user", "", "Username for authentication on outgoing SMTP server")
 	remotePass = flag.String("remote_pass", "", "Password for authentication on outgoing SMTP server")
@@ -47,16 +48,39 @@ func main() {
 		ForceTLS:	*localForceTLS,
 	}
 
-	if *localCert != "" && *localKey != "" {
-		cert, err := tls.LoadX509KeyPair(*localCert, *localKey)
-		if err != nil {
-			log.Fatal(err)
-		}
+	listeners := strings.Split(*listen, " ")
+
+	for i := range(listeners) {
+		listener := listeners[i]
+
+		if strings.Index(listeners[i], "://") == -1 {
+			;
+		} else if strings.HasPrefix(listeners[i], "tls://") || strings.HasPrefix(listeners[i], "starttls://") {
 
-		server.TLSConfig = &tls.Config {
-			Certificates: [] tls.Certificate{cert},
+			listener = strings.TrimPrefix(listener, "tls://")
+			listener = strings.TrimPrefix(listener, "starttls://")
+
+			if *localCert == "" || *localKey == "" {
+				log.Fatal("TLS certificate/key not defined in config")
+			}
+
+			cert, err := tls.LoadX509KeyPair(*localCert, *localKey)
+			if err != nil {
+				log.Fatal(err)
+			}
+
+			server.TLSConfig = &tls.Config {
+				Certificates: [] tls.Certificate{cert},
+			}
+		} else {
+			log.Fatal("Unknown protocol in listener ", listener)
 		}
+
+		log.Printf("Listen on %s ...\n", listener)
+		go server.ListenAndServe(listener)
 	}
 
-	server.ListenAndServe(fmt.Sprintf("%s:%d", *localHost, *localPort))
+	for true {
+		time.Sleep(time.Minute)
+	}
 }

+ 29 - 4
smtp-proxy.ini

@@ -1,15 +1,40 @@
 ; smtp-proxy configuration
 
+; Hostname for this SMTP server
 ;hostname = "localhost.localdomain"
+
+; Welcome message for clients
 ;welcome_msg = "<hostname> ESMTP ready."
 
-;local_host = localhost
-;local_port = 25
-;local_cert =
-;local_key  =
+; Listen on the following addresses for incoming
+; unencrypted connections.
+;listen = 127.0.0.1:25 [::1]:25
+
+; STARTTLS and TLS are also supported but need a
+; SSL certificate and key.
+;listen = tls://127.0.0.1:465 tls://[::1]:465
+;listen = starttls://127.0.0.1:587 starttls://[::1]:587
+;local_cert = smtpd.pem
+;local_key  = smtpd.key
+
+; Enforce encrypted connection on STARTTLS ports before
+; accepting mails from client.
 ;local_forcetls = false
 
+; Relay all mails to this SMTP server
+
+; GMail
 ;remote_host = smtp.gmail.com
 ;remote_port = 587
+
+; Mailgun.org
+;remote_host = smtp.mailgun.org
+;remote_port = 587
+
+; Mailjet.com
+;remote_host = in-v3.mailjet.com
+;remote_port = 465
+
+; Authentication credentials on outgoing SMTP server
 ;remote_user =
 ;remote_pass =