Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: retry logic for fetching the public ip information #2325

Closed
ezekieldas opened this issue Jun 19, 2024 · 7 comments
Closed

Comments

@ezekieldas
Copy link

Is this urgent?

No

Host OS

Ubuntu 22.04.4 LTS

CPU arch

x86_64

VPN service provider

Custom

What are you using to run the container

docker-compose

What is the version of Gluetun

Running version latest built on 2024-06-17T22:37:52.988Z (commit 93ed87d)

What's the problem 🤔

The publicip endpoint is no longer functional:

# curl localhost:8000/v1/publicip/ip
{"public_ip":""}

I discovered this just recently. I have a control wrapper/application which does a regular automated request against that endpoint and stores the results.

I'm near certain, this is due to this commit: 4218dba

Again, I wish my Go skills and knowledge were better so that I might be able to offer an option.

With my configuration I'm running DNS (blocky) with gluetun (network_mode: "service:gluetun") so I don't expect the initial dns request to succeed. However, it would be nice if there were a latter request which would make the public address available.

I did a quick test against gluetun:v3 and found this was not the case with this release. I also applied the optional PUBLICIP_API=ip2location with both gluetun:v3 and gluetun:latest and found the issue consistent only with the more recent release.

Share your logs (at least 10 lines)

...
2024-06-19T07:25:33-07:00 INFO [wireguard] Wireguard setup is complete. Note Wireguard is a silent protocol and it may or may not work, without giving any error message. Typically i/o timeout errors indicate the Wireguard connection is not working.
2024-06-19T07:25:33-07:00 ERROR [vpn] getting public IP address information: fetching information: Get "https://api.ip2location.io/": dial tcp: lookup api.ip2location.io on 127.0.0.1:53: read udp 127.0.0.1:36706->127.0.0.1:53: read: connection refused
2024-06-19T07:25:33-07:00 ERROR [vpn] cannot get version information: Get "https://api.github.com/repos/qdm12/gluetun/commits": dial tcp: lookup api.github.com on 127.0.0.1:53: read udp 127.0.0.1:52976->127.0.0.1:53: read: connection refused
2024-06-19T07:25:35-07:00 INFO [healthcheck] healthy!
...


### Share your configuration

_No response_
Copy link
Contributor

@qdm12 is more or less the only maintainer of this project and works on it in his free time.
Please:

@qdm12
Copy link
Owner

qdm12 commented Jul 26, 2024

Hi there! Thanks for the detailed issue.
read udp 127.0.0.1:36706->127.0.0.1:53: read: connection refused - does that mean the DNS request is sent to blocky but is refused somehow?? Usually this happens because it's blocked by the firewall 🤔

so I don't expect the initial dns request to succeed

Why? 🤔

I'm trying to understand if this is solvable in some cleaner way, than wrapping the public ip information fetch in some retry logic. The public ip fetching is also triggered once the vpn is configured, so it should work, unless the VPN is not working at all.

The commit you mention is indeed likely the source of your problem, especially since it 'fixes'

  • Prevents requesting the public IP address N times after N VPN failures

@qdm12 qdm12 changed the title Bug: /v1/publicip/ip not returning ipaddr Bug: no retry logic for fetching the public ip address Jul 26, 2024
@qdm12 qdm12 changed the title Bug: no retry logic for fetching the public ip address Feature request: retry logic for fetching the public ip information Jul 26, 2024
@ezekieldas
Copy link
Author

ezekieldas commented Sep 6, 2024

So my configuration (docker-compose.yml below) involves blocky for DNS and this works quite well. However, there are times where gluetun has made a connection yet blocky is not yet available for resolution. I've tried variations using depends_on and was unable to find a better solution.

Nonetheless, the result is that gluetun will report "public_ip":"" even if resolution is available seconds later. For example, I have an instance running now that is functioning just fine yet /v1/publicip/ip continues to return empty result.

Would it be possible to retry this somehow that doesn't assume the vpn is failed (as in the commit mentioned above)?

docker-compose.yml
##
## https://github.com/qdm12/gluetun
##
services:
  gluetun:
    image: qmcgaw/gluetun:latest
    container_name: gluetun
    hostname: gluetun
    dns:
      - 127.0.0.1
    network_mode: bridge
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - 8000:8000/tcp # control server - https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md
      - 8008:8888/tcp # HTTP proxy - https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/http-proxy.md
      - 6666:9999/tcp # healthcheck - https://github.com/qdm12/gluetun-wiki/blob/main/faq/healthcheck.md#internal-healthcheck
      - 8053:53/tcp # blocky
      - 8053:53/udp # blocky
      - 9110:4000/tcp   # blocky prometheus exporter

      ##
      ## socks5 is used for ssh tunnelling and access to certain instances (eg, ultra)
      ##
      ## gluetun may include a plain socks5 proxy soon - for now this uses the service defined below
      ##  - https://github.com/qdm12/gluetun/issues/234
      ##
      - 1080:1080/tcp # socks5 proxy -  https://github.com/serjs/socks5-server

      - 8080:8080/tcp # searxng

    volumes:
      - /usr/local/docker/gluetun/gluetun_config:/gluetun
      - /usr/local/docker/gluetun/gluetun_config/post-rules.txt:/iptables/post-rules.txt

    sysctls:
      - net.ipv6.conf.all.disable_ipv6=1

    environment:
      # - LOG_LEVEL=debug
      - TZ=America/Los_Angeles
      #
      # https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/firewall.md
      #
      - FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24
      # - FIREWALL_DEBUG=on
      #
      # https://github.com/qdm12/gluetun/issues/2047
      #
      ### - PUBLICIP_API=ip2location
      #
      # healthcheck - https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/healthcheck.md
      #
      - HEALTH_TARGET_ADDRESS=1.1.1.1:443
      - HEALTH_VPN_DURATION_INITIAL=10s
      - HEALTH_VPN_DURATION_ADDITION=7s
      - HEALTH_SUCCESS_WAIT_DURATION=7s
      - HEALTH_SERVER_ADDRESS=0.0.0.0:9999
      #
      # providers - https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers
      #
      - VPN_TYPE=wireguard
      - VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER}
      # - SERVER_COUNTRIES=${SERVER_COUNTRIES}
      - SERVER_CITIES=${SERVER_CITIES}
      - WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY}
      - WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES}
      - VPN_ENDPOINT_PORT=${VPN_ENDPOINT_PORT}
      #
      # server list update - https://github.com/qdm12/gluetun-wiki/blob/main/setup/servers.md#update-the-vpn-servers-list
      #
      - UPDATER_PERIOD=3h
      - UPDATER_VPN_SERVICE_PROVIDERS="mullvad,ivpn"
      #
      # http proxy - https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/http-proxy.md
      #
      - HTTPPROXY=on
      - HTTPPROXY_STEALTH=on
      #
      # DNS
      # https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/dns.md
      #
      - DOT=off
      - DNS_KEEP_NAMESERVER=on

    restart: always

  blocky:
    image: spx01/blocky
    container_name: blocky
    #
    # https://github.com/0xERR0R/blocky/discussions/1417
    #
    network_mode: "service:gluetun"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./blocky_config/config.yml:/app/config.yml
      - ./blocky_config/local.blocks.txt:/app/local.blocks.txt
      - ./blocky_config/local.allow.txt:/app/local.allow.txt

    restart: always

  socks5:
    image: serjs/go-socks5-proxy
    container_name: socks5
    network_mode: "service:gluetun"
    restart: always

  searxng:
    container_name: searxng
    image: searxng/searxng:latest
    network_mode: "service:gluetun"
    depends_on:
      blocky:
        condition: service_healthy
    healthcheck:
      test: curl --silent --fail 127.0.0.1:8080 || nc -z 127.0.0.1 8080 || exit 1
      interval: 10s
      retries: 3
      start_period: 5s
      timeout: 5s
    restart: always

@qdm12 qdm12 closed this as completed in a54be9a Oct 7, 2024
Copy link
Contributor

github-actions bot commented Oct 7, 2024

Closed issues are NOT monitored, so commenting here is likely to be not seen.
If you think this is still unresolved and have more information to bring, please create another issue.

This is an automated comment setup because @qdm12 is the sole maintainer of this project
which became too popular to monitor issues closed.

@qdm12
Copy link
Owner

qdm12 commented Oct 7, 2024

Would it be possible to retry this somehow that doesn't assume the vpn is failed (as in the commit mentioned above)?

a54be9a adds a retry mechanism only when connection refused is contained as a suffix in the error message, which should do the trick. Not super fan of adding niche code, but I couldn't figure out a more generic approach, or it would block the rest of the 'on tunnel up' setup, in case it's just the public ip echo service which is not working.

@qdm12
Copy link
Owner

qdm12 commented Oct 7, 2024

Just writing this last comment made me realize there is a better solution, done in 5a09cb7:

  1. Peddled back the changes mentioned above
  2. Added a 'wait for dns' check IF the built-in Dns over tls server is not enabled, and before the public ip fetching. This one takes ~5 seconds maximum which should work in your case, and usually should work within 1 second.

qdm12 added a commit that referenced this issue Oct 8, 2024
@qdm12
Copy link
Owner

qdm12 commented Oct 8, 2024

Commit overridden by commit 5fd0af9 and 432eaa6 since they contained a linting error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants