{ config, lib, pkgs, ... }: with lib; let cfg = config.clerie.nginx-port-forward; portForwardConf = '' stream { ${ concatStringsSep "\n" ( mapAttrsToList ( port: forward: '' server { listen ${port}; listen [::]:${port}; proxy_pass ${forward.host}:${toString forward.port}; } '' ) cfg.tcpPorts ) } ${ concatStringsSep "\n" ( mapAttrsToList ( port: forward: '' server { listen ${port} udp; listen [::]:${port} udp; proxy_pass ${forward.host}:${toString forward.port}; } '' ) cfg.udpPorts ) } } ''; portOpts = { config, ... }@moduleAttrs: { options = { host = mkOption { type = types.str; }; port = mkOption { type = types.int; }; }; }; in { options = { clerie.nginx-port-forward = { enable = mkEnableOption "Nginx Port Forward"; tcpPorts = mkOption { type = with types; attrsOf (submodule portOpts); default = {}; }; udpPorts = mkOption { type = with types; attrsOf (submodule portOpts); default = {}; }; }; }; config = mkIf cfg.enable { services.nginx.enable = true; services.nginx.appendConfig = portForwardConf; networking.firewall.allowedTCPPorts = mapAttrsToList ( port: dontcare: toInt port ) cfg.tcpPorts; networking.firewall.allowedUDPPorts = mapAttrsToList ( port: dontcare: toInt port ) cfg.udpPorts; }; }