Merge pull request #6261 from peb-adr/proxy-rework

Proxy rework
This commit is contained in:
peb-adr 2021-10-25 14:59:31 +02:00 committed by GitHub
commit bad1e131ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 279 additions and 46 deletions

View File

@ -135,5 +135,3 @@ services:
- autoupdate
ports:
- "8000:8000"
volumes:
- ../proxy/Caddyfile.dev:/etc/caddy/Caddyfile

View File

@ -1,16 +0,0 @@
import endpoint
reverse_proxy /system/action* backend:9002
reverse_proxy /system/presenter* backend:9003
reverse_proxy /system/autoupdate* autoupdate:9012 {
flush_interval -1
}
reverse_proxy /system/icc* icc:9013 {
flush_interval -1
}
reverse_proxy /system/auth* auth:9004
reverse_proxy /system/media* media:9006
reverse_proxy client:9001
}

View File

@ -1,16 +0,0 @@
https://:8000 {
tls /certs/cert.pem /certs/key.pem
reverse_proxy /system/action* backend:9002
reverse_proxy /system/presenter* backend:9003
reverse_proxy /system/autoupdate* autoupdate:9012 {
flush_interval -1
}
reverse_proxy /system/icc* icc:9013 {
flush_interval -1
}
reverse_proxy /system/auth* auth:9004
reverse_proxy /system/media* media:9006
reverse_proxy client:9001
}

View File

@ -1,8 +1,10 @@
FROM caddy:2.3.0-alpine
COPY Caddyfile /etc/caddy/Caddyfile
RUN apk update && apk add --no-cache jq gettext
COPY caddy_base.json /caddy_base.json
COPY entrypoint /entrypoint
COPY certs /certs
ENTRYPOINT ["/entrypoint"]
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
CMD ["caddy", "run", "--config", "/etc/caddy/config.json"]

View File

@ -1,4 +1,12 @@
FROM caddy:2.3.0-alpine
COPY Caddyfile.dev /etc/caddy/Caddyfile
RUN apk update && apk add --no-cache jq gettext
COPY caddy_base.json /caddy_base.json
COPY entrypoint /entrypoint
COPY certs /certs
ENV ENABLE_LOCAL_HTTPS=1
ENTRYPOINT ["/entrypoint"]
CMD ["caddy", "run", "--config", "/etc/caddy/config.json"]

25
proxy/README.md Normal file
View File

@ -0,0 +1,25 @@
# OpenSlides proxy
The proxy is the entrypoint for traffic going into an OpenSlides instance and
hides all the services needed for production behind a single port. On the
docker container this will be port 8000. An arbitrary port from the host can
then be forwarded to that (e.g. 443->8000).
## HTTPS
It is possible to make use of caddy's automatic https feature in order to not
having to manually generate TLS certificates.
Set `ENABLE_AUTO_HTTPS=1` and `EXTERNAL_ADDRESS=openslides.example.com` to
activate it. Caddy will then retrieve a letsencrypt certificate for that
domain.
For testing a setup e.g.
`ACME_ENDPOINT=https://acme-staging-v02.api.letsencrypt.org/directory` can also
be set to avoid hitting rate limits.
Importantly, port 80 on the host must be forwarded to port 8001 on which caddy
will answer the ACME-challenge during certificate retrieval.
Alternatively a locally generated certificate can be used by executing
`make-localhost-cert.sh` before building the docker image (!) and setting
`ENABLE_LOCAL_HTTPS=1`. This is mostly for dev setup purposes and is not useful
for a public domain as the cert is not issued by a trusted CA and therefore
not trusted by browsers. If set, this overrules `ENABLE_AUTO_HTTPS`.

194
proxy/caddy_base.json Normal file
View File

@ -0,0 +1,194 @@
{
"apps": {
"tls": {
"automation": {
"policies": [
{
"issuers": [
{
"module": "acme",
"challenges": {
"tls-alpn": {
"disabled": true
}
}
}
]
}
]
}
},
"http": {
"servers": {
"srv0": {
"listen": [
":8000"
],
"allow_h2c": true,
"routes": [
{
"handle": [
{
"flush_interval": -1,
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "$AUTOUPDATE_HOST:$AUTOUPDATE_PORT"
}
]
}
],
"match": [
{
"path": [
"/system/autoupdate*"
]
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "$PRESENTER_HOST:$PRESENTER_PORT"
}
]
}
],
"match": [
{
"path": [
"/system/presenter*"
]
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "$ACTION_HOST:$ACTION_PORT"
}
]
}
],
"match": [
{
"path": [
"/system/action*"
]
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "$MEDIA_HOST:$MEDIA_PORT"
}
]
}
],
"match": [
{
"path": [
"/system/media*"
]
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "$AUTH_HOST:$AUTH_PORT"
}
]
}
],
"match": [
{
"path": [
"/system/auth*"
]
}
]
},
{
"handle": [
{
"flush_interval": -1,
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "$ICC_HOST:$ICC_PORT"
}
]
}
],
"match": [
{
"path": [
"/system/icc*"
]
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"flush_interval": -1,
"transport": {
"protocol": "http",
"versions": [
"2",
"h2c"
]
},
"upstreams": [
{
"dial": "$MANAGE_HOST:$MANAGE_PORT"
}
]
}
],
"match": [
{
"header": {
"Content-Type": [
"application/grpc"
]
}
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "$CLIENT_HOST:$CLIENT_PORT"
}
]
}
]
}
],
"automatic_https": {
"disable": true
}
}
}
}
}
}

View File

@ -2,15 +2,53 @@
set -e
if [[ -f "/certs/key.pem" ]] && [[ -f "/certs/cert.pem" ]]; then
cat <<EOF >> /etc/caddy/endpoint
https://:8000 {
tls /certs/cert.pem /certs/key.pem
EOF
echo "Configured https"
config=/etc/caddy/config.json
base=/caddy_base.json
# set defaults in base
ACTION_HOST="${ACTION_HOST:-backend}" ACTION_PORT="${ACTION_PORT:-9002}" \
PRESENTER_HOST="${PRESENTER_HOST:-backend}" PRESENTER_PORT="${PRESENTER_PORT:-9003}" \
AUTOUPDATE_HOST="${AUTOUPDATE_HOST:-autoupdate}" AUTOUPDATE_PORT="${AUTOUPDATE_PORT:-9012}" \
ICC_HOST="${ICC_HOST:-icc}" ICC_PORT="${ICC_PORT:-9013}" \
AUTH_HOST="${AUTH_HOST:-auth}" AUTH_PORT="${AUTH_PORT:-9004}" \
MEDIA_HOST="${MEDIA_HOST:-media}" MEDIA_PORT="${MEDIA_PORT:-9006}" \
MANAGE_HOST="${MANAGE_HOST:-manage}" MANAGE_PORT="${MANAGE_PORT:-9008}" \
CLIENT_HOST="${CLIENT_HOST:-client}" CLIENT_PORT="${CLIENT_PORT:-9001}" \
envsubst < "$base" > "$base.out" && mv -f "$base.out" "$base"
jq_write() {
filter=$1
jq "$filter" "$base" > "$base.out" && mv -f "$base.out" "$base"
}
### HTTPS ###
if [ -n "$ENABLE_LOCAL_HTTPS" ]; then
[ -f /certs/cert.pem ] && [ -f /certs/key.pem ] || {
echo "ERROR: no local cert-files provided. Did you run make-localhost-cert.sh?"
exit 1
}
jq_write ".apps.http.servers.srv0.tls_connection_policies = [{ certificate_selection: { any_tag: [ \"cert0\" ] }}]"
jq_write ".apps.tls = { certificates: { load_files: [{ certificate: \"/certs/cert.pem\", key: \"/certs/key.pem\", tags: [ \"cert0\" ] }] }}"
else
echo "http://:8000 {" > /etc/caddy/endpoint
echo "Configured http"
if [ -n "$ENABLE_AUTO_HTTPS" ]; then
if [ -n "$EXTERNAL_ADDRESS" ]; then
echo "INFO: For the automatic https to work ports 443 and 80 of the host must be
directed to 8000 and 8001 of this container"
jq_write "del(.apps.http.servers.srv0.automatic_https)" # disabled in base
jq_write ".apps.http.https_port = 8000"
jq_write ".apps.http.http_port = 8001"
jq_write ".apps.http.servers.srv0.routes[-1].match = [{ host: [\"$EXTERNAL_ADDRESS\"]}]"
if [ -n "$ACME_ENDPOINT" ]; then
jq_write ".apps.tls.automation.policies[0].issuers[0].ca = \"${ACME_ENDPOINT}\""
fi
else
echo "ERROR: EXTERNAL_ADDRESS needed for automatic HTTPS / cert generation"
exit 1
fi
fi
fi
exec "$@"
mv "$base" "$config"
exec "$@"