Repository: matrix-org/synapse

Issue:
TLS Enabled by default, contrary to docs.
### Description
When I launch the docker image per the readme instructions, I get an error about Synapse not being able to find TLS keys.  The readme for docker deployment and the readme for TLS setup both specifically say that TLS is disabled by default and I have to take steps to enable TLS.

**Recommended remediation**: Make TLS disabled by default in the docker images **OR** update the docs to indicate that TLS is enabled by default and provide information in the setup docs about how to do this.

### Steps to reproduce
```
docker container run --rm -it -e SYNAPSE_SERVER_NAME=synapse.localhost -e SYNAPSE_REPORT_STATS=no matrixdotorg/synapse@sha256:86aaa7dc4546769f909137f9504c640c6955fdf7152035a5357525032c26e3d8
```
<details><summary>Log Output</summary>

```
2020-02-14 04:11:01,497 - synapse.config.tls - 496 - INFO -  - Loading TLS key from /data/synapse.localhost.tls.key
2020-02-14 04:11:01,500 - twisted - 192 - ERROR -  - Traceback (most recent call last):
2020-02-14 04:11:01,500 - twisted - 192 - ERROR -  -   File "/usr/local/lib/python3.7/site-packages/synapse/config/_base.py", line 149, in check_file
2020-02-14 04:11:01,501 - twisted - 192 - ERROR -  -     os.stat(file_path)
2020-02-14 04:11:01,501 - twisted - 192 - ERROR -  - FileNotFoundError: [Errno 2] No such file or directory: '/data/synapse.localhost.tls.key'
2020-02-14 04:11:01,501 - twisted - 192 - ERROR -  -
2020-02-14 04:11:01,502 - twisted - 192 - ERROR -  - During handling of the above exception, another exception occurred:
2020-02-14 04:11:01,502 - twisted - 192 - ERROR -  -
2020-02-14 04:11:01,502 - twisted - 192 - ERROR -  - Traceback (most recent call last):
2020-02-14 04:11:01,502 - twisted - 192 - ERROR -  -   File "/usr/local/lib/python3.7/site-packages/synapse/app/_base.py", line 269, in start
2020-02-14 04:11:01,502 - twisted - 192 - ERROR -  -     refresh_certificate(hs)
2020-02-14 04:11:01,502 - twisted - 192 - ERROR -  -   File "/usr/local/lib/python3.7/site-packages/synapse/app/_base.py", line 212, in refresh_certificate
2020-02-14 04:11:01,502 - twisted - 192 - ERROR -  -     hs.config.read_certificate_from_disk(require_cert_and_key=True)
2020-02-14 04:11:01,502 - twisted - 192 - ERROR -  -   File "/usr/local/lib/python3.7/site-packages/synapse/config/tls.py", line 224, in read_certificate_from_disk
2020-02-14 04:11:01,503 - twisted - 192 - ERROR -  -     self.tls_private_key = self.read_tls_private_key()
2020-02-14 04:11:01,503 - twisted - 192 - ERROR -  -   File "/usr/local/lib/python3.7/site-packages/synapse/config/tls.py", line 497, in read_tls_private_key
2020-02-14 04:11:01,503 - twisted - 192 - ERROR -  -     private_key_pem = self.read_file(private_key_path, "tls_private_key_path")
2020-02-14 04:11:01,503 - twisted - 192 - ERROR -  -   File "/usr/local/lib/python3.7/site-packages/synapse/config/_base.py", line 171, in read_file
2020-02-14 04:11:01,503 - twisted - 192 - ERROR -  -     cls.check_file(file_path, config_name)
2020-02-14 04:11:01,503 - twisted - 192 - ERROR -  -   File "/usr/local/lib/python3.7/site-packages/synapse/config/_base.py", line 153, in check_file
2020-02-14 04:11:01,503 - twisted - 192 - ERROR -  -     % (file_path, config_name, e.strerror)
2020-02-14 04:11:01,504 - twisted - 192 - ERROR -  - synapse.config._base.ConfigError: Error accessing file '/data/synapse.localhost.tls.key' (config for tls_private_key_path): No such file or directory
2020-02-14 04:11:01,521 - twisted - 192 - CRITICAL -  - Unhandled error in Deferred:
2020-02-14 04:11:01,522 - twisted - 192 - CRITICAL -  -
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/synapse/config/_base.py", line 149, in check_file
    os.stat(file_path)
FileNotFoundError: [Errno 2] No such file or directory: '/data/synapse.localhost.tls.key'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/synapse/app/_base.py", line 269, in start
    refresh_certificate(hs)
  File "/usr/local/lib/python3.7/site-packages/synapse/app/_base.py", line 212, in refresh_certificate
    hs.config.read_certificate_from_disk(require_cert_and_key=True)
  File "/usr/local/lib/python3.7/site-packages/synapse/config/tls.py", line 224, in read_certificate_from_disk
    self.tls_private_key = self.read_tls_private_key()
  File "/usr/local/lib/python3.7/site-packages/synapse/config/tls.py", line 497, in read_tls_private_key
    private_key_pem = self.read_file(private_key_path, "tls_private_key_path")
  File "/usr/local/lib/python3.7/site-packages/synapse/config/_base.py", line 171, in read_file
    cls.check_file(file_path, config_name)
  File "/usr/local/lib/python3.7/site-packages/synapse/config/_base.py", line 153, in check_file
    % (file_path, config_name, e.strerror)
synapse.config._base.ConfigError: Error accessing file '/data/synapse.localhost.tls.key' (config for tls_private_key_path): No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/usr/local/lib/python3.7/site-packages/synapse/app/homeserver.py", line 404, in start
    _base.start(hs, config.listeners)
  File "/usr/local/lib/python3.7/site-packages/synapse/app/_base.py", line 287, in start
    sys.exit(1)
SystemExit: 1
2020-02-14 04:11:01,528 - synapse.handlers.user_directory - 152 - INFO - user_directory.notify_new_event-0 - Handling 0 state deltas
2020-02-14 04:11:01,537 - twisted - 192 - INFO -  - Main loop terminated.
```
</details>

Note that the instructions at https://github.com/matrix-org/synapse/tree/master/docker#tls-support say:
> The default configuration exposes a single HTTP port: http://localhost:8008. It is suitable for local testing, but for any practical use, you will either need to use a reverse proxy, or configure Synapse to expose an HTTPS port.

### Version information
- **Version**: v1.9.1

- **Install method**:
Docker

- **Platform**:
Happens on both Windows and Linux Docker hosts.


Discussion:
You missed out an important part of the output:

```
Generating config file '/compiled/homeserver.yaml' on-the-fly from environment variables.
Note that this mode is deprecated. You can migrate to a static config
file by running with 'migrate_config'. See the README for more details.
```

If you follow the documentation about generating a configuration file using in the `generate` option, you'll get a config file with TLS disabled.
Hmm, is there no way to disable TLS without that?  Two step docker deployments don't jive well with docker orchestration environments.  Running `generate` as a one-time setup step prior to running the actual service is a bit of a pain, especially when you want the ability to spin the service back up in a catastrophic failure scenario.
if you're using an orchestration environment, you'll want to generate a configuration file, template it according to your needs, and deploy that. Don't `generate` a new one each time.

Resolving patch:
diff --git a/docker/start.py b/docker/start.py
--- a/docker/start.py
+++ b/docker/start.py
@@ -188,11 +188,6 @@ def main(args, environ):
     else:
         ownership = "{}:{}".format(desired_uid, desired_gid)
 
-    log(
-        "Container running as UserID %s:%s, ENV (or defaults) requests %s:%s"
-        % (os.getuid(), os.getgid(), desired_uid, desired_gid)
-    )
-
     if ownership is None:
         log("Will not perform chmod/su-exec as UserID already matches request")
 
@@ -213,38 +208,30 @@ def main(args, environ):
     if mode is not None:
         error("Unknown execution mode '%s'" % (mode,))
 
-    if "SYNAPSE_SERVER_NAME" in environ:
-        # backwards-compatibility generate-a-config-on-the-fly mode
-        if "SYNAPSE_CONFIG_PATH" in environ:
+    config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data")
+    config_path = environ.get("SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml")
+
+    if not os.path.exists(config_path):
+        if "SYNAPSE_SERVER_NAME" in environ:
             error(
-                "SYNAPSE_SERVER_NAME can only be combined with SYNAPSE_CONFIG_PATH "
-                "in `generate` or `migrate_config` mode. To start synapse using a "
-                "config file, unset the SYNAPSE_SERVER_NAME environment variable."
+                """\
+Config file '%s' does not exist.
+
+The synapse docker image no longer supports generating a config file on-the-fly
+based on environment variables. You can migrate to a static config file by
+running with 'migrate_config'. See the README for more details.
+"""
+                % (config_path,)
             )
 
-        config_path = "/compiled/homeserver.yaml"
-        log(
-            "Generating config file '%s' on-the-fly from environment variables.\n"
-            "Note that this mode is deprecated. You can migrate to a static config\n"
-            "file by running with 'migrate_config'. See the README for more details."
+        error(
+            "Config file '%s' does not exist. You should either create a new "
+            "config file by running with the `generate` argument (and then edit "
+            "the resulting file before restarting) or specify the path to an "
+            "existing config file with the SYNAPSE_CONFIG_PATH variable."
             % (config_path,)
         )
 
-        generate_config_from_template("/compiled", config_path, environ, ownership)
-    else:
-        config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data")
-        config_path = environ.get(
-            "SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml"
-        )
-        if not os.path.exists(config_path):
-            error(
-                "Config file '%s' does not exist. You should either create a new "
-                "config file by running with the `generate` argument (and then edit "
-                "the resulting file before restarting) or specify the path to an "
-                "existing config file with the SYNAPSE_CONFIG_PATH variable."
-                % (config_path,)
-            )
-
     log("Starting synapse with config file " + config_path)
 
     args = ["python", "-m", synapse_worker, "--config-path", config_path]


Test patch: