Skip to content

Site Console

The transport and certificate examples on this page were captured 2026-07-28. Observed 2026-08-03 after the deployment was destroyed and rebuilt from zero: the generated credential posture described below held on all three nodes.

Every Customer Edge serves F5’s Site Console on https://<sli-ip>:65500. On this deployment it is usually the route to try first.

It asks least of you: no SSH key to distribute, no jump host to maintain, no public IP on the node, and no VM replacement to enable it. Who may connect becomes an Azure RBAC decision. And it does not need the site to be registered: this page was first captured while all three sites were reporting site_state: FAILED, and re-verified unchanged against the same nodes once they were ONLINE.

The catch is that the Site Console answers only on the node’s internal (SLI) address, reachable only from inside the VNet. Azure Bastion closes that gap without putting anything else on the network.

  1. Sign in to Azure and add the Bastion extension. Tunneling is a native-client feature and the extension is not installed by default.

    Terminal window
    az login
    az extension add --name bastion
  2. Hold Reader on the CE virtual machine, its network interface, and the Bastion host. This is Microsoft’s documented requirement and is unverified here — every run in this deployment was as the subscription owner, so no lesser role has been shown to be sufficient or insufficient.

  3. Confirm Bastion is deployed and capable. Basic SKU supports neither tunneling nor IP-based connection, so Standard and True here are both load-bearing.

    Terminal window
    az network bastion list -g "$(terraform output -raw resource_group_name)" \
    --query "[].{name:name, sku:sku.name, tunneling:enableTunneling}" -o table
    Name Sku Tunneling
    ----------------- -------- -----------
    mcn-ce-ha-bastion Standard True

Take the values from terraform output rather than typing them — the resource id is not something to assemble by hand.

  1. Read the name of the Bastion host, the resource group, and the target CE’s VM resource id.

    Terminal window
    cd terraform
    BASTION=$(terraform output -raw bastion_name)
    RG=$(terraform output -raw resource_group_name)
    VM_ID=$(terraform output -json ce_vm_ids | jq -r '.eastus01')
    mcn-ce-ha-bastion
    rg-mcn-ce-ha-<deployer>
    /subscriptions/…/providers/Microsoft.Compute/virtualMachines/f5-xc-ce-vm-01

    The resource group name ends in the deployer, resolved by local.deployer, so yours will differ. It is elided here for the same reason the subscription is.

  2. Start the tunnel. It holds the port open until stopped, so background it or use a second terminal.

    Terminal window
    az network bastion tunnel \
    --name "$BASTION" \
    --resource-group "$RG" \
    --target-resource-id "$VM_ID" \
    --resource-port 65500 \
    --port 65500 &
    WARNING: Opening tunnel on port: 65500
    WARNING: Tunnel is ready, connect on port 65500
    WARNING: Ctrl + C to close

    All three lines are prefixed WARNING:. That is the Azure CLI writing progress to stderr, not a problem. Wait for Tunnel is ready before connecting.

  3. Confirm the listener is local, on loopback:

    Terminal window
    lsof -nP -iTCP:65500 -sTCP:LISTEN
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    Python 41648 you 7u IPv4 … 0t0 TCP 127.0.0.1:65500 (LISTEN)
  4. Open the console. The tunnel makes it local, so the address is localhost — not the node’s address.

    Terminal window
    open https://localhost:65500/ # macOS
    xdg-open https://localhost:65500/ # Linux
  5. Stop the tunnel when you are finished — Ctrl-C, or kill %1 if you backgrounded it. Leaving it open holds local port 65500 and the Bastion session.

A credential dialog, not a login page. The console uses HTTP Basic authentication, so the browser raises its own username and password prompt. There is no form to look at:

Terminal window
curl -skI https://localhost:65500/
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Volterra Site Console"
Content-Type: text/html; charset=utf-8
Content-Length: 0

A 401 with that realm is the console working correctly. It is what an unauthenticated request is supposed to get — and supplying the admin credential to the same URL answers 200, which is how you confirm the credential before opening a browser:

Terminal window
curl -sk -u admin -o /dev/null -w '%{http_code}\n' https://localhost:65500/
Enter host password for user 'admin':
200

-u admin with no colon makes curl prompt for the password rather than take it from the command line, where it would land in shell history and in the process list.

A certificate warning, for three reasons at once. Checking the certificate directly:

Terminal window
openssl s_client -connect localhost:65500 -servername localhost </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
subject=C=US, ST=California, L=Santa Clara, O=Volterra, OU=Volterra Edge Services, CN=site-local.volterra.io
issuer=C=US, ST=California, L=Santa Clara, O=Volterra, OU=Volterra Edge Services, CN=site-local.volterra.io
notBefore=Oct 25 04:51:31 2024 GMT
notAfter=Oct 25 04:51:31 2025 GMT

Subject equals issuer, so it is self-signed. The name is site-local.volterra.io while you are connecting to localhost, so it will not match. In the 2026-07-28 capture above, the certificate had also expired on 25 October 2025. The appliance supplied that certificate; this repository did not.

Expect a blunt browser warning, and expect it every time. The subject line above is the useful part: it is how you confirm you reached the appliance rather than something else listening on local port 65500.

Sign in as admin. This documentation does not publish the password, and should not.

Two reasons not publishing it matters more here than it might look:

  • This documentation is public. Printing the fleet’s current console password would turn “holds Reader on the Bastion” into full appliance access for anyone who reads the page.
  • A password published in documentation is wrong the moment somebody rotates it, and wrong in the most misleading way — the reader concludes their access is broken rather than that the page is stale.

Read the active node’s value only when you need it with terraform -chdir=terraform output -json site_console_admin_passwords; select the site key locally and do not record the result.

The output is sensitive and Terraform redacts it from the ordinary output listing. It still exists in Terraform state, so protect the state backend as a secret store and do not paste the value into logs or documentation.

Why the tunnel must target the resource id

Section titled “Why the tunnel must target the resource id”

--target-resource-id is required. Targeting the node’s address instead is refused — whatever address you use, so there is deliberately no real one printed here:

Terminal window
az network bastion tunnel --name "$BASTION" -g "$RG" \
--target-ip-address <any-sli-address> --resource-port 65500 --port 65501
ERROR: Custom ports are not allowed. Allowed ports for Tunnel with IP connect is 22, 3389.

The reason is not that IP-based connection is disabled — on this Bastion ip_connect_enabled is true. Microsoft does not support custom ports over IP-based native-client connections regardless of that setting (Azure docs), and 65500 is a custom port. Inspecting the Bastion configuration here leads nowhere; use the resource id.

SymptomCauseFix
ERROR: Custom ports are not allowed. Allowed ports for Tunnel with IP connect is 22, 3389.Used --target-ip-addressUse --target-resource-id
ERROR: Defined port is currently unavailableAnother tunnel already holds that local portStop the other tunnel, or pass a different --port; --resource-port stays 65500
terraform output -raw bastion_name is null or emptyBastion is not deployedSet enable_bastion = true and apply
Tunnel starts but the resource id is emptyjq filter used the VM name instead of the site keyKey on eastus01/02/03
401 Unauthorized, realm Volterra Site ConsoleNot a fault — unauthenticated requestSupply the admin credential
Browser refuses the certificateSelf-signed and name-mismatched; the 2026-07-28 capture was also expiredConfirm the subject is CN=site-local.volterra.io, inspect the dates, and apply your certificate policy