When hosting Password Pusher behind a reverse proxy (such as Nginx, Apache, Cloudflare, or others), you can take advantage of the proxy’s features for SSL/TLS termination, load balancing, rate limiting, and enhanced security.

Overview

A common issue when using Password Pusher behind a proxy is that generated push URLs are incorrect. Instead of using the public URL (e.g., https://pwpush.example.com), the application may generate URLs with:

  • The backend server address (e.g., http://localhost:5100)
  • The wrong protocol (HTTP instead of HTTPS)
  • The wrong port number
  • The internal hostname

This happens because Password Pusher needs to know the original request details (host, protocol, port) that the client used to reach the proxy, not the internal connection between the proxy and the application.

Solution: Proxy Headers

Password Pusher uses standard X-Forwarded-* headers to determine the original client request. Your proxy must forward these headers to the application.

Required Headers

Your proxy should forward these headers:

  • X-Forwarded-Host - The original hostname from the client request
  • X-Forwarded-Proto - The original protocol (http or https)
  • X-Forwarded-Port - The original port (optional, but recommended)

Optional but useful:

  • X-Forwarded-For - The original client IP address
  • X-Real-IP - Alternative header for client IP

Proxy Configuration Examples

Nginx

For Nginx, add these headers to your location block:

location / {
    proxy_pass http://pwpush:5100;
    proxy_http_version 1.1;

    # Required headers
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $server_port;

    # Optional but recommended
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;

    # Connection settings
    proxy_set_header Connection "";
    proxy_read_timeout 3600;
}

Apache

For Apache with mod_proxy, add these headers in your VirtualHost or .htaccess:

ProxyPreserveHost On
ProxyPass / http://localhost:5100/
ProxyPassReverse / http://localhost:5100/

# Required headers
RequestHeader set X-Forwarded-Host "%{HTTP_HOST}e"
RequestHeader set X-Forwarded-Proto "%{REQUEST_SCHEME}e"
RequestHeader set X-Forwarded-Port "%{SERVER_PORT}e"
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}e"

Caddy

Caddy automatically forwards proxy headers, but you can explicitly configure them:

pwpush.example.com {
    reverse_proxy localhost:5100 {
        header_up X-Forwarded-Host {host}
        header_up X-Forwarded-Proto {scheme}
        header_up X-Forwarded-Port {port}
        header_up X-Real-IP {remote}
    }
}

Traefik

Traefik automatically adds forward headers. Ensure your service configuration includes:

services:
  pwpush:
    labels:
      - "traefik.http.services.pwpush.loadbalancer.server.port=5100"
      - "traefik.http.routers.pwpush.rule=Host(`pwpush.example.com`)"
      - "traefik.http.routers.pwpush.entrypoints=websecure"
      - "traefik.http.routers.pwpush.tls.certresolver=letsencrypt"

Traefik automatically forwards X-Forwarded-* headers.

Cloudflare

If using Cloudflare as your proxy, see the Cloudflare Proxy section below for automatic IP configuration.

Alternative: Override Base URL

If you cannot configure your proxy to forward the required headers, or if you need to force a specific base URL regardless of proxy headers, you can use the PWP__OVERRIDE_BASE_URL environment variable.

When to Use OVERRIDE_BASE_URL

Use PWP__OVERRIDE_BASE_URL when:

  • Your proxy cannot forward X-Forwarded-* headers
  • You need to force a specific URL regardless of request headers
  • You’re using complex proxy chains where headers might be lost
  • You want a simple, explicit configuration

Note: When PWP__OVERRIDE_BASE_URL is set, it takes precedence over proxy headers. All generated URLs will use this base URL.

Configuration

Set the environment variable (without a trailing slash):

# Docker Compose
environment:
  PWP__OVERRIDE_BASE_URL: 'https://pwpush.example.com'
# Environment variable
export PWP__OVERRIDE_BASE_URL='https://pwpush.example.com'

Examples:

  • https://pwpush.example.com
  • https://pwpush.example.com:8443 (if using non-standard port)
  • https://pwpush.example.com/ (trailing slash not allowed)

Trusted Proxies

By default, Password Pusher only trusts proxy headers from requests originating on the local network (127.0.0.1, ::1, and private IP ranges). This is a security feature to prevent header spoofing attacks.

When to Configure Trusted Proxies

You need to configure trusted proxies if:

  • Your proxy is on a different server (not localhost)
  • You’re using a cloud-based proxy (Cloudflare, AWS CloudFront, etc.)
  • Your proxy is in a different network segment
  • You’re using a load balancer or CDN

Why Trusted Proxies Matter:

This setting ensures that only requests from trusted proxy IP addresses are allowed to set X-Forwarded-* headers. Without this, an attacker could spoof these headers to:

  • Make the application generate incorrect URLs
  • Potentially bypass security checks
  • Cause redirect loops or other issues

Configuration Methods

Set PWP__TRUSTED_PROXIES with a comma-separated list of IP addresses:

# Single IP
PWP__TRUSTED_PROXIES='1.2.3.4'

# Multiple IPs
PWP__TRUSTED_PROXIES='1.2.3.4,2.3.4.5,3.4.5.6'

Docker Compose example:

environment:
  PWP__TRUSTED_PROXIES: '1.2.3.4,2.3.4.5'

Method 2: settings.yml File

Add to your settings.yml:

trusted_proxies:
  - '1.2.3.4'
  - '2.3.4.5'
  - '3.4.5.6'

Finding Your Proxy IP Addresses

For Cloud-based proxies:

  • Check your proxy/CDN provider’s documentation for their IP ranges
  • Many providers publish their IP ranges (see Cloudflare section below)

For self-hosted proxies:

  • Use the proxy server’s IP address
  • If using Docker, use the container’s IP or service name (if on same network)

For load balancers:

  • Check your cloud provider’s documentation for load balancer IP ranges
  • AWS, Azure, and GCP publish their IP ranges

Cloudflare Proxy

If you’re using Cloudflare as your proxy/CDN, Password Pusher can automatically fetch and configure Cloudflare’s IP ranges.

Automatic Cloudflare IP Configuration

Instead of manually adding Cloudflare IPs, you can enable automatic fetching:

# Docker Compose
environment:
  PWP__CLOUDFLARE_PROXY: 'true'
# Environment variable
export PWP__CLOUDFLARE_PROXY='true'

How it works:

  • On application startup, Password Pusher fetches Cloudflare’s current IPv4 and IPv6 IP ranges
  • These IPs are automatically added to the trusted proxies list
  • IP ranges are fetched from Cloudflare’s official endpoints:
    • https://www.cloudflare.com/ips-v4
    • https://www.cloudflare.com/ips-v6

Note: This adds a small delay (up to 15 seconds per request) on application startup while fetching IPs. The requests have a 15-second timeout each.

Manual Cloudflare Configuration

If you prefer to manually configure Cloudflare IPs, you can find the current ranges at:

  • IPv4: https://www.cloudflare.com/ips-v4
  • IPv6: https://www.cloudflare.com/ips-v6

Then add them to PWP__TRUSTED_PROXIES or settings.yml as shown above.

Recommendation: Use PWP__CLOUDFLARE_PROXY=true for automatic updates, or manually update IPs periodically if Cloudflare changes their ranges.

Troubleshooting

Generated URLs are incorrect

Symptoms:

  • Push URLs show http://localhost:5100 instead of https://pwpush.example.com
  • URLs use HTTP instead of HTTPS
  • URLs include wrong port numbers

Solutions:

  1. Verify proxy headers are being forwarded:
    • Check your proxy configuration includes X-Forwarded-Host, X-Forwarded-Proto, and X-Forwarded-Port
    • Test by checking request headers in Password Pusher logs
  2. Check trusted proxies:
    • Ensure your proxy’s IP is in the trusted proxies list
    • For remote proxies, you must explicitly add them
  3. Use OVERRIDE_BASE_URL:
    • If headers aren’t working, set PWP__OVERRIDE_BASE_URL as a fallback

Headers not being accepted

Symptoms:

  • Proxy headers are configured but ignored
  • Application still uses backend URL

Solutions:

  1. Verify trusted proxies:
    • Check that your proxy IP is in the trusted proxies list
    • For Cloudflare, enable PWP__CLOUDFLARE_PROXY=true
  2. Check header format:
    • Ensure headers are set correctly (case-sensitive)
    • Verify headers are reaching the application (check logs)
  3. Network connectivity:
    • Ensure the proxy can reach the application
    • Check firewall rules allow proxy → application communication

Cloudflare IPs not loading

Symptoms:

  • Cloudflare proxy enabled but IPs not trusted
  • Application startup delays

Solutions:

  1. Check network connectivity:
    • Application must be able to reach https://www.cloudflare.com on startup
    • Verify DNS resolution works
  2. Check logs:
    • Look for warnings about failed Cloudflare IP fetches
    • Timeout errors indicate network issues
  3. Manual fallback:
    • If automatic fetching fails, manually add Cloudflare IPs to trusted proxies

Best Practices

  1. Use proxy headers when possible: More flexible than OVERRIDE_BASE_URL
  2. Configure trusted proxies: Always set for remote proxies
  3. Use Cloudflare auto-config: Enable PWP__CLOUDFLARE_PROXY if using Cloudflare
  4. Test URL generation: Create a test push and verify the URL is correct
  5. Monitor logs: Check for proxy-related warnings or errors
  6. Keep IPs updated: If manually configuring, update when proxy IPs change

See Also

Updated: