git » chasquid » commit c6c9866

docs: Add documentation for security level checks

author Alberto Bertogli
2019-08-06 01:58:12 UTC
committer Alberto Bertogli
2019-08-06 02:05:43 UTC
parent d34847784104e75d54c4e2643cdb27d6441ff38a

docs: Add documentation for security level checks

This patch adds documentation for the security level checks, and
references it (the rendered version, for convenience) from the README
file.

.mkdocs.yml +2 -0
README.md +2 -1
docs/sec-levels.md +150 -0

diff --git a/.mkdocs.yml b/.mkdocs.yml
index a624b41..436e6ac 100644
--- a/.mkdocs.yml
+++ b/.mkdocs.yml
@@ -12,6 +12,7 @@ repo_url: https://github.com/albertito/chasquid
 markdown_extensions:
   - codehilite:
       guess_lang: false
+  - attr_list
 
 theme: readthedocs
 
@@ -26,4 +27,5 @@ nav:
     - dkim.md
     - flow.md
     - monitoring.md
+    - sec-levels.md
 
diff --git a/README.md b/README.md
index a04e7f6..e86f1df 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ It's written in [Go](https://golang.org), and distributed under the
       DKIM/DMARC.
     * International usernames ([SMTPUTF8]) and domain names ([IDNA]).
 * Secure
-    * Tracking of per-domain TLS support, prevents connection downgrading.
+    * [Tracking] of per-domain TLS support, prevents connection downgrading.
     * Multiple TLS certificates.
     * Easy integration with [Let's Encrypt].
     * [SPF] and [MTA-STS] checking.
@@ -49,6 +49,7 @@ It's written in [Go](https://golang.org), and distributed under the
 [MTA-STS]: https://tools.ietf.org/html/rfc8461
 [Debian]: https://debian.org
 [Ubuntu]: https://ubuntu.com
+[Tracking]: https://chasquid.readthedocs.io/en/latest/sec-levels/
 
 
 ## Documentation
diff --git a/docs/sec-levels.md b/docs/sec-levels.md
new file mode 100644
index 0000000..eade743
--- /dev/null
+++ b/docs/sec-levels.md
@@ -0,0 +1,150 @@
+
+# Security level checks
+
+chasquid tracks per-domain TLS support, and uses it to prevent connection
+downgrading.
+
+Incoming and outgoing connections are tracked independently, but the principle
+of operation is the same: once a domain shows it can establish secure
+connections, chasquid will reject lower-security connections from/to its
+servers.
+
+This is very different from other MTAs, and has some tradeoffs.
+
+
+## Outgoing connections
+
+An outgoing connection has one of 3 security levels, which are (in order):
+
+1. Plain: connection is plain-text (the server does not support TLS).
+2. TLS insecure: TLS connection established, but the certificate itself was
+   not valid.
+3. TLS secure: TLS connection established, with a valid certificate.
+
+When establishing an outgoing connection, chasquid will always attempt to
+negotiate up to the *TLS secure* level.  After the negotiation, it will
+compare which level it got, with the previously recorded value for this
+domain:
+
+* If the connection level is lower than the recorded value, then the
+  connection will be dropped, and the delivery will fail (with a transient
+  failure). The delivery will be retried as usual (using other MXs if
+  available, and repeat after some delay).
+* If the connection level is the same as the recorded value, then the
+  connection will proceed.
+* If the connection level is higher, chasquid will record this new value, and
+  proceed.
+
+If there is no previously recorded value for this domain, a *plain* level is
+assumed.
+
+### Certificate validation
+
+A certificate is considered valid if it satisfies all of the following
+conditions:
+
+1. The certificate is properly signed by one of the system roots.
+2. The name used to contact the server (e.g. the name from the MX record) is
+   declared in the certificate.
+
+This is the standard method used in other services such as HTTPS; however,
+there is no standard to do certificate validation on SMTP.
+
+chasquid chooses to implement validation this way, which is also consistent
+with MTA-STS and HTTPS, but it is not universally agreed upon. It's also why
+the "TLS insecure" state exists, instead of the connection being rejected
+directly.
+
+
+### Tradeoffs
+
+Almost all other MTAs do TLS negotiation but accept *all* certificates, even
+self-signed or expired ones.  chasquid operates differently, as described
+above.
+
+The main advantage is that, *with domains where secure connections were
+previously established*, chasquid will detect connection downgrading (caused
+by malicious interception such as STARTTLS blocking, as well as
+misconfiguration such as incorrectly configured or expired certificates), and
+avoid communicating insecurely.
+
+The main disadvantage is that if a domain changes the configuration to a lower
+security level, chasquid will fail the delivery (returning a message to the
+sender explaining why).  Because there is no formal standard for TLS
+certificate validation, and most MTAs will deliver email in this situation,
+the domain owners might not see this as a problem and thus require [manual
+intervention](#manual-override) on the chasquid side to explicitly allow it.
+
+### MTA-STS
+
+[MTA-STS](https://tools.ietf.org/html/rfc8461) is a relatively new standard
+which defines a mechanism enabling mail service providers to declare their
+ability to receive TLS connections, amongst other things.
+
+It is supported by chasquid, out of the box, and in practice it means that for
+domains that advertise MTA-STS support, the *secure* level will be enforced
+even if the domain was previously unknown.
+
+
+## Incoming connections
+
+Incoming connections from authenticated users are always done over TLS
+(chasquid will never accept authentication over plaintext connections). This
+section applies only to incoming connections from other SMTP servers.
+
+An incoming connection from another SMTP server is first checked through
+[SPF](https://en.wikipedia.org/wiki/Sender_Policy_Framework). If the result of
+the check is negative (fail, softfail, neutral, or error), then the following
+is skipped. This prevents a malicious agent from raising the level and
+interfering with legitimate plaintext delivery.
+
+After the SPF check has passed, the connection is assigned one of the 2
+security levels, which are (in order):
+
+1. Plain: connection is plain-text (client did not do TLS negotiation).
+2. TLS client: connection is over TLS.
+
+At this point, chasquid will compare the level with the previously recorded
+value for this domain:
+
+* If the connection level is lower than the recorded value, then the
+  connection is rejected with an SMTP error.
+* If the connection level is the same as the recorded value, then the
+  connection is allowed.
+* If the connection level is higher, chasquid will record this new value, and
+  the connection is allowed.
+
+If there is no previously recorded value for this domain, a *plain* level is
+assumed.
+
+### Tradeoffs
+
+Almost all other MTAs accept server to server connections regardless of the
+security level, because there is no way for a domain to advertise that it will
+always negotiate TLS when sending email. chasquid operates differently,
+assuming that once a server negotiates TLS, it will always attempt to do so.
+
+The main advantage is that, *with domains that had previously used TLS for
+incoming connections*, chasquid will detect connection downgrading (caused by
+malicious interception such as STARTTLS blocking), and avoid communicating
+insecurely.
+
+The main disadvantage is that if a domain changes the configuration and is
+unable to negotiate TLS, chasquid will reject the connection and not receive
+incoming email from this server. This is unusual nowadays, but because other
+MTAs will accept the connection anyway, domain owners might not even notice
+there is a problem, and might require [manual intervention](#manual-override)
+on the chasquid side to explicitly allow it.
+
+
+
+## Accepting lower security levels {#manual-override}
+
+If a domain changes its configuration to a lower security level and is causing
+chasquid to fail delivery, you can use
+`chasquid-util domaininfo-remove <domain>` to make the server forget about
+that domain.
+
+Then, the next time there is a connection, there is no high security
+expectation so it will proceed just fine, regardless of the level that was
+negotiated.