diff --git a/cookbooks/asterisk/README.md b/cookbooks/asterisk/README.md index b3cec3c..3db54e2 100644 --- a/cookbooks/asterisk/README.md +++ b/cookbooks/asterisk/README.md @@ -4,7 +4,7 @@ [Asterisk](https://www.asterisk.org/) is an open source PBX. This cookbook runs it as a SIP server for phones on the local network, together with the TFTP server the phones fetch their configuration and -firmware from. +firmware from, and an HTTP server for their directory. This cookbook: @@ -13,6 +13,7 @@ This cookbook: - Runs Asterisk directly as a dedicated, unprivileged UID/GID (no user namespace mapping), with PJSIP as its only channel driver. - Runs dnsmasq as a TFTP server only (no DNS, no DHCP), from the same image, as the same user. +- Runs the httpd of busybox as a static HTTP server, from the same image, as the same user. - Loads an explicit list of Asterisk modules: what calls between SIP phones need, and nothing else. - Includes a timer to rebuild the container image daily. @@ -34,11 +35,12 @@ interface. | `/etc/quadlets/asterisk/etc/extensions.conf` | Dialplan. Required. | | `/etc/quadlets/asterisk/etc/indications.conf` | Call progress tones of the country. Optional: without it, Asterisk logs a warning and uses no tones of its own; the phones play theirs. | | `/var/lib/virtiofs/data/asterisk/tftp/` | Configuration files and firmware images of the phones, as each vendor names them. Optional: the TFTP server also runs on an empty directory, so that files written later are served without a restart. | +| `/var/lib/virtiofs/data/asterisk/http/` | Static files served over HTTP, such as the XML directory of the phones. Optional, like the TFTP root. Keep the configuration files of the phones out of it: they hold SIP passwords, and HTTP is easier to reach from another network than TFTP. | Asterisk does not start without `pjsip.conf` and `extensions.conf`. Examples of both are in `config/examples/etc/`. -The TFTP root is on the virtiofs mount rather than under `/etc/quadlets`, so that the host can write +The TFTP and HTTP roots are on the virtiofs mount rather than under `/etc/quadlets`, so that the host can write it: a firmware image weighs tens of megabytes, which an Ignition file cannot carry. The files must be readable by UID 10036. @@ -53,14 +55,15 @@ missing. | 5060 | UDP | SIP | | 10000-10999 | UDP | RTP (set in `rtp.conf`) | | 69 | UDP | TFTP | +| 80 | TCP | HTTP | -Both containers use host networking. +All three containers use host networking. ## UID and GID | UID | GID | Usage | |-----|-----|-------| -| 10036 | 10000 | Asterisk and dnsmasq | +| 10036 | 10000 | Asterisk, dnsmasq and httpd | ## Usage diff --git a/cookbooks/asterisk/asterisk-http.container b/cookbooks/asterisk/asterisk-http.container new file mode 100644 index 0000000..c131bdc --- /dev/null +++ b/cookbooks/asterisk/asterisk-http.container @@ -0,0 +1,48 @@ +[Unit] +Description=Asterisk - HTTP server for the directory of the phones +Documentation=https://busybox.net/downloads/BusyBox.html + +Wants=asterisk-build.service +After=network.target asterisk-build.service var-lib-virtiofs-data.mount +Requires=var-lib-virtiofs-data.mount + +# Static files only, operator-provided on the precious-data mount, like the +# TFTP root and for the same reasons. A separate directory from the TFTP root: +# the configuration files of the phones hold their SIP passwords, and HTTP, +# unlike TFTP, is easily reached from another network. + +# Start/stop this unit when the target is started/stopped +PartOf=asterisk.target + +[Container] +ContainerName=asterisk-http +Image=localhost/asterisk:latest +AutoUpdate=local + +User=10036 +Group=10000 + +# HTTP listens on 80/tcp, a privileged port. +AddCapability=CAP_NET_BIND_SERVICE + +# Host networking, as the two other containers: the phones reach the same +# address for SIP, TFTP and HTTP. +Network=host + +# busybox httpd: -f stays in the foreground, -v logs each request. It reads +# /etc/httpd.conf of the image for the MIME type of XML files, and lists no +# directory. +Entrypoint=/usr/sbin/httpd +Exec=-f -v -p 80 -h /var/lib/virtiofs/data/asterisk/http + +# Read-only: the phones fetch, they never upload. +Volume=/var/lib/virtiofs/data/asterisk/http:/var/lib/virtiofs/data/asterisk/http:ro,z + +[Service] +Restart=always +RestartSec=10 +TimeoutStartSec=300 +TimeoutStopSec=30 + +[Install] +WantedBy=asterisk.target diff --git a/cookbooks/asterisk/asterisk.target b/cookbooks/asterisk/asterisk.target index 172f9af..58efc96 100644 --- a/cookbooks/asterisk/asterisk.target +++ b/cookbooks/asterisk/asterisk.target @@ -2,8 +2,8 @@ Description=Asterisk Service Target Documentation=man:systemd.target(5) Requires=asterisk.service asterisk-build.timer -Wants=asterisk-tftp.service -After=asterisk.service asterisk-tftp.service asterisk-build.timer +Wants=asterisk-tftp.service asterisk-http.service +After=asterisk.service asterisk-tftp.service asterisk-http.service asterisk-build.timer # Allow isolation - can stop/start this target independently AllowIsolate=yes diff --git a/cookbooks/asterisk/config/container/Containerfile b/cookbooks/asterisk/config/container/Containerfile index b1f1568..35c7fee 100644 --- a/cookbooks/asterisk/config/container/Containerfile +++ b/cookbooks/asterisk/config/container/Containerfile @@ -2,8 +2,13 @@ FROM docker.io/library/alpine:3.24 # Asterisk 22 (the LTS branch), PJSIP included: Alpine bundles pjproject in the # main package. dnsmasq serves the provisioning files of the phones over TFTP, -# from the same image, so that a single build keeps both up to date. -RUN apk add --no-cache asterisk dnsmasq +# and the httpd of busybox-extras their directory over HTTP, from the same +# image, so that a single build keeps all three up to date. +RUN apk add --no-cache asterisk dnsmasq busybox-extras + +# busybox httpd sends no Content-Type for .xml files without this line, and +# the XML services of the phones expect text/xml. +RUN printf '.xml:text/xml; charset=utf-8\n' > /etc/httpd.conf # /etc/asterisk is empty: the sample files are in asterisk-sample-config, which # is not installed. The configuration is mounted read-only there at run time. diff --git a/cookbooks/asterisk/tmpfiles.d/asterisk.conf b/cookbooks/asterisk/tmpfiles.d/asterisk.conf index ac4d098..7b3078d 100644 --- a/cookbooks/asterisk/tmpfiles.d/asterisk.conf +++ b/cookbooks/asterisk/tmpfiles.d/asterisk.conf @@ -1,4 +1,5 @@ -# Provisioning files of the phones, served over TFTP. Operator-provided, on the +# Provisioning files of the phones, served over TFTP, and their directory, +# served over HTTP. Operator-provided, on the # precious-data mount so that the host can write them. The "$" marks it for # removal on `systemd-tmpfiles --purge` (i.e. `make uninstall`). # @@ -13,3 +14,4 @@ # not affected: its label is fixed by the mount. d$ /var/lib/virtiofs/data/asterisk 0750 10036 10000 - d$ /var/lib/virtiofs/data/asterisk/tftp 0750 10036 10000 - +d$ /var/lib/virtiofs/data/asterisk/http 0750 10036 10000 -