{"id":22438151,"url":"https://github.com/sr/tsproxy","last_synced_at":"2025-10-16T03:30:29.984Z","repository":{"id":152362956,"uuid":"567836898","full_name":"sr/tsproxy","owner":"sr","description":null,"archived":false,"fork":false,"pushed_at":"2024-12-09T20:34:26.000Z","size":141,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-01-18T01:52:47.495Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-18T17:41:10.000Z","updated_at":"2024-12-09T20:34:30.000Z","dependencies_parsed_at":"2023-12-19T18:06:08.262Z","dependency_job_id":"5c85dd7b-0eba-4f2d-ad50-eb7b241b45aa","html_url":"https://github.com/sr/tsproxy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sr%2Ftsproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sr%2Ftsproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sr%2Ftsproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sr%2Ftsproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sr","download_url":"https://codeload.github.com/sr/tsproxy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236670633,"owners_count":19186491,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-06T00:43:09.507Z","updated_at":"2025-10-16T03:30:29.600Z","avatar_url":"https://github.com/sr.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tailscale Proxy\n\ntsproxy is an HTTP reverse proxy that configures a Tailscale device for each upstream.\n\nThis command exposes the backend at `http://my-app` and `https://my-app.\u003ctailnet-name\u003e.ts.net`:\n\n`tsproxy --upstream=my-app=http://127.0.0.1:8000`\n\n**NOTE:** [MagicDNS](https://tailscale.com/kb/1081/magicdns/) must be enabled.\n\nRepeat the `--upstream` flag for each backends.\n\n## Funnel\n\nBackends can be exposed on the public Internet using [Tailscale Funnel](https://tailscale.com/kb/1223/tailscale-funnel/). Use the `funnel` option:\n\n`tsproxy --upstream=my-public-app=http://127.0.0.1:8000;funnel`\n\n## Prometheus\n\n`tsproxy` serves metrics about itself and [Prometheus HTTP Service Discovery](https://prometheus.io/docs/prometheus/latest/http_sd/) targets on the host's two tailscale IPs.\n\nTo add an upstream to service discovery, use the `prometheus` option:\n\n`tsproxy --upstream=my-app=http://127.0.0.1:8000;prometheus`\n\nThen use this Prometheus scrape config:\n\n\n```yaml\n- job_name: tsproxy\n  http_sd_configs:\n    - url: http://\u003ctsproxy-host\u003e:\u003ctsproxy-port\u003e/sd\n```\n\nThe tsproxy metrics port (flag `--port`) defaults to `32019`. It's automatically registered in service discovery.\n\n## Authentication Headers\n\nThe proxy sets the `X-Webauth-User` and `X-Webauth-Name` headers for requests made by users. This works well with [Grafana's Auth Proxy](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/auth-proxy/).\n\nRequests originating from tagged nodes (this includes Tailscale's Funnel nodes) are proxied as is, without any additional headers.\n\n## Tailscale ACLs\n\nTo add the ACL tag `tag:tsnet` to all devices created by tsproxy, create an [Auth key](https://tailscale.com/kb/1085/auth-keys/), then run the process with `TS_AUTH_KEY=\u003ckey\u003e`. All upstreams will automatically be tagged.\n\nThis works well for ACLs.\n\n```json\n  \"acls\": [\n    {\"action\": \"accept\", \"src\": [\"group:admin\"], \"dst\": [\"tag:tsnet:80,443\"]},\n  ],\n```\n\nTo change the ACL tag, update `TS_AUTH_KEY` and set `FORCE_REAUTH=1`.\n\n## systemd\n\nThis is the systemd unit I use to run `tsproxy`: \u003chttps://gist.github.com/sr/f8b1860cca428b04fc2b0b84ea561348\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsr%2Ftsproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsr%2Ftsproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsr%2Ftsproxy/lists"}