Proxies & Password Pusher
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 requestX-Forwarded-Proto- The original protocol (httporhttps)X-Forwarded-Port- The original port (optional, but recommended)
Optional but useful:
X-Forwarded-For- The original client IP addressX-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
Method 1: Environment Variable (Recommended)
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-v4https://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:5100instead ofhttps://pwpush.example.com - URLs use HTTP instead of HTTPS
- URLs include wrong port numbers
Solutions:
- Verify proxy headers are being forwarded:
- Check your proxy configuration includes
X-Forwarded-Host,X-Forwarded-Proto, andX-Forwarded-Port - Test by checking request headers in Password Pusher logs
- Check your proxy configuration includes
- Check trusted proxies:
- Ensure your proxy’s IP is in the trusted proxies list
- For remote proxies, you must explicitly add them
- Use OVERRIDE_BASE_URL:
- If headers aren’t working, set
PWP__OVERRIDE_BASE_URLas a fallback
- If headers aren’t working, set
Headers not being accepted
Symptoms:
- Proxy headers are configured but ignored
- Application still uses backend URL
Solutions:
- Verify trusted proxies:
- Check that your proxy IP is in the trusted proxies list
- For Cloudflare, enable
PWP__CLOUDFLARE_PROXY=true
- Check header format:
- Ensure headers are set correctly (case-sensitive)
- Verify headers are reaching the application (check logs)
- 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:
- Check network connectivity:
- Application must be able to reach
https://www.cloudflare.comon startup - Verify DNS resolution works
- Application must be able to reach
- Check logs:
- Look for warnings about failed Cloudflare IP fetches
- Timeout errors indicate network issues
- Manual fallback:
- If automatic fetching fails, manually add Cloudflare IPs to trusted proxies
Best Practices
- Use proxy headers when possible: More flexible than
OVERRIDE_BASE_URL - Configure trusted proxies: Always set for remote proxies
- Use Cloudflare auto-config: Enable
PWP__CLOUDFLARE_PROXYif using Cloudflare - Test URL generation: Create a test push and verify the URL is correct
- Monitor logs: Check for proxy-related warnings or errors
- Keep IPs updated: If manually configuring, update when proxy IPs change
See Also
- Installation Guide - Learn how to set up Password Pusher
- Configuration Strategies - How to set environment variables
- Nginx Configuration Example - Nginx setup guide
- Public Gateway - Using proxies with the public gateway container