diff --git a/README.md b/README.md index 07b7633..c1fcb1f 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,6 @@ The goal of this config is to include : \*Not using the "Nix" way (i prefer using Docker atm, i currently lack time) -# TODO - -- [x] fix homepage-dashboard secrets -- [ ] use Docker for Sonarr, seems to be a cleaner approach for double instances -- [ ] move crafty-controller / fressrss to nix -- [ ] setup mautrix-whatsapp / mautrix-discord - ## Installation You will need to do a basic NixOS install with my config files placed @ `/etc/nixos`. diff --git a/features/client/home-manager/home.nix b/features/client/home-manager/home.nix new file mode 100644 index 0000000..e69de29 diff --git a/features/server/default.nix b/features/server/default.nix new file mode 100644 index 0000000..09113c9 --- /dev/null +++ b/features/server/default.nix @@ -0,0 +1,33 @@ +{ config, pkgs, ... }: +{ + imports = [ + ./containers/default.nix + ./multimedia/default.nix + ./databases/default.nix + ./services/default.nix + ./backups.nix + ./caddy.nix + ./prometheus.nix + ./samba-shares.nix + ./ssh.nix + ./tailscale.nix + ]; + + environment.systemPackages = with pkgs; [ + jellyfin + jellyfin-web + jellyfin-ffmpeg + transmission + sonarr + radarr + prowlarr + readarr + jellyseerr + homepage-dashboard + slskd + bazarr + ethtool + networkd-dispatcher + transcrypt + ]; +} diff --git a/features/server/fail2ban.nix b/features/server/fail2ban.nix new file mode 100644 index 0000000..347e0c8 --- /dev/null +++ b/features/server/fail2ban.nix @@ -0,0 +1,9 @@ +{ config, ... }: +{ + services.fail2ban = { + enable = true; + ignoreIP = [ "192.168.1.0/24" ]; + extraPackages = [ ]; + jails = { }; + }; +} diff --git a/features/server/multimedia/default.nix b/features/server/multimedia/default.nix index c32e295..fa082d5 100644 --- a/features/server/multimedia/default.nix +++ b/features/server/multimedia/default.nix @@ -4,5 +4,6 @@ ./calibre-web.nix ./slskd.nix ./transmission.nix + ./jellyfin.nix ]; } diff --git a/features/server/multimedia/jellyfin.nix b/features/server/multimedia/jellyfin.nix new file mode 100644 index 0000000..f7b847e --- /dev/null +++ b/features/server/multimedia/jellyfin.nix @@ -0,0 +1,7 @@ +{ config, ... }: +{ + services.jellyfin = { + enable = true; + openFirewall = true; + }; +} diff --git a/features/server/tailscale.nix b/features/server/tailscale.nix index 16062cc..7df0312 100644 --- a/features/server/tailscale.nix +++ b/features/server/tailscale.nix @@ -4,4 +4,14 @@ enable = true; useRoutingFeatures = "server"; }; + + services.networkd-dispatcher = { + enable = true; + rules."50-tailscale" = { + onState = [ "routable" ]; + script = '' + ${pkgs.ethtool}/bin/ethtool -K ens18 rx-udp-gro-forwarding on rx-gro-list off + ''; + }; + }; } diff --git a/features/shared/ssh.nix b/features/shared/ssh.nix new file mode 100644 index 0000000..ed78121 --- /dev/null +++ b/features/shared/ssh.nix @@ -0,0 +1,11 @@ +{ config, ... }: +{ + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + PermitRootLogin = "no"; + }; + }; +} diff --git a/flake.nix b/flake.nix index b3bfbfc..2e95514 100644 --- a/flake.nix +++ b/flake.nix @@ -3,16 +3,39 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; + sops-nix.url = "github:Mic92/sops-nix"; }; outputs = - { self, nixpkgs, ... }@inputs: { - nixosConfigurations.sisyphe = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - ./configuration.nix - ]; + self, + nixpkgs, + sops-nix, + ... + }@inputs: + let + username = "harry123"; + + specialArgs = { + inherit username; + }; + in + { + nixosConfigurations = { + sisyphe = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./hosts/sisyphe/configuration.nix + sops-nix.nixosModules.sops + ]; + }; + + labouse = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./hosts/labouse/configuration.nix + ]; + }; }; }; } diff --git a/configuration.nix b/hosts/sisyphe/configuration.nix similarity index 73% rename from configuration.nix rename to hosts/sisyphe/configuration.nix index 9c9ee1c..81f1479 100644 --- a/configuration.nix +++ b/hosts/sisyphe/configuration.nix @@ -1,7 +1,3 @@ -# Edit this configuration file to define what should be installed on -# your system. Help is available in the configuration.nix(5) man page, on -# https://search.nixos.org/options and in the NixOS manual (`nixos-help`). - { config, lib, @@ -11,9 +7,9 @@ { imports = [ - ./hardware/vm-hardware.nix # or hardware-configuration.nix + ./hardware-configuration.nix ./server-configuration.nix - "${(import ./nix/sources.nix).sops-nix}/modules/sops" + ../../features/server/default.nix ]; # Use the GRUB 2 boot loader. @@ -38,18 +34,19 @@ "flakes" ]; + system.autoUpgrade.enable = true; + system.autoUpgrade.allowReboot = true; + users.users.homelab = { isNormalUser = true; extraGroups = [ "wheel" "dialout" "docker" - ]; # Enable ‘sudo’ for the user. + ]; packages = with pkgs; [ - neovim btop - tree ]; openssh.authorizedKeys.keys = [ @@ -61,36 +58,14 @@ users.users.root.initialHashedPassword = "$y$j9T$99/NEnBGoewbrl5eHvTw7/$87rjPrvqs0Ys72338SxZJDibi8p7Fe8Can37rJyhcQ."; - # List packages installed in system profile. To search, run: - # $ nix search wget environment.systemPackages = with pkgs; [ git - nvim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. + nvim curl - niv ]; environment.variables.EDITOR = "nvim"; - # Some programs need SUID wrappers, can be configured further or are - # started in user sessions. - # programs.mtr.enable = true; - # programs.gnupg.agent = { - # enable = true; - # enableSSHSupport = true; - # }; - - # List services that you want to enable: - - services.openssh = { - enable = true; - settings = { - PasswordAuthentication = false; - KbdInteractiveAuthentication = false; - PermitRootLogin = "no"; - }; - }; - # Open ports in the firewall. networking.firewall.allowedTCPPorts = [ 22 diff --git a/hardware/vm-hardware.nix b/hosts/sisyphe/hardware-configuration.nix similarity index 100% rename from hardware/vm-hardware.nix rename to hosts/sisyphe/hardware-configuration.nix diff --git a/hosts/sisyphe/server-configuration.nix b/hosts/sisyphe/server-configuration.nix new file mode 100644 index 0000000..ce8855b --- /dev/null +++ b/hosts/sisyphe/server-configuration.nix @@ -0,0 +1,70 @@ +# TODO: move file to configuration.nix +{ + config, + lib, + pkgs, + ... +}: +let + ip = "192.168.1.177"; + gateway = "192.168.1.1"; + username = "homelab"; +in +{ + # setting up networking!! + networking = { + interfaces = { + ens18.ipv4.addresses = [ + { + address = ip; + prefixLength = 24; + } + ]; + }; + + defaultGateway = gateway; + nameservers = [ + "1.1.1.1" + "1.0.0.1" + "2606:4700:4700::1111" + "2606:4700:4700::1001" + ]; + + nftables.enable = true; + # firewall rules + firewall = { + enable = true; + allowedTCPPorts = [ + 22 # ssh + 8008 # matrix-synapse + 8448 # matrix-synapse + 3030 + 3333 + 2344 + 4000 + 5050 # calibre-web + 9091 # transmission + ]; + allowedUDPPorts = [ ]; + }; + }; + + users.groups.multimedia = { + members = [ + "slskd" + "radarr" + "readarr" + "sonarr" + "transmission" + "jellyfin" + "bazarr" + "calibre-web" + username + ]; + }; + + sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + sops.age.keyFile = "/var/lib/sops-nix/key.txt"; + sops.age.generateKey = true; + sops.defaultSopsFile = ../../secrets/secrets.yaml; +} diff --git a/nix/sources.json b/nix/sources.json deleted file mode 100644 index f7db996..0000000 --- a/nix/sources.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "nixpkgs": { - "branch": "nixos-unstable", - "description": "Nix Packages collection", - "homepage": null, - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "6c43a3495a11e261e5f41e5d7eda2d71dae1b2fe", - "sha256": "16f329z831bq7l3wn1dfvbkh95l2gcggdwn6rk3cisdmv2aa3189", - "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/6c43a3495a11e261e5f41e5d7eda2d71dae1b2fe.tar.gz", - "url_template": "https://github.com///archive/.tar.gz" - }, - "sops-nix": { - "branch": "master", - "description": "Atomic secret provisioning for NixOS based on sops", - "homepage": "", - "owner": "Mic92", - "repo": "sops-nix", - "rev": "67035a355b1d52d2d238501f8cc1a18706979760", - "sha256": "1pihm7c30q38k7xzqbfvd5g9ffbim59qhvynmg3v8k7k6lnf3awf", - "type": "tarball", - "url": "https://github.com/Mic92/sops-nix/archive/67035a355b1d52d2d238501f8cc1a18706979760.tar.gz", - "url_template": "https://github.com///archive/.tar.gz" - } -} diff --git a/nix/sources.nix b/nix/sources.nix deleted file mode 100644 index fe3dadf..0000000 --- a/nix/sources.nix +++ /dev/null @@ -1,198 +0,0 @@ -# This file has been generated by Niv. - -let - - # - # The fetchers. fetch_ fetches specs of type . - # - - fetch_file = pkgs: name: spec: - let - name' = sanitizeName name + "-src"; - in - if spec.builtin or true then - builtins_fetchurl { inherit (spec) url sha256; name = name'; } - else - pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; - - fetch_tarball = pkgs: name: spec: - let - name' = sanitizeName name + "-src"; - in - if spec.builtin or true then - builtins_fetchTarball { name = name'; inherit (spec) url sha256; } - else - pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; - - fetch_git = name: spec: - let - ref = - spec.ref or ( - if spec ? branch then "refs/heads/${spec.branch}" else - if spec ? tag then "refs/tags/${spec.tag}" else - abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!" - ); - submodules = spec.submodules or false; - submoduleArg = - let - nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0; - emptyArgWithWarning = - if submodules - then - builtins.trace - ( - "The niv input \"${name}\" uses submodules " - + "but your nix's (${builtins.nixVersion}) builtins.fetchGit " - + "does not support them" - ) - { } - else { }; - in - if nixSupportsSubmodules - then { inherit submodules; } - else emptyArgWithWarning; - in - builtins.fetchGit - ({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg); - - fetch_local = spec: spec.path; - - fetch_builtin-tarball = name: throw - ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`. - $ niv modify ${name} -a type=tarball -a builtin=true''; - - fetch_builtin-url = name: throw - ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`. - $ niv modify ${name} -a type=file -a builtin=true''; - - # - # Various helpers - # - - # https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695 - sanitizeName = name: - ( - concatMapStrings (s: if builtins.isList s then "-" else s) - ( - builtins.split "[^[:alnum:]+._?=-]+" - ((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name) - ) - ); - - # The set of packages used when specs are fetched using non-builtins. - mkPkgs = sources: system: - let - sourcesNixpkgs = - import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; }; - hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; - hasThisAsNixpkgsPath = == ./.; - in - if builtins.hasAttr "nixpkgs" sources - then sourcesNixpkgs - else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then - import { } - else - abort - '' - Please specify either (through -I or NIX_PATH=nixpkgs=...) or - add a package called "nixpkgs" to your sources.json. - ''; - - # The actual fetching function. - fetch = pkgs: name: spec: - - if ! builtins.hasAttr "type" spec then - abort "ERROR: niv spec ${name} does not have a 'type' attribute" - else if spec.type == "file" then fetch_file pkgs name spec - else if spec.type == "tarball" then fetch_tarball pkgs name spec - else if spec.type == "git" then fetch_git name spec - else if spec.type == "local" then fetch_local spec - else if spec.type == "builtin-tarball" then fetch_builtin-tarball name - else if spec.type == "builtin-url" then fetch_builtin-url name - else - abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; - - # If the environment variable NIV_OVERRIDE_${name} is set, then use - # the path directly as opposed to the fetched source. - replace = name: drv: - let - saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name; - ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; - in - if ersatz == "" then drv else - # this turns the string into an actual Nix path (for both absolute and - # relative paths) - if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; - - # Ports of functions for older nix versions - - # a Nix version of mapAttrs if the built-in doesn't exist - mapAttrs = builtins.mapAttrs or ( - f: set: with builtins; - listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) - ); - - # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 - range = first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1); - - # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 - stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); - - # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 - stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); - concatMapStrings = f: list: concatStrings (map f list); - concatStrings = builtins.concatStringsSep ""; - - # https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331 - optionalAttrs = cond: as: if cond then as else { }; - - # fetchTarball version that is compatible between all the versions of Nix - builtins_fetchTarball = { url, name ? null, sha256 }@attrs: - let - inherit (builtins) lessThan nixVersion fetchTarball; - in - if lessThan nixVersion "1.12" then - fetchTarball ({ inherit url; } // (optionalAttrs (name != null) { inherit name; })) - else - fetchTarball attrs; - - # fetchurl version that is compatible between all the versions of Nix - builtins_fetchurl = { url, name ? null, sha256 }@attrs: - let - inherit (builtins) lessThan nixVersion fetchurl; - in - if lessThan nixVersion "1.12" then - fetchurl ({ inherit url; } // (optionalAttrs (name != null) { inherit name; })) - else - fetchurl attrs; - - # Create the final "sources" from the config - mkSources = config: - mapAttrs - ( - name: spec: - if builtins.hasAttr "outPath" spec - then - abort - "The values in sources.json should not have an 'outPath' attribute" - else - spec // { outPath = replace name (fetch config.pkgs name spec); } - ) - config.sources; - - # The "config" used by the fetchers - mkConfig = - { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null - , sources ? if sourcesFile == null then { } else builtins.fromJSON (builtins.readFile sourcesFile) - , system ? builtins.currentSystem - , pkgs ? mkPkgs sources system - }: rec { - # The sources, i.e. the attribute set of spec name to spec - inherit sources; - - # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers - inherit pkgs; - }; - -in -mkSources (mkConfig { }) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/server-configuration.nix b/server-configuration.nix deleted file mode 100644 index 00910b3..0000000 --- a/server-configuration.nix +++ /dev/null @@ -1,129 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - ip = "192.168.1.177"; - gateway = "192.168.1.1"; - username = "homelab"; -in -{ - imports = [ - ./features/server/containers/default.nix - ./features/server/multimedia/default.nix - ./features/server/databases/default.nix - ./features/server/services/default.nix - ./features/server/backups.nix - ./features/server/caddy.nix - ./features/server/prometheus.nix - ./features/server/samba-shares.nix - ]; - - # setting up networking!! - networking = { - interfaces = { - ens18.ipv4.addresses = [ - { - address = ip; - prefixLength = 24; - } - ]; - }; - - defaultGateway = gateway; - nameservers = [ - "1.1.1.1" - "1.0.0.1" - "2606:4700:4700::1111" - "2606:4700:4700::1001" - ]; - - nftables.enable = true; - # firewall rules - firewall = { - enable = true; - allowedTCPPorts = [ - 22 # ssh - 8008 # matrix-synapse - 8448 # matrix-synapse - 3030 - 3333 - 2344 - 4000 - 5050 # calibre-web - 9091 # transmission - ]; - allowedUDPPorts = [ ]; - }; - }; - - #TODO: setup fail2ban - services.fail2ban = { - enable = true; - ignoreIP = [ "192.168.1.0/24" ]; - extraPackages = [ ]; - jails = { }; - }; - - users.groups.multimedia = { - members = [ - "slskd" - "radarr" - "readarr" - "sonarr" - "transmission" - "jellyfin" - "bazarr" - "calibre-web" - username - ]; - }; - - sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; - sops.age.keyFile = "/var/lib/sops-nix/key.txt"; - sops.age.generateKey = true; - sops.defaultSopsFile = ./secrets/secrets.yaml; - - # define your secrets with - # `nix-shell -p sops --run "sops ./secrets/yoursecret.env"` - - environment.systemPackages = with pkgs; [ - jellyfin - jellyfin-web - jellyfin-ffmpeg - transmission - sonarr - radarr - prowlarr - readarr - jellyseerr - homepage-dashboard - slskd - bazarr - ethtool - networkd-dispatcher - transcrypt - ]; - - system.autoUpgrade.enable = true; - system.autoUpgrade.allowReboot = true; - - services.jellyfin = { - enable = true; - openFirewall = true; - }; - - services = { - networkd-dispatcher = { - enable = true; - rules."50-tailscale" = { - onState = [ "routable" ]; - script = '' - ${pkgs.ethtool}/bin/ethtool -K ens18 rx-udp-gro-forwarding on rx-gro-list off - ''; - }; - }; - }; -}