HTTPS API

VyOS provides a built-in HTTPS/HTTP server for the web interface and REST/GraphQL API. This makes it possible to automate router management and integrate it with external systems.

Overview

Key components

HTTPS Server:

  • Nginx-based web server
  • TLS/SSL encryption
  • Support for self-signed and real certificates
  • Virtual hosts (vhost)

API Endpoints:

  • REST API: HTTP/JSON API for configuration and operations (VyOS 1.5+)
  • GraphQL API: Flexible query-based API (VyOS 1.5+)
  • Legacy API: Compatibility with VyOS 1.4

Authentication methods:

  • API keys (recommended)
  • Token-based authentication

VyOS 1.4 vs 1.5

VyOS 1.4 (Sagitta):

set service https api keys id <name> key '<api-key>'

VyOS 1.5 (Circinus):

set service https api keys id <name> key '<api-key>'
set service https api rest          # Enable REST API
set service https api graphql       # Enable GraphQL API (optional)

In VyOS 1.5 the REST and GraphQL endpoints are separate.

Basic configuration

Minimal HTTPS setup

# Basic HTTPS server
set service https listen-address 0.0.0.0
set service https port 443

# Self-signed certificate (for testing)
# VyOS generates one automatically on first startup

commit
save

Enabling the REST API (VyOS 1.5)

# HTTPS server
set service https listen-address 0.0.0.0
set service https port 443

# REST API
set service https api rest
set service https api keys id admin key 'MySecureAPIKey123!'

commit
save

Enabling the REST API (VyOS 1.4)

set service https listen-address 0.0.0.0
set service https port 443

# API (in 1.4 there is no rest/graphql split)
set service https api keys id admin key 'MySecureAPIKey123!'

commit
save

Verifying operation

# Check the service status
show service https

# Check the process
ps aux | grep nginx

# Check the ports
netstat -tlnp | grep 443

# Test the REST API
curl -k https://localhost/retrieve \
  -H "Content-Type: application/json" \
  -d '{"op": "showConfig", "path": ["system", "host-name"]}' \
  -H "key: MySecureAPIKey123!"

Certificate configuration

Self-signed certificate

VyOS automatically creates a self-signed certificate the first time HTTPS starts.

Generating a new one:

# Create a new self-signed certificate
generate pki certificate self-signed install vyos-https \
  common-name "vyos.company.local" \
  country "US" \
  state "California" \
  locality "San Francisco" \
  organization "Company Inc" \
  days 3650

# Apply it to HTTPS
set service https certificates certificate vyos-https

commit
save

Certificate from a CA

Using a certificate from a trusted CA (Let’s Encrypt, a corporate CA).

Preparing the certificates

You will need:

  • Certificate (server.crt): The server certificate
  • Private Key (server.key): The private key
  • CA Certificate (ca.crt): The CA certificate (optional)

Importing the certificates

# Copy the files to the router
scp server.crt vyos@router:/tmp/
scp server.key vyos@router:/tmp/
scp ca.crt vyos@router:/tmp/

# On the router
configure

# Import the CA
generate pki ca import ca-production file /tmp/ca.crt

# Import the server certificate and key
generate pki certificate import vyos-https-prod \
  certificate-file /tmp/server.crt \
  private-key-file /tmp/server.key

# Apply it to HTTPS
set service https certificates certificate vyos-https-prod

commit
save

# Remove the temporary files
rm /tmp/server.crt /tmp/server.key /tmp/ca.crt

Let’s Encrypt with Certbot

Automatically obtaining and renewing Let’s Encrypt certificates.

# Install Certbot (in the shell, not in configure)
sudo apt-get update
sudo apt-get install certbot

# Obtain the certificate (standalone mode)
# The HTTPS service must be temporarily stopped
sudo systemctl stop nginx
sudo certbot certonly --standalone -d vyos.example.com

# Import into VyOS
configure
generate pki certificate import letsencrypt-vyos \
  certificate-file /etc/letsencrypt/live/vyos.example.com/fullchain.pem \
  private-key-file /etc/letsencrypt/live/vyos.example.com/privkey.pem

set service https certificates certificate letsencrypt-vyos
commit
save

# Restart HTTPS
restart service https

Automatic renewal

Create the script /config/scripts/renew-cert.sh:

#!/bin/bash
# Stop nginx
systemctl stop nginx

# Renew the certificate
certbot renew --quiet

# Check the renewal
if [ $? -eq 0 ]; then
  # Import the new certificate
  /usr/libexec/vyos/conf_mode/pki.py import-cert \
    letsencrypt-vyos \
    /etc/letsencrypt/live/vyos.example.com/fullchain.pem \
    /etc/letsencrypt/live/vyos.example.com/privkey.pem

  # Restart nginx
  systemctl restart nginx
else
  # Start nginx even on error
  systemctl start nginx
fi

Setting up cron:

# Add to crontab (check every day at 3:00)
set system task-scheduler task renew-cert executable path '/config/scripts/renew-cert.sh'
set system task-scheduler task renew-cert interval 1d
set system task-scheduler task renew-cert start-time '03:00:00'

commit

REST API

API structure

The REST API uses POST requests to the /configure, /retrieve, /show, etc. endpoints.

Base URL: https://<router-ip>/

Endpoints:

  • /retrieve - Retrieve configuration (showConfig)
  • /configure - Change configuration (set, delete, comment)
  • /show - Operational commands (show)
  • /generate - Generate keys and certificates
  • /reset - Reset operations
  • /image - Manage system images
  • /config-file - Save/load configuration
  • /reboot, /poweroff - Power management

Authentication

# Header
key: MySecureAPIKey123!

# Or in the URL (not recommended)
?key=MySecureAPIKey123!

REST API request examples

Retrieving configuration (retrieve)

# Hostname
curl -k https://192.168.1.1/retrieve \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "showConfig",
    "path": ["system", "host-name"]
  }'

# All interfaces
curl -k https://192.168.1.1/retrieve \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "showConfig",
    "path": ["interfaces"]
  }'

# The entire configuration
curl -k https://192.168.1.1/retrieve \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "showConfig",
    "path": []
  }'

Response:

{
  "success": true,
  "data": {
    "host-name": "vyos-router"
  }
}

Changing configuration (configure)

Set operation:

# Set the hostname
curl -k https://192.168.1.1/configure \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "set",
    "path": ["system", "host-name", "vyos-gw"]
  }'

# Set an IP address on an interface
curl -k https://192.168.1.1/configure \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "set",
    "path": ["interfaces", "ethernet", "eth1", "address", "192.168.10.1/24"]
  }'

Delete operation:

curl -k https://192.168.1.1/configure \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "delete",
    "path": ["interfaces", "ethernet", "eth1", "address", "192.168.10.1/24"]
  }'

Comment operation:

curl -k https://192.168.1.1/configure \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "comment",
    "path": ["interfaces", "ethernet", "eth1"],
    "value": "Management interface"
  }'

Batch operations

Multiple changes in a single request:

curl -k https://192.168.1.1/configure \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "set",
    "path": ["interfaces", "ethernet", "eth2"],
    "commands": [
      {"op": "set", "path": ["address", "10.0.0.1/24"]},
      {"op": "set", "path": ["description", "LAN"]},
      {"op": "set", "path": ["mtu", "1500"]}
    ]
  }'

Show commands

# Show interfaces
curl -k https://192.168.1.1/show \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "show",
    "path": ["interfaces"]
  }'

# Show version
curl -k https://192.168.1.1/show \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "show",
    "path": ["version"]
  }'

Generate operations

# Generate WireGuard key
curl -k https://192.168.1.1/generate \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "generate",
    "path": ["wireguard", "default-keypair"]
  }'

Config-file operations

# Save configuration
curl -k https://192.168.1.1/config-file \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "save"
  }'

# Load configuration
curl -k https://192.168.1.1/config-file \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "load",
    "file": "/config/backup.config"
  }'

Power management

# Reboot
curl -k https://192.168.1.1/reboot \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "reboot",
    "path": ["now"]
  }'

# Poweroff
curl -k https://192.168.1.1/poweroff \
  -H "Content-Type: application/json" \
  -H "key: MySecureAPIKey123!" \
  -d '{
    "op": "poweroff",
    "path": ["now"]
  }'

Python examples

import requests
import json

# Disable SSL warnings for self-signed certificates
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

class VyOSAPI:
    def __init__(self, host, api_key):
        self.base_url = f"https://{host}"
        self.headers = {
            "Content-Type": "application/json",
            "key": api_key
        }

    def show_config(self, path):
        """Retrieve configuration"""
        data = {
            "op": "showConfig",
            "path": path
        }
        response = requests.post(
            f"{self.base_url}/retrieve",
            headers=self.headers,
            json=data,
            verify=False
        )
        return response.json()

    def set_config(self, path, value=None):
        """Set configuration"""
        data = {
            "op": "set",
            "path": path
        }
        if value:
            data["value"] = value

        response = requests.post(
            f"{self.base_url}/configure",
            headers=self.headers,
            json=data,
            verify=False
        )
        return response.json()

    def delete_config(self, path):
        """Delete configuration"""
        data = {
            "op": "delete",
            "path": path
        }
        response = requests.post(
            f"{self.base_url}/configure",
            headers=self.headers,
            json=data,
            verify=False
        )
        return response.json()

    def save(self):
        """Save configuration"""
        data = {"op": "save"}
        response = requests.post(
            f"{self.base_url}/config-file",
            headers=self.headers,
            json=data,
            verify=False
        )
        return response.json()

    def show(self, path):
        """Operational show command"""
        data = {
            "op": "show",
            "path": path
        }
        response = requests.post(
            f"{self.base_url}/show",
            headers=self.headers,
            json=data,
            verify=False
        )
        return response.json()

# Usage
api = VyOSAPI("192.168.1.1", "MySecureAPIKey123!")

# Get the hostname
result = api.show_config(["system", "host-name"])
print(f"Hostname: {result['data']}")

# Set a new hostname
api.set_config(["system", "host-name", "new-hostname"])
api.save()

# Show interfaces
interfaces = api.show(["interfaces"])
print(json.dumps(interfaces, indent=2))

GraphQL API (VyOS 1.5+)

The GraphQL API provides a more flexible, query-based interface.

Enabling GraphQL

set service https api graphql
set service https api keys id graphql-user key 'GraphQLKey123!'

commit
save

GraphQL Endpoint

URL: https://<router-ip>/graphql

GraphQL request examples

Retrieving configuration

curl -k https://192.168.1.1/graphql \
  -H "Content-Type: application/json" \
  -H "key: GraphQLKey123!" \
  -d '{
    "query": "{ systemStatus { hostname version uptime } }"
  }'

Changing configuration

curl -k https://192.168.1.1/graphql \
  -H "Content-Type: application/json" \
  -H "key: GraphQLKey123!" \
  -d '{
    "query": "mutation { configSet(path: \"system host-name\", value: \"vyos-gw\") { success errors } }"
  }'

The GraphQL documentation is available through the GraphiQL interface: https://<router-ip>/graphql (in a browser)

Advanced configuration

Multiple API keys

# Admin full access
set service https api keys id admin key 'AdminKey123!'

# Read-only user (restricted only through the firewall)
set service https api keys id readonly key 'ReadOnlyKey456!'

# Monitoring system
set service https api keys id monitoring key 'MonitorKey789!'

commit

Note: The VyOS API does not have built-in RBAC. Use separate keys and control access through the firewall.

Restricting API access

# Allow the API only from specific IPs
set firewall ipv4 input filter rule 100 action accept
set firewall ipv4 input filter rule 100 destination port 443
set firewall ipv4 input filter rule 100 protocol tcp
set firewall ipv4 input filter rule 100 source address 192.168.1.0/24
set firewall ipv4 input filter rule 100 description 'Allow HTTPS API from management network'

# Block everyone else
set firewall ipv4 input filter rule 109 action drop
set firewall ipv4 input filter rule 109 destination port 443
set firewall ipv4 input filter rule 109 protocol tcp

commit

Listening on specific interfaces

# Only on the management interface
set service https listen-address 192.168.1.1

# On several interfaces
set service https listen-address 192.168.1.1
set service https listen-address 10.0.0.1

commit

Changing the port

# Non-standard port
set service https port 8443

commit

Virtual hosts

# Vhost for different domains
set service https virtual-host api.example.com listen-address 0.0.0.0
set service https virtual-host api.example.com listen-port 443
set service https virtual-host api.example.com server-name api.example.com

# A separate certificate for the vhost
set service https virtual-host api.example.com certificates certificate api-cert

commit

CORS settings

For web applications that call the API:

set service https api cors allow-origin '*'

# Or specific domains
set service https api cors allow-origin 'https://admin.example.com'

commit

Security

Security recommendations

  1. Strong API keys:
# Generate a random key
openssl rand -base64 32
# Example: xK8pL9mN2qR5sT7vW0yZ3aB6cD9eF1gH2iJ4kL7mN0pQ=

set service https api keys id admin key 'xK8pL9mN2qR5sT7vW0yZ3aB6cD9eF1gH2iJ4kL7mN0pQ='
  1. Real TLS certificates:

    • Use Let’s Encrypt or a corporate CA
    • Do not use self-signed certificates in production
  2. Access restriction:

# Firewall rules
set firewall ipv4 input filter rule 100 source address 192.168.1.0/24

# Listen only on the management interface
set service https listen-address 192.168.1.1
  1. Rate limiting:
set firewall ipv4 input filter rule 100 recent count 10
set firewall ipv4 input filter rule 100 recent time minute 1
  1. TLS version:
# Minimum version TLS 1.2
set service https tls-version '1.2'
  1. Disable HTTP (HTTPS only):

    • By default VyOS uses HTTPS only
  2. API key rotation:

    • Rotate API keys regularly
    • Use different keys for different applications
  3. Logging API requests:

# Nginx logs
show log https

# Access log
cat /var/log/nginx/access.log

Access auditing

# View the Nginx access logs
show log https access

# Search for failed requests
cat /var/log/nginx/access.log | grep '401\|403'

# Active connections
netstat -tn | grep :443

Integration with external systems

Ansible

---
- name: Configure VyOS via API
  hosts: localhost
  gather_facts: no
  vars:
    vyos_host: "192.168.1.1"
    vyos_api_key: "MySecureAPIKey123!"

  tasks:
    - name: Set hostname
      uri:
        url: "https://{{ vyos_host }}/configure"
        method: POST
        headers:
          key: "{{ vyos_api_key }}"
          Content-Type: "application/json"
        body_format: json
        body:
          op: "set"
          path: ["system", "host-name", "vyos-ansible"]
        validate_certs: no
      register: result

    - name: Save configuration
      uri:
        url: "https://{{ vyos_host }}/config-file"
        method: POST
        headers:
          key: "{{ vyos_api_key }}"
          Content-Type: "application/json"
        body_format: json
        body:
          op: "save"
        validate_certs: no

Terraform

terraform {
  required_providers {
    vyos = {
      source = "example/vyos"
      version = "1.0.0"
    }
  }
}

provider "vyos" {
  endpoint = "https://192.168.1.1"
  api_key  = "MySecureAPIKey123!"
}

resource "vyos_interface" "eth2" {
  name        = "eth2"
  address     = "10.0.0.1/24"
  description = "LAN managed by Terraform"
}

Monitoring (Prometheus)

# VyOS metrics exporter for Prometheus
from prometheus_client import start_http_server, Gauge
import requests
import time

# Metrics
interface_status = Gauge('vyos_interface_status', 'Interface status', ['interface'])
interface_rx_bytes = Gauge('vyos_interface_rx_bytes', 'RX bytes', ['interface'])
interface_tx_bytes = Gauge('vyos_interface_tx_bytes', 'TX bytes', ['interface'])

class VyOSExporter:
    def __init__(self, vyos_host, api_key):
        self.api = VyOSAPI(vyos_host, api_key)

    def collect(self):
        # Get interface statistics
        result = self.api.show(["interfaces"])

        for iface, data in result['data'].items():
            interface_status.labels(interface=iface).set(1 if data['state'] == 'up' else 0)
            interface_rx_bytes.labels(interface=iface).set(data['stats']['rx_bytes'])
            interface_tx_bytes.labels(interface=iface).set(data['stats']['tx_bytes'])

if __name__ == '__main__':
    exporter = VyOSExporter("192.168.1.1", "MySecureAPIKey123!")
    start_http_server(9100)

    while True:
        exporter.collect()
        time.sleep(15)

Webhook for events

# Event handler for sending a webhook
set system event-handler route-change name 'route-webhook'
set system event-handler route-change script '/config/scripts/route-webhook.sh'
set system event-handler route-change pattern 'route added|route deleted'

commit

/config/scripts/route-webhook.sh:

#!/bin/bash
EVENT="$1"
curl -X POST https://monitoring.example.com/webhook \
  -H "Content-Type: application/json" \
  -d "{\"event\": \"$EVENT\", \"router\": \"vyos-gw\", \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}"

Troubleshooting

HTTPS does not start

Problem: The HTTPS service fails to start.

Diagnostics:

# Check the status
show service https

# Nginx status
systemctl status nginx

# Logs
show log https
cat /var/log/nginx/error.log

# Check the nginx configuration
nginx -t

Possible causes:

  1. Port 443 is occupied by another process
  2. Certificate issues
  3. A syntax error in the configuration

Solution:

# Check what is using the port
netstat -tlnp | grep :443

# Restart the service
restart service https

The API returns 401 Unauthorized

Problem: API requests fail authentication.

Causes:

  1. Incorrect API key
  2. API key not configured
  3. Incorrect header

Solution:

# Check the API keys
show service https api keys

# Make sure the key is passed in the header
curl -k https://192.168.1.1/retrieve \
  -H "key: MySecureAPIKey123!" \
  -v

The API returns 404

Problem: The endpoint is not found.

VyOS 1.5 specifics:

  • In VyOS 1.5 you must explicitly enable the REST API:
set service https api rest
commit

Slow API responses

Problem: API requests take a long time to complete.

Diagnostics:

# CPU load
show system cpu

# Memory
show system memory

# Process list
top

Solution:

  • Reduce the request rate
  • Use batch operations
  • Cache results on the client

SSL certificate issues

Problem: “SSL certificate problem: self signed certificate”.

Solution:

# In curl: use -k
curl -k https://...

# In Python: verify=False
requests.post(url, verify=False)

# Or import the CA certificate into the system

Monitoring and metrics

Nginx statistics

# Active connections
cat /var/run/nginx/nginx-status

# Access log analysis
cat /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn

# Requests per minute
cat /var/log/nginx/access.log | awk '{print $4}' | cut -d: -f1-3 | uniq -c

API usage

# Number of API requests
grep "POST /configure" /var/log/nginx/access.log | wc -l

# Top API users (by IP)
grep "POST /" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn

# API errors
grep "HTTP/1.1\" [45]" /var/log/nginx/access.log

Usage examples

Example 1: Automating DHCP configuration

import requests
import json

class DHCPManager:
    def __init__(self, router, api_key):
        self.router = router
        self.api_key = api_key
        self.base_url = f"https://{router}"
        self.headers = {
            "Content-Type": "application/json",
            "key": api_key
        }

    def add_dhcp_static_mapping(self, network, name, mac, ip):
        """Add a static DHCP mapping"""
        path = [
            "service", "dhcp-server",
            "shared-network-name", network,
            "subnet", self.get_subnet(network),
            "static-mapping", name,
            "mac-address", mac
        ]

        # Set MAC
        self.api_call("/configure", {"op": "set", "path": path})

        # Set IP
        path[-1] = "ip-address"
        path.append(ip)
        self.api_call("/configure", {"op": "set", "path": path})

        # Save
        self.api_call("/config-file", {"op": "save"})

    def api_call(self, endpoint, data):
        response = requests.post(
            f"{self.base_url}{endpoint}",
            headers=self.headers,
            json=data,
            verify=False
        )
        return response.json()

    def get_subnet(self, network):
        # Get the subnet for the network
        result = self.api_call("/retrieve", {
            "op": "showConfig",
            "path": ["service", "dhcp-server", "shared-network-name", network]
        })
        return list(result['data']['subnet'].keys())[0]

# Usage
dhcp = DHCPManager("192.168.1.1", "MySecureAPIKey123!")
dhcp.add_dhcp_static_mapping("LAN", "server1", "00:50:56:11:22:33", "192.168.1.10")

Example 2: Configuration backup

#!/bin/bash
# backup-vyos.sh - Automatic configuration backup

ROUTER="192.168.1.1"
API_KEY="MySecureAPIKey123!"
BACKUP_DIR="/backup/vyos"
DATE=$(date +%Y%m%d-%H%M%S)

# Retrieve the configuration
curl -k https://${ROUTER}/retrieve \
  -H "Content-Type: application/json" \
  -H "key: ${API_KEY}" \
  -d '{"op": "showConfig", "path": []}' \
  > ${BACKUP_DIR}/config-${DATE}.json

# Retrieve the text configuration
curl -k https://${ROUTER}/retrieve \
  -H "Content-Type: application/json" \
  -H "key: ${API_KEY}" \
  -d '{"op": "show", "path": ["configuration"]}' \
  > ${BACKUP_DIR}/config-${DATE}.txt

# Remove old backups (>30 days)
find ${BACKUP_DIR} -type f -mtime +30 -delete

echo "Backup completed: ${BACKUP_DIR}/config-${DATE}.json"

Example 3: Health check monitoring

#!/usr/bin/env python3
# vyos-health-check.py

import requests
import sys
import json
from datetime import datetime

class VyOSHealthCheck:
    def __init__(self, router, api_key):
        self.api = VyOSAPI(router, api_key)
        self.status = {"healthy": True, "issues": []}

    def check_interfaces(self):
        """Check the interface status"""
        result = self.api.show(["interfaces"])

        for iface, data in result['data'].items():
            if data['admin_state'] == 'up' and data['state'] != 'up':
                self.status["healthy"] = False
                self.status["issues"].append(f"Interface {iface} is down")

    def check_bgp(self):
        """Check the BGP neighbors"""
        result = self.api.show(["bgp", "summary"])

        for neighbor in result['data']['neighbors']:
            if neighbor['state'] != 'Established':
                self.status["healthy"] = False
                self.status["issues"].append(f"BGP neighbor {neighbor['ip']} not established")

    def check_vpn(self):
        """Check the VPN tunnels"""
        result = self.api.show(["vpn", "ipsec", "sa"])

        for tunnel in result['data']['tunnels']:
            if tunnel['state'] != 'up':
                self.status["healthy"] = False
                self.status["issues"].append(f"VPN tunnel {tunnel['name']} is down")

    def run(self):
        """Run all checks"""
        self.check_interfaces()
        self.check_bgp()
        self.check_vpn()

        # Output the result
        print(json.dumps({
            "timestamp": datetime.utcnow().isoformat(),
            "healthy": self.status["healthy"],
            "issues": self.status["issues"]
        }, indent=2))

        # Exit code
        sys.exit(0 if self.status["healthy"] else 1)

if __name__ == '__main__':
    checker = VyOSHealthCheck("192.168.1.1", "MySecureAPIKey123!")
    checker.run()

Best practices

  1. Use HTTPS - never use HTTP in production
  2. Strong API keys - at least 32 characters, random
  3. Real certificates - Let’s Encrypt or a corporate CA
  4. Restrict access - firewall rules for API endpoints
  5. Separate keys - use different API keys for different applications
  6. Rate limiting - protection against brute-force
  7. Logging - enable detailed logging of API requests
  8. Monitoring - track API usage
  9. Versioning - document the API version in your code
  10. Error handling - handle API errors correctly
  11. Timeout - set reasonable timeouts for API requests
  12. Retry logic - implement retries for transient errors
  13. Backup - automate configuration backups through the API
  14. Testing - test API integrations in a staging environment
  15. Documentation - document all API integrations

Conclusion

The HTTPS/REST API in VyOS provides a powerful tool for automation and integration. Proper security configuration (certificates, API keys, firewall) is critical for protecting your infrastructure.

Main use cases:

  • Configuration automation through Ansible/Terraform
  • Monitoring the router’s state
  • Integration with external systems
  • Self-service portals for network management
  • CI/CD for network infrastructure as code

The VyOS API provides full access to the configuration and operational commands, making VyOS an ideal choice for modern automated network infrastructures.

Reviewed by OpenNix LLC · Last updated on