diff --git a/README.md b/README.md index a2a5435..5fbab92 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,29 @@ to your `devcontainer.json`: } ``` -Then launch your Codespace. After it starts up, run [`tailscale up`](https://tailscale.com/kb/1080/cli/#up): +## Starting Tailscale + +The Tailscale daemon starts automatically as part of the devcontainer entrypoint. + +### Manual Log in ```shell sudo tailscale up --accept-routes ``` -You'll only need to run `tailscale up` once per Codespace. -The Tailscale state will be saved between rebuilds. +More info: [`tailscale up`](https://tailscale.com/kb/1080/cli/#up) + +### Automatic login + +Create an [auth key](https://tailscale.com/kb/1085/auth-keys) in the Tailscale +[admin panel](https://login.tailscale.com/admin/settings/keys). + +Create a codespace secret called `TS_AUTH_KEY` in your +[codespaces configuration](https://github.com/settings/codespaces) containing +the auth key you made above. + +Now whenever you launch a devcontainer with access to this secret, it will +automatically perform a `tailscale up --accept-routes --auth-key=$TS_AUTH_KEY`. ## Details diff --git a/src/tailscale/tailscaled-devcontainer-start.sh b/src/tailscale/tailscaled-devcontainer-start.sh index ba16f2d..ac370a0 100755 --- a/src/tailscale/tailscaled-devcontainer-start.sh +++ b/src/tailscale/tailscaled-devcontainer-start.sh @@ -11,6 +11,11 @@ if [[ $(id -u) -ne 0 ]]; then exec sudo --non-interactive -E "$0" "$@" fi +# Move the auth key to a non-exported variable so it is not leaking into child +# process environments. +auth_key="$TS_AUTH_KEY" +unset TS_AUTH_KEY + if [[ ! -c /dev/net/tun ]]; then mkdir -p /dev/net mknod /dev/net/tun c 10 200 @@ -31,11 +36,18 @@ TAILSCALED_PID="" TAILSCALED_SOCK=/var/run/tailscale/tailscaled.sock TAILSCALED_LOG=/var/log/tailscaled.log -# Note: TS_DEBUG_FIREWALL_MODE: it is not recommended that users copy this -# setting into other environments, the feature is in test and will be formally -# released in the future, debug flags may later be recycled for other purposes -# leading to unexpected behavior. ->$TAILSCALED_LOG 2>&1 TS_DEBUG_FIREWALL_MODE=auto /usr/local/sbin/tailscaled & +( + exec 1>$TAILSCALED_LOG 2>&1 + cd / + umask 0 + # Note: TS_DEBUG_FIREWALL_MODE: it is not recommended that users copy this + # setting into other environments, the feature is in test and will be formally + # released in the future, debug flags may later be recycled for other purposes + # leading to unexpected behavior. + unset TAILSCALED_PID TAILSCALED_SOCK TAILSCALED_LOG + export TS_DEBUG_FIREWALL_MODE=auto + exec setsid /usr/local/sbin/tailscaled +) & TAILSCALED_PID=$! if [[ -n "$TAILSCALED_PID" ]]; then @@ -50,4 +62,16 @@ if [[ -n "$TAILSCALED_PID" ]]; then break fi done +fi + +if [[ -n "$auth_key" ]]; then + if [[ "$auth_key" == "test-auth-key" ]]; then + touch /tmp/test-auth-key-seen + else + hostnamearg="" + if [[ -n "${CODESPACE_NAME}" ]]; then + hostnamearg="--hostname=${CODESPACE_NAME}" + fi + /usr/local/sbin/tailscale up --accept-routes --authkey="$auth_key" $hostnamearg + fi fi \ No newline at end of file diff --git a/src/tailscale/tailscaled-entrypoint.sh b/src/tailscale/tailscaled-entrypoint.sh index 1d5f2af..35eb881 100644 --- a/src/tailscale/tailscaled-entrypoint.sh +++ b/src/tailscale/tailscaled-entrypoint.sh @@ -5,4 +5,6 @@ /usr/local/sbin/tailscaled-devcontainer-start +unset TS_AUTH_KEY + exec "$@" diff --git a/test/tailscale/scenarios.json b/test/tailscale/scenarios.json index ae5eaa4..f7a1683 100644 --- a/test/tailscale/scenarios.json +++ b/test/tailscale/scenarios.json @@ -18,5 +18,14 @@ "version": "1.80.2" } } + }, + "tailscale_auth_key": { + "image": "ubuntu:latest", + "containerEnv": { + "TS_AUTH_KEY": "test-auth-key" + }, + "features": { + "tailscale": {} + } } } \ No newline at end of file diff --git a/test/tailscale/tailscale_auth_key.sh b/test/tailscale/tailscale_auth_key.sh new file mode 100644 index 0000000..63369fe --- /dev/null +++ b/test/tailscale/tailscale_auth_key.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Copyright (c) 2025 Tailscale Inc & AUTHORS All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +set -e + +source dev-container-features-test-lib + +# Wait for the auth key to be seen by the start script. +count=100 +while ((count--)); do + [[ -f /tmp/test-auth-key-seen ]] && break + sleep 0.1 +done + +check "/tmp/test-auth-key-seen" ls /tmp/test-auth-key-seen + +# It would be nice to directly test that the entrypoint is doing unset +# TS_AUTH_KEY, however that isn't visible to the test execution. + +reportResults \ No newline at end of file diff --git a/test/tailscale/test.sh b/test/tailscale/test.sh index 2b38243..bb3d8a7 100644 --- a/test/tailscale/test.sh +++ b/test/tailscale/test.sh @@ -7,10 +7,10 @@ set -e source dev-container-features-test-lib -if [[ "$VERSION" == latest ]]; then - check "Daemon: " tailscale version --daemon -else - check "$VERSION" tailscale version --daemon +check "daemon is running" tailscale version --daemon + +if [[ -n "$VERSION" ]]; then + check "version is correct" bash -c "tailscale version --daemon | grep -q $VERSION" fi reportResults \ No newline at end of file