[Feature] Advertises a STUN port different from the one it listens on #1063

Closed
opened 2025-12-29 02:28:03 +01:00 by adam · 2 comments
Owner

Originally created by @Kromtar on GitHub (Jul 13, 2025).

Use case

There are scenarios where the embedded DERP server is deployed behind a reverse proxy.

For the DERP port, it's currently possible to advertise a different port than the one used for local listening by configuring server_url and listen_addr. Example:

server_url: https://mysite.com:443
listen_addr: 127.0.0.1:5555

However, this is not possible for the STUN protocol port. When setting stun_listen_addr, that port is used both for local listening and as the advertised port to peers.

Description

This requirement arises from the need to run Headscale and the embedded DERP server behind a reverse proxy.
When using a reverse proxy, it's common to redirect traffic from a public-facing port to different local ports where the services are actually running.

This setup works well for both the Headscale server and the DERP component of the embedded server by configuring different ports using server_url and listen_addr.

However, the same cannot be achieved with the STUN server included in the embedded DERP server, as it lacks the ability to separate the advertised port from the local listening port.

Contribution

  • I can write the design doc for this feature
  • I can contribute this feature

How can it be implemented?

This feature is already implemented in my fork.

It adds a new optional configuration field to the embedded DERP server called stun_advertised_port.
When defined, this port will be used in the DERP region generation (i.e., advertised to peers), instead of the one specified in stun_listen_addr. The stun_listen_addr will then be used only for local packet listening.

This implementation does not change the current usage of stun_listen_addr, so it remains compatible with existing configuration files. If stun_advertised_port is not defined, the port from stun_listen_addr will continue to be used for both advertising and local listening.

Originally created by @Kromtar on GitHub (Jul 13, 2025). ### Use case There are scenarios where the embedded DERP server is deployed behind a reverse proxy. For the DERP port, it's currently possible to advertise a different port than the one used for local listening by configuring `server_url` and `listen_addr`. Example: ``` server_url: https://mysite.com:443 listen_addr: 127.0.0.1:5555 ``` However, this is not possible for the STUN protocol port. When setting `stun_listen_addr`, that port is used both for local listening and as the advertised port to peers. ### Description This requirement arises from the need to run Headscale and the embedded DERP server behind a reverse proxy. When using a reverse proxy, it's common to redirect traffic from a public-facing port to different local ports where the services are actually running. This setup works well for both the Headscale server and the DERP component of the embedded server by configuring different ports using `server_url` and `listen_addr`. However, the same cannot be achieved with the STUN server included in the embedded DERP server, as it lacks the ability to separate the advertised port from the local listening port. ### Contribution - [x] I can write the design doc for this feature - [x] I can contribute this feature ### How can it be implemented? This feature is already implemented in [my fork](https://github.com/Kromtar/headscale/tree/feat/promote-stun-port). It adds a new optional configuration field to the embedded DERP server called `stun_advertised_port`. When defined, this port will be used in the DERP region generation (i.e., advertised to peers), instead of the one specified in `stun_listen_addr`. The `stun_listen_addr` will then be used only for local packet listening. This implementation does not change the current usage of `stun_listen_addr`, so it remains compatible with existing configuration files. If `stun_advertised_port` is not defined, the port from `stun_listen_addr` will continue to be used for both advertising and local listening.
adam added the enhancementstaleDERP labels 2025-12-29 02:28:03 +01:00
adam closed this issue 2025-12-29 02:28:03 +01:00
Author
Owner

@github-actions[bot] commented on GitHub (Nov 14, 2025):

This issue is stale because it has been open for 90 days with no activity.

@github-actions[bot] commented on GitHub (Nov 14, 2025): This issue is stale because it has been open for 90 days with no activity.
Author
Owner

@github-actions[bot] commented on GitHub (Nov 22, 2025):

This issue was closed because it has been inactive for 14 days since being marked as stale.

@github-actions[bot] commented on GitHub (Nov 22, 2025): This issue was closed because it has been inactive for 14 days since being marked as stale.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/headscale#1063