{ config, lib, ... }: let cfg = config.services.nginx; inherit (lib) mkDefault mkIf mkOption optional optionals types ; in { options.services.nginx = { forceSSL = mkOption { type = types.bool; default = false; description = "Force SSL for Nginx virtual host."; }; openFirewall = mkOption { type = types.bool; default = false; description = "Whether to open the firewall for HTTP (and HTTPS if forceSSL is enabled)."; }; }; config = mkIf cfg.enable { networking.firewall.allowedTCPPorts = optionals cfg.openFirewall ( [ 80 ] ++ optional cfg.forceSSL 443 ); services.nginx = { recommendedOptimisation = mkDefault true; recommendedGzipSettings = mkDefault true; recommendedProxySettings = mkDefault true; recommendedTlsSettings = cfg.forceSSL; commonHttpConfig = "access_log syslog:server=unix:/dev/log;"; resolver.addresses = let isIPv6 = addr: builtins.match ".*:.*:.*" addr != null; escapeIPv6 = addr: if isIPv6 addr then "[${addr}]" else addr; cloudflare = [ "1.1.1.1" "2606:4700:4700::1111" ]; resolvers = if config.networking.nameservers == [ ] then cloudflare else config.networking.nameservers; in map escapeIPv6 resolvers; sslDhparam = mkIf cfg.forceSSL config.security.dhparams.params.nginx.path; }; security.acme = mkIf cfg.forceSSL { acceptTerms = true; defaults.email = mkDefault "postmaster@${config.networking.domain}"; defaults.webroot = mkDefault "/var/lib/acme/acme-challenge"; defaults.group = mkDefault "nginx"; }; security.dhparams = mkIf cfg.forceSSL { enable = true; params.nginx = { }; }; }; }