Add ALLOWED_HOSTS
the proxy responds with a 421, if a host header with an invalid host name is encountered. If nothing is provided (see default .env) all hosts are allowed. Examples: ALLOWED_HOSTS="localhost:8000 127.0.0.1:8000" ALLOWED_HOSTS="some.domain.example.com" Add EXTERNAL_HTTPS_PORT. See .env for the configuration.
This commit is contained in:
parent
ee8702aff1
commit
91a15d24a8
10
README.rst
10
README.rst
@ -33,8 +33,8 @@ first and initialize all submodules::
|
|||||||
|
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
|
|
||||||
Setup Docker images
|
Setup Docker Compose
|
||||||
-------------------
|
--------------------
|
||||||
|
|
||||||
You need to build the Docker images and have to setup some configuration. First,
|
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
|
configure HTTPS by checking the `Using HTTPS`_ section. In this section are
|
||||||
@ -64,11 +64,15 @@ Afterwards, generate the configuration file::
|
|||||||
|
|
||||||
m4 docker-compose.yml.m4 > docker-compose.yml
|
m4 docker-compose.yml.m4 > docker-compose.yml
|
||||||
|
|
||||||
|
You can configure OpenSlides using the `.env` file. See `More settings`_. Another
|
||||||
|
hint: If you choose to deploy the default configuration, a https certificate is
|
||||||
|
needed, so make sure you have set it up beforehand.
|
||||||
|
|
||||||
Finally, you can start the instance using ``docker-compose``::
|
Finally, you can start the instance using ``docker-compose``::
|
||||||
|
|
||||||
docker-compose up
|
docker-compose up
|
||||||
|
|
||||||
OpenSlides is accessible on http://localhost:8000/ (or https, if configured).
|
OpenSlides is accessible on https://localhost/ (or https, if configured).
|
||||||
|
|
||||||
Use can also use daemonized instance::
|
Use can also use daemonized instance::
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import endpoint
|
import endpoint
|
||||||
|
import invalid_host*
|
||||||
|
|
||||||
reverse_proxy /system/* autoupdate:8002 {
|
reverse_proxy /system/* autoupdate:8002 {
|
||||||
flush_interval -1
|
flush_interval -1
|
||||||
@ -15,3 +16,5 @@ import endpoint
|
|||||||
|
|
||||||
reverse_proxy client:4200
|
reverse_proxy client:4200
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import redirect*
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
localhost:8000
|
:8000 {
|
||||||
|
reverse_proxy /system/* autoupdate:8002 {
|
||||||
|
flush_interval -1
|
||||||
|
}
|
||||||
|
|
||||||
reverse_proxy /system/* autoupdate:8002 {
|
@server {
|
||||||
flush_interval -1
|
path /apps/*
|
||||||
|
path /rest/*
|
||||||
|
path /server-version.txt
|
||||||
|
path /media/*
|
||||||
|
}
|
||||||
|
reverse_proxy @server server:8000
|
||||||
|
|
||||||
|
reverse_proxy client:4200
|
||||||
}
|
}
|
||||||
|
|
||||||
@server {
|
|
||||||
path /apps/*
|
|
||||||
path /rest/*
|
|
||||||
path /server-version.txt
|
|
||||||
path /media/*
|
|
||||||
}
|
|
||||||
reverse_proxy @server server:8000
|
|
||||||
|
|
||||||
reverse_proxy client:4200
|
|
||||||
|
@ -2,15 +2,77 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if [[ -z "$EXTERNAL_HTTP_PORT" ]] && [[ -z "$EXTERNAL_HTTPS_PORT" ]]; then
|
||||||
|
echo "EXTERNAL_HTTP_PORT and EXTERNAL_HTTPS_PORT are not set. Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -f "/certs/key.pem" ]] && [[ -f "/certs/cert.pem" ]]; then
|
if [[ -f "/certs/key.pem" ]] && [[ -f "/certs/cert.pem" ]]; then
|
||||||
|
certs_exists=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$EXTERNAL_HTTPS_PORT" ]] && [[ -z "$certs_exists" ]]; then
|
||||||
|
echo "Configured https, but no certificates found. Aborting"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# config: https
|
||||||
|
if [[ -n "$EXTERNAL_HTTPS_PORT" ]] ; then
|
||||||
cat <<EOF >> /etc/caddy/endpoint
|
cat <<EOF >> /etc/caddy/endpoint
|
||||||
https://:8000 {
|
https://:8001 {
|
||||||
tls /certs/cert.pem /certs/key.pem
|
tls /certs/cert.pem /certs/key.pem
|
||||||
EOF
|
EOF
|
||||||
echo "Configured https"
|
echo "Configured https"
|
||||||
else
|
fi
|
||||||
|
|
||||||
|
# config: http and no https
|
||||||
|
if [[ -n "$EXTERNAL_HTTP_PORT" ]] && [[ -z "$EXTERNAL_HTTPS_PORT" ]] ; then
|
||||||
echo "http://:8000 {" > /etc/caddy/endpoint
|
echo "http://:8000 {" > /etc/caddy/endpoint
|
||||||
echo "Configured http"
|
echo "Configured http only"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# config: https and additionally http -> create redirect-file
|
||||||
|
if [[ -n "$EXTERNAL_HTTP_PORT" ]] && [[ -n "$EXTERNAL_HTTPS_PORT" ]] ; then
|
||||||
|
cat <<EOF >> /etc/caddy/redirect
|
||||||
|
http://:8000 {
|
||||||
|
redir https://$INSTANCE_DOMAIN{uri}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
echo "Configured http to https redirect"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add allowed hosts from $ALLOWED_HOSTS
|
||||||
|
# If the variable is empty, all hosts are allowed.
|
||||||
|
# The hosts are ORed, so the request is valid, if one host matches.
|
||||||
|
# Example: ALLOWED_HOSTS="localhost:8000 127.0.0.1:8000"
|
||||||
|
#
|
||||||
|
# @invalid-host {
|
||||||
|
# not {
|
||||||
|
# header Host localhost:8000
|
||||||
|
# header Host 127.0.0.1:8000
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# respond @invalid-host "Misdirected Request" 421 {
|
||||||
|
# close
|
||||||
|
# }
|
||||||
|
if [[ ! -z "$ALLOWED_HOSTS" ]]; then
|
||||||
|
cat <<EOF >> /etc/caddy/invalid_host
|
||||||
|
@invalid-host {
|
||||||
|
not {
|
||||||
|
EOF
|
||||||
|
for host in $ALLOWED_HOSTS; do
|
||||||
|
echo " host $host" >> /etc/caddy/invalid_host
|
||||||
|
done
|
||||||
|
cat <<EOF >> /etc/caddy/invalid_host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
respond @invalid-host "Misdirected Request" 421 {
|
||||||
|
close
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
echo "Configured allowed hosts: $ALLOWED_HOSTS"
|
||||||
|
else
|
||||||
|
echo "All hosts allowed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
33
docker/.env
33
docker/.env
@ -10,9 +10,40 @@
|
|||||||
|
|
||||||
# General
|
# General
|
||||||
# -------
|
# -------
|
||||||
|
|
||||||
|
# The domain your OpenSlides installation in reachable. E.g. example.com or
|
||||||
|
# 127.0.0.1 for a local deployment. This domain is used when generating links
|
||||||
|
# in emails and so on, so it should be the public facing domain. The default
|
||||||
|
# is 127.0.0.1
|
||||||
|
# If you do not have any port-changing proxies, this setting should be kept in
|
||||||
|
# sync with the EXTERNAL_*_PORTS below
|
||||||
INSTANCE_DOMAIN=
|
INSTANCE_DOMAIN=
|
||||||
PROJECT_STACK_NAME=
|
|
||||||
|
# The schema (http or https) to use for generating public links. The default
|
||||||
|
# is https.
|
||||||
|
INSTANCE_URL_SCHEME=
|
||||||
|
|
||||||
|
# The ports the setup binds to to listen for http/https requests. To not bind
|
||||||
|
# to http or https, leave the port empty. Behavior of port-combinations:
|
||||||
|
# - If both ports are set, the server listens to https. Additionally, a http to
|
||||||
|
# https redirect is activated on the http port.
|
||||||
|
# - If no ports are set, the https port defaults to 443.
|
||||||
|
# - If exactly one port is set, the server listens to the given port.
|
||||||
|
# If the https port is set, there must be a ssl certificate. See the README
|
||||||
|
# for more information.
|
||||||
EXTERNAL_HTTP_PORT=
|
EXTERNAL_HTTP_PORT=
|
||||||
|
EXTERNAL_HTTPS_PORT=
|
||||||
|
|
||||||
|
# A list of hosts, that are allowed to accept. If there is a not accepted host,
|
||||||
|
# a 421 response will be returned.
|
||||||
|
# The default is an empty list, so all hosts are accepted.
|
||||||
|
# Example with two hosts: ALLOWED_HOSTS="127.0.0.1:443 example.com"
|
||||||
|
ALLOWED_HOSTS=
|
||||||
|
|
||||||
|
# The name for the docker stack used.
|
||||||
|
PROJECT_STACK_NAME=
|
||||||
|
|
||||||
|
# The default registry. Defaults to "openslides".
|
||||||
DEFAULT_DOCKER_REGISTRY=
|
DEFAULT_DOCKER_REGISTRY=
|
||||||
|
|
||||||
# Docker Images
|
# Docker Images
|
||||||
|
@ -42,6 +42,14 @@ ifelse(read_env(`PGNODE_3_ENABLED'), 1, `,pgnode3')')
|
|||||||
define(`PROJECT_DIR', ifdef(`PROJECT_DIR',PROJECT_DIR,.))
|
define(`PROJECT_DIR', ifdef(`PROJECT_DIR',PROJECT_DIR,.))
|
||||||
define(`ADMIN_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/adminsecret.env')sysval')
|
define(`ADMIN_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/adminsecret.env')sysval')
|
||||||
define(`USER_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/usersecret.env')sysval')
|
define(`USER_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/usersecret.env')sysval')
|
||||||
|
|
||||||
|
dnl set EXTERNAL_HTTPS_PORT to 443 if EXTERNAL_HTTPS_PORT and EXTERNAL_HTTP_PORT are empty
|
||||||
|
define(
|
||||||
|
`EXTERNAL_HTTPS_PORT',
|
||||||
|
ifelse(read_env(`EXTERNAL_HTTPS_PORT')read_env(`EXTERNAL_HTTP_PORT'),,443,read_env(`EXTERNAL_HTTPS_PORT'))dnl
|
||||||
|
)
|
||||||
|
define(`EXTERNAL_HTTP_PORT',read_env(`EXTERNAL_HTTP_PORT'))
|
||||||
|
|
||||||
divert(0)dnl
|
divert(0)dnl
|
||||||
dnl ----------------------------------------
|
dnl ----------------------------------------
|
||||||
# This configuration was created from a template file. Before making changes,
|
# This configuration was created from a template file. Before making changes,
|
||||||
@ -75,7 +83,8 @@ x-osserver-env: &default-osserver-env
|
|||||||
ENABLE_ELECTRONIC_VOTING: "ifenvelse(`ENABLE_ELECTRONIC_VOTING', False)"
|
ENABLE_ELECTRONIC_VOTING: "ifenvelse(`ENABLE_ELECTRONIC_VOTING', False)"
|
||||||
ENABLE_CHAT: "ifenvelse(`ENABLE_CHAT', False)"
|
ENABLE_CHAT: "ifenvelse(`ENABLE_CHAT', False)"
|
||||||
ENABLE_SAML: "ifenvelse(`ENABLE_SAML', False)"
|
ENABLE_SAML: "ifenvelse(`ENABLE_SAML', False)"
|
||||||
INSTANCE_DOMAIN: "ifenvelse(`INSTANCE_DOMAIN', http://example.com:8000)"
|
INSTANCE_DOMAIN: "ifenvelse(`INSTANCE_DOMAIN', 127.0.0.1)"
|
||||||
|
INSTANCE_URL_SCHEME: "ifenvelse(`INSTANCE_URL_SCHEME', https)"
|
||||||
JITSI_DOMAIN: "ifenvelse(`JITSI_DOMAIN',)"
|
JITSI_DOMAIN: "ifenvelse(`JITSI_DOMAIN',)"
|
||||||
JITSI_ROOM_PASSWORD: "ifenvelse(`JITSI_ROOM_PASSWORD',)"
|
JITSI_ROOM_PASSWORD: "ifenvelse(`JITSI_ROOM_PASSWORD',)"
|
||||||
JITSI_ROOM_NAME: "ifenvelse(`JITSI_ROOM_NAME',)"
|
JITSI_ROOM_NAME: "ifenvelse(`JITSI_ROOM_NAME',)"
|
||||||
@ -108,11 +117,17 @@ services:
|
|||||||
- client
|
- client
|
||||||
- autoupdate
|
- autoupdate
|
||||||
- media
|
- media
|
||||||
|
environment:
|
||||||
|
INSTANCE_DOMAIN: "ifenvelse(`INSTANCE_DOMAIN', 127.0.0.1:443)"
|
||||||
|
`EXTERNAL_HTTP_PORT': "EXTERNAL_HTTP_PORT"
|
||||||
|
`EXTERNAL_HTTPS_PORT': "EXTERNAL_HTTPS_PORT"
|
||||||
|
ALLOWED_HOSTS: "ifenvelse(`ALLOWED_HOSTS',)"
|
||||||
networks:
|
networks:
|
||||||
- front
|
- front
|
||||||
- back
|
- back
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:ifenvelse(`EXTERNAL_HTTP_PORT', 8000):8000"
|
ifelse(EXTERNAL_HTTP_PORT,,,- "127.0.0.1:EXTERNAL_HTTP_PORT:8000")
|
||||||
|
ifelse(EXTERNAL_HTTPS_PORT,,,- "127.0.0.1:EXTERNAL_HTTPS_PORT:8001")
|
||||||
|
|
||||||
server:
|
server:
|
||||||
<< : *default-osserver
|
<< : *default-osserver
|
||||||
|
@ -42,6 +42,14 @@ ifelse(read_env(`PGNODE_3_ENABLED'), 1, `,pgnode3')')
|
|||||||
define(`PROJECT_DIR', ifdef(`PROJECT_DIR',PROJECT_DIR,.))
|
define(`PROJECT_DIR', ifdef(`PROJECT_DIR',PROJECT_DIR,.))
|
||||||
define(`ADMIN_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/adminsecret.env')sysval')
|
define(`ADMIN_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/adminsecret.env')sysval')
|
||||||
define(`USER_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/usersecret.env')sysval')
|
define(`USER_SECRET_AVAILABLE', `syscmd(`test -f 'PROJECT_DIR`/secrets/usersecret.env')sysval')
|
||||||
|
|
||||||
|
dnl set EXTERNAL_HTTPS_PORT to 443 if EXTERNAL_HTTPS_PORT and EXTERNAL_HTTP_PORT are empty
|
||||||
|
define(
|
||||||
|
`EXTERNAL_HTTPS_PORT',
|
||||||
|
ifelse(read_env(`EXTERNAL_HTTPS_PORT')read_env(`EXTERNAL_HTTP_PORT'),,443,read_env(`EXTERNAL_HTTPS_PORT'))dnl
|
||||||
|
)
|
||||||
|
define(`EXTERNAL_HTTP_PORT',read_env(`EXTERNAL_HTTP_PORT'))
|
||||||
|
|
||||||
divert(0)dnl
|
divert(0)dnl
|
||||||
dnl ----------------------------------------
|
dnl ----------------------------------------
|
||||||
# This configuration was created from a template file. Before making changes,
|
# This configuration was created from a template file. Before making changes,
|
||||||
@ -74,7 +82,8 @@ x-osserver-env: &default-osserver-env
|
|||||||
ENABLE_ELECTRONIC_VOTING: "ifenvelse(`ENABLE_ELECTRONIC_VOTING', False)"
|
ENABLE_ELECTRONIC_VOTING: "ifenvelse(`ENABLE_ELECTRONIC_VOTING', False)"
|
||||||
ENABLE_CHAT: "ifenvelse(`ENABLE_CHAT', False)"
|
ENABLE_CHAT: "ifenvelse(`ENABLE_CHAT', False)"
|
||||||
ENABLE_SAML: "ifenvelse(`ENABLE_SAML', False)"
|
ENABLE_SAML: "ifenvelse(`ENABLE_SAML', False)"
|
||||||
INSTANCE_DOMAIN: "ifenvelse(`INSTANCE_DOMAIN', http://example.com:8000)"
|
INSTANCE_DOMAIN: "ifenvelse(`INSTANCE_DOMAIN', 127.0.0.1)"
|
||||||
|
INSTANCE_URL_SCHEME: "ifenvelse(`INSTANCE_URL_SCHEME', https)"
|
||||||
JITSI_DOMAIN: "ifenvelse(`JITSI_DOMAIN',)"
|
JITSI_DOMAIN: "ifenvelse(`JITSI_DOMAIN',)"
|
||||||
JITSI_ROOM_PASSWORD: "ifenvelse(`JITSI_ROOM_PASSWORD',)"
|
JITSI_ROOM_PASSWORD: "ifenvelse(`JITSI_ROOM_PASSWORD',)"
|
||||||
JITSI_ROOM_NAME: "ifenvelse(`JITSI_ROOM_NAME',)"
|
JITSI_ROOM_NAME: "ifenvelse(`JITSI_ROOM_NAME',)"
|
||||||
@ -101,11 +110,17 @@ x-pgnode-env: &default-pgnode-env
|
|||||||
services:
|
services:
|
||||||
proxy:
|
proxy:
|
||||||
image: PROXY_IMAGE
|
image: PROXY_IMAGE
|
||||||
|
environment:
|
||||||
|
INSTANCE_DOMAIN: "ifenvelse(`INSTANCE_DOMAIN', 127.0.0.1:443)"
|
||||||
|
`EXTERNAL_HTTP_PORT': "EXTERNAL_HTTP_PORT"
|
||||||
|
`EXTERNAL_HTTPS_PORT': "EXTERNAL_HTTPS_PORT"
|
||||||
|
ALLOWED_HOSTS: "ifenvelse(`ALLOWED_HOSTS',)"
|
||||||
networks:
|
networks:
|
||||||
- front
|
- front
|
||||||
- back
|
- back
|
||||||
ports:
|
ports:
|
||||||
- "0.0.0.0:ifenvelse(`EXTERNAL_HTTP_PORT', 8000):8000"
|
ifelse(EXTERNAL_HTTP_PORT,,,- "127.0.0.1:EXTERNAL_HTTP_PORT:8000")
|
||||||
|
ifelse(EXTERNAL_HTTPS_PORT,,,- "127.0.0.1:EXTERNAL_HTTPS_PORT:8001")
|
||||||
deploy:
|
deploy:
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: on-failure
|
||||||
|
@ -77,7 +77,9 @@ def get_config_variables():
|
|||||||
# TODO: Use Django's URLValidator here.
|
# TODO: Use Django's URLValidator here.
|
||||||
yield ConfigVariable(
|
yield ConfigVariable(
|
||||||
name="users_pdf_url",
|
name="users_pdf_url",
|
||||||
default_value=os.getenv("INSTANCE_DOMAIN", default="http://example.com:8000"),
|
default_value=os.getenv("INSTANCE_URL_SCHEME", default="https")
|
||||||
|
+ "://"
|
||||||
|
+ os.getenv("INSTANCE_DOMAIN", default="127.0.0.1"),
|
||||||
label="System URL",
|
label="System URL",
|
||||||
help_text="Used for QRCode in PDF of access data.",
|
help_text="Used for QRCode in PDF of access data.",
|
||||||
weight=540,
|
weight=540,
|
||||||
|
Loading…
Reference in New Issue
Block a user