Installing and updating an SBC
This is the hands-on companion to The Exovo SBC: what to put on the box at the branch office, how to tell it worked, and what to look at when it didn't. Allow about fifteen minutes for a first install.
Before you start
The box. Any small always-on x86-64 Linux machine on the same LAN as the phones — a NUC-class PC
or a VM is plenty. Install Docker Engine with the Compose plugin
(docs.docker.com/engine/install); docker compose version
should print a version. Give the box a fixed LAN address (a DHCP reservation is fine): the phones
use it as their outbound proxy.
The network. Outbound only — nothing is opened to the branch:
| From the SBC to | Port | Why |
|---|---|---|
| Your PBX | 443 TCP | One-time enrollment, fetching its certificate |
| Your PBX | 5090 TCP and UDP | The tunnel: signalling on TCP, call audio on UDP |
On the LAN the SBC listens for the phones on 5060 UDP. If the site has Cisco 8800 phones on Enterprise firmware it also serves them on 69 UDP (TFTP) and 6970 TCP — see Cisco Enterprise phones. Nothing else on the box may already be using those ports.
The image needs no login. registry.exovo.tel/exovo/sbc can be pulled anonymously, so no license
key is ever placed on a machine at the customer's site. The SBC does nothing until it is enrolled.
1. Create the site in the console
Admin → Advanced → SBC → Provision a new SBC: enter a site name and a short scope (site1,
cincinnati …) and choose Create SBC. The console shows the appliance's .env — your system's
host name and a one-time enrollment key — exactly once. Choose Copy .env. The key is good for
7 days and can enroll one box.
2. Run the installer
On the box at the branch office:
curl -fsSL https://get.exovo.tel/onboard | sudo bash
It prints a link; open it in a browser (accept the one-time certificate warning) and choose
Install a site SBC. Paste the .env you copied — it fills in your system's host name and the
enrollment key — and choose Check connection: the installer tests, from this box, that your system's
name resolves and that ports 443 and 5090 answer, which is where most first installs go wrong. Then
Install. It puts the SBC in /opt/exovo-sbc, starts it, and waits for it to connect, so the last
screen tells you whether the site is really up — not merely that a container started. The SIP port and the
LAN address are under Advanced and rarely need changing.
This is the same installer that sets up a new Exovo system; the SBC path needs no license key. Running it again on a box that already has an SBC offers to replace its settings while keeping its certificate.
Skip to step 3 if you used the installer.
Or by hand
The installer only writes two files and runs Docker Compose; you can do the same yourself.
sudo mkdir -p /opt/exovo-sbc && cd /opt/exovo-sbc
Create docker-compose.yml with exactly this:
name: exovo-sbc
services:
sbc:
image: registry.exovo.tel/exovo/sbc:${EXOVO_SBC_CHANNEL:-stable}
security_opt: [no-new-privileges:true]
cap_drop: [ALL]
cap_add: [NET_BIND_SERVICE] # to listen on port 5060 (and 69 for Cisco TFTP)
network_mode: host # required: the SBC must see and use the real LAN address
environment:
PBX_HOST: ${PBX_HOST:?set PBX_HOST, e.g. pbx.example.com}
EXOVO_WEB_URL: ${EXOVO_WEB_URL:-}
SBC__Terminator: ${SBC_TERMINATOR:-}
SBC_ENROLL_KEY: ${SBC_ENROLL_KEY:-}
SBC__SipPort: ${SBC_SIP_PORT:-5060}
SBC__MediaIp: ${SBC_MEDIA_IP:-}
SBC__AdvertiseIp: ${SBC_ADVERTISE_IP:-}
volumes:
- sbc-certs:/data
restart: unless-stopped
volumes:
sbc-certs:
Create .env next to it and paste what you copied from the console:
PBX_HOST=pbx.example.com
SBC_ENROLL_KEY=paste-the-one-time-key-here
network_mode: host is not optional. In Docker's default bridge mode the SBC cannot see the LAN
address the phones must be told to use, and call audio will not flow.
Then start it:
sudo docker compose up -d
3. Check it
cd /opt/exovo-sbc && sudo docker compose logs --tail 30
A healthy first start reads, in order:
[sbc] no persisted certificate — enrolling with the one-time key
[sbc] enrolled and persisted certificate to /data […]
[sbc] SBC identity from cert: tenant=1 scope=site1
[sbc] tunnel UP: session=…, heartbeat=20s
[sbc] media channel -> <your PBX>:5090/udp
[sbc] SIP listener bound on :5060 (relaying LAN phones <-> tunnel; media via 192.168.1.20)
[sbc] reported SBC LAN endpoint 192.168.1.20:5060
Check the address in the last two lines is the box's real LAN address. In the console the site moves from Pending to Enrolled and shows that same address.
The certificate now lives in the sbc-certs volume and is reused on every restart. The enrollment key
has been consumed; you can leave the line in .env or blank it.
4. Point the phones at it
Assign each phone in the console with connection type SBC and this site selected — see
provisioning. The phone's outbound proxy is set to the SBC's
LAN address automatically; its registrar stays your system's host name. Once a phone registers, the
SBC's log shows its REGISTER going up the tunnel and a 200 OK coming back, and the phone appears
under Admin → Phones as registered.
Updating
cd /opt/exovo-sbc && sudo docker compose pull && sudo docker compose up -d
Calls in progress through the SBC drop when it restarts, so pick a quiet moment; the phones are back within seconds. The SBC and the PBX are updated independently and either may be newer than the other — but fixes that live in the SBC only reach a site when that site's SBC is updated, so update SBCs after a PBX release whose notes mention the SBC.
When the PBX itself is updated you do not need to touch the SBC. It loses the tunnel for the few seconds the PBX is restarting, reconnects by itself, and the PBX puts the site's phone registrations straight back — phones are reachable again within about ten seconds, without waiting for each phone's own re-registration timer.
Troubleshooting
Start with cd /opt/exovo-sbc && sudo docker compose logs --tail 50. If you used the installer, its own
log is kept beside the SBC as /opt/exovo-sbc/install.log.
| What the log says | What it means | What to do |
|---|---|---|
tunnel error: no answer from …:5090 within 15s (older versions: Connection timed out) |
Port 5090 to the PBX is not reachable. | Check the branch firewall allows outbound TCP and UDP 5090; check PBX_HOST resolves to the right address; check the PBX's own firewall and that its tunnel service is running (Dashboard → Services). |
tunnel error: … Connection refused |
The PBX answered but nothing is listening on 5090 — usually the PBX is mid-update. | Wait a minute; the SBC retries every 5 seconds forever. |
enroll rejected (401) — check SBC_ENROLL_KEY or regenerate it … |
The one-time key was already used, mistyped, or is older than 7 days. | Regenerate key on the SBC page, then run the installer again (or update .env and docker compose up -d). It keeps retrying, so it enrolls as soon as the key is right. |
no certificate in /data and SBC_ENROLL_KEY is not set |
First start without a key (or the .env file is not next to docker-compose.yml). |
Put the key in .env and docker compose up -d. |
enroll failed (attempt N): … / enroll HTTP 5xx — retrying |
The box cannot reach https://<PBX_HOST> — DNS, outbound 443, or the PBX is down. |
Fix the path; it retries every 5 seconds. For a test PBX without TLS set EXOVO_WEB_URL=http://host:port. |
| TLS or certificate errors after it used to work | The site was revoked in the console, or the PBX's certificate authority was replaced. | Provision the site again and enroll with a new key. To start clean: docker compose down -v removes the stored certificate. |
address already in use for 5060 (or 69) |
Another SIP service or a TFTP server is running on the box. | Stop it, or set SBC_SIP_PORT to a free port and re-provision the phones. |
| The LAN address in the log is wrong (a VPN or second NIC) | Autodetection picked another interface. | Set SBC_MEDIA_IP and SBC_ADVERTISE_IP to the LAN address in .env. |
| Phones register but there is no audio, or one-way audio | UDP 5090 is blocked (signalling rides TCP and still works), or the box is in bridge mode. | Allow outbound UDP 5090; confirm network_mode: host. |
tunnel -> [unrouted] … |
The PBX sent something for a phone this SBC has not heard from. | Update the SBC — current versions deliver it to the phone's own LAN address. Otherwise it clears when the phone next re-registers. |
tunnel -> no learned route for 104; using its contact address … |
Normal right after a reconnect: the SBC is delivering to the phone's known LAN address until it re-registers. | Nothing. |
If a phone shows registered in the console but calls to it fail right after a PBX update, give it ten seconds and try again before digging — that is the window in which registrations are being put back.
Moving or retiring a site
To move the SBC to new hardware, provision a new SBC entry for the site, install it as above with the new key, then Revoke the old entry. Certificates are per-appliance and are not copied between boxes. To retire a site, Revoke it in the console — the tunnel is cut immediately — and on the box:
cd /opt/exovo-sbc && sudo docker compose down -v