Common Configuration Recipes
Each recipe maps a business policy to the config options that implement it. Copy the blocks, adjust values, ship through Git.
1. Cost-Optimized Outbound Routing
Policy: cheapest carrier first, fail over on quality, protect margin.
[[routes]]
name = "intl-outbound"
direction = "outbound"
priority = 10
match = { callee = "^\\+?(1|86|44)" }
# weighted selection across same-priority trunks; LCR orders by buy price
[[routes.action.trunks]]
name = "carrier-a"
weight = 10
[[routes.action.trunks]]
name = "carrier-b"
weight = 5
Also set per trunk: max_cps/max_concurrent (capacity), allowed_ips (trust), header_passthrough = { mode = "x_only" } (partner metadata). Verify changes with the wholesale route simulator.
2. Toll-Fraud Prevention (International Dialing Control)
Policy: internal extensions may not dial premium/international destinations unless authorized.
# 1) ACL: only carrier egress + internal ranges
acl_rules = ["allow 10.0.0.0/8", "allow 203.0.113.5", "deny 0.0.0.0/0"]
# 2) Frequency limits mitigate mass dialing
[proxy.frequency_limit]
enabled = true
window_secs = 60
max_attempts = 30
block_secs = 600
Combine with per-extension outbound permissions and a routing rule that rejects non-matching international prefixes. See Security hardening.
3. VIP Treatment
Policy: gold customers skip the queue and reach senior agents.
[acd.policies.support.priority]
base_priority = 0
wait_time_weight = 1.0
[acd.policies.support.priority.vip_bonus]
gold = 100
silver = 50
[acd.policies.support.strategy]
strategy_type = "skill_based"
require_exact_skill = true
Route the VIP DID to the same queue but stamp priority via queue metadata; add an overflow ladder for spill. See Queues & ACD.
4. After-Hours & Holidays
[acd.policies.support.schedule.business_hours]
start = "09:00"
end = "18:00"
timezone = "Asia/Shanghai"
[acd.policies.support.schedule.night_mode]
enabled = true
start = "18:00"
end = "09:00"
action = "voicemail"
[acd.policies.support.schedule.holidays]
"2026-01-01" = { name = "New Year", overflow_chain = ["voicemail"] }
Pair with [proxy] voicemail_greeting and emergency routing that bypasses schedules. See After-hours handling.
5. Recording Compliance
[recording]
enabled = true
type = "s3"
auto_start = true
auto_start_at = "answer"
[storage]
type = "s3"
[storage.s3]
bucket = "compliance-recordings"
region = "us-east-1"
endpoint = "https://s3.example.com"
Per trunk, override enabled = false where recording is legally forbidden; list auto-start exemptions for PCI pauses. See Recording compliance.
6. NAT / Multi-WAN Media
external_ip = "203.0.113.10"
local_networks = ["10.0.0.0/8", "192.168.0.0/16"]
[[network_profile]]
id = "overlay"
external_ip = "100.64.10.1"
Per trunk: external_ip / bind_ip override; ice_lite = true for Teams; per-dialplan relay_only for EIP paths. See NAT & EIP media.
7. Capacity Protection
[proxy]
max_concurrent = 600 # node-level cap
# per trunk
# max_cps = 40
# max_concurrent = 300
Queues add their own caps (max_wait_secs, overflow on queue length). Circuit breakers (asr_alert_threshold) protect against bad routes. Combine with the local stats log for evidence. See Performance planning.
8. Cluster & Rolling Restarts
[cluster]
peers = [
{ addr = "10.0.0.2", sip_port = 5060, ami_port = 8080 },
{ addr = "10.0.0.3", sip_port = 5060, ami_port = 8080 },
]
Shared MySQL/PostgreSQL + identical config via GitOps + drain restarts. See Cluster Deployment.
9. Screen-Pop & CRM Context
# per trunk, forward only partner metadata
header_passthrough = { mode = "x_only" }
Desk popup template: https://crm.example.com/customer/${customerId}?phone=${phone}. Attach customerId via RWI user data or route stamping. See Screen-pop.
10. Cost/Ops Visibility Baseline
stats_log = "/var/log/rustpbx.stats.log"
stats_interval = 5
log_level = "info"
log_rotation = "daily"
Plus /metrics for Prometheus and the reports API for aggregations. See Observability.
Recipe Composition
Most production policies combine several recipes: VLAN-separated media (6), capacity caps (7), recording (5), and after-hours (4) on the same node. Keep each in its own config file section and ship via Git — the audit trail is free.