# Tailcat Server Mode Service Types: The Complete Guide to Built-in Network Services

> Discover the six Tailcat server mode service types: all, exit-node, ssh, no-auth-ssh, files, and exec. Learn how to leverage built-in network services on your tailnet.

- Repository: [Tailscale/tailcat](https://github.com/tailscale/tailcat)
- Tags: deep-dive
- Published: 2026-09-08

---

**Tailcat server mode supports six distinct service types: `all`, `exit-node`, `ssh`, `no-auth-ssh`, `files`, and `exec`, each exposing different server capabilities that clients can connect to over the tailnet.**

Tailcat—an open-source networking tool from the Tailscale ecosystem—provides a flexible `serve` subcommand that transforms any node into a multi-protocol server. Understanding the available Tailcat server mode service types is essential for configuring secure file transfers, remote shells, traffic forwarding, and custom command execution across your private network.

## Overview of Tailcat Server Mode

When you invoke `tailcat serve`, the binary initializes a `tailcat.Server` struct that dispatches incoming connections based on the service flags you specify. According to the source code in [`main/cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/main/cmd/tailcat/tailcat.go), the service names are parsed by the `parsePortSet` helper (lines 94–104) and validated to prevent incompatible combinations (lines 1264–1273). This architecture allows a single Tailcat instance to expose multiple services simultaneously while maintaining strict security boundaries.

## The Six Supported Service Types

### `all`: Full-Port Exposure

The `all` service type exposes **every port**—both TCP and UDP—on the server’s Tailscale address. This mode effectively turns the node into a transparent proxy where any incoming connection attempt is accepted, making it useful for development environments or testing scenarios where you need unrestricted access without configuring individual ports.

### `exit-node`: Full-Mesh Traffic Forwarding

When configured as an `exit-node`, the server acts as a full-mesh router that forwards traffic to arbitrary destinations outside the tailnet. This service implements the forwarding logic found in [`main/cmd/tailcat/forward.go`](https://github.com/tailscale/tailcat/blob/main/main/cmd/tailcat/forward.go), allowing clients to route internet-bound traffic through the server. Exit nodes are particularly valuable for accessing geo-restricted content or enforcing centralized internet filtering policies.

### `ssh`: Authenticated SSH Server

The `ssh` service spins up a public-key-authenticated SSH server using the implementation in [`main/tailcat_ssh.go`](https://github.com/tailscale/tailcat/blob/main/main/tailcat_ssh.go). To use this service, you **must** provide the `--ssh-authorized-keys` flag pointing to a file containing permitted public keys. This creates a secure, key-based remote shell accessible only to holders of the corresponding private keys.

### `no-auth-ssh`: Authentication-Free SSH Access

For scenarios requiring immediate access without key management—such as automated testing or secure sandboxed environments—the `no-auth-ssh` service provides an SSH server that **does not require authentication**. While convenient, this should only be deployed in trusted network segments due to its open-access nature.

### `files`: SFTP and SCP File Service

The `files` service enables SFTP/scp file transfers through the logic implemented in [`main/tailcat_files.go`](https://github.com/tailscale/tailcat/blob/main/main/tailcat_files.go). Configure this service using the `--files` flag with a path and mode suffix:

- `:ro` for read-only access
- `:rw` for read-write access
- `:wo` for write-only access

This creates a hardened file server without requiring separate SFTP daemon configuration.

### `exec`: Per-Connection Command Execution

The `exec` service—implemented in [`main/tailcat_exec.go`](https://github.com/tailscale/tailcat/blob/main/main/tailcat_exec.go)—executes a specified command for each incoming connection, piping the network stream directly to the process’s stdio. Append `--` followed by your command to the serve invocation. This transforms Tailcat into a network-wrapped process supervisor, ideal for creating ad-hoc TCP/IP services from standard Unix tools.

## Service Validation and Conflict Detection

The Tailcat CLI enforces strict validation rules to prevent security-impossible configurations. In [`main/cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/main/cmd/tailcat/tailcat.go) (lines 1264–1273), the validation logic explicitly rejects attempts to combine mutually exclusive services. For example, you cannot simultaneously enable `ssh` and `no-auth-ssh` on the same instance, as this would create ambiguous authentication requirements. The `parsePortSet` function handles the initial string parsing of comma-separated service lists before this validation occurs.

## Configuration Examples

### Hosting SSH and File Services Together

Expose both authenticated SSH and read-write file access:

```bash
$ tailcat serve \
    --ssh-authorized-keys=~/.ssh/id_rsa.pub \
    --files=/srv/share:rw \
    ssh,files

```

### Unauthenticated SSH with Command Execution

Create a netcat-like service that runs `/usr/bin/cat` for every connection without requiring SSH keys:

```bash
$ tailcat serve \
    --serve=no-auth-ssh,exec \
    -- /usr/bin/cat

```

### Programmatic Exit Node Configuration

Using the Go library to start an exit node server:

```go
package main

import (
    "log"
    "tailscale.com/tailcat"
)

func main() {
    srv := &tailcat.Server{
        // Exit-node mode is activated implicitly or via configuration
    }
    if err := srv.Start(); err != nil {
        log.Fatalf("server start: %v", err)
    }
    // Server now forwards traffic as a full-mesh exit node
}

```

## Summary

- **Tailcat supports six service types**: `all`, `exit-node`, `ssh`, `no-auth-ssh`, `files`, and `exec`, defined in [`main/cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/main/cmd/tailcat/tailcat.go) lines 94–104.
- **Validation prevents conflicts**: The source code at lines 1264–1273 explicitly blocks incompatible combinations like `ssh` with `no-auth-ssh`.
- **Authentication requirements vary**: The `ssh` service requires `--ssh-authorized-keys`, while `no-auth-ssh` provides immediate access.
- **File permissions are granular**: The `files` service supports read-only (`:ro`), read-write (`:rw`), and write-only (`:wo`) modes via the `--files` flag.
- **Implementation is modular**: Each service maps to specific source files like [`main/tailcat_ssh.go`](https://github.com/tailscale/tailcat/blob/main/main/tailcat_ssh.go), [`main/tailcat_files.go`](https://github.com/tailscale/tailcat/blob/main/main/tailcat_files.go), and [`main/tailcat_exec.go`](https://github.com/tailscale/tailcat/blob/main/main/tailcat_exec.go).

## Frequently Asked Questions

### Can I combine multiple Tailcat service types in a single command?

Yes, you can specify multiple services as comma-separated values to the `--serve` flag, such as `ssh,files` or `exit-node,exec`. However, the validation logic in [`main/cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/main/cmd/tailcat/tailcat.go) will reject combinations that create security conflicts, such as mixing authenticated and unauthenticated SSH services on the same instance.

### What is the difference between the `ssh` and `no-auth-ssh` services?

The `ssh` service requires public key authentication via the `--ssh-authorized-keys` flag, using the implementation in [`main/tailcat_ssh.go`](https://github.com/tailscale/tailcat/blob/main/main/tailcat_ssh.go) to verify credentials before granting shell access. In contrast, `no-auth-ssh` immediately grants access without credential verification, making it suitable for automated testing but inappropriate for production environments requiring access control.

### How do I configure the `files` service for read-only access?

Append the `:ro` suffix to your path in the `--files` flag. For example: `--files=/srv/data:ro` creates a read-only SFTP endpoint. You can also specify `:rw` for read-write or `:wo` for write-only access, with the permission logic enforced by the file service implementation in [`main/tailcat_files.go`](https://github.com/tailscale/tailcat/blob/main/main/tailcat_files.go).

### Can I run an exit node alongside other services like `files` or `exec`?

Yes, the `exit-node` service can coexist with other service types such as `files` or `exec`. The exit node functionality—implemented in [`main/cmd/tailcat/forward.go`](https://github.com/tailscale/tailcat/blob/main/main/cmd/tailcat/forward.go)—operates independently of the application-layer services, allowing your node to simultaneously route traffic for the mesh network and host specific application services for direct client connections.