-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.go
More file actions
114 lines (102 loc) · 3.85 KB
/
Copy pathmain.go
File metadata and controls
114 lines (102 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"context"
"crypto/tls"
"flag"
"log/slog"
"os"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/cloudwatch"
"github.com/solita/inbound/core"
"github.com/solita/inbound/metrics"
"github.com/solita/inbound/sinks"
)
func main() {
localDir := flag.String("local-dir", "", "Local directory to store mail to")
s3Bucket := flag.String("s3-bucket", "", "S3 bucket to store mail to")
s3Prefix := flag.String("s3-prefix", "", "S3 prefix inside the bucket")
s3Endpoint := flag.String("s3-endpoint", "", "S3 base endpoint URL (for non-AWS object storage)")
listenAddr := flag.String("listen", "localhost:1025", "Address to listen for incoming mail")
domain := flag.String("domain", "localhost", "Domain to identify this server in SMTP greetings")
maxSizeMb := flag.Int("max-size", 100, "Maximum size of an incoming message in megabytes")
tlsCert := flag.String("tls-cert", "", "Path to TLS certificate file")
tlsKey := flag.String("tls-key", "", "Path to TLS private key file")
tlsFromEnv := flag.Bool("tls-from-env", false, "Load TLS certificate from INBOUND_TLS_CERT and private key from INBOUND_TLS_KEY environment variables")
cloudwatchMetrics := flag.Bool("cloudwatch-metrics", false, "Enable CloudWatch metrics")
metricNamespace := flag.String("metric-namespace", "InboundMail", "CloudWatch metrics namespace")
flag.Parse()
enabledSinks := []core.Sink{&sinks.LoggingSink{}}
if *localDir != "" {
slog.Info("Storing mail to local directory", "directory", *localDir)
localSink, err := sinks.NewLocal(*localDir)
if err != nil {
slog.Error("Failed to create local sink", "error", err)
return
}
enabledSinks = append(enabledSinks, localSink)
}
if *s3Bucket != "" {
slog.Info("Storing mail to S3", "bucket", *s3Bucket, "prefix", *s3Prefix, "endpoint", *s3Endpoint)
s3Sink, err := sinks.NewS3(*s3Bucket, *s3Prefix, *s3Endpoint)
if err != nil {
slog.Error("Failed to create S3 sink", "error", err)
return
}
enabledSinks = append(enabledSinks, s3Sink)
}
var metricCollector metrics.Collector
if *cloudwatchMetrics {
slog.Info("Enabling CloudWatch metrics")
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
slog.Error("Failed to load AWS config for CloudWatch", "error", err)
return
}
cwClient := cloudwatch.NewFromConfig(cfg)
metricCollector = metrics.NewCloudWatchCollector(cwClient, *metricNamespace, nil)
}
logError := func(err error) {
slog.Error("failed to receive mail", "error", err)
if metricCollector != nil {
metricCollector.ReceiveError()
}
}
slog.Info("Setting up mail server")
server := core.NewServer(enabledSinks, logError, metricCollector)
server.Addr = *listenAddr
server.Domain = *domain
server.MaxMessageBytes = int64(*maxSizeMb) * 1024 * 1024
if *tlsCert != "" {
slog.Info("STARTTLS support enabled", "certFile", *tlsCert, "keyFile", *tlsKey)
cert, err := tls.LoadX509KeyPair(*tlsCert, *tlsKey)
if err != nil {
slog.Error("Failed to load TLS certificate and key", "error", err)
return
}
server.TLSConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS12,
}
} else if *tlsFromEnv {
slog.Info("STARTTLS support enabled, using environment variables for key material")
certPEMBlock := []byte(os.Getenv("INBOUND_TLS_CERT"))
keyPEMBlock := []byte(os.Getenv("INBOUND_TLS_KEY"))
cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
if err != nil {
slog.Error("Failed to load TLS certificate and key", "error", err)
return
}
server.TLSConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS12,
}
} else {
slog.Warn("Certificate not present, STARTTLS will fail!")
}
slog.Info("Starting mail server", "address", *listenAddr)
err := server.ListenAndServe()
if err != nil {
slog.Error("Failed to start server", "error", err)
return
}
}