Skip to content

Latest commit

 

History

348 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FreeSBC

An open-source SIP/WebRTC edge proxy with the Caddy experience: one binary, one YAML file, ./freesbc run.

License Go

  • Pure Go, one static binary, zero external dependencies: no database, no Redis, no kernel modules, and no external media process.
  • Keeps your switch off the public internet: FreeSBC is the only element with a public address. FreeSWITCH or Asterisk stays on a private LAN and only ever talks to FreeSBC.
  • Phones, browsers and carriers through one public address: SIP/UDP phones, WS/WSS WebRTC browsers, and carriers (the switch uses FreeSBC as its outbound proxy).
  • Embedded WebUI, REST API and Prometheus metrics behind bcrypt Basic Auth.

Install

Prebuilt binary: each release carries freesbc_<version>_<os>_<arch>.tar.gz for linux and darwin on amd64 and arm64, plus SHA256SUMS. Each archive holds the binary, this README, the license and freesbc.example.yaml:

v=v0.1.0 os=linux arch=amd64   # os: linux|darwin, arch: amd64|arm64
curl -LO https://github.com/rasonyang/freesbc/releases/download/$v/freesbc_${v}_${os}_${arch}.tar.gz
curl -LO https://github.com/rasonyang/freesbc/releases/download/$v/SHA256SUMS
shasum -a 256 -c --ignore-missing SHA256SUMS   # Linux: sha256sum -c --ignore-missing SHA256SUMS
tar -xzf freesbc_${v}_${os}_${arch}.tar.gz && cd freesbc_${v}_${os}_${arch}
./freesbc check -c freesbc.example.yaml

From source: requires Go >= 1.27.1:

go build -o freesbc ./cmd/freesbc

Quick start

Read before exposing to the public internet: docs/design.md (networking and deployment topology, security model) and docs/edge.md (switch-side requirements).

cp freesbc.example.yaml freesbc.yaml   # then edit the addresses
./freesbc check -c freesbc.yaml        # validate; errors name the line and key
./freesbc run   -c freesbc.yaml

A minimal config (every key is documented in docs/config.md):

public:
  ip: 203.0.113.7            # advertised to phones, browsers, carriers
private:
  ip: 10.77.0.2              # faces the switch
edge:
  switch: [10.77.0.10:5060]  # the switch, literal IP:port
  listen:
    udp: 5060                # ports on public.bind

freesbc.yaml is gitignored since it may hold real addresses and a password hash. -c defaults to freesbc.yaml; a positional argument is a usage error.

The config file is watched. A shield edit is validated and applied atomically; a bad edit never takes down the process, because the previous config stays active and the error is logged. Everything else (addresses, rtp, tls, edge, admin) is read once at startup: a reload that edits it is logged as a warning listing the keys, and the running process keeps its startup values until restarted.

On SIGINT/SIGTERM FreeSBC drops its calls with their media released; no BYE is sent. A second SIGINT/SIGTERM exits at once.

How it fits together

  Internet ──> FreeSBC  203.0.113.7   public: SIP/UDP, WS/WSS, RTP, WebRTC
                  │
                  │ private LAN/VPN: plain SIP/UDP + RTP
                  │ one fixed socket, 10.77.0.2:5060
                  v
              switch (FreeSWITCH / Asterisk)  10.77.0.10   no public IP, no port forward
                  │
                  └── carriers: the switch sends carrier traffic to FreeSBC as its outbound proxy
  • Clients. REGISTER is proxied to the switch verbatim (the switch is the registrar; FreeSBC holds no credential) with the Contact rewritten to carry an fsbc= token. Calls to clients and from clients are proxied with FreeSBC on the path.
  • Carriers. The switch owns carrier accounts, line selection and failover, and points each gateway at FreeSBC as outbound proxy. Requests to a host listed in edge.carriers are proxied to that carrier with the switch's private addresses hidden; inbound carrier requests are delivered to the switch's carrier port with an X-FreeSBC-Carrier header.
  • Topology hiding. Every SDP body is constructed by FreeSBC, never copied from the other leg, and all media is anchored on FreeSBC ports. A public party never gets the switch's address, and the switch never gets the public party's address in SDP, Contact or Request-URI.
  • Shield. Per-IP rate limiting (separate limits for carrier sources) and scanner fingerprinting with an in-memory ban; every denial is a silent drop. FreeSBC touches no kernel firewall state. The private socket is trusted and exempt, so keep it unreachable from anywhere else.

Details: docs/edge.md (behaviour, switch-side requirements, limitations) and docs/design.md.

Features

  • Edge proxy: SIP/UDP, WS and WSS interworking in front of a private switch; REGISTER proxying; a multi-switch pool with per-user hashing.
  • Carrier path: carrier directory by literal IP or DNS (SRV/A/AAAA, cached), switch-to-carrier proxying with topology hiding, inbound carrier delivery to the switch's carrier port, and deterministic carrier registration tokens.
  • Media anchoring: RTP relay on FreeSBC ports with hardened first-packet latching and a silence watchdog; no transcoding.
  • WebRTC: ICE-Lite, DTLS-SRTP and RTCP-mux terminated for browsers (any of edge.listen.ws/wss), relayed to plain RTP.
  • Built-in security: per-IP rate limiting, scanner fingerprinting, in-memory bans, admission control for public INVITEs and REGISTER enumeration.
  • Embedded WebUI + REST API: a live dashboard and a validated, atomic editor for the same YAML file, Prometheus metrics, bcrypt Basic Auth.

Documentation

Admin & WebUI

Enable the optional admin block (a bcrypt password_hash; generate with htpasswd -bnBC 10 "" 'your-password' | tr -d ':\n'; the user is always admin), then:

  • browse http://<admin.listen>/ (HTTP Basic Auth) for the live dashboard and the raw-config editor. Edits are validated, written atomically and reloaded; keep secrets as ${ENV} references,
  • scrape http://<admin.listen>/metrics with Prometheus (basic_auth in the scrape config),
  • read live state from /api/status, /api/calls and /api/config.

Bind the admin listener private. Validation rejects a non-loopback admin.listen unless admin.allow_remote: true is set, which also requires the top-level tls identity and then serves HTTPS. Read the security model section of docs/design.md before setting it.

Status & limitations

FreeSBC targets small and medium deployments on a single node. The repo carries no benchmarks and no load-test harness.

Non-goals: transcoding, CDR, clustering, and being a registrar in its own right. The edge proxy proxies registrations to the switch rather than owning users or credentials.

  • No transcoding; left to the switch.
  • All state is in memory; a restart drops every call, dialog and binding.
  • The edge never offers or reads a=crypto: a SIP phone gets plain RTP, and only browser legs get DTLS-SRTP.
  • Switches and carrier gateways are UDP only; switches are literal IP:port, with no DNS.
  • Call-ID passes through the proxy unchanged.
  • No SUBSCRIBE, PRACK or UPDATE, and no TURN or full ICE.

See known limitations for the full list.

Development

go vet ./...
go test ./... -race

The edge suite runs entirely on 127.0.0.1 and passes on macOS and Linux. See CLAUDE.md for per-package test ports and the opt-in FreeSWITCH interop test.

Layout

cmd/freesbc/          argv parsing, signal handling, exit codes
internal/
  app/                construction and lifecycle: builds every component and runs it
  config/             freesbc.yaml: parse, validate, hot reload
  sip/                SIP protocol primitives
  sip/sdp/            SDP subsystem (parse, codec negotiation, construction)
  edge/               SIP/RTP/WebRTC proxy between public parties and the switch
  media/              RTP/RTCP relay, port pools, WebRTC leg (ICE/DTLS/SRTP)
  shield/             per-IP rate limiting, scanner fingerprinting, in-memory bans
  admin/              operator HTTP API, Prometheus metrics, embedded WebUI

Everything is under internal/: the only consumer is cmd/freesbc, so no package here carries an API promise. Dependencies run one way: cmd/freesbc -> app -> {edge, admin}.

License

Apache License 2.0. See LICENSE.

About

All-in-one open source Session Border Controller in pure Go. One static binary, one YAML file: trunk B2BUA, edge proxy, RTP/SRTP relay, WebRTC gateway, built-in SIP security.

Topics

Resources

Stars

92 stars

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages