1 { config, lib, pkgs, ... }:
3 cfg = config.services.asterisk;
5 asteriskUser = "asterisk";
6 asteriskGroup = "asterisk";
8 varlibdir = "/var/lib/asterisk";
9 spooldir = "/var/spool/asterisk";
10 logdir = "/var/log/asterisk";
12 # Add filecontents from files of useTheseDefaultConfFiles to confFiles, do not override
13 defaultConfFiles = lib.subtractLists (lib.attrNames cfg.confFiles) cfg.useTheseDefaultConfFiles;
15 # Default asterisk.conf file
16 "asterisk.conf".text = ''
18 astetcdir => /etc/asterisk
19 astmoddir => ${cfg.package}/lib/asterisk/modules
20 astvarlibdir => /var/lib/asterisk
21 astdbdir => /var/lib/asterisk
22 astkeydir => /var/lib/asterisk
23 astdatadir => /var/lib/asterisk
24 astagidir => /var/lib/asterisk/agi-bin
25 astspooldir => /var/spool/asterisk
26 astrundir => /run/asterisk
27 astlogdir => /var/log/asterisk
28 astsbindir => ${cfg.package}/sbin
32 # Loading all modules by default is considered sensible by the authors of
33 # "Asterisk: The Definitive Guide". Secure sites will likely want to
34 # specify their own "modules.conf" in the confFiles option.
35 "modules.conf".text = ''
40 # Use syslog for logging so logs can be viewed with journalctl
41 "logger.conf".text = ''
45 syslog.local0 => notice,warning,error
48 lib.mapAttrs (name: text: { inherit text; }) cfg.confFiles //
49 lib.listToAttrs (map (x: lib.nameValuePair x { source = cfg.package + "/etc/asterisk/" + x; }) defaultConfFiles);
56 enable = lib.mkOption {
57 type = lib.types.bool;
60 Whether to enable the Asterisk PBX server.
64 extraConfig = lib.mkOption {
66 type = lib.types.lines;
73 Extra configuration options appended to the default
78 confFiles = lib.mkOption {
80 type = lib.types.attrsOf lib.types.str;
81 example = lib.literalExpression
84 "extensions.conf" = '''
86 ; Dial 100 for "hello, world"
87 exten => 100,1,Answer()
89 same => n,Playback(hello-world)
99 allowguest=no ; Require authentication
100 context=unauthorized ; Send unauthorized users to /dev/null
101 srvlookup=no ; Don't do DNS lookup
102 udpbindaddr=0.0.0.0 ; Listen on all interfaces
103 nat=force_rport,comedia ; Assume device is behind NAT
106 type=friend ; Match on username first, IP second
107 context=softphones ; Send to softphones context in
108 ; extensions.conf file
109 host=dynamic ; Device will register with asterisk
110 disallow=all ; Manually specify codecs to allow
116 secret=GhoshevFew ; Change this password!
122 ; Add debug output to log
123 syslog.local0 => notice,warning,error,debug
128 Sets the content of config files (typically ending with
129 `.conf`) in the Asterisk configuration directory.
131 Note that if you want to change `asterisk.conf`, it
132 is preferable to use the {option}`services.asterisk.extraConfig`
133 option over this option. If `"asterisk.conf"` is
134 specified with the {option}`confFiles` option (not recommended),
135 you must be prepared to set your own `astetcdir`
139 <https://www.asterisk.org/community/documentation/>
140 for more examples of what is possible here.
144 useTheseDefaultConfFiles = lib.mkOption {
145 default = [ "ari.conf" "acl.conf" "agents.conf" "amd.conf" "calendar.conf" "cdr.conf" "cdr_syslog.conf" "cdr_custom.conf" "cel.conf" "cel_custom.conf" "cli_aliases.conf" "confbridge.conf" "dundi.conf" "features.conf" "hep.conf" "iax.conf" "pjsip.conf" "pjsip_wizard.conf" "phone.conf" "phoneprov.conf" "queues.conf" "res_config_sqlite3.conf" "res_parking.conf" "statsd.conf" "udptl.conf" "unistim.conf" ];
146 type = lib.types.listOf lib.types.str;
147 example = [ "sip.conf" "dundi.conf" ];
148 description = ''Sets these config files to the default content. The default value for
149 this option contains all necesscary files to avoid errors at startup.
150 This does not override settings via {option}`services.asterisk.confFiles`.
154 extraArguments = lib.mkOption {
156 type = lib.types.listOf lib.types.str;
158 [ "-vvvddd" "-e" "1024" ];
160 Additional command line arguments to pass to Asterisk.
163 package = lib.mkPackageOption pkgs "asterisk" { };
167 config = lib.mkIf cfg.enable {
168 environment.systemPackages = [ cfg.package ];
170 environment.etc = lib.mapAttrs' (name: value:
171 lib.nameValuePair "asterisk/${name}" value
174 users.users.asterisk =
175 { name = asteriskUser;
176 group = asteriskGroup;
177 uid = config.ids.uids.asterisk;
178 description = "Asterisk daemon user";
182 users.groups.asterisk =
183 { name = asteriskGroup;
184 gid = config.ids.gids.asterisk;
187 systemd.services.asterisk = {
192 wantedBy = [ "multi-user.target" ];
194 # Do not restart, to avoid disruption of running calls. Restart unit by yourself!
195 restartIfChanged = false;
198 # Copy skeleton directory tree to /var
199 for d in '${varlibdir}' '${spooldir}' '${logdir}'; do
200 # TODO: Make exceptions for /var directories that likely should be updated
201 if [ ! -e "$d" ]; then
203 cp --recursive ${cfg.package}/"$d"/* "$d"/
204 chown --recursive ${asteriskUser}:${asteriskGroup} "$d"
205 find "$d" -type d | xargs chmod 0755
213 # FIXME: This doesn't account for arguments with spaces
214 argString = lib.concatStringsSep " " cfg.extraArguments;
216 "${cfg.package}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F";
217 ExecReload = ''${cfg.package}/bin/asterisk -x "core reload"
220 PIDFile = "/run/asterisk/asterisk.pid";