1
0
Fork 0
mirror of https://github.com/overleaf/toolkit.git synced 2025-04-19 15:28:06 +02:00

Add a TLS proxy option to the Toolkit

This commit is contained in:
Christopher Hoskin 2021-04-08 11:56:10 +01:00
parent 4efb350f14
commit 0a5905b434
10 changed files with 188 additions and 0 deletions

View file

@ -48,6 +48,10 @@ function __main__() {
if [[ "$SIBLING_CONTAINERS_ENABLED" == "true" ]]; then
compose_file_flags+=("-f $TOOLKIT_ROOT/lib/docker-compose.sibling-containers.yml")
fi
if [[ "$NGINX_ENABLED" == "true" ]]; then
compose_file_flags+=("-f $TOOLKIT_ROOT/lib/docker-compose.nginx.yml")
fi
# Include docker-compose.override.yml if it is present
if [[ -f "$TOOLKIT_ROOT/config/docker-compose.override.yml" ]]; then
@ -94,6 +98,7 @@ function __main__() {
export REDIS_DATA_PATH
export REDIS_HOST
export REDIS_PORT
export OL_DOMAINS
# shellcheck disable=SC2068
exec docker-compose -p "$project_name" ${compose_file_flags[@]} "$@"

View file

@ -23,6 +23,7 @@ documentation on the [Overleaf Wiki](https://github.com/overleaf/overleaf/wiki)
- [Configuration Overview](./configuration.md)
- [overleaf.rc](./overleaf-rc.md)
- [TLS proxy](./tls-proxy.md)
## Persistent Data

View file

@ -105,3 +105,7 @@ Specifies the Redis port to use when `REDIS_ENABLED` is `false`
Sets the path to the directory that will be mounted into the `redis` container, and used to store the Redis database. This can be either a full path (beginning with a `/`), or relative to the base directory of the toolkit. This option only affects the local `redis` container that is created when `REDIS_ENABLED` is `true`.
- Default: data/redis
### `OL_DOMAINS`
A comma separated list of host names for which a TLS certificate will be generated when using the [TLS Proxy](./tls-proxy.md)

57
doc/tls-proxy.md Normal file
View file

@ -0,0 +1,57 @@
## TLS Proxy for Overleaf Toolkit environment
This provides an nginx proxy for overleaf-toolkit with TLS certificates loaded.
The first time you bring up the toolkit environment, this will generate TLS certificates for the web server(s) and a CA certificate in `tls_proxy/certs`.
The TLS certificates will be generated for a comma-separated list of domains specified in the `OL_DOMAINS` environment variable. The default value is for `localhost` and `overleaf-toolkit.com`.
For local testing you can add `overleaf-toolkit.com` to your `/etc/hosts` file.
**Mac users note:** Apache may be running on your machine by default. If the toolkit environment fails to come up, you should run `sudo apachectl stop`. To make this change permanent, run: `sudo launchctl unload -w /Applications/Server.app/Contents/ServerRoot/System/Library/LaunchDaemons/com.apple.serviceproxy.plist`.
You will need to configure your system to trust the new CA certificate, so that you get a green padlock in your browser and can use command-line tools like `curl`.
The new root CA certificate you need to trust will be `tls_proxy/certs/minica.pem` and you should add it thusly:
### On Mac
Run this command:
```
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain tls_proxy/certs/minica.pem
```
##### Using Firefox?
You need to manually add the certificate to Firefox.
To do so go to Firefox's settings and search for the "Certificates" section. Click "View Certificates..." then "Import...".
### On Linux
Linux is more complicated, as not all trust stores work the same way and it can differ based on distribution.
To add the certificate to the system-wide trust store so that command-line tools work, run these commands, after bringing up the toolkit env:
```
sudo mkdir -p /usr/local/share/ca-certificates
sudo cp tls_proxy/certs/minica.pem /usr/local/share/ca-certificates/minica.crt
# note different extension here
sudo update-ca-certificates
```
Unfortunately, your *browser* will not trust the system CA store. Instead you need to run (as your normal user, not root):
```
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n "Overleaf Minica" -i tls_proxy/certs/minica.pem
```
If running Chromium as a snap (e.g. on Ubuntu > 20.04) run
```
certutil -d $HOME/snap/chromium/current/.pki/nssdb -A -t "C,," -n "Overleaf Minica" -i tls_proxy/certs/minica.pem
```
This should work, but might not in all cases. If your browser still does not trust the site certificate at https://localhost/ you may need to manually add it to the list of trusted certificates in your browser's settings.
```

View file

@ -18,3 +18,7 @@ MONGO_DATA_PATH=data/mongo
# Redis configuration
REDIS_ENABLED=true
REDIS_DATA_PATH=data/redis
# TLS Proxy
NGINX_ENABLED=false
OL_DOMAINS=localhost,*.localhost,overleaf-toolkit.com,*.overleaf-toolkit.com

View file

@ -0,0 +1,16 @@
---
version: '2.2'
services:
tls_proxy:
build: ../tls_proxy
ports:
- 127.0.0.1:443:18443
volumes:
- ./../tls_proxy/certs:/certs
- ./../tls_proxy/nginx.conf:/etc/nginx/nginx.conf
environment:
OL_DOMAINS: "${OL_DOMAINS}"
restart: on-failure:5
depends_on:
- sharelatex

15
tls_proxy/Dockerfile Normal file
View file

@ -0,0 +1,15 @@
FROM golang:alpine AS build
RUN apk add git
RUN go get github.com/jsha/minica
FROM nginx:alpine
VOLUME /certs
COPY --from=build /go/bin/minica /usr/bin/minica
ADD run.sh /run.sh
ADD nginx.conf /etc/nginx/nginx.conf
EXPOSE 18443
CMD /run.sh

1
tls_proxy/certs/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.pem

70
tls_proxy/nginx.conf Normal file
View file

@ -0,0 +1,70 @@
user nginx;
worker_processes 1;
error_log /dev/stderr notice;
events {
worker_connections 1024;
use epoll;
}
http {
resolver 127.0.0.11 ipv6=off valid=30s;
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
server {
listen 18443 ssl;
server_name _; # Catch all, see http://nginx.org/en/docs/http/server_names.html
server_name overleaf-toolkit.com;
ssl_certificate /certs/nginx_certificate.pem;
ssl_certificate_key /certs/nginx_key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
# used cloudflares ciphers https://github.com/cloudflare/sslconfig/blob/master/conf
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
# config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
# to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
server_tokens off;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
client_max_body_size 50M;
location / {
proxy_pass http://sharelatex:80; # change to whatever host/port the docker container is listening on.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 3m;
proxy_send_timeout 3m;
}
}
}

15
tls_proxy/run.sh Executable file
View file

@ -0,0 +1,15 @@
#!/bin/sh
CERT_FOLDER=${OL_DOMAINS%%,*}
cd /certs
rm -rf $CERT_FOLDER
/usr/bin/minica --domains $OL_DOMAINS && \
cat $CERT_FOLDER/cert.pem minica.pem > nginx_certificate.pem && \
cp $CERT_FOLDER/key.pem nginx_key.pem && \
chmod a+r *.pem && \
rm -rf $CERT_FOLDER
nginx -g "daemon off;"