diff --git a/common.nix b/common.nix index 719bd99..93aed80 100644 --- a/common.nix +++ b/common.nix @@ -46,5 +46,18 @@ binutils neovim home-manager + ripgrep ]; + + fileSystems."/tmp" = { + device = "tmpfs"; + fsType = "tmpfs"; + options = ["size=5G"]; + }; + + fileSystems."/var/cache" = { + device = "tmpfs"; + fsType = "tmpfs"; + options = ["size=3G"]; + }; } diff --git a/hosts/giupi/backup.nix b/hosts/giupi/backup.nix new file mode 100644 index 0000000..93b9764 --- /dev/null +++ b/hosts/giupi/backup.nix @@ -0,0 +1,26 @@ +{config, lib, ...} : + +{ + services.restic.backups = { + local = { + initialize = true; + passwordFile = "/etc/restic/local.key"; + repository = "/backup"; + paths = [ "/" ]; + extraBackupArgs = [ + "-x" # same filesystem + "-e /nix" + ]; + pruneOpts = [ + "--keep-daily 45" + "--keep-weekly 12" + "--keep-monthly 12" + "--keep-yearly 3" + ]; + timerConfig = { + OnCalendar = "00:05"; + RandomizedDelaySec = "5h"; + }; + }; + }; +} diff --git a/hosts/giupi/default.nix b/hosts/giupi/default.nix index 794c580..40ae258 100644 --- a/hosts/giupi/default.nix +++ b/hosts/giupi/default.nix @@ -5,165 +5,240 @@ { config, pkgs, variables, ... }: with import ./network.nix; -let +let + unstable = import {}; pubkeys = ["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1we38/N+t8Ah5yrLof8QUwhrob7/VXFKIddaJeOVBLuDVnW7ljiAtdtEiL69D/DV4Ohmt5wMvkAAjfuHmim6FD9A6lzPbSU4KH9W2dcckszKbbI636kuDwem/xui6BW3wJa6P+0xW5ksygEAkzcK2PXuC2b4B9uwhuUdKahiGMKDxISG/WianqAe72cGMfNkYvion3Y1VsMLUdm48d2ABnxNpr7NI9B5iJ8dziOft9gpgfz13CCQRlReo75gk/4xI+vSNrQp7eR+wzJy2/dZg/T8jtyA9Q6jVxrxBpqQ1LNXkAKaJkGo9OabF6Wgpzp+YTAurL4nwR2NaJxwFuyoKvACQy0ai4jrS3206gC6JXZv8ktZMZrwUN+jPqCwfgh5qObFkAqKCxbp52ioDek2MQLdOvzQBX//DBhGEp5rzHGLZ3vhRIiiQiaof5sF5zWiYDW5mqezSPNxJPX/BrTP/Wbs/jpwTLBh3wytiia0S1WXQmya89bqzTPFiDWvTRA62EVKB/JaQtPQQOFAxWwg799DMycPeZ81xttZOyMtI/MZSddyqx2S8fWGwvToZQvuZ38mSIpFseLM1IkgabRIrAmat5SBNGGy9Dqa0eMEa7bwIY/4CMB1y6HMTnaoMXA6cnQfHMoB/zyTZ6oTXIeqeOyiZsK+RN0Mvahj8mXi7dw== giulio@giulio-X230"]; hostname = "giupi"; -in { - imports = - [ # Include the results of the hardware scan. - ./hardware.nix - ../../variables.nix - ../../common.nix - ../../users.nix - ./firewall.nix - ]; +in + { + imports = + [ # Include the results of the hardware scan. + ./hardware.nix + ../../variables.nix + ../../common.nix + ../../users.nix + ./firewall.nix + ]; - variables.hostname = hostname; - time.timeZone = "Europe/Rome"; - system.stateVersion = "21.05"; # Did you read the comment? - users.users.giulio.openssh.authorizedKeys.keys = pubkeys; + variables.hostname = hostname; + time.timeZone = "Europe/Rome"; + system.stateVersion = "21.05"; # Did you read the comment? + users.users.giulio.openssh.authorizedKeys.keys = pubkeys; - boot = { - kernelParams = ["ip=${giupi_lan_ip}::10.0.0.1:255.255.255.0::${wan_if}:off"]; + boot = { + kernelParams = ["ip=${giupi_lan_ip}::10.0.0.1:255.255.255.0::${wan_if}:off"]; - initrd = { - availableKernelModules = ["igc" "r8169"]; - network = { - enable = true; - ssh = { - enable = true; - port = 22; - hostKeys = [/boot/ssh_host_rsa_key]; - authorizedKeys = pubkeys; + initrd = { + availableKernelModules = ["igc" "r8169"]; + network = { + enable = true; + ssh = { + enable = true; + port = 22; + hostKeys = [/boot/ssh_host_rsa_key]; + authorizedKeys = pubkeys; + }; + + postCommands = '' + zpool import backedpool + zpool import zpool + + mkdir /mnt-root + echo "zfs load-key -ar; mount -t zfs zpool/nixos/root /mnt-root; zfs load-key -a; umount /mnt-root; rmdir /mnt-root; killall zfs" >> /root/.profile + ''; }; - - postCommands = '' - echo "zfs load-key -a; killall zfs" >> /root/.profile - ''; }; + + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + supportedFilesystems = ["zfs"]; + zfs.requestEncryptionCredentials = true; }; - loader = { - systemd-boot.enable = true; - efi.canTouchEfiVariables = true; - }; + networking = { + hostName = hostname; + hostId = "49350853"; + useDHCP = false; + defaultGateway = "10.0.0.1"; + interfaces = { + enp5s0.ipv4.addresses = [{ address = giupi_lan_ip; prefixLength = 24; }]; + enp6s0.useDHCP = false; + wlp4s0.useDHCP = false; + }; + extraHosts = '' + 127.0.0.1 ${hostname}.devs.giugl.io jf.giugl.io yt.giugl.io s3.giugl.io synclounge.giugl.io giugl.io htson.giugl.io htrad.giugl.io htnzb.giugl.io httra.giugl.io giupyter.giugl.io irc.giugl.io localhost - supportedFilesystems = ["zfs"]; - zfs.requestEncryptionCredentials = true; - }; +# LAN +${giupi_lan_ip} ${hostname}.devs.giugl.io giugl.io jf.giugl.io yt.giugl.io s3.giugl.io synclounge.giugl.io htson.giugl.io htrad.giugl.io htnzb.giugl.io httra.giugl.io todo.giugl.io giupyter.giugl.io collabora.giugl.io htjak.giugl.io irc.giugl.io + 10.0.0.1 router.devs.giugl.io + ${dvr_ip} dvr.devs.giugl.io + ${nas_ip} nas.devs.giugl.io - networking = { - hostName = hostname; - hostId = "49350853"; - useDHCP = false; - defaultGateway = "10.0.0.1"; - interfaces = { - enp5s0.ipv4.addresses = [{ address = giupi_lan_ip; prefixLength = 24; }]; - enp6s0.useDHCP = false; - wlp4s0.useDHCP = false; - }; -# extraHosts = '' -# 127.0.0.1 ${hostname}.devs.giugl.io jf.giugl.io yt.giugl.io s3.giugl.io synclounge.giugl.io giugl.io htson.giugl.io htrad.giugl.io htnzb.giugl.io httra.giugl.io giupyter.giugl.io irc.giugl.io localhost -# -## LAN -#${giupi_lan_ip} ${hostname}.devs.giugl.io giugl.io jf.giugl.io yt.giugl.io s3.giugl.io synclounge.giugl.io htson.giugl.io htrad.giugl.io htnzb.giugl.io httra.giugl.io todo.giugl.io giupyter.giugl.io collabora.giugl.io htjak.giugl.io irc.giugl.io -# -# 10.0.0.1 router.devs.giugl.io -# ${dvr_ip} dvr.devs.giugl.io -# ${nas_ip} nas.devs.giugl.io -# -## Wireguard hosts -# ${giupi_wg_ip} ${hostname}.devs.giugl.io jf.giugl.io giugl.io yt.giugl.io s3.giugl.io synclounge.giugl.io htson.giugl.io htrad.giugl.io htnzb.giugl.io httra.giugl.io todo.giugl.io giupyter.giugl.io collabora.giugl.io htjak.giugl.io irc.giugl.io -# ${galuminum-wg} galuminum.devs.giugl.io -# ${oneplus-wg} oneplus.devs.giugl.io -# ${ipad-wg} ipad.devs.giugl.io -# ${manduria-wg} manduria.devs.giugl.io -# ${antonio-wg} antonio.devs.giugl.io -# ${gbeast-wg} gbeast.devs.giugl.io -# ${parisaphone-wg} parisa-phone.devs.giugl.io -# ${parisapc-wg} parisa-pc.devs.giugl.io -# ${peppiniell-wg} peppiniell.devs.giugl.io -# ${padulino-wg} padulino.devs.giugl.io -# ${shield-wg} shield.devs.giugl.io -# ${angelino-wg} angelino.devs.giugl.io -# ${pepos_one-wg} peposone.devs.giugl.io -# ${pepos_two-wg} pepostwo.devs.giugl.io -# ${eleonora-wg} eleonora.devs.giugl.io -# ${broccolino-wg} broccolino.devs.giugl.io -# ${hotpottino-wg} hotpottino.devs.giugl.io -# -## Blacklist -# 0.0.0.0 metrics.plex.tv -# 0.0.0.0 analytics.plex.tv -# 0.0.0.0 cdn.luckyorange.com -# 0.0.0.0 w1.luckyorange.com -# 0.0.0.0 browser.sentry-cdn.com -# 0.0.0.0 analytics.facebook.com -# 0.0.0.0 ads.facebook.com -# 0.0.0.0 extmaps-api.yandex.net -# 0.0.0.0 logservice.hicloud.com -# 0.0.0.0 logbak.hicloud.com -# 0.0.0.0 logservice1.hicloud.com -# 0.0.0.0 samsung-com.112.2o7.net -# 0.0.0.0 supportmetrics.apple.com -# 0.0.0.0 analytics.oneplus.cn -# 0.0.0.0 click.oneplus.cn -# 0.0.0.0 analytics-api.samsunghealthcn.com -# -## The following lines are desirable for IPv6 capable hosts -# ::1 localhost ip6-localhost ip6-loopback -# ff02::1 ip6-allnodes -# ff02::2 ip6-allrouters -# ''; - }; +# Wireguard hosts + ${giupi_wg_ip} ${hostname}.devs.giugl.io jf.giugl.io giugl.io yt.giugl.io s3.giugl.io synclounge.giugl.io htson.giugl.io htrad.giugl.io htnzb.giugl.io httra.giugl.io todo.giugl.io giupyter.giugl.io collabora.giugl.io htjak.giugl.io irc.giugl.io + ${galuminum-wg} galuminum.devs.giugl.io + ${oneplus-wg} oneplus.devs.giugl.io + ${ipad-wg} ipad.devs.giugl.io + ${manduria-wg} manduria.devs.giugl.io + ${antonio-wg} antonio.devs.giugl.io + ${gbeast-wg} gbeast.devs.giugl.io + ${parisaphone-wg} parisa-phone.devs.giugl.io + ${parisapc-wg} parisa-pc.devs.giugl.io + ${peppiniell-wg} peppiniell.devs.giugl.io + ${padulino-wg} padulino.devs.giugl.io + ${shield-wg} shield.devs.giugl.io + ${angelino-wg} angelino.devs.giugl.io + ${pepos_one-wg} peposone.devs.giugl.io + ${pepos_two-wg} pepostwo.devs.giugl.io + ${eleonora-wg} eleonora.devs.giugl.io + ${broccolino-wg} broccolino.devs.giugl.io + ${hotpottino-wg} hotpottino.devs.giugl.io - environment.systemPackages = with pkgs; - [ - docker - openiscsi - wireguard - ]; +# Blacklist + 0.0.0.0 metrics.plex.tv + 0.0.0.0 analytics.plex.tv + 0.0.0.0 cdn.luckyorange.com + 0.0.0.0 w1.luckyorange.com + 0.0.0.0 browser.sentry-cdn.com + 0.0.0.0 analytics.facebook.com + 0.0.0.0 ads.facebook.com + 0.0.0.0 extmaps-api.yandex.net + 0.0.0.0 logservice.hicloud.com + 0.0.0.0 logbak.hicloud.com + 0.0.0.0 logservice1.hicloud.com + 0.0.0.0 samsung-com.112.2o7.net + 0.0.0.0 supportmetrics.apple.com + 0.0.0.0 analytics.oneplus.cn + 0.0.0.0 click.oneplus.cn + 0.0.0.0 analytics-api.samsunghealthcn.com - hardware = { - cpu.amd.updateMicrocode = true; - }; - - services = { - zfs.autoScrub.enable = true; - xserver.videoDrivers = [ "nvidia" ]; - - dnsmasq = { - enable = true; - servers = ["127.0.0.1#5353"]; - extraConfig = '' - localise-queries +# The following lines are desirable for IPv6 capable hosts + ::1 localhost ip6-localhost ip6-loopback + ff02::1 ip6-allnodes + ff02::2 ip6-allrouters ''; }; - dnscrypt-proxy2 = { - enable = true; - settings = { - listen_addresses = ["127.0.0.1:5353"]; - ipv4_servers = true; - ipv6_servers = false; - dnscrypt_servers = true; - doh_servers = true; - require_nolog = true; - require_nofilter = true; - timeout = 350; - lb_strategy = "p4"; - lb_estimator = true; - ignore_system_dns = true; - fallback_resolvers = ["1.1.1.1:53" "9.9.9.9:53"]; + environment.systemPackages = with pkgs; + [ + docker + openiscsi + wireguard + cudatoolkit + ]; + + hardware = { + cpu.amd.updateMicrocode = true; + opengl.enable = true; + opengl.extraPackages= with pkgs; [vaapiVdpau]; + opengl.driSupport = true; + }; + + services = { + zfs.autoScrub.enable = true; + xserver.videoDrivers = [ "nvidia" ]; + jellyfin.enable = true; + bazarr.enable = true; + radarr.enable = true; + sonarr.enable = true; + nzbget.enable = true; + thelounge.enable = true; + + dnsmasq = { + enable = true; + servers = ["127.0.0.1#5353"]; + extraConfig = '' + localise-queries + ''; + }; + + dnscrypt-proxy2 = { + enable = true; + settings = { + listen_addresses = ["127.0.0.1:5353"]; + ipv4_servers = true; + ipv6_servers = false; + dnscrypt_servers = true; + doh_servers = true; + require_nolog = true; + require_nofilter = true; + timeout = 350; + lb_strategy = "p4"; + lb_estimator = true; + ignore_system_dns = true; + fallback_resolvers = ["1.1.1.1:53" "9.9.9.9:53"]; + }; + }; + + openssh = { + enable = true; + passwordAuthentication = true; + permitRootLogin = "yes"; + }; + + postgresql = { + enable = true; + + # Ensure the database, user, and permissions always exist + ensureDatabases = [ "nextcloud" ]; + ensureUsers = [ + { name = "nextcloud"; + ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; + } + ]; + }; + + nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + + virtualHosts."media.giugl.io" = { + locations."/" = { + proxyPass = "http://localhost:8096"; }; }; - openssh = { - enable = true; - passwordAuthentication = true; - permitRootLogin = "yes"; + virtualHosts."htbaz.giugl.io" = { + locations."/" = { + proxyPass = "http://localhost:6767"; + }; }; - }; -} + + virtualHosts."htrad.giugl.io" = { + locations."/" = { + proxyPass = "http://localhost:7878"; + }; + }; + + virtualHosts."htson.giugl.io" = { + locations."/" = { + proxyPass = "http://localhost:8989"; + }; + }; + + virtualHosts."htnzb.giugl.io" = { + locations."/" = { + proxyPass = "http://localhost:6789"; + }; + }; + + }; + +}; + +environment.variables = { + LIBVA_DRIVER_NAME="vdpau"; +}; +users.groups.media.members = ["radarr" "sonarr" "nzbget" "bazarr" "transmission" "jellyfin" "jellyfin"]; +users.groups.video.members = ["jellyfin"]; +users.groups.render.members = ["jellyfin"]; + } + diff --git a/hosts/giupi/firewall.nix b/hosts/giupi/firewall.nix index ae52829..085c23c 100644 --- a/hosts/giupi/firewall.nix +++ b/hosts/giupi/firewall.nix @@ -1,6 +1,29 @@ -{config, ...} : +{config, lib, ...} : -{ +with import ./network.nix; +let + open_tcp_ports = lib.concatMapStringsSep "," (x: toString x) [ + 22 # ssh + 80 # http + 443 # https + 6567 # mindustry + 9001 # rocketpool + 10022 # gitea + 25565 # minecraft + 30303 # rocketpool + 51413 # transmission + 60025 # protonmail IMAP + 60143 # protonmail SMTP + ]; + open_udp_ports = lib.concatMapStringsSep "," (x: toString x) [ + 1194 # wireguard + 6567 # mindustry + 9001 # rocketpool + 25565 # minecraft + 30303 # rocketpool + 51413 # transmission + ]; +in { networking = { # needed to use nftables firewall.enable = false; @@ -9,7 +32,150 @@ nftables = { enable = true; ruleset = '' - + table ip raw { + chain PREROUTING { + type filter hook prerouting priority raw; policy accept; + } + + chain OUTPUT { + type filter hook output priority raw; policy accept; + } + } + + table ip nat { + chain PREROUTING { + type nat hook prerouting priority dstnat; policy accept; + } + + chain INPUT { + type nat hook input priority 100; policy accept; + } + + chain OUTPUT { + type nat hook output priority -100; policy accept; + } + + chain POSTROUTING { + type nat hook postrouting priority srcnat; policy accept; + oifname ${wan_if} ip saddr {${lib.concatStringsSep "," towan-wg}} masquerade + } + } + + table ip mangle { + chain PREROUTING { + type filter hook prerouting priority mangle; policy drop; + ct state invalid,untracked drop comment "drop invalid" + ip daddr 255.255.255.255 accept comment "allow broadcast traffic" + ip daddr 224.0.0.0/4 accept comment "allow multicast traffic" + iifname ${wan_if} ip saddr 10.3.0.0/24 drop comment "bind any ip to intf ${wan_if}" + iifname ${wan_if} ip saddr 127.0.0.0/8 drop comment "bind any ip to intf ${wan_if}" + iifname ${wan_if} accept comment "bind any ip to intf ${wan_if}" + iifname ${wg_if} ip saddr 10.3.0.0/24 accept comment "bind ip 10.3.0.0/24 to intf ${wg_if}" + iifname "lo" accept comment "bind any ip to intf lo" + jump mangle_drop + } + + chain INPUT { + type filter hook input priority mangle; policy accept; + } + + chain FORWARD { + type filter hook forward priority mangle; policy accept; + } + + chain OUTPUT { + type route hook output priority mangle; policy accept; + } + + chain POSTROUTING { + type filter hook postrouting priority mangle; policy accept; + } + + chain mangle_drop { + ip protocol icmp jump mangle_drop_icmp + ip protocol udp jump mangle_drop_udp + ip protocol tcp jump mangle_drop_tcp + log prefix "MANGLE-DROP-UNK " + drop + } + + chain mangle_drop_icmp { + log prefix "MANGLE-DROP-ICMP " + drop + } + + chain mangle_drop_tcp { + log prefix "MANGLE-DROP-TCP " + drop + } + + chain mangle_drop_udp { + log prefix "MANGLE-DROP-UDP " + drop + } + } + + table ip filter { + chain INPUT { + type filter hook input priority filter; policy drop; + + ct state established,related accept + iifname "lo" accept comment "loopback" + ip daddr 255.255.255.255 accept comment "allow broadcast traffic" + ip daddr 224.0.0.0/4 accept comment "allow multicast traffic" + ip saddr ${lan_net} accept comment "lan > local" + + iifname ${wan_if} tcp dport {${open_tcp_ports}} accept + iifname ${wan_if} udp dport {${open_udp_ports}} accept + iifname ${wg_if} accept comment "vpn > local" + + jump filter_drop + } + + chain FORWARD { + type filter hook forward priority filter; policy drop; + ct state established,related accept + + # client to client + ip saddr {${lib.concatStringsSep "," c2c-wg}} ip daddr {${lib.concatStringsSep "," c2c-wg}} accept + # gdevices talking to each other + ip saddr {${lib.concatStringsSep "," gdevices-wg}} ip daddr {${lib.concatStringsSep "," gdevices-wg}} accept + # nat to wan + oifname ${wan_if} ip saddr {${lib.concatStringsSep "," towan-wg}} accept + + jump filter_drop + } + + chain OUTPUT { + type filter hook output priority filter; policy drop; + ct state established,related accept + accept comment "local > *" + jump filter_drop + } + + chain filter_drop { + ip protocol icmp jump filter_drop_icmp + ip protocol udp jump filter_drop_udp + ip protocol tcp jump filter_drop_tcp + log prefix "DROP-UNK " + drop + } + + chain filter_drop_icmp { + log prefix "DROP-icmp " + drop + } + + chain filter_drop_tcp { + log prefix "DROP-tcp " + drop + } + + chain filter_drop_udp { + log prefix "DROP-udp " + drop + } + } ''; }; }; diff --git a/hosts/giupi/hardware.nix b/hosts/giupi/hardware.nix index 7fbd1f9..b46ad2c 100644 --- a/hosts/giupi/hardware.nix +++ b/hosts/giupi/hardware.nix @@ -6,27 +6,42 @@ { imports = [ (modulesPath + "/installer/scan/not-detected.nix") - ]; + ]; boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; - boot.initrd.kernelModules = [ ]; - boot.kernelModules = [ "kvm-amd" ]; - boot.extraModulePackages = [ ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.extraModulePackages = [ ]; fileSystems."/" = { device = "zpool/nixos/root"; - fsType = "zfs"; - }; + fsType = "zfs"; + }; fileSystems."/home" = { device = "zpool/data/home"; - fsType = "zfs"; - }; + fsType = "zfs"; + }; + fileSystems."/media" = + { device = "datapool/media"; + fsType = "zfs"; + }; + + fileSystems."/docker" = + { device = "backedpool/docker"; + fsType = "zfs"; + }; + + fileSystems."/var/lib" = + { device = "backedpool/services"; + fsType = "zfs"; + }; + fileSystems."/boot" = { device = "/dev/disk/by-uuid/AF19-5616"; - fsType = "vfat"; - }; + fsType = "vfat"; + }; swapDevices = [ ];