smtprelay
smtprelay copied to clipboard
doc: Full Usage Guide w/ Working Examples
I just set this up for a client. This is the config we ended up going with.
- Directory Structure
- TLS Config via Let's Encrypt / Caddy
- SMTP Relay Config
Directory Structure
caddy(for automated TLS certificates via Let's Encrypt)smtprelay
/home/app/
├── .config/
│ ├── caddy/
│ │ ├── caddy.env
│ │ └── Caddyfile
│ └── smtprelay/
│ ├── allowed_users.txt
│ └── smtprelay.ini
└── .local/
└── share/
└── caddy/
└── certificates/
└── acme-v02.api.letsencrypt.org-directory/
└── smtp.example.com/
├── smtp.example.com.crt
├── smtp.example.com.json
└── smtp.example.com.key
Let's Encrypt TLS Certs via caddy
caddy run --config ~/.config/caddy/Caddyfile --envfile ~/.config/caddy/caddy.env
- Install
go,xcaddy, and (optional)servicemanvia https://webinstall.devcurl https://webi.sh/ | sh source ~/.config/envman/PATH.env webi go xcaddy serviceman source ~/.config/envman/PATH.env - Build
caddywith DNS support (no webserver required). Example w/ DNSimple:#!/bin/sh g_caddy_version='v2.7.6' CGO_ENABLED=0 xcaddy build "${g_caddy_version}" \ --with github.com/caddy-dns/lego-deprecated \ --output ~/bin/caddy-"${g_caddy_version}"-dnsimple ln -sf caddy-"${g_caddy_version}"-dnsimple ~/bin/caddy - Configure caddy via
~/.config/caddy/Caddyfile:mkdir -p ~/.config/caddy touch ~/.config/caddy/caddy.env chmod 0600 ~/.config/caddy/caddy.env# note: to keep ports 80 and 443 free, use "https://smtp.example.com:1234" # instead of just the hostname here smtp.example.com { tls { dns lego_deprecated dnsimple } } - Add DNSimple's ENVs to
~/.config/caddy/caddy.env:DNSIMPLE_OAUTH_TOKEN='dnsimple_a_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - Test the configuration
caddy run --config ~/.config/caddy/Caddyfile --envfile ~/.config/caddy/caddy.env - Start
caddyas a service withserviceman(Linux, macOS, & Windows)
(my_app_user="$(id -u -n)" sudo env PATH="${PATH}" \ serviceman add --system --cap-net-bind \ --username "${my_app_user}" --name caddy -- \ caddy run --config ~/.config/caddy/Caddyfile --envfile ~/.config/caddy/caddy.env--cap-net-bindis only necessary if using default ports 80 & 443)
smtprelay config
smtprelay --config ~/.config/smtprelay/smtprelay.ini
- Create the config file
~/.config/smtprelay/smtprelay.ini:mkdir -p ~/.config/smtprelay/ touch ~/.config/smtprelay/smtprelay.ini chmod 0600 ~/.config/smtprelay/smtprelay.ini; Hostname for this SMTP server hostname = smtp.example.com ; File which contains username and password used for ; authentication before they can send mail. allowed_users = /home/app/.config/smtprelay/allowed_users.txt ; Networks that are allowed to send mails to us ; Defaults to localhost. If set to "", then any address is allowed. ;allowed_nets = 0.0.0.0/0 ::/0 allowed_nets = 0.0.0.0/0 ; STARTTLS and TLS are also supported but need a ; SSL certificate and key. ;listen = starttls://0.0.0.0:587 starttls://[::]:587 tls://0.0.0.0:465 tls://[::]:465 listen = starttls://0.0.0.0:587 tls://0.0.0.0:465 local_cert = /home/app/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/smtp.example.com/smtp.example.com.crt local_key = /home/app/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/smtp.example.com/smtp.example.com.key ; Enforce encrypted connection on STARTTLS ports before ; accepting mails from client. local_forcetls = true ; Relay Config (ex: Mailgun) remotes = starttls://user:[email protected]:587 - Set permissions via
~/.config/smtprelay/allowed_users.txt:# go run ./smtprelay/cmd/hasher.go 'my-password' # <username> <bcrypt-hash> <email,list> my-username $2a$10$uZntKVdnFmAZiswYLTl8auUUxeH4wOnAU5C4zz3rGWvMf2iOmhcDy @account.example.com,[email protected] - Test the config
smtprelay --config ~/.config/smtprelay/smtprelay.ini - Test with Curl
my_smtprelay_host=smtp.example.com my_smtprelay_auth='my-user:my-pass' my_from="[email protected]" my_to="[email protected]" my_subject='Hello, World!' my_ts="$(date '+%F %H:%M:%S')" my_text="It's ${my_ts}. Do you know where your emails are?" my_file="$(mktemp)" printf 'From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s\r\n' \ "${my_from}" \ "${my_to}" \ "${my_subject}" \ "${my_text}" \ > "${my_file}"# requires tls on 465 curl -v --url "smtps://${my_smtprelay_host}" \ --ssl-reqd \ --user "${my_smtprelay_auth}" \ --mail-from "${my_from}" \ --mail-rcpt "${my_to}" \ --upload-file "${my_file}" - Start as a system service with
serviceman:my_app_user="$( id -u -n )" sudo env PATH="${PATH}" \ serviceman add --system --cap-net-bind \ --username "${my_app_user}" --name smtprelay -- \ smtprelay --config ~/.config/smtprelay/smtprelay.ini
This is great, thanks!
Also, if you want to test SMTP directly, swaks is a great tool for this, comes in most distro repositories I believe.
When using startls (port 587 etc), you need to add --tls:
swaks --to [email protected] --from [email protected] --port 587 --tls
When testing user authentication:
swaks --to [email protected] --from [email protected] --auth-user yourusername --auth-password yourpassword --port 587 --tls
When testing a specific IP/interface, add --server 127.0.0.1, where 127.0.0.1 is the IP.
@coolaj86 How are you shipping logs? This is the first time i've used serviceman and journalctl -xef --unit smtprelay.service is showing great output but strangely /var/log/smtprelay is an empty folder.
If it works with systemd you could just use StandardOutput/Standard error in your service file to log to file.
Depending what you mean by shipping logs but depending what you're trying to do it might be easier to hook into joirnalctl vs writing to file.
Thanks! Here's what I did if it helps other people:
sudo vi /etc/systemd/system/smtprelay.service
[Service]
StandardOutput=append:/var/log/smtprelay/service.log
StandardError=append:/var/log/smtprelay/service_error.log
touch /var/log/smtprelay/service.log
touch /var/log/smtprelay/service_error.log
sudo systemctl reload smtprelay.service
Then added /var/log/smtprelay/*.log as a folder to look for in my collector configuration and it started picking it up
Didn't find documentation how to run in container (docker) so I created a repo containing some example workflow https://github.com/schtritoff/docker-smtprelay