Skip to content
Skip to content

IPsec#

2 operations. Roles, error format and pagination are common to the whole API — see the REST API overview.

Authentication

Use a named bearer token. Every endpoint except POST /api/v1/auth/login, POST /api/v1/auth/enrol and GET /api/v1/system/health requires one. A super-user creates a token with POST /api/v1/auth/tokens; the plaintext (bngtok_…) is returned exactly once at creation and only a SHA-256 hash is stored on the appliance, so a lost token is replaced rather than recovered. Send it on every request:

Authorization: Bearer bngtok_…

Each token carries a fixed role (read-only, operator or super-user) and is exempt from CSRF checks. This is the single credential you need for scripts, integrations and monitoring.

Accounts and tokens share one identity model with the appliance CLI (login.users). Repeated authentication failures lock the account/source-IP pair out temporarily (HTTP 423 on login).

Session cookies (bundled web UI only)

The appliance also accepts an interactive session cookie, which is how the bundled web UI authenticates. It is documented for completeness — API clients should not use it. It is bound to a login session and obliges the caller to manage a CSRF token, neither of which suits automation.

POST /api/v1/auth/login with username + password (and a TOTP code when enrolled) sets the bng_session cookie and returns a csrfToken (also available from GET /api/v1/auth/whoami). Cookie-authenticated mutating requests (anything other than GET/HEAD/OPTIONS) must also send that value in the X-CSRF-Token header or they are rejected with 403.

One endpoint refuses the cookie outright: GET /api/v1/metrics, the Prometheus scrape, accepts a bearer token only, so that a scraper can never keep a login session alive.

NetavoBNG Management API v1#

Contact: Netavo

IPsec#


GET /api/v1/ipsec#

IPsec peers and their security associations.

Description

One row per configured peer with its IKE SA state, rekey timers and child (ESP) SAs including byte/packet counters and traffic selectors — the API equivalent of swanctl --list-sas, joined with ipsec.peers so a configured peer with no SA still appears (state DOWN). reachable: false means strongSwan could not be queried and every state reads UNKNOWN. lastError is the manager's last apply/load failure. A peer with configured: false is an SA whose connection has been deleted but not yet torn down. Fleet-proxyable.

Input parameters

Parameter In Type Default Nullable Description
bearerToken header string N/A No Named API token — the recommended credential for automation. See Authentication in the API overview.

Responses

{
    "enabled": true,
    "reachable": true,
    "lastError": null,
    "establishedCount": 1,
    "peers": [
        {
            "name": "partner-l2tp",
            "configured": true,
            "state": "ESTABLISHED",
            "configuredRemote": "46.247.38.12",
            "localHost": "45.84.200.69",
            "remoteHost": "46.247.38.12",
            "localId": "45.84.200.69",
            "remoteId": "46.247.38.12",
            "ikeVersion": "IKEv2",
            "establishedSeconds": 4514,
            "rekeyInSeconds": 9813,
            "proposal": "AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048",
            "children": [
                {
                    "name": "l2tp",
                    "state": "INSTALLED",
                    "mode": "TUNNEL-in-UDP",
                    "espProposal": "AES_CBC-256/HMAC_SHA2_256_128",
                    "installedSeconds": 1418,
                    "rekeyInSeconds": 1850,
                    "expiresInSeconds": 2542,
                    "inBytes": 10520,
                    "inPackets": 213,
                    "outBytes": 9002,
                    "outPackets": 215,
                    "localTs": [
                        "10.200.0.0/29"
                    ],
                    "remoteTs": [
                        "10.200.1.1/32"
                    ]
                }
            ]
        }
    ]
}
Schema of the response body
{
    "type": "object",
    "properties": {
        "enabled": {
            "type": "boolean",
            "description": "ipsec.enabled in the box configuration."
        },
        "reachable": {
            "type": "boolean",
            "description": "False when strongSwan could not be queried; peers are then configuration only."
        },
        "lastError": {
            "type": "string",
            "description": "The manager's last apply/load failure, or null when everything is current.",
            "nullable": true
        },
        "peers": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/IpsecPeerStatus"
            },
            "description": "Configured peers (and any SA for a connection that is no longer configured)."
        },
        "establishedCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Peers with an established IKE SA — the number SNMP and the dashboards want.",
            "format": "int32"
        }
    },
    "description": "GET /api/v1/ipsec — the whole IPsec picture for one box.",
    "example": {
        "enabled": true,
        "reachable": true,
        "lastError": null,
        "establishedCount": 1,
        "peers": [
            {
                "name": "partner-l2tp",
                "configured": true,
                "state": "ESTABLISHED",
                "configuredRemote": "46.247.38.12",
                "localHost": "45.84.200.69",
                "remoteHost": "46.247.38.12",
                "localId": "45.84.200.69",
                "remoteId": "46.247.38.12",
                "ikeVersion": "IKEv2",
                "establishedSeconds": 4514,
                "rekeyInSeconds": 9813,
                "proposal": "AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048",
                "children": [
                    {
                        "name": "l2tp",
                        "state": "INSTALLED",
                        "mode": "TUNNEL-in-UDP",
                        "espProposal": "AES_CBC-256/HMAC_SHA2_256_128",
                        "installedSeconds": 1418,
                        "rekeyInSeconds": 1850,
                        "expiresInSeconds": 2542,
                        "inBytes": 10520,
                        "inPackets": 213,
                        "outBytes": 9002,
                        "outPackets": 215,
                        "localTs": [
                            "10.200.0.0/29"
                        ],
                        "remoteTs": [
                            "10.200.1.1/32"
                        ]
                    }
                ]
            }
        ]
    }
}
{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
    "title": "VRF not found",
    "status": 404,
    "detail": "No VRF named 'wholesale-b' is configured.",
    "instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "nullable": true
        },
        "title": {
            "type": "string",
            "nullable": true
        },
        "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "format": "int32",
            "nullable": true
        },
        "detail": {
            "type": "string",
            "nullable": true
        },
        "instance": {
            "type": "string",
            "nullable": true
        }
    },
    "example": {
        "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
        "title": "VRF not found",
        "status": 404,
        "detail": "No VRF named 'wholesale-b' is configured.",
        "instance": "/api/v1/vrfs/wholesale-b"
    }
}
{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
    "title": "VRF not found",
    "status": 404,
    "detail": "No VRF named 'wholesale-b' is configured.",
    "instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "nullable": true
        },
        "title": {
            "type": "string",
            "nullable": true
        },
        "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "format": "int32",
            "nullable": true
        },
        "detail": {
            "type": "string",
            "nullable": true
        },
        "instance": {
            "type": "string",
            "nullable": true
        }
    },
    "example": {
        "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
        "title": "VRF not found",
        "status": 404,
        "detail": "No VRF named 'wholesale-b' is configured.",
        "instance": "/api/v1/vrfs/wholesale-b"
    }
}

GET /api/v1/ipsec/peers/{name}#

One peer by name.

Description

404 when no peer of that name is configured and no SA carries it.

Input parameters

Parameter In Type Default Nullable Description
bearerToken header string N/A No Named API token — the recommended credential for automation. See Authentication in the API overview.
name path string No The swanctl connection name (ipsec.peers[].name).

Responses

{
    "name": "partner-l2tp",
    "configured": true,
    "state": "ESTABLISHED",
    "configuredRemote": "46.247.38.12",
    "localHost": "45.84.200.69",
    "remoteHost": "46.247.38.12",
    "localId": "45.84.200.69",
    "remoteId": "46.247.38.12",
    "ikeVersion": "IKEv2",
    "establishedSeconds": 4514,
    "rekeyInSeconds": 9813,
    "proposal": "AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048",
    "children": []
}
Schema of the response body
{
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "The swanctl connection name (ipsec.peers[].name)."
        },
        "configured": {
            "type": "boolean",
            "description": "True when the peer is in the box configuration. False means an SA for a connection\n            the configuration no longer has — normally a peer just deleted."
        },
        "state": {
            "type": "string",
            "description": "The IKE SA state (ESTABLISHED, CONNECTING, …), or \"DOWN\" when there is no SA, or\n            \"UNKNOWN\" when strongSwan could not be queried."
        },
        "configuredRemote": {
            "type": "string",
            "description": "The configured remote address, even when no SA exists.",
            "nullable": true
        },
        "localHost": {
            "type": "string",
            "nullable": true
        },
        "remoteHost": {
            "type": "string",
            "nullable": true
        },
        "localId": {
            "type": "string",
            "nullable": true
        },
        "remoteId": {
            "type": "string",
            "nullable": true
        },
        "ikeVersion": {
            "type": "string",
            "nullable": true
        },
        "establishedSeconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "format": "int64",
            "nullable": true
        },
        "rekeyInSeconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "format": "int64",
            "nullable": true
        },
        "proposal": {
            "type": "string",
            "description": "The negotiated IKE proposal, e.g. AES_CBC-256/HMAC_SHA2_256_128/…/MODP_2048.",
            "nullable": true
        },
        "children": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/IpsecChildSa"
            },
            "description": "The child (ESP) SAs of this peer — one per configured child, normally \"l2tp\"."
        }
    },
    "description": "One peer: its configuration and, when strongSwan is reachable, its IKE SA.",
    "example": {
        "name": "partner-l2tp",
        "configured": true,
        "state": "ESTABLISHED",
        "configuredRemote": "46.247.38.12",
        "localHost": "45.84.200.69",
        "remoteHost": "46.247.38.12",
        "localId": "45.84.200.69",
        "remoteId": "46.247.38.12",
        "ikeVersion": "IKEv2",
        "establishedSeconds": 4514,
        "rekeyInSeconds": 9813,
        "proposal": "AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048",
        "children": []
    }
}
{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
    "title": "VRF not found",
    "status": 404,
    "detail": "No VRF named 'wholesale-b' is configured.",
    "instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "nullable": true
        },
        "title": {
            "type": "string",
            "nullable": true
        },
        "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "format": "int32",
            "nullable": true
        },
        "detail": {
            "type": "string",
            "nullable": true
        },
        "instance": {
            "type": "string",
            "nullable": true
        }
    },
    "example": {
        "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
        "title": "VRF not found",
        "status": 404,
        "detail": "No VRF named 'wholesale-b' is configured.",
        "instance": "/api/v1/vrfs/wholesale-b"
    }
}
{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
    "title": "VRF not found",
    "status": 404,
    "detail": "No VRF named 'wholesale-b' is configured.",
    "instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "nullable": true
        },
        "title": {
            "type": "string",
            "nullable": true
        },
        "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "format": "int32",
            "nullable": true
        },
        "detail": {
            "type": "string",
            "nullable": true
        },
        "instance": {
            "type": "string",
            "nullable": true
        }
    },
    "example": {
        "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
        "title": "VRF not found",
        "status": 404,
        "detail": "No VRF named 'wholesale-b' is configured.",
        "instance": "/api/v1/vrfs/wholesale-b"
    }
}
{
    "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
    "title": "VRF not found",
    "status": 404,
    "detail": "No VRF named 'wholesale-b' is configured.",
    "instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "nullable": true
        },
        "title": {
            "type": "string",
            "nullable": true
        },
        "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "format": "int32",
            "nullable": true
        },
        "detail": {
            "type": "string",
            "nullable": true
        },
        "instance": {
            "type": "string",
            "nullable": true
        }
    },
    "example": {
        "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
        "title": "VRF not found",
        "status": 404,
        "detail": "No VRF named 'wholesale-b' is configured.",
        "instance": "/api/v1/vrfs/wholesale-b"
    }
}

Schemas#

IpsecChildSa#

Name Type Description
espProposal string | null
expiresInSeconds
inBytes
inPackets
installedSeconds
localTs Array<string> Our side of the tunnel — must cover the box's L2TP source address (doc 46 §46.2).
mode string | null Encapsulation as strongSwan reports it, e.g. TUNNEL or TUNNEL-in-UDP.
name string
outBytes
outPackets
rekeyInSeconds
remoteTs Array<string> The peer's selectors; the data plane diverts traffic to these for encryption.
state string INSTALLED, REKEYING, …

IpsecPeerStatus#

Name Type Description
children Array<IpsecChildSa> The child (ESP) SAs of this peer — one per configured child, normally "l2tp".
configured boolean True when the peer is in the box configuration. False means an SA for a connection the configuration no longer has — normally a peer just deleted.
configuredRemote string | null The configured remote address, even when no SA exists.
establishedSeconds
ikeVersion string | null
localHost string | null
localId string | null
name string The swanctl connection name (ipsec.peers[].name).
proposal string | null The negotiated IKE proposal, e.g. AES_CBC-256/HMAC_SHA2_256_128/…/MODP_2048.
rekeyInSeconds
remoteHost string | null
remoteId string | null
state string The IKE SA state (ESTABLISHED, CONNECTING, …), or "DOWN" when there is no SA, or "UNKNOWN" when strongSwan could not be queried.

IpsecStatus#

Name Type Description
enabled boolean ipsec.enabled in the box configuration.
establishedCount Peers with an established IKE SA — the number SNMP and the dashboards want.
lastError string | null The manager's last apply/load failure, or null when everything is current.
peers Array<IpsecPeerStatus> Configured peers (and any SA for a connection that is no longer configured).
reachable boolean False when strongSwan could not be queried; peers are then configuration only.

ProblemDetails#

Name Type Description
detail string | null
instance string | null
status
title string | null
type string | null

Security schemes#

Name Type Scheme Description
bearerToken http bearer Named API token — the recommended credential for automation. See Authentication in the API overview.
sessionCookie apiKey Interactive session cookie used by the bundled web UI. Not the integration path for API clients — use a bearer token. See Authentication in the API overview.

Tags#

Name Description
IPsec