141 lines
4.1 KiB
Nix
141 lines
4.1 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
let
|
|
cfg = config.nginxssl;
|
|
sslcfg = dir: ''
|
|
ssl on;
|
|
ssl_certificate_key ${dir}/key.pem;
|
|
ssl_certificate ${dir}/fullchain.pem;
|
|
ssl_trusted_certificate ${dir}/fullchain.pem;
|
|
add_header Strict-Transport-Security max-age=15768000;
|
|
'';
|
|
|
|
makeChallenges = servername: key_webroot: ''
|
|
server {
|
|
listen 80;
|
|
server_name ${servername};
|
|
location /.well-known/acme-challenge {
|
|
default_type text/plain;
|
|
alias ${key_webroot}/.well-known/acme-challenge;
|
|
}
|
|
}
|
|
'';
|
|
makeServerBlock = servername: {key_root, key_webroot, contents, ...}: ''
|
|
server {
|
|
listen 80;
|
|
server_name ${servername};
|
|
server_tokens off;
|
|
location /.well-known/acme-challenge {
|
|
default_type text/plain;
|
|
alias ${key_webroot}/.well-known/acme-challenge;
|
|
}
|
|
location / {
|
|
rewrite ^(.*) https://$host$1 permanent;
|
|
}
|
|
}
|
|
server {
|
|
listen 443;
|
|
server_name ${servername};
|
|
${sslcfg key_root}
|
|
${contents}
|
|
}
|
|
'';
|
|
#vhosts = with lib; unique (concatMap (splitString " ") (attrNames cfg.servers));
|
|
servopts = {...}: {
|
|
options = {
|
|
key_webroot = mkOption {
|
|
type = types.string;
|
|
description = "The path where the acme challenge is stored";
|
|
};
|
|
key_root = mkOption {
|
|
type = types.string;
|
|
description = "The path where the SSL keys are stored";
|
|
};
|
|
contents = mkOption {
|
|
type = types.string;
|
|
description = "Extra server block contents, like location blocks";
|
|
example = "location / {}";
|
|
};
|
|
};
|
|
};
|
|
inherit (lib) mkEnableOption mkOption types mkIf;
|
|
in
|
|
{
|
|
options.nginxssl = {
|
|
enable = mkEnableOption "enable new nginx module";
|
|
no_vhost_keydir = mkOption {
|
|
type = types.string;
|
|
default = "/etc/sslcerts/no_vhost";
|
|
description = "The path where the SSL keys for the default are stored (can and will be self-signed)";
|
|
};
|
|
servers = mkOption {
|
|
type = types.attrsOf types.optionSet;
|
|
description = "The servers to host";
|
|
default = {};
|
|
example = {"git.domain.com" = {
|
|
contents = "location / {}";
|
|
key_root = "/var/lib/acme/git.domain.com";
|
|
key_webroot = "/etc/sslcerts/acmeroot";
|
|
};
|
|
};
|
|
options = [ servopts ];
|
|
};
|
|
challenges = mkOption {
|
|
type = types.attrsOf types.string;
|
|
default = {};
|
|
example = {"mail.domain.com" = "/var/lib/acme/mail.domain.com";};
|
|
description = "Other domains to host challenges for";
|
|
};
|
|
};
|
|
config = mkIf cfg.enable {
|
|
services.nginx = {
|
|
enable = true;
|
|
recommendedTlsSettings = true;
|
|
recommendedGzipSettings = true;
|
|
recommendedProxySettings = true;
|
|
recommendedOptimisation = true;
|
|
serverTokens = false;
|
|
sslDhparam = "/etc/nginx/dhparam.pem";
|
|
virtualHosts = {
|
|
"\"\"" = {
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
index = "index.html index.htm";
|
|
root = "${pkgs.nginx}/html";
|
|
};
|
|
sslCertificate = "${cfg.no_vhost_keydir}/fullchain.pem";
|
|
sslCertificateKey = "${cfg.no_vhost_keydir}/key.pem";
|
|
default = true;
|
|
};
|
|
};
|
|
|
|
appendHttpConfig = ''
|
|
|
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList makeChallenges cfg.challenges)}
|
|
|
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList makeServerBlock cfg.servers)}
|
|
|
|
'';
|
|
};
|
|
networking.firewall.allowedTCPPorts = [80 443];
|
|
system.activationScripts.nginxdhparams =
|
|
''
|
|
if ! [[ -e /etc/nginx/dhparam.pem ]]; then
|
|
mkdir -p /etc/nginx/
|
|
${pkgs.openssl}/bin/openssl dhparam -out /etc/nginx/dhparam.pem 2048
|
|
fi
|
|
# self-sign certs in case an invalid vhost is looked up
|
|
dir=${cfg.no_vhost_keydir}
|
|
mkdir -m 0700 -p $dir
|
|
if ! [[ -e $dir/key.pem ]]; then
|
|
${pkgs.openssl}/bin/openssl genrsa -passout pass:foo -des3 -out $dir/key-in.pem 1024
|
|
${pkgs.openssl}/bin/openssl req -passin pass:foo -new -key $dir/key-in.pem -out $dir/key.csr \
|
|
-subj "/C=NL/CN=www.example.com"
|
|
${pkgs.openssl}/bin/openssl rsa -passin pass:foo -in $dir/key-in.pem -out $dir/key.pem
|
|
${pkgs.openssl}/bin/openssl x509 -req -days 365 -in $dir/key.csr -signkey $dir/key.pem -out $dir/fullchain.pem
|
|
fi
|
|
'';
|
|
};
|
|
|
|
|
|
}
|