From fc14a394aa0c5ea924051de9f4db2cb409f32eb8 Mon Sep 17 00:00:00 2001 From: muon Date: Fri, 26 Dec 2025 10:48:31 +0000 Subject: [PATCH] Add embedded syntax hl --- README.md | 2 +- modules/home/desktop/development.nix | 102 ++++++------- modules/nixos/impermanence.nix | 56 ++++---- modules/nixos/server/grav/service.nix | 197 ++++++++++++++------------ modules/nixos/server/nginx.nix | 177 ++++++++++++----------- 5 files changed, 284 insertions(+), 250 deletions(-) diff --git a/README.md b/README.md index 10eb0b5..66c51b3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ sudo cp {/mnt,/mnt/persist}/etc/machine-id ## Erasure ```nix - boot.initrd.postResumeCommands = lib.mkAfter '' + boot.initrd.postResumeCommands = lib.mkAfter /* bash */ '' mkdir /btrfs_tmp mount /dev/mapper/crypted /btrfs_tmp if [[ -e /btrfs_tmp/root ]]; then diff --git a/modules/home/desktop/development.nix b/modules/home/desktop/development.nix index f3d4373..3abbb3c 100644 --- a/modules/home/desktop/development.nix +++ b/modules/home/desktop/development.nix @@ -12,46 +12,48 @@ programs.nyxt = { enable = false; - config = '' - (in-package #:nyxt-user) + config = + # lisp + '' + (in-package #:nyxt-user) - (defvar *my-search-engines* - (list - (make-instance 'search-engine - :name "Searx" - :shortcut "s" - #+nyxt-4 :control-url #+nyxt-3 :search-url - ""https://search.muon.host/?q=~a";") + (defvar *my-search-engines* + (list + (make-instance 'search-engine + :name "Searx" + :shortcut "s" + #+nyxt-4 :control-url #+nyxt-3 :search-url + ""https://search.muon.host/?q=~a";") - (make-instance 'search-engine - :name "nixpkgs" - :shortcut "np" - #+nyxt-4 :control-url #+nyxt-3 :search-url - "https://search.nixos.org/packages?channel=unstable&query=~a"))) + (make-instance 'search-engine + :name "nixpkgs" + :shortcut "np" + #+nyxt-4 :control-url #+nyxt-3 :search-url + "https://search.nixos.org/packages?channel=unstable&query=~a"))) - (make-instance 'search-engine - :name "nix options" - :shortcut "np" - #+nyxt-4 :control-url #+nyxt-3 :search-url - "https://search.nixos.org/options?channel=unstable&query=~a"))) + (make-instance 'search-engine + :name "nix options" + :shortcut "np" + #+nyxt-4 :control-url #+nyxt-3 :search-url + "https://search.nixos.org/options?channel=unstable&query=~a"))) - (make-instance 'search-engine - :name "home-manager" - :shortcut "hm" - #+nyxt-4 :control-url #+nyxt-3 :search-url - "https://home-manager-options.extranix.com/?release=master&query=~a"))) + (make-instance 'search-engine + :name "home-manager" + :shortcut "hm" + #+nyxt-4 :control-url #+nyxt-3 :search-url + "https://home-manager-options.extranix.com/?release=master&query=~a"))) - (define-configuration browser - ((restore-session-on-startup-p nil) - (default-new-buffer-url (quri:uri "https://online.bonjourr.fr/")) - (external-editor-program ("alacritty -e hx") - #+nyxt-4 - (search-engine-suggestions-p nil) - #+nyxt-4 - (search-engines (append %slot-default% *my-search-engines*)) - )) - ''; + (define-configuration browser + ((restore-session-on-startup-p nil) + (default-new-buffer-url (quri:uri "https://online.bonjourr.fr/")) + (external-editor-program ("alacritty -e hx") + #+nyxt-4 + (search-engine-suggestions-p nil) + #+nyxt-4 + (search-engines (append %slot-default% *my-search-engines*)) + )) + ''; }; programs.qutebrowser = { @@ -73,23 +75,25 @@ hm = "https://home-manager-options.extranix.com/?release=master&query={}"; }; - extraConfig = '' - host = c.content.blocking.hosts.lists.append - host("https://www.github.developerdan.com/hosts/lists/facebook-extended.txt") + extraConfig = + # py + '' + host = c.content.blocking.hosts.lists.append + host("https://www.github.developerdan.com/hosts/lists/facebook-extended.txt") - abp = c.content.blocking.adblock.lists.append - abp("https://fanboy.co.nz/r/fanboy-ultimate.txt") - abp("https://fanboy.co.nz/fanboy-antifacebook.txt") - abp("https://fanboy.co.nz/fanboy-annoyance.txt") - abp("https://fanboy.co.nz/fanboy-cookiemonster.txt") - abp("https://easylist-downloads.adblockplus.org/antiadblockfilters.txt") - abp("https://easylist-downloads.adblockplus.org/abp-filters-anti-cv.txt") + abp = c.content.blocking.adblock.lists.append + abp("https://fanboy.co.nz/r/fanboy-ultimate.txt") + abp("https://fanboy.co.nz/fanboy-antifacebook.txt") + abp("https://fanboy.co.nz/fanboy-annoyance.txt") + abp("https://fanboy.co.nz/fanboy-cookiemonster.txt") + abp("https://easylist-downloads.adblockplus.org/antiadblockfilters.txt") + abp("https://easylist-downloads.adblockplus.org/abp-filters-anti-cv.txt") - abp("https://github.com/DandelionSprout/adfilt/raw/master/LegitimateURLShortener.txt") - abp("https://github.com/DandelionSprout/adfilt/raw/master/AnnoyancesList") - abp("https://github.com/DandelionSprout/adfilt/raw/master/SocialShareList.txt") - abp("https://github.com/DandelionSprout/adfilt/raw/master/ExtremelyCondensedList.txt") - ''; + abp("https://github.com/DandelionSprout/adfilt/raw/master/LegitimateURLShortener.txt") + abp("https://github.com/DandelionSprout/adfilt/raw/master/AnnoyancesList") + abp("https://github.com/DandelionSprout/adfilt/raw/master/SocialShareList.txt") + abp("https://github.com/DandelionSprout/adfilt/raw/master/ExtremelyCondensedList.txt") + ''; }; }; } diff --git a/modules/nixos/impermanence.nix b/modules/nixos/impermanence.nix index 8ce89a0..2b65dc8 100644 --- a/modules/nixos/impermanence.nix +++ b/modules/nixos/impermanence.nix @@ -1,36 +1,44 @@ -{ pkgs, lib, config, ... }: +{ + pkgs, + lib, + config, + ... +}: with lib; { options.mods.impermanence.enable = mkEnableOption "enables impermanence"; config = mkIf config.mods.impermanence.enable { environment.persistence."/persist" = { - directories = [ "/var/lib/nixos" "/var/lib/systemd/coredump" ]; - files = [ "/var/lib/sops-nix/key.txt" "/etc/machine-id" ]; + directories = ["/var/lib/nixos" "/var/lib/systemd/coredump"]; + files = ["/var/lib/sops-nix/key.txt" "/etc/machine-id"]; }; - boot.initrd.postResumeCommands = lib.mkAfter '' - mkdir /btrfs_tmp - mount /dev/mapper/crypted /btrfs_tmp - if [[ -e /btrfs_tmp/root ]]; then - mkdir -p /btrfs_tmp/old_roots - timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S") - mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp" - fi + boot.initrd.postResumeCommands = + lib.mkAfter # sh + + '' + mkdir /btrfs_tmp + mount /dev/mapper/crypted /btrfs_tmp + if [[ -e /btrfs_tmp/root ]]; then + mkdir -p /btrfs_tmp/old_roots + timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S") + mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp" + fi - delete_subvolume_recursively() { - IFS=$'\n' - for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do - delete_subvolume_recursively "/btrfs_tmp/$i" - done - btrfs subvolume delete "$1" - } + delete_subvolume_recursively() { + IFS=$'\n' + for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "/btrfs_tmp/$i" + done + btrfs subvolume delete "$1" + } - for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do - delete_subvolume_recursively "$i" - done + for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do + delete_subvolume_recursively "$i" + done - btrfs subvolume create /btrfs_tmp/root - umount /btrfs_tmp - ''; + btrfs subvolume create /btrfs_tmp/root + umount /btrfs_tmp + ''; }; } diff --git a/modules/nixos/server/grav/service.nix b/modules/nixos/server/grav/service.nix index c9b90f5..db735e9 100644 --- a/modules/nixos/server/grav/service.nix +++ b/modules/nixos/server/grav/service.nix @@ -1,10 +1,20 @@ -{ config, lib, pkgs, ... }: - -let - - inherit (lib) - generators mapAttrs mkDefault mkEnableOption mkIf mkPackageOption mkOption - types; +{ + config, + lib, + pkgs, + ... +}: let + inherit + (lib) + generators + mapAttrs + mkDefault + mkEnableOption + mkIf + mkPackageOption + mkOption + types + ; cfg = config.mods.services.grav; @@ -12,9 +22,9 @@ let poolName = "grav"; - pkgs_grav = pkgs.callPackage ./package.nix { }; + pkgs_grav = pkgs.callPackage ./package.nix {}; - servedRoot = pkgs.runCommand "grav-served-root" { } '' + servedRoot = pkgs.runCommand "grav-served-root" {} '' cp --reflink=auto --no-preserve=mode -r ${pkgs_grav} $out for p in assets images user system/config; do @@ -22,10 +32,8 @@ let ln -sf /var/lib/grav/$p $out/$p done ''; - # systemSettingsYaml = # yamlFormat.generate "grav-settings.yaml" cfg.systemSettings; - in { options.mods.services.grav = { enable = mkEnableOption "grav"; @@ -70,7 +78,7 @@ in { default = 3000; }; - phpPackage = mkPackageOption pkgs "php" { }; + phpPackage = mkPackageOption pkgs "php" {}; maxUploadSize = mkOption { type = types.str; @@ -97,7 +105,10 @@ in { group = "grav"; phpPackage = cfg.phpPackage.buildEnv { - extensions = { all, enabled }: + extensions = { + all, + enabled, + }: with all; [ apcu ctype @@ -115,27 +126,28 @@ in { zip ]; - extraConfig = generators.toKeyValue { - mkKeyValue = generators.mkKeyValueDefault { } " = "; - } { - output_buffering = "0"; - short_open_tag = "Off"; - expose_php = "Off"; - error_reporting = "E_ALL"; - display_errors = "stderr"; - "opcache.interned_strings_buffer" = "8"; - "opcache.max_accelerated_files" = "10000"; - "opcache.memory_consumption" = "128"; - "opcache.revalidate_freq" = "1"; - "opcache.fast_shutdown" = "1"; - "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; - catch_workers_output = "yes"; + extraConfig = + generators.toKeyValue { + mkKeyValue = generators.mkKeyValueDefault {} " = "; + } { + output_buffering = "0"; + short_open_tag = "Off"; + expose_php = "Off"; + error_reporting = "E_ALL"; + display_errors = "stderr"; + "opcache.interned_strings_buffer" = "8"; + "opcache.max_accelerated_files" = "10000"; + "opcache.memory_consumption" = "128"; + "opcache.revalidate_freq" = "1"; + "opcache.fast_shutdown" = "1"; + "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; + catch_workers_output = "yes"; - upload_max_filesize = cfg.maxUploadSize; - post_max_size = cfg.maxUploadSize; - memory_limit = cfg.maxUploadSize; - "apc.enable_cli" = "1"; - }; + upload_max_filesize = cfg.maxUploadSize; + post_max_size = cfg.maxUploadSize; + memory_limit = cfg.maxUploadSize; + "apc.enable_cli" = "1"; + }; }; phpEnv = { @@ -169,10 +181,12 @@ in { ${cfg.virtualHost} = { root = "${servedRoot}"; - listen = [{ - addr = cfg.addr; - port = cfg.port; - }]; + listen = [ + { + addr = cfg.addr; + port = cfg.port; + } + ]; locations = { "= /robots.txt" = { @@ -202,31 +216,28 @@ in { }; # deny running scripts inside core system folders - "~* /(system|vendor)/.*\\.(txt|xml|md|html|htm|shtml|shtm|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$" = - { - priority = 300; - extraConfig = '' - return 403; - ''; - }; + "~* /(system|vendor)/.*\\.(txt|xml|md|html|htm|shtml|shtm|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$" = { + priority = 300; + extraConfig = '' + return 403; + ''; + }; # deny running scripts inside user folder - "~* /user/.*\\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$" = - { - priority = 300; - extraConfig = '' - return 403; - ''; - }; + "~* /user/.*\\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$" = { + priority = 300; + extraConfig = '' + return 403; + ''; + }; # deny access to specific files in the root folder - "~ /(LICENSE\\.txt|composer\\.lock|composer\\.json|nginx\\.conf|web\\.config|htaccess\\.txt|\\.htaccess)" = - { - priority = 300; - extraConfig = '' - return 403; - ''; - }; + "~ /(LICENSE\\.txt|composer\\.lock|composer\\.json|nginx\\.conf|web\\.config|htaccess\\.txt|\\.htaccess)" = { + priority = 300; + extraConfig = '' + return 403; + ''; + }; # deny all files and folder beginning with a dot (hidden files & folders) "~ (^|/)\\." = { @@ -245,41 +256,45 @@ in { }; }; - extraConfig = '' - index index.php index.html /index.php$request_uri; - add_header X-Content-Type-Options nosniff; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Robots-Tag "noindex, nofollow"; - add_header X-Download-Options noopen; - add_header X-Permitted-Cross-Domain-Policies none; - add_header X-Frame-Options sameorigin; - add_header Referrer-Policy no-referrer; - client_max_body_size ${cfg.maxUploadSize}; - fastcgi_buffers 64 4K; - fastcgi_hide_header X-Powered-By; - gzip on; - gzip_vary on; - gzip_comp_level 4; - gzip_min_length 256; - gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; - gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; - ''; + extraConfig = + # sh + '' + index index.php index.html /index.php$request_uri; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag "noindex, nofollow"; + add_header X-Download-Options noopen; + add_header X-Permitted-Cross-Domain-Policies none; + add_header X-Frame-Options sameorigin; + add_header Referrer-Policy no-referrer; + client_max_body_size ${cfg.maxUploadSize}; + fastcgi_buffers 64 4K; + fastcgi_hide_header X-Powered-By; + gzip on; + gzip_vary on; + gzip_comp_level 4; + gzip_min_length 256; + gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; + gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; + ''; }; }; }; - systemd.tmpfiles.rules = let datadir = "/var/lib/grav"; - in map (dir: "d '${dir}' 0750 grav grav - -") [ - "/var/cache/grav" - "${datadir}/assets" - "${datadir}/backup" - "${datadir}/images" - "${datadir}/system/config" - "${datadir}/user/accounts" - "${datadir}/user/config" - "${datadir}/user/data" - "/var/log/grav" - ]; + systemd.tmpfiles.rules = let + datadir = "/var/lib/grav"; + in + map (dir: "d '${dir}' 0750 grav grav - -") [ + "/var/cache/grav" + "${datadir}/assets" + "${datadir}/backup" + "${datadir}/images" + "${datadir}/system/config" + "${datadir}/user/accounts" + "${datadir}/user/config" + "${datadir}/user/data" + "/var/log/grav" + ]; # ++ [ # "L+ ${datadir}/user/config/system.yaml - - - - ${systemSettingsYaml}" # ]; @@ -287,7 +302,7 @@ in { systemd.services = { "phpfpm-${poolName}" = mkIf (cfg.pool == "${poolName}") { # restartTriggers = [ servedRoot systemSettingsYaml ]; - restartTriggers = [ servedRoot ]; + restartTriggers = [servedRoot]; serviceConfig = { ExecStartPre = pkgs.writeShellScript "grav-pre-start" '' @@ -329,6 +344,6 @@ in { group = "grav"; }; - users.groups.grav = { members = [ config.services.nginx.user ]; }; + users.groups.grav = {members = [config.services.nginx.user];}; }; } diff --git a/modules/nixos/server/nginx.nix b/modules/nixos/server/nginx.nix index 7322c39..fafb4df 100644 --- a/modules/nixos/server/nginx.nix +++ b/modules/nixos/server/nginx.nix @@ -1,105 +1,112 @@ -{ pkgs, lib, config, ... }: -let - +{ + pkgs, + lib, + config, + ... +}: let cfg = config.mods.server.nginx; +in + with lib; { + options.mods.server.nginx = { + enable = mkEnableOption { + default = false; + description = "enables nginx reverse proxy"; + }; -in with lib; { - options.mods.server.nginx = { - enable = mkEnableOption { - default = false; - description = "enables nginx reverse proxy"; + ip = mkOption { + type = types.str; + default = "10.0.0.3"; + }; + + domain = mkOption { + type = types.str; + default = "muon.host"; + }; + + ports = mkOption { + type = types.attrsOf (types.ints.u16); + default = {}; + }; }; - ip = mkOption { - type = types.str; - default = "10.0.0.3"; - }; + config = mkIf cfg.enable { + # ACME won't be able to authenticate your domain + # if ports 80 & 443 aren't open in your firewall. + networking.firewall = {allowedTCPPorts = [443 80];}; + security.acme.defaults.email = "acme@muon.host"; + security.acme.acceptTerms = true; - domain = mkOption { - type = types.str; - default = "muon.host"; - }; + services.nginx = { + enable = true; - ports = mkOption { - type = types.attrsOf (types.ints.u16); - default = { }; - }; - }; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; - config = mkIf cfg.enable { - # ACME won't be able to authenticate your domain - # if ports 80 & 443 aren't open in your firewall. - networking.firewall = { allowedTCPPorts = [ 443 80 ]; }; - security.acme.defaults.email = "acme@muon.host"; - security.acme.acceptTerms = true; + # Only allow PFS-enabled ciphers with AES256 + # sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; - services.nginx = { - enable = true; + appendHttpConfig = + # sh + '' + # Add HSTS header with preloading to HTTPS requests. + # Adding this header to HTTP requests is discouraged + # map $scheme $hsts_header { + # https "max-age=31536000; includeSubdomains; preload"; + # } + # add_header Strict-Transport-Security $hsts_header; - recommendedGzipSettings = true; - recommendedOptimisation = true; - recommendedProxySettings = true; - recommendedTlsSettings = true; + # Enable CSP for your services. + # add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always; - # Only allow PFS-enabled ciphers with AES256 - # sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; + # Minimize information leaked to other domains + # add_header 'Referrer-Policy' 'origin-when-cross-origin'; - appendHttpConfig = '' - # Add HSTS header with preloading to HTTPS requests. - # Adding this header to HTTP requests is discouraged - # map $scheme $hsts_header { - # https "max-age=31536000; includeSubdomains; preload"; - # } - # add_header Strict-Transport-Security $hsts_header; + # Disable embedding as a frame + add_header X-Frame-Options DENY; - # Enable CSP for your services. - # add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always; + # Prevent injection of code in other mime types (XSS Attacks) + # add_header X-Content-Type-Options nosniff; - # Minimize information leaked to other domains - # add_header 'Referrer-Policy' 'origin-when-cross-origin'; + # This might create errors + # proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; - # Disable embedding as a frame - add_header X-Frame-Options DENY; + # required when the server wants to use HTTP Authentication + proxy_pass_header Authorization; - # Prevent injection of code in other mime types (XSS Attacks) - # add_header X-Content-Type-Options nosniff; + # This is necessary to pass the correct IP to be hashed + real_ip_header X-Real-IP; - # This might create errors - # proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; + # security + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always; + add_header Permissions-Policy "interest-cohort=()" always; + # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + ''; - # required when the server wants to use HTTP Authentication - proxy_pass_header Authorization; + virtualHosts = let + base = locations: { + inherit locations; - # This is necessary to pass the correct IP to be hashed - real_ip_header X-Real-IP; - - # security - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "no-referrer-when-downgrade" always; - add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always; - add_header Permissions-Policy "interest-cohort=()" always; - # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; - ''; - - virtualHosts = let - base = locations: { - inherit locations; - - forceSSL = true; - enableACME = true; - }; - proxy = port: - base { - "/" = { - proxyPass = "http://${cfg.ip}:${toString port}/"; - proxyWebsockets = true; - }; + forceSSL = true; + enableACME = true; }; - in mapAttrs' (name: port: - nameValuePair ("${name}.${cfg.domain}") - # (proxy port // { default = true; })) cfg.ports; - (proxy port)) cfg.ports; + proxy = port: + base { + "/" = { + proxyPass = "http://${cfg.ip}:${toString port}/"; + proxyWebsockets = true; + }; + }; + in + mapAttrs' (name: port: + nameValuePair "${name}.${cfg.domain}" + # (proxy port // { default = true; })) cfg.ports; + (proxy port)) + cfg.ports; + }; }; - }; -} + }