infrastructure/nixos/access/freepbx.nix
2024-06-13 14:52:23 -07:00

144 lines
4.1 KiB
Nix

{
config,
access,
gensokyo-zone,
lib,
...
}: let
inherit (gensokyo-zone.lib) mapDefaults;
inherit (lib.modules) mkIf mkDefault;
inherit (lib.lists) optional;
inherit (config.services) nginx;
system = access.systemForService "freepbx";
inherit (system.exports.services) freepbx;
upstreamName = "freepbx";
upstreamName'ucp = "freepbx'ucp";
in {
config.services.nginx = {
upstreams' = {
${upstreamName} = {
servers.access = {
accessService = mapDefaults {
inherit (freepbx) name id;
system = system.name;
port = "https";
};
};
};
${upstreamName'ucp} = {
servers.access = {
accessService = mapDefaults {
inherit (freepbx) name id;
system = system.name;
port = "ucp-ssl";
getAddressFor = "getAddress4For";
};
};
};
};
virtualHosts = let
ucpPath = "/socket.io/";
# TODO: ports.asterisk/asterisk-ssl?
hostCommon = {xvars, ...}: {
extraConfig = ''
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_cookie_flags ~ nosamesite;
proxy_cookie_domain ~ ${xvars.get.host};
'';
locations = {
${ucpPath} = {
xvars,
virtualHost,
...
}: {
proxy = {
enable = true;
websocket.enable = true;
headers.hide.Access-Control-Allow-Origin = true;
};
headers.set.Access-Control-Allow-Origin = "${xvars.get.scheme}://${virtualHost.serverName}";
};
};
};
hostWeb = {...}: {
imports = [hostCommon];
locations = {
"/" = {xvars, ...}: {
xvars.enable = true;
proxy = {
enable = true;
redirect = {
enable = true;
fromScheme = xvars.get.proxy_scheme;
};
};
};
${ucpPath}.proxy = {
upstream = mkDefault nginx.virtualHosts.freepbx'ucp.proxy.upstream;
};
};
};
name.shortServer = mkDefault "pbx";
in {
freepbx = {...}: {
imports = [hostWeb];
vouch.enable = mkDefault true;
ssl.force = true;
proxy.upstream = upstreamName;
inherit name;
};
freepbx'ucp = {...}: {
imports = [hostCommon];
serverName = mkDefault nginx.virtualHosts.freepbx.serverName;
ssl.cert.copyFromVhost = "freepbx";
listen' = {
ucp = {
port = mkDefault freepbx.ports.ucp.port;
extraParameters = ["default_server"];
};
ucpSsl = {
port = mkDefault freepbx.ports.ucp-ssl.port;
ssl = true;
extraParameters = ["default_server"];
};
};
proxy = {
upstream = mkDefault upstreamName'ucp;
websocket.enable = true;
};
vouch.enable = mkDefault true;
local.denyGlobal = mkDefault nginx.virtualHosts.freepbx.local.denyGlobal;
};
freepbx'local = {...}: {
imports = [hostWeb];
listen' = {
http = {};
https.ssl = true;
ucp = {
port = mkDefault nginx.virtualHosts.freepbx'ucp.listen'.ucp.port;
};
ucpSsl = {
port = mkDefault nginx.virtualHosts.freepbx'ucp.listen'.ucpSsl.port;
ssl = true;
};
};
ssl.cert.copyFromVhost = "freepbx";
proxy.copyFromVhost = "freepbx";
local.enable = true;
inherit name;
};
};
};
config.networking.firewall = let
websocketPorts = virtualHost:
[
virtualHost.listen'.ucp.port
]
++ optional virtualHost.listen'.ucpSsl.enable virtualHost.listen'.ucpSsl.port;
in {
interfaces.local.allowedTCPPorts = websocketPorts nginx.virtualHosts.freepbx'local;
allowedTCPPorts = mkIf (!nginx.virtualHosts.freepbx'ucp.local.denyGlobal) (websocketPorts nginx.virtualHosts.freepbx'ucp);
};
}