Skip to content

v2: Redirect from 80/http to https://<tsdproxy.name>.<funny_name> refuses connections if configured through labels #381

@sbrocket

Description

@sbrocket

Describe the bug
I'm attempting to use tsdproxy to automatically upgrade http requests to a given proxy to https without certificate errors by redirecting to the proxy's FQDN. However, my attempts to do this using Docker labels are failing. For example, with the following labels applied to the Docker compose stack for tsdproxy itself:

    labels:
      tsdproxy.enable: "true"
      tsdproxy.name: tsdproxy
      tsdproxy.port.1: 443/https:8080/http
      tsdproxy.port.2: 80/http->https://tsdproxy.civet-vibes.ts.net

The https redirect on port 443 works correctly, but connections to port 80 are refused completely:

❯ curl -v http://tsdproxy
* Host tsdproxy:80 was resolved.
* IPv6: (none)
* IPv4: 100.124.102.19
*   Trying 100.124.102.19:80...
* connect to 100.124.102.19 port 80 from 100.98.62.32 port 45598 failed: Connection refused
* Failed to connect to tsdproxy port 80 after 2 ms: Couldn't connect to server

Configuring the same thing through a YAML "list", however, does work as expected on both port 80 and 443:

tsdproxy2:
    ports:
        80/http:
            targets:
                - https://tsdproxy.civet-vibes.ts.net
            isRedirect: true
        443/https:
            targets:
                - http://host.docker.internal:9001

I've also tested the same labels applied to a different stack, in case this was some odd behavior about tsdproxy redirecting to itself. The behavior is unfortunately the same.

Expected behavior
Redirects should work if configured through labels in addition to YAML.

Send config

My config doesn't have anything particularly non-default in it. I've got an OAuth credential configured, debug logs enabled, and the single list entry shown above in manual.yaml:

defaultProxyProvider: default
docker:
    local:
        host: unix:///var/run/docker.sock
        targetHostname: host.docker.internal
lists:
    manual:
        filename: /config/manual.yaml
        defaultProxyAccessLog: true
tailscale:
    providers:
        default:
            controlUrl: https://controlplane.tailscale.com
            clientId: "id"
            clientSecret: "secret"
            tags: "tag:tsdproxy,tag:container"
    dataDir: /data/
http:
    hostname: 0.0.0.0
    port: 8080
log:
    level: debug
    json: false
proxyAccessLog: true

Logs

Initializing server
Version 2.0.0-beta4
loading configuration from: /config/tsdproxy.yaml
Validating configuration...
Setting up logger
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/core/log.go:43 > Log Settings Log level=debug
5:53AM INF home/runner/work/tsdproxy/tsdproxy/cmd/server/main.go:84 > Starting server Version=2.0.0-beta4
5:53AM INF home/runner/work/tsdproxy/tsdproxy/cmd/server/main.go:107 > Setting up proxy proxies
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxymanager.go:206 > Setting up Tailscale Providers module=proxymanager
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxymanager.go:212 > Created Proxy provider module=proxymanager provider=default
5:53AM INF home/runner/work/tsdproxy/tsdproxy/cmd/server/main.go:89 > Initializing WebServer
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/core/healthcheck.go:54 > Health check set to ready
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/targetproviders/docker/docker.go:270 > Default Network found defaultIPAdress=172.17.0.1 docker=local module=proxymanager
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/targetproviders/list/list.go:99 > Start WatchEvents file=manual module=proxymanager
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/config/configfile.go:86 > Start watching file file=/config/manual.yaml files=/config/manual.yaml module=file
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxymanager.go:261 > Adding target module=proxymanager targetID=tsdproxy2
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxymanager.go:306 > Creating proxy module=proxymanager proxy=tsdproxy2
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:47 > setting up proxy hostname=tsdproxy2 module=proxymanager proxyname=tsdproxy2
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:50 > initializing proxy hostname=tsdproxy2 module=proxymanager proxyname=tsdproxy2
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:64 > Setting up tailscale server hostname=tsdproxy2 module=proxymanager tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:61 > Proxy server created successfully hostname=tsdproxy2 module=proxymanager proxyname=tsdproxy2
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:136 > newport module=proxymanager port=proxyname=tsdproxy2
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:136 > newport module=proxymanager port=proxyname=tsdproxy2
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:146 > starting proxy module=proxymanager proxyname=tsdproxy2
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/targetproviders/docker/docker.go:209 > Container 0321f7abd7797b4138b2f26ef83d717ab5da881e3073628838bc4055dcf8ded8 started docker=local module=proxymanager
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxymanager.go:261 > Adding target module=proxymanager targetID=0321f7abd7797b4138b2f26ef83d717ab5da881e3073628838bc4055dcf8ded8
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:78 > tsnet running state path /data/default/tsdproxy2/tailscaled.state Hostname=tsdproxy2 module=proxymanager tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/targetproviders/docker/container.go:219 > target URL container=/tsdproxy docker=local module=proxymanager port=443/https:8080/http target=http://127.0.0.1:8080
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxymanager.go:306 > Creating proxy module=proxymanager proxy=tsdproxy
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:47 > setting up proxy hostname=tsdproxy module=proxymanager proxyname=tsdproxy
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:50 > initializing proxy hostname=tsdproxy module=proxymanager proxyname=tsdproxy
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:64 > Setting up tailscale server hostname=tsdproxy module=proxymanager tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:61 > Proxy server created successfully hostname=tsdproxy module=proxymanager proxyname=tsdproxy
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:78 > tsnet starting with hostname "tsdproxy2", varRoot "/data/default/tsdproxy2" Hostname=tsdproxy2 module=proxymanager tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:136 > newport module=proxymanager port=proxyname=tsdproxy
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:146 > starting proxy module=proxymanager proxyname=tsdproxy
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:78 > tsnet running state path /data/default/tsdproxy/tailscaled.state Hostname=tsdproxy module=proxymanager tailscale=default
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:78 > tsnet starting with hostname "tsdproxy", varRoot "/data/default/tsdproxy" Hostname=tsdproxy module=proxymanager tailscale=default
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:78 > Authkey is set; but state is NoState. Ignoring authkey. Re-run with TSNET_FORCE_LOGIN=1 to force use of authkey. Hostname=tsdproxy2 module=proxymanager tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:170 > Starting proxy port module=proxymanager port=80/http proxyname=tsdproxy2
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:170 > Starting proxy port module=proxymanager port=443/https proxyname=tsdproxy2
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:78 > Authkey is set; but state is NoState. Ignoring authkey. Re-run with TSNET_FORCE_LOGIN=1 to force use of authkey. Hostname=tsdproxy module=proxymanager tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxymanager/proxy.go:170 > Starting proxy port module=proxymanager port=tsdproxy.port.1 proxyname=tsdproxy
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/proxy.go:178 > tailscale status Hostname=tsdproxy2 authURL= module=proxymanager status=Starting tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/proxy.go:178 > tailscale status Hostname=tsdproxy authURL= module=proxymanager status=Starting tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/proxy.go:178 > tailscale status Hostname=tsdproxy2 authURL=tsdproxy2.civet-vibes.ts.net module=proxymanager status=Running tailscale=default
5:53AM DBG home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/proxy.go:178 > tailscale status Hostname=tsdproxy authURL=tsdproxy.civet-vibes.ts.net module=proxymanager status=Running tailscale=default
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:78 > AuthLoop: state is Running; done Hostname=tsdproxy2 module=proxymanager tailscale=default
5:53AM INF home/runner/work/tsdproxy/tsdproxy/internal/proxyproviders/tailscale/provider.go:78 > AuthLoop: state is Running; done Hostname=tsdproxy module=proxymanager tailscale=default

I'll note in the logs here that there is a Starting proxy port log for tsdproxy.port.1, but none for tsdproxy.port.2. The tsdproxy2 configured in YAML shows Starting proxy port for both port 80 and port 443. Perhaps there's some bug in the label parsing for redirects that the YAML config side steps?

If I switch tsdproxy.port.1 and tsdproxy.port.2's values so that .1 is the redirect, then the logs show Starting proxy port module=proxymanager port=tsdproxy.port.2 proxyname=tsdproxy, but again no similar log for the redirect in tsdproxy.port.1.

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions