diff --git a/.gitignore b/.gitignore index 771dfd5..741d668 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,9 @@ *.tfbackend terraform.tfstate* terraform.tfvars + +# Plaintext secrets/credentials generated while bridging tofu output into sops. +# Never commit these; only the sops-encrypted file belongs in the repository. +*-credentials.json +*.plain.yaml +*.plain.yml diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..d3c7777 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,10 @@ +keys: + - &admin age10u08tppfhh290a6hal553jdcqflew9pkkuatxaphy6aanp2qwe4qmf6vfz + - &lilith age1t6sz0u9gkyrlwmfmt3rm5h07z0ae6f9w9a2gmujz9gmzcrk9xqtq6zf5ge + +creation_rules: + - path_regex: lilith/secrets\.yaml$ + key_groups: + - age: + - *admin + - *lilith diff --git a/application.yaml b/application.yaml deleted file mode 100644 index b43f77e..0000000 --- a/application.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: argocd - namespace: argocd -spec: - project: default - source: - repoURL: https://github.com/akimon658/banda.git - targetRevision: HEAD - path: applications - destination: - server: https://kubernetes.default.svc - namespace: argocd - syncPolicy: - automated: {} diff --git a/applications/argocd_repo_server.yaml b/applications/argocd_repo_server.yaml deleted file mode 100644 index 1ecc916..0000000 --- a/applications/argocd_repo_server.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: argocd-repo-server -spec: - template: - spec: - automountServiceAccountToken: true - volumes: - - configMap: - name: cmp-plugin - name: cmp-plugin - - name: custom-tools - emptyDir: {} - initContainers: - - name: download-tools - image: registry.access.redhat.com/ubi8 - env: - - name: AVP_VERSION - value: 1.18.1 - command: [sh, -c] - args: - - >- - curl -L https://github.com/argoproj-labs/argocd-vault-plugin/releases/download/v$(AVP_VERSION)/argocd-vault-plugin_$(AVP_VERSION)_linux_amd64 -o argocd-vault-plugin && - chmod +x argocd-vault-plugin && - mv argocd-vault-plugin /custom-tools/ - volumeMounts: - - mountPath: /custom-tools - name: custom-tools - containers: - - name: avp - command: [/var/run/argocd/argocd-cmp-server] - image: registry.access.redhat.com/ubi8 - securityContext: - runAsNonRoot: true - runAsUser: 999 - volumeMounts: - - mountPath: /var/run/argocd - name: var-files - - mountPath: /home/argocd/cmp-server/plugins - name: plugins - - mountPath: /tmp - name: tmp - - # Register plugins into sidecar - - mountPath: /home/argocd/cmp-server/config/plugin.yaml - subPath: avp.yaml - name: cmp-plugin - - # Important: Mount tools into $PATH - - name: custom-tools - subPath: argocd-vault-plugin - mountPath: /usr/local/bin/argocd-vault-plugin diff --git a/applications/avp_cm.yaml b/applications/avp_cm.yaml deleted file mode 100644 index 523616f..0000000 --- a/applications/avp_cm.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: cmp-plugin -data: - avp.yaml: | - apiVersion: argoproj.io/v1alpha1 - kind: ConfigManagementPlugin - metadata: - name: argocd-vault-plugin - spec: - allowConcurrency: true - discover: - find: - command: - - sh - - "-c" - - "find . -name '*.yaml' | xargs -I {} grep \" diff --git a/flake.nix b/flake.nix index b61bd63..c679951 100644 --- a/flake.nix +++ b/flake.nix @@ -13,7 +13,10 @@ { devShells.default = pkgs.mkShell { packages = with pkgs; [ + age opentofu + sops + ssh-to-age ]; }; } diff --git a/lilith/configuration.nix b/lilith/configuration.nix new file mode 100644 index 0000000..55d8f92 --- /dev/null +++ b/lilith/configuration.nix @@ -0,0 +1,48 @@ +{ config, pkgs, ... }: +let + cloudflaredTunnelId = "13a0d38d-0486-465c-a54d-58da5c6388e6"; +in +{ + imports = [ + ./hardware-configuration.nix + ]; + boot.loader = { + efi.canTouchEfiVariables = true; + systemd-boot.enable = true; + }; + environment.systemPackages = with pkgs; [ + cloudflared + ]; + networking.networkmanager.enable = true; + nix.settings.experimental-features = [ "flakes" "nix-command" ]; + sops = { + age.keyFile = "/var/lib/sops-nix/key.txt"; + defaultSopsFile = ./secrets.yaml; + secrets."cloudflared-lilith-credentials" = { }; + }; + services = { + cloudflared = { + enable = true; + tunnels.${cloudflaredTunnelId} = { + credentialsFile = config.sops.secrets."cloudflared-lilith-credentials".path; + default = "http_status:404"; + ingress."lilith.akimo.dev" = { + service = "ssh://localhost:22"; + }; + }; + }; + logind.settings.Login = { + HandleLidSwitch = "ignore"; + HandleLidSwitchDocked = "ignore"; + HandleLidSwitchExternalPower = "ignore"; + }; + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "no"; + }; + }; + }; + system.stateVersion = "26.05"; +} diff --git a/lilith/flake.lock b/lilith/flake.lock new file mode 100644 index 0000000..a3fb593 --- /dev/null +++ b/lilith/flake.lock @@ -0,0 +1,48 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1789542786, + "narHash": "sha256-ajQuqcxnj6RYnwCjA/9FTCnrdR2+BDzstE8UembXf60=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4c7870105e7f1fdf9c48688c8d7efc21abf0688a", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-26.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "sops-nix": "sops-nix" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1788914643, + "narHash": "sha256-4GuMPW90JSxXWDPUB9M+1m7fYbe3H0apOd86/zBQ2Kw=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "13616fff713a9f94055c66f15687ebdc17a335df", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/lilith/flake.nix b/lilith/flake.nix new file mode 100644 index 0000000..1fd75f3 --- /dev/null +++ b/lilith/flake.nix @@ -0,0 +1,18 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05"; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + outputs = { nixpkgs, sops-nix, ... }: { + nixosConfigurations.lilith = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + sops-nix.nixosModules.sops + ./configuration.nix + ]; + }; + }; +} diff --git a/lilith/hardware-configuration.nix b/lilith/hardware-configuration.nix new file mode 100644 index 0000000..5b528b6 --- /dev/null +++ b/lilith/hardware-configuration.nix @@ -0,0 +1,45 @@ +{ config, lib, modulesPath, ... }: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + boot = { + extraModulePackages = []; + initrd = { + availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usb_storage" + "sd_mod" + "sdhci_pci" + ]; + kernelModules = []; + }; + kernelModules = [ "kvm-intel" ]; + }; + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/dca26fe3-e20b-4e28-8824-f5aeff64e667"; + fsType = "btrfs"; + options = [ "subvol=@" ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/4332-3C36"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + "/home" = { + device = "/dev/disk/by-uuid/dca26fe3-e20b-4e28-8824-f5aeff64e667"; + fsType = "btrfs"; + options = [ "subvol=@home" ]; + }; + "/nix" = { + device = "/dev/disk/by-uuid/dca26fe3-e20b-4e28-8824-f5aeff64e667"; + fsType = "btrfs"; + options = [ "subvol=@nix" ]; + }; + }; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + swapDevices = []; +} diff --git a/lilith/secrets.yaml b/lilith/secrets.yaml new file mode 100644 index 0000000..6e55677 --- /dev/null +++ b/lilith/secrets.yaml @@ -0,0 +1,25 @@ +cloudflared-lilith-credentials: ENC[AES256_GCM,data:oSwrJYZMCWZjdKGAasmaTCwWvLMYv3Z3I8AJGJOFxVX24mI3I62LahTDLrtUM28a5QD+xgL65ztbhJoOkg9ZgJduuQNCb4AXq4cOJhCiReN97fYNq8uAjku95uNFkufFLnIxMvKMgBVNdAiuZYUQyB8BAZkceRgmNxn6zaoyIMYVyh3vgTpqoQbBk2L9FgllvJtYWSln95odO6KltmUcze/c,iv:+YD3W0YfpctJhIFPJNDlFKGOGtUehUl62KR0jgUoXyQ=,tag:HTPNTtHKDiYrFeNe2XNtHQ==,type:str] +sops: + age: + - recipient: age10u08tppfhh290a6hal553jdcqflew9pkkuatxaphy6aanp2qwe4qmf6vfz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkc3VOdzFEN1p5ZGI0MXBs + L2wyUnYvcnUwWTNsKzYvOWRHNFpZOHBLeG40CkVHR0ZHVmhXYXNKOWcrdjcrS1FX + aFhoblBpMVcyQWJxR2RmSWJvWjMrQVEKLS0tIFM2Qkh3WE0wanV2SUx1OWNzRnk0 + TlJEUlZMdkN6aGx0NWNSQXVrVnZpcUEKv+DPzNQrxCE+1i5AAJ8MICg/lH1rUGH7 + 3yfB0mAsYZB14otDzIwI12K+vIqLK6WPazeyo5NBPPypK4BrwzoVVw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1t6sz0u9gkyrlwmfmt3rm5h07z0ae6f9w9a2gmujz9gmzcrk9xqtq6zf5ge + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUbmQwN3BOTFYxTGU3cVRu + S21EUHFSWWtwMzloWUY4dkRtbHFyZlNMSFJRClJQUjhUQmVrOEZLZ0Q3SWhveWNZ + enRRNHRXUlFwcnhDeG03L0VqQWFzUzgKLS0tIDRmM0h5QzhVZkNJTThKYVZQbUxR + VTl3S0FvcjUzaS96K3VEQllzSGdHTFUK7IJSl1zosX+QaKUv4ogNEOYOG3TvHFgh + q9y+Ga5IJ6Usurkk1GLbHtD0yxJTaBMT6V6wsBLeT48q8hsAZ8vC2Q== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-10-12T04:48:59Z" + mac: ENC[AES256_GCM,data:YLJzM27GF9MVLqHu2wmbPBWqoS89ia53l7KEu48llnmZvkWsFPIVJRi7C4MCBj+yaKSXrUdG1ecnwmRICzQ8Uc4pDCwtAqeWkTIuGaiWYj/4qM1MeTuR6dnQwYs8cfONnTe6dXxXJ45EiffZSe7kigUmtkNXZdl9pU84lXTYHQ8=,iv:3A4ULu8AtmEeygsk4YxyJZEupoCV1GXy9RerFnURhPs=,tag:u/WP3FQ+Bc4HASDTZzRH2w==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.2 diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl index d2474d7..39711f3 100644 --- a/terraform/.terraform.lock.hcl +++ b/terraform/.terraform.lock.hcl @@ -16,3 +16,25 @@ provider "registry.opentofu.org/cloudflare/cloudflare" { "zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32", ] } + +provider "registry.opentofu.org/hashicorp/random" { + version = "3.9.1" + hashes = [ + "h1:v3SAJKN4D3dOM95xKwgKGIWELe5nUBbyXdb5HNz7icw=", + "zh:09aaf19b0d22726d2378e0e89fbbefc183494d7bd585759d6c4e69ba50951a2f", + "zh:31575ca9bc0db20337096d178ea73bce3ebca343ed071c67f78cf39f800c9ec6", + "zh:624fb6ed552abc34a5aaac41e76a373da65ac08e524b09b672f29c60e6ac896a", + "zh:6a4760d55132b9750ac1a04f6fc32e247034daa999f71452dba9cbca225a529a", + "zh:768a6047cfb8958e7b0b120c580aa3de6624a7fbb2c56ad6df85cd559ed26ec7", + "zh:8983c788ba660bcb587e64ff9c3e4323515caf78facbe0abe6432e7aff8df893", + "zh:8d570eb026a4f00b58a1d36be0ce3c13adf4d973efcd4162b05cb295bbc14257", + "zh:a2259540854d5f699c36b89244fb202ebb2c219b64669a51072687d04fb47152", + "zh:aaa51d905b0e80a28e02f9bee2cf6c91ffade7389d77ab9198aa12809ed04955", + "zh:afb60995e98573facddfb47baedf7e288408680eb00b5d3df570611758947c72", + "zh:b9a46d852ce53fa037f47537a7de53f37b759ccf211600b7ba44c66ba4b616b7", + "zh:bafcfeeefcd0dfefeff120b655b45edb0497c4717534ffe5201b3cb556d1ffe6", + "zh:c3ac24d397eae054aca2290e20943e0c767592cc661c890850c25ac01829308d", + "zh:eafba4127ebadcc5ed0e427935c66fb5e2da7cfdaae39a66d52f4a50d51faf1e", + "zh:f39d4bce213ed9bba3474bad468136af08ff6c4c33adaafcc10c1f78067adfe3", + ] +} diff --git a/terraform/cloudflare_tunnel_lilith.tf b/terraform/cloudflare_tunnel_lilith.tf new file mode 100644 index 0000000..f211bf8 --- /dev/null +++ b/terraform/cloudflare_tunnel_lilith.tf @@ -0,0 +1,32 @@ +resource "random_bytes" "lilith_tunnel_secret" { + length = 32 +} + +resource "cloudflare_zero_trust_tunnel_cloudflared" "lilith" { + account_id = var.cloudflare_account_id + name = "lilith" + config_src = "local" + tunnel_secret = random_bytes.lilith_tunnel_secret.base64 +} + +resource "cloudflare_dns_record" "lilith_ssh" { + content = "${cloudflare_zero_trust_tunnel_cloudflared.lilith.id}.cfargotunnel.com" + name = "lilith" + proxied = true + ttl = 1 + type = "CNAME" + zone_id = var.cloudflare_zone_id +} + +output "lilith_tunnel_id" { + value = cloudflare_zero_trust_tunnel_cloudflared.lilith.id +} + +output "lilith_tunnel_secret" { + value = random_bytes.lilith_tunnel_secret.base64 + sensitive = true +} + +output "lilith_tunnel_hostname" { + value = "lilith.akimo.dev" +} diff --git a/terraform/main.tf b/terraform/main.tf index 4bbeed5..08f6d1c 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -16,7 +16,10 @@ terraform { required_providers { cloudflare = { source = "cloudflare/cloudflare" - } + } + random = { + source = "hashicorp/random" + } } }