Fs
Networking AWS

Flexisip SIP Proxy 2.6.2 on AWS User Guide

| Product: Flexisip SIP Proxy 2.6.2 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and verifying Flexisip SIP Proxy 2.6.2 on Ubuntu 24.04 from cloudimg on Amazon EC2. It is one version of the cloudimg 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 other VPN, proxy and remote access servers in the listing are described on the listing's guide hub.

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.

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

What is on the image:

  • Flexisip 2.6.2 (flexisip-proxy.service): proxy + 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 (cloudimg-flexisip-guard.service): 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), cloudimg-sip-test (a SIP test client and the image's self-test), flexisip-sip-guard, flexisip-preflight, 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 and writes only its 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 (an IP in your VPC, the instance itself, loopback, the metadata service) is dropped before authentication and never forwarded;
  • a request addressed to another SIP domain is refused (403 Domain forbidden);
  • a Route header a client adds cannot steer a request anywhere;
  • the proxy does not stay in the path of established calls (no Record-Route), so in-dialog requests such as BYE and ACK, which SIP never challenges, are never relayed either.

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, so 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 other Flexisip servers' units are masked. The registrar keeps registrations in memory: 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, and 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. cloudimg checked the journal and /var/log for the secret, its hashes and every digest response sent during testing: none were there. * Per-instance identity. SSH host keys and the machine ID are generated fresh on every instance.

Prerequisites

  1. An AWS account and permission to launch EC2 instances
  2. An EC2 key pair in the Region you launch in
  3. 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 (a few MB of memory idle); the number of registered phones and calls per second is what grows its needs.

Connecting to your instance

Version Operating system SSH user
Flexisip SIP Proxy 2.6.2 on Ubuntu 24.04 Ubuntu 24.04 LTS ubuntu

Step 1: Launch the instance

Option A: AWS Marketplace console

  1. Open the cloudimg Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
  2. Once the subscription is active, choose Launch your software.
  3. 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.
  4. Pick an instance type (m5.large recommended; the software charge is $0.04 per vCPU per hour) and your key pair.
  5. Security group: the listing's default group allows SSH (22), SIP 5060 (UDP and TCP) and SIP over TLS 5061 (TCP), the ports phones need. Restrict SSH to your own IP address, and the SIP ports to your phones' networks where you can.
  6. Choose a subnet with internet access and a public IP, leave the metadata defaults (the image already requires IMDSv2), then choose Launch.

Option B: AWS CLI

Run this on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and 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: the AMI already makes IMDSv2 required.

Step 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, starts Flexisip and 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 cloudimg-sip-test selftest
# Guide: https://www.cloudimg.co.uk/guides/flexisip-sip-proxy-2-6-2-on-ubuntu-24-04-aws/

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 cloudimg-sip-test selftest

The SIP domain is the instance's public IPv4 address (its private address if it has none). Show the secret when you configure a phone:

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

Step 3: Confirm Flexisip is running

systemctl status flexisip-proxy --no-pager | head -12
● flexisip-proxy.service - Flexisip 2.6.2 SIP proxy and registrar (cloudimg)
     Loaded: loaded (/etc/systemd/system/flexisip-proxy.service; enabled; preset: enabled)
    Drop-In: /etc/systemd/system/flexisip-proxy.service.d
             └─50-cloudimg-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://www.cloudimg.co.uk/guides/flexisip-sip-proxy-2-6-2-on-ubuntu-24-04-aws/
    Process: 6120 ExecStartPre=/usr/local/sbin/flexisip-preflight (code=exited, status=0/SUCCESS)
   Main PID: 6130 (flexisip)

The listening ports are the SIP ports on the private address and 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.

Step 4: Run the self-test

sudo cloudimg-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

Step 5: Register a softphone

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

Setting Value
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 the same <public-ip>

The phone should show the account as registered. Add a second account (Step 6) for a second phone and 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 (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 (copy cert.pem to the phone), or replace it with a certificate from your CA for your SIP DNS name: put the key and full chain in /etc/flexisip/tls/key.pem and cert.pem (owner root:flexisip, key mode 0640) and run sudo systemctl restart flexisip-proxy.

Step 6: Add accounts

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

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>

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

sudo flexisip-adduser 1002

Running it 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.

Step 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 cloudimg settings in /etc/flexisip/flexisip.conf enforce it:

  • [module::GarbageIn] drops, before authentication, every request whose Request-URI host is not the SIP domain and 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/cloudimg-routes.conf, which sends a request still addressed to the domain itself when it reaches the forwarding stage (one that carries a client-supplied Route header) 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 cloudimg-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

Keep the self-test working with that drop-in in place by also allowing the instance's own private address (IPAddressAllow=<sip.bind>/32 in the same file).

Step 8: Configuration changes

The configuration is /etc/flexisip/flexisip.conf; every Flexisip parameter is documented in /usr/share/doc/cloudimg-flexisip/flexisip.conf.packaged-reference. After a change:

sudo systemctl restart flexisip-proxy

The pre-start check (sudo flexisip-preflight) tells you why Flexisip refuses to start if a change disables a protection. The transports and aliases lines are rewritten at every boot from the instance's addresses while the # cloudimg-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/cloudimg-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. Note that the media relay inserts Record-Route, so in-dialog requests then pass through the proxy and the in-dialog methods must be removed from the [module::GarbageIn] filter; review the trade-off before you do it.

Step 9: Metadata access is blocked

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 it; only the resolver stub 127.0.0.53 is allowed back, for DNS.) The self-test proves it from inside the service (its last check). cloudimg also registered a contact on 127.0.0.1 and one on 169.254.169.254 during testing: neither received anything, and the loopback one did once the filter was lifted, which shows the filter is what stops it.

Step 10: The anti-flood guard

sudo flexisip-sip-guard show

Per source address, at most 50 UDP packets per second (burst 100) reach port 5060, and at most 10 new TCP connections per second (burst 30) reach 5060/5061; the rest are dropped and counted. 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 cloudimg-flexisip-guard. (Flexisip's own DoS protection module bans addresses with iptables and needs root, so it is off on this image.)

Step 11: Health check for a load balancer

curl -s http://127.0.0.1/healthz
ok

nginx answers only GET /healthz (every other path is 404 and other methods are refused). Port 80 is not open in the default security group; open it only to your load balancer.

Step 12: How the fail-closed start works

  • flexisip-proxy.service has ConditionPathExists=/var/lib/cloudimg/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 authentication is off or set to a wildcard domain, a clear-text secret is in the users database, the STUN server is enabled, a first-boot placeholder 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 (the SIP domain becomes the instance's current address):

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

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

Step 13: Logs

journalctl -u flexisip-proxy and /var/log/flexisip/flexisip-proxy.log hold errors only. For troubleshooting you can 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.

Step 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, which Canonical patches 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 (free for up to five machines for personal use) keeps them patched.

Step 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 (tag 2.6.2, commit 68ba0e8a, at https://github.com/BelledonneCommunications/flexisip and https://gitlab.linphone.org/BC/public/flexisip; also available from support@cloudimg.co.uk) are in /usr/share/doc/cloudimg-flexisip/. cloudimg 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.

cloudimg 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 support@cloudimg.co.uk or visit cloudimg support.