HOMER 7
Overview
HOMER 7 is an open-source SIP and VoIP capture and troubleshooting platform. This SecureAnyCloud image is a complete HOMER 7 capture platform whose three parts are installed and already wired to each other:
- heplify-server 1.60.9 receives HEP (the Homer Encapsulation Protocol) from your SBCs, SIP proxies and media servers, and writes every packet into the capture store.
- PostgreSQL 16 is that store. It uses a partitioned, automatically rotated schema that is created and ready before you sign in.
- homer-app 1.5.20, with the HOMER 7 web UI bundled inside it, serves search, ladder diagrams, per-hop SIP messages and QoS reports behind a TLS front door.
On a plain install, you would create the databases and roles by hand, run the schema migrations, write a heplify-server configuration, wire the web app to both databases, generate a JWT secret and set up TLS. Here, all of that is done during the VM's first boot, with secrets generated uniquely for your machine.
The HEP ingest port is deliberately closed until you open it. heplify-server listens on 9060 (UDP and TCP) exactly as upstream intends, so the capture path works the moment you permit the traffic. On a stock deployment, nothing off the box can reach it.
HEP carries no authentication that the server enforces, so restricting the source of the traffic is the security control. Step 7 walks through opening the port to your own signalling hosts and nothing else.
What you get:
heplify-server1.60.9 as the heplify-server systemd service, listening for HEP on9060/udpand9060/tcphomer-app1.5.20 with the bundled HOMER 7 UI (7.11.23) as the homer-app service, bound to127.0.0.1:9080- PostgreSQL 16 holding
homer_configandhomer_data, bound to127.0.0.1:5432, on a dedicated 32 GiB Azure data disk - A partitioned capture schema with automatic rotation and a 14-day retention window, both tunable
- nginx terminating TLS on a certificate generated on this VM, with HTTP permanently redirecting to HTTPS
- A default-deny host firewall that permits only SSH, HTTP and HTTPS
- Five independent secrets generated on first boot: the
adminlogin, thesupportlogin, the PostgreSQL password, the JWT signing secret and the TLS key. None of them ships inside the image - A self test that sends a synthetic SIP call into this VM's own HEP listener and reads it back through the API
- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a virtual network and subnet in the target region.
Standard_B2s (2 vCPU, 4 GiB RAM) is a comfortable starting point for a lab or a small production capture. Scale the VM and the data disk up with your call volume.
In the network security group (NSG), allow inbound 22/tcp from your management network and 443/tcp from wherever you will browse the UI. 80/tcp is optional and exists only to redirect callers to HTTPS.
Do not add a 9060 rule yet. Step 7 covers that, scoped to your own signalling hosts.
The TLS certificate generated on first boot is self-signed, so browsers show a warning until you replace it with your own certificate (see Maintenance). The curl examples below therefore use -k.
Step 1 - Deploy from the Azure Marketplace
In the Azure portal, select Create a resource, search for HOMER 7 on Ubuntu 24.04 LTS by SecureAnyCloud, and select Create.
Pick your subscription, resource group and region. Choose Standard_B2s or larger, and select SSH public key authentication with the username azureuser.
On the Networking tab, allow inbound ports 22 and 443. Then select Review + create.
Step 2 - Deploy from the Azure CLI
Replace the resource group, region and image reference with the values for your subscription.
az group create --name voip-capture-rg --location eastus
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:sipcapture-homer:default:latest
az vm create \
--resource-group voip-capture-rg \
--name homer7-01 \
--image sac1647283583153:sipcapture-homer:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
az vm open-port --resource-group voip-capture-rg --name homer7-01 --port 443 --priority 1001Step 3 - Connect to your VM
Connect over SSH:
ssh azureuser@<your-vm-ip>Step 4 - Confirm that the services are running
Four services make up the appliance: PostgreSQL (the capture store), heplify-server (the HEP receiver), homer-app (the UI and API) and nginx (the TLS front door). Check them with:
systemctl is-active postgresql heplify-server homer-app nginxExpected output:
active active active activeNow check the network posture. It is the most important thing to understand about this image. heplify-server listens on 9060, but the host firewall permits only 22, 80 and 443:
echo "bound off box:" { ss -tlnH | awk '{print "tcp/"$4}'; ss -ulnH | awk '{print "udp/"$4}'; } \
| grep -vE '/(127\.|\[::1\])' | sed -E 's#(tcp|udp)/.*:([0-9]+)$# \1/\2#' | sort -u
echo "permitted by the firewall:"
sudo ufw status verbose | grep 'ALLOW IN' | sed -E 's/[[:space:]]+ALLOW IN.*//' | sed 's/^/ /' | sort -uExpected output:
bound off box: tcp/22 tcp/443 tcp/80 tcp/9060 udp/68 udp/9060 permitted by the firewall: 22/tcp 22/tcp (v6) 443/tcp 443/tcp (v6) 80/tcp 80/tcp (v6)udp/68 is the DHCP client. The HEP port appears in the first list and not in the second. The appliance ships with its capture capability switched on and its front door shut.
Step 5 - Retrieve your credentials
Every secret on this VM was generated during its first boot. Nothing here shipped inside the image, and no two deployments share a value.
HOMER seeds two built-in accounts, admin and support. Each gets its own distinct password, and neither keeps the upstream default.
sudo cat /root/sipcapture-homer-credentials.txtThe file contains both sign-ins and a reminder of how to open the HEP port safely:
HOMER_URL=https://<your-vm>/ HOMER_USERNAME=admin HOMER_ADMIN_PASSWORD=<generated on this VM> HOMER_SUPPORT_USERNAME=support HOMER_SUPPORT_PASSWORD=<generated on this VM> HEP_PORT=9060 HEP_STATUS=listening on this VM, closed at the firewall until you open itConfirm that the TLS front door is answering and that plain HTTP redirects to it:
curl -sk -o /dev/null -w 'healthz: HTTP %{http_code}\n' https://127.0.0.1/healthz
curl -sk -o /dev/null -w 'port 80: HTTP %{http_code}\n' http://127.0.0.1/Expected output:
healthz: HTTP 200 port 80: HTTP 301/healthz is deliberately unauthenticated, so that an Azure Load Balancer health probe can use it. Everything else requires a login.
Step 6 - Sign in to the web UI
Open https://<your-vm-ip>/ in a browser. Accept the certificate warning. The certificate was generated on your VM and is not signed by a public authority. To replace it, see Maintenance.
Sign in with admin and the HOMER_ADMIN_PASSWORD from Step 5.
Step 7 - Enable HEP ingest from your SBC
This is the one piece of configuration that the appliance deliberately leaves to you.
heplify-server already listens on 9060/udp and 9060/tcp. The port is not reachable from off the box, because it is absent from the image's firewall policy and from the network security group that the offer creates.
HEP has no authentication that heplify-server enforces. The protocol carries an optional authenticate-key chunk, but the server parses it and stores it with the packet rather than rejecting anything on it. There is no capture password to set. Anyone who can reach an open HEP port can therefore write arbitrary call records into your capture store.
The security control is therefore to restrict the source of the traffic. The two rules below do that. Open the port to your own SBC, SIP proxy or media server, and to nothing else.
In both commands, replace 203.0.113.10 with the address or prefix of your signalling host. Run the first command from a machine with the Azure CLI, and the second on the VM itself.
az network nsg rule create \
--resource-group voip-capture-rg \
--nsg-name homer7-01NSG \
--name allow-hep-from-sbc \
--priority 500 \
--direction Inbound --access Allow --protocol '*' \
--source-address-prefixes 203.0.113.10/32 \
--destination-port-ranges 9060sudo ufw allow from 203.0.113.10 to any port 9060 proto udp
sudo ufw allow from 203.0.113.10 to any port 9060 proto tcp
sudo ufw status verboseRepeat both commands for each signalling host, or use a prefix (203.0.113.0/24) if they share one.
Never open 9060 to 0.0.0.0/0, to Any, or to the Azure Internet service tag. An open HEP port is an unauthenticated write endpoint into your capture database.
If you prefer cryptographic peer authentication to source-IP scoping, heplify-server also supports HEP over mutual TLS. Set HEPTLSAddr, TLSCertFile, TLSKeyFile, TLSClientCAFile and TLSRequireClientCert = true in /etc/heplify-server.toml. Restart the service, and point your agents at the TLS listener. See the heplify-server documentation for the current option names.
HEPTLSAddr and HEPTCPAddr cannot both use port 9060. Give the TLS listener its own port, and open that port instead. Even then, keep the source-IP rule in place as defence in depth.
Step 8 - Point your capture agents at it
Each of the following configurations tells the signalling element to duplicate its SIP traffic to this VM as HEP. Use your VM's private address if the agent is in the same virtual network, and its public address otherwise.
Kamailio (siptrace with HEP):
loadmodule "siptrace.so" modparam("siptrace", "duplicate_uri", "sip:<your-vm-ip>:9060") modparam("siptrace", "hep_mode_on", 1) modparam("siptrace", "hep_version", 3) modparam("siptrace", "trace_to_database", 0) modparam("siptrace", "trace_on", 1)Asterisk (res_hep, in hep.conf):
[general] enabled = yes capture_address = <your-vm-ip>:9060 capture_id = 1234 uuid_type = call-idFreeSWITCH: load mod_sofia's HEP capture with capture-server set to udp:<your-vm-ip>:9060 in sofia.conf.xml, or run the heplify agent alongside it.
OpenSIPS (proto_hep plus siptrace):
loadmodule "proto_hep.so" loadmodule "siptrace.so" modparam("siptrace", "trace_id", "[hep]uri=hep:<your-vm-ip>:9060;version=3")Anything else: run heplify, the lightweight capture agent, on the signalling host with heplify -i eth0 -m SIP -hs <your-vm-ip>:9060.
Step 9 - Watch calls arrive
Sign in, and the dashboard's CALL SIP SEARCH widget lists what has been captured. Set a time range in the top bar and press Search. Each SIP message appears with its method, from and to users, source and destination addresses, and the session ID (the Call-ID). Messages that belong to the same call share a row colour.
You can prove the whole path from the shell without waiting for real traffic. The self test sends a synthetic SIP call into this VM's own HEP listener, searches it back out through the API, and then deletes its own rows. It only ever sends to 127.0.0.1, so it never touches traffic that is not its own:
sudo /usr/local/sbin/sipcapture-homer-selftest.shExpected output:
capture round trip OK: sac-selftest-<random> was captured, searched and purgedStep 10 - Read a call's ladder diagram
Double-click any row in the result grid. HOMER opens that Call-ID with tabs for Message, Flow, Session Info, Logs and Export, and lands on Flow, the ladder diagram.
Each participant is a vertical lane, and each SIP message is an arrow between lanes. Each arrow is annotated with the method or response code, the transport, the timestamp and the delta from the previous message.
Export gives you the same call as a PCAP or as text.
Step 11 - Manage users
Select the sliders icon at the top left to open Admin Settings. USERS lists the two accounts created at first boot: admin and support, each with its own per-VM password. Add your own users here, change passwords, or delete the support account if you do not want it.
You can do the same from the API. Sign in for a session token, then list the accounts:
ADMIN_PW=$(sudo grep '^HOMER_ADMIN_PASSWORD=' /root/sipcapture-homer-credentials.txt | cut -d= -f2-)
TOKEN=$(curl -sk -X POST -H 'Content-Type: application/json' \
-d "{\"username\":\"admin\",\"password\":\"${ADMIN_PW}\"}" \
https://127.0.0.1/api/v3/auth | python3 -c 'import json,sys; print(json.load(sys.stdin).get("token",""))')
curl -sk -H "Authorization: Bearer ${TOKEN}" https://127.0.0.1/api/v3/users \
| python3 -c 'import json,sys; [print(u["username"], "-", u["usergroup"]) for u in json.load(sys.stdin)["data"]]'Reading the password from the credentials file keeps it out of your shell history. Run this on the VM itself. From elsewhere, substitute the HOMER_ADMIN_PASSWORD value from Step 5.
Expected output:
admin - admin support - adminStep 12 - Check where captures are stored and for how long
The capture store is PostgreSQL on a dedicated Azure data disk mounted at /var/lib/postgresql, so you can size and scale it independently of the operating system disk. heplify-server creates date partitions ahead of time and drops them once they age out.
df -h /var/lib/postgresql | tail -1 sudo grep -E '^DB(Rotate|PartSip|DropDays|UsageProtection|PercentageUsage)' /etc/heplify-server.tomlExpected output:
/dev/sdc 32G ... /var/lib/postgresql DBRotate = true DBPartSip = "1h" DBDropDays = 14 DBUsageProtection = true DBPercentageUsage = "80%"DBDropDays is the retention window in days. Raise it to keep captures longer, and grow the data disk to match. Lower it to store less.
DBUsageProtection stops heplify-server writing once the disk passes DBPercentageUsage, so a burst of traffic cannot fill the volume.
To apply a change, edit /etc/heplify-server.toml and run sudo systemctl restart heplify-server.
Maintenance
Replace the TLS certificate. The certificate generated at first boot is self-signed. To use your own, copy the certificate and key onto the VM, then reload nginx:
sudo cp your-cert.pem /etc/ssl/sac/sipcapture-homer.crt
sudo cp your-key.pem /etc/ssl/sac/sipcapture-homer.key
sudo chown root:www-data /etc/ssl/sac/sipcapture-homer.key
sudo chmod 640 /etc/ssl/sac/sipcapture-homer.key
sudo nginx -t && sudo systemctl reload nginxChange a password. In the UI, go to Admin Settings > USERS and edit the user. From the shell, run:
sudo /usr/local/bin/homer-app -update-ui-user admin -update-ui-password 'your-new-password'Back up the capture store. sudo -u postgres pg_dump homer_config captures your users, dashboards and settings. homer_data holds the packets themselves and is usually recreated rather than restored.
Operating system updates are delivered by Ubuntu's unattended-upgrades, which is enabled in the image.
Service logs:
sudo journalctl -u heplify-server -n 20 --no-pager -o cat | tail -5Troubleshooting
No calls appear after you point an agent at the VM. First check that the port is open from the agent's side, by running nc -vzu <your-vm-ip> 9060 from the signalling host. Then confirm that both the NSG rule and the ufw rule from Step 7 name that host's address. sudo journalctl -u heplify-server -f shows packets as they arrive.
The UI loads but a search returns nothing. Widen the time range in the top bar. HOMER searches the window shown there, and the default is narrow. Confirm that data is landing with:
sudo -u postgres psql -d homer_data -qtAc "SELECT count(*) FROM hep_proto_1_call"A service will not start. Both product services start only when their rendered configuration exists, which first boot creates. If systemctl status homer-app reports that the condition failed, check that first boot completed:
sudo systemctl status sipcapture-homer-firstboot.service --no-pager | head -5Certificate warnings in the browser are expected until you install your own certificate. See Maintenance.
Security notes
- On a stock deployment, the only ports reachable from off the box are
22,80(which redirects) and443. The HEP port is listening but firewalled until you open it to a specific source. - HOMER's UI and API are never exposed directly. nginx is the only network gate, and homer-app is bound to loopback.
- PostgreSQL listens on loopback only, with TLS disabled because nothing off-host connects to it. The role that both services use is not a superuser and cannot create roles or databases.
- Both built-in HOMER accounts are seeded with passwords generated on your VM's first boot. The upstream default is never written, and the demo API token that HOMER seeds is deleted.
- The JWT signing secret is generated on your VM. An empty signing key would let anyone forge a session token, so the appliance refuses to start the web application without one.
- The image ships the capture schema and the retention policy only. It contains no call data of any kind.
About this image
SecureAnyCloud builds and maintains this image. HOMER, heplify-server and homer-app are open-source projects released under the AGPL-3.0 licence by the SIPCAPTURE community. The software is shipped unmodified, and its source is available at github.com/sipcapture. PostgreSQL is the Ubuntu distribution package.
"HOMER" and "SIPCAPTURE" are used here only to identify the software that this image contains. SecureAnyCloud is not affiliated with, endorsed by or sponsored by the HOMER or SIPCAPTURE projects or their maintainers.
Support: sales@secureanycloud.com
Deploy on Azure
Launch HOMER 7 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com