Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ ENV DOMAINNAMES ${DOMAINNAMES}
ENV TERM xterm
ENV HAPROXY_USER_PARAMS ${HAPROXY_USER_PARAMS}
ENV HAPROXY_CONFIG ${HAPROXY_CONFIG:-/etc/haproxy/haproxy.cfg}
ENV HTTP_PORT ${HTTP_PORT:-80}
ENV HTTPS_PORT ${HTTPS_PORT:-443}
ENV HTTPS_FORWARDED_PORT ${HTTPS_FORWARDED_PORT:-%[dst_port]}
ENV NAMESERVER ${NAMESERVER:-127.0.0.11:53}
ENV PROXY_LOGLEVEL ${PROXY_LOGLEVEL:-notice}
ENV MANAGER_HOST ${MANAGER_HOST:-manager}
ENV MANAGER_WEB_PORT ${MANAGER_WEB_PORT:-8080}
Expand Down
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
# HAProxy docker image

[![Docker Image](https://github.com/openremote/proxy/actions/workflows/proxy.yml/badge.svg)](https://github.com/openremote/proxy/actions/workflows/proxy.yml)

HAProxy docker image with Lets Encrypt SSL auto renewal using certbot with built in support for wildcard certificates using AWS Route53.

## Paths

* `/deployment/letsencrypt` - Certbot config directory where generated certificates are stored
* `/etc/haproxy/haproxy.cfg` - Default location of haproxy configuration file
* `/etc/haproxy/certs` - Static (non certbot) certificates includes self-signed and any other static certificates should be volume mapped into this folder
* `/var/log/*` - Location of log files (all are symlinked to stdout)

## Environment variables

* `DOMAINNAME` - IANA TLD subdomain for which a Lets Encrypt certificate should be requested
* `DOMAINNAMES` - Comma separated list of IANA TLD subdomain names for which Lets Encrypt certificates should be
requested (this is a multi-value alternative to DOMAINNAME)
* `HAPROXY_USER_PARAMS` - Additional arguments that should be passed to the haproxy process during startup
* `HAPROXY_CONFIG` - Location of HAProxy config file (default: `/etc/haproxy/haproxy.cfg`)
* `PROXY_LOGLEVEL` - Log level for HAProxy (default: `notice`)
* `HTTP_PORT` - The container binds to this port for handling HTTP requests (default: `80`)
* `HTTPS_PORT` - The container binds to this port for handling HTTPS requests (default: `443`)
* `HTTPS_FORWARDED_PORT` - The port set in the `X-Forwarded-Port` header of requests send to the Manager/Keycloak (default: `%[dst_port]` this is the HAProxy port)
* `NAMESERVER` - The nameserver hostname and port used for resolving the Manager/Keycloak hosts (default: `127.0.0.11:53`)
* `MANAGER_HOST` - Hostname of OpenRemote Manager (default: `manager`)
* `MANAGER_WEB_PORT` - Web server port of OpenRemote Manager (default `8080`)
* `MANAGER_MQTT_PORT` - MQTT broker port of OpenRemote Manager (default `1883`)
Expand All @@ -31,12 +38,22 @@ requested (this is a multi-value alternative to DOMAINNAME)
* `MQTT_RATE_LIMIT` - Enable rate limiting for MQTT connections (connections/s)

## Custom certificate format

Any custom certificate volume mapped into `/etc/haproxy/certs` should be in PEM format and must include the full certificate chain and the private key, i.e.:
```
cat privkey.pem cert.pem chain.pem > ssl-certs.pem
```shell
cat privkey.pem cert.pem chain.pem > ssl-certs.pem
```

See `haproxy` SSL cert [documentation](https://www.haproxy.com/blog/haproxy-ssl-termination/#enabling-ssl-with-haproxy).

## Edge gateway tunnelling using SISH

The built in `haproxy.cfg` has support for forwarding requsts beginning with `gw-` to `https://SISH_HOST:SISH_PORT` just define these environment variables to enable this.

## Kubernetes

When running the proxy in Kubernetes make sure to set the `HTTP_PORT` and `HTTPS_PORT` environment variables to a non-privileged port (> 1024).
If you use an Ingress, reconfigure the `HTTPS_FORWARDED_PORT` to the HTTPS port of your Ingress (443).
Comment thread
wborn marked this conversation as resolved.

You will also need to set the `NAMESERVER` environment variable to the cluster DNS (usually 10.96.0.10:53).
The cluster DNS typically only resolves fully qualified hostnames, so make sure to set these using the `MANAGER_HOST` and `KEYCLOAK_HOST` environment variables (e.g. `manager.default.svc.cluster.local`).
11 changes: 4 additions & 7 deletions haproxy.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ defaults
default-server init-addr none

resolvers docker_resolver
nameserver dns 127.0.0.11:53
nameserver dns "${NAMESERVER}"

frontend stats
bind *:8404
Expand All @@ -40,7 +40,7 @@ frontend stats
stats refresh 10s

frontend http
bind *:80
bind *:"${HTTP_PORT}"

# Serve certificate validation challenges directly with Lua plugin
acl url_acme_http01 path_beg /.well-known/acme-challenge/
Expand All @@ -55,7 +55,7 @@ frontend http
redirect scheme https code 301 if !url_acme_http01 !url_docker_health

frontend https
bind *:443 ssl crt /etc/haproxy/certs crt "${CERT_DIR}" no-tls-tickets
bind *:"${HTTPS_PORT}" ssl crt /etc/haproxy/certs crt "${CERT_DIR}" no-tls-tickets

# Optional: redirects for root requests with certain host names to service paths
acl is_root path -i /
Expand Down Expand Up @@ -105,7 +105,7 @@ frontend https
option forwardfor
http-request add-header X-Forwarded-Proto https
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
http-request add-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Port "${HTTPS_FORWARDED_PORT}"
# Enforce HSTS
http-response add-header Strict-Transport-Security max-age=15768000
# Block bot indexing
Expand Down Expand Up @@ -150,9 +150,6 @@ backend manager_backend

backend keycloak_backend
server keycloak "${KEYCLOAK_HOST}":"${KEYCLOAK_PORT}" resolvers docker_resolver
.if defined(KEYCLOAK_PATH_PREFIX)
http-request replace-path ^"${KEYCLOAK_PATH_PREFIX}"(/.*)?$ \1
.endif

# Gateway tunnelling config
.if defined(SISH_HOST) && defined(SISH_PORT)
Expand Down