Skip to content

RStephanH/connectit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

connectit ⛓‍💥

Go app to connect automatically into your private Tailscale network via an auth key generated in your admin console.

Built on tsnet — Tailscale's embedded networking library — connectit registers any Linux host as a node on your tailnet programmatically, with no Tailscale daemon or manual browser login required.


Overview

Standard Tailscale installation runs a background daemon (tailscaled) and requires interactive authentication. connectit bypasses both: it embeds the Tailscale network stack directly into the process via tsnet, authenticates using a pre-shared auth key, and keeps the node connected until it receives a shutdown signal.

This makes it suitable for:

  • Automated infrastructure provisioning
  • Ephemeral test environments (VMs, containers)
  • Nodes that must join a tailnet without human interaction

Prerequisites

Requirement Notes
Go >= 1.21 Tested with 1.22
Tailscale account tailscale.com
Auth key Generate one in the admin console
Linux host Needs a TUN-capable kernel (standard on any modern distro)
root or CAP_NET_ADMIN Required to create the TUN network interface

Project Structure

connectit/
├── bin/                  # Compiled binary (git-ignored)
│   └── connectit
├── endpointstate/        # Tailscale node identity — persists between runs (git-ignored)
├── infra/
│   └── Vagrantfile       # Ubuntu 22.04 VM for isolated integration testing
├── main.go
├── go.mod
├── go.sum
└── README.md

Note: bin/ and endpointstate/ should both be in your .gitignore. The endpointstate/ directory holds the node's private key and tailnet identity — committing it would expose your node's credentials.


Build

# Build for your current platform
go build -o bin/connectit .

# Build explicitly for Linux amd64 (required before Vagrant testing)
GOOS=linux GOARCH=amd64 go build -o bin/connectit .

tsnet is pure Go with no cgo dependencies, so the binary is fully statically linked — no shared libraries to worry about on the target host.


Usage

export TS_AUTH_KEY="tskey-auth-<your-key-here>" #OR source your .env
sudo ./bin/connectit -hostname <your-chosen-hostname>
Flag Default Description
-hostname (required) Name the node will appear as in the Tailscale admin console

AUTH_KEY is read from the environment — never pass it as a CLI argument, as arguments are visible in ps output and shell history.

What to expect

2024/01/15 12:00:00 Endpoint connected successfully
        Ip address : [100.x.x.x]
2024/01/15 12:00:00 Running... press Ctrl+C to disconnect

The node will appear in your Tailscale admin console within a few seconds. On Ctrl+C, connectit logs out the node cleanly before exiting.


Node State and Reuse

connectit stores node identity under endpointstate/ in the working directory it's launched from. This is intentional:

  • First run: creates the directory, registers a new node, obtains a Tailscale IP.
  • Subsequent runs: reuses the existing identity — the node reconnects as the same device with the same IP rather than registering a new one.

Always run the binary from the same working directory if you want consistent identity between restarts.


Testing with Vagrant

The infra/ directory contains a Vagrantfile that boots an isolated Ubuntu 22.04 VM for integration testing — verifying that the binary correctly registers a node on a real tailnet without touching your host machine's network.

Requirements

Workflow

# 1. Build a Linux binary on your host
GOOS=linux GOARCH=amd64 go build -o bin/connectit .

# 2. Boot the VM (mounts bin/ into the guest, marks binary executable)
cd infra
vagrant up

# 3. SSH into the VM
vagrant ssh

# 4. Set your auth key inside the guest shell (never touches a file)
export AUTH_KEY="tskey-auth-<your-key-here>"

# 5. Run the binary
sudo /vagrant_bin/connectit -hostname connectit-test-vm

# 6. Check your Tailscale admin console — the node should appear within seconds

# 7. Ctrl+C to disconnect, then clean up
exit
vagrant destroy

The VM has no internet exposure beyond what Tailscale requires — there are no open ports, no public IP forwarding, and the default Vagrant synced folder is explicitly disabled so only bin/ is mounted.


Security Notes

  • Auth keys are credentials. Treat them like passwords — use environment variables, never hardcode them in files or pass them as CLI flags.
  • Reusable vs. ephemeral keys: For repeated testing, generate a reusable auth key in the admin console. For production nodes, prefer one-time keys and rotate them.
  • endpointstate/ is sensitive. It contains your node's private key. Add it to .gitignore immediately and never commit it.
  • sudo scope: connectit needs root only to create the TUN interface at startup. A production hardening step would be granting CAP_NET_ADMIN to the binary specifically rather than running the whole process as root.

How It Works

connectit
    │
    ├── tsnet.Server{} ──► userspace WireGuard stack (no tailscaled daemon needed)
    │       │
    │       └── srv.Up(ctx) ──► authenticates via AUTH_KEY
    │                           registers node with Tailscale coordination server
    │                           creates TUN interface, assigns 100.x.x.x IP
    │
    └── signal.Notify() ──► blocks until SIGINT / SIGTERM
            │
            └── lc.Logout(ctx) ──► cleanly deregisters node before exit

About

Programmatically register any Linux / Windows host as a Tailscale node — no daemon, no interactive login

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages