modules(pihole-container): simplify exposing PiHole ports

Initially the PiHole module was supposed to provide an option to expose rootless PiHole on privileged ports s.t. the user does not have to find out/decide how to do it herself.
However, it seems to be out-of-scope for flake which should provide a rootless PiHole container.
Further, any decision taken on how to achieve this could limit the users choices for other system configuration options.
Inestead options for making PiHole available on priviledged ports should be described in the Readme and maybe in example configurations.
This commit is contained in:
Christopher Bacher 2022-12-03 23:07:47 +01:00
parent f4ff6d5e91
commit 4a2a0b86d6
2 changed files with 50 additions and 53 deletions

View file

@ -1,40 +0,0 @@
nixpkgsLib: with nixpkgsLib; {
mkContainerEnvOption = { envVar, ... }@optionAttrs:
(mkOption (removeAttrs optionAttrs [ "envVar" ]))
// { inherit envVar; };
mkHostPortsOption = { service, publicDefaultPort }: {
hostInternalPort = mkOption {
type = types.port;
description = ''
The internal port on the host on which the ${service} port of the pihole container should be exposed.
Only needs to be specified if he container port should be exposed
or if the port-forwarding for this service is enabled.
As the pihole container is running rootless this cannot be a privileged port (<1024).
'';
};
hostPublicPort = mkOption {
type = types.port;
description = ''
The public port on the host on which the ${service} port of the pihole container should be forwared to.
This option can be used to together with the according `forwardPublicToInternal` to expose a pihole subservice on a privileged port,
e.g., if you want to expose the DNS service on port 53.
'';
default = publicDefaultPort;
};
forwardPublicToInternal = mkOption {
type = types.bool;
description = ''
Enable port-forwarding between the public & the internal port of the host.
This effectively makes pihole's ${service} port available on the network to which the host is connected to.
Use this option together with the according `hostPublicPort` to expose a pihole subservice on a privileged port.
'';
default = false;
};
};
}

View file

@ -1,6 +1,9 @@
{ piholeFlake, lingerFlake }: { config, pkgs, lib, ... }: with lib; with builtins; let
inherit (import ../lib/util.nix) extractContainerEnvVars extractContainerFTLEnvVars;
inherit (import ../lib/options.nix lib) mkContainerEnvOption mkHostPortsOption;
mkContainerEnvOption = { envVar, ... }@optionAttrs:
(mkOption (removeAttrs optionAttrs [ "envVar" ]))
// { inherit envVar; };
cfg = config.services.pihole;
hostUserCfg = config.users.users.${cfg.hostConfig.user};
@ -59,19 +62,40 @@ in rec {
example = "/home/pihole-user/pihole-volumes";
};
dns = mkHostPortsOption {
service = "DNS";
publicDefaultPort = 53;
dnsPort = mkOption {
type = with types; nullOr (either port str);
description = ''
THe port on which PiHole's DNS service shoud be exposed.
Either pass a port number as integer or a string in the format `ip:port` (see [Docker docs](https://docs.docker.com/engine/reference/run/#expose-incoming-ports) for details).
If this option is not specified the DNS service will not be exposed on the host.
Remember that if the container is running rootless exposing on a privileged port is not possible.
'';
default = null;
};
dhcp = mkHostPortsOption {
service = "DHCP";
publicDefaultPort = 67;
dhcpPort = mkOption {
type = with types; nullOr (either port str);
description = ''
THe port on which PiHole's DHCP service shoud be exposed.
Either pass a port number as integer or a string in the format `ip:port` (see [Docker docs](https://docs.docker.com/engine/reference/run/#expose-incoming-ports) for details).
If this option is not specified the DHCP service will not be exposed on the host.
Remember that if the container is running rootless exposing on a privileged port is not possible.
'';
default = null;
};
web = mkHostPortsOption {
service = "Web";
publicDefaultPort = 80;
webPort = mkOption {
type = with types; nullOr (either port str);
description = ''
THe port on which PiHole's web interface shoud be exposed.
Either pass a port number as integer or a string in the format `ip:port` (see [Docker docs](https://docs.docker.com/engine/reference/run/#expose-incoming-ports) for details).
If this option is not specified the web interface will not be exposed on the host.
Remember that if the container is running rootless exposing on a privileged port is not possible.
'';
default = null;
};
suppressTmpDirWarning = mkOption {
@ -359,9 +383,22 @@ in rec {
-v ${cfg.hostConfig.volumesPath}/etc-dnsmasq.d:/etc/dnsmasq.d \
'' else ""
} \
-p ${toString cfg.hostConfig.dns.hostInternalPort}:53/tcp \
-p ${toString cfg.hostConfig.dns.hostInternalPort}:53/udp \
-p ${toString cfg.hostConfig.web.hostInternalPort}:80/tcp \
${
if !(isNull cfg.hostConfig.dnsPort) then ''
-p ${toString cfg.hostConfig.dnsPort}:53/tcp \
-p ${toString cfg.hostConfig.dnsPort}:53/udp \
'' else ""
} \
${
if !(isNull cfg.hostConfig.dhcpPort) then ''
-p ${toString cfg.hostConfig.dhcpPort}:67/udp \
'' else ""
} \
${
if !(isNull cfg.hostConfig.webPort) then ''
-p ${toString cfg.hostConfig.webPort}:80/tcp \
'' else ""
} \
${
concatStringsSep " \\\n"
(map (envVar: " -e '${envVar.name}=${toString envVar.value}'") (containerEnvVars ++ containerFTLEnvVars))