Conversation
Going to get more complex with k8s config + OIDC, make it a file.
Want to run it in k8s, add a backend that uses a secret to store the data. While tailscale has one in their codebase, it's not suitable for our usage so we just add a simple one.
Want a dedicated listener, so we can selectively apply auth etc. So just add a new listener/server for that. Redirect to https for internal requests on funnel fqdn's, to keep URLs consistent. Rework startup/shutdown a little to be more graceful.
Adds OIDC auth to funnel endpoints, setting user header consistently. Optionally paths can be specified to be authless.
When running in a container, tailscale doesn't already exist so we can't talk to it. Just use a local listener, need to think about this more.
|
Need to think about the local tailscale daemon usage - it's there to figure out where to bind the discovery and metrics endpoints, but this doesn't work when it's running in a container. Might make a config option (ugh, checkboxes) for metrics listen - either set it to a fixed ip/port, or fallback to daemon discovery. But will think on it more |
| @@ -0,0 +1,117 @@ | |||
| package main | |||
There was a problem hiding this comment.
may be able to use https://pkg.go.dev/tailscale.com/kube:
https://github.com/tailscale/tailscale/blob/main/cmd/containerboot/kube.go#L21-L23
I don't mind client-go tho, it's fine
|
|
||
| for i, upstream := range upstreams { | ||
| // https://go.dev/doc/faq#closures_and_goroutines | ||
| i := i |
| // OIDCClientID sets the OIDC client ID | ||
| OIDCClientID string `json:"oidcClientID"` | ||
| // OIDCClientSecret sets the OIDC client secret | ||
| OIDCClientSecret string `json:"oidcClientSecret"` |
There was a problem hiding this comment.
be cool to support a file too, play nice with systemd-creds. For flags I usually do this:
if _, path, ok := strings.Cut(*cliSecret, "file://"); ok {
b, err := os.ReadFile(path)
if err != nil {
return err
}
s := strings.TrimSpace(string(b))
cliSecret = &s
}
but doesn't really work w/ a config file. Maybe oidcClientSecretFile?
There was a problem hiding this comment.
also wondering if this should be on the root config struct, or do you plan on using a different issuer for some upstream(s)?
| StateDir string `json:"stateDir"` | ||
| // Kubernetes configures the proxy to run in a kubernetes cluster. In this | ||
| // case the StateDir is ignored, and state managed in a secret. | ||
| Kubernetes kubernetesConfig `json:"kubernetes"` |
There was a problem hiding this comment.
*kubernetesConfig? then can drop the enabled field.
| } | ||
| listeners = append(listeners, ln) | ||
| }*/ | ||
| ln, err := net.Listen("tcp", "0.0.0.0:"+p) |
There was a problem hiding this comment.
I use http://nuc10i5/sd in my prom config, I guess I could make tsproxy.service listen on the node's tailscale IP using some ansible: {{ ansible_facts.tailscale0.ipv4.address }
alternatively could you check for the presence of a local socket? will think about it too.
| // Proxy requests from non-funnel tagged nodes as is. | ||
| // | ||
| // TODO(lstoll) figure out why - and if end-user nodes would be tagged? | ||
| if whois.Node.IsTagged() && !isFunnel { |
There was a problem hiding this comment.
yeah I guess a config w/ a list of tags, or maybe node id to consider as end-users??
For it to work, the checkout needs to happen first
* Switch to lds.li/oauth2ext import path, get latest * go get -u ./... * go get gvisor.dev/gvisor@9414b50a5633 (from tailscale go.mod)
cab12e7 to
45fa636
Compare
If configured, dynamically register and renew a client. Add support for filtering groups to allow access.
45fa636 to
3d135ee
Compare
6440b3a to
31cdf64
Compare
f462549 to
2bd0d27
Compare
2bd0d27 to
52c384b
Compare
This adds OIDC auth for funnel usage. By default all funnel requests will require this, unless explicitly overridden.
Because this makes the config more complex, move to just using a file for it.
Add support for persisting state in a k8s secret too.
Add CI build, with docker image.
TODO