mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2025-12-06 09:07:21 +01:00
feat[server]: improve nginx config
This commit is contained in:
parent
4473255269
commit
56c1f35548
2 changed files with 192 additions and 2 deletions
|
|
@ -7049,9 +7049,60 @@ Here we just define some aliases for rebuilding the system, and we allow some in
|
||||||
inherit (config.repo.secrets.common) dnsProvider;
|
inherit (config.repo.secrets.common) dnsProvider;
|
||||||
inherit (config.repo.secrets.common.mail) address3;
|
inherit (config.repo.secrets.common.mail) address3;
|
||||||
|
|
||||||
|
serviceUser = "nginx";
|
||||||
|
serviceGroup = serviceUser;
|
||||||
|
|
||||||
|
sslBasePath = "/etc/ssl";
|
||||||
|
dhParamsPathBase = "${sslBasePath}/dhparams.pem";
|
||||||
|
dhParamsPath =
|
||||||
|
if config.swarselsystems.isImpermanence then
|
||||||
|
"/persist/${dhParamsPathBase}"
|
||||||
|
else
|
||||||
|
"${dhParamsPathBase}";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.swarselmodules.server.nginx = lib.mkEnableOption "enable nginx on server";
|
options.swarselmodules.server.nginx = lib.mkEnableOption "enable nginx on server";
|
||||||
|
options.services.nginx = {
|
||||||
|
recommendedSecurityHeaders = lib.mkEnableOption "additional security headers by default in each location block.";
|
||||||
|
virtualHosts = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
options.locations = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule (submod: {
|
||||||
|
options = {
|
||||||
|
recommendedSecurityHeaders = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = config.services.nginx.recommendedSecurityHeaders;
|
||||||
|
description = "Whether to add additional security headers to this location.";
|
||||||
|
};
|
||||||
|
|
||||||
|
X-Frame-Options = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "DENY";
|
||||||
|
description = "The value to use for X-Frame-Options";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf submod.config.recommendedSecurityHeaders {
|
||||||
|
extraConfig = lib.mkBefore ''
|
||||||
|
# Enable HTTP Strict Transport Security (HSTS)
|
||||||
|
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
|
||||||
|
|
||||||
|
# Minimize information leaked to other domains
|
||||||
|
add_header Referrer-Policy "origin-when-cross-origin";
|
||||||
|
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
add_header X-Frame-Options "${submod.config.X-Frame-Options}";
|
||||||
|
add_header X-Content-Type-Options "nosniff";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
config = lib.mkIf config.swarselmodules.server.nginx {
|
config = lib.mkIf config.swarselmodules.server.nginx {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
lego
|
lego
|
||||||
|
|
@ -7064,23 +7115,67 @@ Here we just define some aliases for rebuilding the system, and we allow some in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
users.groups.acme.members = [ "nginx" ];
|
||||||
|
|
||||||
security.acme = {
|
security.acme = {
|
||||||
acceptTerms = true;
|
acceptTerms = true;
|
||||||
defaults = {
|
defaults = {
|
||||||
inherit dnsProvider;
|
inherit dnsProvider;
|
||||||
email = address3;
|
email = address3;
|
||||||
environmentFile = "${config.sops.templates."certs.secret".path}";
|
environmentFile = "${config.sops.templates."certs.secret".path}";
|
||||||
|
reloadServices = [ "nginx" ];
|
||||||
|
dnsPropagationCheck = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
|
||||||
|
environment.persistence."/persist" = lib.mkIf config.swarselsystems.isImpermanence {
|
||||||
|
files = [ dhParamsPathBase ];
|
||||||
|
};
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
user = serviceUser;
|
||||||
|
group = serviceGroup;
|
||||||
statusPage = true;
|
statusPage = true;
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
recommendedTlsSettings = true;
|
recommendedTlsSettings = true;
|
||||||
recommendedOptimisation = true;
|
recommendedOptimisation = true;
|
||||||
recommendedGzipSettings = true;
|
recommendedGzipSettings = true;
|
||||||
# virtualHosts are defined in the respective sections
|
recommendedBrotliSettings = true;
|
||||||
|
recommendedSecurityHeaders = true;
|
||||||
|
sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:!aNULL";
|
||||||
|
sslDhparam = dhParamsPathBase;
|
||||||
|
virtualHosts.fallback = {
|
||||||
|
default = true;
|
||||||
|
rejectSSL = true;
|
||||||
|
locations."/".extraConfig = ''
|
||||||
|
deny all;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
system.activationScripts."createPersistentStorageDirs" = lib.mkIf config.swarselsystems.isImpermanence {
|
||||||
|
deps = [ "generateDHParams" "users" "groups" ];
|
||||||
|
};
|
||||||
|
system.activationScripts."generateDHParams" =
|
||||||
|
{
|
||||||
|
text = ''
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
${pkgs.coreutils}/bin/install -d -m 0755 ${sslBasePath}
|
||||||
|
${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0755 /persist${sslBasePath}" else ""}
|
||||||
|
|
||||||
|
if [ ! -f "${dhParamsPathBase}" ]; then
|
||||||
|
${pkgs.openssl}/bin/openssl dhparam -out ${dhParamsPath} 4096
|
||||||
|
chmod 0644 ${dhParamsPath}
|
||||||
|
chown ${serviceUser}:${serviceGroup} ${dhParamsPath}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
deps = [
|
||||||
|
"etc"
|
||||||
|
(lib.mkIf config.swarselsystems.isImpermanence "specialfs")
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,60 @@ let
|
||||||
inherit (config.repo.secrets.common) dnsProvider;
|
inherit (config.repo.secrets.common) dnsProvider;
|
||||||
inherit (config.repo.secrets.common.mail) address3;
|
inherit (config.repo.secrets.common.mail) address3;
|
||||||
|
|
||||||
|
serviceUser = "nginx";
|
||||||
|
serviceGroup = serviceUser;
|
||||||
|
|
||||||
|
sslBasePath = "/etc/ssl";
|
||||||
|
dhParamsPathBase = "${sslBasePath}/dhparams.pem";
|
||||||
|
dhParamsPath =
|
||||||
|
if config.swarselsystems.isImpermanence then
|
||||||
|
"/persist/${dhParamsPathBase}"
|
||||||
|
else
|
||||||
|
"${dhParamsPathBase}";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.swarselmodules.server.nginx = lib.mkEnableOption "enable nginx on server";
|
options.swarselmodules.server.nginx = lib.mkEnableOption "enable nginx on server";
|
||||||
|
options.services.nginx = {
|
||||||
|
recommendedSecurityHeaders = lib.mkEnableOption "additional security headers by default in each location block.";
|
||||||
|
virtualHosts = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
options.locations = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule (submod: {
|
||||||
|
options = {
|
||||||
|
recommendedSecurityHeaders = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = config.services.nginx.recommendedSecurityHeaders;
|
||||||
|
description = "Whether to add additional security headers to this location.";
|
||||||
|
};
|
||||||
|
|
||||||
|
X-Frame-Options = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "DENY";
|
||||||
|
description = "The value to use for X-Frame-Options";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf submod.config.recommendedSecurityHeaders {
|
||||||
|
extraConfig = lib.mkBefore ''
|
||||||
|
# Enable HTTP Strict Transport Security (HSTS)
|
||||||
|
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
|
||||||
|
|
||||||
|
# Minimize information leaked to other domains
|
||||||
|
add_header Referrer-Policy "origin-when-cross-origin";
|
||||||
|
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
add_header X-Frame-Options "${submod.config.X-Frame-Options}";
|
||||||
|
add_header X-Content-Type-Options "nosniff";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
config = lib.mkIf config.swarselmodules.server.nginx {
|
config = lib.mkIf config.swarselmodules.server.nginx {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
lego
|
lego
|
||||||
|
|
@ -18,23 +69,67 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
users.groups.acme.members = [ "nginx" ];
|
||||||
|
|
||||||
security.acme = {
|
security.acme = {
|
||||||
acceptTerms = true;
|
acceptTerms = true;
|
||||||
defaults = {
|
defaults = {
|
||||||
inherit dnsProvider;
|
inherit dnsProvider;
|
||||||
email = address3;
|
email = address3;
|
||||||
environmentFile = "${config.sops.templates."certs.secret".path}";
|
environmentFile = "${config.sops.templates."certs.secret".path}";
|
||||||
|
reloadServices = [ "nginx" ];
|
||||||
|
dnsPropagationCheck = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
|
||||||
|
environment.persistence."/persist" = lib.mkIf config.swarselsystems.isImpermanence {
|
||||||
|
files = [ dhParamsPathBase ];
|
||||||
|
};
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
user = serviceUser;
|
||||||
|
group = serviceGroup;
|
||||||
statusPage = true;
|
statusPage = true;
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
recommendedTlsSettings = true;
|
recommendedTlsSettings = true;
|
||||||
recommendedOptimisation = true;
|
recommendedOptimisation = true;
|
||||||
recommendedGzipSettings = true;
|
recommendedGzipSettings = true;
|
||||||
# virtualHosts are defined in the respective sections
|
recommendedBrotliSettings = true;
|
||||||
|
recommendedSecurityHeaders = true;
|
||||||
|
sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:!aNULL";
|
||||||
|
sslDhparam = dhParamsPathBase;
|
||||||
|
virtualHosts.fallback = {
|
||||||
|
default = true;
|
||||||
|
rejectSSL = true;
|
||||||
|
locations."/".extraConfig = ''
|
||||||
|
deny all;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
system.activationScripts."createPersistentStorageDirs" = lib.mkIf config.swarselsystems.isImpermanence {
|
||||||
|
deps = [ "generateDHParams" "users" "groups" ];
|
||||||
|
};
|
||||||
|
system.activationScripts."generateDHParams" =
|
||||||
|
{
|
||||||
|
text = ''
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
${pkgs.coreutils}/bin/install -d -m 0755 ${sslBasePath}
|
||||||
|
${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0755 /persist${sslBasePath}" else ""}
|
||||||
|
|
||||||
|
if [ ! -f "${dhParamsPathBase}" ]; then
|
||||||
|
${pkgs.openssl}/bin/openssl dhparam -out ${dhParamsPath} 4096
|
||||||
|
chmod 0644 ${dhParamsPath}
|
||||||
|
chown ${serviceUser}:${serviceGroup} ${dhParamsPath}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
deps = [
|
||||||
|
"etc"
|
||||||
|
(lib.mkIf config.swarselsystems.isImpermanence "specialfs")
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue