README
¶
Containerlab API Server
This project provides a standalone RESTful API server written in Go to interact with the Containerlab command-line tool (clab). It allows you to manage Containerlab deployments programmatically or remotely.
Features
- Lab Management: Deploy, destroy, redeploy, inspect, and list labs
- Node Operations: Execute commands and save configurations
- Topology Tools: Generate and deploy CLOS topologies
- Network Tools: Manage network emulation, virtual Ethernet pairs, VxLAN tunnels
- Certification tools: Certificate management, user authentication via Linux PAM and JWT
- User Context: Track ownership and manage files within user home directories
- Configuration: Configurable via environment variables and .env files
- Documentation: Embedded Swagger UI for API exploration
Prerequisites
Before running the clab-api server, ensure the following are set up on the server machine:
- Containerlab: Requieres clab
v0.68.0+Theclabexecutable must be installed and available in the system'sPATHfor the user running the API server. See Containerlab Installation Guide.
[!NOTE] Containerlab 0.68.0+ is not available yet, but the 0.1.0 release of the clab-api-server is compatible with the 0.67.0 version of Containerlab. 2. Linux System: The API server is designed for Linux environments. 3. PAM Configuration: Pluggable Authentication Modules (PAM) must be configured correctly ( Linux default is good ). The API uses the
loginservice by default. PAM is available on most Linux distributions out of the box and doesn't require additional installation for using the pre-built binary. 4. User Group: Linux groups need to exist according to your .env settings to successfully authenticate via the/loginendpoint.
Installation
-
Download: Obtain the latest
clab-api-serverbinary from the Releases page. -
Place Binary: Copy the downloaded binary to a suitable location on your server, for example,
/usr/local/bin/.sudo mv ./clab-api-server /usr/local/bin/clab-api-server sudo chmod +x /usr/local/bin/clab-api-server -
Optional: Create User Group: Ensure the
clab_apigroup exists.sudo groupadd clab_api -
Optional: Add Users: Add any Linux users who should be allowed to use the API to the
clab_apigroup.sudo usermod -aG clab_api your_linux_username
[!NOTE] If the API_USER_GROUP is not set in the
.envfile, the user must be a member of theclab_adminsgroup to authenticate via the/loginendpoint.
Configuration
The server is configured via environment variables or a .env file located in the same directory as the binary.
-
Create
.envfile:cd /path/where/you/placed/the/binary # e.g., /usr/local/bin sudo nano .env -
Populate
.env: Copy the following content and changeJWT_SECRETto a strong, random value.# --- Server Settings --- API_PORT=8080 # --- Security --- # IMPORTANT: Change this to a long, random, secret string! JWT_SECRET=default_secret_change_me JWT_EXPIRATION_MINUTES=60m # Token validity duration # Optional: Specify a group whose members bypass ownership checks (e.g., "clab_superusers") # Leave empty ("") to disable superuser functionality. SUPERUSER_GROUP="" # Optional: Specify a group whose members can use the API # The API group name, if not defined, the user needs to be in clab_admins group API_USER_GROUP=clab_api # --- Containerlab --- # Specify the container runtime clab should use (e.g., docker, podman). Defaults to 'docker'. CLAB_RUNTIME=docker # --- Logging --- # Log level: debug, info, warn, error, fatal. Defaults to 'info'. LOG_LEVEL=info # --- TLS --- # Enable HTTPS (true/false). Defaults to false. TLS_ENABLE=false # Path to the TLS certificate file (e.g., /etc/clab-api/cert.pem) TLS_CERT_FILE="" # Path to the TLS key file (e.g., /etc/clab-api/key.pem) TLS_KEY_FILE="" # --- Gin Web Framework Settings --- # Gin mode: debug, release, test. Defaults to 'debug'. Use 'release' for production. GIN_MODE=debug # Comma-separated list of trusted proxy IPs/CIDRs, or "nil" to disable proxy trust. # Empty string (default) trusts all proxies (use with caution). # Example: TRUSTED_PROXIES="192.168.1.100,10.0.0.0/16" TRUSTED_PROXIES="" -
Set Permissions: Ensure the
.envfile is readable by the user running the server.# Example if running as root, adjust owner/group if running as a different user sudo chown root:root .env sudo chmod 600 .env
Environment Variables: Any setting in the .env file can be overridden by setting the corresponding environment variable (e.g., export API_PORT=9090).
Running the Server
You can run the server directly or set it up as a systemd service for background operation and management.
Directly (for testing):
# Run as a user with clab and container runtime access
# (sudo might be needed if that user is root or requires elevated privileges for runtime access)
sudo /usr/local/bin/clab-api-server
As a systemd Service (Recommended):
- Create Service File: Create a file named
/etc/systemd/system/clab-api.service:
sudo nano /etc/systemd/system/clab-api.service
- Add Service Definition: Paste the following content. Adjust User, Group, WorkingDirectory, and ExecStart if necessary. Ensure the specified User has clab and container runtime access, and can read the .env file.
[Unit]
Description=Containerlab API Server
After=network.target docker.service # Add other runtimes if needed (e.g., podman.service)
[Service]
User=root # Or a dedicated user with necessary permissions
Group=root # Or the primary group of the dedicated user
WorkingDirectory=/usr/local/bin # Directory containing the binary and .env file
ExecStart=/usr/local/bin/clab-api-server
Restart=on-failure
RestartSec=5s
# Optional: Load environment variables from a different file if not using .env in WorkingDirectory
# EnvironmentFile=/etc/clab-api/clab-api.conf
[Install]
WantedBy=multi-user.target
- Enable and Start:
sudo systemctl daemon-reload
sudo systemctl enable clab-api.service
sudo systemctl start clab-api.service
- Check Status:
sudo systemctl status clab-api.service
journalctl -u clab-api.service -f # View logs
API Usage
Authentication
- Endpoint:
POST /login - Request Body (JSON):
{
"username": "your_linux_user",
"password": "your_linux_password"
}
(Note: your_linux_user must be a member of the API_USER_GROUP or be in the clab_admins group)
- Response (JSON):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Copy the received JWT token.
Authenticated Requests
For all endpoints under /api/v1/, include the JWT token in the Authorization header:
Authorization: Bearer <your_jwt_token>
Example using curl:
TOKEN="your_jwt_token"
API_HOST="localhost:8080" # Or your server address
# List labs
curl -H "Authorization: Bearer $TOKEN" http://$API_HOST/api/v1/labs
API Documentation (Swagger UI)
Once the server is running, access the interactive API documentation in your browser:
http://<server_ip_or_hostname>:<API_PORT>/swagger/index.html
(e.g., http://localhost:8080/swagger/index.html)
The Swagger UI allows you to:
- Explore all available endpoints.
- View request/response models.
- Try out API calls directly from the browser (use the "Authorize" button to input your
Bearer <token>).
Privilege Model and Security
Server User: The API server process runs as the user specified in the systemd service file or the user who manually starts it. This user requires:
- Permission to execute
clab. - Access to the configured container runtime (e.g., member of
dockergroup). - Read/write access to
~/.clab/directories for all potential authenticated users if deploying topologies via content/archive or using certificate features. This is a significant permission requirement. Consider security implications carefully. - Read access to the
.envconfiguration file.
Authenticated User: The API authenticates Linux users via PAM and checks for API_USER_GROUP group membership.
Command Execution: clab commands are executed as the server user, not the authenticated user.
Ownership:
- Lab ownership for API operations (inspect, destroy, list, etc.) is determined by the owner label set on containers by clab during deployment.
- File operations (topology saving, certificate generation) attempt to create files/directories within the authenticated user's home directory (
~/.clab/) and set ownership to that user. This requires the server user to have sufficient permissions (e.g., running as root or having write access to user homes).
Security Measures:
- JWT for session management.
- PAM for credential validation.
- Input validation (regex) for names and paths.
- Path sanitization to prevent directory traversal.
- Configurable TLS for encrypted communication.
- Configurable trusted proxies.
- Command execution timeout.
IMPORTANT: Granting the server user write access to user home directories has security implications. Ensure you understand and accept the risks.
Development
These instructions are for developers contributing to the clab-api server. Users should refer to the Installation section above.
Prerequisites
- Go: Version 1.21 or higher.
- Task: A task runner. Install via Task Installation.
- System Dependencies:
build-essential,libpam-dev(Debian/Ubuntu) orpam-devel(CentOS/Fedora).
Setup
- Clone:
git clone https://github.com/srl-labs/clab-api-server.git && cd clab-api - Install Dependencies:
task deps(Installs system build dependencies) - Configure Environment: Copy
.env.exampleto.envand set a strongJWT_SECRET. - Build:
task(Runsgo mod tidy, generates Swagger docs, and builds the binaryclab-api-server)
Taskfile Commands
task tidy: Rungo mod tidy.task swag: Generate/update Swagger documentation (./docs). Requires swag CLI (go install github.com/swaggo/swag/cmd/swag@latest).task build: Compile the server binary.task deps: Install system build dependencies using apt.task: Default task: runs tidy, swag, then build.
Running Locally
# Ensure clab is in PATH and you have runtime access
./clab-api-server
Access Swagger UI at http://localhost:8080/swagger/index.html.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
server
command
cmd/server/main.go
|
cmd/server/main.go |
|
Package docs Code generated by swaggo/swag.
|
Package docs Code generated by swaggo/swag. |
|
internal
|
|
|
api
internal/api/auth_handlers.go
|
internal/api/auth_handlers.go |
|
auth
internal/auth/credentials.go
|
internal/auth/credentials.go |
|
clab
internal/clab/executor.go
|
internal/clab/executor.go |
|
config
internal/config/config.go
|
internal/config/config.go |
|
models
internal/models/models.go
|
internal/models/models.go |