diff --git a/machines/congenital-optimist/configuration.nix b/machines/congenital-optimist/configuration.nix index b511564..8b2bc00 100644 --- a/machines/congenital-optimist/configuration.nix +++ b/machines/congenital-optimist/configuration.nix @@ -9,6 +9,9 @@ ./hardware-configuration.nix ../../modules/network/network-congenital-optimist.nix + # Security modules + ../../modules/security/ssh-keys.nix + # System modules ../../modules/system/fonts.nix ../../modules/system/applications.nix diff --git a/machines/sleeper-service/configuration.nix b/machines/sleeper-service/configuration.nix index c12f2e6..9f5b4de 100644 --- a/machines/sleeper-service/configuration.nix +++ b/machines/sleeper-service/configuration.nix @@ -2,6 +2,13 @@ imports = [ ./hardware-configuration.nix ../../modules/network/network-sleeper-service.nix + + # Security modules + ../../modules/security/ssh-keys.nix + + # User modules + ../../modules/users/geir.nix + ../../modules/users/sma.nix ]; # Boot configuration diff --git a/modules/security/ssh-keys.nix b/modules/security/ssh-keys.nix new file mode 100644 index 0000000..dc6623a --- /dev/null +++ b/modules/security/ssh-keys.nix @@ -0,0 +1,97 @@ +# SSH Key Management Module +# Two-key strategy: admin (sma) and development (geir) +{ config, pkgs, lib, ... }: + +{ + # Global SSH daemon configuration + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + PermitRootLogin = "no"; + PubkeyAuthentication = true; + }; + + # Use modern, secure algorithms only + extraConfig = '' + PubkeyAcceptedKeyTypes ssh-ed25519,ssh-ed25519-cert-v01@openssh.com + KexAlgorithms curve25519-sha256@libssh.org + Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com + MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com + ''; + }; + + # Centralized SSH key management + security.ssh-keys = { + # Admin keys for sma user (server administration) + admin = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPgzKS1N7+7+N1/8U8++1pl4hapDm6TOy0QhrfrYA8mz geir@geokkjer.eu-admin" + ]; + + # Development keys for geir user (git, daily use) + development = [ + # Current key (keep for continuity during transition) + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHeOvTHIw+hZOAiWkIrz9t11UeGwxAMx7jN/1IIdgq7O geokkjer@gmail.com" + # New development key + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHukJK0Kc1YexvzF8PdqaqWNZdVffGoM6ePPMecrU6dM geir@geokkjer.eu-dev" + ]; + }; + + # SSH client configuration + programs.ssh = { + enable = true; + extraConfig = '' + # Default to development key for daily use + Host * + IdentityFile ~/.ssh/id_ed25519_dev + AddKeysToAgent yes + ServerAliveInterval 60 + ServerAliveCountMax 3 + + # Admin access to servers (use sma user) + Host admin-* *.admin + User sma + IdentityFile ~/.ssh/id_ed25519_admin + + # Git services (use geir user with dev key) + Host git.* github.com gitlab.com + User git + IdentityFile ~/.ssh/id_ed25519_dev + + # Home lab servers (geir user for development access) + Host sleeper-service sleeper-service.home 10.0.0.8 + User geir + IdentityFile ~/.ssh/id_ed25519_dev + + Host grey-area grey-area.home 10.0.0.11 + User geir + IdentityFile ~/.ssh/id_ed25519_dev + + Host reverse-proxy reverse-proxy.home 10.0.0.12 + User geir + IdentityFile ~/.ssh/id_ed25519_dev + + # Admin access to servers (when needed) + Host admin-sleeper sleeper-service.admin + Hostname 10.0.0.8 + User sma + IdentityFile ~/.ssh/id_ed25519_admin + + Host admin-grey grey-area.admin + Hostname 10.0.0.11 + User sma + IdentityFile ~/.ssh/id_ed25519_admin + + Host admin-reverse reverse-proxy.admin + Hostname 10.0.0.12 + User sma + IdentityFile ~/.ssh/id_ed25519_admin + + # Tailscale network + Host 100.* *.tail* + User geir + IdentityFile ~/.ssh/id_ed25519_dev + ''; + }; +} diff --git a/modules/users/geir.nix b/modules/users/geir.nix index f4118a9..6ac35c2 100644 --- a/modules/users/geir.nix +++ b/modules/users/geir.nix @@ -21,6 +21,12 @@ shell = pkgs.zsh; + # SSH access with development keys + openssh.authorizedKeys.keys = config.security.ssh-keys.development or [ + # Fallback to current key during transition + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHeOvTHIw+hZOAiWkIrz9t11UeGwxAMx7jN/1IIdgq7O geokkjer@gmail.com" + ]; + # User-specific packages packages = with pkgs; [ # Browsers & Communication diff --git a/modules/users/sma.nix b/modules/users/sma.nix index a5223ae..9ba29be 100644 --- a/modules/users/sma.nix +++ b/modules/users/sma.nix @@ -22,9 +22,8 @@ shell = pkgs.zsh; # SSH key-based authentication only (no password login) - openssh.authorizedKeys.keys = [ - # Add SSH public key here when ready - # "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5... sma@home-lab" + openssh.authorizedKeys.keys = config.security.ssh-keys.admin or [ + # Admin keys will be populated from security module ]; # Essential admin packages diff --git a/plan.md b/plan.md index d8ec657..ee317d5 100644 --- a/plan.md +++ b/plan.md @@ -266,18 +266,19 @@ Home-lab/ - **10.0.0.8**: sleeper-service (Intel Xeon file server - rename from files.home) - **10.0.0.11**: grey-area (planned application server) - **10.0.0.12**: reverse-proxy (planned edge server) - - **10.0.0.14**: pi.hole (Pi-hole DNS/ad-blocker) - - **10.0.0.90**: wordpresserver.home (existing WordPress server) - - **10.0.0.117**: webdev.home (existing web development server) - - **10.0.0.138**: lan.home (router/gateway) + - **10.0.0.14**: pi.hole (Pi-hole DNS/ad-blocker) maybe move to nixos + - **10.0.0.90**: wordpresserver.home (existing WordPress server) to be deleted, incus container + - **10.0.0.117**: webdev.home (existing web development server) to be deleted, incus container + - **10.0.0.138**: lan.home (router/gateway/dhcp) - **Tailscale Network (100.x.x.x/10)**: - **100.109.28.53**: congenital-optimist (current machine) - **100.119.86.92**: apps (active server) (rename to grey area) - **100.114.185.71**: arlaptop (laptop) (Arch Linux with plans to migrate to NixOS) - - **100.81.15.84**: files (file server) + - **100.81.15.84**: files (file server rename to sleeper-service ) - **100.103.143.108**: pihole (DNS server) - **100.96.189.104**: vps1 (external VPS) (rename to reverse proxy) - - **100.126.202.40**: wordpresserver (WordPress) + - **100.126.202.40**: wordpresserver (WordPress) to be deleted + - remind user to update tailsce or find a way to use the cli to do this - [ ] **VLAN planning**: Consider network segmentation for different service types - [ ] **DNS configuration**: Plan local DNS resolution for internal services @@ -377,9 +378,18 @@ Home-lab/ ### 5.3 Security & Networking - [x] **systemd-networkd migration**: Completed for sleeper-service with static IP configuration +- [x] **SSH key management centralization**: Implemented two-key strategy + - **Admin key** (`geir@geokkjer.eu-admin`): For sma user, server administration access + - **Development key** (`geir@geokkjer.eu-dev`): For geir user, git services, daily development + - **NixOS module**: `modules/security/ssh-keys.nix` centralizes key management + - **SSH client config**: Updated with role-based host patterns and key selection + - **Security benefits**: Principle of least privilege, limited blast radius if compromised + - **Usage examples**: + - `ssh geir@sleeper-service.home` - Uses dev key automatically + - `ssh admin-sleeper` - Uses admin key for sma user access + - `git clone git@github.com:user/repo` - Uses dev key for git operations - [ ] VPN configuration (Tailscale expansion) - [ ] Firewall rules standardization across machines -- [ ] SSH key management centralization - [ ] Certificate management (Let's Encrypt) - [ ] Network segmentation planning (VLANs for services vs. user devices) - [ ] DNS infrastructure (local DNS server for service discovery) diff --git a/scripts/setup-ssh-keys.sh b/scripts/setup-ssh-keys.sh new file mode 100755 index 0000000..f0b830b --- /dev/null +++ b/scripts/setup-ssh-keys.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# SSH Key Generation Script - Two-Key Strategy +# Generates admin and development SSH keys + +set -euo pipefail + +SSH_DIR="$HOME/.ssh" +HOSTNAME="$(hostname)" +EMAIL_BASE="geir@geokkjer.eu" + +echo "🔑 Setting up SSH keys for $HOSTNAME" +echo "📧 Using email base: $EMAIL_BASE" + +# Create SSH directory if it doesn't exist +mkdir -p "$SSH_DIR" +chmod 700 "$SSH_DIR" + +# Backup existing key if it exists +if [[ -f "$SSH_DIR/id_ed25519" ]]; then + echo "💾 Backing up existing key to id_ed25519.backup" + cp "$SSH_DIR/id_ed25519" "$SSH_DIR/id_ed25519.backup" + cp "$SSH_DIR/id_ed25519.pub" "$SSH_DIR/id_ed25519.pub.backup" +fi + +echo "" +echo "🔐 Generating two SSH keys:" +echo " 1. Admin key (for sma user, server administration)" +echo " 2. Development key (for geir user, git, daily use)" +echo "" + +# Generate admin key +ADMIN_KEY="$SSH_DIR/id_ed25519_admin" +if [[ ! -f "$ADMIN_KEY" ]]; then + echo "🔐 Generating admin key..." + ssh-keygen -t ed25519 -f "$ADMIN_KEY" -C "$EMAIL_BASE-admin" -N "" + chmod 600 "$ADMIN_KEY" + chmod 644 "$ADMIN_KEY.pub" + echo "✅ Generated: $ADMIN_KEY" +else + echo "⏭️ Admin key already exists" +fi + +# Generate development key +DEV_KEY="$SSH_DIR/id_ed25519_dev" +if [[ ! -f "$DEV_KEY" ]]; then + echo "🔐 Generating development key..." + ssh-keygen -t ed25519 -f "$DEV_KEY" -C "$EMAIL_BASE-dev" -N "" + chmod 600 "$DEV_KEY" + chmod 644 "$DEV_KEY.pub" + echo "✅ Generated: $DEV_KEY" +else + echo "⏭️ Development key already exists" +fi + +echo "" +echo "🎯 Next steps:" +echo "1. Add these public keys to your NixOS configuration:" +echo "2. Deploy updated configuration to target servers" +echo "3. Test SSH access with both keys" +echo "4. Update external Git services with new development key" +echo "" + +echo "📋 Public keys to add to NixOS configuration:" +echo "" + +if [[ -f "$ADMIN_KEY.pub" ]]; then + echo "# Admin key (add to security.ssh-keys.admin in modules/security/ssh-keys.nix)" + echo "\"$(cat "$ADMIN_KEY.pub")\"" + echo "" +fi + +if [[ -f "$DEV_KEY.pub" ]]; then + echo "# Development key (add to security.ssh-keys.development in modules/security/ssh-keys.nix)" + echo "\"$(cat "$DEV_KEY.pub")\"" + echo "" +fi + +echo "💡 Usage examples:" +echo " ssh geir@sleeper-service.home # Uses dev key automatically" +echo " ssh admin-sleeper # Uses admin key for sma user" +echo " git clone git@github.com:user/repo # Uses dev key for git" +echo "" + +echo "🔄 To update your Git remotes with the new key:" +echo " # Add new key to GitHub/GitLab first, then:" +echo " ssh -T git@github.com # Test the connection" +echo "" + +echo "✅ SSH key setup complete!"