Standalone Daemon Administration
This guide covers managing clients, IP assignments, and connection profiles when running the Camouflage daemon in standalone mode (without the Enterprise backend).
Overview
In standalone mode, the daemon (camouflage-daemon) manages its own client registry via a clients.toml file. Every client must have a registered auth key to connect, and each client receives a fixed IP address that persists across reconnections.
The daemon provides four management subcommands:
| Command | Purpose |
|---|---|
camouflage-daemon add-client | Register a new client and assign a fixed IP |
camouflage-daemon revoke-client | Disable a client's access |
camouflage-daemon list-clients | Show all registered clients |
camouflage-daemon export-profile | Generate a .camouflage connection profile |
Client Registry (clients.toml)
The client registry is stored alongside your daemon config. If your config is at /etc/camouflage/config.toml, the registry will be at /etc/camouflage/clients.toml.
File Format
[settings]
ttl_days = 30
subnet = "10.99.0.0/24"
[clients.tskey-abc123...]
ip = "10.99.0.2"
name = "alice-laptop"
enabled = true
last_seen = "2025-02-12T10:30:00Z"
[clients.tskey-def456...]
ip = "10.99.0.3"
name = "bob-desktop"
enabled = true
Settings
| Field | Default | Description |
|---|---|---|
ttl_days | 30 | Unused client expiration (future use) |
subnet | 10.99.0.0/24 | Subnet for IP allocation. Must match daemon config. |
Client Fields
| Field | Description |
|---|---|
ip | Fixed IPv4 address assigned to this client |
name | Human-readable name for identification |
enabled | true to allow connections, false to revoke |
last_seen | ISO 8601 timestamp of last connection (auto-updated) |
Adding Clients
Register a new client with add-client:
# Basic usage - name is required
camouflage-daemon add-client --name "alice-laptop"
# Output:
# Client added successfully
# Name: alice-laptop
# Auth Key: tskey-a1b2c3d4e5f6...
# IP: 10.99.0.2
#
# Save the auth key - it cannot be recovered later.
# Assign a specific IP address
camouflage-daemon add-client --name "server-node" --ip 10.99.0.100
Options
| Flag | Description |
|---|---|
--name <NAME> | Required. Human-readable client name |
--ip <IP> | Optional. Assign a specific IP instead of auto-assigning |
--config <PATH> | Path to daemon config (default: /etc/camouflage/config.toml) |
Auth Key Format
Auth keys follow the format tskey-{64_hex_chars} (70 characters total). They are generated using cryptographically secure random bytes and cannot be recovered after creation.
Revoking Clients
Disable a client's access with revoke-client:
camouflage-daemon revoke-client --auth-key "tskey-a1b2c3d4e5f6..."
# Output:
# Client 'alice-laptop' has been revoked.
Revoking sets enabled = false in clients.toml. The client's IP reservation is kept so it can be re-enabled later if needed. Active connections from the revoked client will be rejected on next reconnect.
Listing Clients
View all registered clients:
camouflage-daemon list-clients
# Output:
# Clients (2 registered):
# tskey-a1b2... alice-laptop 10.99.0.2 enabled last seen: 2025-02-12T10:30:00Z
# tskey-d4e5... bob-desktop 10.99.0.3 revoked last seen: 2025-02-11T08:15:00Z
Exporting Connection Profiles
Generate a .camouflage profile file that clients can import to connect:
# Export to stdout
camouflage-daemon export-profile \
--auth-key "tskey-a1b2c3d4e5f6..." \
--server "vpn.example.com:61700"
# Export to file
camouflage-daemon export-profile \
--auth-key "tskey-a1b2c3d4e5f6..." \
--server "vpn.example.com:61700" \
--output alice-laptop.camouflage
# With custom KEX method
camouflage-daemon export-profile \
--auth-key "tskey-a1b2c3d4e5f6..." \
--server "vpn.example.com:61700" \
--kex hybrid
Options
| Flag | Description |
|---|---|
--auth-key <KEY> | Required. The client's auth key |
--server <HOST:PORT> | Required. Daemon address clients will connect to |
--kex <METHOD> | Key exchange method: hybrid (default), pqxdh, or noise |
--output <PATH> | Write to file instead of stdout |
Profile Format
The exported .camouflage file is a JSON document compatible with the Camouflage desktop app and CLI client:
{
"version": "1.0",
"type": "camouflage-connection",
"connection": {
"id": "a1b2c3d4-e5f6-...",
"name": "alice-laptop",
"server": "vpn.example.com:61700",
"auth_key": "tskey-a1b2c3d4e5f6...",
"kex": "hybrid",
"network_name": "",
"route_all_traffic": false,
"is_relay": true,
"created_at": "2025-02-12T10:30:00Z"
}
}
Importing Profiles (Client Side)
Clients can import a .camouflage profile to connect:
CLI Client
# Connect using a profile file
camouflage-client connect --profile alice-laptop.camouflage
The --profile flag reads the server address, auth key, KEX method, and other settings from the profile file. It overrides any --server, --auth-key, or --kex flags.
Desktop App
- Open Camouflage desktop app
- Click "Import Profile" or drag-and-drop the
.camouflagefile - The connection will appear in your connection list
Fixed IP Assignment
Every registered client receives a fixed IP address from the daemon's subnet. This address is persistent:
- Same IP on every reconnect — the client always gets the same address
- Reserved while disconnected — the IP is not reassigned to other clients
- Survives daemon restarts — stored in
clients.tomlon disk
How It Works
- When you
add-client, the next available IP in the subnet is assigned (skipping .0, .1, and .255) - When a client connects, the daemon looks up their auth key and assigns their registered IP
- When a client disconnects, the IP is released from the active pool but stays reserved in
clients.toml - On the next connection with the same auth key, the same IP is allocated again
Enterprise Mode
When the daemon is connected to the Camouflage Enterprise backend, IP assignments are managed centrally via the API. The daemon queries the backend's /daemon/node-ip/ endpoint with the client's auth key and receives the assigned IP. If the API is unreachable, the daemon falls back to clients.toml.
Authentication Flow
The daemon enforces auth key validation on every connection:
Client connects with auth_key
├─ No auth_key provided → Connection REJECTED
└─ auth_key provided →
Enterprise backend configured?
├─ YES → Query backend API for IP
│ ├─ 200 OK → Assign fixed IP, allow connection
│ ├─ 403 Forbidden → Connection REJECTED (client disabled)
│ ├─ 404 Not Found → Connection REJECTED (unknown client)
│ └─ Timeout → Fall back to clients.toml lookup
└─ NO → Look up auth_key in clients.toml
├─ Found + enabled → Assign fixed IP, allow connection
└─ Not found or disabled → Connection REJECTED
Typical Workflow
1. Set up the daemon
# Generate daemon config
camouflage-daemon --generate-config
# Edit /etc/camouflage/config.toml as needed
2. Register clients
camouflage-daemon add-client --name "alice-laptop"
camouflage-daemon add-client --name "bob-desktop"
camouflage-daemon add-client --name "server-01" --ip 10.99.0.100
3. Export and distribute profiles
camouflage-daemon export-profile \
--auth-key "tskey-..." \
--server "vpn.example.com:61700" \
--output alice-laptop.camouflage
Send the .camouflage file to the user via a secure channel.
4. Start the services
# Enable and start both the VPN daemon and client daemon
sudo systemctl enable --now camouflage camouflage-client
# Verify they're running
sudo systemctl status camouflage camouflage-client
# View logs
journalctl -u camouflage -f
journalctl -u camouflage-client -f
5. Clients connect
camouflage-client connect --profile alice-laptop.camouflage
6. Monitor and manage
# Check who's registered
camouflage-daemon list-clients
# Revoke access
camouflage-daemon revoke-client --auth-key "tskey-..."