nixos/modules/core/vhost.nix

116 lines
4.1 KiB
Nix

{ config, lib, ... }:
let
inherit (lib) mkOption types mapAttrs concatMapStringsSep optionalString mkIf;
cfg = config.pepe.core.vhost;
in
{
options.pepe.core.vhost = {
hosts = mkOption {
type = types.attrsOf (types.submodule {
options = {
locations = mkOption {
type = types.attrsOf (types.submodule {
options = {
extraConfig = mkOption {
type = types.str;
description = "Extra configuration for the location.";
default = "";
};
proxyWebsockets = mkOption {
type = types.bool;
default = false;
};
host = mkOption {
type = types.str;
description = "The host for the location.";
default = "127.0.0.1";
};
port = mkOption {
type = types.int;
description = "The port number for the location.";
};
allow = mkOption {
type = types.listOf types.str;
default = [ ];
description = "IP address or CIDR block to allow.";
};
allowVPN = mkOption {
type = types.bool;
default = false;
description = "If set to true, allow VPN traffic.";
};
allowLAN = mkOption {
type = types.bool;
default = false;
description = "If set to true, allow LAN traffic.";
};
allowWAN = mkOption {
type = types.bool;
default = false;
description = "If set to true, allow WAN traffic. If false, deny all WAN traffic.";
};
path = mkOption {
type = types.str;
default = "";
};
recommendedProxySettings = mkOption {
type = types.bool;
default = true;
description = "Force the use of recommended proxy configuration.";
};
};
});
default = { };
description = "An attribute set of location configurations.";
};
};
});
default = { };
description = "An attribute set of domain configurations.";
};
};
config = {
# Configure DNS entries for vhosts when DNS is enabled
pepe.core.dns = mkIf config.pepe.core.dns.enable {
extraDomains = mapAttrs (domain: conf: {
dnsInterfaces =
(lib.optionals (lib.any (loc: loc.allowLAN) (lib.attrValues conf.locations))
config.pepe.core.network.interfacesByType.lan) ++
(lib.optionals (lib.any (loc: loc.allowVPN) (lib.attrValues conf.locations))
config.pepe.core.network.interfacesByType.vpn);
}) cfg.hosts;
};
services.nginx.virtualHosts = mapAttrs
(domain: conf: {
forceSSL = true;
useACMEHost= "giugl.io";
locations = mapAttrs
(path: location: {
proxyPass = "http://${location.host}:${toString location.port}${location.path}";
proxyWebsockets = location.proxyWebsockets;
recommendedProxySettings = location.recommendedProxySettings;
extraConfig = ''
${concatMapStringsSep "\n" (allowCIDR: "allow ${allowCIDR};") location.allow}
${optionalString location.allowLAN (concatMapStringsSep "\n" (ifaceName: "allow ${config.pepe.core.network.interfaces.${ifaceName}.net};") config.pepe.core.network.interfacesByType.lan)}
${optionalString location.allowVPN (concatMapStringsSep "\n" (ifaceName: "allow ${config.pepe.core.network.interfaces.${ifaceName}.net};") config.pepe.core.network.interfacesByType.vpn)}
${optionalString (!location.allowWAN) "deny all;"}
'' + location.extraConfig;
})
conf.locations;
})
cfg.hosts;
};
}