mail/cmd/inbound/inbound.go
2023-09-30 16:52:35 -04:00

97 lines
2.1 KiB
Go

package main
import (
"context"
"crypto/tls"
"encoding/json"
"flag"
"os"
"os/signal"
"syscall"
"time"
"github.com/emersion/go-milter"
"github.com/emersion/go-smtp"
"go.uber.org/zap"
"golang.org/x/time/rate"
localtls "git.cycore.io/cycore/mail/pkg/tls"
"git.cycore.io/cycore/mail/server"
)
var (
listenPort int
healthPort int
)
var allowedDomains []string
func init() {
flag.IntVar(&listenPort, "smtp", 2525, "port on which to listen for incoming emails")
flag.IntVar(&healthPort, "health", 8080, "port on which to listen for health checks")
}
func main() {
var err error
var log *zap.Logger
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
if _, ok := os.LookupEnv("DEBUG"); ok {
log, err = zap.NewDevelopment()
} else {
log, err = zap.NewProduction()
}
if err != nil {
panic("failed to instantiate logger: " + err.Error())
}
if v := os.Getenv("ALLOWED_DOMAINS"); v != "" {
if err := json.Unmarshal([]byte(v), &allowedDomains); err != nil {
log.Fatal("failed to read ALLOWED_DOMAINS from environment", zap.Error(err))
}
}
if len(allowedDomains) < 1 {
log.Fatal("no allowed domains")
}
cm, err := localtls.NewCertManager(os.Getenv("CERTIFICATE_NAME"), os.Getenv("CERTIFICATE_NAMESPACE"))
if err != nil {
log.Fatal("failed to create certificate manager", zap.Error(err))
}
go func() {
if err := cm.Watch(ctx, log); err != nil {
log.Error("certificate manager exited", zap.Error(err))
cancel()
}
}()
be := &server.Backend{
AllowedDomains: allowedDomains,
Log: log,
LMTPAddress: os.Getenv("LMTP_ADDRESS"),
RootContext: ctx,
RSpam: milter.NewDefaultClient("tcp", "rspamd"),
OverallLimiter: rate.NewLimiter(rate.Limit(10), 20),
}
s := smtp.NewServer(be)
defer s.Close() //nolint:errcheck
s.Addr = ":2525"
s.Domain = "cycore.io"
s.WriteTimeout = 10 * time.Second
s.WriteTimeout = 10 * time.Second
s.MaxMessageBytes = 300 * 1024 * 1024 // 300 MiB
s.MaxRecipients = 10
s.TLSConfig = &tls.Config{
GetCertificate: cm.Get,
}
log.Fatal("server exited", zap.Error(s.ListenAndServeTLS()))
}