Skip to main content

Manage IPsec tunnelers

This guide shows how to create and manage IPsec tunnelers through the NetFoundry API. For the concepts behind the bridge and the console workflow, see IPsec tunnelers overview.

You'll need curl and jq. Set NETFOUNDRY_API_TOKEN before you start — see Authentication if you don't have a token yet.

NF_API=https://gateway.production.netfoundry.io
note

IPsec tunnelers are a network capability. The target network must be provisioned and have the IPsec tunneler capability enabled, or create calls are rejected. IPsec tunneler endpoints are part of the /core/v3 API.

Create a tunneler

Provisioning runs asynchronously. The call returns 202 Accepted, and the response includes the generated pre-shared key once — capture it now, because it isn't returned again on later reads.

  1. Create the tunneler, supplying the network, cloud provider, region, the customer's public IP, and the peer CIDRs:

    NF_CREATE=$(curl -s -X POST ${NF_API}/core/v3/ipsec-tunnelers \
    --header "Authorization: Bearer ${NETFOUNDRY_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --data '{
    "networkId": "'"${NF_NETWORK}"'",
    "name": "acme-dc-east",
    "provider": "AWS",
    "region": "us-east-1",
    "customerPublicIp": "203.0.113.42",
    "customerPeerCidrs": ["10.20.0.0/16", "192.168.5.0/24"]
    }')
    NF_TUNNELER=$(echo "${NF_CREATE}" | jq -r .ipsecTunneler.id)
    echo "${NF_CREATE}" | jq -r .plaintextPskOnce

    Request fields:

    • networkId (required): The provisioned network to create the tunneler in.
    • provider (required): The cloud provider. Currently AWS.
    • region (required): The cloud region code (for example, us-east-1).
    • customerPublicIp (required): The remote site's public IPv4 address.
    • customerPeerCidrs (required): The internal subnets behind the remote device. Each entry's host bits must be zero — 10.20.0.0/16 for a subnet or 10.20.0.5/32 for a single host.
    • name (optional): A display name, unique within the network. A name is generated if you omit it.
    • hostSize (optional): The bridge instance size (for example, SMALL).
    • ikeProposals / espProposals (optional): Catalog values to restrict the Phase 1 / Phase 2 proposals. Omit to offer all catalog values. See List proposals.
    • attributes (optional): Ziti attributes to apply to the tunneler's endpoint.
    • alternateDomainName (optional): An alternate DNS name for the bridge host.
    warning

    plaintextPskOnce is the pre-shared key, and it's surfaced only at create time (and when you rotate it). Capture it now and deliver it to the remote site over a secure channel. Treat it like a password.

  2. Poll the tunneler until its status is PROVISIONED:

    curl -s ${NF_API}/core/v3/ipsec-tunnelers/${NF_TUNNELER} \
    --header "Authorization: Bearer ${NETFOUNDRY_API_TOKEN}" | jq -r .status

Get the client configuration

Once the tunneler is provisioned, retrieve the customer-facing configuration document (Markdown) to hand to the remote site. It contains the bridge address, the pre-shared key, the negotiated proposals, and a ready-to-use swanctl.conf example, so this endpoint requires update permission:

curl -s "${NF_API}/core/v3/ipsec-tunnelers/${NF_TUNNELER}?meta=configuration" \
--header "Authorization: Bearer ${NETFOUNDRY_API_TOKEN}" \
--header "Accept: text/markdown" \
-o ipsec-client-config.md

List tunnelers

curl -s ${NF_API}/core/v3/ipsec-tunnelers \
--header "Authorization: Bearer ${NETFOUNDRY_API_TOKEN}" \
| jq '._embedded.ipsecTunnelerList[] | {name, status, id}'

You can filter by property (for example, ?status=PROVISIONED or ?name=acme-dc-east) and page with ?page=0&size=20.

List the proposal catalog

The valid ikeProposals and espProposals values come from the proposal catalog:

curl -s ${NF_API}/core/v3/ipsec-proposals \
--header "Authorization: Bearer ${NETFOUNDRY_API_TOKEN}" \
| jq '._embedded.ipsecProposalList[] | {type, value}'

Update a tunneler

Updates run asynchronously and return 202 Accepted. Use PUT for a full update or PATCH to change only the fields you provide; omitting customerPeerCidrs (or sending it empty) preserves the existing selection:

curl -s -X PATCH ${NF_API}/core/v3/ipsec-tunnelers/${NF_TUNNELER} \
--header "Authorization: Bearer ${NETFOUNDRY_API_TOKEN}" \
--header "Content-Type: application/json" \
--data '{ "customerPeerCidrs": ["10.20.0.0/16", "10.30.0.0/16"] }'

Rotate the pre-shared key with the dedicated action — not through an update. Like create, the response returns the new PSK once:

curl -s -X POST ${NF_API}/core/v3/ipsec-tunnelers/${NF_TUNNELER}/actions/rotate-psk \
--header "Authorization: Bearer ${NETFOUNDRY_API_TOKEN}" \
| jq -r .plaintextPskOnce

Delete a tunneler

Teardown runs asynchronously and returns 202 Accepted:

curl -s -X DELETE ${NF_API}/core/v3/ipsec-tunnelers/${NF_TUNNELER} \
--header "Authorization: Bearer ${NETFOUNDRY_API_TOKEN}"

Paths

- GET /core/v3/ipsec-tunnelers[?page=0&size=20]
- GET /core/v3/ipsec-tunnelers/{id}
- GET /core/v3/ipsec-tunnelers/{id}?meta=configuration (text/markdown)
- POST /core/v3/ipsec-tunnelers
- PUT /core/v3/ipsec-tunnelers/{id}
- PATCH /core/v3/ipsec-tunnelers/{id}
- DELETE /core/v3/ipsec-tunnelers/{id}
- POST /core/v3/ipsec-tunnelers/{id}/actions/rotate-psk
- POST /core/v3/ipsec-tunnelers/{id}/actions/replay
- GET /core/v3/ipsec-proposals