diff --git a/hosts/servers/alexandria/configuration.nix b/hosts/servers/alexandria/configuration.nix new file mode 100644 index 0000000..b7f076b --- /dev/null +++ b/hosts/servers/alexandria/configuration.nix @@ -0,0 +1,77 @@ +{ config, pkgs, lib, ...}: + +{ + imports = [ + ./hardware-configuration.nix + ./hosted-services.nix + ./packages.nix + ./users.nix + + ]; + + swapDevices = [ { device = "/swapfile"; size = 8192; } ]; + + boot = { + kernelPackages = pkgs.linuxPackages_hardened; + loader = { + timeout = 1; + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + }; + + networking = { + networkmanager.enable = true; + hostName = "alexandria"; + firewall = { + enable = true; + checkReversePath = "loose"; + allowedTCPPorts = [ + 80 + 443 + 9666 + ]; + }; + }; + + time.timeZone = "Europe/Berlin"; + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "en_IE.UTF-8"; + LC_IDENTIFICATION = "en_IE.UTF-8"; + LC_MEASUREMENT = "en_IE.UTF-8"; + LC_MONETARY = "en_IE.UTF-8"; + LC_NAME = "en_IE.UTF-8"; + LC_NUMERIC = "en_IE.UTF-8"; + LC_PAPER = "en_IE.UTF-8"; + LC_TELEPHONE = "en_IE.UTF-8"; + LC_TIME = "en_IE.UTF-8"; + }; + }; + + services = { + openssh.enable = true; + tailscale.enable = true; + fstrim.enable = true; + }; + + nix = { + settings.auto-optimise-store = true; + extraOptions = "experimental-features = nix-command flakes"; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 8d"; + }; + }; + + system = { + stateVersion = "22.05"; + autoUpgrade = { + enable = true; + dates = "weekly"; + allowReboot = true; + }; + }; +} diff --git a/hosts/servers/alexandria/hardware-configuration.nix b/hosts/servers/alexandria/hardware-configuration.nix new file mode 100644 index 0000000..9758742 --- /dev/null +++ b/hosts/servers/alexandria/hardware-configuration.nix @@ -0,0 +1,39 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/31289617-1d84-4432-a833-680b52e88525"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/4130-BE54"; + fsType = "vfat"; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp1s0.useDHCP = lib.mkDefault true; + + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + # high-resolution display + hardware.video.hidpi.enable = lib.mkDefault true; +} diff --git a/hosts/servers/alexandria/hosted-services.nix b/hosts/servers/alexandria/hosted-services.nix new file mode 100644 index 0000000..b6c5582 --- /dev/null +++ b/hosts/servers/alexandria/hosted-services.nix @@ -0,0 +1,312 @@ +{ config, pkgs, libs, ... }: + +{ + + # security.acme = { + # acceptTerms = true; + # defaults = { + # email = "baduhai@baduhai.me"; + # server = "https://acme-staging-v02.api.letsencrypt.org/directory"; + # credentialsFile = "/var/secrets/acme"; # Transfer to secret file once I have a proper secrets solution + # extraLegoFlags = [ "--dns" "cloudflare" "--dns.resolvers=100.100.100.100:53" ]; + # }; + # }; +# + # services = { + # nginx = { + # enable = true; + # recommendedGzipSettings = true; + # recommendedOptimisation = true; + # recommendedProxySettings = true; + # recommendedTlsSettings = true; + # virtualHosts = { + # "baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8000/"; }; + # "detect.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8001/"; }; + # "cinny.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8002/"; }; + # "jellyfin.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8003/"; }; + # "librespeed.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8004/"; }; + # "paperless.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8005/"; }; + # "pyload.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8006/"; }; + # "shiori.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8007/"; }; + # "sync.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8008/"; }; + # "whoogle.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://127.0.0.1:8009/"; }; + # "adguard.baduhai.me" = { default = true; enableACME = true; addSSL = true; locations."/".proxyPass = "http://100.77.225.37:3000/"; }; + # }; + # }; + # }; + + virtualisation = { + docker.enable = true; + oci-containers = { + backend = "docker"; + containers = { + "traefik" = { # Reverse proxy + image = "docker.io/traefik:v2.8"; + cmd = [ + "--api" + "--providers.docker=true" # Enable the docker traefik provider + "--providers.docker.exposedbydefault=false" + "--api.dashboard=true" # Enable the Trafik dashboard + "--certificatesresolvers.letsencrypt.acme.dnschallenge=true" # Enable dns challenge + "--certificatesresolvers.letsencrypt.acme.email=baduhai@baduhai.me" # Dummy email + "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" + "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare" # Cloudflare has my dns records + "--certificatesresolvers.letsencrypt.acme.dnschallenge.resolvers=100.100.100.100:53" # Use tailscale as dns resolver + "--entrypoints.web.address=:80" # Listen on port 80 + "--entrypoints.web.http.redirections.entrypoint.to=websecure" # Redirect all http trafic to https + "--entrypoints.web.http.redirections.entrypoint.scheme=https" # Redirect all http trafic to https + "--entrypoints.websecure.address=:443" # Redirect all http trafic to https + "--entrypoints.websecure.http.tls=true" # Enable tls + "--entrypoints.websecure.http.tls.certResolver=letsencrypt" # Use letsencrypt for tls + "--entrypoints.websecure.http.tls.domains[0].main=baduhai.me" # tls for top-level domain + "--entrypoints.websecure.http.tls.domains[0].sans=*.baduhai.me" # tls for sub-domains + "--global.sendAnonymousUsage=false" # Stop traefik from reporting usage data + "--global.checkNewVersion=false" # Don't check for new versions + ]; + environment = { # Transfer to secret environmentFiles once I have a proper secrets solution + CLOUDFLARE_EMAIL = "haiwilliam0@gmail.com"; + CLOUDFLARE_DNS_API_TOKEN = "_zorlWkGYhCBrxn3g82pqOOiy9XULTdP2j7VoMVK"; + }; + volumes = [ + "/var/run/docker.sock:/var/run/docker.sock:ro" + "/data/traefik/certs:/letsencrypt" + ]; + ports = [ + "80:80" + "443:443" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.traefik.service=api@internal" + "--label=traefik.http.routers.traefik.entrypoints=websecure" + "--label=traefik.http.routers.traefik.tls.certresolver=letsencrypt" + "--label=traefik.http.routers.traefik.rule=Host(`traefik.baduhai.me`)" + ]; + }; + "changedetection" = { # Detect changes in webpages + image = "lscr.io/linuxserver/changedetection.io:latest"; + environment = { + PUID = "1000"; + PGID = "100"; + TZ = "Europe/Berlin"; + BASE_URL = "detect.baduhai.me"; + }; + volumes = [ + "/data/changedetection:/config" + ]; + ports = [ + "8001:5000" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.detect.entrypoints=websecure" + "--label=traefik.http.routers.detect.tls.certresolver=letsencrypt" + "--label=traefik.http.services.detect.loadbalancer.server.port=5000" + "--label=traefik.http.routers.detect.rule=Host(`detect.baduhai.me`)" + ]; + }; + "homarr" = { # Dashboard + image = "ghcr.io/ajnart/homarr:latest"; + volumes = [ + "/data/homarr/configs:/app/data/configs" + "/var/run/docker.sock:/var/run/docker.sock:ro" + ]; + ports = [ + "8000:7575" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.homarr.entrypoints=websecure" + "--label=traefik.http.routers.homarr.tls.certresolver=letsencrypt" + "--label=traefik.http.services.homarr.loadbalancer.server.port=7575" + "--label=traefik.http.routers.homarr.rule=Host(`baduhai.me`)" + ]; + }; + "jellyfin" = { + image = "lscr.io/linuxserver/jellyfin:10.8.4"; + environment = { + PUID = "1000"; + PGID = "100"; + TZ = "Europe/Berlin"; + DOCKER_MODS = "linuxserver/mods:jellyfin-opencl-intel"; + }; + volumes = [ + "/data/jellyfin/library:/config" + "/data/jellyfin/tvseries:/data/tvshows" + "/data/jellyfin/movies:/data/movies" + ]; + ports = [ + "8003:8096" + ]; + extraOptions = [ + "--pull=always" + "--device=/dev/dri:/dev/dri" + "--label=traefik.enable=true" + "--label=traefik.http.routers.jellyfin.entrypoints=websecure" + "--label=traefik.http.routers.jellyfin.tls.certresolver=letsencrypt" + "--label=traefik.http.services.jellyfin.loadbalancer.server.port=8096" + "--label=traefik.http.routers.jellyfin.rule=Host(`jellyfin.baduhai.me`)" + ]; + }; + "paperless" = { # Digital document manager + image = "lscr.io/linuxserver/paperless-ngx:latest"; + environment = { + PUID = "1000"; + PGID = "100"; + TZ = "Europe/Berlin"; + PAPERLESS_URL = "https://paperless.baduhai.me"; + PAPERLESS_OCR_LANGUAGE = "eng+deu+por"; + DOCKER_MODS = "linuxserver/mods:papermerge-multilangocr"; + OCRLANG = "eng,por,deu"; + }; + volumes = [ + "/data/paperless-ngx/config:/config" + "/data/paperless-ngx/data:/data" + ]; + ports = [ + "8005:8000" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.paperless.entrypoints=websecure" + "--label=traefik.http.routers.paperless.tls.certresolver=letsencrypt" + "--label=traefik.http.services.paperless.loadbalancer.server.port=8000" + "--label=traefik.http.routers.paperless.rule=Host(`paperless.baduhai.me`)" + ]; + }; + "pyload" = { # Download manager + image = "lscr.io/linuxserver/pyload-ng:latest"; + environment = { + PUID = "1000"; + PGID = "100"; + TZ = "Europe/Berlin"; + }; + volumes = [ + "/data/pyload/config:/config" + "/data/pyload/downloads:/downloads" + ]; + ports = [ + "8006:8000" + "9666:9666" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.pyload.entrypoints=websecure" + "--label=traefik.http.routers.pyload.tls.certresolver=letsencrypt" + "--label=traefik.http.services.pyload.loadbalancer.server.port=8000" + "--label=traefik.http.routers.pyload.rule=Host(`pyload.baduhai.me`)" + ]; + }; + "shiori" = { # Bookmark manager + image = "docker.io/nicholaswilde/shiori:latest"; + environment = { + TZ = "Europe/Berlin"; + PUID = "1000"; + PGID = "100"; + SHIORI_DIR = "/data"; + }; + volumes = [ + "/data/shiori:/data" + ]; + ports = [ + "8007:8080" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.shiori.entrypoints=websecure" + "--label=traefik.http.routers.shiori.tls.certresolver=letsencrypt" + "--label=traefik.http.services.shiori.loadbalancer.server.port=8080" + "--label=traefik.http.routers.shiori.rule=Host(`shiori.baduhai.me`)" + ]; + }; + "syncthing" = { # P2P file synchronisation + image = "lscr.io/linuxserver/syncthing:1.20.4"; + environment = { + PUID = "1000"; + PGID = "100"; + TZ = "Europe/Berlin"; + }; + volumes = [ + "/data/syncthing/config:/config" + "/data/syncthing/data1:/data1" + "/data/syncthing/data2:/data2" + "/data/syncthing/notes:/sync/notes" + ]; + ports = [ + "8008:8384" + "22000:22000" + "21027:21027/udp" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.syncthing.entrypoints=websecure" + "--label=traefik.http.routers.syncthing.tls.certresolver=letsencrypt" + "--label=traefik.http.services.syncthing.loadbalancer.server.port=8384" + "--label=traefik.http.routers.syncthing.rule=Host(`sync.baduhai.me`)" + ]; + }; + "cinny" = { # Cinny matrix client + image = "ghcr.io/cinnyapp/cinny:latest"; + ports = [ + "8002:80" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.cinny.entrypoints=websecure" + "--label=traefik.http.routers.cinny.tls.certresolver=letsencrypt" + "--label=traefik.http.services.cinny.loadbalancer.server.port=80" + "--label=traefik.http.routers.cinny.rule=Host(`cinny.baduhai.me`)" + ]; + }; + "librespeed" = { # Speedtest + image = "lscr.io/linuxserver/librespeed:latest"; + environment = { + TZ = "Europe/Berlin"; + }; + ports = [ + "8004:80" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.librespeed.entrypoints=websecure" + "--label=traefik.http.routers.librespeed.tls.certresolver=letsencrypt" + "--label=traefik.http.services.librespeed.loadbalancer.server.port=80" + "--label=traefik.http.routers.librespeed.rule=Host(`librespeed.baduhai.me`)" + ]; + }; + "whoogle" = { # Anonymised google search + image = "benbusby/whoogle-search:latest"; + environment = { + HTTPS_ONLY = "1"; + WHOOGLE_CONFIG_DISABLE = "1"; + WHOOGLE_CONFIG_LANGUAGE = "lang_en"; + WHOOGLE_CONFIG_SEARCH_LANGUAGE = "lang_en"; + WHOOGLE_CONFIG_THEME = "system"; + WHOOGLE_CONFIG_VIEW_IMAGE = "1"; + WHOOGLE_CONFIG_GET_ONLY = "1"; + }; + ports = [ + "8009:5000" + ]; + extraOptions = [ + "--pull=always" + "--label=traefik.enable=true" + "--label=traefik.http.routers.whoogle.entrypoints=websecure" + "--label=traefik.http.routers.whoogle.tls.certresolver=letsencrypt" + "--label=traefik.http.services.whoogle.loadbalancer.server.port=5000" + "--label=traefik.http.routers.whoogle.rule=Host(`whoogle.baduhai.me`)" + ]; + }; + }; + }; + }; +} diff --git a/hosts/servers/alexandria/packages.nix b/hosts/servers/alexandria/packages.nix new file mode 100644 index 0000000..4579dfa --- /dev/null +++ b/hosts/servers/alexandria/packages.nix @@ -0,0 +1,19 @@ +{ config, pkgs, lib, ... }: + +{ + nixpkgs.config = { + allowUnfree = true; + }; + + environment.systemPackages = with pkgs; [ + any-nix-shell + bind + btop + git + htop + lazydocker + micro + tmux + wget + ]; +} diff --git a/hosts/servers/alexandria/users.nix b/hosts/servers/alexandria/users.nix new file mode 100644 index 0000000..1457114 --- /dev/null +++ b/hosts/servers/alexandria/users.nix @@ -0,0 +1,115 @@ +{ config, pkgs, ... }: + +{ + users.users = { + user = { + isNormalUser = true; + extraGroups = [ "wheel" "networkmanager" "docker" ]; + shell = pkgs.fish; + openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL foxtrot@rotterdam" ]; + hashedPassword = ""; + }; + root.hashedPassword = "!"; + }; + + home-manager.users.user = { pkgs, ... }: { + home = { + sessionVariables = { + EDITOR = "micro"; + }; + file = { + ".scripts/pfetch" = { + executable = true; + source = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/baduhai/dotfiles/master/scripts/pfetch"; + sha256 = "UEfTG1XCuN2GlpPz1gdQ5mxgutlX2XL58rGOqtaUgV4="; + }; + }; + }; + }; + programs = { + home-manager.enable = true; + password-store.enable = true; + bash = { + enable = true; + historyFile = "~/.cache/bash_history"; + }; + #micro = { + # enable = true; + # settings = { + # clipboard = "terminal"; + # mkparents = true; + # scrollbar = true; + # tabstospaces = true; + # tabsize = 2; + # }; + #}; + fish = { + enable = true; + interactiveShellInit = "any-nix-shell fish --info-right | source"; + loginShellInit = "any-nix-shell fish --info-right | source"; + shellAliases = { + d = "kitty +kitten diff"; + nano = "micro"; + wget = "wget --hsts-file=\"$XDG_DATA_HOME/wget-hsts\""; + }; + functions = { + fish_greeting = '' + set -x PF_INFO ascii title os kernel uptime pkgs memory palette + eval $HOME/.scripts/pfetch + ''; + tsh = "ssh -o RequestTTY=yes $argv tmux -u -CC new -A -s tmux-main"; + pacin = "nix-env -iA nixos.$argv"; + pacre = "nix-env -e $argv"; + trizen = "nix-env -qaP $argv"; + rebuild = "sudo nixos-rebuild switch"; + upgrade = "sudo nixos-rebuild switch --upgrade"; + }; + shellInit = '' + set -g PF_INFO ascii title os kernel uptime wm memory palette + set -g theme_date_format "+%H:%M" + set -g theme_date_timezone Europe/Berlin + set -g theme_avoid_ambiguous_glyphs yes + set -g theme_color_scheme dark + set -g theme_nerd_fonts yes + set -g theme_display_git_default_branch yes + set -g -x FONTCONFIG_FILE ${pkgs.fontconfig.out}/etc/fonts/fonts.conf + ''; + plugins = [ + { + name = "bobthefish"; + src = pkgs.fetchFromGitHub { + owner = "oh-my-fish"; + repo = "theme-bobthefish"; + rev = "2dcfcab653ae69ae95ab57217fe64c97ae05d8de"; + sha256 = "jBbm0wTNZ7jSoGFxRkTz96QHpc5ViAw9RGsRBkCQEIU="; + }; + } + { + name = "bang-bang"; + src = pkgs.fetchFromGitHub { + owner = "oh-my-fish"; + repo = "plugin-bang-bang"; + rev = "f969c618301163273d0a03d002614d9a81952c1e"; + sha256 = "A8ydBX4LORk+nutjHurqNNWFmW6LIiBPQcxS3x4nbeQ="; + }; + } + { + name = "fzf.fish"; + src = pkgs.fetchFromGitHub { + owner = "PatrickF1"; + repo = "fzf.fish"; + rev = "v9.2"; + sha256 = "XmRGe39O3xXmTvfawwT2mCwLIyXOlQm7f40mH5tzz+s="; + }; + } + ]; + }; + tmux = { + enable = true; + clock24 = true; + extraConfig = "set -g mouse on"; + }; + }; + }; +} diff --git a/overlays/signal-wayland.nix b/overlays/signal-wayland.nix new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/overlays/signal-wayland.nix @@ -0,0 +1 @@ +