commit ccc343dda3fb57f976c40fb6c5f8906f26145582
parent 6d0ea3959a19770131510eb5423f62443ae06bc0
Author: MTRNord <mtrnord1@gmail.com>
Date: Fri, 25 Aug 2023 23:21:57 +0200
Setup for custom built asterisk
Diffstat:
6 files changed, 340 insertions(+), 3 deletions(-)
diff --git a/nixos/worker-1/configuration.nix b/nixos/worker-1/configuration.nix
@@ -45,6 +45,7 @@
asterisk = {
withOpus = true;
+
};
};
};
@@ -628,8 +629,6 @@
apps=dial,park
events=ALL
'';
- "cdr_custom.conf" = "";
- "cel_custom.conf" = "";
"cdr.conf" = ''
[general]
enable = yes
diff --git a/pkgs/asterisk/default.nix b/pkgs/asterisk/default.nix
@@ -0,0 +1,226 @@
+{ stdenv
+, lib
+, fetchurl
+, fetchsvn
+, fetchFromGitHub
+, jansson
+, libedit
+, libxml2
+, libxslt
+, ncurses
+, openssl
+, sqlite
+, util-linux
+, dmidecode
+, libuuid
+, newt
+, lua
+, speex
+, libopus
+, opusfile
+, libogg
+, srtp
+, wget
+, curl
+, iksemel
+, pkg-config
+, autoconf
+, libtool
+, automake
+, fetchpatch
+, python39
+, writeScript
+, withOpus ? true
+, ldapSupport ? false
+, openldap
+}:
+
+let
+ # remove when upgrading to pjsip >2.13
+ pjsip_2_13_patches = [
+ (fetchpatch {
+ name = "CVE-2022-23537.patch";
+ url = "https://github.com/pjsip/pjproject/commit/d8440f4d711a654b511f50f79c0445b26f9dd1e1.patch";
+ sha256 = "sha256-7ueQCHIiJ7MLaWtR4+GmBc/oKaP+jmEajVnEYqiwLRA=";
+ })
+ (fetchpatch {
+ name = "CVE-2022-23547.patch";
+ url = "https://github.com/pjsip/pjproject/commit/bc4812d31a67d5e2f973fbfaf950d6118226cf36.patch";
+ sha256 = "sha256-bpc8e8VAQpfyl5PX96G++6fzkFpw3Or1PJKNPKl7N5k=";
+ })
+ (fetchpatch {
+ name = "CVE-2023-27585.patch";
+ url = "https://github.com/pjsip/pjproject/commit/d1c5e4da5bae7f220bc30719888bb389c905c0c5.patch";
+ hash = "sha256-+yyKKTKG2FnfyLWnc4S80vYtDzmiu9yRmuqb5eIulPg=";
+ })
+ ];
+
+ common = { version, sha256, externals, pjsip_patches ? [ ] }: stdenv.mkDerivation {
+ inherit version;
+ pname = "asterisk"
+ + lib.optionalString ldapSupport "-ldap";
+
+
+ buildInputs = [
+ jansson
+ libedit
+ libxml2
+ libxslt
+ ncurses
+ openssl
+ sqlite
+ dmidecode
+ libuuid
+ newt
+ lua
+ speex
+ srtp
+ wget
+ curl
+ iksemel
+ ]
+ ++ lib.optionals withOpus [ libopus opusfile libogg ]
+ ++ lib.optionals ldapSupport [ openldap ];
+ nativeBuildInputs = [ util-linux pkg-config autoconf libtool automake ];
+
+ patches = [
+ # We want the Makefile to install the default /var skeleton
+ # under ${out}/var but we also want to use /var at runtime.
+ # This patch changes the runtime behavior to look for state
+ # directories in /var rather than ${out}/var.
+ ./runtime-vardirs.patch
+ ] ++ lib.optional withOpus "${asterisk-opus}/asterisk.patch";
+
+ postPatch = ''
+ echo "PJPROJECT_CONFIG_OPTS += --prefix=$out" >> third-party/pjproject/Makefile.rules
+ '';
+
+ src = fetchurl {
+ url = "https://downloads.asterisk.org/pub/telephony/asterisk/old-releases/asterisk-${version}.tar.gz";
+ inherit sha256;
+ };
+
+ # The default libdir is $PREFIX/usr/lib, which causes problems when paths
+ # compiled into Asterisk expect ${out}/usr/lib rather than ${out}/lib.
+
+ # Copy in externals to avoid them being downloaded;
+ # they have to be copied, because the modification date is checked.
+ # If you are getting a permission denied error on this dir,
+ # you're likely missing an automatically downloaded dependency
+ preConfigure = ''
+ mkdir externals_cache
+
+ ${lib.concatStringsSep "\n"
+ (lib.mapAttrsToList (dst: src: "cp -r --no-preserve=mode ${src} ${dst}") externals)}
+
+ ${lib.optionalString (externals ? "addons/mp3") "bash contrib/scripts/get_mp3_source.sh || true"}
+
+ chmod -w externals_cache
+ ${lib.optionalString withOpus ''
+ cp ${asterisk-opus}/include/asterisk/* ./include/asterisk
+ cp ${asterisk-opus}/codecs/* ./codecs
+ cp ${asterisk-opus}/formats/* ./formats
+ ''}
+ ${lib.concatMapStringsSep "\n" (patch: ''
+ cp ${patch} ./third-party/pjproject/patches/${patch.name}
+ '') pjsip_patches}
+ ./bootstrap.sh
+ '';
+
+ configureFlags = [
+ "--libdir=\${out}/lib"
+ "--with-lua=${lua}/lib"
+ "--with-pjproject-bundled"
+ "--with-externals-cache=$(PWD)/externals_cache"
+ ];
+
+ preBuild = ''
+ cat third-party/pjproject/source/pjlib-util/src/pjlib-util/scanner.c
+ make menuselect.makeopts
+ ${lib.optionalString (externals ? "addons/mp3") ''
+ substituteInPlace menuselect.makeopts --replace 'format_mp3 ' ""
+ ''}
+ ${lib.optionalString withOpus ''
+ substituteInPlace menuselect.makeopts --replace 'codec_opus_open_source ' ""
+ substituteInPlace menuselect.makeopts --replace 'format_ogg_opus_open_source ' ""
+ ''}
+ '';
+
+ postInstall = ''
+ # Install sample configuration files for this version of Asterisk
+ make samples
+ ${lib.optionalString (lib.versionAtLeast version "17.0.0") "make install-headers"}
+ '';
+
+ meta = with lib; {
+ description = "Software implementation of a telephone private branch exchange (PBX)";
+ homepage = "https://www.asterisk.org/";
+ license = licenses.gpl2Only;
+ maintainers = with maintainers; [ auntie DerTim1 yorickvp ];
+ };
+ };
+
+ pjproject_2_13 = fetchurl
+ {
+ url = "https://raw.githubusercontent.com/asterisk/third-party/master/pjproject/2.13/pjproject-2.13.tar.bz2";
+ hash = "sha256-Zj93PUAct13KVR5taOWEbQdKq76wicaBTNHpHC0rICY=";
+ } // {
+ pjsip_patches = pjsip_2_13_patches;
+ };
+
+ mp3-202 = fetchsvn {
+ url = "http://svn.digium.com/svn/thirdparty/mp3/trunk";
+ rev = "202";
+ sha256 = "1s9idx2miwk178sa731ig9r4fzx4gy1q8xazfqyd7q4lfd70s1cy";
+ };
+
+ asterisk-opus = fetchFromGitHub {
+ owner = "traud";
+ repo = "asterisk-opus";
+ # No releases, points to master as of 2022-04-06
+ rev = "a959f072d3f364be983dd27e6e250b038aaef747";
+ sha256 = "sha256-CASlTvTahOg9D5jccF/IN10LP/U8rRy9BFCSaHGQfCw=";
+ };
+
+ # auto-generated by update.py
+ versions = lib.mapAttrs
+ (_: { version, sha256 }:
+ let
+ pjsip = pjproject_2_13;
+ in
+ common {
+ inherit version sha256;
+ inherit (pjsip) pjsip_patches;
+ externals = {
+ "externals_cache/${pjsip.name}" = pjsip;
+ "addons/mp3" = mp3-202;
+ };
+ })
+ (lib.importJSON ./versions.json);
+
+ updateScript_python = python39.withPackages (p: with p; [ packaging beautifulsoup4 requests ]);
+ updateScript = writeScript "asterisk-update" ''
+ #!/usr/bin/env bash
+ exec ${updateScript_python}/bin/python ${toString ./update.py}
+ '';
+
+in
+{
+ # Supported releases (as of 2023-04-19).
+ # v16 and v19 have been dropped because they go EOL before the NixOS 23.11 release.
+ # Source: https://wiki.asterisk.org/wiki/display/AST/Asterisk+Versions
+ # Exact version can be found at https://www.asterisk.org/downloads/asterisk/all-asterisk-versions/
+ #
+ # Series Type Rel. Date Sec. Fixes EOL
+ # 16.x LTS 2018-10-09 2022-10-09 2023-10-09 (dropped)
+ # 18.x LTS 2020-10-20 2024-10-20 2025-10-20
+ # 19.x Standard 2021-11-02 2022-11-02 2023-11-02 (dropped)
+ # 20.x LTS 2022-11-02 2026-10-19 2027-10-19
+ # 21.x Standard 2023-10-18 2025-10-18 2026-10-18 (unreleased)
+ asterisk-lts = versions.asterisk_18;
+ asterisk-stable = versions.asterisk_20;
+ asterisk = versions.asterisk_20.overrideAttrs (o: {
+ passthru = (o.passthru or { }) // { inherit updateScript; };
+ });
+
+} // versions
diff --git a/pkgs/asterisk/runtime-vardirs.patch b/pkgs/asterisk/runtime-vardirs.patch
@@ -0,0 +1,50 @@
+diff -rupN asterisk-14.1.2/build_tools/make_defaults_h asterisk-14.1.2-patched/build_tools/make_defaults_h
+--- asterisk-14.1.2/build_tools/make_defaults_h 2016-11-10 20:43:02.000000000 +0100
++++ asterisk-14.1.2-patched/build_tools/make_defaults_h 2016-11-16 10:09:04.189625495 +0100
+@@ -1,4 +1,13 @@
+ #!/bin/sh
++
++ASTLOGDIR=/var/log/asterisk
++ASTVARRUNDIR=/run/asterisk
++ASTVARLIBDIR=/var/lib/asterisk
++ASTDBDIR=${ASTVARLIBDIR}
++ASTDATADIR=${ASTVARLIBDIR}
++AGI_DIR=${ASTDATADIR}/agi-bin
++ASTSPOOLDIR=/var/spool/asterisk
++
+ cat << END
+ /*
+ * defaults.h
+@@ -9,21 +18,21 @@ cat << END
+
+ #define DEFAULT_CONFIG_DIR "${INSTALL_PATH}${ASTETCDIR}"
+ #define DEFAULT_MODULE_DIR "${INSTALL_PATH}${ASTMODDIR}"
+-#define DEFAULT_AGI_DIR "${INSTALL_PATH}${AGI_DIR}"
+-#define DEFAULT_LOG_DIR "${INSTALL_PATH}${ASTLOGDIR}"
++#define DEFAULT_AGI_DIR "${AGI_DIR}"
++#define DEFAULT_LOG_DIR "${ASTLOGDIR}"
+
+-#define DEFAULT_RUN_DIR "${INSTALL_PATH}${ASTVARRUNDIR}"
+-#define DEFAULT_SOCKET "${INSTALL_PATH}${ASTVARRUNDIR}/asterisk.ctl"
+-#define DEFAULT_PID "${INSTALL_PATH}${ASTVARRUNDIR}/asterisk.pid"
++#define DEFAULT_RUN_DIR "${ASTVARRUNDIR}"
++#define DEFAULT_SOCKET "${ASTVARRUNDIR}/asterisk.ctl"
++#define DEFAULT_PID "${ASTVARRUNDIR}/asterisk.pid"
+
+-#define DEFAULT_VAR_DIR "${INSTALL_PATH}${ASTVARLIBDIR}"
+-#define DEFAULT_DB "${INSTALL_PATH}${ASTDBDIR}/astdb"
++#define DEFAULT_VAR_DIR "${ASTVARLIBDIR}"
++#define DEFAULT_DB "${ASTDBDIR}/astdb"
+
+-#define DEFAULT_DATA_DIR "${INSTALL_PATH}${ASTDATADIR}"
+-#define DEFAULT_KEY_DIR "${INSTALL_PATH}${ASTDATADIR}/keys"
++#define DEFAULT_DATA_DIR "${ASTDATADIR}"
++#define DEFAULT_KEY_DIR "${ASTDATADIR}/keys"
+
+-#define DEFAULT_SPOOL_DIR "${INSTALL_PATH}${ASTSPOOLDIR}"
+-#define DEFAULT_TMP_DIR "${INSTALL_PATH}${ASTSPOOLDIR}/tmp"
++#define DEFAULT_SPOOL_DIR "${ASTSPOOLDIR}"
++#define DEFAULT_TMP_DIR "${ASTSPOOLDIR}/tmp"
+
+ #define DEFAULT_SBIN_DIR "${INSTALL_PATH}${ASTSBINDIR}"
+ END
+\ No newline at end of file
diff --git a/pkgs/asterisk/update.py b/pkgs/asterisk/update.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env nix-shell
+#!nix-shell -i python3 -p python39 python39.pkgs.packaging python39.pkgs.beautifulsoup4 python39.pkgs.requests
+# mirrored in ./default.nix
+from packaging import version
+from bs4 import BeautifulSoup
+import re, requests, json
+import os, sys
+from pathlib import Path
+
+URL = "https://downloads.asterisk.org/pub/telephony/asterisk"
+
+page = requests.get(URL)
+changelog = re.compile("^ChangeLog-\d+\.\d+\.\d+$")
+changelogs = [a.get_text() for a in BeautifulSoup(page.text, 'html.parser').find_all('a') if changelog.match(a.get_text())]
+major_versions = {}
+for changelog in changelogs:
+ v = version.parse(changelog.removeprefix("ChangeLog-"))
+ major_versions.setdefault(v.major, []).append(v)
+
+out = {}
+for mv in major_versions.keys():
+ v = max(major_versions[mv])
+ sha = requests.get(f"{URL}/asterisk-{v}.sha256").text.split()[0]
+ out["asterisk_" + str(mv)] = {
+ "version": str(v),
+ "sha256": sha
+ }
+
+versions_path = Path(sys.argv[0]).parent / "versions.json"
+
+try:
+ with open(versions_path, "r") as in_file:
+ in_data = json.loads(in_file.read())
+ for v in in_data.keys():
+ print(v + ":", in_data[v]["version"], "->", out[v]["version"])
+except:
+ # nice to have for the PR, not a requirement
+ pass
+
+with open(versions_path, "w") as out_file:
+ out_file.write(json.dumps(out, sort_keys=True, indent=2) + "\n")
+\ No newline at end of file
diff --git a/pkgs/asterisk/versions.json b/pkgs/asterisk/versions.json
@@ -0,0 +1,18 @@
+{
+ "asterisk_16": {
+ "sha256": "f8448e8784df7fac019e459bf7c82529d80afe64ae97d73d40e6aa0e4fb39724",
+ "version": "16.30.0"
+ },
+ "asterisk_18": {
+ "sha256": "66f0e55d84f9e5bf4e79a56255d35a034448acce00d219c3bf4930b1ebb0e88e",
+ "version": "18.17.1"
+ },
+ "asterisk_19": {
+ "sha256": "f0c56d1f8e39e0427455edfe25d24ff088c756bdc32dd1278c9f7a320815cbaa",
+ "version": "19.8.0"
+ },
+ "asterisk_20": {
+ "sha256": "df12e47000fbac42bb780bb06172aa8bb8ac26faf77cc9f95184695b0cec69c3",
+ "version": "20.2.1"
+ }
+}
+\ No newline at end of file
diff --git a/pkgs/default.nix b/pkgs/default.nix
@@ -2,5 +2,5 @@
# You can build them using 'nix build .#example' or (legacy) 'nix-build -A example'
{ pkgs ? (import ../nixpkgs.nix) { } }: {
- # example = pkgs.callPackage ./example { };
+ asterisk = pkgs.callPackage ./asterisk/default { };
}