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

Support for Serve and Funnel #117

Open
jason-riddle opened this issue Jul 21, 2024 · 3 comments
Open

Support for Serve and Funnel #117

jason-riddle opened this issue Jul 21, 2024 · 3 comments

Comments

@jason-riddle
Copy link
Owner

jason-riddle commented Jul 21, 2024

So supporting all of the serve and funnel arguments would be quite complex.

Looking at https://tailscale.com/blog/reintroducing-serve-funnel, here are some of the possible configurations for using these commands.

# Serve a file, directory, or plain text:

$ tailscale serve /path/to/file.html
$ tailscale funnel /path/to/directory
$ tailscale serve text:"hello from tailscale"

# Start an HTTPS reverse proxy to port 3000

$ tailscale serve 3000
$ tailscale funnel localhost:3000
$ tailscale serve http://localhost:3000
$ tailscale funnel http://127.0.0.1:3000

# The same, but at a path

$ tailscale serve localhost:3000/foo
$ tailscale funnel http://localhost:3000/foo
$ tailscale serve http://127.0.0.1:3000/foo

# The same, but listen on alternate port 8443

$ tailscale serve --https=8443 3000
$ tailscale funnel --https=8443 3000

# Run Funnel or Serve in the background

$ tailscale serve --bg 3000
$ taiscale funnel --bg 3000

# Specify a multiple mount point- all of these can be active at the same time

$ tailscale serve --set-path=/ --bg 3000
$ tailscale funnel --set-path=/foo --bg localhost:5000
$ tailscale serve --set-path=/bar --bg /path/to/file.html

# Ignore an invalid or self-signed certificate

$ tailscale serve https+insecure://localhost:5454
$ tailscale funnel https+insecure://localhost:5454

# Forward incoming TCP connections on port 10000 to a local TCP server on port 22
# (eg.g to run OpenSSH in parallel with Tailscale SSH):

$ tailscale serve --tcp=2222 22
$ tailscale serve --tcp=2222 tcp://localhost:22

As a user, I appreciate that there are a lot of different ways to configure serving and funnel traffic. As a maintainer of this ansible role, it is annoying to try to figure out how to standardize these commands and flags in a way that makes sense for ansible.

An alternative option is providing a JSON file via the TS_SERVE_CONFIG env var. The description for this env var, as mentioned here https://tailscale.com/kb/1282/docker#ts_serve_config, says

Accepts a JSON file to programmatically configure Serve and Funnel functionality. Use tailscale serve status --json to export your current configuration in the correct format.

So as an example, if I want to serve traffic on :80 and forward it to my application, I can create the following JSON file

/serve-config/tailscale-serve-config.json

{
  "TCP": {
    "80": {
      "HTTP": true
    }
  },
  "Web": {
    "coder.greyhound-little.ts.net:80": {
      "Handlers": {
        "/": {
          "Proxy": "http://localhost:8443"
        }
      }
    }
  }
}

And set the environment variable like so

TS_SERVE_CONFIG=/serve-config/tailscale-serve-config.json

And then upon starting, Tailscale will pick this up and start serving traffic as directed.

The only problem with this approach is this JSON file is responsible for storing ALL serving and forwarding traffic information. There isn't a way to specify multiple files for serving traffic. So if traffic is already being served via a different JSON file and this file is instead placed there, then the previous serving configuration is essentially deleted.

Since it doesn't seem like there is a documented way of building this JSON file and thus some sort of backwards compatibility guarantee, I feel the only option is to allow the user to pass in a JSON structure via and ansible var and then have it be set at the proper location.

The only other thing I could do is document some command commands on their JSON outputs for users to try and experiment on their own. For example, given the Tailscale example commands above, I could provide the equivalent JSON structures for the user to test for themselves.

@jason-riddle
Copy link
Owner Author

Correction: TS_SERVE_CONFIG is only supported while running within a Docker container. I don't imagine people are going to be using this ansible role to configure tailscale in a Docker container.

@jason-riddle
Copy link
Owner Author

jason-riddle commented Jul 31, 2024

Another idea is to require all of the available arguments to be specified.

Enabled would accept 5? and disabled would accept 2.

It can be argued that this

tailscale serve 3000

Is much harder to understand compared to the command fully written out

tailscale serve --bg --https=443 --set-path=/ http://127.0.0.1:3000

Here are some more examples

# Enable the serve behavior.
tailscale_serve_enabled: true

# Create new routes.

# tailscale serve --bg --http=80 --set-path=/ http://localhost:8000
tailscale_serve_routes_enabled:
  - background: true # defaults to true
    protocol: http
    port: 80
    path: /
    url: http://localhost:8000

# tailscale serve --bg --http=80 --set-path=/ http://localhost:8000
tailscale_serve_routes_enabled:
  - background: true # defaults to true
    protocol: http
    port: 80
    path: /
    url: http://localhost:8000

# Disable existing routes.

# tailscale serve --http=80 off
tailscale_serve_routes_disabled:
  - protocol: http
    port: 80

@jason-riddle
Copy link
Owner Author

Another idea is to just pass in the raw commands

# tailscale serve --bg --http=80 --set-path=/ http://localhost:8000
tailscale_serve_commands:
- "tailscale serve --bg --http=80 --set-path=/ http://localhost:8000"

This provides the most flexibility, but it's not using the usual Ansible yaml code structure.

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

No branches or pull requests

1 participant