Compare commits

..

13 Commits

Author SHA1 Message Date
Alexander Heldt b6fcd199c1 pinwheel/tadpole: Add ed25519 ssh key 2026-06-17 08:35:07 +02:00
Alexander Heldt 9a49839eee Update whib-frontend flake input 2026-06-03 12:59:11 +02:00
Alexander Heldt 2606f1a1c6 tadpole: Scope authorized_keys_command to alex
The command was hijacking auth for all users, including `gitea`, which
broke `git push` over SSH — `gitea`'s `authorized_keys` (with the
`gitea serv` command restriction) was being bypassed, and sshd would
try to exec the raw `git-receive-pack` instead.

Pass `%u` to the command and short-circuit unless the requested user
is `alex`, so other users fall back to their own `~/.ssh/authorized_keys`.
2026-06-03 12:58:08 +02:00
Alexander Heldt 331a86deb0 pinwheel: Use opensshs ssh-agent for SSH
As gnomes gcr-ssh-agent stalls RSA signing
2026-06-03 12:58:07 +02:00
Alexander Heldt 5cf4c1037a pinwheel: Load direnv ZSH on devshell load 2026-06-03 12:58:05 +02:00
Alexander Heldt 50bf270d1c pinwheel: Pin tailscale version 2026-06-03 12:58:04 +02:00
Alexander Heldt 6e7e3aeebd pinwheel: Fix ts LSP package location 2026-06-03 12:58:02 +02:00
Alexander Heldt 477d54c7db pinwheel: Fix hyprland lock input 2026-06-03 12:58:01 +02:00
Alexander Heldt e02b21013b Update whib-backend flake input 2026-06-03 10:25:19 +00:00
Alexander Heldt 4a63c4eb5e manatee: Update monitoring in home-assistant
- Add all disks to smartd
- Generate home-assistant config in nix
- Add metrics for all HDDs
2026-05-30 16:54:40 +00:00
Alexander Heldt d291633fe2 manatee: Update ssh module
- current naming
- set defaults to off
2026-05-30 16:45:27 +00:00
Alexander Heldt 188ad0a75a manatee: Make romm network creation idempotent 2026-05-30 16:44:30 +00:00
Alexander Heldt 993528418c Update flake inputs 2026-05-20 09:26:39 +02:00
16 changed files with 480 additions and 205 deletions
Generated
+56 -56
View File
@@ -43,11 +43,11 @@
]
},
"locked": {
"lastModified": 1776702787,
"narHash": "sha256-qc5uwEWbuubzYthmZcfCapooZGXhoYZWfTQ24TozbCQ=",
"lastModified": 1778620495,
"narHash": "sha256-Gu7UhWjwKCgSiVC3Qz/Rc7cYi9DNuDTBxYzg3kfLvfM=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "9a1ca6b8cb4d86a599787a55b78f2ddf809bf945",
"rev": "be35f75ac305f430f5f9d89b5f5a4af59ca7567e",
"type": "github"
},
"original": {
@@ -85,11 +85,11 @@
]
},
"locked": {
"lastModified": 1776613567,
"narHash": "sha256-gC9Cp5ibBmGD5awCA9z7xy6MW6iJufhazTYJOiGlCUI=",
"lastModified": 1779226674,
"narHash": "sha256-wuOkjI6pRiN4sEn/EPBRnNW5cmcpvd7xtIM8y5LooAs=",
"owner": "nix-community",
"repo": "disko",
"rev": "32f4236bfc141ae930b5ba2fb604f561fed5219d",
"rev": "65fb947964bd44fc0008faf77d1fcb7a9f40bb32",
"type": "github"
},
"original": {
@@ -106,11 +106,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1776936542,
"narHash": "sha256-UEC1ywLxd+0bSX+qNWuooO2nrJAT7hRrLONyycG8gnE=",
"lastModified": 1779250628,
"narHash": "sha256-QrHi1w+g7p58wMxcK9jOXr3oi2PRWQ+i4Sw38sL3dB4=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "32f7f12480ae05b1f89d06161230ac16cb4656ef",
"rev": "5f8f3a12b25e29c1dd0a6363b61eba7d2f9944fe",
"type": "github"
},
"original": {
@@ -237,11 +237,11 @@
]
},
"locked": {
"lastModified": 1776950293,
"narHash": "sha256-t6KMARLILjPuTBSRoYanUxV+FU50IFZ7L5XVdOcdtaY=",
"lastModified": 1779213149,
"narHash": "sha256-Cf+p/T4Z3n9Sw0TiR3kQaIwQI+/hfvLJcoTzeq6yS3E=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "6837e0d6c5eda81fd26308489799fbf83a160465",
"rev": "bd868f769a69d3b6091a1da68a75cb83a181033c",
"type": "github"
},
"original": {
@@ -327,11 +327,11 @@
"xdph": "xdph"
},
"locked": {
"lastModified": 1776947531,
"narHash": "sha256-DBE9ECXz4ItAyIZ0NCfccpjFjpLALvDbkLd62xDZPQI=",
"lastModified": 1779190425,
"narHash": "sha256-C0hPhLeo3ztBXYSnpYarYjw6HDvlgZRnNyFfG5PoaVI=",
"owner": "hyprwm",
"repo": "Hyprland",
"rev": "b65714e3b8e123fb2febd507905d25fa6abd0400",
"rev": "203a121537d0868bd4d8258b58861ca970483157",
"type": "github"
},
"original": {
@@ -347,11 +347,11 @@
]
},
"locked": {
"lastModified": 1776426061,
"narHash": "sha256-3rROoGl8xBsIOM+5m+qZS4GJnsdQPAH3NJJe1OUfJ5o=",
"lastModified": 1778488488,
"narHash": "sha256-6Vvr0qMRdccvJqwzrXJkqoK6lWsdyC1nMrLjoHKqoGM=",
"owner": "hyprwm",
"repo": "contrib",
"rev": "1f71628d86a7701fd5ba0f8aeabe15376f4c6afc",
"rev": "55b1393a23d6e4968ce6da704c8095f7e5e9fa3c",
"type": "github"
},
"original": {
@@ -447,11 +447,11 @@
]
},
"locked": {
"lastModified": 1776426736,
"narHash": "sha256-rl7i4aY+9p8LysJp7o8uRWahCkpFznCgGHXszlTw7b0=",
"lastModified": 1777320127,
"narHash": "sha256-Qu+Wf2Bp5qUjyn2YpZNq8a7JyzTGowhT1knrwE38a9U=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "7833ff33b2e82d3406337b5dcf0d1cec595d83e9",
"rev": "090117506ddc3d7f26e650ff344d378c2ec329cc",
"type": "github"
},
"original": {
@@ -524,11 +524,11 @@
]
},
"locked": {
"lastModified": 1776428866,
"narHash": "sha256-XfRlBolGtjvalTHJp3XvvpYLBjkMhaZLLU0WqZ91Fcg=",
"lastModified": 1778234770,
"narHash": "sha256-jAcsogZwWMfXT9MfXxZzkwliAqIuZUV0p71h6Ba9ReE=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "eedd60805cd96d4442586f2ba5fe51d549b12674",
"rev": "a2dbd8a4cc51f7cbe4224732668392bb1aa79df2",
"type": "github"
},
"original": {
@@ -549,11 +549,11 @@
]
},
"locked": {
"lastModified": 1776430932,
"narHash": "sha256-Yv3RPiUvl7CAsJgwIVsqcj7akn1gLyJP1F/mocof5hA=",
"lastModified": 1777159683,
"narHash": "sha256-Jxixw6wZphUp+nHYxOKUYSckL17QMBx2d5Zp0rJHr1g=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "4c2fcc06dc9722c97dbb54ba649c69b18ce83d2e",
"rev": "b8632713a6beaf28b56f2a7b0ab2fb7088dbb404",
"type": "github"
},
"original": {
@@ -578,11 +578,11 @@
]
},
"locked": {
"lastModified": 1776728575,
"narHash": "sha256-z9eGphrArEBpl1O/GCH0wlY6z4K9vA6yWh2gAS6qytU=",
"lastModified": 1778410714,
"narHash": "sha256-o6RzFj4nJXaPRY7EM01siuCQeT41RfwwmcmFQqwFJJg=",
"owner": "hyprwm",
"repo": "hyprwire",
"rev": "f3a80888783702a39691b684d099e16b83ed4702",
"rev": "85148a8e612808cf5ddb25d0b3c5840f3498a7dc",
"type": "github"
},
"original": {
@@ -719,11 +719,11 @@
"systems": "systems_5"
},
"locked": {
"lastModified": 1776531667,
"narHash": "sha256-AFiJUWK8RDeL4c3s0XW3oSTkBqxxsQqUXrwHoJZfIm8=",
"lastModified": 1778951860,
"narHash": "sha256-aFjBC3AVLh/bsgcsoI6Z/yQmh/NABffwHJIqQOTj+Tg=",
"owner": "nix-community",
"repo": "nix-jetbrains-plugins",
"rev": "96ef56d2c967771d7f1f5436ac11e8cca5014d95",
"rev": "68930eefa5e77fc6bb7977635c83a003683c2f11",
"type": "github"
},
"original": {
@@ -734,11 +734,11 @@
},
"nixos-hardware": {
"locked": {
"lastModified": 1776830795,
"narHash": "sha256-PAfvLwuHc1VOvsLcpk6+HDKgMEibvZjCNvbM1BJOA7o=",
"lastModified": 1779099457,
"narHash": "sha256-u73aVD/lUmmT3JV+kPDztl7zPwQKd0eobD1AbJltaGs=",
"owner": "nixos",
"repo": "nixos-hardware",
"rev": "72674a6b5599e844c045ae7449ba91f803d44ebc",
"rev": "8792fab9d4a6454a9201675f01326f827ce35ead",
"type": "github"
},
"original": {
@@ -766,11 +766,11 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1776734388,
"narHash": "sha256-vl3dkhlE5gzsItuHoEMVe+DlonsK+0836LIRDnm6MXQ=",
"lastModified": 1779102034,
"narHash": "sha256-vZJZjLo513IeI8hjzHFc6TDezUd4uCE2Eq4SNO3DNNg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "10e7ad5bbcb421fe07e3a4ad53a634b0cd57ffac",
"rev": "687f05a9184cad4eaf905c48b63649e3a86f5433",
"type": "github"
},
"original": {
@@ -782,11 +782,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1776548001,
"narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=",
"lastModified": 1778869304,
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc",
"rev": "d233902339c02a9c334e7e593de68855ad26c4cb",
"type": "github"
},
"original": {
@@ -827,11 +827,11 @@
]
},
"locked": {
"lastModified": 1776796298,
"narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=",
"lastModified": 1778507602,
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad",
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"type": "github"
},
"original": {
@@ -944,11 +944,11 @@
]
},
"locked": {
"lastModified": 1774202723,
"narHash": "sha256-z3kfGSm1EFzzUorewI5Jtgv79lPV128pZd8EEak4xZg=",
"lastModified": 1780482259,
"narHash": "sha256-buOczAkw78U+g7DYcB7nMabTGzQoN15HtVE3y0kIt3I=",
"ref": "master",
"rev": "02ad04e1460d7ce84db24b3bb526339df1e76501",
"revCount": 372,
"rev": "b9ee418d14d6cb500506f9ef0cb9d54a8e78afa9",
"revCount": 373,
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/whib.git"
},
@@ -965,11 +965,11 @@
]
},
"locked": {
"lastModified": 1761508816,
"narHash": "sha256-adV/lyxcmuopyuzZ49v46Yt0gft+ioEL4yl1S+vUbus=",
"lastModified": 1780483645,
"narHash": "sha256-Nr0WTh72uBCSO5jCcvHPE+4dqAPn07HZ5U1lAE4/3II=",
"ref": "master",
"rev": "ab10bf50cb6b023a1b99f91c7e8d550231135eef",
"revCount": 223,
"rev": "14f98eced1ccf1e62493ad65eb38502b38db5cba",
"revCount": 224,
"type": "git",
"url": "ssh://gitea@git.ppp.pm:1122/alex/whib-react.git"
},
@@ -1007,11 +1007,11 @@
]
},
"locked": {
"lastModified": 1776608502,
"narHash": "sha256-UH8YoQxx4hFOm6qjMdjRQNRvSejFIR/wBZ8fW1p9sME=",
"lastModified": 1778265244,
"narHash": "sha256-8jlPtGSsv/CQY6tVVyLF4Jjd0gnS+Zbn9yk/V13A9nM=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "4a293523d36dfa367e67ec304cc718ea66a8fec2",
"rev": "813ea5ca9a1702a9a2d1f5836bc00172ef698968",
"type": "github"
},
"original": {
+5
View File
@@ -79,11 +79,16 @@
{ device = config.disko.devices.disk.root.device; }
{ device = config.disko.devices.disk.disk1.device; }
{ device = config.disko.devices.disk.disk2.device; }
{ device = config.disko.devices.disk.disk3.device; }
{ device = config.disko.devices.disk.disk4.device; }
];
};
services.zfs.autoScrub.enable = true;
# Don't force-import the pool if it appears in use elsewhere; safer default in 26.11+.
boot.zfs.forceImportRoot = false;
networking.hostId = "0a9474e7"; # Required by ZFS
disko.devices = {
disk = {
+1
View File
@@ -23,6 +23,7 @@ in
komga.enable = true;
romm.enable = true;
homepage.enable = true;
disk-smart.enable = true;
};
};
}
@@ -0,0 +1,159 @@
{
pkgs,
lib,
config,
...
}:
let
enabled = config.mod.disk-smart.enable;
disks = [
{ path = "/dev/disk/by-id/ata-ST8000VN004-3CP101_WWZ8QCG4"; name = "seagate_8tb_1"; label = "Seagate 8TB #1"; }
{ path = "/dev/disk/by-id/ata-ST8000VN004-3CP101_WWZ8QDJ5"; name = "seagate_8tb_2"; label = "Seagate 8TB #2"; }
{ path = "/dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_85K2A0UCF4MJ"; name = "toshiba_20tb_1"; label = "Toshiba 20TB #1"; }
{ path = "/dev/disk/by-id/ata-TOSHIBA_MG10ACA20TE_85K2A0V6F4MJ"; name = "toshiba_20tb_2"; label = "Toshiba 20TB #2"; }
];
outputDir = "/var/lib/disk-smart";
collectScript = pkgs.writeShellScript "disk-smart-collect" ''
set -euo pipefail
export PATH="${lib.makeBinPath [ pkgs.smartmontools pkgs.jq pkgs.coreutils ]}"
mkdir -p ${outputDir}
result="{"
${lib.concatMapStringsSep "\n" (disk: ''
raw=$(smartctl -j -A -H ${disk.path} 2>/dev/null || true)
temp=$(echo "$raw" | jq -r '.temperature.current // empty')
power_on=$(echo "$raw" | jq -r '.power_on_time.hours // empty')
smart_status=$(echo "$raw" | jq -r '.smart_status.passed // empty')
reallocated=$(echo "$raw" | jq -r '[.ata_smart_attributes.table[] | select(.name == "Reallocated_Sector_Ct")][0].raw.value // empty')
pending=$(echo "$raw" | jq -r '[.ata_smart_attributes.table[] | select(.name == "Current_Pending_Sector")][0].raw.value // empty')
result="$result\"${disk.name}\":{\"temperature\":$temp,\"power_on_hours\":$power_on,\"smart_passed\":$smart_status,\"reallocated_sectors\":$reallocated,\"pending_sectors\":$pending},"
'') disks}
# Remove trailing comma, close object
result="''${result%,}}"
echo "$result" | jq . > ${outputDir}/smart.json.tmp
mv ${outputDir}/smart.json.tmp ${outputDir}/smart.json
'';
indent = prefix: s:
lib.concatMapStringsSep "\n"
(line: if line == "" then line else prefix + line)
(lib.splitString "\n" s);
mkSensor = disk: ''
- name: "${disk.label} Temperature"
value_template: "{{ value_json.${disk.name}.temperature }}"
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
- name: "${disk.label} Power On Hours"
value_template: "{{ value_json.${disk.name}.power_on_hours }}"
unit_of_measurement: "h"
state_class: total_increasing
- name: "${disk.label} SMART Passed"
value_template: "{{ value_json.${disk.name}.smart_passed }}"
- name: "${disk.label} Reallocated Sectors"
value_template: "{{ value_json.${disk.name}.reallocated_sectors }}"
state_class: measurement
- name: "${disk.label} Pending Sectors"
value_template: "{{ value_json.${disk.name}.pending_sectors }}"
state_class: measurement
'';
sensorYaml = indent " " (lib.concatMapStrings mkSensor disks);
sectorEntities = lib.concatMap (disk: [
"sensor.${disk.name}_reallocated_sectors"
"sensor.${disk.name}_pending_sectors"
]) disks;
sectorEntitiesYaml = lib.concatMapStringsSep "\n"
(id: " - ${id}") sectorEntities;
smartPassedEntities = map (disk: "sensor.${disk.name}_smart_passed") disks;
smartPassedEntitiesYaml = lib.concatMapStringsSep "\n"
(id: " - ${id}") smartPassedEntities;
in
{
options = {
mod.disk-smart = {
enable = lib.mkEnableOption "Enable disk SMART monitoring module";
};
};
config = lib.mkIf enabled {
mod.home-assistant.extraConfig = ''
rest:
- resource: http://127.0.0.1:9633/smart.json
scan_interval: 60
sensor:
${sensorYaml}
automation disk_smart:
- alias: "Disk sector count increased"
trigger:
- platform: state
entity_id:
${sectorEntitiesYaml}
condition:
- condition: template
value_template: "{{ trigger.from_state.state | int(-1) >= 0 and trigger.to_state.state | int(0) > trigger.from_state.state | int(0) }}"
action:
- service: notify.mobile_app_pixel_9_pro
data:
title: "Disk SMART warning"
message: "{{ trigger.to_state.attributes.friendly_name }} increased from {{ trigger.from_state.state }} to {{ trigger.to_state.state }}"
- alias: "Disk SMART check failed"
trigger:
- platform: state
entity_id:
${smartPassedEntitiesYaml}
condition:
- condition: template
value_template: "{{ trigger.to_state.state | lower == 'false' }}"
action:
- service: notify.mobile_app_pixel_9_pro
data:
title: "Disk SMART FAILURE"
message: "{{ trigger.to_state.attributes.friendly_name }} reports SMART failure drive is likely failing"
'';
systemd.services.disk-smart-collect = {
description = "Collect disk SMART data";
serviceConfig = {
Type = "oneshot";
ExecStart = collectScript;
};
};
systemd.timers.disk-smart-collect = {
description = "Periodically collect disk SMART data";
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1min";
OnUnitActiveSec = "1min";
};
};
services.nginx.virtualHosts."127.0.0.1" = {
listen = [
{ addr = "127.0.0.1"; port = 9633; }
];
locations."= /smart.json" = {
alias = "${outputDir}/smart.json";
extraConfig = ''
default_type application/json;
'';
};
};
};
}
@@ -6,8 +6,42 @@
}:
let
nginxEnabled = config.mod.nginx.enable;
cfg = config.mod.home-assistant;
script = pkgs.writeShellScript "bt-reset" ''
configFile = pkgs.writeText "ha-configuration.yaml" ''
# Loads default set of integrations. Do not remove.
default_config:
http:
use_x_forwarded_for: true
trusted_proxies:
- 127.0.0.1
# Load frontend themes from the themes folder
frontend:
themes: !include_dir_merge_named themes
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
recorder:
purge_keep_days: 365
alert:
fridge_door:
name: Fridge is open
done_message: Fride is closed
entity_id: binary_sensor.kyldorr
state: "on"
repeat: 2
skip_first: true
notifiers:
- mobile_app_pixel_9_pro
${cfg.extraConfig}'';
btResetScript = pkgs.writeShellScript "bt-reset" ''
set -euo pipefail
export PATH="${
lib.makeBinPath [
@@ -62,6 +96,17 @@ let
'';
in
{
options = {
mod.home-assistant = {
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra YAML to append to Home Assistant's configuration.yaml";
};
};
};
config = {
mod.homepage.services = [
{
name = "Home Assistant";
@@ -80,6 +125,7 @@ in
volumes = [
"/home/alex/.config/home-assistant:/config"
"${configFile}:/config/configuration.yaml:ro"
# Pass in bluetooth
"/run/dbus:/run/dbus:ro"
];
@@ -140,7 +186,7 @@ in
serviceConfig = {
Type = "oneshot";
ExecStart = script;
ExecStart = btResetScript;
Restart = "on-failure";
RestartSec = "10s";
@@ -240,4 +286,5 @@ in
};
};
};
};
}
+5 -2
View File
@@ -69,8 +69,11 @@ in
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "/run/current-system/sw/bin/podman network create romm-net";
ExecStop = "/run/current-system/sw/bin/podman network rm -f romm-net";
ExecStart = pkgs.writeShellScript "romm-net-create" ''
${pkgs.podman}/bin/podman network exists romm-net \
|| ${pkgs.podman}/bin/podman network create romm-net
'';
ExecStop = "${pkgs.podman}/bin/podman network rm -f romm-net";
};
};
+2 -1
View File
@@ -21,8 +21,9 @@ in
home-manager.users.alex = {
programs.ssh = {
enable = true;
enableDefaultConfig = false;
matchBlocks = {
settings = {
"git.ppp.pm" = {
hostname = "git.ppp.pm";
identityFile = "/home/alex/.ssh/alex.manatee-git.ppp.pm";
+1 -1
View File
@@ -45,7 +45,7 @@ in
valign = "center";
outline_thickness = 2;
dots_center = true;
fade_on_empty = true;
fade_on_empty = false;
placeholder_text = "";
}
];
@@ -1,6 +1,6 @@
{ pkgs, ... }:
{
home-manager.users.alex = {
home.packages = [ pkgs.nodePackages.typescript-language-server ];
home.packages = [ pkgs.typescript-language-server ];
};
}
+18 -1
View File
@@ -3,10 +3,14 @@
# Enable gnome-keyring at system level for PAM integration
services.gnome.gnome-keyring.enable = true;
# Use openssh's own ssh-agent — gcr's ssh-agent stalls signing RSA keys.
services.gnome.gcr-ssh-agent.enable = false;
programs.ssh.startAgent = true;
home-manager.users.alex = {
services.gnome-keyring = {
enable = true;
components = [ "secrets" "ssh" ];
components = [ "secrets" ];
};
programs.ssh = {
@@ -131,6 +135,19 @@
owner = "alex";
group = "users";
};
"alex.pinwheel-tadpole-ed25519" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-tadpole-ed25519.age;
path = "/home/alex/.ssh/alex.pinwheel-tadpole-ed25519";
owner = "alex";
group = "users";
};
"alex.pinwheel-tadpole-ed25519.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-tadpole-ed25519.pub.age;
path = "/home/alex/.ssh/alex.pinwheel-tadpole-ed25519.pub";
owner = "alex";
group = "users";
};
};
services.openssh = {
+17 -1
View File
@@ -1,7 +1,23 @@
{ ... }:
{ pkgs, ... }:
{
services.tailscale.enable = true;
# Pinned to 1.96.5. 1.98.0 regressed split-DNS handling under work-vpn: the
# netmap's "resolve <tailnet>.ts.net locally via MagicDNS" hint is dropped
# when translated into systemd-resolved config, so *.ts.net queries get sent
# to a public resolver (199.247.155.53) that the corporate VPN's port-53
# egress filter blocks.
services.tailscale.package = pkgs.tailscale.overrideAttrs (_: rec {
version = "1.96.5";
src = pkgs.fetchFromGitHub {
owner = "tailscale";
repo = "tailscale";
tag = "v${version}";
hash = "sha256-vYYb+2OtuXftjGGG0zWJesHccrClB8YZpclv9KzNN/c=";
};
vendorHash = "sha256-rhuWEEN+CtumVxOw6Dy/IRxWIrZ2x6RJb6ULYwXCQc4=";
});
networking.firewall = {
checkReversePath = "loose";
allowedUDPPorts = [ 41641 ];
+18
View File
@@ -22,6 +22,24 @@ in
[[ "$PATH" == "${pkgs.bashInteractive}/bin:"* ]] || export PATH="${pkgs.bashInteractive}/bin:$PATH"
}
precmd_functions+=(_ensure_bash_interactive)
# Source the zsh-specific rc file that nix-direnv emits ($DIRENV_ZSH_RC)
# so devshell completions and zsh setup are picked up. direnv itself only
# exports env vars, so without this hook the zsh side of the devshell is
# never loaded. Guarded by LAST_LOADED_DIRENV_ZSH_RC so we don't re-source
# it on every precmd.
_nix_direnv_bridge_hook() {
if [[ -n "$DIRENV_ZSH_RC" && "$LAST_LOADED_DIRENV_ZSH_RC" != "$DIRENV_ZSH_RC" ]]; then
if [[ -f "$DIRENV_ZSH_RC" ]]; then
source "$DIRENV_ZSH_RC"
export LAST_LOADED_DIRENV_ZSH_RC="$DIRENV_ZSH_RC"
echo " direnv zsh loaded..."
fi
fi
}
autoload -Uz add-zsh-hook
add-zsh-hook precmd _nix_direnv_bridge_hook
'';
# Configure IntelliJ to exclude .direnv from indexing
+7 -1
View File
@@ -48,6 +48,7 @@ in
mode = "0755";
text = ''
#!${pkgs.bash}/bin/bash
[ "$1" = "alex" ] || exit 0
for file in ${authorizedKeysPath}/*; do
${pkgs.coreutils}/bin/cat "$file"
done
@@ -71,7 +72,7 @@ in
KbdInteractiveAuthentication = false;
};
authorizedKeysCommand = "/etc/ssh/authorized_keys_command";
authorizedKeysCommand = "/etc/ssh/authorized_keys_command %u";
authorizedKeysCommandUser = "root";
};
};
@@ -97,6 +98,11 @@ in
path = "${authorizedKeysPath}/alex.pinwheel-tadpole.pub";
};
"alex.pinwheel-tadpole-ed25519.pub" = {
file = ../../../../secrets/pinwheel/alex.pinwheel-tadpole-ed25519.pub.age;
path = "${authorizedKeysPath}/alex.pinwheel-tadpole-ed25519.pub";
};
"alex.tadpole-git.ppp.pm" = {
file = ../../../../secrets/tadpole/alex.tadpole-git.ppp.pm.age;
path = "/home/alex/.ssh/alex.tadpole-git.ppp.pm";
Binary file not shown.
+2
View File
@@ -15,6 +15,8 @@ in {
"pinwheel/alex.pinwheel-backwards.pub.age".publicKeys = [ pinwheel backwards alex ];
"pinwheel/alex.pinwheel-tadpole.age".publicKeys = [ pinwheel alex ];
"pinwheel/alex.pinwheel-tadpole.pub.age".publicKeys = [ pinwheel tadpole alex ];
"pinwheel/alex.pinwheel-tadpole-ed25519.age".publicKeys = [ pinwheel alex ];
"pinwheel/alex.pinwheel-tadpole-ed25519.pub.age".publicKeys = [ pinwheel tadpole alex ];
"pinwheel/alex.pinwheel-github.com.age".publicKeys = [ pinwheel alex ];
"pinwheel/alex.pinwheel-github.com.pub.age".publicKeys = [ pinwheel alex ];
"pinwheel/alex.pinwheel-github.com-signing.age".publicKeys = [ pinwheel alex ];