torrust-tracker icon indicating copy to clipboard operation
torrust-tracker copied to clipboard

Add support for dynamic external ip in the config

Open mickvandijke opened this issue 2 years ago • 8 comments

IP Addresses can change over time, so it would be useful for tracker operators if they could set a dynamic DNS as external IP. Currently the external_ip config option only supports an IP address.

mickvandijke avatar Aug 26 '22 16:08 mickvandijke

I have put some more thought into this. It might be easier to replace the external_ip: IpAddress config option with replace_local_Ip_with_external_ip: bool. If this is enabled, the tracker will resolve the external ip using a public API such as https://www.ipify.org/ . And then when a peer announces with a local ip address (such as 192.168.X.X or 127.0.0.1), the local ip gets replaced with the resolved external ip address from https://www.ipify.org/ .

mickvandijke avatar Aug 31 '22 18:08 mickvandijke

Hey @WarmBeer,

Let me try and comprehend this.

Currently we have the config option:

external_ip: Option<String>,

You propose to have:

external_ipv4: Option<Ipv4Addr>,
replace_local_peer_ip_with_external_ip: bool,
  1. What is the current behavior when the optional external_ip is empty?
  2. What is the current behavior when external_ip is a ipv6 address?
  3. What is the behavior when external_ipv4 is empty and replace_local_peer_ip_with_external_ip is false?

And then when a peer announces with a local ip address (such as 192.168.X.X or 127.0.0.1), the local ip gets replaced with the resolved external ip address from https://www.ipify.org/ .

How dose a peer make an announcement with a local or loopback IP? But we replace it with the trackers external ip?

da2ce7 avatar Sep 02 '22 16:09 da2ce7

Hey @WarmBeer,

Let me try and comprehend this.

Currently we have the config option:

external_ip: Option<String>,

You propose to have:

external_ipv4: Option<Ipv4Addr>,
replace_local_peer_ip_with_external_ip: bool,
  1. What is the current behavior when the optional external_ip is empty?
  2. What is the current behavior when external_ip is a ipv6 address?
  3. What is the behavior when external_ipv4 is empty and replace_local_peer_ip_with_external_ip is false?

And then when a peer announces with a local ip address (such as 192.168.X.X or 127.0.0.1), the local ip gets replaced with the resolved external ip address from https://www.ipify.org/ .

How dose a peer make an announcement with a local or loopback IP? But we replace it with the trackers external ip?

Hey @da2ce7 ,

Currently we have the option external_ip in the config which can be an Ipv4 or Ipv6 address, or nothing at all. If external_ip is set, every peer that announces from the same network as the tracker will have their IP replaced with the external_ip set in the config.

What I'm proposing is instead of setting the external_ip manually, we replace external_ip with another option called replace_local_peer_ip_with_external_ip which can be set to true or false.

when replace_local_peer_ip_with_external_ip is set to true, the tracker will resolve the external Ipv4 address using https://www.ipify.org/ and stores this in the running application. The benefit of this is that the tracker operator does not have to set the external IP manually, since it can change over time. If a peer then announces with an IP that matches 192.168.X.X or 127.0.0.1, the peer address gets replaced with the earlier stored external Ipv4 address.

mickvandijke avatar Sep 02 '22 18:09 mickvandijke

Okay, so if you have a peer on the same host or local network as the tracker, the server will see a local or loop-back address from this peer. (the peer doesn't choose their own IP, it is the IP that the server observes that counts?) I.e. the remote_address, correct.

What is the current behavior when the optional external_ip is empty?

It just uses and shares the local or loop-back address?

What is the behavior when external_ipv4 is empty and replace_local_peer_ip_with_external_ip is false?

Same as current behavior?

external_ip in the config which can be an Ipv4 or Ipv6 address

What happened if the external_ip set an IPv4 address, but the server observes to peer to have a local or loop-back IPv6 address? (or the other way around) do you replace it with the IPv4 address?

Does the server replace internal IPv6 addresses with looked-up external IPv6 or external IPv4 address?

da2ce7 avatar Sep 03 '22 04:09 da2ce7

Okay, so if you have a peer on the same host or local network as the tracker, the server will see a local or loop-back address from this peer. (the peer doesn't choose their own IP, it is the IP that the server observes that counts?) I.e. the remote_address, correct.

Correct.

What is the current behavior when the optional external_ip is empty? It just uses and shares the local or loop-back address?

Yes, it will just list the peer with the local or loopback ip.

What is the behavior when external_ipv4 is empty and replace_local_peer_ip_with_external_ip is false? Same as current behavior?

Yes, same as above.

What happened if the external_ip set an IPv4 address, but the server observes to peer to have a local or loop-back IPv6 address? (or the other way around) do you replace it with the IPv4 address?

In the current behaviour, every local or loopback address that is either Ipv6 or Ipv4 will be replaced by the ip set in external_ip. So it is possible that an Ipv6 loopback address gets replaced by an Ipv4 address and vice versa.

In the proposed behaviour, only Ipv4 local and loopback addresses will be swapped with the external_ipv4 address resolved if replace_local_peer_ip_with_external_ip is enabled. This is because Ipv6 does not actually use local addresses in the same way that Ipv4 does.

We could support Ipv6 by swapping ULA addresses: https://en.wikipedia.org/wiki/Unique_local_address . But I don't know if that is the right thing to do.

mickvandijke avatar Sep 03 '22 08:09 mickvandijke

hi @da2ce7 @WarmBeer,

In this PR I've added some tests for the current behavior.

I think the peer IP is replaced only if it's a loopback IP (both IPv4 to IPv6), not a local network IP.

  • Why should we replace the IP if the peer is using the loopback addresses?
  • What would be the use case? I suppose this only happens when you have the peer using the localhost IP announcing itself to a tracker which is supposed to be using the same external IP as the peer. Is that right?

josecelano avatar Sep 20 '22 13:09 josecelano

@da2ce7 @WarmBeer I'm working on another PR to add tests to the TorrentPeer constructor from the requests. This is where all this logic is implemented right now.

josecelano avatar Sep 21 '22 16:09 josecelano

Hi @WarmBeer, I do not like the idea of relying on an external service like https://www.ipify.org/.

I found this article https://dev.to/adityathebe/a-handy-way-to-know-your-public-ip-address-with-dns-servers-4nmn

And it seems you can get your public IP with the following:

# To know you public ipv4 address
dig +short myip.opendns.com @resolver1.opendns.com -4

# To know you public ipv6 address
dig +short AAAA myip.opendns.com @resolver1.opendns.com

But in the end, I think it's the same because you also rely on an external service.

If there is no other solution we should use at least two different services or even out the service URL in a settings option.

josecelano avatar Mar 16 '23 08:03 josecelano