Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: Full Usage Guide w/ Working Examples #149

Open
coolaj86 opened this issue Jan 27, 2024 · 0 comments
Open

doc: Full Usage Guide w/ Working Examples #149

coolaj86 opened this issue Jan 27, 2024 · 0 comments

Comments

@coolaj86
Copy link

coolaj86 commented Jan 27, 2024

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
  1. Install go, xcaddy, and (optional) serviceman via https://webinstall.dev
    curl https://webi.sh/ | sh
    source ~/.config/envman/PATH.env
    
    webi go xcaddy serviceman
    source ~/.config/envman/PATH.env
  2. Build caddy with 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
  3. 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
            }
    }
    
  4. Add DNSimple's ENVs to ~/.config/caddy/caddy.env:
    DNSIMPLE_OAUTH_TOKEN='dnsimple_a_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  5. Test the configuration
    caddy run --config ~/.config/caddy/Caddyfile --envfile ~/.config/caddy/caddy.env
  6. Start caddy as a service with serviceman (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-bind is only necessary if using default ports 80 & 443)

smtprelay config

smtprelay --config ~/.config/smtprelay/smtprelay.ini
  1. 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:pass@smtp.mailgun.org:587
  2. 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,support@example.com
    
  3. Test the config
    smtprelay --config ~/.config/smtprelay/smtprelay.ini
  4. Test with Curl
    my_smtprelay_host=smtp.example.com
    my_smtprelay_auth='my-user:my-pass'
    
    my_from="rob-the-robot@example.com"
    my_to="alice@example.net"
    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}"
  5. 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant