maddy icon indicating copy to clipboard operation
maddy copied to clipboard

Support HAProxy's PROXY protocol for SMTP and IMAP

Open foxcpp opened this issue 4 years ago • 6 comments

Use case

Putting maddy behind a reverse proxy/load balancer/TLS terminator while still providing necessary information for any policy validation.

Implementation

See #296 for relevant discussion.

Exact configuration syntax and semantics is up for discussion.

Task list

  • [x] https://github.com/emersion/go-smtp/issues/147
  • [x] https://github.com/emersion/go-smtp/pull/148
  • [ ] Implement server support in endpoint/smtp
  • [ ] Implement server support in endpoint/imap
  • [ ] Implement client support in target.smtp (note that it would prevent pooling from working)

foxcpp avatar Jul 08 '21 14:07 foxcpp

Use-cases to evaluate:

maddy behind a TLS terminator for all endpoints

TLS terminator needs to be protocol aware for server-server SMTP: It needs to proxy SMTP capabilities and inject STARTTLS support, implement it and pass through all necessary metadata (EHLO hostname). maddy needs to be aware of TLS being used for security policy evaluation.

For client-server SMTP and IMAP any special support in TLS terminator is not needed as long as implicit TLS is used which is recommended by IETF over STARTTLS anyway.

In addition, it might be useful to support TLS between proxy and maddy. We can probably limit this to implicit TLS to keep things simple.

TCP load balancer with TLS handled by maddy

Simplest configuration to be supported.

foxcpp avatar Jul 08 '21 15:07 foxcpp

smtp tcp://127.0.0.1:2525 {
  proxy_protocol {
    assume_tls # should be turned on by default?
  }

  # if TLS is configured - it is for TLS between proxy and maddy. Not considered in policy evaluation.
  #tls ...

  ...
}

submission tcp://127.0.0.1:565 {
  proxy_protocol
  # insecure_auth assumed if proxy_protocol is used
}

imap tcp://127.0.0.1:1447 {
  proxy_protocol
  # insecure_auth assumed if proxy_protocol is used 
}

foxcpp avatar Jul 08 '21 15:07 foxcpp

Blocked by https://github.com/emersion/go-smtp/issues/147

foxcpp avatar Jul 16 '21 15:07 foxcpp

This block seems to be resolved in https://github.com/emersion/go-smtp/pull/148

infogulch avatar Jul 15 '22 01:07 infogulch

It looks like Caddy 2 currently supports the PROXY protocol via the caddy-l4 app (see linked discussion). So Caddy is in good company with other proxies that will support this mail reverse-proxy configuration.

From OP:

Putting maddy behind a reverse proxy/load balancer/TLS terminator while still providing necessary information for any policy validation.

From README.md:

In addition to that it implements auxiliary protocols that are mandatory to keep email reasonably secure (DKIM, SPF, DMARC, DANE, MTA-STS).

Will a plain PROXY-based reverse proxy still allow maddy to serve all of these these auxiliary protocols?

  • [ ] DKIM adds a signature to sent emails, and requires setting the signature public key in DNS.
  • [x] SPF publishes which IP addresses are authorized to send email for a particular domain
  • [x] DMARC is a combined validation policy published in DNS TXT records that tells recipient infra how to validate DKIM/SPF for email received from a domain
  • [x] DANE publishes DNS records that control which CAs are allowed to sign SMTP over TLS certificates, and its presence means TLS is required
  • [ ] MTA-STS is the complement to DANE, in that it publishes an https document (presumably authenticated by some public CA) that contains a policy indicating which DNS entries should be considered

Of these, only MTA-STS seems like it would need to be handled directly by the upstream proxy/Caddy. The rest come down to DNS configuration. Maybe there's an opportunity for a Caddy app that autoconfigures the necessary DNS (and either setting up DKIM manually, or pushing it out to be handled by caddy directly, see also dkim-milter, maddy/internal/modify/dkim/keys.go, and "/dkim.go).

See also maddy's initial configuration docs.

infogulch avatar Jul 15 '22 22:07 infogulch