{ config, pkgs, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix ]; # Use the systemd-boot EFI boot loader. boot.loader = { systemd-boot.enable = true; efi = { canTouchEfiVariables = true; efiSysMountPoint = "/boot/efi"; }; }; console = { font = "Lat2-Terminus16"; keyMap = "us"; }; # List packages installed in the system profile. To search, run: # $ nix search wget environment.systemPackages = with pkgs; [ curl git tmux vim wget ]; hardware = { enableRedistributableFirmware = true; enableAllFirmware = true; pulseaudio.enable = true; opengl.enable = true; }; # Select internationalisation properties. i18n.defaultLocale = "en_GB.utf8"; networking = { hostName = "Niko"; domain = "depeuter.dev"; enableIPv6 = true; # Open ports in the firewall. firewall = { enable = true; }; networkmanager.enable = true; }; nix = { package = pkgs.nixFlakes; extraOptions = '' experimental-features = nix-command flakes ''; settings.trusted-users = [ config.users.users.admin.name ]; }; nixpkgs.config.allowUnfree = true; # List services that you want to enable: services = { displayManager = { enable = true; autoLogin = { enable = true; user = config.users.users.jellyfin-mpv-shim.name; }; }; xserver = { enable = true; displayManager.startx.enable = true; }; openssh = { # Enable the OpenSSH daemon. enable = true; settings = { PasswordAuthentication = false; PermitRootLogin = "no"; }; }; }; sound.enable = true; # Set your time zone. time.timeZone = "Europe/Brussels"; users = { # Define users groups groups = { # The group used to deploy rebuilds without password authentication deploy = { }; }; # Define a user account. Don't forget to set a password with 'passwd'. users = { admin = { description = "System Administrator"; isNormalUser = true; extraGroups = [ config.users.groups.wheel.name # Enable 'sudo' for the user. config.users.groups.deploy.name ]; initialPassword = "ChangeMe"; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPrG+ldRBdCeHEXrsy/qHXIJYg8xQXVuiUR0DxhFjYNg" ]; }; jellyfin-mpv-shim = { description = "Jellyfin MPV Shim User"; isNormalUser = true; extraGroups = [ config.users.groups.audio.name config.users.groups.video.name ]; packages = with pkgs; [ jellyfin-mpv-shim ]; }; }; }; security.sudo = { enable = true; extraRules = [ { groups = [ config.users.groups.deploy.name ]; commands = [ { command = "/nix/store/*/bin/switch-to-configuration"; options = [ "NOPASSWD" ]; } { command = "/run/current-system/sw/bin/nix-store"; options = [ "NOPASSWD" ]; } { command = ''/bin/sh -c "readlink -e /nix/var/nix/profiles/system || readlink -e /run/current-system"''; options = [ "NOPASSWD" ]; } { command = "${config.system.build.nixos-rebuild}/bin/nixos-rebuild"; options = [ "NOPASSWD" ]; } ]; } ]; }; system.stateVersion = "24.05"; virtualisation = { docker = { enable = true; autoPrune.enable = true; }; oci-containers = { backend = "docker"; containers = { reverse-proxy = { hostname = "traefik"; image = "traefik:v3.0"; cmd = [ "--api.insecure=true" # Add Docker provider "--providers.docker=true" "--providers.docker.exposedByDefault=false" # Add web entrypoint "--entrypoints.web.address=:80/tcp" "--entrypoints.web.http.redirections.entrypoint.to=websecure" "--entrypoints.web.http.redirections.entrypoint.scheme=https" # Add websecure entrypoint "--entrypoints.websecure.address=:443/tcp" "--entrypoints.websecure.http.tls=true" "--entrypoints.websecure.http.tls.certResolver=letsencrypt" "--entrypoints.websecure.http.tls.domains[0].main=depeuter.dev" "--entrypoints.websecure.http.tls.domains[0].sans=*.depeuter.dev" "--entrypoints.websecure.http.tls.domains[1].sans=*.niko.depeuter.dev" # Certificates "--certificatesresolvers.letsencrypt.acme.dnschallenge=true" "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare" "--certificatesresolvers.letsencrypt.acme.email=tibo.depeuter@telenet.be" "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" ]; ports = [ "80:80/tcp" "443:443/tcp" # "8080:8080/tcp" # The Web UI (enabled by --api.insecure=true) ]; environment = { "CLOUDFLARE_DNS_API_TOKEN" = "6Vz64Op_a6Ls1ljGeBxFoOVfQ-yB-svRbf6OyPv2"; }; environmentFiles = [ ]; volumes = [ "/var/run/docker.sock:/var/run/docker.sock:ro" # So that Traefik can listen to the Docker events "letsencrypt:/letsencrypt" ]; labels = { "traefik.enable" = "true"; "traefik.http.routers.traefik.rule" = "Host(`traefik.niko.depeuter.dev`)"; "traefik.http.services.traefik.loadbalancer.server.port" = "8080"; }; autoStart = true; }; technitium-dns = { hostname = "technitium-dns"; image = "technitium/dns-server:12.1"; ports = [ # "5380:5380/tcp" #DNS web console (HTTP) # "53443:53443/tcp" #DNS web console (HTTPS) "53:53/udp" #DNS service "53:53/tcp" #DNS service # "853:853/udp" #DNS-over-QUIC service # "853:853/tcp" #DNS-over-TLS service # "443:443/udp" #DNS-over-HTTPS service (HTTP/3) # "443:443/tcp" #DNS-over-HTTPS service (HTTP/1.1, HTTP/2) # "80:80/tcp" #DNS-over-HTTP service (use with reverse proxy or certbot certificate renewal) # "8053:8053/tcp" #DNS-over-HTTP service (use with reverse proxy) # "67:67/udp" #DHCP service ]; environment = { # The primary domain name used by this DNS Server to identify itself. DNS_SERVER_DOMAIN = config.networking.hostName; # DNS Server will use IPv6 for querying whenever possible with this option enabled. DNS_SERVER_PREFER_IPV6 = "true"; # The TCP port number for the DNS web console over HTTP protocol. # DNS_SERVER_WEB_SERVICE_HTTP_PORT=5380 # The TCP port number for the DNS web console over HTTPS protocol. # DNS_SERVER_WEB_SERVICE_HTTPS_PORT=53443 # Enables HTTPS for the DNS web console. # DNS_SERVER_WEB_SERVICE_ENABLE_HTTPS=false # Enables self signed TLS certificate for the DNS web console. # DNS_SERVER_WEB_SERVICE_USE_SELF_SIGNED_CERT=false # Enables DNS server optional protocol DNS-over-HTTP on TCP port 8053 to be used with a TLS terminating reverse proxy like nginx. # DNS_SERVER_OPTIONAL_PROTOCOL_DNS_OVER_HTTP=false # Recursion options: Allow, Deny, AllowOnlyForPrivateNetworks, UseSpecifiedNetworks. #nDNS_SERVER_RECURSION=AllowOnlyForPrivateNetworks # Comma separated list of IP addresses or network addresses to deny recursion. Valid only for `UseSpecifiedNetworks` recursion option. # DNS_SERVER_RECURSION_DENIED_NETWORKS=1.1.1.0/24 # Comma separated list of IP addresses or network addresses to allow recursion. Valid only for `UseSpecifiedNetworks` recursion option. # DNS_SERVER_RECURSION_ALLOWED_NETWORKS=127.0.0.1, 192.168.1.0/24 # Sets the DNS server to block domain names using Blocked Zone and Block List Zone. DNS_SERVER_ENABLE_BLOCKING = "false"; # Specifies if the DNS Server should respond with TXT records containing a blocked domain report for TXT type requests. # DNS_SERVER_ALLOW_TXT_BLOCKING_REPORT=false # A comma separated list of block list URLs. # DNS_SERVER_BLOCK_LIST_URLS= #Comma separated list of forwarder addresses. DNS_SERVER_FORWARDERS="195.130.130.2,195.130.131.2"; # Forwarder protocol options: Udp, Tcp, Tls, Https, HttpsJson. # DNS_SERVER_FORWARDER_PROTOCOL=Tcp # Enable this option to use local time instead of UTC for logging. # DNS_SERVER_LOG_USING_LOCAL_TIME=true }; volumes = [ "dns:/etc/dns" ]; labels = { "traefik.enable" = "true"; "traefik.http.routers.technitium-dns.rule" = "Host(`dns.niko.depeuter.dev`)"; "traefik.http.services.technitium-dns.loadbalancer.server.port" = "5380"; "traefik.tls.options.default.minVersion" = "VersionTLS13"; }; autoStart = true; }; }; }; }; }