SBC Complete Example
This section demonstrates a typical SBC deployment scenario: an enterprise PBX interconnected with carriers through an SBC.
Scenario Description
Enterprise Internal Network:
- PBX subnet:
192.168.1.0/24 - Extensions: 1000-1999
- SIP server:
192.168.1.10:5060
SBC:
- Internal IP:
192.168.1.100 - Public IP:
203.0.113.100 - Exposes SIP port
5060and HTTP8080
Carriers:
- Carrier A:
198.51.100.10:5060(primary) - Carrier B:
198.51.100.20:5060(backup)
Requirements:
- Topology hiding: Carriers can only see the SBC address
- Outbound routing: Calls starting with 9 go to Carrier A, failover to Carrier B
- Inbound control: Only accept inbound calls from carrier IPs
- Number rewrite: Strip prefix 9 from outbound calls, prepend area code 0571
- Security protection: Limit CPS, prevent DoS
Step 1: config.toml
http_addr = "0.0.0.0:8080"
database_url = "sqlite://rustpbx.sqlite3"
external_ip = "203.0.113.100"
[proxy]
addr = "0.0.0.0"
udp_port = 5060
modules = ["acl", "auth", "registrar", "call"]
media_proxy = "all"
addons = ["sbc"]
max_concurrency = 500
[proxy.dos]
enabled = true
max_cps_per_ip = 20
max_concurrent_per_ip = 50
scan_detection = true
[console]
session_secret = "sbc-console-secret"
Step 2: Trunk Configuration
config/trunks/carriers.toml:
[[trunk]]
name = "carrier-a"
dest = "sip:198.51.100.10:5060"
direction = "outbound"
codec = ["pcmu", "pcma", "g729"]
max_calls = 200
[trunk.auth]
username = "ent_acct"
password = "ent_pass"
[trunk.health_check]
enabled = true
interval_secs = 30
timeout_secs = 5
[[trunk]]
name = "carrier-b"
dest = "sip:198.51.100.20:5060"
direction = "outbound"
codec = ["pcmu", "pcma"]
max_calls = 100
[trunk.auth]
username = "ent_acct_b"
password = "ent_pass_b"
[[trunk]]
name = "inbound-trunk"
direction = "inbound"
inbound_hosts = ["198.51.100.10", "198.51.100.20"]
codec = ["pcmu", "pcma", "g729"]
max_calls = 300
Step 3: Route Configuration
config/routes/outbound.toml:
[[route]]
name = "outbound-via-a"
action = "forward"
trunk = "carrier-a"
[route.match]
from_user = "^(?=.{4}$)" # 4-digit extension
to_user = "^9(.*)" # outbound starts with 9
[route.rewrite]
to_user_strip = 1 # Strip prefix 9
to_user_prepend = "0571" # Add area code
[[route]]
name = "outbound-via-b"
action = "forward"
trunk = "carrier-b"
[route.match]
from_user = "^(?=.{4}$)"
to_user = "^9(.*)"
[route.rewrite]
to_user_strip = 1
to_user_prepend = "0571"
Step 4: SBC JSON-RPC Configuration (Optional)
If you need dynamic routing via an external API:
config/sbc/sbc_jsonrpc.toml:
[[rules]]
name = "office-hours"
description = "Office hours routing"
[rules.match]
logic = "all"
conditions = [
{ field = "Direction", operator = "Equals", value = "inbound" },
]
[rules.upstream]
url = "http://192.168.1.50:3000/api/route"
method = "POST"
timeout_ms = 1000
[rules.response]
action_field = "action"
trunk_field = "trunk"
callee_rewrite_field = "callee"
Step 5: Start
docker run -d --name sbc \
--network host \
-v $(pwd)/config.toml:/app/config.toml \
-v $(pwd)/config:/app/config \
docker.cnb.cool/miuda.ai/rustpbx:latest
Step 6: Verification
6.1 Internal Extension Registration
Extension 1000 registers to 192.168.1.100:5060 (SBC internal address). The SBC proxies the registration to the internal PBX.
6.2 Outbound Call Test
Extension 1000 dials 9138000138000:
- Matches route
outbound-via-a - Number rewrite:
9138000138000→ strip 1 →138000138000→ prepend 0571 →0571138000138000 - Forwarded to carrier-a (
198.51.100.10) - RTP address in SDP is SBC public IP (
203.0.113.100), topology hidden
6.3 Failover Test
- Disconnect carrier-a
- Health check marks DOWN after 3 consecutive failures
- Subsequent outbound calls automatically use carrier-b
6.4 Inbound Test
Call from carrier to enterprise number:
- Matches inbound-trunk (IP ACL passes)
- Forwarded to internal PBX
- RTP address in SDP rewritten by SBC, internal IP not exposed
6.5 Security Test
High-frequency calls from unauthorized IPs:
- DoS detection triggered, source IP temporarily blocked
- Requests exceeding CPS limit are rejected
Step 7: Daily Operations
| Operation | Frequency | Location |
|---|---|---|
| Check trunk health | Daily | SBC → Dashboard |
| Validate configuration | After changes | SBC → Validation |
| Route simulation | After changes | SBC → Routes → Simulate |
| View active calls | Real-time | Dashboard |
| Review DoS logs | Daily | System logs |