From ea9850107fc17b7b1a8291a2a8f8cf86aa00253a Mon Sep 17 00:00:00 2001 From: gwg313 Date: Wed, 2 Jul 2025 06:51:06 -0400 Subject: [PATCH] add panopticon Signed-off-by: gwg313 --- flake.nix | 7 + home-manager/modules/ssh.nix | 16 +-- hosts/panopticon/configuration.nix | 116 ++++++++++++++++ hosts/panopticon/grafana.nix | 27 ++++ hosts/panopticon/hardware-configuration.nix | 43 ++++++ hosts/panopticon/loki.nix | 53 ++++++++ hosts/panopticon/prometheus_node_exporter.nix | 6 + hosts/panopticon/promtail.nix | 28 ++++ hosts/panopticon/traefik.nix | 127 ++++++++++++++++++ 9 files changed, 412 insertions(+), 11 deletions(-) create mode 100644 hosts/panopticon/configuration.nix create mode 100644 hosts/panopticon/grafana.nix create mode 100644 hosts/panopticon/hardware-configuration.nix create mode 100644 hosts/panopticon/loki.nix create mode 100644 hosts/panopticon/prometheus_node_exporter.nix create mode 100644 hosts/panopticon/promtail.nix create mode 100644 hosts/panopticon/traefik.nix diff --git a/flake.nix b/flake.nix index c767d53..29770e4 100644 --- a/flake.nix +++ b/flake.nix @@ -246,6 +246,13 @@ }; imports = [ ./hosts/seikan/configuration.nix ]; }; + + panopticon = { + deployment = { + targetHost = "panopticon"; # <- defined in ~/.ssh/config + }; + imports = [ ./hosts/panopticon/configuration.nix ]; + }; }; }; } diff --git a/home-manager/modules/ssh.nix b/home-manager/modules/ssh.nix index 2528f03..da190ff 100644 --- a/home-manager/modules/ssh.nix +++ b/home-manager/modules/ssh.nix @@ -45,17 +45,11 @@ user = "root"; identityFile = "/home/gwg313/.ssh/digital_ocean/id_ed25519"; }; - "onedev.local" = { - hostname = "git.local.gwg313.xyz"; - user = "git"; - identityFile = "/home/gwg313/.ssh/onedev/id_ed25519"; - port = 2222; - }; - "onedev" = { - hostname = "10.1.10.3"; - user = "git"; - identityFile = "/home/gwg313/.ssh/onedev/id_ed25519"; - port = 2222; + + "panopticon" = { + hostname = "10.1.10.9"; + user = "root"; + identityFile = "/home/gwg313/.ssh/colmena/id_ed25519"; }; }; }; diff --git a/hosts/panopticon/configuration.nix b/hosts/panopticon/configuration.nix new file mode 100644 index 0000000..cfafb5c --- /dev/null +++ b/hosts/panopticon/configuration.nix @@ -0,0 +1,116 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). +{ + config, + pkgs, + lib, + inputs, + ... +}: +{ + # sops + sops = { + defaultSopsFile = ../../secrets/secrets.yaml; + defaultSopsFormat = "yaml"; + age.keyFile = "/home/gwg313/.config/sops/age/keys.txt"; + }; + imports = [ + # Include the results of the hardware scan. + ./hardware-configuration.nix + ../../common/nixos/ssh/default.nix + ./grafana.nix + ./promtail.nix + ./loki.nix + ./prometheus_node_exporter.nix + inputs.sops-nix.nixosModules.sops + ]; + + ssh.enable = true; + ssh_guard.enable = true; + ssh_client.enable = false; + services.openssh.authorizedKeysFiles = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINvOfDSjlvegGqfUS18XwXB7SvS2n9/hGYUpKxRb9vgb gwg313@pm.me" + ]; + services.openssh.settings = { + PermitRootLogin = lib.mkForce "yes"; + + AllowUsers = lib.mkForce [ + "gwg313" + "root" + ]; + }; + + users.users.gwg313 = { + isNormalUser = true; + description = "gwg313"; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINvOfDSjlvegGqfUS18XwXB7SvS2n9/hGYUpKxRb9vgb gwg313@pm.me" + ]; + extraGroups = [ + "networkmanager" + "wheel" + ]; + packages = with pkgs; [ ]; + }; + + users.users = { + root = { + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINvOfDSjlvegGqfUS18XwXB7SvS2n9/hGYUpKxRb9vgb gwg313@pm.me" + ]; + }; + }; + + # Bootloader. + boot.loader.grub.enable = true; + boot.loader.grub.device = "/dev/sda"; + boot.loader.grub.useOSProber = true; + networking.hostName = "panopticon"; # Define your hostname. + # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + # Enable networking + networking.networkmanager.enable = true; + # Set your time zone. + time.timeZone = "America/Toronto"; + # Select internationalisation properties. + i18n.defaultLocale = "en_CA.UTF-8"; + # Configure keymap in X11 + services.xserver.xkb = { + layout = "us"; + variant = ""; + }; + # Define a user account. Don't forget to set a password with ‘passwd’. + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + # List packages installed in system profile. To search, run: + # $ nix search wget + environment.systemPackages = with pkgs; [ + # vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. + # wget + ]; + # 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: + # Enable the OpenSSH daemon. + # services.openssh.enable = true; + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + # networking.firewall.enable = false; + # 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 leave + # 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 = "24.11"; # Did you read the comment? +} diff --git a/hosts/panopticon/grafana.nix b/hosts/panopticon/grafana.nix new file mode 100644 index 0000000..578cdda --- /dev/null +++ b/hosts/panopticon/grafana.nix @@ -0,0 +1,27 @@ +_: { + services.grafana = { + enable = true; + settings = { + server = { + http_addr = "127.0.0.1"; + http_port = 3000; + }; + security = { + admin_user = "admin"; + admin_password = "changeme"; + }; + }; + + provision = { + datasources.settings.datasources = [ + { + name = "Loki"; + type = "loki"; + access = "proxy"; + url = "http://localhost:3100"; + isDefault = true; + } + ]; + }; + }; +} diff --git a/hosts/panopticon/hardware-configuration.nix b/hosts/panopticon/hardware-configuration.nix new file mode 100644 index 0000000..107ed92 --- /dev/null +++ b/hosts/panopticon/hardware-configuration.nix @@ -0,0 +1,43 @@ +# 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 + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ + "ata_piix" + "uhci_hcd" + "virtio_pci" + "virtio_scsi" + "sd_mod" + "sr_mod" + ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/979e137f-7d21-4dac-b6eb-51c8add1cf48"; + fsType = "ext4"; + }; + + 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.ens18.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/hosts/panopticon/loki.nix b/hosts/panopticon/loki.nix new file mode 100644 index 0000000..2c4ace0 --- /dev/null +++ b/hosts/panopticon/loki.nix @@ -0,0 +1,53 @@ +_: { + services.loki = { + enable = true; + configuration = { + auth_enabled = false; + server.http_listen_port = 3100; + + ingester = { + lifecycler = { + ring = { + kvstore = { + store = "inmemory"; + }; + }; + final_sleep = "0s"; + }; + chunk_idle_period = "5m"; + max_chunk_age = "1h"; + chunk_target_size = 1048576; + }; + + schema_config = { + configs = [ + { + from = "2024-01-01"; + store = "boltdb-shipper"; + object_store = "filesystem"; + schema = "v11"; + index = { + prefix = "index_"; + period = "24h"; + }; + } + ]; + }; + + storage_config = { + boltdb_shipper = { + active_index_directory = "/var/lib/loki/index"; + cache_location = "/var/lib/loki/cache"; + shared_store = "filesystem"; + }; + filesystem = { + directory = "/var/lib/loki/chunks"; + }; + }; + + limits_config = { + retention_period = "168h"; + }; + }; + }; +} diff --git a/hosts/panopticon/prometheus_node_exporter.nix b/hosts/panopticon/prometheus_node_exporter.nix new file mode 100644 index 0000000..993f8a1 --- /dev/null +++ b/hosts/panopticon/prometheus_node_exporter.nix @@ -0,0 +1,6 @@ +_: { + services.prometheus.exporters.node = { + enable = true; + openFirewall = true; + }; +} diff --git a/hosts/panopticon/promtail.nix b/hosts/panopticon/promtail.nix new file mode 100644 index 0000000..479791b --- /dev/null +++ b/hosts/panopticon/promtail.nix @@ -0,0 +1,28 @@ +{ config, ... }: +{ + services.promtail = { + enable = true; + configuration = { + server.http_listen_port = 9080; + positions = { + filename = "/var/lib/promtail/positions.yaml"; + }; + clients = [ + { + url = "http://localhost:3100/loki/api/v1/push"; + } + ]; + scrape_configs = [ + { + job_name = "journal"; + journal = { + labels = { + job = "systemd-journal"; + host = config.networking.hostName; + }; + }; + } + ]; + }; + }; +} diff --git a/hosts/panopticon/traefik.nix b/hosts/panopticon/traefik.nix new file mode 100644 index 0000000..7abab33 --- /dev/null +++ b/hosts/panopticon/traefik.nix @@ -0,0 +1,127 @@ +# Traefik +{ config, ... }: +{ + imports = [ + ]; + sops.secrets.cf-api-token = { + mode = "0440"; + owner = config.users.users.traefik.name; + group = config.users.users.traefik.group; + }; + + systemd.services.traefik.environment = { + CF_DNS_API_TOKEN_FILE = "${config.sops.secrets.cf-api-token.path}"; + }; + + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + + services.traefik = { + enable = true; + staticConfigOptions = { + serversTransport = { + insecureSkipVerify = true; + }; + entryPoints = { + web = { + address = ":80"; + http = { + redirections = { + entryPoint = { + to = "websecure"; + scheme = "https"; + }; + }; + }; + }; + websecure = { + address = ":443"; + http = { + tls = { + options = "default"; + }; + }; + }; + }; + api = { + dashboard = true; + }; + certificatesResolvers = { + le = { + acme = { + email = "glen.goodwin@protonmail.com"; + storage = "/var/lib/traefik/acme.json"; + dnsChallenge = { + provider = "cloudflare"; + resolvers = [ "1.1.1.1:53" ]; + }; + }; + }; + }; + log = { + level = "DEBUG"; + filePath = "/var/log/traefik/traefik.log"; + }; + + accessLog = { + filePath = "/var/log/traefik/access.log"; + bufferingSize = 0; + filters = { }; + fields = { + defaultMode = "keep"; + names = { + StartUTC = "drop"; + }; + }; + }; + }; + dynamicConfigOptions = { + http = { + routers = { + dashboard = { + rule = "Host(`monitor.local.gwg313.xyz`)"; + service = "api@internal"; + middlewares = [ + # "auth" + "headers" + ]; + entrypoints = [ "websecure" ]; + tls = { + certResolver = "le"; + }; + }; + }; + middlewares = { + headers = { + headers = { + browserxssfilter = true; + contenttypenosniff = true; + customframeoptionsvalue = "SAMEORIGIN"; + forcestsheader = true; + framedeny = true; + sslhost = "gwg313.xyz"; + sslredirect = true; + stsincludesubdomains = true; + stspreload = true; + stsseconds = "315360000"; + }; + }; + }; + }; + tls = { + options = { + default = { + minVersion = "VersionTLS13"; + sniStrict = true; + curvePreferences = [ + "CurveP521" + "CurveP384" + ]; + }; + }; + }; + }; + }; +}