Compare commits

..

No commits in common. "3e5ebafed6435f47ed2e8dae3b87e45ae086d56b" and "0359491756e19f18f30096ead9c18abd5c2049e9" have entirely different histories.

35 changed files with 308 additions and 751 deletions

View File

@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1716431128,
"narHash": "sha256-t3T8HlX3udO6f4ilLcN+j5eC3m2gqsouzSGiriKK6vk=",
"lastModified": 1715756862,
"narHash": "sha256-cNGZK/RNvb29giR2KtnbwU5lx2Kw+wWqAaeWqfYlPts=",
"owner": "nix-community",
"repo": "disko",
"rev": "7ffc4354dfeb37c8c725ae1465f04a9b45ec8606",
"rev": "cb1d6fba694ab3887600d606106f5a044ba1712c",
"type": "github"
},
"original": {
@ -27,11 +27,11 @@
]
},
"locked": {
"lastModified": 1716448020,
"narHash": "sha256-u1ddoBOILtLVX4NYzqSZ9Qaqusql1M4reLd1fs554hY=",
"lastModified": 1715486357,
"narHash": "sha256-4pRuzsHZOW5W4CsXI9uhKtiJeQSUoe1d2M9mWU98HC4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "25dedb0d52c20448f6a63cc346df1adbd6ef417e",
"rev": "44677a1c96810a8e8c4ffaeaad10c842402647c1",
"type": "github"
},
"original": {
@ -40,29 +40,14 @@
"type": "github"
}
},
"impermanence": {
"locked": {
"lastModified": 1708968331,
"narHash": "sha256-VUXLaPusCBvwM3zhGbRIJVeYluh2uWuqtj4WirQ1L9Y=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "a33ef102a02ce77d3e39c25197664b7a636f9c30",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "impermanence",
"type": "github"
}
},
"nix-secrets": {
"flake": false,
"locked": {
"lastModified": 1716456952,
"narHash": "sha256-fd57j4M++Fte1hrRZkDIqGbYbimqPNmERlFr/Fbh1Ek=",
"lastModified": 1715783829,
"narHash": "sha256-aNuuTd4nXt9SxYLgJSgBxuvIBmAyh5+2IT2iLepZKds=",
"ref": "refs/heads/master",
"rev": "f5abdf254dbee888be5f65c96a4a571f2a91da91",
"revCount": 28,
"rev": "450e494f36a74c0786d1cb01db46731b01b713dc",
"revCount": 5,
"type": "git",
"url": "ssh://git@git.bitlab21.com/sam/nix-secrets.git"
},
@ -85,11 +70,11 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1716061101,
"narHash": "sha256-H0eCta7ahEgloGIwE/ihkyGstOGu+kQwAiHvwVoXaA0=",
"lastModified": 1715458492,
"narHash": "sha256-q0OFeZqKQaik2U8wwGDsELEkgoZMK7gvfF6tTXkpsqE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e7cc61784ddf51c81487637b3031a6dd2d6673a2",
"rev": "8e47858badee5594292921c2668c11004c3b0142",
"type": "github"
},
"original": {
@ -101,11 +86,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1716330097,
"narHash": "sha256-8BO3B7e3BiyIDsaKA0tY8O88rClYRTjvAp66y+VBUeU=",
"lastModified": 1715534503,
"narHash": "sha256-5ZSVkFadZbFP1THataCaSf0JH2cAH3S29hU9rrxTEqk=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "5710852ba686cc1fd0d3b8e22b3117d43ba374c2",
"rev": "2057814051972fa1453ddfb0d98badbea9b83c06",
"type": "github"
},
"original": {
@ -119,7 +104,6 @@
"inputs": {
"disko": "disko",
"home-manager": "home-manager",
"impermanence": "impermanence",
"nix-secrets": "nix-secrets",
"nixpkgs": "nixpkgs",
"nixpkgs-unstable": "nixpkgs-unstable",
@ -134,11 +118,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1716400300,
"narHash": "sha256-0lMkIk9h3AzOHs1dCL9RXvvN4PM8VBKb+cyGsqOKa4c=",
"lastModified": 1715482972,
"narHash": "sha256-y1uMzXNlrVOWYj1YNcsGYLm4TOC2aJrwoUY1NjQs9fM=",
"owner": "mic92",
"repo": "sops-nix",
"rev": "b549832718b8946e875c016a4785d204fcfc2e53",
"rev": "b6cb5de2ce57acb10ecdaaf9bbd62a5ff24fa02e",
"type": "github"
},
"original": {

View File

@ -17,10 +17,6 @@
inputs.nixpkgs.follows = "nixpkgs";
};
impermanence = {
url = "github:nix-community/impermanence";
};
# Secrets management
sops-nix = {
url = "github:mic92/sops-nix";
@ -38,7 +34,6 @@
nixpkgs,
home-manager,
disko,
#impermanence,
...
} @ inputs:
let
@ -78,18 +73,11 @@
bootstrap = nixpkgs.lib.nixosSystem {
inherit specialArgs;
modules = [
disko.nixosModules.disko
./hosts/common/disks/gpt-bios-compact.nix
./hosts/bootstrap
];
};
sparky = nixpkgs.lib.nixosSystem {
inherit specialArgs;
modules = [
./hosts/sparky
home-manager.nixosModules.home-manager{
home-manager.extraSpecialArgs = specialArgs;
}
];
};
};
# # Standalone home-manager configuration entrypoint

View File

@ -1,6 +1,5 @@
{ config, lib, pkgs, outputs, ... }:
{ pkgs, ... }:
{
imports = [
./zsh.nix
] ;
}

View File

@ -1,23 +0,0 @@
{ pkgs, config, ... }: {
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
shellAliases = {
ll = "ls -l";
};
history.size = 10000;
history.path = "${config.xdg.dataHome}/zsh/history";
initExtra = ''
bindkey -v
bindkey "^H" backward-delete-char
bindkey "^?" backward-delete-char
set -o vi
export TERM=xterm
'';
};
}

View File

@ -1,10 +1,8 @@
{ inputs, config, osConfig, ... }:
{ inputs, config, ... }:
let
secretsDirectory = builtins.toString inputs.nix-secrets;
secretsFile = "${secretsDirectory}/secrets.yaml";
homeDirectory = config.home.homeDirectory;
username = config.home.username;
hostname = osConfig.networking.hostName;
in
{
imports = [
@ -12,10 +10,18 @@ in
];
sops = {
age.sshKeyPaths = ["${homeDirectory}/.ssh/id_ed25519"];
age.keyFile = "${homeDirectory}/.config/sops/age/keys.txt";
defaultSopsFile = "${secretsFile}";
validateSopsFiles = false;
secrets = {
"ssh_keys/sam/gitea" = {
path = "${homeDirectory}/.ssh/gitea";
};
"ssh_keys/sam/gitea.pub" = {
path = "${homeDirectory}/.ssh/gitea.pub";
};
};
};
}

View File

@ -5,13 +5,12 @@
...
}: {
imports = [
# Import users
./users/admin
./common/core
./common/optional/sops.nix
# Import optional
./common/optional/git.nix
# Import users
./users/admin
];

View File

@ -5,9 +5,6 @@
...
}: {
imports = [
# Import users
./users/sam
./common/core
./common/optional/desktop/hyprland
./common/optional/desktop/waybar.nix
@ -15,6 +12,9 @@
# Import optional
./common/optional/git.nix
# Import users
./users/sam
];
# ------

View File

@ -1,18 +0,0 @@
{
pkgs,
config,
lib,
...
}: {
imports = [
# Import users
./users/media
./common/core
./common/optional/sops.nix
# Import optional
./common/optional/git.nix
];
}

View File

@ -11,6 +11,28 @@
home.packages = [
];
programs.zsh = {
enable = true;
enableCompletion = true;
autosuggestion.enable = true;
syntaxHighlighting.enable = true;
shellAliases = {
ll = "ls -l";
};
history.size = 10000;
history.path = "${config.xdg.dataHome}/zsh/history";
initExtra = ''
bindkey -v
bindkey "^H" backward-delete-char
bindkey "^?" backward-delete-char
set -o vi
export TERM=xterm
'';
};
home.file = {
};

View File

@ -1,39 +0,0 @@
{ config, pkgs, lib, outputs, inputs, ... }:
{
home.username = "media";
home.homeDirectory = "/home/media";
home.stateVersion = "23.11";
imports = [
inputs.impermanence.nixosModules.home-manager.impermanence
] ++ (builtins.attrValues outputs.homeManagerModules); # import all homeManagerModules?
xdg.userDirs = {
enable = true;
createDirectories = false;
desktop = "/home/media/Desktop";
documents = null;
download = null;
music = null;
pictures = null;
publicShare = null;
templates = null;
videos = null;
};
home.packages = [
];
home.file = {
};
home.sessionPath = [
];
home.sessionVariables = {
};
programs.home-manager.enable = true;
}

View File

@ -16,7 +16,29 @@
pkgs.xfce.thunar
#pkgs.age
];
programs.zsh = {
enable = true;
enableCompletion = true;
programs.zsh.autosuggestion.enable = true;
syntaxHighlighting.enable = true;
shellAliases = {
ll = "ls -l";
};
history.size = 10000;
history.path = "${config.xdg.dataHome}/zsh/history";
initExtra = ''
bindkey -v
bindkey "^H" backward-delete-char
bindkey "^?" backward-delete-char
set -o vi
export TERM=xterm
'';
};
home.file = {
".icons/bibata".source = "${pkgs.bibata-cursors}/share/icons/Bibata-Modern-Classic";
};
@ -49,5 +71,6 @@
IMAGE_EDITOR="";
};
programs.home-manager.enable = true;
}

View File

@ -1,103 +1,89 @@
{ inputs, config, lib, pkgs, outputs,... }:
let
pubKeys = lib.filesystem.listFilesRecursive (../common/users/keys);
in
{ lib, pkgs, configLib, configVars, ... }:
{
imports =
[
# Disk configuration
inputs.disko.nixosModules.disko
(import ../common/disks/std-disk-config.nix { device = "/dev/vda"; })
../common/optional/btrfs-impermanence.nix
inputs.impermanence.nixosModules.impermanence
imports = [
# Import core options
./hardware-configuration.nix
../common/core
];
nixpkgs = {
overlays = [
outputs.overlays.additions
outputs.overlays.modifications
outputs.overlays.unstable-packages
];
config = {
allowUnfree = true;
};
};
# Import optional options
# ../common/optional/openssh
fileSystems."/persist".neededForBoot = true;
environment.persistence."/persist" = {
hideMounts = true;
directories = [
"/etc/nixos"
];
files = [
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
"/etc/ssh/deploy_key-ssh-ed25519"
];
};
# Create users for this host
../common/users/admin
];
boot = {
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
timeout = 3;
#virtualisation.virtualbox.guest.enable = true;
virtualisation.libvirtd = {
qemu = {
package = pkgs.qemu_kvm; # only emulates host arch, smaller download
swtpm.enable = true; # allows for creating emulated TPM
ovmf.packages = [(pkgs.OVMF.override {
secureBoot = true;
tpmSupport = true;
}).fd]; # or use pkgs.OVMFFull.fd, which enables more stuff
};
};
#fileSystems."/boot".options = ["umask=0077"]; # Removes permissions and security warnings.
#boot.loader.efi.canTouchEfiVariables = true;
#boot.loader.grub.device = "/dev/vda";
boot.loader.grub.enable = true;
# boot.loader.systemd-boot = {
# enable = true;
# # we use Git for version control, so we don't need to keep too many generations.
# # FIXME lower this even more after testing complete
# configurationLimit = lib.mkDefault 10;
# # pick the highest resolution for systemd-boot's console.
# consoleMode = lib.mkDefault "max";
# };
boot.initrd.systemd.enable = true;
users = {
mutableUsers = true;
extraUsers = {
root = {
initialPassword = "1234";
openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
};
};
i18n.defaultLocale = "en_GB.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "uk";
useXkbConfig = false;
};
networking = {
hostName = "bootstrap";
networkmanager.enable = true;
enableIPv6 = false;
};
services.openssh = {
enable = true;
ports = [22];
authorizedKeysFiles = lib.mkForce ["/etc/ssh/authorized_keys.d/%u"];
hostKeys = [{
path = "/persist/etc/ssh/ssh_host_ed25519_key";
type = "ed25519";
}];
settings = {
PasswordAuthentication = false;
PermitRootLogin = "yes";
PubKeyAuthentication = "yes";
StreamLocalBindUnlink = "yes";
UsePAM = true;
services = {
qemuGuest.enable = true;
openssh = {
enable = true;
ports = [22]; # FIXME: Make this use configVars.networking
settings.PermitRootLogin = "yes";
# Fix LPE vulnerability with sudo use SSH_AUTH_SOCK: https://github.com/NixOS/nixpkgs/issues/31611
# this mitigates the security issue caused by enabling u2fAuth in pam
authorizedKeysFiles = lib.mkForce ["/etc/ssh/authorized_keys.d/%u"];
};
};
programs.ssh.extraConfig = ''
Host git.bitlab21.com
IdentitiesOnly yes
StrictHostKeyChecking no
IdentityFile /etc/ssh/deploy_key-ssh-ed25519
'';
security.pam = {
sshAgentAuth.enable = true;
#FIXME the above is deprecated in 24.05 but we will wait until release
#sshAgentAuth.enable = true;
services = {
sudo.u2fAuth = true;
};
};
networking.firewall.allowedTCPPorts = [ 22 ];
services = {
qemuGuest.enable = true;
# ssh-agent is used to pull my private secrets repo from gitlab when deploying nix-config.
# programs.ssh.startAgent = true;
environment.systemPackages = builtins.attrValues {
inherit(pkgs)
wget
curl
git
rsync;
};
nix.settings.experimental-features = [ "nix-command" "flakes" ];
system.stateVersion = "23.11";
}

View File

@ -10,9 +10,17 @@
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.kernelModules = [ "kvm-amd" "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{
};
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

View File

@ -1,8 +1,6 @@
{ pkgs, lib, inputs, config, ...}:
{
{pkgs, ...}: {
imports = [
./sops.nix
./locale.nix
];
environment.systemPackages = [
@ -10,7 +8,6 @@
pkgs.curl
pkgs.just
pkgs.git
pkgs.neovim
];
}

View File

@ -1,8 +0,0 @@
{
i18n.defaultLocale = "en_GB.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "uk";
useXkbConfig = false;
};
}

View File

@ -1,8 +1,8 @@
{ pkgs, inputs, config, username, ... }:
{ pkgs, inputs, config, configVars, ... }:
let
secretsDirectory = builtins.toString inputs.nix-secrets;
secretsFile = "${secretsDirectory}/secrets.yaml";
homeDirectory = "/home/${configVars.username}";
in
{
imports = [
@ -15,12 +15,8 @@ in
age = {
sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
};
secrets = {
"passwords/root".neededForUsers = true;
"ssh_keys/deploy_key/id_ed25519" = {
path = "/etc/ssh/deploy_key-ssh-ed25519";
};
keyFile = "/var/lib/sops-nix/key.txt";
generateKey = true;
};
};
}

View File

@ -1,63 +0,0 @@
{
disko.devices = {
disk = {
vdb = {
type = "disk";
device = "/dev/vdb";
content = {
type = "gpt";
partitions = {
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
keyFile = "/tmp/secret.key";
};
additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [ "compress=zstd" "noatime" ];
};
"/home" = {
mountpoint = "/home";
mountOptions = [ "compress=zstd" "noatime" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" ];
};
"/swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "20M";
};
};
};
};
};
};
};
};
};
};
}

View File

@ -1,9 +1,11 @@
{device ? throw "Must define a device, e.g. /dev/sda"}:
{
disko.devices = {
disk.main = {
inherit device;
disk = {
#FIXME change to proper device or make dynamic like figdetingbits
sda = {
type = "disk";
# FIXME change to proper device or make dynamic like figdetingbits
device = "/dev/sda";
content = {
type = "gpt";
partitions = {
@ -19,38 +21,25 @@
mountpoint = "/boot";
};
};
root = {
name = "root";
size = "100%";
content = {
type = "lvm_pv";
vg = "root_vg";
};
};
};
};
};
lvm_vg = {
root_vg = {
type = "lvm_vg";
lvs = {
root = {
size = "100%FREE";
content = {
type = "btrfs";
extraArgs = ["-f"];
root = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ]; # Override existing partition
# Subvolumes must set a mountpoint in order to be mounted,
# unless their parent is mounted
subvolumes = {
"/root" = {
mountpoint = "/";
};
"/persist" = {
mountOptions = [ "subvol=persist" ];
mountOptions = [ "compress=zstd" ];
mountpoint = "/persist";
};
"/nix" = {
mountOptions = [ "subvol=nix" "noatime" ];
mountOptions = [ "compress=zstd" "noatime" ];
mountpoint = "/nix";
};
@ -62,6 +51,7 @@
};
};
};
};
};
};
};

View File

@ -1,29 +0,0 @@
{lib, ...}:
{
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount /dev/root_vg/root /btrfs_tmp
if [[ -e /btrfs_tmp/root ]]; then
mkdir -p /btrfs_tmp/old_roots
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
fi
delete_subvolume_recursively() {
IFS=$'\n'
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
delete_subvolume_recursively "/btrfs_tmp/$i"
done
btrfs subvolume delete "$1"
}
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
delete_subvolume_recursively "$i"
done
btrfs subvolume create /btrfs_tmp/root
umount /btrfs_tmp
'';
}

View File

@ -1,33 +0,0 @@
{ lib, config, ... }:
let
sshPort = 22;
in
{
services.openssh = {
enable = true;
ports = [ sshPort ];
authorizedKeysFiles = lib.mkForce ["/etc/ssh/authorized_keys.d/%u"];
hostKeys = [{
path = "/persist/etc/ssh/ssh_host_ed25519_key";
type = "ed25519";
}];
settings = {
PasswordAuthentication = false;
PermitRootLogin = "no";
PubKeyAuthentication = "yes";
StreamLocalBindUnlink = "yes";
UsePAM = true;
};
};
security.pam = {
sshAgentAuth.enable = true;
};
programs.ssh.extraConfig = ''
Host git.bitlab21.com
IdentitiesOnly yes
StrictHostKeyChecking no
IdentityFile /etc/ssh/deploy_key-ssh-ed25519
'';
networking.firewall.allowedTCPPorts = [ sshPort ];
}

View File

@ -0,0 +1,22 @@
{ lib, config, ... }:
let
sshPort = 22;
in
{
services.openssh = {
enable = true;
ports = [ sshPort ];
settings = {
# Harden
PasswordAuthentication = true;
PermitRootLogin = "no";
# Automatically remove stale sockets
StreamLocalBindUnlink = "yes";
};
};
networking.firewall.allowedTCPPorts = [ sshPort ];
}

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILywv6g5k5cOVplxgbbStrGf3qYVukgCcd80TJSBM8e8 sam@nixos

View File

@ -1 +0,0 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFc+y7KKEbutJe9u9UPP3rWqchjS7/yrpyoQRd178c7u sam

View File

@ -1,49 +0,0 @@
{ pkgs, inputs, config, lib, ... }:
let
pubKeys = lib.filesystem.listFilesRecursive (../keys);
hostname = config.networking.hostName;
sopsHashedPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."passwords/media".path;
secretsDirectory = builtins.toString inputs.nix-secrets;
secretsFile = "${secretsDirectory}/secrets.yaml";
in
{
users.users.media = {
isNormalUser = true;
shell = pkgs.zsh; # default shell
#hashedPasswordFile = sopsHashedPasswordFile;
password = "nixos";
openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
extraGroups =
[ "qemu-libvirtd" "libvirtd"
"wheel" "video" "audio" "disk" "networkmanager"
];
};
sops.secrets."passwords/media" = {
sopsFile = "${secretsFile}";
neededForUsers = true;
};
sops.secrets."ssh_keys/media/id_ed25519" = {
path = "/home/media/.ssh/id_ed25519";
};
sops.secrets."ssh_keys/media/id_ed25519.pub" = {
path = "/home/media/.ssh/id_ed25519.pub";
};
programs.zsh.enable = true;
programs.fuse.userAllowOther = true;
home-manager = {
extraSpecialArgs = { inherit inputs; };
users = {
media = import ../../../../home/${hostname}.nix;
};
};
environment.systemPackages = [
];
}

View File

@ -1,18 +1,14 @@
{ pkgs, inputs, config, lib, ... }:
let
hostname = config.networking.hostName;
pubKeys = lib.filesystem.listFilesRecursive (../keys);
sopsHashedPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."passwords/sam".path;
secretsDirectory = builtins.toString inputs.nix-secrets;
secretsFile = "${secretsDirectory}/secrets.yaml";
hostname = config.networking.hostName;
in
{
users.users.sam = {
mutableUsers = true;
isNormalUser = true;
#password = "nixos"; # Overridden if sops is working
shell = pkgs.zsh; # default shell
initialPassword = "nixos";
hashedPasswordFile = sopsHashedPasswordFile;
openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
extraGroups = [
@ -24,13 +20,9 @@ in
};
sops.secrets."passwords/sam" = {
sopsFile = "${secretsFile}";
neededForUsers = true;
};
programs.zsh.enable = true;
#home-manager.users.sam =
home-manager = {
extraSpecialArgs = { inherit inputs; };
users = {

View File

@ -41,6 +41,13 @@
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "uk";
useXkbConfig = false;
};
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;

32
hosts/media/default.nix Normal file
View File

@ -0,0 +1,32 @@
{ inputs, config, lib, pkgs, outputs,... }:
{
imports =
[
# Import core options
./hardware-configuration.nix
../common/core
# Import optional options
../common/optional/pipewire.nix
../common/optional/hyprland.nix
../common/optional/displayManager/sddm.nix
../common/optional/openssh
# Create users for this host
../common/users/sam
];
nixpkgs = {
overlays = [
outputs.overlays.additions
outputs.overlays.modifications
outputs.overlays.unstable-packages
];
config = {
allowUnfree = true;
};
};
nix.settings.experimental-features = [ "nix-command" "flakes" ];

View File

@ -11,7 +11,7 @@
../common/optional/pipewire.nix
../common/optional/hyprland.nix
../common/optional/displayManager/sddm.nix
../common/optional/openssh.nix
../common/optional/openssh
# Create users for this host
../common/users/sam
@ -42,6 +42,13 @@
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "uk";
useXkbConfig = false;
};
services.printing.enable = true;
services.libinput.enable = true;

View File

@ -1,107 +0,0 @@
{ inputs, config, lib, pkgs, outputs,... }:
let
sopsHashedPasswordFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."passwords/root".path;
secretsDirectory = builtins.toString inputs.nix-secrets;
secretsFile = "${secretsDirectory}/secrets.yaml";
in
{
imports =
[
# Disk configuration
inputs.disko.nixosModules.disko
(import ../common/disks/std-disk-config.nix { device = "/dev/vda"; })
../common/optional/btrfs-impermanence.nix
inputs.impermanence.nixosModules.impermanence
# Create users for this host
../common/users/media
# Import core options
./hardware-configuration.nix
../common/core
# Import optional options
../common/optional/openssh.nix
];
nixpkgs = {
overlays = [
outputs.overlays.additions
outputs.overlays.modifications
outputs.overlays.unstable-packages
];
config = {
allowUnfree = true;
};
};
fileSystems."/persist".neededForBoot = true;
environment.persistence."/persist" = {
hideMounts = true;
directories = [
"/etc/nixos"
"/var/log"
"/var/lib/nixos"
"/var/lib/systemd/coredump"
"/etc/NetworkManager/system-connections"
];
files = [
"/etc/ssh/ssh_host_ed25519_key"
"/etc/ssh/ssh_host_ed25519_key.pub"
];
users.media= {
directories = [
"sync"
"keep"
".ssh"
".config/dconf"
".config/cinnamon"
".config/nemo"
];
files = [
];
};
};
users = {
mutableUsers = true;
extraUsers = {
root = {
hashedPasswordFile = sopsHashedPasswordFile;
};
};
};
boot = {
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
timeout = 3;
};
};
networking = {
hostName = "sparky";
networkmanager.enable = true;
enableIPv6 = false;
};
services = {
qemuGuest.enable = true;
};
#services.libinput.enable = true;
#services.displayManager.defaultSession = "cinnamon";
# services.xserver = {
# enable = true;
# displayManager.lightdm.enable = true;
# desktopManager = {
# cinnamon.enable = true;
# };
# };
#
nix.settings.experimental-features = [ "nix-command" "flakes" ];
system.stateVersion = "23.11";
}

View File

@ -1,24 +0,0 @@
# 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 = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
# 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.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@ -4,15 +4,15 @@ SOPS_FILE := "../nix-secrets/secrets.yaml"
default:
@just --list
# fetches from remote and updates flake.lock with latest revisions of nix-secrets for next time a rebuild occurs
update-flake-secrets:
# ensure the latest revisions of nix-secrets are used next time a rebuild occurs
update-nix-secrets:
(cd ../nix-secrets && git fetch && git rebase) || true
nix flake lock --update-input nix-secrets
# full system rebuild from flake (stages changes and automatically detects host)
rebuild-system:
git add *.nix
sudo nixos-rebuild switch --flake .#$(hostname)
sudo nixos-rebuild switch --flake $HOME/nixos#$(hostname)
# updates all flake inputs for system
update-flake:
@ -23,10 +23,9 @@ edit-sops:
echo "Editing {{SOPS_FILE}}"
nix-shell -p sops --run "SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops {{SOPS_FILE}}"
# update keys in secrets.yaml and push to remote
update-sops-secrets:
# update
update-secrets:
cd $HOME/nix-secrets && (\
nix-shell -p sops --run "sops updatekeys -y secrets.yaml" && \
git add -u && (git commit -m "updated secrets" || true) && git push \
)

View File

@ -12,100 +12,87 @@ for the root user.
read -p "Confirm host had been setup using the above steps...(yes|no): " confirm
[ "$confirm" != "yes" ] && echo "Exiting" && exit 0
# Target host details
#cd ~
#read -p "Enter hostname: " hostname
#read -p "Enter username: " username
#read -p "Enter ip address: " ip
#read -p "Enter nixosSystem to build, e.g. 'bootstrap': " config
hostname="bootstrap"
ip="192.168.122.192"
config="bootstrap"
cd ~
read -p "Enter hostname: " hostname
read -p "Enter username: " username
read -p "Enter ip address: " ip
# Generate key name and dir
HOST_KEY_DIR="$HOME/keys/hosts/$hostname"
mkdir -p "$HOST_KEY_DIR"
KEY_DIR="$HOME/keys/$hostname/"
mkdir -p $KEY_DIR
ssh-copy-id -i "$(readlink -n "$HOME/.ssh/gitea.pub" )" "root@$ip"
# Create ssh keys if not exists
echo "Creating '$hostname' ssh keys"
bash "/$HOME/nixos/scripts/generate_ssh_keys.sh" --type "host" --username "root" --hostname "$hostname"
echo "Creating ssh keys for new host. Will create in current directory: "$KEY_DIR
KEY_NAME="ssh_ed25519_key_$hostname"
# Delete key in known hosts if exists
sed -i "/$ip/d" ~/.ssh/known_hosts
KNOWN_HOSTS=$(grep "$ip" ~/.ssh/known_hosts)
confirm_delete=""
# Authorise source public key
echo "Copying pubkey to target host"
ssh-copy-id -i "$(readlink -f "$HOME/.ssh/id_ed25519.pub")" "root@$ip"
[ "$KNOWN_HOSTS" != "" ] && echo -e "Host found in: ~/.ssh/known_hosts\n\n$KNOWN_HOSTS\n" && read -p "Delete existing hosts from ~/.ssh/known_hosts? (yes|no) " confirm_delete
[ "$confirm_delete" = "yes" ] && sed -i "/$ip/d" ~/.ssh/known_hosts
# Generate age key from target host and user public ssh key
echo "Generating age key from target host and user ssh key"
nix-shell -p ssh-to-age --run "cat $HOST_KEY_DIR/ssh_host_ed25519_key.pub | ssh-to-age > $HOST_KEY_DIR/age_host_key"
HOST_AGE_KEY=$(cat "$HOST_KEY_DIR/age_host_key")
echo -e "Host age key:\n$HOST_AGE_KEY\n"
echo "These keys needs to be inserted into .sops.yaml file. This will be prompted again later."
overwrite=""
[ -f "$KEY_DIR/$KEY_NAME" ] && read -p "Key exists, would you like to overwrite it? (yes|no) " overwrite
# Create temp directory for ssh keys to be copied to host:
temp=$(mktemp -d)
[ "$overwrite" == "yes" ] && ssh-keygen -t ed25519 -f "$KEY_DIR/$KEY_NAME" -C "$hostname@$ip" -N ""
# Function to cleanup temporary directory on exit
cleanup() {
rm -rf "$temp"
}
trap cleanup EXIT
echo "Copying ssh key to target host:"
# Rsync currently not available in Nixos. Use scp instead.
#rsync -av "ssh_ed25519_key_$hostname"* "root@$ip:/etc/ssh/"
scp -i "$KEY_DIR/ssh_ed25519_key_$hostname"* "root@$ip:/etc/ssh/"
[ $? != 0 ] && echo "Error copying keys to target host" && exit 1
# Create the directory where sshd expects to find the host keys
install -d -m755 "$temp/persist/etc/ssh"
echo "Generating age key from ssh key"
nix-shell -p ssh-to-age --run "cat $KEY_DIR/$KEY_NAME.pub | ssh-to-age > $KEY_DIR/age_key_$hostname"
[ $? != 0 ] && echo "Error generating age key" && exit 1
cat "$HOST_KEY_DIR/ssh_host_ed25519_key" > "$temp/persist/etc/ssh/ssh_host_ed25519_key"
cat "$HOST_KEY_DIR/ssh_host_ed25519_key.pub" > "$temp/persist/etc/ssh/ssh_host_ed25519_key.pub"
AGE_KEY=$(cat "$KEY_DIR/age_key_$hostname")
chmod 600 "$temp/persist/etc/ssh/ssh_host_ed25519_key"
chmod 644 "$temp/persist/etc/ssh/ssh_host_ed25519_key.pub"
echo -e "Age key:\n$AGE_KEY\n"
echo "This needs to be inserted into .sops.yaml file."
# Install Nixos to target
# Install Nixos bootstrap
cd "$HOME/nixos"
git add . && git commit -m "auto: bootstrapping $hostname" && git push
[ $? != 0 ] && echo "Error commiting current changes" && exit 1
SHELL=/bin/sh nix run github:nix-community/nixos-anywhere -- --extra-files "$temp" --flake .#"$config" root@"$ip" -i "$HOME/.ssh/id_ed25519"
SHELL=/bin/sh nix run github:nix-community/nixos-anywhere -- --flake .#bootstrap root@"$ip" -i "$KEY_DIR/ssh_ed25519_key_$hostname"
[ $? != 0 ] && echo "Error installing Nixos" && exit 1
## Delete keys from local known_hosts
echo "Deleting host from known_hosts"
sed -i "/$ip/d" ~/.ssh/known_hosts
# Check host OS has booted (and not booted back into live cd)
while true;
do
read -p "Confirm live CD has been removed... (yes|no): " confirm
read -p "Confirm live CD has been removed... (yes|no)" confirm
[ "$confirm" = "yes" ] && break
done
echo "Waiting for $ip to come back online and port 22 to be open..."
while ! ping -c 1 $ip &> /dev/null || ! nc -zvw3 $ip 22 &> /dev/null
do
echo "$ip is still offline or port 22 is not open. Checking again in 5 seconds..."
sleep 5
done
echo "$ip is now online and port 22 is open!"
# Authorise source public key
echo "Copying pubkey to target host"
ssh-copy-id -i "$(readlink -f "$HOME/.ssh/id_ed25519.pub")" "root@$ip"
echo "Configuring ssh keys on target host to enable connection to gitea:"
ssh-copy-id -i "$HOME/.ssh/gitea.pub" "$username@$ip"
read -r -d '' config << EOM
Host git.bitlab21.com
IdentitiesOnly yes
StrictHostKeyChecking no
IdentityFile ~/.ssh/gitea
EOM
# Copy deploy_key to target for personal repo authorisation
scp -i "$(readlink -f "$HOME/.ssh/id_ed25519")" "$(readlink -f "$HOME/.ssh/deploy_key-ssh-ed25519")" "root@$ip:/persist/etc/ssh/deploy_key-ssh-ed25519"
# Append the string to file on target machine
echo "$config" | ssh "$username@$ip" 'mkdir -p ~/.ssh/ && cat > ~/.ssh/config'
echo -e "
Complete!
Now add the new target host age key to .sops.yaml. This is needed to enable the
new host to decrypt the secrets.yaml file from the ssh key we generated
previously.
Enter the details as following:
Now add the age key to .sops.yaml, like this:
keys:
- &hosts:
- &$hostname $HOST_AGE_KEY
- &$hostname $AGE_KEY
creation_rules:
- path_regex: secrets.yaml$
@ -113,16 +100,13 @@ creation_rules:
- age:
- *$hostname
Then update (i.e. re-encrypt) the secrets.yaml file with the new keys, run:
'sops --config .sops.yaml updatekeys secrets.yaml'
or with just:
'just update-sops-secrets'
Then commit and push these changes to remote so they can be accessed on the new
host.
Then to update the keys for the secrets.yaml file, run:
'sops --config .sops.yaml updatekeys secrets.yaml'
or with nix-shell:
'nix-shell -p sops --run 'sops --config .sops.yaml updatekeys secrets.yaml''
then run 'nix flake lock --update-input nix-secrets $HOME/nixos'
Finally, commit and push these changes to remote so they can be accessed on
the new host.
"
while true;
@ -131,8 +115,12 @@ do
[ "$confirm" = "yes" ] && break
done
ssh -i "$(readlink -f "$HOME/.ssh/id_ed25519")" "root@$ip" "nix-shell -p git --run 'git clone git@git.bitlab21.com:sam/nixos.git /persist/etc/nixos/'"
echo "Copying gitea private ssh key to host"
echo "New password is 'nixos'"
echo -e "###\nSuccessfully installed Nixos on the target host!\n###"
rsync -av "$(readlink -n "$HOME/.ssh/gitea" )" "$username@$ip":~/.ssh/gitea
ssh "$username@$ip" "nix-shell -p git --run 'git clone git@git.bitlab21.com:sam/nixos.git'"
ssh "$username@$ip" "nix-shell -p git --run 'git clone git@git.bitlab21.com:sam/nix-secrets.git'"
exit 0
echo "Successfully installed Nixos on the target host!"
echo "Please remote into the new host and run 'sudo nixos-generate-config && cp /etc/nixos/hardware-configuration.nix /home/$username/nixos/hosts/$hostname/'"

View File

@ -1,35 +0,0 @@
#!/usr/bin/env bash
echo "Generating an age key based on the new ssh_host_ed25519_key."
target_key=$(ssh-keyscan -p $ssh_port -t ssh-ed25519 "$target_destination" 2>&1 | grep ssh-ed25519 | cut -f2- -d" ")
age_key=$(nix shell nixpkgs#ssh-to-age.out -c sh -c "echo $target_key | ssh-to-age")
if grep -qv '^age1' <<<"$age_key"; then
echo "The result from generated age key does not match the expected format."
echo "Result: $age_key"
echo "Expected format: age10000000000000000000000000000000000000000000000000000000000"
exit 1
else
echo "$age_key"
fi
echo "Updating nix-secrets/.sops.yaml"
cd ../nix-secrets
SOPS_FILE=".sops.yaml"
sed -i "{
# Remove any * and & entries for this host
/[*&]$target_hostname/ d;
# Inject a new age: entry
# n matches the first line following age: and p prints it, then we transform it while reusing the spacing
/age:/{n; p; s/\(.*- \*\).*/\1$target_hostname/};
# Inject a new hosts: entry
/&hosts:/{n; p; s/\(.*- &\).*/\1$target_hostname $age_key/}
}" $SOPS_FILE
echo "Updating nix-secrets/.sops.yaml"
cd -
just rekey
echo "Updating flake lock on source machine with new .sops.yaml info"
nix flake lock --update-input nix-secrets

View File

@ -1,60 +0,0 @@
#!/usr/bin/env bash
#
# usage: ./generate_ssh_keys.sh --type "host" --username "root" --hostname "hostname"
#
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
--type)
type="$2"
shift # past argument
shift # past value
;;
--username)
username="$2"
shift # past argument
shift # past value
;;
--hostname)
hostname="$2"
shift # past argument
shift # past value
;;
*) # unknown option
echo "Unknown option $1"
exit 1
;;
esac
done
if [[ -z "$type" || -z "$username" || -z "$hostname" ]]; then
echo "All arguments are not specified."
exit 1
fi
if [[ $type != "user" && $type != "host" ]]; then
echo "Invalid type. It should be either 'user' or 'host'"
exit 1
fi
HOST_KEY_DIR="$HOME/keys/hosts/$hostname"
USER_KEY_DIR="$HOME/keys/users/$username"
mkdir -p "$HOST_KEY_DIR" "$USER_KEY_DIR"
if [[ $type == "user" ]]; then
keyfile="id_ed25519"
name="$username"
else
keyfile="ssh_host_ed25519_key"
name="root@$hostname"
fi
keydir=$([[ $type == "user" ]] && echo "$USER_KEY_DIR" || echo "$HOST_KEY_DIR")
fullpath="$keydir/$keyfile"
overwrite=""
[ -f "$fullpath" ] && read -p "Target key '$fullpath' already exists, would you like to overwrite it? (yes|no) " overwrite
[ "$overwrite" = "yes" ] || [ -z "$overwrite" ] && ssh-keygen -t ed25519 -f "$fullpath" -C "$name" -N ""