Skip to content

Support per-HTTP-tracker on_reverse_proxy setting #1640

@josecelano

Description

@josecelano

Summary

The [core.net].on_reverse_proxy configuration option is currently global and applies to all HTTP trackers. This creates a limitation when deploying mixed configurations where some HTTP trackers are behind a reverse proxy while others are accessed directly.

Problem Description

When using a reverse proxy (like Caddy or nginx) for TLS termination on some HTTP trackers, we need on_reverse_proxy = true for those trackers to correctly read the X-Forwarded-For header and identify real client IPs.

However, the current configuration only allows:

[core.net]
on_reverse_proxy = true  # Applies to ALL HTTP trackers

This means we cannot have:

  • Trackers on ports 7070, 7071 behind a reverse proxy (need on_reverse_proxy = true)
  • Tracker on port 7072 accessed directly (needs on_reverse_proxy = false)

How We Discovered This

While implementing HTTPS support with Caddy as a TLS-terminating reverse proxy in the Torrust Tracker Deployer (PR #273), we encountered this limitation.

Our use case involves deploying multiple HTTP trackers where some are exposed via HTTPS through Caddy (TLS termination) while others are exposed directly via HTTP.

Impact

When on_reverse_proxy = true globally:

  • All HTTP trackers expect X-Forwarded-For headers
  • Trackers accessed directly (without proxy) fail to identify client IPs correctly

When on_reverse_proxy = false globally:

  • All HTTP trackers ignore X-Forwarded-For headers
  • Trackers behind a proxy see the proxy's IP as the client IP
  • All peers appear to come from the same IP (the proxy), breaking peer identification

Current workaround in deployer:

If ANY HTTP tracker uses a TLS proxy, ALL HTTP trackers must use the TLS proxy.

This reduces deployment flexibility significantly.

Proposed Solution

Add an optional on_reverse_proxy field to each HTTP tracker configuration:

[core.net]
on_reverse_proxy = false  # Default for trackers without explicit setting

[[http_trackers]]
bind_address = "0.0.0.0:7070"
on_reverse_proxy = true  # Override: this tracker is behind a proxy

[[http_trackers]]
bind_address = "0.0.0.0:7071"
on_reverse_proxy = true  # Override: this tracker is behind a proxy

[[http_trackers]]
bind_address = "0.0.0.0:7072"
# No override: uses global default (false) - direct access

Behavior

  1. If on_reverse_proxy is specified on an HTTP tracker, use that value
  2. If not specified, fall back to [core.net].on_reverse_proxy (backward compatible)
  3. Each HTTP tracker independently decides whether to read X-Forwarded-For

Use Cases Enabled

  1. Mixed TLS/non-TLS deployment: Some trackers via HTTPS (Caddy/nginx), some via direct HTTP
  2. Internal monitoring: Direct localhost tracker for Prometheus, proxied trackers for public access
  3. Gradual migration: Move trackers behind proxy one at a time
  4. Multi-tenant: Different trackers for different networks with different proxy configurations

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions