Use configuration file
This commit is contained in:
parent
13ec8c2272
commit
3e25a724d4
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,3 +1,3 @@
|
|||
*.log
|
||||
mailing
|
||||
maildir/
|
||||
cmd/mailing/mailing
|
||||
tmp/
|
||||
|
|
59
cmd/mailing/config.go
Normal file
59
cmd/mailing/config.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
"github.com/pelletier/go-toml"
|
||||
)
|
||||
|
||||
// Config holds the program configuration
|
||||
type Config struct {
|
||||
FQDN string
|
||||
SMTP string
|
||||
Cert string
|
||||
Key string
|
||||
Maildir string
|
||||
Trace string
|
||||
Blocklists Blocklists
|
||||
}
|
||||
|
||||
// Blocklists holds the configuration of blocklists
|
||||
type Blocklists struct {
|
||||
DNS struct {
|
||||
IP []string
|
||||
Domain []string
|
||||
}
|
||||
}
|
||||
|
||||
func defaultConfig() Config {
|
||||
// In the future this will set values that are not in
|
||||
// the default configuration file.
|
||||
return Config{}
|
||||
}
|
||||
|
||||
func readConfig(filename string) Config {
|
||||
config := defaultConfig()
|
||||
|
||||
// Read in TOML config
|
||||
// nolint: gosec // config file can be anywhere
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
decoder := toml.NewDecoder(file)
|
||||
err = decoder.Decode(&config)
|
||||
if err != nil {
|
||||
log.Fatalf("cannot read %s: %s", filename, err)
|
||||
}
|
||||
// Override with environment variables
|
||||
err = envconfig.Process("mailing", &config)
|
||||
if err != nil {
|
||||
log.Fatalf("cannot override config: %s", err)
|
||||
}
|
||||
js, _ := json.MarshalIndent(config, "", " ")
|
||||
log.Println("config:", string(js))
|
||||
return config
|
||||
}
|
33
cmd/mailing/main.go
Normal file
33
cmd/mailing/main.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"gitlab.com/alienscience/mailing/smtp"
|
||||
)
|
||||
|
||||
var (
|
||||
configFile = flag.String("config", "mailing.toml", "configuration file")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
config := readConfig(*configFile)
|
||||
handler, err := newSMTPHandler(config.Blocklists, config.Maildir)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
server, err := smtp.NewServer(
|
||||
smtp.WithFqdn(config.FQDN),
|
||||
smtp.WithHandler(handler),
|
||||
smtp.WithAddress(config.SMTP),
|
||||
smtp.WithTLS(config.Cert, config.Key),
|
||||
smtp.WithTracer(tracer(config.Trace)),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("%s SMTP server starting on %s", config.FQDN, config.SMTP)
|
||||
server.ListenAndServe()
|
||||
}
|
|
@ -15,13 +15,14 @@ type smtpHandler struct {
|
|||
mailstore *store.Mailstore
|
||||
}
|
||||
|
||||
func newSMTPHandler(blocklists []string, maildir string) (*smtpHandler, error) {
|
||||
func newSMTPHandler(blocklists Blocklists, maildir string) (*smtpHandler, error) {
|
||||
mailstore, err := store.NewMailstore(maildir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ipBlocklists := blocklists.DNS.IP
|
||||
return &smtpHandler{
|
||||
mxDNS: mxdns.NewMxDNS(blocklists...),
|
||||
mxDNS: mxdns.NewMxDNS(ipBlocklists...),
|
||||
mailstore: mailstore,
|
||||
}, nil
|
||||
}
|
36
configs/mailing.toml
Normal file
36
configs/mailing.toml
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
# All settings at the top level can be overridden by an environment variables e.g
|
||||
# MAILING_FQDN="mail.example.org"
|
||||
|
||||
# Fully qualified domain name of the mail server
|
||||
fqdn ="localhost"
|
||||
|
||||
# SMTP address to listen on. Use ":25" to listen on all interfaces.
|
||||
smtp = "127.0.0.1:8025"
|
||||
|
||||
# TLS Certificate file
|
||||
cert = "test/certs/cert.pem"
|
||||
|
||||
# TLS Certificate key
|
||||
key = "test/certs/key.pem"
|
||||
|
||||
# Directory where mail will be stored
|
||||
maildir = "tmp/maildir"
|
||||
|
||||
# Directory where SMTP trace files will be stored
|
||||
# Comment this out to turn off tracing
|
||||
trace = "tmp/trace"
|
||||
|
||||
[blocklists.dns]
|
||||
# DNS blocklists that are queried by IP address
|
||||
ip = [
|
||||
"zen.spamhaus.org",
|
||||
"dnsbl-1.uceprotect.net",
|
||||
"b.barracuda.central.org",
|
||||
"cbl.abuseat.org",
|
||||
"spam.dnsbl.sorbs.net"
|
||||
]
|
||||
# DNS blocklists that are queried by domain
|
||||
domain = [
|
||||
"dbl.spamhaus.org"
|
||||
]
|
2
go.mod
2
go.mod
|
@ -6,7 +6,9 @@ require (
|
|||
github.com/etcd-io/bbolt v1.3.3 // indirect
|
||||
github.com/google/go-cmp v0.4.0
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/namsral/flag v1.7.4-pre
|
||||
github.com/pelletier/go-toml v1.7.0
|
||||
gitlab.com/alienscience/parser v0.0.0-20200430105728-00f56c127330
|
||||
go.etcd.io/bbolt v1.3.3
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||
|
|
7
go.sum
7
go.sum
|
@ -1,11 +1,17 @@
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
|
||||
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
|
||||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
github.com/namsral/flag v1.7.4-pre h1:b2ScHhoCUkbsq0d2C15Mv+VU8bl8hAXV8arnWiOHNZs=
|
||||
github.com/namsral/flag v1.7.4-pre/go.mod h1:OXldTctbM6SWH1K899kPZcf65KxJiD7MsceFUpB5yDo=
|
||||
github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
gitlab.com/alienscience/parser v0.0.0-20200307061714-ec2be86e273c h1:K+Fg60Yl9163ymLEtmyed4detme82ypT4/3Yro1x/SM=
|
||||
gitlab.com/alienscience/parser v0.0.0-20200307061714-ec2be86e273c/go.mod h1:M8FwZu4WH1chcF1Ku5d8P7pvLSjY/a+j9pVUjp4mfdM=
|
||||
gitlab.com/alienscience/parser v0.0.0-20200428102854-a44c299feeeb h1:RhMX3jR6GrLItVi9e92Pc7KnIEcEdOxeZasqxBQ86XM=
|
||||
|
@ -21,5 +27,6 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
|||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
41
main.go
41
main.go
|
@ -1,41 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/namsral/flag"
|
||||
"gitlab.com/alienscience/mailing/smtp"
|
||||
)
|
||||
|
||||
const defaultBlocklists = "zen.spamhaus.org,dnsbl-1.uceprotect.net,b.barracudacentral.org"
|
||||
|
||||
var (
|
||||
fqdn = flag.String("fqdn", "localhost", "fully qualified domain name")
|
||||
smtpAddress = flag.String("smtp", ":8025", "smtp listen address")
|
||||
certFile = flag.String("cert", "test-certs/cert.pem", "certificate file")
|
||||
keyFile = flag.String("key", "test-certs/key.pem", "certificate key file")
|
||||
blocklists = flag.String("blocklists", defaultBlocklists, "SMTP blocklists")
|
||||
maildir = flag.String("maildir", "maildir", "write mail messages to this directory")
|
||||
traceDir = flag.String("tracedir", ".", "write trace files to this directory")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
handler, err := newSMTPHandler(strings.Split(*blocklists, ","), *maildir)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
server, err := smtp.NewServer(
|
||||
smtp.WithFqdn(*fqdn),
|
||||
smtp.WithHandler(handler),
|
||||
smtp.WithAddress(*smtpAddress),
|
||||
smtp.WithTLS(*certFile, *keyFile),
|
||||
smtp.WithTracer(tracer(*traceDir)),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("%s SMTP server starting on %s", *fqdn, *smtpAddress)
|
||||
server.ListenAndServe()
|
||||
}
|
3
scripts/run.sh
Executable file
3
scripts/run.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
cmd/mailing/mailing -config configs/mailing.toml
|
Loading…
Reference in a new issue