sip: TLS transport with a checked certificate, TLS + SRTP trunks
ci / check (push) Successful in 58s
ci / images (push) Successful in 24s

The certificate lives in data/tls (fullchain.pem + privkey.pem), mounted
read-only into asterisk and the api. Asterisk quietly drops transport-tls
when the files are missing, so the api won't turn TLS on unless they load
and match, shows the certificate on Settings -> Security, and warns on the
dashboard when it expires within 14 days. scripts/tls-cert.sh copies it
from the bundled Caddy (or given paths) and reloads res_pjsip: Asterisk 24
re-reads a changed certificate on reload, calls stay up.

transport-tls checks the provider's certificate (verify_server). Asterisk
24 checks a qualify's certificate against the IP instead of the name, which
fails on voip.ms, so TLS trunks don't qualify; REGISTER and INVITE verify
the name fine.

Task: M11-T2
This commit is contained in:
iamdoubz committed 2026-10-19 16:33:11 -05:00
1 parent 8c750c67ca
commit 803859a1d2
23 files changed
+772 -19

No files matched your search

+46
View File
@@ -53,6 +53,47 @@ async function check(name) {
const mohConf = readFileSync(join(tmp, 'musiconhold_selfphoneng.conf'), 'utf8');
for (const [, d] of mohConf.matchAll(/^directory = \/var\/lib\/asterisk\/moh\/(.+)$/gm))
mkdirSync(join(moh, d));
// transport-tls needs a certificate, or Asterisk quietly leaves it out: make a throwaway one.
const tls = mkdtempSync(join(tmpdir(), `sp-golden-tls-`));
const wantTls = /^\[transport-tls\]$/m.test(
readFileSync(join(tmp, 'pjsip_selfphoneng.conf'), 'utf8'),
);
if (wantTls) {
const cert = docker(
'run',
'--rm',
'-v',
`${tls}:/out`,
'--entrypoint',
'openssl',
IMAGE,
'req',
'-x509',
'-newkey',
'rsa:2048',
'-nodes',
'-days',
'1',
'-subj',
'/CN=golden.test',
'-keyout',
'/out/privkey.pem',
'-out',
'/out/fullchain.pem',
);
if (!cert.ok) throw new Error(`making a test certificate failed: ${cert.out}`);
docker(
'run',
'--rm',
'-v',
`${tls}:/out`,
'--entrypoint',
'chmod',
IMAGE,
'644',
'/out/privkey.pem',
);
}
const run = docker(
'run',
'-d',
@@ -65,6 +106,8 @@ async function check(name) {
`${tmp}:/etc/asterisk/selfphoneng`,
'-v',
`${moh}:/var/lib/asterisk/moh`,
'-v',
`${tls}:/var/lib/selfphoneng/tls:ro`,
IMAGE,
);
if (!run.ok) throw new Error(`docker run failed: ${run.out}`);
@@ -78,6 +121,8 @@ async function check(name) {
await sleep(500);
const { endpoints, contexts, mailboxes, queues } = expectations(tmp);
if (wantTls && !/transport-tls\s+tls/.test(cli('pjsip show transports').out))
problems.push('transport-tls not loaded');
const shown = cli('pjsip show endpoints').out;
for (const e of endpoints)
if (!new RegExp(`Endpoint:\\s+${e}[\\s/]`).test(shown))
@@ -106,6 +151,7 @@ async function check(name) {
docker('rm', '-f', NAME);
rmSync(tmp, { recursive: true, force: true });
rmSync(moh, { recursive: true, force: true });
rmSync(tls, { recursive: true, force: true });
}
}