Compare commits
36 Commits
8a091acccc
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
2624e68a7c
|
|||
|
4335687f48
|
|||
|
44cd77e46f
|
|||
|
5b66eb3049
|
|||
|
1eddde2bdb
|
|||
|
31c72186ad
|
|||
|
f566267663
|
|||
|
5c14b05c16
|
|||
|
f613917d4c
|
|||
|
a765ea2844
|
|||
|
36dd8b8c34
|
|||
|
977c15a57f
|
|||
|
c348c97ea0
|
|||
|
9d6017432d
|
|||
|
9c9935b550
|
|||
|
5da4d36d25
|
|||
|
d83b03bbd8
|
|||
|
c371552dfd
|
|||
|
8b5111e9a1
|
|||
|
cca5c48725
|
|||
|
b4e4036c41
|
|||
|
3aab755e37
|
|||
|
6e361b197c
|
|||
|
6fd0b18746
|
|||
|
0c15063a58
|
|||
|
9056237e8a
|
|||
|
64b450bbe7
|
|||
|
8eee1ab82f
|
|||
|
c133ff306e
|
|||
|
5a53ce36e9
|
|||
|
7c25228bc5
|
|||
|
1ca8cc8c57
|
|||
| 014216de6b | |||
| 1ad1614509 | |||
| fa2ae3b86e | |||
| 91faab704c |
@@ -0,0 +1,2 @@
|
|||||||
|
.omc/
|
||||||
|
wg1.conf
|
||||||
+103
-12
@@ -104,15 +104,27 @@
|
|||||||
code-cursor
|
code-cursor
|
||||||
adwaita-icon-theme
|
adwaita-icon-theme
|
||||||
pkgs-unstable.claude-code # Use unstable for latest version
|
pkgs-unstable.claude-code # Use unstable for latest version
|
||||||
|
yubikey-manager
|
||||||
|
# iOS interop
|
||||||
|
uxplay
|
||||||
|
libimobiledevice
|
||||||
|
ifuse
|
||||||
];
|
];
|
||||||
|
|
||||||
# Some programs need SUID wrappers, can be configured further or are
|
# Some programs need SUID wrappers, can be configured further or are
|
||||||
# started in user sessions.
|
# started in user sessions.
|
||||||
# programs.mtr.enable = true;
|
# programs.mtr.enable = true;
|
||||||
# programs.gnupg.agent = {
|
programs.gnupg.agent = {
|
||||||
# enable = true;
|
enable = true;
|
||||||
# enableSSHSupport = true;
|
enableSSHSupport = true;
|
||||||
# };
|
pinentryPackage = pkgs.pinentry-gnome3;
|
||||||
|
};
|
||||||
|
|
||||||
|
# AirDrop-style file transfer (LocalSend)
|
||||||
|
programs.localsend = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
|
||||||
# List services that you want to enable:
|
# List services that you want to enable:
|
||||||
|
|
||||||
@@ -123,7 +135,7 @@
|
|||||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||||
# Or disable the firewall altogether.
|
# Or disable the firewall altogether.
|
||||||
# networking.firewall.enable = false;
|
networking.firewall.enable = false;
|
||||||
|
|
||||||
# This value determines the NixOS release from which the default
|
# This value determines the NixOS release from which the default
|
||||||
# settings for stateful data, like file locations and database versions
|
# settings for stateful data, like file locations and database versions
|
||||||
@@ -172,16 +184,63 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
services.tailscale = {
|
# WireGuard VPN
|
||||||
enable = true;
|
networking.wg-quick.interfaces.wg0 = {
|
||||||
useRoutingFeatures = "client"; # or "both" for subnet routing
|
address = [ "10.0.1.67/32" ];
|
||||||
|
dns = [ "1.1.1.1" ];
|
||||||
|
privateKeyFile = "/etc/wireguard/private.key";
|
||||||
|
|
||||||
|
# Route endpoint via local gateway to avoid routing loop
|
||||||
|
preUp = ''
|
||||||
|
GW=$(ip route show default | awk '{print $3; exit}')
|
||||||
|
DEV=$(ip route show default | awk '{print $5; exit}')
|
||||||
|
ip route add 69.48.243.22/32 via "$GW" dev "$DEV" || true
|
||||||
|
'';
|
||||||
|
postDown = ''
|
||||||
|
ip route del 69.48.243.22/32 || true
|
||||||
|
'';
|
||||||
|
|
||||||
|
peers = [{
|
||||||
|
publicKey = "VEpzr/CeGdS6Wsy0NDDfmlB/bCYxS55A155HWGCIIzc=";
|
||||||
|
endpoint = "69.48.243.22:51820";
|
||||||
|
# Route all traffic through VPN EXCEPT the local 10.0.0.0/24 network
|
||||||
|
allowedIPs = [
|
||||||
|
"0.0.0.0/5"
|
||||||
|
"8.0.0.0/7"
|
||||||
|
"10.0.1.0/24"
|
||||||
|
"10.0.2.0/23"
|
||||||
|
"10.0.4.0/22"
|
||||||
|
"10.0.8.0/21"
|
||||||
|
"10.0.16.0/20"
|
||||||
|
"10.0.32.0/19"
|
||||||
|
"10.0.64.0/18"
|
||||||
|
"10.0.128.0/17"
|
||||||
|
"10.1.0.0/16"
|
||||||
|
"10.2.0.0/15"
|
||||||
|
"10.4.0.0/14"
|
||||||
|
"10.8.0.0/13"
|
||||||
|
"10.16.0.0/12"
|
||||||
|
"10.32.0.0/11"
|
||||||
|
"10.64.0.0/10"
|
||||||
|
"10.128.0.0/9"
|
||||||
|
"11.0.0.0/8"
|
||||||
|
"12.0.0.0/6"
|
||||||
|
"16.0.0.0/4"
|
||||||
|
"32.0.0.0/3"
|
||||||
|
"64.0.0.0/2"
|
||||||
|
"128.0.0.0/1"
|
||||||
|
];
|
||||||
|
persistentKeepalive = 25;
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
|
|
||||||
# Open firewall for Tailscale
|
|
||||||
|
# Open firewall for Tailscale + UxPlay AirPlay receiver
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
checkReversePath = "loose";
|
checkReversePath = "loose";
|
||||||
trustedInterfaces = [ "tailscale0" ];
|
trustedInterfaces = [ "tailscale0" "wg0" ];
|
||||||
allowedUDPPorts = [ config.services.tailscale.port ];
|
allowedTCPPorts = [ 7000 7001 7100 ];
|
||||||
|
allowedUDPPorts = [ config.services.tailscale.port 6000 6001 7011 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# Auto-connect tailscale on boot
|
# Auto-connect tailscale on boot
|
||||||
@@ -214,6 +273,38 @@
|
|||||||
# Enable necessary services
|
# Enable necessary services
|
||||||
xdg.portal = {
|
xdg.portal = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.pcscd.enable = true;
|
||||||
|
|
||||||
|
# iPhone USB mount (libimobiledevice)
|
||||||
|
services.usbmuxd.enable = true;
|
||||||
|
|
||||||
|
# mDNS for AirPlay receiver (UxPlay) discovery from iPhone
|
||||||
|
services.avahi = {
|
||||||
|
enable = true;
|
||||||
|
nssmdns4 = true;
|
||||||
|
openFirewall = true;
|
||||||
|
publish = {
|
||||||
|
enable = true;
|
||||||
|
addresses = true;
|
||||||
|
userServices = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Auto-start UxPlay with the graphical session so iOS Screen Mirroring
|
||||||
|
# can find this host without manually launching it.
|
||||||
|
systemd.user.services.uxplay = {
|
||||||
|
description = "UxPlay AirPlay Mirror Receiver";
|
||||||
|
partOf = [ "graphical-session.target" ];
|
||||||
|
after = [ "graphical-session.target" "pipewire.service" ];
|
||||||
|
wantedBy = [ "graphical-session.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.uxplay}/bin/uxplay";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 5;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
security.pam.services = {
|
security.pam.services = {
|
||||||
@@ -255,7 +346,7 @@
|
|||||||
|
|
||||||
services.desktopManager.gnome.extraGSettingsOverrides = ''
|
services.desktopManager.gnome.extraGSettingsOverrides = ''
|
||||||
[org.gnome.mutter]
|
[org.gnome.mutter]
|
||||||
experimental-features=['scale-monitor-framebuffer', 'xwayland-native-scaling']
|
experimental-features=['scale-monitor-framebuffer']
|
||||||
'';
|
'';
|
||||||
|
|
||||||
environment.gnome.excludePackages = with pkgs; [
|
environment.gnome.excludePackages = with pkgs; [
|
||||||
|
|||||||
Generated
+44
-10
@@ -1,5 +1,21 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"caveman": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1776507098,
|
||||||
|
"narHash": "sha256-M+NoWXxrhtbkbe/lmq7P0/KpmqOZzJjhgeUVjY+7N2k=",
|
||||||
|
"owner": "JuliusBrussee",
|
||||||
|
"repo": "caveman",
|
||||||
|
"rev": "84cc3c14fa1e10182adaced856e003406ccd250d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "JuliusBrussee",
|
||||||
|
"repo": "caveman",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
@@ -25,11 +41,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772633058,
|
"lastModified": 1775077333,
|
||||||
"narHash": "sha256-SO7JapRy2HPhgmqiLbfnW1kMx5rakPMKZ9z3wtRLQjI=",
|
"narHash": "sha256-OXcxobt7lBkh1B8AjwreU+24myhtKpqeLfAeIyNLFY8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "080657a04188aca25f8a6c70a0fb2ea7e37f1865",
|
"rev": "49ca96b2714c5931e17401eff87f3edd42d2b0f2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -76,11 +92,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773597492,
|
"lastModified": 1779536132,
|
||||||
"narHash": "sha256-hQ284SkIeNaeyud+LS0WVLX+WL2rxcVZLFEaK0e03zg=",
|
"narHash": "sha256-q+fF42iv/geEbHfgSzy3tS0FF/EyD6XTZ98E6yxiBO8=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "a07d4ce6bee67d7c838a8a5796e75dff9caa21ef",
|
"rev": "3d8f0f3f72a6cd4d93d0ad13203f2ea1cb7e1456",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -92,11 +108,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772822230,
|
"lastModified": 1775002709,
|
||||||
"narHash": "sha256-yf3iYLGbGVlIthlQIk5/4/EQDZNNEmuqKZkQssMljuw=",
|
"narHash": "sha256-d3Yx83vSrN+2z/loBh4mJpyRqr9aAJqlke4TkpFmRJA=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "71caefce12ba78d84fe618cf61644dce01cf3a96",
|
"rev": "bcd464ccd2a1a7cd09aa2f8d4ffba83b761b1d0e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -106,12 +122,30 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"oh-my-claudecode": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1776693787,
|
||||||
|
"narHash": "sha256-C/m8Vlt6MXy8nlgqtoey9A5JnVTHCPkGUjar9x5Y2uw=",
|
||||||
|
"owner": "Yeachan-Heo",
|
||||||
|
"repo": "oh-my-claudecode",
|
||||||
|
"rev": "084fc47266824b35f4c8cbe886c0990ae716c184",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Yeachan-Heo",
|
||||||
|
"repo": "oh-my-claudecode",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"caveman": "caveman",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"kickstart-nvim": "kickstart-nvim",
|
"kickstart-nvim": "kickstart-nvim",
|
||||||
"nixpkgs": "nixpkgs_2",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable"
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
|
"oh-my-claudecode": "oh-my-claudecode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
|
|||||||
@@ -9,9 +9,17 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
kickstart-nvim.url = "github:0xWheatyz/kickstart.nvim";
|
kickstart-nvim.url = "github:0xWheatyz/kickstart.nvim";
|
||||||
|
caveman = {
|
||||||
|
url = "github:JuliusBrussee/caveman";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
oh-my-claudecode = {
|
||||||
|
url = "github:Yeachan-Heo/oh-my-claudecode";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, nixpkgs-unstable, home-manager, kickstart-nvim, ... }:
|
outputs = { self, nixpkgs, nixpkgs-unstable, home-manager, kickstart-nvim, caveman, oh-my-claudecode, ... }:
|
||||||
let
|
let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
pkgs-unstable = import nixpkgs-unstable {
|
pkgs-unstable = import nixpkgs-unstable {
|
||||||
@@ -31,7 +39,7 @@
|
|||||||
home-manager.useUserPackages = true;
|
home-manager.useUserPackages = true;
|
||||||
home-manager.users.l-wyatt = import ./home.nix;
|
home-manager.users.l-wyatt = import ./home.nix;
|
||||||
home-manager.extraSpecialArgs = {
|
home-manager.extraSpecialArgs = {
|
||||||
inherit kickstart-nvim;
|
inherit kickstart-nvim caveman oh-my-claudecode;
|
||||||
};
|
};
|
||||||
home-manager.sharedModules = [
|
home-manager.sharedModules = [
|
||||||
kickstart-nvim.homeManagerModules.default
|
kickstart-nvim.homeManagerModules.default
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, pkgs, lib, caveman, oh-my-claudecode, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
home.username = "l-wyatt";
|
home.username = "l-wyatt";
|
||||||
@@ -20,11 +20,15 @@
|
|||||||
bitwarden-cli
|
bitwarden-cli
|
||||||
lunarvim
|
lunarvim
|
||||||
minicom
|
minicom
|
||||||
kicad
|
|
||||||
ghostty
|
ghostty
|
||||||
|
gnupg
|
||||||
|
pinentry-gnome3
|
||||||
gnomeExtensions.blur-my-shell
|
gnomeExtensions.blur-my-shell
|
||||||
gnomeExtensions.just-perfection
|
gnomeExtensions.just-perfection
|
||||||
gnomeExtensions.arc-menu
|
gnomeExtensions.arc-menu
|
||||||
|
freecad
|
||||||
|
gtk3 # Provides org.gtk.Settings.FileChooser schema for FreeCAD
|
||||||
|
nodejs # Required by claude-code and oh-my-claudecode (HUD, npm plugins)
|
||||||
];
|
];
|
||||||
|
|
||||||
# --------------------------
|
# --------------------------
|
||||||
@@ -114,16 +118,43 @@
|
|||||||
exec = "ghostty";
|
exec = "ghostty";
|
||||||
exec-arg = "";
|
exec-arg = "";
|
||||||
};
|
};
|
||||||
|
"org/gnome/crypto/cache" = {
|
||||||
|
enable-ssh-agent = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Disable GCR ssh-agent so gpg-agent handles SSH
|
||||||
|
systemd.user.sockets.gcr-ssh-agent.Install.WantedBy = lib.mkForce [];
|
||||||
|
|
||||||
|
# GPG configuration
|
||||||
|
programs.gpg = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
keyserver = "hkps://keys.openpgp.org";
|
||||||
|
keyid-format = "0xlong";
|
||||||
|
with-fingerprint = true;
|
||||||
|
personal-cipher-preferences = "AES256 AES192 AES";
|
||||||
|
personal-digest-preferences = "SHA512 SHA384 SHA256";
|
||||||
|
personal-compress-preferences = "ZLIB BZIP2 ZIP Uncompressed";
|
||||||
|
};
|
||||||
|
scdaemonSettings = {
|
||||||
|
disable-ccid = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Manage your git configuration declaratively
|
# Manage your git configuration declaratively
|
||||||
programs.git = {
|
programs.git = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
signing = {
|
||||||
|
key = "0xADCEAC560B498269";
|
||||||
|
signByDefault = true;
|
||||||
|
};
|
||||||
settings = {
|
settings = {
|
||||||
user = {
|
user = {
|
||||||
name = "0xWheatyz";
|
name = "0xWheatyz";
|
||||||
email = "wyatt@leeworks.dev";
|
email = "wyatt@leeworks.dev";
|
||||||
};
|
};
|
||||||
|
pull.rebase = "false";
|
||||||
init.defaultBranch = "master";
|
init.defaultBranch = "master";
|
||||||
push.autoSetupRemote = "true";
|
push.autoSetupRemote = "true";
|
||||||
alias.lg = "log --graph --pretty=format:'%C(yellow)%h%Creset -%C(red)%d%Creset %s %Cgreen(%cr)%Creset %C(bold blue)<%an>%Creset' --abbrev-commit";
|
alias.lg = "log --graph --pretty=format:'%C(yellow)%h%Creset -%C(red)%d%Creset %s %Cgreen(%cr)%Creset %C(bold blue)<%an>%Creset' --abbrev-commit";
|
||||||
@@ -176,9 +207,30 @@
|
|||||||
# Use kickstart.nvim configuration from flake
|
# Use kickstart.nvim configuration from flake
|
||||||
programs.neovim-kickstart.enable = true;
|
programs.neovim-kickstart.enable = true;
|
||||||
|
|
||||||
|
# Claude Code skills (managed declaratively via flake inputs)
|
||||||
|
home.file.".claude/skills/caveman" = {
|
||||||
|
source = "${caveman}/skills/caveman";
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
home.file.".claude/skills/caveman-help" = {
|
||||||
|
source = "${caveman}/skills/caveman-help";
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
home.file.".claude/skills" = {
|
||||||
|
source = "${oh-my-claudecode}/skills";
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Claude Code agents (managed declaratively via flake inputs)
|
||||||
|
home.file.".claude/agents" = {
|
||||||
|
source = "${oh-my-claudecode}/agents";
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
|
||||||
# Claude Code configuration
|
# Claude Code configuration
|
||||||
home.file.".claude/CLAUDE.md" = {
|
home.file.".claude/CLAUDE.md" = {
|
||||||
text = ''
|
text = builtins.readFile "${oh-my-claudecode}/CLAUDE.md" + ''
|
||||||
|
|
||||||
## Commit Behavior
|
## Commit Behavior
|
||||||
|
|
||||||
After completing each logical unit of work, use the /commit skill to stage
|
After completing each logical unit of work, use the /commit skill to stage
|
||||||
@@ -219,18 +271,35 @@
|
|||||||
|
|
||||||
home.file.".claude/settings.json" = {
|
home.file.".claude/settings.json" = {
|
||||||
text = builtins.toJSON {
|
text = builtins.toJSON {
|
||||||
|
hasCompletedOnboarding = true;
|
||||||
permissions = {
|
permissions = {
|
||||||
allow = [
|
allow = [
|
||||||
"Edit"
|
"Edit"
|
||||||
"Write"
|
"Write"
|
||||||
"Bash(git:*)"
|
"Read"
|
||||||
"Bash(nix-shell:*)"
|
"Glob"
|
||||||
"Bash(nix eval:*)"
|
"Grep"
|
||||||
"Bash(nix flake check:*)"
|
"Bash"
|
||||||
|
"WebFetch"
|
||||||
|
"WebSearch"
|
||||||
|
"Agent"
|
||||||
|
"NotebookEdit"
|
||||||
|
"Monitor"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
alwaysThinkingEnabled = true;
|
alwaysThinkingEnabled = true;
|
||||||
includeCoAuthoredBy = false;
|
includeCoAuthoredBy = false;
|
||||||
|
statusLine = {
|
||||||
|
type = "command";
|
||||||
|
command = "node \${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hud/omc-hud.mjs";
|
||||||
|
};
|
||||||
|
env = {
|
||||||
|
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1";
|
||||||
|
OMC_PLUGIN_ROOT = "${oh-my-claudecode}";
|
||||||
|
#ANTHROPIC_BASE_URL = "http://10.0.1.16:20128/v1";
|
||||||
|
#ANTHROPIC_AUTH_TOKEN = "sk-634d6ea8670969de-qzxian-1a74cc97";
|
||||||
|
};
|
||||||
|
teammateMode = "tmux";
|
||||||
};
|
};
|
||||||
force = true;
|
force = true;
|
||||||
};
|
};
|
||||||
@@ -264,7 +333,7 @@
|
|||||||
proxyJump = "_JumpHost";
|
proxyJump = "_JumpHost";
|
||||||
};
|
};
|
||||||
"git" = {
|
"git" = {
|
||||||
hostname = "10.0.1.10";
|
hostname = "gitea.leeworks.dev";
|
||||||
port = 22;
|
port = 22;
|
||||||
user = "git";
|
user = "git";
|
||||||
};
|
};
|
||||||
|
|||||||
+247
@@ -0,0 +1,247 @@
|
|||||||
|
# Post-Rebuild YubiKey Setup Guide
|
||||||
|
|
||||||
|
## Step 1: Generate GPG Master Key
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --expert --full-generate-key
|
||||||
|
```
|
||||||
|
|
||||||
|
At the prompts:
|
||||||
|
|
||||||
|
1. Select **(9) ECC and ECC**
|
||||||
|
2. Curve: **Curve 25519**
|
||||||
|
3. Expiration: **1y**
|
||||||
|
4. Real name: **0xWheatyz**
|
||||||
|
5. Email: **wyatt@leeworks.dev**
|
||||||
|
6. Set a strong passphrase
|
||||||
|
|
||||||
|
Note the key ID printed (e.g. `0x1234ABCD5678EFGH`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 2: Add Subkeys
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --expert --edit-key <KEY-ID>
|
||||||
|
```
|
||||||
|
|
||||||
|
Add 3 subkeys at the `gpg>` prompt:
|
||||||
|
|
||||||
|
**Signing subkey:**
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg> addkey
|
||||||
|
→ (10) ECC (sign only)
|
||||||
|
→ Curve 25519
|
||||||
|
→ 1y expiry
|
||||||
|
```
|
||||||
|
|
||||||
|
**Encryption subkey** (may already exist — check with `list`):
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg> addkey
|
||||||
|
→ (12) ECC (encrypt only)
|
||||||
|
→ Curve 25519
|
||||||
|
→ 1y expiry
|
||||||
|
```
|
||||||
|
|
||||||
|
**Authentication subkey:**
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg> addkey
|
||||||
|
→ (11) ECC (set your own capabilities)
|
||||||
|
→ Toggle: disable Sign, enable Authenticate
|
||||||
|
→ Curve 25519
|
||||||
|
→ 1y expiry
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg> save
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 3: Back Up Master Key (CRITICAL)
|
||||||
|
|
||||||
|
> Once keys are moved to the YubiKey, they cannot be extracted. Back up now.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /tmp/gpg-backup
|
||||||
|
gpg --armor --export-secret-keys <KEY-ID> > /tmp/gpg-backup/master-secret.asc
|
||||||
|
gpg --armor --export-secret-subkeys <KEY-ID> > /tmp/gpg-backup/subkeys-secret.asc
|
||||||
|
gpg --armor --export <KEY-ID> > /tmp/gpg-backup/public.asc
|
||||||
|
gpg --export-ownertrust > /tmp/gpg-backup/ownertrust.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy `/tmp/gpg-backup/` to an encrypted USB drive or other secure offline storage. Then remove the temp copy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf /tmp/gpg-backup
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 4: Move Subkeys to YubiKey
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --edit-key <KEY-ID>
|
||||||
|
```
|
||||||
|
|
||||||
|
Move each subkey to its corresponding card slot:
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg> key 1
|
||||||
|
gpg> keytocard
|
||||||
|
→ (1) Signature key
|
||||||
|
gpg> key 1
|
||||||
|
|
||||||
|
gpg> key 2
|
||||||
|
gpg> keytocard
|
||||||
|
→ (2) Encryption key
|
||||||
|
gpg> key 2
|
||||||
|
|
||||||
|
gpg> key 3
|
||||||
|
gpg> keytocard
|
||||||
|
→ (3) Authentication key
|
||||||
|
|
||||||
|
gpg> save
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 5: Set Trust & Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --edit-key <KEY-ID>
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg> trust
|
||||||
|
→ (5) I trust ultimately
|
||||||
|
gpg> quit
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify the card:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --card-status # Should show all 3 subkeys
|
||||||
|
gpg --list-secret-keys # Subkeys should show "ssb>" (stub pointing to card)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 6: Back Up & Remove Old SSH Keys
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.ssh/old
|
||||||
|
mv ~/.ssh/id_ed25519 ~/.ssh/old/
|
||||||
|
mv ~/.ssh/id_ed25519.pub ~/.ssh/old/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 7: Get Your New SSH Public Key
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --export-ssh-key <KEY-ID>
|
||||||
|
```
|
||||||
|
|
||||||
|
This outputs the SSH public key derived from your GPG auth subkey. Save it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --export-ssh-key <KEY-ID> > ~/.ssh/yubikey.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify gpg-agent serves it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh-add -L # Should show the same key
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy this key to your remote servers:
|
||||||
|
|
||||||
|
- **vps** (45.79.198.105) — add to `~/.ssh/authorized_keys` for user `wyatt`
|
||||||
|
- **home** (10.0.0.20) — add to `~/.ssh/authorized_keys` for user `l-wyatt`
|
||||||
|
- **git** (10.0.1.10) — add via your Gitea/Forgejo web UI
|
||||||
|
- **GitHub** — Settings → SSH and GPG Keys → New SSH Key
|
||||||
|
|
||||||
|
> **Tip:** Use the old key (still in `~/.ssh/old/`) to SSH in and deploy the new one:
|
||||||
|
> ```bash
|
||||||
|
> ssh -i ~/.ssh/old/id_ed25519 vps "echo '$(gpg --export-ssh-key <KEY-ID>)' >> ~/.ssh/authorized_keys"
|
||||||
|
> ```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 8: Update home.nix with Your Signing Key
|
||||||
|
|
||||||
|
Get your key ID:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --list-secret-keys --keyid-format 0xlong
|
||||||
|
```
|
||||||
|
|
||||||
|
Then edit `home.nix` and replace the `key = null;` line:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
signing = {
|
||||||
|
key = "<YOUR-0xLONG-KEY-ID>"; # e.g. "0x1234ABCD5678EFGH"
|
||||||
|
signByDefault = true;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Rebuild again:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nixos-rebuild switch
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 9: Verify Everything
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Smartcard
|
||||||
|
gpg --card-status
|
||||||
|
|
||||||
|
# SSH via YubiKey
|
||||||
|
ssh-add -L
|
||||||
|
ssh vps echo "YubiKey SSH works!"
|
||||||
|
|
||||||
|
# Git signing
|
||||||
|
cd /tmp && git init test-sign && cd test-sign
|
||||||
|
git commit --allow-empty -m "test signing"
|
||||||
|
git log --show-signature -1
|
||||||
|
# Should show "Good signature from 0xWheatyz <wyatt@leeworks.dev>"
|
||||||
|
rm -rf /tmp/test-sign
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 10 (Optional): Change YubiKey PINs
|
||||||
|
|
||||||
|
The default PINs are `123456` (user) and `12345678` (admin). Change them:
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg --card-edit
|
||||||
|
gpg/card> admin
|
||||||
|
gpg/card> passwd
|
||||||
|
→ (1) Change PIN
|
||||||
|
→ (3) Change Admin PIN
|
||||||
|
gpg/card> quit
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 11 (Optional): Upload GPG Public Key to GitHub
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gpg --armor --export <KEY-ID>
|
||||||
|
```
|
||||||
|
|
||||||
|
Paste the output into **GitHub → Settings → SSH and GPG Keys → New GPG Key**. This makes your signed commits show "Verified" on GitHub.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Note
|
||||||
|
|
||||||
|
The config changes to `configuration.nix` and `home.nix` are already saved. After you rebuild, reboot, and follow the steps above, you'll need to come back to update `home.nix` one more time with your actual GPG key ID (Step 8) and do a final rebuild.
|
||||||
Reference in New Issue
Block a user