Deployment guide

Flexisip SIP Proxy 2.6.2

Overview

Flexisip is Belledonne Communications' open-source SIP server, the server side of the Linphone project. On this image it runs as a SIP proxy and registrar. SIP phones and softphones (Linphone, Zoiper, MicroSIP, desk phones) register their accounts with it and call each other through it. The audio and video of a call flow directly between the phones.

This guide covers launching and verifying Flexisip SIP Proxy 2.6.2 on Ubuntu 24.04 from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace. You pick it as the software version when you subscribe and launch. The listing's guide hub describes the other VPN, proxy and remote access servers in the listing.

Flexisip 2.6.2 is Belledonne's official bc-flexisip 2.6.2-1 package from Belledonne's own apt repository (download.linphone.org). The repository stays enabled with its signing key, so the package keeps receiving Belledonne's updates. SecureAnyCloud pins the checksums of the package and of the repository key.

What you get:

  • Flexisip 2.6.2 (flexisip-proxy.service): proxy and registrar on 5060 UDP/TCP and SIP over TLS on 5061, bound to the instance's private address and advertising its public address.
  • One demo account, 1000, whose secret is generated on your instance's first boot. The users database holds only digest hashes of it.
  • A per-instance TLS certificate for SIP over TLS, generated on first boot.
  • An anti-flood guard (sac-flexisip-guard.service) that applies per-source rate limits on the SIP ports.
  • nginx answering only GET /healthz on port 80, for load-balancer health checks.
  • Helpers: flexisip-adduser (add accounts), sac-sip-test (a SIP test client and the image's self-test), flexisip-sip-guard, flexisip-preflight and flexisip-addresses.

Default user: ubuntu. Architecture: x86_64. Root volume: 8 GiB gp3.

Security posture

  • No default account. The image ships an empty users database. First boot generates a 32-character secret for the demo account 1000. It writes only the digest hashes (MD5 and SHA-256, RFC 8760) to /etc/flexisip/users.db.txt. The secret itself is only in /root/flexisip-credentials.txt, readable only by root. No two instances share it.
  • Digest authentication on every request. Every REGISTER, INVITE, MESSAGE and other request from the instance's SIP domain must answer a digest challenge (SHA-256 or MD5). A wrong or empty secret is refused. A request claiming another domain is refused (403 Domain forbidden).
  • Not a relay. Flexisip forwards a request only to a registered contact of the instance's own SIP domain:
    • A request whose Request-URI names any other domain, host or address is dropped before authentication and never forwarded. This includes an IP in your VPC, the instance itself, loopback and the metadata service.
    • A request addressed to another SIP domain is refused (403 Domain forbidden).
    • A Route header that a client adds cannot steer a request anywhere.
    • The proxy does not stay in the path of established calls (no Record-Route). In-dialog requests such as BYE and ACK, which SIP never challenges, are therefore never relayed either.
  • No PSTN. There is no PSTN gateway, trunk or fallback route, so an account cannot place calls to telephone numbers through the instance.
  • No path to the instance metadata service. flexisip-proxy.service carries an IPAddressDeny rule for 169.254.169.254, fd00:ec2::254, 168.63.129.16, all of 169.254.0.0/16 and fe80::/10, and loopback. Even a contact registered on one of those addresses is unreachable. nginx.service is denied the metadata addresses too. The AMI is registered IMDSv2 only.
  • Proxy and registrar only. Flexisip's STUN server (on by default upstream, port 3478), media relay, transcoder, presence, B2BUA, push notifications and statistics collector are off. The units of the other Flexisip servers are masked. The registrar keeps registrations in memory, so no database or Redis runs.
  • Least privilege. Flexisip runs as the unprivileged system user flexisip, with no capabilities, NoNewPrivileges and a read-only system. The control socket is a local Unix socket.
  • Fails closed. flexisip-proxy.service cannot start until first boot has written the ready marker. A root pre-start check refuses to start it if authentication is off, the domain is a wildcard, a clear-text secret is in the users database, the STUN server is on, the TLS key is missing or the anti-flood guard is not loaded. If first boot cannot finish, Flexisip stays stopped and the next boot starts over.
  • Secrets stay out of logs. Flexisip logs at error level and never logs message bodies. SecureAnyCloud checked the journal and /var/log for the secret, its hashes and every digest response sent during testing, and none were there.
  • Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance.

Prerequisites

  • An AWS account and permission to launch EC2 instances.
  • An EC2 key pair in the Region you launch in.
  • A subnet with outbound internet access, and a public IP address (or Elastic IP) if phones outside AWS will register.

Recommended instance type: m5.large. Flexisip is light, using a few MB of memory when idle. The number of registered phones and calls per second is what grows its needs.

Connecting to your instance

For Flexisip SIP Proxy 2.6.2 on Ubuntu 24.04 (operating system: Ubuntu 24.04 LTS), the SSH user is ubuntu.

1

Launch the instance

Option A: AWS Marketplace console

  • Open the SecureAnyCloud Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace. Choose View purchase options, then Subscribe. One subscription covers every version in the listing.
  • When the subscription is active, choose Launch your software.
  • Choose One-click launch from AWS Marketplace (or Launch from EC2 Console). In Version, choose Flexisip SIP Proxy 2.6.2 on Ubuntu 24.04, then choose your Region.
  • Pick an instance type and your key pair. m5.large is recommended, and the software charge is $0.04 per vCPU per hour.
  • Review the security group. The listing's default group allows SSH (22), SIP 5060 (UDP and TCP) and SIP over TLS 5061 (TCP), which are the ports phones need. Restrict SSH to your own IP address, and the SIP ports to your phones' networks where you can.
  • Choose a subnet with internet access and a public IP. Leave the metadata defaults, because the image already requires IMDSv2. Then choose Launch.

Option B: AWS CLI

Run the commands below on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page. Replace the VPC, subnet, key pair and address ranges with your own:

SG=$(aws ec2 create-security-group --group-name flexisip \
  --description "Flexisip SIP proxy" --vpc-id vpc-0123456789abcdef0 \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol udp --port 5060 --cidr <your-phones-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 5060 --cidr <your-phones-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 5061 --cidr <your-phones-cidr>
aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name my-key-pair \
  --security-group-ids "$SG" \
  --subnet-id subnet-0123456789abcdef0 \
  --associate-public-ip-address \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=flexisip}]'

You do not need --metadata-options, because the AMI already makes IMDSv2 required.

2

Connect and read your SIP account

Connect as ubuntu with the key pair you chose:

ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>

First boot finishes within a minute of launch. It reads the instance's addresses, generates the demo account and the TLS certificate, sets the SIP domain and starts Flexisip. It then proves a registration over UDP and TLS before it writes /root/flexisip-credentials.txt.

This command shows everything except the secret:

sudo grep -v '^sip.demo.secret=' /root/flexisip-credentials.txt
# Flexisip SIP Proxy 2.6.2 - generated on first boot by flexisip-firstboot.service. Unique to this instance.
# Register a softphone as sip:1000@54.89.245.1 with the secret below (UDP/TCP 54.89.245.1:5060 or TLS
# 54.89.245.1:5061). The users database holds only digest hashes of it. Keep this file private.
# Add accounts:
sudo flexisip-adduser <user> --generate Self-test:
sudo sac-sip-test selftest
# Guide: https://secureanycloud.com/stacks/flexisip-sip-proxy-2-6-2/ sip.domain=54.89.245.1 sip.realm=54.89.245.1 sip.host=54.89.245.1 sip.bind=172.31.93.134 sip.udp_tcp=54.89.245.1:5060 sip.tls=54.89.245.1:5061 sip.demo.username=1000 sip.demo.aor=sip:1000@54.89.245.1 sip.tls_certificate=/etc/flexisip/tls/cert.pem flexisip.config=/etc/flexisip/flexisip.conf flexisip.self_test=sudo sac-sip-test selftest

The SIP domain is the instance's public IPv4 address, or its private address if it has no public one. Show the secret when you configure a phone:

sudo grep '^sip.demo.secret=' /root/flexisip-credentials.txt
3

Confirm Flexisip is running

Check the service status:

systemctl status flexisip-proxy --no-pager | head -12
● flexisip-proxy.service - Flexisip 2.6.2 SIP proxy and registrar (sac) Loaded: loaded (/etc/systemd/system/flexisip-proxy.service; enabled; preset: enabled) Drop-In: /etc/systemd/system/flexisip-proxy.service.d └─50-sac-imds-deny.conf Active: active (running) since Tue 2026-10-27 13:23:36 UTC; 1min 32s ago Docs: https://www.linphone.org/en/flexisip-sip-server/ https://secureanycloud.com/stacks/flexisip-sip-proxy-2-6-2/ Process: 6120 ExecStartPre=/usr/local/sbin/flexisip-preflight (code=exited, status=0/SUCCESS) Main PID: 6130 (flexisip)

Flexisip listens on the SIP ports on the private address, and nginx serves the health check on port 80:

sudo ss -tulnp | grep -E ':5060|:5061|:80 '
udp UNCONN 0 0 172.31.93.134:5060 0.0.0.0:* users:(("flexisip",pid=6130,fd=9)) tcp LISTEN 0 1000 172.31.93.134:5061 0.0.0.0:* users:(("flexisip",pid=6130,fd=11)) tcp LISTEN 0 1000 172.31.93.134:5060 0.0.0.0:* users:(("flexisip",pid=6130,fd=10)) tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=4998,fd=5),...) tcp LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=4998,fd=6),...)

Flexisip binds the private address because EC2 delivers traffic for the public address to it. It advertises the public address in its SIP headers. flexisip-addresses.service refreshes both at every boot, so a stop and start that changes the public IP keeps working.

4

Run the self-test

Run the self-test client:

sudo sac-sip-test selftest
ok: REGISTER 1000 over UDP with the per-instance secret (MD5 digest) -> 200 Registration successful ok: REGISTER 1000 over TCP with the per-instance secret (SHA-256 digest) -> 200 Registration successful ok: REGISTER 1000 over TLS 5061 (per-instance certificate) with the per-instance secret -> 200 Registration successful ok: REGISTER 1000 with a wrong secret is refused -> 403 Forbidden ok: REGISTER 1000 without credentials is challenged -> 401 Unauthorized ok: REGISTER of an unknown user is refused -> 403 Forbidden ok: INVITE without credentials is challenged (no anonymous calls) -> 407 Proxy Authentication Required ok: INVITE addressed to a foreign domain is refused (no relay) -> 403 Domain forbidden ok: INVITE whose Request-URI is another host is dropped, never forwarded -> no answer (dropped) ok: BYE whose Request-URI is another host is dropped, never forwarded -> no answer (dropped) ok: REGISTER 1000 removes the self-test contact -> 200 Registration successful ok: metadata 169.254.169.254 is unreachable from inside flexisip-proxy.service SELFTEST_OK
5

Register a softphone

In any SIP softphone (Linphone, Zoiper, MicroSIP and others), add a SIP account with these settings:

  • Username / user ID: 1000
  • Domain / realm: the sip.domain value, for example 54.89.245.1
  • Password: the sip.demo.secret value
  • Proxy / server: <public-ip>:5060 (UDP or TCP), or <public-ip>:5061 with transport TLS
  • Outbound proxy: leave empty, or use the same <public-ip>

The phone should show the account as registered. Add a second account (Step 6) for a second phone, then call sip:1001@<sip-domain> between them.

Calls and NAT. Flexisip carries the call setup. The audio and video go directly between the two phones, because the media relay is off. Phones on the same network, in your VPC or on a VPN reach each other directly. Phones on the internet behind NAT need their own NAT traversal (STUN or ICE, which most softphones offer as a setting). Flexisip already corrects the address a NATed phone registers from, so incoming calls reach it.

SIP over TLS. The certificate in /etc/flexisip/tls/cert.pem is self-signed and names the instance's addresses and its public DNS name. A phone that verifies certificates needs it as a trusted certificate, so copy cert.pem to the phone. Alternatively, replace it with a certificate from your CA for your SIP DNS name.

To replace it, put the key and full chain in /etc/flexisip/tls/key.pem and cert.pem (owner root:flexisip, key mode 0640). Then run sudo systemctl restart flexisip-proxy.

6

Add accounts

flexisip-adduser writes an account as digest hashes only and restarts Flexisip. To have it generate a 32-character secret and print it once, run:

sudo flexisip-adduser 1001 --generate
flexisip-adduser: 1001@54.89.245.1 added (realm 54.89.245.1; digest hashes only) secret for 1001: <printed once>

Alternatively, type your own secret (at least 16 characters) when prompted, or pass it on standard input. Never pass it on the command line:

sudo flexisip-adduser 1002

Running the command again for an existing user replaces that user's secret.

To remove a user, delete its line from /etc/flexisip/users.db.txt and run sudo systemctl restart flexisip-proxy.

7

The request gate: only registered contacts are reachable

Flexisip forwards a request only after its registrar has resolved the Request-URI, an address of the instance's SIP domain, to the contacts a phone registered. Three SecureAnyCloud settings in /etc/flexisip/flexisip.conf enforce this:

  • [module::GarbageIn] drops, before authentication, every request whose Request-URI host is not the SIP domain. It also drops every in-dialog-only method (BYE, ACK, PRACK, UPDATE, INFO, REFER, NOTIFY).
  • [module::NatHelper] runs for REGISTER only, so Flexisip adds no Record-Route header and calls continue directly between the phones.
  • [module::Forward] reads /etc/flexisip/sac-routes.conf. A request that is still addressed to the domain itself when it reaches the forwarding stage (one that carries a client-supplied Route header) is sent to a discard address on loopback that Flexisip cannot reach.

You can see the effect with the test client. An authenticated INVITE whose Request-URI names another host is never answered or forwarded. The test client exits with status 3 when no answer arrives:

sudo sac-sip-test request INVITE --server "$(sudo sed -n 's/^sip.bind=//p' /root/flexisip-credentials.txt)" \
  --domain "$(sudo sed -n 's/^sip.domain=//p' /root/flexisip-credentials.txt)" --user 1000 \
  --secret-file /root/flexisip-credentials.txt --ruri sip:test@192.0.2.10:5060 --timeout 3 | grep '^RESULT' || true
RESULT TIMEOUT

Egress policy. Private address ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) stay reachable, because SIP phones often live in a VPC or behind a VPN. An account holder can therefore direct Flexisip's SIP messages to any address their own phone registers from, except the metadata, link-local and loopback addresses.

If every phone is on the internet, deny the private ranges too:

sudo tee /etc/systemd/system/flexisip-proxy.service.d/60-private-ranges.conf <<'EOF' [Service] IPAddressDeny=10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 100.64.0.0/10 fc00::/7 EOF
sudo systemctl daemon-reload && sudo systemctl restart flexisip-proxy

To keep the self-test working with that drop-in in place, also allow the instance's own private address with IPAddressAllow=<sip.bind>/32 in the same file.

8

Configuration changes

The configuration is /etc/flexisip/flexisip.conf. Every Flexisip parameter is documented in /usr/share/doc/sac-flexisip/flexisip.conf.packaged-reference. After a change, restart Flexisip:

sudo systemctl restart flexisip-proxy

If a change disables a protection, Flexisip refuses to start. The pre-start check (sudo flexisip-preflight) tells you why.

The transports and aliases lines are rewritten at every boot from the instance's addresses, while the # sac-managed: transports aliases line is present. Delete that line to manage them yourself.

A DNS name as the SIP domain. For production, use a DNS name (for example sip.example.com) that resolves to the instance's Elastic IP. Replace the IP address with the name in auth-domains, realm, reg-domains, both filter lines of /etc/flexisip/flexisip.conf and the rule in /etc/flexisip/sac-routes.conf. Restart Flexisip, then re-add every account with flexisip-adduser. Digest hashes include the realm, so the old ones no longer match.

Media relay, presence and other modules. To relay audio for phones that cannot reach each other, enable [module::MediaRelay] with an RTP port range (sdp-port-range, for example 40000-40999) and open that UDP range in the security group.

The media relay inserts Record-Route, so in-dialog requests then pass through the proxy. You must remove the in-dialog methods from the [module::GarbageIn] filter. Review the trade-off before you do it.

9

Metadata access is blocked

Show the address deny list on the service:

systemctl show -p IPAddressDeny flexisip-proxy
IPAddressDeny=169.254.0.0/16 fd00:ec2::254/128 127.0.0.0/8 ::1/128 fe80::/10 168.63.129.16/32

The order of the list varies. systemd folds 169.254.169.254 into 169.254.0.0/16 when it shows the list, and only the resolver stub 127.0.0.53 is allowed back, for DNS.

The self-test proves the block from inside the service in its last check. During testing, SecureAnyCloud also registered a contact on 127.0.0.1 and one on 169.254.169.254. Neither received anything. The loopback one did receive traffic once the filter was lifted, which shows that the filter is what stops it.

10

The anti-flood guard

Show the guard's current state:

sudo flexisip-sip-guard show

Per source address, at most 50 UDP packets per second (burst 100) reach port 5060. At most 10 new TCP connections per second (burst 30) reach 5060/5061. The guard drops and counts the rest.

If many phones share one NAT address, raise the two rates at the top of /usr/local/sbin/flexisip-sip-guard and run sudo systemctl restart sac-flexisip-guard. Flexisip's own DoS protection module bans addresses with iptables and needs root, so it is off on this image.

11

Health check for a load balancer

Query the health endpoint:

curl -s http://127.0.0.1/healthz
ok

nginx answers only GET /healthz. Every other path returns 404, and other methods are refused. Port 80 is not open in the default security group, so open it only to your load balancer.

12

How the fail-closed start works

  • flexisip-proxy.service has ConditionPathExists=/var/lib/sac/data/flexisip-ready. First boot creates the marker only after the account, the hashes, the TLS key and the SIP domain exist.
  • Before every start, flexisip-preflight (as root) refuses to start Flexisip if any of these is true: authentication is off or set to a wildcard domain, a clear-text secret is in the users database, the STUN server is enabled, an unreplaced first-boot value survives, the TLS key is missing or has unsafe permissions, the request-gate route file is missing, or the anti-flood guard is not loaded.
  • If first boot fails, it removes the marker, shreds what it created and leaves Flexisip stopped. The next boot starts over.

To start over with a new demo secret and certificate, run the commands below. The SIP domain becomes the instance's current address:

sudo rm -f /var/lib/sac/data/flexisip-firstboot.done
sudo systemctl restart flexisip-firstboot

This replaces the users database, so re-add any accounts you created.

13

Logs

journalctl -u flexisip-proxy and /var/log/flexisip/flexisip-proxy.log hold errors only.

For troubleshooting, set log-level=message (or debug) in [global] and restart. At debug level, Flexisip logs the users database lines (digest hashes) and full SIP messages, so switch back to error afterwards.

14

Updates and the Ubuntu universe packages

Belledonne's repository stays enabled, signed by /etc/apt/keyrings/belledonne.gpg. An apt pin lets it supply bc-flexisip only. Update Flexisip with:

sudo apt-get update && sudo apt-get install --only-upgrade bc-flexisip

Ubuntu's unattended security upgrades stay on for the rest of the system.

The bc-flexisip package depends on seven packages from Ubuntu's universe component. Canonical patches these through Ubuntu Pro (ESM Apps) rather than the standard security pocket: libgsm1, libhiredis1.1.0, libmariadb3, mariadb-common, libxerces-c3.2t64, python3-google-auth and python3-rsa. They cannot be removed without removing Flexisip.

When this image was built, no ESM-only security fix was pending for any of them (pro security-status --esm-apps). Attaching Ubuntu Pro, which is free for up to five machines for personal use, keeps them patched.

15

Security recommendations

  • Keep SSH open only to your management addresses, and the SIP ports only to your phones' networks where you can.
  • Give every phone its own account and a generated secret. Treat secrets like passwords.
  • Use SIP over TLS (5061) and a CA certificate for a DNS name in production.
  • Do not configure a PSTN gateway or trunk without your own fraud controls (per-account limits, allowed destinations).
  • Leave unattended security upgrades on, and update bc-flexisip from Belledonne's repository.

Support and licensing

Flexisip is open-source software by Belledonne Communications, distributed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). Belledonne also sells it under a commercial licence, and this image carries the AGPL distribution only.

The licence and the source offer for the unmodified upstream 2.6.2 release are in /usr/share/doc/sac-flexisip/. The release is tag 2.6.2, commit 68ba0e8a, at https://github.com/BelledonneCommunications/flexisip and https://gitlab.linphone.org/BC/public/flexisip. It is also available from sales@secureanycloud.com.

SecureAnyCloud provides the packaging, the per-instance account and certificate, the request gate and other secure defaults, the anti-flood guard, the metadata block, the fail-closed start, the self-test and 24/7 support.

SecureAnyCloud is not affiliated with or endorsed by Belledonne Communications. Flexisip and Linphone are used here only to identify the software.

For help with deployment or configuration, email sales@secureanycloud.com or visit SecureAnyCloud support.

Deploy on AWS

Launch Flexisip SIP Proxy 2.6.2 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS