From ce3e2588c5b0f6bbd3ebe28cec22a71f37eaf47f Mon Sep 17 00:00:00 2001 From: Finn Stutzenstein Date: Mon, 15 Feb 2021 11:19:05 +0100 Subject: [PATCH] add optional https for caddy --- Makefile | 2 ++ README.rst | 43 ++++++++++++++++++++++++++++++++---- caddy/Caddyfile | 29 ++++++++++++------------ caddy/Dockerfile | 5 +++++ caddy/certs/.keep | 0 caddy/entrypoint | 16 ++++++++++++++ caddy/make-localhost-cert.sh | 22 ++++++++++++++++++ 7 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 caddy/certs/.keep create mode 100755 caddy/entrypoint create mode 100755 caddy/make-localhost-cert.sh diff --git a/Makefile b/Makefile index ef8fd4cdf..646c7f91d 100644 --- a/Makefile +++ b/Makefile @@ -12,3 +12,5 @@ stop-dev: get-server-shell: docker-compose -f docker/docker-compose.dev.yml run server bash +reload-proxy: + docker-compose -f docker/docker-compose.dev.yml exec -w /etc/caddy proxy caddy reload diff --git a/README.rst b/README.rst index e3f5e07fe..724413620 100644 --- a/README.rst +++ b/README.rst @@ -36,10 +36,11 @@ first and initialize all submodules:: Setup Docker images ------------------- -You need to build the Docker images for the client and server and have to setup some -configuration. +You need to build the Docker images and have to setup some configuration. First, +configure HTTPS by checking the `Using HTTPS`_ section. In this section are +reasons why HTTPS is required for large deployments. -First go to ``docker`` subdirectory:: +Go to ``docker`` subdirectory:: cd docker @@ -67,7 +68,7 @@ Finally, you can start the instance using ``docker-compose``:: docker-compose up -OpenSlides runs on https://localhost:8000/. +OpenSlides is accessible on http://localhost:8000/ (or https, if configured). Use can also use daemonized instance:: @@ -75,6 +76,40 @@ Use can also use daemonized instance:: docker-compose logs docker-compose down +Using HTTPS +----------- + +The main reason (next to obviously security ones) HTTPS is required originates +from the need of HTTP/2. OpenSlides uses streaming responses to asynchronously +send data to the client. With HTTP/1.1 one TCP-Connection per request is opened. +Browsers limit the amount of concurrent connections +(`reference`_), +so you are limited in opening tabs. HTTPS/2 just uses one connection per browser +and eliminates these restrictions. The main point to use HTTPS is that browsers +only use HTTP/2 if HTTPS is enabled. + +Setting up HTTPS +"""""""""""""""" + +Use common providers for retrieving a certificate and private key for your +deployment. Place the certificate and private key in ``caddy/certs/cert.pem`` +and ``caddy/certs/key.pem``. To use a self-signed localhost certificate, you can +execute ``caddy/make-localhost-cert.sh``. + +The certificate and key are put into the docker image into ``/certs/``, so +setting up these files needs to be done before calling ``./build.sh``. When you +update the files, you must run ``./build.sh proxy`` again. If you want to have a +more flexible setup without the files in the image, you can also mount the +folder or the certificate and key into the running containers if you wish to do +so. + +If both files are not present, OpenSlides will be configured to run with HTTP +only. When mounting the files make sure, that they are present during the +container startup. + +Caddy, the proxy used, wants the user to persist the ``/data`` directory. If you +are going to use HTTPS add a volume in your ``docker-compose.yml`` / +``docker-stack.yml`` persisting the ``/data`` directory. More settings ------------- diff --git a/caddy/Caddyfile b/caddy/Caddyfile index b00ddd0aa..68dcdf45f 100644 --- a/caddy/Caddyfile +++ b/caddy/Caddyfile @@ -1,16 +1,17 @@ -:8000 +import endpoint -reverse_proxy /system/* autoupdate:8002 { - flush_interval -1 + reverse_proxy /system/* autoupdate:8002 { + flush_interval -1 + } + + @server { + path /apps/* + path /rest/* + path /server-version.txt + } + reverse_proxy @server server:8000 + + reverse_proxy /media/* media:8000 + + reverse_proxy client:4200 } - -@server { - path /apps/* - path /rest/* - path /server-version.txt -} -reverse_proxy @server server:8000 - -reverse_proxy /media/* media:8000 - -reverse_proxy client:4200 diff --git a/caddy/Dockerfile b/caddy/Dockerfile index 94bf8cfa0..89473efff 100644 --- a/caddy/Dockerfile +++ b/caddy/Dockerfile @@ -1,3 +1,8 @@ FROM caddy:2.3.0-alpine COPY Caddyfile /etc/caddy/Caddyfile +COPY entrypoint /entrypoint +COPY certs /certs + +ENTRYPOINT ["/entrypoint"] +CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"] diff --git a/caddy/certs/.keep b/caddy/certs/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/caddy/entrypoint b/caddy/entrypoint new file mode 100755 index 000000000..eea7dd8aa --- /dev/null +++ b/caddy/entrypoint @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e + +if [[ -f "/certs/key.pem" ]] && [[ -f "/certs/cert.pem" ]]; then + cat <> /etc/caddy/endpoint +https://:8000 { + tls /certs/cert.pem /certs/key.pem +EOF + echo "Configured https" +else + echo "http://:8000 {" > /etc/caddy/endpoint + echo "Configured http" +fi + +exec "$@" diff --git a/caddy/make-localhost-cert.sh b/caddy/make-localhost-cert.sh new file mode 100755 index 000000000..cc5fc60c7 --- /dev/null +++ b/caddy/make-localhost-cert.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e +cd "$(dirname "$0")" + +if [[ -f "certs/key.pem" ]] || [[ -f "certs/cert.pem" ]]; then + echo >&2 "Error: Certificate already exists." + exit 1 +fi + +if ! type 2>&1 >/dev/null openssl ; then + echo >&2 "Error: openssl not found!" + exit 1 +fi + +echo "Creating certificates..." +echo "You will need to accept an security exception for the" +echo "generated certificate in your browser manually." +openssl req -x509 -newkey rsa:4096 -nodes -days 3650 \ + -subj "/C=DE/O=Selfsigned Test/CN=localhost" \ + -keyout certs/key.pem -out certs/cert.pem +echo "done"