# What Is the Exit-Node Service Type in Tailcat?

> Discover the Tailscale exit node service type in Tailcat. Learn how to configure Tailcat to act as a full-mesh exit node and forward inbound connections to your local network.

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

---

**The `exit-node` service type configures Tailcat to operate as a full-mesh Tailscale exit node, forwarding all inbound connections to the host's local network interfaces when you start the service with `--serve=exit-node`.**

The `exit-node` service type is a core networking mode in the Tailcat repository (`tailscale/tailcat`) that transforms the process into a bidirectional traffic gateway. When activated, Tailcat advertises itself to the Tailscale network as an exit node capable of routing traffic for any address reachable by the host, enabling other Tailscale clients to obtain internet access or reach internal resources through the Tailcat host's network stack.

## How the Exit-Node Service Works in Tailcat

When you invoke Tailcat with the `exit-node` service, the program diverges from its default single-connection behavior and initializes a persistent server that listens for Tailscale network traffic.

### Command-Line Activation

You can activate the exit-node mode using either the flag syntax or the subcommand syntax:

```bash

# Using the serve subcommand (recommended)

tailcat serve exit-node

# Using the explicit flag syntax

tailcat --serve=exit-node

```

According to the source in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) at line 94, the `--serve` flag description explicitly lists `exit-node` as an option to "run an exit node for all addresses." Additional usage examples appear at lines 312 and 487, demonstrating the expected CLI patterns for this service type.

### Network Architecture

When operating as an exit node, Tailcat performs three critical functions:

- **Full-Mesh Advertisement**: The process registers itself with the Tailscale coordination server as an exit node, making it available to all devices in your tailnet.
- **Traffic Forwarding**: All inbound connections from Tailscale clients are forwarded to the host's local network interfaces, allowing access to the broader internet or private subnets.
- **Bidirectional Routing**: Unlike the default stdout mode, which handles single connections, the exit-node service maintains a persistent forwarding path for sustained traffic flow.

## Implementation Details in the Tailcat Source Code

The exit-node logic is implemented primarily in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go), with supporting tests verifying the behavior across network conditions.

### Service Detection Logic

The main server loop specifically checks for the presence of the `exit-node` service before falling back to one-shot mode. As implemented at line 1388 in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go), the code inspects the service list:

```go
// Example pattern from the Tailcat source
if services.Contains("exit-node") {
    // Initialize the exit-node server path
}

```

This conditional ensures that when `exit-node` is present, Tailcat skips the stdout-streaming behavior and instead launches the exit-node server initialization routines.

### Server Initialization

Once detected, the exit-node startup path executes at lines 1421 and 1464 of [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go). This code path:

1. Configures the Tailscale node to accept subnet routes and exit-node traffic
2. Sets up the TCP forwarder that bridges Tailscale connections to the local network stack
3. Maintains the advertisement to the coordination server, ensuring the node remains discoverable

The implementation ensures that any Tailscale client selecting this node as its exit node will route **all** non-Tailscale traffic through the Tailcat host, effectively using the host's network connection as a proxy.

## Practical Configuration Examples

To deploy Tailcat as an exit node in production environments, use the following patterns:

```bash

# Start as exit node with default settings

tailcat serve exit-node

# Run as exit node with explicit backend binding

tailcat --serve=exit-node --backend=100.64.0.1:8080

```

For systemd integration, create a service that invokes the exit-node mode on boot:

```ini

# /etc/systemd/system/tailcat-exit-node.service

[Unit]
Description=Tailcat Exit Node
After=network.target

[Service]
ExecStart=/usr/local/bin/tailcat serve exit-node
Restart=always

[Install]
WantedBy=multi-user.target

```

## Testing and Validation

The Tailcat repository includes comprehensive tests that verify exit-node functionality:

- **[`cmd/tailcat/serve_test.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/serve_test.go)**: Validates that `--serve=exit-node` correctly initializes the server without errors and properly registers the service type.
- **[`cmd/tailcat/forward_test.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/forward_test.go)**: Verifies that traffic forwarding through an exit-node target functions correctly, ensuring packets reach their intended destinations via the host's network stack.
- **[`cmd/tailcat/ssh.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/ssh.go)**: Demonstrates interaction patterns between SSH connections and exit-node mode, confirming that the service type influences how other protocols (like SSH) are handled when the server operates as a network gateway.

These tests ensure that when `services.Contains("exit-node")` evaluates to true, the resulting server configuration correctly handles both ingress and egress traffic flows.

## Summary

- The `exit-node` service type in Tailcat transforms the process into a Tailscale exit node capable of routing all client traffic through the host's network interfaces.
- Activation requires either `tailcat serve exit-node` or `tailcat --serve=exit-node`, as defined in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) (lines 94, 312, 487).
- The implementation checks for this service at line 1388 to bypass single-connection mode and initializes the exit-node server at lines 1421 and 1464.
- When active, the node advertises itself to the full Tailscale mesh, allowing any client to select it as their internet gateway or route to internal resources.

## Frequently Asked Questions

### How do I verify that Tailcat is running correctly as an exit node?

Check the Tailscale admin console to confirm the device appears as an exit node option, or run `tailcat serve exit-node` with verbose logging enabled. According to [`cmd/tailcat/serve_test.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/serve_test.go), successful initialization shows no startup errors and the process remains running rather than exiting after a single connection.

### Can I run multiple service types alongside `exit-node` in Tailcat?

The source code in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) processes the service list as a collection, checking `services.Contains("exit-node")` among other options. While the exit-node mode primarily focuses on full-network forwarding, you should verify compatibility with other specific service combinations by consulting the server initialization logic at lines 1388-1464.

### What is the difference between `exit-node` and standard port forwarding in Tailcat?

Standard Tailcat operation accepts a single connection and streams data to stdout, suitable for one-off debugging or specific port tunnels. The `exit-node` service, conversely, creates a persistent server that handles **all** inbound connections from the Tailscale network, forwarding them to the host's local interfaces to provide comprehensive network access rather than single-port exposure.

### Does the exit-node service require special permissions on the host system?

Yes, operating as an exit node typically requires elevated privileges to bind to low-numbered ports and to configure the host's networking stack for IP forwarding. The implementation in [`cmd/tailcat/tailcat.go`](https://github.com/tailscale/tailcat/blob/main/cmd/tailcat/tailcat.go) assumes the process has sufficient permissions to advertise subnet routes and accept traffic destined for arbitrary destinations.