feat: update readmes and keys and fixes

This commit is contained in:
Jet 2026-03-17 01:46:02 -07:00
parent f1c75d2109
commit b2d9406831
No known key found for this signature in database
16 changed files with 472 additions and 534 deletions

1
pi/.envrc Normal file
View file

@ -0,0 +1 @@
use flake

View file

@ -16,6 +16,14 @@ On startup it also syncs the initial state.
## Setup
### Prerequisites
If you're building on an x86_64 machine, you need binfmt emulation for aarch64. On NixOS, add this to your system config and rebuild:
```nix
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
```
### 1. Flash the SD card
```sh
@ -23,14 +31,12 @@ nix build .#nixosConfigurations.bootstrap.config.system.build.sdImage
dd if=result/sd-image/*.img of=/dev/sdX bs=4M status=progress
```
Boot the Pi. It connects to the Noisebridge WiFi automatically.
Boot the Pi. It connects to the Noisebridge WiFi automatically and is discoverable via mDNS as `noisebridge-pi.local`.
### 2. Find the Pi
```sh
nmap -sn 192.168.1.0/24
# or
arp -a
ping noisebridge-pi.local
```
### 3. SSH host key
@ -38,7 +44,7 @@ arp -a
Grab the key and add it to `secrets/secrets.nix`:
```sh
ssh-keyscan <pi-ip> | grep ed25519
ssh-keyscan noisebridge-pi.local 2>/dev/null | grep ed25519
```
```nix

View file

@ -5,7 +5,7 @@
hardware.enableRedistributableFirmware = true;
networking.hostName = "noisebell";
networking.hostName = "noisebridge-pi";
networking.wireless = {
enable = true;
@ -16,6 +16,15 @@
};
};
services.avahi = {
enable = true;
nssmdns4 = true;
publish = {
enable = true;
addresses = true;
};
};
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE40ISu3ydCqfdpb26JYD5cIN0Fu0id/FDS+xjB5zpqu"

View file

@ -3,13 +3,33 @@
{
system.stateVersion = "24.11";
networking.hostName = "noisebell";
networking.hostName = "noisebridge-pi";
networking.wireless = {
enable = true;
networks."Noisebridge".psk = "noisebridge";
};
services.avahi = {
enable = true;
nssmdns4 = true;
publish = {
enable = true;
addresses = true;
};
};
# Decrypted at runtime by agenix
age.secrets.tailscale-auth-key.file = ./secrets/tailscale-auth-key.age;
age.secrets.api-key.file = ./secrets/api-key.age;
age.secrets.inbound-api-key.file = ./secrets/inbound-api-key.age;
age.secrets.api-key = {
file = ./secrets/api-key.age;
owner = "noisebell";
};
age.secrets.inbound-api-key = {
file = ./secrets/inbound-api-key.age;
owner = "noisebell";
};
services.noisebell = {
enable = true;
@ -34,5 +54,6 @@
};
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE40ISu3ydCqfdpb26JYD5cIN0Fu0id/FDS+xjB5zpqu"
];
}

View file

@ -180,5 +180,11 @@
system = "aarch64-linux";
modules = [ ./bootstrap.nix ];
};
devShells.x86_64-linux.default = let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
in pkgs.mkShell {
packages = [ agenix.packages.x86_64-linux.default ];
};
};
}

842
pi/pi-service/Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@ edition = "2021"
anyhow = "1.0"
axum = "0.8"
libc = "0.2"
reqwest = { version = "0.12", features = ["json"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
rppal = "0.22"
sd-notify = "0.4"
serde = { version = "1.0", features = ["derive"] }

64
pi/pi-service/flake.lock generated Normal file
View file

@ -0,0 +1,64 @@
{
"nodes": {
"crane": {
"locked": {
"lastModified": 1773189535,
"narHash": "sha256-E1G/Or6MWeP+L6mpQ0iTFLpzSzlpGrITfU2220Gq47g=",
"owner": "ipetkov",
"repo": "crane",
"rev": "6fa2fb4cf4a89ba49fc9dd5a3eb6cde99d388269",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1773646010,
"narHash": "sha256-iYrs97hS7p5u4lQzuNWzuALGIOdkPXvjz7bviiBjUu8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5b2c2d84341b2afb5647081c1386a80d7a8d8605",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"crane": "crane",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1773716879,
"narHash": "sha256-vXCTasEzzTTd0ZGEuyle20H2hjRom66JeNr7i2ktHD0=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "1a9ddeb45c5751b800331363703641b84d1f41f0",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View file

@ -42,6 +42,9 @@
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER =
"${crossPkgs.stdenv.cc.targetPrefix}cc";
TARGET_CC = "${crossPkgs.stdenv.cc.targetPrefix}cc";
CC_aarch64_unknown_linux_gnu = "${crossPkgs.stdenv.cc.targetPrefix}cc";
HOST_CC = "${pkgs.stdenv.cc.nativePrefix}cc";
depsBuildBuild = [ crossPkgs.stdenv.cc ];

View file

@ -264,7 +264,7 @@ async fn main() -> Result<()> {
// pin must live for the entire program — rppal runs interrupts on a background
// thread tied to the InputPin. If pin drops, the interrupt thread is joined and
// monitoring stops. We move it into a binding that lives until main() returns.
let _pin = pin;
let mut _pin = pin;
_pin.set_async_interrupt(
Trigger::Both,
Some(Duration::from_secs(debounce_secs)),

1
pi/result Symbolic link
View file

@ -0,0 +1 @@
/nix/store/pmrzmz2b2hsffk62icl3c0ni56gpi3qs-nixos-image-sd-card-26.05.20260308.9dcb002-aarch64-linux.img.zst

7
pi/secrets/api-key.age Normal file
View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 Ziw7aw KeT7ZRx4LnoXw4TzbqAZ6U4tc74XdTGOoFvF3p1cwwc
FMlEdlMjMGfMJByOBYaY2m0Zr6eGOVm/wYCBkUMUUmg
-> ssh-ed25519 jcT/MQ A0b/6ZhKbqAk8Wx/jCcZsPSygXDyll+f6v8GmM3v1T8
BE4MTRbbXBFGVYFpKdbD8EzYSLCZxxo3UX9hxrlX9N8
--- rsyZbWLKxYWHT71Yg0nVryroF8QCjmVvGsYidVM2LP0
lh^²õM5£<35>Ê<><>QO¤¼'Ûs­xœUë§å¥[[‰Ðf1¦Ï1Nô"¡K—ð„ÿ ߬Ëçbb*FÐÉhPõu»¯sáÀ

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 Ziw7aw Gykk5VLi/S/Lbf0YDFG7rax5WCIwjmfJMpe9r8XK4T0
nbggjY+m082BdKzUYucVFrwu08ziQtnY3BMXQ2dwMJo
-> ssh-ed25519 jcT/MQ OmtLLN7acSjwZrbYpc8eCOfgw1ZelHk2OWusj3kukyM
DoW2NvsOBLHhfa7NYEZP92nm1fAY7gYjM+/WHIPLD88
--- HuvJEBrp5h5PXzlruLVL9pIKmlu8VBK17spsb/gco2E
`%ñ(OÐÜtãNÝAß^ؽÞz¿ô Ü%i'cÖGKý3v0bZ0߇ПŒ Ü\ŒÙ”¸2gIV†+9˲¦Í1ÅA¢T.V‡MöZ

View file

@ -1,8 +1,9 @@
let
pi = "ssh-ed25519 AAAA..."; # Pi's SSH host public key
jet = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE40ISu3ydCqfdpb26JYD5cIN0Fu0id/FDS+xjB5zpqu";
pi = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKmJFZAVJUjDziQ7XytVhQIv+Pm9hnbVU0flxZK17K5E";
in
{
"api-key.age".publicKeys = [ pi ];
"inbound-api-key.age".publicKeys = [ pi ];
"tailscale-auth-key.age".publicKeys = [ pi ];
"api-key.age".publicKeys = [ jet pi ];
"inbound-api-key.age".publicKeys = [ jet pi ];
"tailscale-auth-key.age".publicKeys = [ jet pi ];
}

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 Ziw7aw VR4dTYsFGIL0wGdikj1l034Uxg+C06qn9xwNrDfrYGg
FSp36eUOslycLme0hQalv/6oS6tQmJbXbIZ9ezaCznc
-> ssh-ed25519 jcT/MQ 65epjpYA8RNKGxgyEbASm7aZaAdaj88FH2D3/yWHXH0
rUhjanumw1mr/YkpMYfVamegTKNMXkQS/CifOTvQHAA
--- nyitQGsf/UyVmRaqMXOBXYRhbeViymeHhCWZkKqtfNo
Öè!ñ¯¡¿áf#ÙŒCZGßÔíByÆ%©èA<C3A8>·µ/ç~}õJA¬(„³™‡ru¬Lþ•“gðDy§Â2RÑà®vû<76>€%¼eP ÈÕ(ÀqŽ»ÛÃÔ