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