Use configuration file

This commit is contained in:
Alienscience 2020-05-10 14:19:45 +02:00
parent 13ec8c2272
commit 3e25a724d4
12 changed files with 145 additions and 45 deletions

4
.gitignore vendored
View file

@ -1,3 +1,3 @@
*.log
mailing
maildir/
cmd/mailing/mailing
tmp/

59
cmd/mailing/config.go Normal file
View 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
View 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()
}

View file

@ -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
View 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
View file

@ -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
View file

@ -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
View file

@ -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
View file

@ -0,0 +1,3 @@
#!/bin/sh
cmd/mailing/mailing -config configs/mailing.toml