nix/hosts/telefonmann/default.nix

172 lines
6.2 KiB
Nix

{ config, ... }:
let
address = "10.0.10.2";
in {
imports = [
./hardware.nix
./disko.nix
../../modules/voip
];
networking.hostName = "telefonmann";
networking.interfaces.ens19 = {
ipv4.addresses = [{
address = address;
prefixLength = 24;
}];
};
services.voip = {
enable = true;
serverAddress = address;
ntpServer = "10.0.10.1";
# directoryName = "tel.baubs.net"; # shown in phone directory title and HTML page header
# directoryPort = 8080; # HTTP port for directory, intercom XML, and status page
# sipPort = 5060; # SIP TCP/UDP port
# rtpStart = 10000; # RTP port range start
# rtpEnd = 20000; # RTP port range end
sharedPhones = {
"e0899d946ccc" = {
model = "cisco-8961";
extension = "20";
displayName = "Küche";
label = "Küchentelefon"; # shown on the phone screen (max ~12 chars)
password = "changeme100";
};
"e0899d947650" = {
model = "cisco-8961";
extension = "22";
displayName = "Flur";
label = "Flur";
password = "changeme100";
};
"fromschofon" = {
model = "sip-client";
extension = "23";
displayName = "Frosch";
label = "Frosch";
password = "changeme102";
};
};
persons = {
"jannel" = {
extension = "21";
displayName = "Jannel";
mailbox = true;
# ringTimeout = 30; # seconds to ring before going to voicemail
mailboxGreeting = ./greetings/anrufbeantworter.wav;
phones = {
"jannel-mobile" = { model = "sip-client"; password = "changeme101"; };
"f47f35a3fb72" = { model = "cisco-9971"; label = "Jannelfon"; password = "changeme101"; };
};
};
};
backgroundImages = {
"Wombel" = ./backgrounds/wombel.png;
};
intercomPrefix = "*80"; # generates e.g. *8020, *8021, *8022 per extension
mohClasses = {
"default" = {
files = [ ./music/vapor.mp3 ];
sort = "random";
# sort = "alphabetical";
};
# add more classes here and reference them per-DID via musicOnHold = "classname"
};
sipTrunks = {
"ewe1" = {
hostFile = config.age.secrets."voip-trunk-ewe-host".path;
usernameFile = config.age.secrets."voip-trunk-ewe1-username".path;
passwordFile = config.age.secrets."voip-trunk-ewe1-password".path;
callerIdFile = config.age.secrets."voip-trunk-ewe1-callerid".path;
codecs = [ "g722" "alaw" "ulaw" ];
};
"ewe2" = {
hostFile = config.age.secrets."voip-trunk-ewe-host".path;
usernameFile = config.age.secrets."voip-trunk-ewe2-username".path;
passwordFile = config.age.secrets."voip-trunk-ewe2-password".path;
callerIdFile = config.age.secrets."voip-trunk-ewe2-callerid".path;
codecs = [ "g722" "alaw" "ulaw" ];
};
"ewe3" = {
hostFile = config.age.secrets."voip-trunk-ewe-host".path;
usernameFile = config.age.secrets."voip-trunk-ewe3-username".path;
passwordFile = config.age.secrets."voip-trunk-ewe3-password".path;
callerIdFile = config.age.secrets."voip-trunk-ewe3-callerid".path;
codecs = [ "g722" "alaw" "ulaw" ];
};
};
sharedMailbox = {
mailboxId = "200";
checkExtension = "*98";
displayName = "Baubse";
greeting = ./greetings/anrufbeantworter.wav;
};
dids = {
"baubse" = {
numberFile = config.age.secrets."voip-trunk-ewe1-callerid".path;
trunk = "ewe1";
displayName = "Baubse";
routing = {
type = "all"; # ring all phones (sharedPhones + persons) on their L2 line
# timeout = 30; # seconds to ring before falling through to mailbox
};
mailbox = "shared"; # → sharedMailbox on no answer
musicOnHold = "default";
};
"jannel" = {
numberFile = config.age.secrets."voip-trunk-ewe2-callerid".path;
trunk = "ewe2";
displayName = "Jannel";
routing = {
type = "person";
person = "jannel"; # ring jannel's phones on their L1 line
# timeout = 30;
};
mailbox = "person"; # → jannel's personal mailbox on no answer
# musicOnHold = "default";
};
# ewe3 DID — uncomment and fill in number when known:
# "ewe3-main" = {
# number = ""; # or: numberFile = ./secrets/did-ewe3;
# trunk = "ewe3";
# displayName = "...";
# routing = { type = "all"; };
# mailbox = "shared";
# };
};
extensions = {
"*99" = { mode = "page"; displayName = "Durchsage an alle"; };
"*100" = { mode = "all"; displayName = "Alle rufen"; };
# custom app extension example:
# "*00" = { mode = "app"; displayName = "Echo test"; app = "Echo()"; };
};
};
# Age-encrypted secrets (decrypted on the host at activation time).
age.secrets =
let asteriskSecret = file: { inherit file; owner = "asterisk"; group = "voip-keys"; mode = "0640"; };
in {
"voip-trunk-ewe-host" = asteriskSecret ../../secrets/voip-trunk-ewe-host.age;
"voip-trunk-ewe1-username" = asteriskSecret ../../secrets/voip-trunk-ewe1-username.age;
"voip-trunk-ewe1-password" = asteriskSecret ../../secrets/voip-trunk-ewe1-password.age;
"voip-trunk-ewe1-callerid" = asteriskSecret ../../secrets/voip-trunk-ewe1-callerid.age;
"voip-trunk-ewe2-username" = asteriskSecret ../../secrets/voip-trunk-ewe2-username.age;
"voip-trunk-ewe2-password" = asteriskSecret ../../secrets/voip-trunk-ewe2-password.age;
"voip-trunk-ewe2-callerid" = asteriskSecret ../../secrets/voip-trunk-ewe2-callerid.age;
"voip-trunk-ewe3-username" = asteriskSecret ../../secrets/voip-trunk-ewe3-username.age;
"voip-trunk-ewe3-password" = asteriskSecret ../../secrets/voip-trunk-ewe3-password.age;
"voip-trunk-ewe3-callerid" = asteriskSecret ../../secrets/voip-trunk-ewe3-callerid.age;
};
}