Skip to content

Commit

Permalink
Merge pull request #277 from bento-platform/releases/v17.1
Browse files Browse the repository at this point in the history
Release v17.1
  • Loading branch information
davidlougheed authored Nov 27, 2024
2 parents c4a60d8 + 1b1f473 commit 0cd6dcf
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 32 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ that make up the Bento platform.
* [Deployment](./docs/deployment.md)
* [Monitoring](./docs/monitoring.md)
* [Public discovery configuration](./docs/public_discovery.md)
* [Using a reverse proxy in front of Bento](./docs/reverse-proxy.md)

### Data ingestion and usage

Expand All @@ -47,6 +48,7 @@ that make up the Bento platform.

### Migration documents

* [v17 to v17.1](./docs/migrating_to_17_1.md)
* [v16 to v17](./docs/migrating_to_17.md)
* [v15.2 to v16](./docs/migrating_to_16.md)
* [v15.1 to v15.2](./docs/migrating_to_15_2.md)
Expand Down
Binary file added docs/img/private-network-reverse-proxy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions docs/migrating_to_17_1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Migrating to Bento v17.1

Migrating to version 17.1 from version 17 should be straightforward.
Check out our new documentation on [using a reverse proxy in front of Bento](./reverse-proxy.md)!


## 1. Update services and restart

Run the following commands to pull the latest service images and restart services as needed:

```bash
./bentoctl.bash pull
./bentoctl.bash start
```
142 changes: 142 additions & 0 deletions docs/reverse-proxy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Bento behind a proxy

A Bento instance is typically deployed on a dedicated VM with a public IP address.

By creating DNS `A` or `CNAME` records pointing hostnames to the VM's IP, deployers
can obtain SSL certificates from Let's Encrypt using `certbot`.

Having a Bento instance on a VM with a public IP is convenient in terms of deployment,
but is a security trade-off, as it exposes the VM's IP and ports to attackers.

A more secure deployment can be achieved by using a VM with no public IP to host Bento
and proxy the traffic through a reverse proxy.

## Using a reverse proxy in front of Bento

### Deployment overview
As an example, let's assume we have the following hostnames to deploy:
- Public dashboard: `sandbox.bento.example.com`
- Portal: `portal.sandbox.bento.example.com`
- Auth: `auth.sandbox.bento.example.com`

We will be using the following deployment infrastructure:
- **Bento VM** (`bento-sandbox`)
- Linux VM in a private or public cloud
- On the subnet `private-network`
- Public IP: `NONE`
- Private IP: `10.0.0.1`
- DNS records: `NONE`
- **Reverse Proxy**
- Has network access to `bento-sandbox (10.0.0.1)` on `private-network`
- Public IP: `some.public.ip.adr`
- DNS records:
- (A) `sandbox.bento.example.com` => `some.public.ip.adr`
- (A) `*.sandbox.bento.example.com` => `some.public.ip.adr`
- Manages the SSL certificates for our domains
- Proxies the requests to the `bento-sandbox` host with SSL termination
- `sandbox.bento.example.com` => `10.0.0.1:80`
- `*.sandbox.bento.example.com` => `10.0.0.1:80`


![Reverse proxy architecture](./img/private-network-reverse-proxy.png)
The diagram above illustrates the deployment architecture.

With the Bento VM on a dedicated private network, we can have SSL
termination at the reverse proxy in front of our Bento.
As a result, all the SSL certificates can be managed at the level of the reverse proxy.

### Configure the Bento hosting VM

To run a Bento instance in SSL termination mode:
```bash
# Set feature flag in local.env
BENTO_GATEWAY_USE_TLS='false'

# Start the services
./bentoctl.bash start
```

### Configure the reverse proxy

For this example, we are assuming that the reverse proxy is a Linux VM
on which NGINX has been installed and configured.

You could use another reverse proxy software of your liking, like Traefik or Caddy.
Alternatively, your reverse proxy could also be a service, like AWS's API Gateway, although this is out of scope for this demonstration.

Assuming a reverse proxy VM with NGINX installed and started, add this
configuration file to the `/etc/nginx/conf.d` directory:

```nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Redirect HTTP -> HTTPS
server {
listen 80 ;
return 301 https://$host$request_uri;
}
# Reject HTTPS requests on unspecified subdomains
server {
listen 443 ssl;
ssl_reject_handshake on;
}
server {
listen 443 ssl;
# Only accept "sandbox.bento.example.com" and auth|portal subdomains
server_name sandbox.bento.example.com auth.sandbox.bento.example.com portal.sandbox.bento.example.com;
# Wildcard certificate for *.sandbox.bento.example.com
ssl_certificate /etc/letsencrypt/live/sandbox.bento.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sandbox.bento.example.com/privkey.pem;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Crucial for Keycloak proxying with SSL termination
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
# For large requests
client_body_timeout 660s;
proxy_read_timeout 660s;
proxy_send_timeout 660s;
send_timeout 660s;
client_max_body_size 200m;
# Bento VM instance IP on the private network
# On port 80 since we use SSL termination
proxy_pass http://10.0.0.1:80;
proxy_redirect default;
}
}
```

Then restart the NGINX server to load the new configuration.

If everything was done correctly, you should now be able to reach the Bento instance through the reverse-proxy!

### Proxying multiple Bento instances
If more Bento instances are needed, the same reverse proxy can be used to route traffic.

To do so, one would simply need to:
1. Create and configure a Bento VM on a private network accesible by the reverse-proxy
2. Create new DNS records for the desired domains
1. Not necessary if using wildcard DNS records already covering the domain
3. Obtain the certificates for the desired domains on the reverse proxy
1. Or use wildcard certificates (recommended)
4. Configure the reverse proxy to route traffic to the new instance
1. Add a conf to `/etc/nginx/conf.d/`
2. Restart the reverse proxy
40 changes: 20 additions & 20 deletions etc/bento.env
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ BENTOV2_GATEWAY_INTERNAL_CERTS_DIR=/usr/local/openresty/nginx/certs

# Gateway
BENTOV2_GATEWAY_IMAGE=ghcr.io/bento-platform/bento_gateway
BENTOV2_GATEWAY_VERSION=0.13.0
BENTOV2_GATEWAY_VERSION=0.13.2
BENTOV2_GATEWAY_VERSION_DEV=${BENTOV2_GATEWAY_VERSION}-dev
BENTOV2_GATEWAY_CONTAINER_NAME=${BENTOV2_PREFIX}-gateway

Expand All @@ -47,7 +47,7 @@ BENTOV2_GATEWAY_CPUS=2

# - Keycloak IdP - 'auth'
BENTOV2_AUTH_IMAGE=ghcr.io/bento-platform/bento_keycloak_dist
BENTOV2_AUTH_VERSION=2024.09.26
BENTOV2_AUTH_VERSION=2024.11.22
BENTOV2_AUTH_CONTAINER_NAME=${BENTOV2_PREFIX}-auth
BENTO_AUTH_NETWORK=${BENTOV2_PREFIX}-auth-net
BENTOV2_AUTH_SERVICE_HOST=0.0.0.0
Expand Down Expand Up @@ -80,7 +80,7 @@ BENTO_AUTH_DB_NETWORK="${BENTOV2_PREFIX}-auth-db-net"

# - Authz service
BENTO_AUTHZ_IMAGE=ghcr.io/bento-platform/bento_authorization_service
BENTO_AUTHZ_VERSION=0.10.1
BENTO_AUTHZ_VERSION=0.10.2
BENTO_AUTHZ_VERSION_DEV=${BENTO_AUTHZ_VERSION}-dev
BENTO_AUTHZ_CONTAINER_NAME=${BENTOV2_PREFIX}-authz
BENTO_AUTHZ_NETWORK=${BENTOV2_PREFIX}-authz-net
Expand All @@ -100,7 +100,7 @@ BENTO_AUTHZ_DB_MEM_LIM=1G
# Web
BENTO_WEB_CUSTOM_HEADER=
BENTOV2_WEB_IMAGE=ghcr.io/bento-platform/bento_web
BENTOV2_WEB_VERSION=6.0.0
BENTOV2_WEB_VERSION=6.1.0
BENTOV2_WEB_VERSION_DEV=${BENTOV2_WEB_VERSION}-dev
BENTOV2_WEB_CONTAINER_NAME=${BENTOV2_PREFIX}-web
BENTO_WEB_NETWORK=${BENTOV2_PREFIX}-web-net
Expand All @@ -112,7 +112,7 @@ BENTOV2_WEB_CPUS=2

# Drop-Box
BENTOV2_DROP_BOX_IMAGE=ghcr.io/bento-platform/bento_drop_box_service
BENTOV2_DROP_BOX_VERSION=1.1.10
BENTOV2_DROP_BOX_VERSION=1.1.11
BENTOV2_DROP_BOX_VERSION_DEV=${BENTOV2_DROP_BOX_VERSION}-dev
BENTOV2_DROP_BOX_CONTAINER_NAME=${BENTOV2_PREFIX}-drop-box
BENTO_DROP_BOX_NETWORK=${BENTOV2_PREFIX}-drop-box-net
Expand All @@ -126,7 +126,7 @@ BENTOV2_DROP_BOX_CPUS=3

# Service Registry
BENTOV2_SERVICE_REGISTRY_IMAGE=ghcr.io/bento-platform/bento_service_registry
BENTOV2_SERVICE_REGISTRY_VERSION=1.4.2
BENTOV2_SERVICE_REGISTRY_VERSION=1.4.3
BENTOV2_SERVICE_REGISTRY_VERSION_DEV=${BENTOV2_SERVICE_REGISTRY_VERSION}-dev
BENTOV2_SERVICE_REGISTRY_CONTAINER_NAME=${BENTOV2_PREFIX}-service-registry
BENTO_SERVICE_REGISTRY_NETWORK=${BENTOV2_PREFIX}-service-registry-net
Expand All @@ -140,7 +140,7 @@ BENTO_SERVICE_REGISTRY_URL=${BENTOV2_PUBLIC_URL}/api/service-registry

# Notification
BENTOV2_NOTIFICATION_IMAGE=ghcr.io/bento-platform/bento_notification_service
BENTOV2_NOTIFICATION_VERSION=3.1.6
BENTOV2_NOTIFICATION_VERSION=3.1.7
BENTOV2_NOTIFICATION_VERSION_DEV=${BENTOV2_NOTIFICATION_VERSION}-dev
BENTOV2_NOTIFICATION_CONTAINER_NAME=${BENTOV2_PREFIX}-notification
BENTO_NOTIFICATION_NETWORK=${BENTOV2_PREFIX}-notification-net
Expand All @@ -155,7 +155,7 @@ BENTOV2_NOTIFICATION_CPUS=2

# Aggregation
BENTOV2_AGGREGATION_IMAGE=ghcr.io/bento-platform/bento_aggregation_service
BENTOV2_AGGREGATION_VERSION=0.19.8
BENTOV2_AGGREGATION_VERSION=0.19.9
BENTOV2_AGGREGATION_VERSION_DEV=${BENTOV2_AGGREGATION_VERSION}-dev
BENTOV2_AGGREGATION_CONTAINER_NAME=${BENTOV2_PREFIX}-aggregation
BENTO_AGGREGATION_NETWORK=${BENTOV2_PREFIX}-aggregation-net
Expand All @@ -170,7 +170,7 @@ BENTOV2_AGGREGATION_CPUS=2

# Event-Relay
BENTOV2_EVENT_RELAY_IMAGE=ghcr.io/bento-platform/bento_event_relay
BENTOV2_EVENT_RELAY_VERSION=3.1.5
BENTOV2_EVENT_RELAY_VERSION=3.1.6
BENTOV2_EVENT_RELAY_VERSION_DEV=${BENTOV2_EVENT_RELAY_VERSION}-dev
BENTOV2_EVENT_RELAY_CONTAINER_NAME=${BENTOV2_PREFIX}-event-relay
BENTO_EVENT_RELAY_NETWORK=${BENTOV2_PREFIX}-event-relay-net
Expand All @@ -184,7 +184,7 @@ BENTOV2_EVENT_RELAY_CPUS=1
# Reference
# - Service
BENTO_REFERENCE_IMAGE=ghcr.io/bento-platform/bento_reference_service
BENTO_REFERENCE_VERSION=0.3.0
BENTO_REFERENCE_VERSION=0.3.2
BENTO_REFERENCE_VERSION_DEV=${BENTO_REFERENCE_VERSION}-dev
BENTO_REFERENCE_CONTAINER_NAME=${BENTOV2_PREFIX}-reference
BENTO_REFERENCE_NETWORK=${BENTOV2_PREFIX}-reference-net
Expand All @@ -206,7 +206,7 @@ BENTO_REFERENCE_DB_USER="reference_user"

# WES
BENTOV2_WES_IMAGE=ghcr.io/bento-platform/bento_wes
BENTOV2_WES_VERSION=0.14.5
BENTOV2_WES_VERSION=0.14.6
BENTOV2_WES_VERSION_DEV=${BENTOV2_WES_VERSION}-dev
BENTOV2_WES_CONTAINER_NAME=${BENTOV2_PREFIX}-wes
BENTO_WES_NETWORK=${BENTOV2_PREFIX}-wes-net
Expand All @@ -233,7 +233,7 @@ BENTOV2_WES_WORKFLOW_TIMEOUT=172800

# DRS
BENTOV2_DRS_IMAGE=ghcr.io/bento-platform/bento_drs
BENTOV2_DRS_VERSION=0.18.0
BENTOV2_DRS_VERSION=0.19.0
BENTOV2_DRS_VERSION_DEV=${BENTOV2_DRS_VERSION}-dev
BENTOV2_DRS_CONTAINER_NAME=${BENTOV2_PREFIX}-drs
BENTO_DRS_NETWORK=${BENTOV2_PREFIX}-drs-net
Expand Down Expand Up @@ -278,7 +278,7 @@ BENTOV2_KATSU_DB_CPUS=4

# Katsu
BENTOV2_KATSU_IMAGE=ghcr.io/bento-platform/katsu
BENTOV2_KATSU_VERSION=9.0.0
BENTOV2_KATSU_VERSION=9.1.0
BENTOV2_KATSU_VERSION_DEV=${BENTOV2_KATSU_VERSION}-dev
BENTOV2_KATSU_CONTAINER_NAME=${BENTOV2_PREFIX}-katsu
BENTO_KATSU_NETWORK=${BENTOV2_PREFIX}-katsu-net
Expand Down Expand Up @@ -325,7 +325,7 @@ BENTOV2_GOHAN_DATA_ROOT=${BENTO_FAST_DATA_DIR}/gohan

# -- API
BENTOV2_GOHAN_API_IMAGE=ghcr.io/bento-platform/gohan-api
BENTOV2_GOHAN_API_VERSION=5.0.2
BENTOV2_GOHAN_API_VERSION=6.0.0
BENTOV2_GOHAN_API_VERSION_DEV=${BENTOV2_GOHAN_API_VERSION}-dev

BENTOV2_GOHAN_API_CONTAINER_NAME=${BENTOV2_PREFIX}-gohan-api
Expand Down Expand Up @@ -358,7 +358,7 @@ BENTOV2_GOHAN_ES_USERNAME=elastic
# BENTOV2_GOHAN_ES_PASSWORD comes from default_config

BENTOV2_GOHAN_ES_IMAGE=ghcr.io/bento-platform/gohan-elasticsearch
BENTOV2_GOHAN_ES_VERSION=5.0.2
BENTOV2_GOHAN_ES_VERSION=6.0.0

BENTOV2_GOHAN_ES_CONTAINER_NAME=${BENTOV2_PREFIX}-gohan-elasticsearch
BENTO_GOHAN_ES_NETWORK=${BENTOV2_PREFIX}-gohan-elasticsearch-net
Expand Down Expand Up @@ -388,7 +388,7 @@ BENTOV2_GOHAN_PRIVATE_AUTHZ_URL=http://${BENTOV2_GOHAN_AUTHZ_OPA_CONTAINER_NAME}
# Bento-Public

BENTO_PUBLIC_IMAGE=ghcr.io/bento-platform/bento_public
BENTO_PUBLIC_VERSION=0.20.0
BENTO_PUBLIC_VERSION=0.22.0
BENTO_PUBLIC_VERSION_DEV=${BENTO_PUBLIC_VERSION}-dev
BENTO_PUBLIC_CONTAINER_NAME=${BENTOV2_PREFIX}-public
BENTO_PUBLIC_NETWORK=${BENTOV2_PREFIX}-public-net
Expand All @@ -408,7 +408,7 @@ BENTO_PUBLIC_PORTAL_URL=${BENTOV2_PORTAL_PUBLIC_URL}
BENTO_BEACON_CONTAINER_NAME=${BENTOV2_PREFIX}-beacon
BENTO_BEACON_NETWORK=${BENTOV2_PREFIX}-beacon-net
BENTO_BEACON_IMAGE=ghcr.io/bento-platform/bento_beacon
BENTO_BEACON_VERSION=0.16.0
BENTO_BEACON_VERSION=0.18.1
BENTO_BEACON_VERSION_DEV=${BENTO_BEACON_VERSION}-dev
BENTO_BEACON_INTERNAL_PORT=${BENTO_STD_SERVICE_INTERNAL_PORT}
BENTO_BEACON_EXTERNAL_PORT=5000
Expand Down Expand Up @@ -460,16 +460,16 @@ BENTO_MONITORING_NETWORK=${BENTOV2_PREFIX}-monitoring-net
BENTO_PRIVATE_GRAFANA_URL=${BENTOV2_PORTAL_PUBLIC_URL}/api/grafana
BENTO_PUBLIC_GRAFANA_URL=${BENTOV2_PORTAL_PUBLIC_URL}/grafana
BENTO_LOKI_IMAGE=grafana/loki
BENTO_LOKI_IMAGE_VERSION=3.1.1
BENTO_LOKI_IMAGE_VERSION=3.1.2
BENTO_LOKI_CONTAINER_NAME=${BENTOV2_PREFIX}-loki
BENTO_LOKI_TEMP_DIR=${BENTO_SLOW_DATA_DIR}/loki/tmp
BENTO_GRAFANA_IMAGE=grafana/grafana
BENTO_GRAFANA_IMAGE_VERSION=11.1.5
BENTO_GRAFANA_IMAGE_VERSION=11.1.8
BENTO_GRAFANA_CONTAINER_NAME=${BENTOV2_PREFIX}-grafana
BENTO_GRAFANA_LIB_DIR=${BENTO_SLOW_DATA_DIR}/grafana/lib
# JMESPath to recover the user's role from the ID token
BENTO_GRAFANA_ROLE_ATTRIBUTE_PATH="contains(resource_access.grafana.roles[*], 'admin') && 'Admin' || contains(resource_access.grafana.roles[*], 'editor') && 'Editor' || contains(resource_access.grafana.roles[*], 'viewer') && 'Viewer' || 'None'"
BENTO_GRAFANA_SIGNOUT_REDIRECT_URL=https://${BENTOV2_AUTH_DOMAIN}/realms/${BENTOV2_AUTH_REALM}/protocol/openid-connect/logout?post_logout_redirect_uri=https%3A%2F%2F${BENTOV2_PORTAL_DOMAIN}%2Fapi%2Fgrafana%2Flogin
BENTO_PROMTAIL_IMAGE=grafana/promtail
BENTO_PROMTAIL_IMAGE_VERSION=2.9.10
BENTO_PROMTAIL_IMAGE_VERSION=3.1.2
BENTO_PROMTAIL_CONTAINER_NAME=${BENTOV2_PREFIX}-promtail
9 changes: 4 additions & 5 deletions etc/bento_post_config.bash
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#!/usr/bin/env bash

if [[ "$BENTO_GATEWAY_USE_TLS" == 'true' || "$BENTO_GATEWAY_USE_TLS" == '1' ]]; then
KC_HOSTNAME_STRICT_HTTPS='true'
KC_HOSTNAME=${BENTOV2_AUTH_DOMAIN}
KC_HTTP_ENABLED='false'
KC_HTTPS_CERTIFICATE_FILE=/run/secrets/keycloak-cert-file
KC_HTTPS_CERTIFICATE_KEY_FILE=/run/secrets/keycloak-cert-key-file
KC_PROXY='passthrough'
else
# Disable TLS in keycloak
KC_HOSTNAME_STRICT_HTTPS='false'
KC_HTTP_ENABLED='true'
KC_PROXY='edge'
KC_HOSTNAME=https://${BENTOV2_AUTH_DOMAIN} # full URL with HTTPS when KC_HTTP_ENABLED=true
KC_HTTP_ENABLED='true' # Required for TLS termination at the proxy
KC_PROXY_HEADERS=xforwarded # xforwarded (non-standard) instead of forwarded (RFC7239) for NGINX compatibility
fi
7 changes: 3 additions & 4 deletions lib/auth/docker-compose.auth.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,18 @@ services:
- KC_DB_URL=jdbc:postgresql://${BENTO_AUTH_DB_CONTAINER_NAME}:5432/${BENTO_AUTH_DB}
- KC_DB_USERNAME=${BENTO_AUTH_DB_USER}
- KC_DB_PASSWORD=${BENTO_AUTH_DB_PASSWORD}
- KC_HOSTNAME=${BENTOV2_AUTH_DOMAIN}
# the below environment variables are set up in etc/bento_post_config.bash based on the value of the
# BENTO_GATEWAY_USE_TLS environment variable.
- KC_HOSTNAME_STRICT_HTTPS
- KC_HOSTNAME
- KC_HTTP_ENABLED
- KC_HTTPS_CERTIFICATE_FILE
- KC_HTTPS_CERTIFICATE_KEY_FILE
- KC_PROXY
- KC_PROXY_HEADERS
mem_limit: ${BENTOV2_AUTH_MEM_LIM} # for mem_limit to work, make sure docker-compose is v2.4
cpus: ${BENTOV2_AUTH_CPUS}
cpu_shares: 512
healthcheck:
test: [ "CMD", "curl", "https://localhost:8443", "-k" ]
test: [ "CMD", "bash", "/healthcheck.bash" ]
timeout: ${BENTO_HEALTHCHECK_TIMEOUT}
# interval: ${BENTO_HEALTHCHECK_INTERVAL}
# For Docker <25 and Compose <2.24.x, start_interval doesn't work - use a shorter interval for now
Expand Down
1 change: 1 addition & 0 deletions lib/beacon/docker-compose.beacon.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ services:
- BENTO_BEACON_UI_ENABLED
- BENTO_BEACON_NETWORK_ENABLED
- DRS_URL=${BENTO_DRS_URL}
- REFERENCE_URL=${BENTOV2_PUBLIC_URL}/api/reference
# Authorization
- BENTO_AUTHZ_SERVICE_URL
- BENTO_OPENID_CONFIG_URL
Expand Down
Loading

0 comments on commit 0cd6dcf

Please sign in to comment.