diff --git a/server/configuration.nix b/server/configuration.nix deleted file mode 100644 index 4b0f9a7..0000000 --- a/server/configuration.nix +++ /dev/null @@ -1,160 +0,0 @@ -{ config, pkgs, ... }: - -{ - # Bootloader. - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = true; - boot.loader.efi.efiSysMountPoint = "/boot"; - boot.kernelPackages = pkgs.linuxPackages_latest; - - # Enable networking - networking.networkmanager.enable = true; - networking.networkmanager.wifi.powersave = true; - networking.useDHCP = false; - networking.extraHosts = - '' - 100.75.7.116 harper.tail rss.duckland.org vault.duckland.org git.duckland.org photos.duckland.org recipes.duckland.org vault.duckland.org dashy.duckland.org music.duckland.org bandwidth.duckland.org bandwidth2.duckland.org speed.duckland.org cloud.duckland.org plex.duckland.org smoke.duckland.org smart.duckland.org drone.home.duckland.org webhook.home.duckland.org cal.duckland.org gluetun.config.duckland.org jelly.duckland.org harper - ''; - - # Set your time zone. - time.timeZone = "America/Chicago"; - - # Select internationalisation properties. - i18n.defaultLocale = "en_US.utf8"; - - # Splash screen - boot.plymouth.enable = false; - boot.plymouth.theme = "breeze"; - - # Enable doas instead of sudo - security.sudo.enable = false; - security.doas.enable = true; - security.doas.extraRules = [{ - users = [ "don" ]; - keepEnv = true; - noPass = true; - }]; - - sound.enable = false; - security.rtkit.enable = true; - - # Define a user account. Don't forget to set a password with ‘passwd’. - users.users.don = { - isNormalUser = true; - description = "Don Harper"; - extraGroups = [ "networkmanager" "wheel" "scanner" "lp" ]; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINd8AdVbQQ/Fmw+b9mI8EMYqIoRkwmSwAOtmlte3incL don@loki" - ]; - }; - - # Allow unfree packages - nixpkgs.config.allowUnfree = false; - - # List packages installed in system profile. To search, run: - # $ nix search wget - environment.systemPackages = with pkgs; [ - #vim - git-crypt - gitFull - gnupg - home-manager - keyutils - mosh - podman-compose - python310 - python310Packages.pipx - python310Packages.setuptools - python310Packages.tldextract - syncthing - tailscale - tmux - tmuxp - topgrade - wget - ]; - - programs.mtr.enable = true; - services.tailscale.enable = true; - # create a oneshot job to authenticate to Tailscale - systemd.services.tailscale-autoconnect = { - description = "Automatic connection to Tailscale"; - - # make sure tailscale is running before trying to connect to tailscale - after = [ "network-pre.target" "tailscale.service" ]; - wants = [ "network-pre.target" "tailscale.service" ]; - wantedBy = [ "multi-user.target" ]; - - # set this service as a oneshot job - serviceConfig.Type = "oneshot"; - - # have the job run this shell script - script = with pkgs; '' - # wait for tailscaled to settle - sleep 2 - - # check if we are already authenticated to tailscale - status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)" - if [ $status = "Running" ]; then # if so, then do nothing - exit 0 - fi - - # otherwise authenticate with tailscale - ${tailscale}/bin/tailscale up -authkey tskey-auth-kt22J52CNTRL-iT7CCqfci73sWvVy6Dyi83DWzwLnNyknF - ''; - }; - - - # Enable the OpenSSH daemon. - services.openssh = { - enable = true; - passwordAuthentication = false; - kbdInteractiveAuthentication = false; - #permitRootLogin = "yes"; - }; - - # Open ports in the firewall. - networking.firewall = { - enable = true; - # always allow traffic from your Tailscale network - trustedInterfaces = [ "tailscale0" ]; - checkReversePath = "loose"; - - # allow the Tailscale UDP port through the firewall - allowedUDPPorts = [ config.services.tailscale.port ]; - - # allow you to SSH in over the public internet - allowedTCPPorts = [ 22 80 443 ]; - }; - - - system.stateVersion = "22.05"; # Did you read the comment? - programs.msmtp = { - enable = true; - accounts = { - default = { - auth = true; - tls = true; - from = "don@donharper.org"; - host = "smtp.gmail.com"; - user = "duckunix@gmail.com"; - passwordeval = "cat /home/don/.smtp_password.txt"; - }; - }; - }; - nix.gc = { - automatic = true; - options = "-d"; - }; - virtualisation = { - podman = { - enable = true; - - # Create a `docker` alias for podman, to use it as a drop-in replacement - dockerCompat = true; - - # Required for containers under podman-compose to be able to talk to each other. - defaultNetwork.dnsname.enable = true; - }; - }; -} diff --git a/server/default.nix b/server/default.nix new file mode 100644 index 0000000..7b65966 --- /dev/null +++ b/server/default.nix @@ -0,0 +1,305 @@ +{ config, pkgs, ... }: + +let + my-python-packages = python-packages: with python-packages; [ + pip + pipx + python-dateutil + setuptools + requests + ]; + python-with-my-packages = pkgs.python3Full.withPackages my-python-packages; +in +{ + nix = { + settings = { + experimental-features = [ "nix-command" "flakes" ]; + warn-dirty = false; + auto-optimise-store = true; + trusted-users = [ "root" "don" ]; + }; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 7d"; + }; + }; + imports = + [ + ./detect-reboot-needed.nix + ./systemd.nix + ./upgrade-diff.nix + ]; + + # Enable networking + networking.networkmanager.enable = true; + networking.enableIPv6 = true; + networking.networkmanager.wifi.powersave = true; + networking.useDHCP = false; + + # Set your time zone. + time = { + timeZone = "America/Chicago"; + hardwareClockInLocalTime = false; + }; + + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.utf8"; + i18n.inputMethod = { + enabled = "fcitx5"; + fcitx5.addons = with pkgs; [ + fcitx5-mozc + fcitx5-gtk + ]; + }; + + # Bootloader. + boot = { + kernelPackages = pkgs.linuxPackages_latest; + kernelParams = [ "consoleblank=60" ]; + loader = { + systemd-boot = { + enable = true; + }; + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot"; + }; + }; + plymouth = { + enable = true; + theme = "breeze"; + }; + kernel = { + sysctl = { "vm.swappiness" = 10;}; + }; + }; + + security = { + polkit = { + enable = true; + }; + sudo.enable = false; + doas = { + enable = true; + extraRules = [{ + users = [ "don" ]; + keepEnv = true; + noPass = true; + }]; + }; + }; + + services = { + #udev = { + #extraRules = '' + #KERNEL=="card0", SUBSYSTEM=="drm", RUN+=""${pkgs.kanshi-fix}"/bin/kanshi-fix" + #''; + #}; + pcscd = { + enable = true; + }; + avahi = { + enable = true; + nssmdns4 = true; + }; + printing = { + enable = true; + }; + udisks2 = { + enable = true; + }; + nscd = { + enableNsncd = true; + }; + flatpak = { + enable = true; + }; + pipewire = { + enable = true; + alsa = { + enable = true; + support32Bit = true; + }; + pulse = { + enable = true; + }; + }; + tailscale = { + enable = true; + }; + logind = { + lidSwitchExternalPower = "ignore"; + lidSwitchDocked = "ignore"; + }; + locate = { + enable = true; + package = pkgs.mlocate; + localuser = null; + }; + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + #permitRootLogin = "yes"; + }; + }; + }; + + # Enable sound with pipewire. + sound.enable = true; + hardware.bluetooth.enable = true; + hardware.pulseaudio.enable = false; + hardware.sane = { + enable = true; + extraBackends = [ pkgs.sane-airscan ]; + }; + security.rtkit.enable = true; + + xdg.portal = { + enable = true; + wlr.enable = true; + extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; + #gtkUsePortal = true; + }; + + users.users.don = { + isNormalUser = true; + description = "Don Harper"; + extraGroups = [ "networkmanager" "wheel" "scanner" "lp" "video" "mlocate" "disk" ]; + openssh.authorizedKeys.keys = [ + "git ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINd8AdVbQQ/Fmw+b9mI8EMYqIoRkwmSwAOtmlte3incL don@loki" + ]; + }; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + nixpkgs.config.permittedInsecurePackages = [ "electron-21.4.0" "electron-25.9.0" ]; + + environment.systemPackages = with pkgs; [ + #(callPackage ../mypackages/kanshi-fix/default.nix {}) + python-with-my-packages + acpi + aspell + aspellDicts.en + bash-completion + nix-bash-completions + btop + espeak-classic + # fwup + # fwupd + # fwupd-efi + git-crypt + gitFull + headsetcontrol + home-manager + hunspell + hunspellDicts.en_US + imagemagick + isync + libsForQt5.qtkeychain + lsb-release + pkg-config + playerctl + poppler_utils + pulseaudio + ruby + steam + udiskie + wireplumber + wlsunset + xdg-utils + xfce.thunar + zathura + ]; + + programs = { + steam = { + enable = true; + # Open ports in the firewall for Steam Remote Play + remotePlay.openFirewall = true; + # Open ports in the firewall for Source Dedicated Server + dedicatedServer.openFirewall = true; + }; + dconf = { + enable = true; + }; + light = { + enable = true; + }; + mtr = { + enable = true; + }; + kdeconnect = { + enable = true; + }; + gnupg = { + agent = { + enable = true; + pinentryFlavor = "curses"; + enableSSHSupport = true; + }; + }; + }; + + + nixpkgs.overlays = [ + (final: prev: { qutebrowser = prev.qutebrowser.override { enableWideVine = true; }; }) + (final: super:{ khal = super.khal.overridePythonAttrs (_: { doCheck = false; }); }) + ]; + + # Open ports in the firewall. + networking.firewall = { + enable = true; + # always allow traffic from your Tailscale network + trustedInterfaces = [ "tailscale0" ]; + checkReversePath = "loose"; + + # allow the Tailscale UDP port through the firewall + allowedUDPPorts = [ config.services.tailscale.port ]; + #allowedUDPPortRanges = [ { from = 1714 ; to = 1764; }]; + + # allow you to SSH in over the public internet + allowedTCPPorts = [ 22 ]; + #allowedTCPPortRanges = [ { from = 1714 ; to = 1764; } ]; + interfaces = { + "tailscale0" = { + allowedTCPPorts = [ 22 8080 8443 ]; + }; + }; + }; + + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It's perfectly fine and recommended to leavecatenate(variables, "bootdev", bootdev) + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.11"; # Did you read the comment? + programs.msmtp = { + enable = true; + accounts = { + default = { + auth = true; + tls = true; + port = 587; + from = "duck@duckland.org"; + host = "smtp.gmail.com"; + user = "duckunix@gmail.com"; + passwordeval = "cat /home/don/.smtp_password.txt"; + }; + }; + }; + xdg.mime.enable = true; + xdg.mime.defaultApplications = { + "text/html" = "org.qutebrowser.qutebrowser.desktop"; + "x-scheme-handler/http" = "org.qutebrowser.qutebrowser.desktop"; + "x-scheme-handler/https" = "org.qutebrowser.qutebrowser.desktop"; + "x-scheme-handler/about" = "org.qutebrowser.qutebrowser.desktop"; + "x-scheme-handler/unknown" = "org.qutebrowser.qutebrowser.desktop"; + }; + environment.sessionVariables.DEFAULT_BROWSER = "${pkgs.qutebrowser}/bin/qutebrowser"; +} diff --git a/server/systemd.nix b/server/systemd.nix new file mode 100644 index 0000000..674f39c --- /dev/null +++ b/server/systemd.nix @@ -0,0 +1,88 @@ +{ pkgs, ... }: + +let + readlink = "${pkgs.coreutils}/bin/readlink"; + notify-send = "${pkgs.libnotify}/bin/notify-send"; +in { + systemd = { + services = { + #console-blank = { + # enable = true; + # description ="Blank screen"; + # serviceConfig = { + # Type = "oneshot"; + # ExecStart = "${pkgs.util-linux}/bin/setterm -blank 1"; + # TTYPath="/dev/console"; + # StandardOutput="tty"; + # }; + # wantedBy = ["multi-user.target"]; + # environment = { + # TERM = "linux"; + # }; + tailscale-autoconnect = { + description = "Automatic connection to Tailscale"; + + # make sure tailscale is running before trying to connect to tailscale + after = [ "network-pre.target" "tailscale.service" ]; + wants = [ "network-pre.target" "tailscale.service" ]; + wantedBy = [ "multi-user.target" ]; + + # set this service as a oneshot job + serviceConfig.Type = "oneshot"; + + # have the job run this shell script + script = with pkgs; '' + # wait for tailscaled to settle + sleep 2 + + # check if we are already authenticated to tailscale + status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)" + if [ $status = "Running" ]; then # if so, then do nothing + exit 0 + fi + + # otherwise authenticate with tailscale + ${tailscale}/bin/tailscale up --operator=don --authkey tskey-auth-kt22J52CNTRL-iT7CCqfci73sWvVy6Dyi83DWzwLnNyknF + ''; + }; + + clean-keychain = { + description = "Clean up .keychain on boot"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.coreutils-full}/bin/rm -rf /home/don/.keychain"; + }; + }; + }; + user = { + services = { + detect-reboot-for-upgrade = { + script = '' + set -eu -o pipefail + booted="$(${readlink} /run/booted-system/{initrd,kernel,kernel-modules})" + built="$(${readlink} /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})" + if [[ "''${booted}" != "''${built}" ]]; + then + echo "Looks like we need a reboot!" + ${notify-send} --urgency=low --icon=system-reboot "Reboot is needed for a NixOS upgrade." + fi + ''; + serviceConfig = { + Type = "oneshot"; + }; + }; + }; + timers = { + detect-reboot-for-upgrade = { + wantedBy = [ "timers.target" ]; + partOf = [ "detect-reboot-for-upgrade.service" ]; + timerConfig = { + OnCalendar = "hourly"; + Unit = "detect-reboot-for-upgrade.service"; + }; + }; + }; + }; + }; +} diff --git a/server/upgrade-diff.nix b/server/upgrade-diff.nix new file mode 100644 index 0000000..1903966 --- /dev/null +++ b/server/upgrade-diff.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: { + system.activationScripts.diff = { + supportsDryActivation = true; + text = '' + ${pkgs.nvd}/bin/nvd --nix-bin-dir=${pkgs.nix}/bin diff /run/current-system "$systemConfig" + ''; + }; +}