mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-05-06 08:47:18 +00:00
Co-authored-by: Boon <boon@security8.work>
This commit is contained in:
@@ -0,0 +1,64 @@
|
|||||||
|
# Prowler Reverse Proxy Configuration
|
||||||
|
|
||||||
|
Ready-to-use nginx configuration for running Prowler behind a reverse proxy.
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
Prowler's default Docker setup exposes two separate services:
|
||||||
|
- **UI** on port 3000
|
||||||
|
- **API** on port 8080
|
||||||
|
|
||||||
|
This causes CORS issues and authentication failures (especially SAML SSO) when accessed through an external reverse proxy, since the proxy typically exposes a single domain.
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
This adds an nginx container that unifies both services behind a single port, correctly forwarding headers so that Django generates proper URLs for SAML ACS callbacks and API responses.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
From the prowler root directory:
|
||||||
|
|
||||||
|
docker compose -f docker-compose.yml \
|
||||||
|
-f contrib/reverse-proxy/docker-compose.reverse-proxy.yml \
|
||||||
|
up -d
|
||||||
|
|
||||||
|
Access Prowler at http://localhost (port 80).
|
||||||
|
|
||||||
|
## With an External Reverse Proxy
|
||||||
|
|
||||||
|
Point your external reverse proxy to the prowler-nginx container on port 80.
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| PROWLER_PROXY_PORT | 80 | Port exposed by the nginx proxy |
|
||||||
|
|
||||||
|
### Example: Traefik
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.prowler.rule=Host(`prowler.example.com`)"
|
||||||
|
- "traefik.http.routers.prowler.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.prowler.loadbalancer.server.port=80"
|
||||||
|
|
||||||
|
### Example: Caddy
|
||||||
|
|
||||||
|
prowler.example.com {
|
||||||
|
reverse_proxy prowler-nginx:80
|
||||||
|
}
|
||||||
|
|
||||||
|
## SAML SSO
|
||||||
|
|
||||||
|
If using SAML SSO behind a reverse proxy, also set the SAML_ACS_BASE_URL environment variable:
|
||||||
|
|
||||||
|
SAML_ACS_BASE_URL=https://prowler.example.com
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
Internet -> External Reverse Proxy -> prowler-nginx:80
|
||||||
|
|-- /api/* -> prowler-api:8080
|
||||||
|
|-- /accounts/saml/ -> prowler-api:8080
|
||||||
|
+-- /* -> prowler-ui:3000
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Prowler Reverse Proxy - Docker Compose Override
|
||||||
|
#
|
||||||
|
# Use this alongside the main docker-compose.yml to add an nginx
|
||||||
|
# reverse proxy that unifies UI and API behind a single port.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# docker compose -f docker-compose.yml -f contrib/reverse-proxy/docker-compose.reverse-proxy.yml up -d
|
||||||
|
#
|
||||||
|
# Then access Prowler at http://localhost (port 80) or configure
|
||||||
|
# your external reverse proxy (Traefik, Caddy, Cloudflare Tunnel,
|
||||||
|
# Pangolin, etc.) to point to this container on port 80.
|
||||||
|
#
|
||||||
|
# For HTTPS with your own certs, see the README in this directory.
|
||||||
|
#
|
||||||
|
# Fixes: https://github.com/prowler-cloud/prowler/issues/8516
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: prowler-nginx
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${PROWLER_PROXY_PORT:-80}:80"
|
||||||
|
volumes:
|
||||||
|
- ./contrib/reverse-proxy/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
depends_on:
|
||||||
|
- prowler-ui
|
||||||
|
- prowler-api
|
||||||
|
networks:
|
||||||
|
- prowler-network
|
||||||
|
|
||||||
|
# Override UI to not expose port externally (nginx handles it)
|
||||||
|
prowler-ui:
|
||||||
|
ports: !reset []
|
||||||
|
|
||||||
|
# Override API to not expose port externally (nginx handles it)
|
||||||
|
prowler-api:
|
||||||
|
ports: !reset []
|
||||||
|
|
||||||
|
networks:
|
||||||
|
prowler-network:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# Prowler Reverse Proxy Configuration
|
||||||
|
# Routes both UI and API through a single endpoint
|
||||||
|
#
|
||||||
|
# Usage: See docker-compose.reverse-proxy.yml
|
||||||
|
# Fixes: https://github.com/prowler-cloud/prowler/issues/8516
|
||||||
|
|
||||||
|
upstream prowler-ui {
|
||||||
|
server prowler-ui:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream prowler-api {
|
||||||
|
server prowler-api:8080;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||||
|
|
||||||
|
# API requests — proxy to prowler-api
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://prowler-api/api/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
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_read_timeout 300s;
|
||||||
|
proxy_connect_timeout 10s;
|
||||||
|
|
||||||
|
# Handle large scan payloads
|
||||||
|
client_max_body_size 50m;
|
||||||
|
}
|
||||||
|
|
||||||
|
# SAML endpoints — proxy to prowler-api
|
||||||
|
location /accounts/saml/ {
|
||||||
|
proxy_pass http://prowler-api/accounts/saml/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Everything else — proxy to prowler-ui
|
||||||
|
location / {
|
||||||
|
proxy_pass http://prowler-ui/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# WebSocket support for Next.js HMR (dev) and live updates
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "ok\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user