diff --git a/hosts/malcolm/configuration.nix b/hosts/malcolm/configuration.nix index 7e345f3..3f88c55 100644 --- a/hosts/malcolm/configuration.nix +++ b/hosts/malcolm/configuration.nix @@ -6,6 +6,10 @@ ../../base.nix ../../common/metrics-exporters.nix + + ./services/mysql.nix + ./services/nginx.nix + ./services/www-kinealbrigtsen-no.nix ]; networking = { @@ -18,8 +22,26 @@ hostId = "620c42d0"; defaultGateway = "192.168.11.1"; + + # Prepend the following output rules to disallow talking to other devices on LAN + firewall.extraCommands = lib.strings.concatLines ([ + "iptables -F OUTPUT" + ] ++ (map (addr: "iptables -A OUTPUT -p udp --dport 53 -d ${addr} -j nixos-fw-accept") config.networking.nameservers) ++ [ # Exception for DNS + "iptables -A OUTPUT -p tcp --dport 3100 -d 192.168.10.175 -j nixos-fw-accept" # Exception for loki logging + "iptables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT" + "iptables -A OUTPUT -d 192.168.10.0/24 -j nixos-fw-refuse" + "iptables -A OUTPUT -d 192.168.11.0/24 -j nixos-fw-refuse" + ]); }; + # virtualisation.oci-containers.backend = "docker"; + # systemd.services.docker.postStart = lib.concatMapStringsSep "\n" (rule: "${pkgs.iptables}/bin/iptables ${rule}") ([ + # "-F DOCKER-USER" + # ] ++ (map (addr: "-A DOCKER-USER -p udp --dport 53 -d ${addr} -j RETURN") config.networking.nameservers) ++ [ + # "-A DOCKER-USER -d 192.168.10.0/24 -j REJECT" + # "-A DOCKER-USER -d 192.168.11.0/24 -j REJECT" + # "-A DOCKER-USER -j RETURN" + # ]); - system.stateVersion = "24.05"; # Did you read the comment? + system.stateVersion = "24.05"; } diff --git a/hosts/malcolm/services/mysql.nix b/hosts/malcolm/services/mysql.nix new file mode 100644 index 0000000..128f2d6 --- /dev/null +++ b/hosts/malcolm/services/mysql.nix @@ -0,0 +1,10 @@ +{ config, pkgs, lib, ... }: + +{ + services.mysql = { + enable = true; + package = pkgs.mariadb; + }; + + # TODO: services.mysqlBackup +} diff --git a/hosts/malcolm/services/nginx.nix b/hosts/malcolm/services/nginx.nix new file mode 100644 index 0000000..b32ba6d --- /dev/null +++ b/hosts/malcolm/services/nginx.nix @@ -0,0 +1,15 @@ +{ config, values, ... }: +{ + services.nginx = { + enable = true; + + clientMaxBodySize = "100m"; + + recommendedProxySettings = true; + recommendedTlsSettings = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + }; + + networking.firewall.allowedTCPPorts = [ 80 443 ]; +} diff --git a/hosts/malcolm/services/www-kinealbrigtsen-no.nix b/hosts/malcolm/services/www-kinealbrigtsen-no.nix new file mode 100644 index 0000000..43d73a6 --- /dev/null +++ b/hosts/malcolm/services/www-kinealbrigtsen-no.nix @@ -0,0 +1,96 @@ +{ config, pkgs, lib, ... }: + +{ + users.users.www-kinealbrigtsen-no = { + isSystemUser = true; + group = "www-kinealbrigtsen-no"; + }; + + users.groups.www-kinealbrigtsen-no = { }; + + services.mysql.ensureDatabases = [ + "www_kinealbrigtsen_no" + ]; + services.mysql.ensureUsers = [ + { + name = "www-kinealbrigtsen-no"; + ensurePermissions = { + # "www_kinealbrigtsen_no.*" = "ALL PRIVILEGES"; # For upgrades and special procedures + "www_kinealbrigtsen_no.*" = "SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX"; + }; + } + ]; + + services.phpfpm.pools.www-kinealbrigtsen-no = { + user = "www-kinealbrigtsen-no"; + group = "www-kinealbrigtsen-no"; + phpOptions = lib.generators.toKeyValue {} { + upload_max_filesize = "1000M"; + post_max_size = "1000M"; + memory_limit = "1000M"; + }; + + settings = { + "listen.owner" = config.services.nginx.user; + "listen.group" = config.services.nginx.group; + "pm" = "dynamic"; + "pm.max_children" = 32; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 2; + "pm.max_spare_servers" = 4; + "pm.process_idle_timeout" = "10s"; + "pm.max_requests" = 1000; + }; + }; + + services.nginx.virtualHosts."kinealbrigtsen.no" = { + serverAliases = [ "www.kinealbrigtsen.no" ]; + root = "/var/www/www-kinealbrigtsen-no"; + locations = { + "/".extraConfig = '' + try_files $uri $uri/ /index.php?$args; + ''; + + "~ \\.php$".extraConfig = '' + include ${config.services.nginx.package}/conf/fastcgi_params; + + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass unix:${config.services.phpfpm.pools.www-kinealbrigtsen-no.socket}; + ''; + + "~ /\\.ht".extraConfig = '' + deny all; + ''; + + "/favicon.ico".extraConfig = '' + log_not_found off; + access_log off; + ''; + + "/robots.txt".extraConfig = '' + allow all; + log_not_found off; + access_log off; + ''; + + "~* \\.(js|css|png|jpg|jpeg|gif|ico)$".extraConfig = '' + expires max; + log_not_found off; + ''; + }; + extraConfig = '' + index index.php index.html; + set_real_ip_from 192.168.11.0/24; + real_ip_header X-Forwarded-For; + + add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always; + add_header 'Referrer-Policy' 'origin-when-cross-origin'; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + ''; + }; + + # TODO: + # - Configure a mailer so wp_mail() works + # - Enable periodic backups +}