Compare commits

..

1 Commits

Author SHA1 Message Date
c9d08c72e7 WIP: matrix: add signal bridge 2023-01-16 06:20:17 +00:00
96 changed files with 320 additions and 1001 deletions

39
flake.lock generated
View File

@@ -39,11 +39,11 @@
"mobile-nixos": {
"flake": false,
"locked": {
"lastModified": 1674593731,
"narHash": "sha256-RHJOhxqPKLxbLLabbj1IEuUQqO76TOTtmpxYyTtfDmU=",
"lastModified": 1670131242,
"narHash": "sha256-T/o1/3gffr010fsqgNshs1NJJjsnUYvQnUZgm6hilsY=",
"owner": "nixos",
"repo": "mobile-nixos",
"rev": "4d2093efa7efa00131d385fd9d11e54ce16bc57a",
"rev": "5ee45cc1f8e43f4af14ee17ccef9156b0db8cd77",
"type": "github"
},
"original": {
@@ -56,26 +56,27 @@
"inputs": {
"nixpkgs": [
"nixpkgs-unpatched"
]
],
"patches": []
},
"locked": {
"lastModified": 1,
"narHash": "sha256-P5BXhRIaKF6ze3am7CY//NFOJ4ihoys9h0ka9S15VV4=",
"path": "/nix/store/41f11k8hk1qjd440mavrybc7xgrcp9gj-source/nixpatches",
"narHash": "sha256-d3XSehPFkNwvwlOYy7gch0NLxOgdXuV7j5r/Qsn7kHc=",
"path": "/nix/store/wq6rmmnd7yhw9w44k54w4x5v63ah1psr-source/nixpatches",
"type": "path"
},
"original": {
"path": "/nix/store/41f11k8hk1qjd440mavrybc7xgrcp9gj-source/nixpatches",
"path": "/nix/store/wq6rmmnd7yhw9w44k54w4x5v63ah1psr-source/nixpatches",
"type": "path"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1674407282,
"narHash": "sha256-2qwc8mrPINSFdWffPK+ji6nQ9aGnnZyHSItVcYDZDlk=",
"lastModified": 1673704454,
"narHash": "sha256-5Wdj1MgdOgn3+dMFIBtg+IAYZApjF8JzwLWDPieg0C4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "ab1254087f4cdf4af74b552d7fc95175d9bdbb49",
"rev": "a83ed85c14fcf242653df6f4b0974b7e1c73c6c6",
"type": "github"
},
"original": {
@@ -87,11 +88,11 @@
},
"nixpkgs-stable_2": {
"locked": {
"lastModified": 1674352297,
"narHash": "sha256-OkAnJPrauEcUCrst4/3DKoQfUn2gXKuU6CFvhtMrLgg=",
"lastModified": 1673740915,
"narHash": "sha256-MMH8zONfqahgHly3K8/A++X34800rajA/XgZ2DzNL/M=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "918b760070bb8f48cb511300fcd7e02e13058a2e",
"rev": "7c65528c3f8462b902e09d1ccca23bb9034665c2",
"type": "github"
},
"original": {
@@ -103,11 +104,11 @@
},
"nixpkgs-unpatched": {
"locked": {
"lastModified": 1674459583,
"narHash": "sha256-L0UZl/u2H3HGsrhN+by42c5kNYeKtdmJiPzIRvEVeiM=",
"lastModified": 1673631141,
"narHash": "sha256-AprpYQ5JvLS4wQG/ghm2UriZ9QZXvAwh1HlgA/6ZEVQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "1b1f50645af2a70dc93eae18bfd88d330bfbcf7f",
"rev": "befc83905c965adfd33e5cae49acb0351f6e0404",
"type": "github"
},
"original": {
@@ -136,11 +137,11 @@
"nixpkgs-stable": "nixpkgs-stable_2"
},
"locked": {
"lastModified": 1674546403,
"narHash": "sha256-vkyNv0xzXuEnu9v52TUtRugNmQWIti8c2RhYnbLG71w=",
"lastModified": 1673752321,
"narHash": "sha256-EFfXY1ZHJq4FNaNQA9x0djtu/jiOhBbT0Xi+BT06cJw=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "b6ab3c61e2ca5e07d1f4eb1b67304e2670ea230c",
"rev": "e18eefd2b133a58309475298052c341c08470717",
"type": "github"
},
"original": {

View File

@@ -26,6 +26,8 @@
nixpkgs = {
url = "./nixpatches";
inputs.nixpkgs.follows = "nixpkgs-unpatched";
# TODO: remove this dependency injection: it's from when we used url = path:...
inputs.patches.follows = "";
};
mobile-nixos = {
# <https://github.com/nixos/mobile-nixos>
@@ -170,7 +172,6 @@
};
init-feed = {
# use like `nix run '.#init-feed' uninsane.org`
type = "app";
program = "${pkgs.feeds.passthru.initFeedScript}";
};
@@ -186,6 +187,9 @@
description = "python environment for data processing";
};
};
# unofficial output; used by inputs.nixpatches
nixpatches = import ./nixpatches/list.nix;
};
}

View File

@@ -1,41 +0,0 @@
{ ... }:
{
sops.secrets."ddns_afraid" = {
sopsFile = ../../../secrets/servo.yaml;
};
sops.secrets."ddns_he" = {
sopsFile = ../../../secrets/servo.yaml;
};
sops.secrets."dovecot_passwd" = {
sopsFile = ../../../secrets/servo.yaml;
};
sops.secrets."duplicity_passphrase" = {
sopsFile = ../../../secrets/servo.yaml;
};
sops.secrets."freshrss_passwd" = {
sopsFile = ../../../secrets/servo.yaml;
};
sops.secrets."matrix_synapse_secrets" = {
sopsFile = ../../../secrets/servo.yaml;
};
sops.secrets."mautrix_signal_env" = {
sopsFile = ../../../secrets/servo/mautrix_signal_env.bin;
};
sops.secrets."mediawiki_pw" = {
sopsFile = ../../../secrets/servo.yaml;
};
sops.secrets."pleroma_secrets" = {
sopsFile = ../../../secrets/servo.yaml;
};
sops.secrets."wg_ovpns_privkey" = {
sopsFile = ../../../secrets/servo.yaml;
};
}

View File

@@ -1,34 +0,0 @@
# config options:
# - <https://github.com/mautrix/signal/blob/master/mautrix_signal/example-config.yaml>
{ config, pkgs, ... }:
{
services.signald.enable = true;
services.mautrix-signal.enable = true;
services.mautrix-signal.environmentFile =
config.sops.secrets.mautrix_signal_env.path;
services.mautrix-signal.settings.signal.socket_path = "/run/signald/signald.sock";
services.mautrix-signal.settings.homeserver.domain = "uninsane.org";
services.mautrix-signal.settings.bridge.permissions."@colin:uninsane.org" = "admin";
services.matrix-synapse.settings.app_service_config_files = [
# auto-created by mautrix-signal service
"/var/lib/mautrix-signal/signal-registration.yaml"
];
systemd.services.mautrix-signal.serviceConfig = {
# allow communication to signald
SupplementaryGroups = [ "signald" ];
ReadWritePaths = [ "/run/signald" ];
};
sane.persist.sys.plaintext = [
{ user = "mautrix-signal"; group = "mautrix-signal"; directory = "/var/lib/mautrix-signal"; }
];
sops.secrets."mautrix_signal_env" = {
format = "binary";
mode = "0440";
owner = config.users.users.mautrix-signal.name;
group = config.users.users.matrix-synapse.name;
};
}

View File

@@ -0,0 +1,16 @@
{ lib, pkgs, ... }:
{
# persist external pairings by default
sane.persist.sys.plaintext = [ "/var/lib/bluetooth" ];
sane.fs."/var/lib/bluetooth".generated.acl.mode = "0700";
sane.fs."/var/lib/bluetooth/.secrets.stamp" = {
wantedBeforeBy = [ "bluetooth.service" ];
# XXX: install-bluetooth uses sed, but that's part of the default systemd unit path, it seems
generated.script.script = builtins.readFile ../../scripts/install-bluetooth + ''
touch "/var/lib/bluetooth/.secrets.stamp"
'';
generated.script.scriptArgs = [ "/run/secrets/bt" ];
};
}

View File

@@ -1,10 +1,11 @@
{ pkgs, ... }:
{
imports = [
./bluetooth.nix
./cross.nix
./feeds.nix
./fs.nix
./hardware.nix
./hardware
./i2p.nix
./ids.nix
./machine-id.nix
@@ -29,9 +30,6 @@
"/var/lib/machines" # maybe not needed, but would be painful to add a VM and forget.
];
# some services which use private directories error if the parent (/var/lib/private) isn't 700.
sane.fs."/var/lib/private".dir.acl.mode = "0700";
nixpkgs.config.allowUnfree = true;
# time.timeZone = "America/Los_Angeles";

View File

@@ -47,6 +47,7 @@ let
podcasts = [
(fromDb "lexfridman.com/podcast" // rat)
# (mkPod "https://lexfridman.com/feed/podcast/" // rat // weekly)
## Astral Codex Ten
(fromDb "sscpodcast.libsyn.com" // rat)
## Econ Talk
@@ -84,14 +85,10 @@ let
(fromDb "feed.podbean.com/matrixlive/feed.xml" // tech)
## Michael Malice - Your Welcome -- also available here: <https://origin.podcastone.com/podcast?categoryID2=2232>
(fromDb "rss.art19.com/your-welcome" // pol)
(fromDb "seattlenice.buzzsprout.com" // pol)
## Sci-Fi? has Peter Watts; author of No Moods, Ads or Cutesy Fucking Icons (rifters.com)
(fromDb "talesfromthebridge.buzzsprout.com" // tech)
];
texts = [
# AGGREGATORS (> 1 post/day)
(fromDb "lwn.net" // tech)
(fromDb "lesswrong.com" // rat)
(fromDb "econlib.org" // pol)
@@ -108,11 +105,8 @@ let
# DEVELOPERS
(fromDb "uninsane.org" // tech)
(fromDb "mg.lol" // tech)
(fromDb "drewdevault.com" // tech)
## Ken Shirriff
(fromDb "righto.com" // tech)
## shared blog by a few NixOS devs, notably onny
(fromDb "project-insanity.org" // tech)
## Vitalik Buterin
(mkText "https://vitalik.ca/feed.xml" // tech // infrequent)
## ian (Sanctuary)

View File

@@ -2,6 +2,7 @@
{
imports = [
./all.nix
./x86_64.nix
];
}

View File

@@ -1,7 +1,8 @@
{ lib, pkgs, ... }:
with lib;
{
config = lib.mkIf (pkgs.system == "x86_64-linux") {
config = mkIf (pkgs.system == "x86_64-linux") {
boot.initrd.availableKernelModules = [
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
"usb_storage" # rpi needed this to boot from usb storage, i think.

View File

@@ -21,12 +21,6 @@
sane.ids.freshrss.uid = 2401;
sane.ids.freshrss.gid = 2401;
sane.ids.mediawiki.uid = 2402;
sane.ids.signald.uid = 2403;
sane.ids.signald.gid = 2403;
sane.ids.mautrix-signal.uid = 2404;
sane.ids.mautrix-signal.gid = 2404;
sane.ids.navidrome.uid = 2405;
sane.ids.navidrome.gid = 2405;
sane.ids.colin.uid = 1000;
sane.ids.guest.uid = 1100;

View File

@@ -1,6 +1,16 @@
{ config, lib, pkgs, ... }:
{
# if using router's DNS, these mappings will already exist.
# if using a different DNS provider (which servo does), then we need to explicity provide them.
# ugly hack. would be better to get servo to somehow use the router's DNS
networking.hosts = {
"192.168.0.5" = [ "servo" ];
"192.168.0.20" = [ "lappy" ];
"192.168.0.22" = [ "desko" ];
"192.168.0.48" = [ "moby" ];
};
# the default backend is "wpa_supplicant".
# wpa_supplicant reliably picks weak APs to connect to.
# see: <https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/474>
@@ -20,4 +30,14 @@
General.RoamThreshold = "-52"; # default -70
General.RoamThreshold5G = "-52"; # default -76
};
sane.fs."/var/lib/iwd/.secrets.psk.stamp" = {
wantedBeforeBy = [ "iwd.service" ];
generated.acl.mode = "0600";
# XXX: install-iwd uses sed, but that's part of the default systemd unit path, it seems
generated.script.script = builtins.readFile ../../scripts/install-iwd + ''
touch "/var/lib/iwd/.secrets.psk.stamp"
'';
generated.script.scriptArgs = [ "/run/secrets/iwd" "/var/lib/iwd" ];
};
}

View File

@@ -1,33 +1,24 @@
{ config, lib, sane-data, sane-lib, ... }:
let
inherit (builtins) head map mapAttrs tail;
inherit (lib) concatStringsSep mkMerge reverseList;
in
{
sane.ssh.pubkeys =
let
# path is a DNS-style path like [ "org" "uninsane" "root" ]
keyNameForPath = path:
let
rev = reverseList path;
name = head rev;
host = concatStringsSep "." (tail rev);
rev = lib.reverseList path;
name = builtins.head rev;
host = lib.concatStringsSep "." (builtins.tail rev);
in
"${name}@${host}";
# [{ path :: [String], value :: String }] for the keys we want to install
globalKeys = sane-lib.flattenAttrs sane-data.keys;
domainKeys = sane-lib.flattenAttrs (
mapAttrs (host: cfg: {
colin = cfg.ssh.user_pubkey;
root = cfg.ssh.host_pubkey;
}) config.sane.hosts.by-name
);
in mkMerge (map
localKeys = sane-lib.flattenAttrs sane-data.keys.org.uninsane.local;
in lib.mkMerge (builtins.map
({ path, value }: {
"${keyNameForPath path}" = lib.mkIf (value != null) value;
"${keyNameForPath path}" = value;
})
(globalKeys ++ domainKeys)
(globalKeys ++ localKeys)
);
}

View File

@@ -126,8 +126,8 @@ in
services.openssh = {
enable = true;
settings.PermitRootLogin = "no";
settings.PasswordAuthentication = false;
permitRootLogin = "no";
passwordAuthentication = false;
};
};
}

View File

@@ -6,16 +6,12 @@
# sane.packages.enableDevPkgs = true;
sane.roles.client = true;
sane.services.wg-home.enable = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."desko".wg-home.ip;
sane.gui.sway.enable = true;
sane.services.duplicity.enable = true;
sane.services.nixserve.enable = true;
sane.services.nixserve.sopsFile = ../../../secrets/desko.yaml;
sane.services.nixserve.sopsFile = ../../secrets/desko.yaml;
sane.persist.enable = true;
sane.gui.sway.enable = true;
boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
@@ -23,7 +19,7 @@
services.usbmuxd.enable = true;
sops.secrets.colin-passwd = {
sopsFile = ../../../secrets/desko.yaml;
sopsFile = ../../secrets/desko.yaml;
neededForUsers = true;
};
@@ -45,7 +41,7 @@
};
sops.secrets.duplicity_passphrase = {
sopsFile = ../../../secrets/desko.yaml;
sopsFile = ../../secrets/desko.yaml;
};
programs.steam = {

View File

@@ -1,16 +1,12 @@
# trampoline from flake.nix into the specific host definition, while doing a tiny bit of common setup
# args from flake-level `import`
{ hostName, localSystem }:
# module args
{ config, ... }:
{ ... }:
{
imports = [
./by-name/${hostName}
./${hostName}
./common
./modules
];
networking.hostName = hostName;

View File

@@ -1,13 +1,9 @@
{ config, pkgs, ... }:
{ pkgs, ... }:
{
imports = [
./fs.nix
];
sane.roles.client = true;
sane.services.wg-home.enable = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip;
# sane.packages.enableDevPkgs = true;
# sane.users.guest.enable = true;
@@ -18,7 +14,7 @@
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
sops.secrets.colin-passwd = {
sopsFile = ../../../secrets/lappy.yaml;
sopsFile = ../../secrets/lappy.yaml;
neededForUsers = true;
};

View File

@@ -6,10 +6,6 @@
./kernel.nix
];
sane.roles.client = true;
sane.services.wg-home.enable = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."moby".wg-home.ip;
# cross-compiled documentation is *slow*.
# no obvious way to natively compile docs (2022/09/29).
# entrypoint is nixos/modules/misc/documentation.nix
@@ -23,7 +19,7 @@
services.getty.autologinUser = "root"; # allows for emergency maintenance?
sops.secrets.colin-passwd = {
sopsFile = ../../../secrets/moby.yaml;
sopsFile = ../../secrets/moby.yaml;
neededForUsers = true;
};
@@ -58,10 +54,9 @@
# without this some GUI apps fail: `DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory`
# this is because they can't allocate enough video ram.
# the default CMA seems to be 32M.
# i was running fine with 256MB from 2022/07-ish through 2022/12-ish, but then the phone quit reliably coming back from sleep: maybe a memory leak?
# the default CMA seems to be 32M. we could probably get by with as little as 64M, and safely with 128M.
# `cat /proc/meminfo` to see CmaTotal/CmaFree if interested in tuning this.
boot.kernelParams = [ "cma=384M" ];
boot.kernelParams = [ "cma=256M" ];
# mobile-nixos' /lib/firmware includes:
# rtl_bt (bluetooth)

View File

@@ -1,12 +0,0 @@
{ ... }:
{
imports = [
./derived-secrets.nix
./hardware
./hostnames.nix
./hosts.nix
./roles
./wg-home.nix
];
}

View File

@@ -1,47 +0,0 @@
{ config, lib, ... }:
let
inherit (builtins) toString;
inherit (lib) mapAttrs mkOption types;
cfg = config.sane.derived-secrets;
secret = types.submodule {
options = {
len = mkOption {
type = types.int;
};
encoding = mkOption {
type = types.enum [ "base64" ];
};
};
};
in
{
options = {
sane.derived-secrets = mkOption {
type = types.attrsOf secret;
default = {};
description = ''
fs path => secret options.
for each entry, we create an item at the given path whose value is deterministic,
but also pseudo-random and not predictable by anyone without root access to the machine.
as PRNG source we use the host ssh key, and derived secrets are salted based on the destination path.
'';
};
};
config = {
sane.fs = mapAttrs (path: c: {
generated.script.script = ''
echo "$1" | cat /dev/stdin /etc/ssh/host_keys/ssh_host_ed25519_key \
| sha512sum \
| cut -c 1-${toString (c.len * 2)} \
| tr a-z A-Z \
| basenc -d --base16 \
| basenc --${c.encoding} \
> "$1"
'';
generated.script.scriptArgs = [ path ];
generated.acl.mode = "0600";
}) cfg;
};
}

View File

@@ -1,11 +0,0 @@
{ config, lib, ... }:
{
# if using router's DNS, these mappings will already exist.
# if using a different DNS provider (which servo does), then we need to explicity provide them.
# ugly hack. would be better to get servo to somehow use the router's DNS
networking.hosts = lib.mapAttrs' (host: cfg: {
name = cfg.lan-ip;
value = [ host ];
}) config.sane.hosts.by-name;
}

View File

@@ -1,100 +0,0 @@
{ config, lib, ... }:
let
inherit (lib) attrValues filterAttrs mkMerge mkOption types;
cfg = config.sane.hosts;
host = types.submodule ({ config, ... }: {
options = {
ssh.user_pubkey = mkOption {
type = types.str;
description = ''
ssh pubkey that the primary user of this machine will use when connecting to other machines.
e.g. "ssh-ed25519 AAAA<base64>".
'';
};
ssh.host_pubkey = mkOption {
type = types.str;
description = ''
ssh pubkey which this host will present to connections initiated against it.
e.g. "ssh-ed25519 AAAA<base64>".
'';
};
wg-home.pubkey = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
wireguard public key for the wg-home VPN.
e.g. "pWtnKW7f7sNIZQ2M83uJ7cHg3IL1tebE3IoVkCgjkXM=".
'';
};
wg-home.ip = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
IP address to use on the wg-home VPN.
e.g. "10.0.10.5";
'';
};
wg-home.endpoint = mkOption {
type = types.nullOr types.str;
default = null;
};
lan-ip = mkOption {
type = types.str;
description = ''
ip address when on the lan.
e.g. "192.168.0.5";
'';
};
};
});
in
{
options = {
sane.hosts.by-name = mkOption {
type = types.attrsOf host;
default = {};
description = ''
map of hostname => attrset of information specific to that host,
like its ssh pubkey, etc.
'';
};
};
config = {
# TODO: this should be populated per-host
sane.hosts.by-name."desko" = {
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
wg-home.pubkey = "17PMZssYi0D4t2d0vbmhjBKe1sGsE8kT8/dod0Q2CXc=";
wg-home.ip = "10.0.10.22";
lan-ip = "192.168.0.22";
};
sane.hosts.by-name."lappy" = {
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
wg-home.pubkey = "FTUWGw2p4/cEcrrIE86PWVnqctbv8OYpw8Gt3+dC/lk=";
wg-home.ip = "10.0.10.20";
lan-ip = "192.168.0.20";
};
sane.hosts.by-name."moby" = {
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw";
wg-home.pubkey = "I7XIR1hm8bIzAtcAvbhWOwIAabGkuEvbWH/3kyIB1yA=";
wg-home.ip = "10.0.10.48";
lan-ip = "192.168.0.48";
};
sane.hosts.by-name."servo" = {
ssh.user_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX";
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
wg-home.pubkey = "roAw+IUFVtdpCcqa4khB385Qcv9l5JAB//730tyK4Wk=";
wg-home.ip = "10.0.10.5";
wg-home.endpoint = "uninsane.org:51820";
lan-ip = "192.168.0.5";
};
};
}

View File

@@ -1,18 +0,0 @@
{ config, lib, pkgs, ... }:
{
config = lib.mkIf config.sane.roles.client {
# persist external pairings by default
sane.persist.sys.plaintext = [ "/var/lib/bluetooth" ];
sane.fs."/var/lib/bluetooth".generated.acl.mode = "0700";
sane.fs."/var/lib/bluetooth/.secrets.stamp" = {
wantedBeforeBy = [ "bluetooth.service" ];
# XXX: install-bluetooth uses sed, but that's part of the default systemd unit path, it seems
generated.script.script = builtins.readFile ../../../../scripts/install-bluetooth + ''
touch "/var/lib/bluetooth/.secrets.stamp"
'';
generated.script.scriptArgs = [ "/run/secrets/bt" ];
};
};
}

View File

@@ -1,17 +0,0 @@
{ config, lib, ... }:
let
inherit (lib) mkIf mkOption types;
in
{
imports = [
./bluetooth-pairings.nix
./wifi-pairings.nix
];
# option is consumed by the other imports in this dir
options.sane.roles.client = mkOption {
type = types.bool;
default = false;
};
}

View File

@@ -1,15 +0,0 @@
{ config, lib, pkgs, ... }:
{
config = lib.mkIf config.sane.roles.client {
sane.fs."/var/lib/iwd/.secrets.psk.stamp" = {
wantedBeforeBy = [ "iwd.service" ];
generated.acl.mode = "0600";
# XXX: install-iwd uses sed, but that's part of the default systemd unit path, it seems
generated.script.script = builtins.readFile ../../../../scripts/install-iwd + ''
touch "/var/lib/iwd/.secrets.psk.stamp"
'';
generated.script.scriptArgs = [ "/run/secrets/iwd" "/var/lib/iwd" ];
};
};
}

View File

@@ -1,6 +0,0 @@
{ ... }:
{
imports = [
./client
];
}

View File

@@ -1,80 +0,0 @@
{ config, lib, pkgs, ... }:
let
inherit (builtins) filter map;
inherit (lib) concatMap mapAttrsToList mkIf mkMerge mkOption optionalAttrs types;
cfg = config.sane.services.wg-home;
server-cfg = config.sane.hosts.by-name."servo".wg-home;
mkPeer = { ips, pubkey, endpoint }: {
publicKey = pubkey;
allowedIPs = map (k: "${k}/32") ips;
} // (optionalAttrs (endpoint != null) {
inherit endpoint;
# send keepalives every 25 seconds to keep NAT routes live.
# only need to do this from client -> server though, i think.
persistentKeepalive = 25;
# allows wireguard to notice DNS/hostname changes, with this much effective TTL.
dynamicEndpointRefreshSeconds = 600;
});
# make separate peers to route each given host
mkClientPeers = hosts: map (p: mkPeer {
inherit (p) pubkey endpoint;
ips = [ p.ip ];
}) hosts;
# make a single peer which routes all the given hosts
mkServerPeer = hosts: mkPeer {
inherit (server-cfg) pubkey endpoint;
ips = map (h: h.ip) hosts;
};
in
{
options = {
sane.services.wg-home.enable = mkOption {
type = types.bool;
default = false;
};
sane.services.wg-home.ip = mkOption {
type = types.str;
};
};
config = mkIf cfg.enable {
# generate a (deterministic) wireguard private key
sane.derived-secrets."/run/wg-home.priv" = {
len = 32;
encoding = "base64";
};
# wireguard VPN which allows everything on my domain to speak to each other even when
# not behind a shared LAN.
# this config defines both the endpoint (server) and client configs
# for convenience, have both the server and client use the same port for their wireguard connections.
networking.firewall.allowedUDPPorts = [ 51820 ];
networking.wireguard.interfaces.wg-home = {
listenPort = 51820;
privateKeyFile = "/run/wg-home.priv";
preSetup =
let
gen-key = config.sane.fs."/run/wg-home.priv".unit;
in
"${pkgs.systemd}/bin/systemctl start '${gen-key}'";
ips = [
"${cfg.ip}/24"
];
peers =
let
all-peers = mapAttrsToList (_: hostcfg: hostcfg.wg-home) config.sane.hosts.by-name;
peer-list = filter (p: p.ip != null && p.ip != cfg.ip && p.pubkey != null) all-peers;
in
if cfg.ip == server-cfg.ip then
# if we're the server, then we maintain the entire client list
mkClientPeers peer-list
else
# but if we're a client, we maintain a single peer -- the server -- which does the actual routing
[ (mkServerPeer peer-list) ];
};
};
}

View File

@@ -1,32 +1,29 @@
{ config, pkgs, ... }:
{ pkgs, ... }:
{
imports = [
./fs.nix
./net.nix
./secrets.nix
./users.nix
./services
];
sane.packages.extraUserPkgs = with pkgs; [
sane.packages.extraUserPkgs = [
# for administering services
freshrss
matrix-synapse
signaldctl
pkgs.matrix-synapse
pkgs.freshrss
];
sane.persist.enable = true;
sane.services.dyn-dns.enable = true;
sane.services.wg-home.enable = true;
sane.services.wg-home.ip = config.sane.hosts.by-name."servo".wg-home.ip;
# sane.services.duplicity.enable = true; # TODO: re-enable after HW upgrade
# automatically log in at the virtual consoles.
# using root here makes sure we always have an escape hatch
services.getty.autologinUser = "root";
boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
sops.secrets.duplicity_passphrase = {
sopsFile = ../../secrets/servo.yaml;
};
# both transmission and ipfs try to set different net defaults.
# we just use the most aggressive of the two here:
boot.kernel.sysctl = {

View File

@@ -52,18 +52,18 @@
# services.resolved.extraConfig = ''
# # docs: `man resolved.conf`
# # DNS servers to use via the `wg-ovpns` interface.
# # DNS servers to use via the `wg0` interface.
# # i hope that from the root ns, these aren't visible.
# DNS=46.227.67.134%wg-ovpns 192.165.9.158%wg-ovpns
# DNS=46.227.67.134%wg0 192.165.9.158%wg0
# FallbackDNS=1.1.1.1 9.9.9.9
# '';
# OVPN CONFIG (https://www.ovpn.com):
# DOCS: https://nixos.wiki/wiki/WireGuard
# if you `systemctl restart wireguard-wg-ovpns`, make sure to also restart any other services in `NetworkNamespacePath = .../ovpns`.
# if you `systemctl restart wireguard-wg0`, make sure to also restart any other services in `NetworkNamespacePath = .../ovpns`.
# TODO: why not create the namespace as a seperate operation (nix config for that?)
networking.wireguard.enable = true;
networking.wireguard.interfaces.wg-ovpns = let
networking.wireguard.interfaces.wg0 = let
ip = "${pkgs.iproute2}/bin/ip";
in-ns = "${ip} netns exec ovpns";
iptables = "${pkgs.iptables}/bin/iptables";
@@ -159,10 +159,13 @@
# create a new routing table that we can use to proxy traffic out of the root namespace
# through the ovpns namespace, and to the WAN via VPN.
networking.iproute2.rttablesExtraConfig = ''
5 ovpns
5 ovpns
'';
networking.iproute2.enable = true;
sops.secrets."wg_ovpns_privkey" = {
sopsFile = ../../secrets/servo.yaml;
};
# HURRICANE ELECTRIC CONFIG:
# networking.sits = {

View File

@@ -24,4 +24,8 @@ lib.mkIf false
OnUnitActiveSec = "10min";
};
};
sops.secrets."ddns_afraid" = {
sopsFile = ../../../secrets/servo.yaml;
};
}

View File

@@ -27,4 +27,8 @@ lib.mkIf false
OnUnitActiveSec = "10min";
};
};
sops.secrets."ddns_he" = {
sopsFile = ../../../secrets/servo.yaml;
};
}

View File

@@ -11,7 +11,8 @@
{ config, lib, pkgs, sane-lib, ... }:
{
sops.secrets."freshrss_passwd" = {
sops.secrets.freshrss_passwd = {
sopsFile = ../../../secrets/servo.yaml;
owner = config.users.users.freshrss.name;
mode = "0400";
};
@@ -41,10 +42,7 @@
description = "import sane RSS feed list";
after = [ "freshrss-config.service" ];
script = ''
# easiest way to preserve feeds: delete the user, recreate it, import feeds
${pkgs.freshrss}/cli/delete-user.php --user colin || true
${pkgs.freshrss}/cli/create-user.php --user colin --password "$(cat ${config.services.freshrss.passwordFile})" || true
${pkgs.freshrss}/cli/import-for-user.php --user colin --filename ${opml}
${pkgs.freshrss}/cli/import-for-user.php --user admin --filename ${opml}
'';
};

View File

@@ -15,17 +15,6 @@
services.gitea.settings.session.COOKIE_SECURE = true;
# services.gitea.disableRegistration = true;
# gitea doesn't create the git user
users.users.git = {
description = "Gitea Service";
home = "/var/lib/gitea";
useDefaultShell = true;
group = "gitea";
isSystemUser = true;
# sendmail access (not 100% sure if this is necessary)
extraGroups = [ "postdrop" ];
};
services.gitea.settings = {
server = {
# options: "home", "explore", "organizations", "login" or URL fragment (or full URL)

View File

@@ -7,8 +7,8 @@
];
services.jackett.enable = true;
systemd.services.jackett.after = [ "wireguard-wg-ovpns.service" ];
systemd.services.jackett.partOf = [ "wireguard-wg-ovpns.service" ];
systemd.services.jackett.after = [ "wireguard-wg0.service" ];
systemd.services.jackett.partOf = [ "wireguard-wg0.service" ];
systemd.services.jackett.serviceConfig = {
# run this behind the OVPN static VPN
NetworkNamespacePath = "/run/netns/ovpns";

View File

@@ -9,15 +9,17 @@
./signal.nix
];
# allow synapse to read the registration files of its appservices
users.users.matrix-synapse.extraGroups = [ "mautrix-signal" ];
services.matrix-appservices = {
# configure defaults. used by e.g. ./signal.nix
homeserverUrl = "http://127.0.0.1:8008";
homeserverDomain = "uninsane.org";
addRegistrationFiles = true;
};
sane.persist.sys.plaintext = [
{ user = "matrix-synapse"; group = "matrix-synapse"; directory = "/var/lib/matrix-synapse"; }
];
services.matrix-synapse.enable = true;
# this changes the default log level from INFO to WARN.
# maybe there's an easier way?
services.matrix-synapse.settings.log_config = ./synapse-log_level.yaml;
services.matrix-synapse.settings.server_name = "uninsane.org";
@@ -133,7 +135,8 @@
};
sops.secrets."matrix_synapse_secrets" = {
sops.secrets.matrix_synapse_secrets = {
sopsFile = ../../../../secrets/servo.yaml;
owner = config.users.users.matrix-synapse.name;
};
}

View File

@@ -43,7 +43,6 @@
};
};
# TODO: should use a dedicated user
systemd.services.mx-puppet-discord.serviceConfig = {
# fix up to not use /var/lib/private, but just /var/lib
DynamicUser = lib.mkForce false;

View File

@@ -0,0 +1,32 @@
{ ... }:
{
services.signald.enable = true;
# TODO: required?
# comes from <nix-matrix-appservices:examples/mautrix.nix>
systemd.services.matrix-as-signal = {
requires = [ "signald.service" ];
after = [ "signald.service" ];
unitConfig = {
JoinsNamespaceOf = "signald.service";
};
path = [
pkgs.ffmpeg # voice messages need `ffmpeg`
];
};
services.matrix-appservices.services.signal = {
port = 29184;
format = "mautrix-python";
package = pkgs.mautrix-signal;
serviceConfig = {
StateDirectory = [ "matrix-as-signal" "signald" ];
SupplementaryGroups = [ "signald" ];
};
settings.signal = {
socket_path = config.services.signald.socketPath;
outgoing_attachment_dir = "/var/lib/signald/tmp";
};
};
}

View File

@@ -1,8 +1,11 @@
{ lib, ... }:
{ ... }:
{
sane.persist.sys.plaintext = [
{ user = "navidrome"; group = "navidrome"; directory = "/var/lib/navidrome"; }
# TODO: we don't have a static user allocated for navidrome!
# the chown would happen too early for us to set static perms
"/var/lib/private/navidrome"
# { user = "navidrome"; group = "navidrome"; directory = "/var/lib/private/navidrome"; }
];
services.navidrome.enable = true;
services.navidrome.settings = {
@@ -15,20 +18,6 @@
ScanSchedule = "@every 1h";
};
systemd.services.navidrome.serviceConfig = {
# fix to use a normal user so we can configure perms correctly
DynamicUser = lib.mkForce false;
User = "navidrome";
Group = "navidrome";
};
users.groups.navidrome = {};
users.users.navidrome = {
group = "navidrome";
isSystemUser = true;
};
services.nginx.virtualHosts."music.uninsane.org" = {
forceSSL = true;
enableACME = true;

View File

@@ -17,5 +17,5 @@
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."nixcache" = "native";
sane.services.nixserve.enable = true;
sane.services.nixserve.sopsFile = ../../../../secrets/servo.yaml;
sane.services.nixserve.sopsFile = ../../../secrets/servo.yaml;
}

View File

@@ -111,7 +111,7 @@
''
];
systemd.services.pleroma.path = [
systemd.services.pleroma.path = [
# something inside pleroma invokes `sh` w/o specifying it by path, so this is needed to allow pleroma to start
pkgs.bash
# used by Pleroma to strip geo tags from uploads
@@ -135,11 +135,6 @@
# CapabilityBoundingSet = lib.mkForce "~";
# };
# this is required to allow pleroma to send email.
# raw `sendmail` works, but i think pleroma's passing it some funny flags or something, idk.
# hack to fix that.
users.users.pleroma.extraGroups = [ "postdrop" ];
# Pleroma server and web interface
# TODO: enable publog?
services.nginx.virtualHosts."fed.uninsane.org" = {
@@ -184,7 +179,8 @@
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."fed" = "native";
sops.secrets."pleroma_secrets" = {
sops.secrets.pleroma_secrets = {
sopsFile = ../../../secrets/servo.yaml;
owner = config.users.users.pleroma.name;
};
}

View File

@@ -110,8 +110,8 @@ in
services.postfix.enableSubmissions = true;
services.postfix.submissionsOptions = submissionOptions;
systemd.services.postfix.after = [ "wireguard-wg-ovpns.service" ];
systemd.services.postfix.partOf = [ "wireguard-wg-ovpns.service" ];
systemd.services.postfix.after = [ "wireguard-wg0.service" ];
systemd.services.postfix.partOf = [ "wireguard-wg0.service" ];
systemd.services.postfix.serviceConfig = {
# run this behind the OVPN static VPN
NetworkNamespacePath = "/run/netns/ovpns";
@@ -132,8 +132,8 @@ in
# keeping this the same as the hostname seems simplest
services.opendkim.selector = "mx";
systemd.services.opendkim.after = [ "wireguard-wg-ovpns.service" ];
systemd.services.opendkim.partOf = [ "wireguard-wg-ovpns.service" ];
systemd.services.opendkim.after = [ "wireguard-wg0.service" ];
systemd.services.opendkim.partOf = [ "wireguard-wg0.service" ];
systemd.services.opendkim.serviceConfig = {
# run this behind the OVPN static VPN
NetworkNamespacePath = "/run/netns/ovpns";
@@ -197,7 +197,8 @@ in
# }
];
sops.secrets."dovecot_passwd" = {
sops.secrets.dovecot_passwd = {
sopsFile = ../../../secrets/servo.yaml;
owner = config.users.users.dovecot2.name;
# TODO: debug why mail can't be sent without this being world-readable
mode = "0444";

View File

@@ -40,8 +40,8 @@
# transmission will by default not allow the world to read its files.
services.transmission.downloadDirPermissions = "775";
systemd.services.transmission.after = [ "wireguard-wg-ovpns.service" ];
systemd.services.transmission.partOf = [ "wireguard-wg-ovpns.service" ];
systemd.services.transmission.after = [ "wireguard-wg0.service" ];
systemd.services.transmission.partOf = [ "wireguard-wg0.service" ];
systemd.services.transmission.serviceConfig = {
# run this behind the OVPN static VPN
NetworkNamespacePath = "/run/netns/ovpns";

View File

@@ -8,6 +8,7 @@ lib.mkIf false
{
sops.secrets."mediawiki_pw" = {
owner = config.users.users.mediawiki.name;
sopsFile = ../../../secrets/servo.yaml;
};
services.mediawiki.enable = true;

24
hosts/servo/users.nix Normal file
View File

@@ -0,0 +1,24 @@
{ config, ... }:
# installer docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix
{
# automatically log in at the virtual consoles.
# using root here makes sure we always have an escape hatch
services.getty.autologinUser = "root";
# gitea doesn't create the git user
users.users.git = {
description = "Gitea Service";
home = "/var/lib/gitea";
useDefaultShell = true;
group = "gitea";
isSystemUser = true;
# sendmail access (not 100% sure if this is necessary)
extraGroups = [ "postdrop" ];
};
# this is required to allow pleroma to send email.
# raw `sendmail` works, but i think pleroma's passing it some funny flags or something, idk.
# hack to fix that.
users.users.pleroma.extraGroups = [ "postdrop" ];
}

File diff suppressed because one or more lines are too long

View File

@@ -1,21 +0,0 @@
{
"bozo": 0,
"content_length": 14068,
"content_type": "application/xml; charset=utf-8",
"description": "LWN.net is a comprehensive source of news and opinions from\n and about the Linux community. This is the main LWN.net feed,\n listing all articles which are posted to the site front page.",
"favicon": "https://static.lwn.net/images/favicon.png",
"favicon_data_uri": "data:image/png;base64,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",
"hubs": [],
"is_podcast": false,
"is_push": false,
"item_count": 15,
"last_updated": "2023-01-22T15:53:01+00:00",
"score": 18,
"self_url": "",
"site_name": "Welcome to LWN.net [LWN.net]",
"site_url": "https://lwn.net",
"title": "LWN.net",
"url": "https://lwn.net/headlines/newrss",
"velocity": 2.78,
"version": "rss10"
}

View File

@@ -1,21 +0,0 @@
{
"bozo": 0,
"content_length": 11426,
"content_type": "application/rss+xml; charset=utf-8",
"description": "Awesome hacking blog",
"favicon": "",
"favicon_data_uri": "",
"hubs": [],
"is_podcast": false,
"is_push": false,
"item_count": 10,
"last_updated": "2023-01-01T22:57:33+00:00",
"score": 12,
"self_url": "https://blog.project-insanity.org/feed/",
"site_name": "project-insanity.org",
"site_url": "https://blog.project-insanity.org",
"title": "project-insanity.org",
"url": "https://blog.project-insanity.org/feed/",
"velocity": 0.026,
"version": "rss20"
}

View File

@@ -1,23 +0,0 @@
{
"bozo": 0,
"content_length": 96380,
"content_type": "text/xml; charset=utf-8",
"description": "It\u2019s getting harder and harder to talk about politics, especially if you disagree. Well, screw that. Seattle Nice aims to be the most opinionated and smartest analysis of what\u2019s really happening in Seattle politics available in any medium. Each episode dives into contentious and sometimes ridiculous topics, exploring perspectives from across Seattle's political spectrum, from city council brawls to the ways the national political conversation filters through our unique political process. Even if you\u2019re not from Seattle, you need to listen to Seattle Nice. Because it\u2019s coming for you. Unlike the sun, politics rises in the West and sets in the East.",
"favicon": "",
"favicon_data_uri": "",
"hubs": [
"https://pubsubhubbub.appspot.com/"
],
"is_podcast": true,
"is_push": true,
"item_count": 43,
"last_updated": "2023-01-20T21:00:00+00:00",
"score": 12,
"self_url": "https://feeds.buzzsprout.com/1897925.rss",
"site_name": "",
"site_url": "",
"title": "Seattle Nice",
"url": "https://feeds.buzzsprout.com/1897925.rss",
"velocity": 0.104,
"version": "rss20"
}

View File

@@ -1,23 +0,0 @@
{
"bozo": 0,
"content_length": 357855,
"content_type": "text/xml; charset=utf-8",
"description": "Tales From the Bridge is a bi-weekly Science Fiction podcast. Join Tristan, Marty, Kevin, and Sam as they sit down with your favorite science fiction authors and filmmakers. We also discuss the best in sci-fi from books and graphic novels - to television and film. We cover cutting-edge concepts on our news segment; Science Fiction-Science Fact and throw in a bit of trivia for fun. Apple Podcasts; https://podcasts.apple.com/us/podcast/tales-from-the-bridge-all-things-sci-fi/id1570902818 Find out more on our website: https://talesfromthebridge.buzzsprout.com/",
"favicon": "",
"favicon_data_uri": "",
"hubs": [
"https://pubsubhubbub.appspot.com/"
],
"is_podcast": true,
"is_push": true,
"item_count": 64,
"last_updated": "2023-01-18T23:00:00+00:00",
"score": 12,
"self_url": "https://feeds.buzzsprout.com/1795352.rss",
"site_name": "",
"site_url": "",
"title": "Tales From The Bridge: All Things Sci-Fi",
"url": "https://feeds.buzzsprout.com/1795352.rss",
"velocity": 0.101,
"version": "rss20"
}

View File

@@ -5,9 +5,24 @@
org.uninsane = rec {
root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
git.root = root;
local = {
# machine aliases i specify on my lan; not actually asserted as DNS
desko.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX";
desko.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
lappy.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
lappy.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
moby.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU";
moby.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw";
servo.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX";
servo.root = root;
};
};
com.github = {
com.github = rec {
# documented here: <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints>
# Github actually uses multiple keys -- one per format
root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";

View File

@@ -140,7 +140,5 @@ in
cfg.programs
];
};
sane.persist.home.plaintext = [ ".cache/nix-index" ];
};
}

View File

@@ -59,10 +59,10 @@ let
# `wget ...xpi`; `unar ...xpi`; `cat */manifest.json | jq '.browser_specific_settings.gecko.id'`
(addon "ublock-origin" "uBlock0@raymondhill.net" "sha256-a/ivUmY1P6teq9x0dt4CbgHt+3kBsEMMXlOfZ5Hx7cg=")
(addon "sponsorblock" "sponsorBlocker@ajay.app" "sha256-d2K3ufvurWnYVzqLbyR//MgejybkY9exitAf9RdLNRo=")
(addon "bypass-paywalls-clean" "{d133e097-46d9-4ecc-9903-fa6a722a6e0e}" "sha256-JOj5P7c2JTTReHCRZXm4BscaGr3i+9Y4Ey/y621x8PI=")
(addon "bypass-paywalls-clean" "{d133e097-46d9-4ecc-9903-fa6a722a6e0e}" "sha256-t6Q335Nq60mDILPmzem+DT5KflleAPVJL3bsaA+UL0g=")
(addon "sidebery" "{3c078156-979c-498b-8990-85f7987dd929}" "sha256-YONfK/rIjlsrTgRHIt3km07Q7KnpIW89Z9r92ZSCc6w=")
(addon "ether-metamask" "webextension@metamask.io" "sha256-G+MwJDOcsaxYSUXjahHJmkWnjLeQ0Wven8DU/lGeMzA=")
(addon "ublacklist" "@ublacklist" "sha256-RqY5iHzbL2qizth7aguyOKWPyINXmrwOlf/OsfqAS48=")
(addon "ublacklist" "@ublacklist" "sha256-vHe/7EYOzcKeAbTElmt0Rb4E2rX0f3JgXThJaUmaz+M=")
(addon "i2p-in-private-browsing" "i2ppb@eyedeekay.github.io" "sha256-dJcJ3jxeAeAkRvhODeIVrCflvX+S4E0wT/PyYzQBQWs=")
# (addon "browserpass-ce" "browserpass@maximbaz.com" "sha256-sXgUBbRvMnRpeIW1MTkmTcoqtW/8RDXAkxAq1evFkpc=")
(localAddon pkgs.browserpass-extension)

View File

@@ -115,6 +115,7 @@ let
krita
libreoffice-fresh # XXX colin: maybe don't want this on mobile
lollypop
mesa-demos
{ pkg = mpv; dir = [ ".config/mpv/watch_later" ]; }

View File

@@ -4,7 +4,6 @@
./duplicity.nix
./dyn-dns.nix
./kiwix-serve.nix
./mautrix-signal.nix
./nixserve.nix
./trust-dns.nix
];

View File

@@ -1,174 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
dataDir = "/var/lib/mautrix-signal";
registrationFile = "${dataDir}/signal-registration.yaml";
cfg = config.services.mautrix-signal;
settingsFormat = pkgs.formats.json {};
settingsFile =
settingsFormat.generate "mautrix-signal-config.json" cfg.settings;
in
{
options = {
services.mautrix-signal = {
enable = mkEnableOption (lib.mdDoc "Mautrix-Signal, a Matrix-Signal puppeting bridge");
settings = mkOption rec {
apply = recursiveUpdate default;
inherit (settingsFormat) type;
default = {
# defaults based on this upstream example config:
# - <https://github.com/mautrix/signal/blob/master/mautrix_signal/example-config.yaml>
homeserver = {
address = "http://localhost:8008";
software = "standard";
# domain = "SETME";
};
appservice = rec {
address = "http://${hostname}:${toString port}";
hostname = "localhost";
port = 29328;
database = "sqlite:///${dataDir}/mautrix-signal.db";
database_opts = {};
bot_username = "signalbot";
};
bridge = {
username_template = "signal_{userid}";
permissions."*" = "relay";
double_puppet_server_map = {};
login_shared_secret_map = {};
};
logging = {
version = 1;
formatters.precise.format = "[%(levelname)s@%(name)s] %(message)s";
handlers.console = {
class = "logging.StreamHandler";
formatter = "precise";
};
# log to console/systemd instead of file
root = {
level = "INFO";
handlers = ["console"];
};
};
};
example = literalExpression ''
{
homeserver = {
address = "http://localhost:8008";
domain = "mydomain.example";
};
bridge.permissions = {
"@admin:mydomain.example" = "admin";
"mydomain.example" = "user";
};
}
'';
description = lib.mdDoc ''
{file}`config.yaml` configuration as a Nix attribute set.
Configuration options should match those described in
[example-config.yaml](https://github.com/mautrix/signale/blob/master/mautrix_signal/example-config.yaml).
'';
};
environmentFile = mkOption {
type = types.nullOr types.path;
default = null;
description = lib.mdDoc ''
File containing environment variables to be passed to the mautrix-signal service,
in which secret tokens can be specified securely by defining values for e.g.
`MAUTRIX_SIGNAL_APPSERVICE_AS_TOKEN`,
`MAUTRIX_SIGNAL_APPSERVICE_HS_TOKEN`
These environment variables can also be used to set other options by
replacing hierarchy levels by `.`, converting the name to uppercase
and prepending `MAUTRIX_SIGNAL_`.
For example, the first value above maps to
{option}`settings.appservice.as_token`.
The environment variable values can be prefixed with `json::` to have
them be parsed as JSON. For example, `login_shared_secret_map` can be
set as follows:
`MAUTRIX_SIGNAL_BRIDGE_LOGIN_SHARED_SECRET_MAP=json::{"example.com":"secret"}`.
'';
};
serviceDependencies = mkOption {
type = with types; listOf str;
default = optional config.services.matrix-synapse.enable "matrix-synapse.service";
defaultText = literalExpression ''
optional config.services.matrix-synapse.enable "matrix-synapse.service"
'';
description = lib.mdDoc ''
List of Systemd services to require and wait for when starting the application service.
'';
};
};
};
config = mkIf cfg.enable {
users.groups.mautrix-signal = {};
users.users.mautrix-signal = {
group = "mautrix-signal";
isSystemUser = true;
};
systemd.services.mautrix-signal = {
description = "Mautrix-Signal, a Matrix-Signal puppeting bridge.";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
after = [ "network-online.target" ] ++ cfg.serviceDependencies;
path = [ pkgs.ffmpeg ]; # voice messages need `ffmpeg`
# environment.HOME = dataDir;
preStart = ''
# generate the appservice's registration file if absent
if [ ! -f '${registrationFile}' ]; then
${pkgs.mautrix-signal}/bin/mautrix-signal \
--generate-registration \
--no-update \
--base-config='${pkgs.mautrix-signal}/${pkgs.mautrix-signal.pythonModule.sitePackages}/mautrix_signal/example-config.yaml' \
--config='${settingsFile}' \
--registration='${registrationFile}'
fi
'';
serviceConfig = {
Type = "simple";
Restart = "always";
User = "mautrix-signal";
ProtectSystem = "strict";
ProtectHome = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
PrivateTmp = true;
WorkingDirectory = pkgs.mautrix-signal;
StateDirectory = baseNameOf dataDir;
UMask = "0027";
EnvironmentFile = cfg.environmentFile;
ExecStart = ''
${pkgs.mautrix-signal}/bin/mautrix-signal \
--config='${settingsFile}' \
--no-update
'';
};
};
};
}

View File

@@ -57,7 +57,7 @@ in
options = {
sane.ssh.pubkeys = mkOption {
type = types.attrsOf coercedToKey;
default = {};
default = [];
description = ''
mapping from "user@host" to pubkey.
'';

View File

@@ -1,14 +1,16 @@
{
inputs = {
nixpkgs = {};
patches = {};
};
outputs = { self, nixpkgs }@inputs:
outputs = { self, nixpkgs, patches }@inputs:
let
patchedPkgsFor = system: nixpkgs.legacyPackages.${system}.applyPatches {
name = "nixpkgs-patched-uninsane";
src = nixpkgs;
patches = import ./list.nix {
inherit (nixpkgs.legacyPackages.${system}) fetchpatch fetchurl;
patches = inputs.patches.nixpatches {
inherit (nixpkgs.legacyPackages.${system}) fetchpatch;
inherit (nixpkgs.lib) fakeHash;
};
};
patchedFlakeFor = system: import "${patchedPkgsFor system}/flake.nix";

View File

@@ -1,4 +1,4 @@
{ fetchpatch, fetchurl }: [
{ fakeHash, fetchpatch }: [
# librewolf: build with `MOZ_REQUIRE_SIGNING=false`
(fetchpatch {
url = "https://github.com/NixOS/nixpkgs/pull/199134.diff";
@@ -13,18 +13,11 @@
sha256 = "sha256-t4sG+xLDaxbJ/mV5G18N4ag8EC3IXPgtN5FJGANh1Dc=";
})
# splatmoji: init at 1.2.0
# whalebird: 4.6.5 -> 4.7.4
(fetchpatch {
# https://github.com/NixOS/nixpkgs/pull/211874
url = "https://git.uninsane.org/colin/nixpkgs/commit/75149039b6eaf57d8a92164e90aab20eb5d89196.diff";
hash = "sha256-IvsIcd2wPdz4b/7FMrDrcVlIZjFecCQ9uiL0Umprbx0=";
})
# matrix-synapse,mautrix-facebook: fix runtime inclusion of python3 systemd #212391
# merged 2023/01/24
(fetchpatch {
url = "https://github.com/NixOS/nixpkgs/pull/212391.diff";
hash = "sha256-N9lzQLi8NN9cbd+d04yx2v5mI9tVnlSKVbl0+QGE1YQ=";
# url = "https://git.uninsane.org/colin/nixpkgs/compare/master...pr.whalebird-4.7.4.diff";
url = "https://git.uninsane.org/colin/nixpkgs/commit/f5c7c70dde720e990fa7e0748d1dc4764d6e4406.diff";
sha256 = "sha256-L9Ie80loaP6yl5ZFnJ1b5WMDpvO1QFE8tbrW5HBauko=";
})
./2022-12-19-i2p-aarch64.patch

View File

@@ -1,15 +1,6 @@
# when a `nixos-rebuild` fails after a nixpkgs update:
# - take the failed package
# - search it here: <https://hydra.nixos.org/search?query=pkgname>
# - if it's broken by that upstream builder, then pin it: somebody will come along and fix the package.
# - otherwise, search github issues/PRs for knowledge of it before pinning.
# - if nobody's said anything about it yet, probably want to root cause it or hold off on updating.
(next: prev: {
# XXX: when invoked outside our flake (e.g. via NIX_PATH) there is no `next.stable`,
# so just forward the unstable packages.
inherit (next.stable or prev)
# broken on 2023/01/14 via mtxclient dep, aarch64-only:
# fixed on 2023/01/24?
inherit (next.stable)
# TODO(unpin): broken on 2023/01/14 via mtxclient dep, aarch64-only:
# error: builder for '/nix/store/gwidl0c9ksxjgx0dgwnjssix4ikq73v5-mtxclient-0.9.0.drv' failed with exit code 2;
# last 10 log lines:
# > make[2]: *** [CMakeFiles/matrix_client.dir/build.make:370: CMakeFiles/matrix_client.dir/lib/structs/events/encrypted.cpp.o] Error 1
@@ -29,9 +20,5 @@
# error: 1 dependencies of derivation '/nix/store/5qjxzhsw1jvh2d7jypbcam9409ivb472-user-environment.drv' failed to build
# error: 1 dependencies of derivation '/nix/store/hrb3qpdbisqh0lzlyz1g9g4164khmqwn-etc.drv' failed to build
# error: 1 dependencies of derivation '/nix/store/ny21xyicbgim5wy7ksg2hibd9gn7i01b-nixos-system-moby-23.05pre-git.drv' failed to build
# nheko
# TODO(unpin): broken build on 2023/01/16. <https://hydra.nixos.org/build/205551450>
handbrake
;
nheko;
})

View File

@@ -29,11 +29,11 @@
fluffychat-moby = prev.callPackage ../pkgs/fluffychat-moby { };
gpodder-configured = prev.callPackage ../pkgs/gpodder-configured { };
# nixos-unstable pleroma is too far out-of-date for our db
# pleroma = prev.callPackage ../pkgs/pleroma { };
pleroma = prev.callPackage ../pkgs/pleroma { };
# jackett doesn't allow customization of the bind address: this will probably always be here.
jackett = prev.callPackage ../pkgs/jackett { inherit (prev) jackett; };
# mozilla keeps nerfing itself and removing configuration options
firefox-unwrapped = next.callPackage ../pkgs/firefox-unwrapped { inherit (prev) firefox-unwrapped; };
firefox-unwrapped = prev.callPackage ../pkgs/firefox-unwrapped { };
# patch rpi uboot with something that fixes USB HDD boot
ubootRaspberryPi4_64bit = prev.callPackage ../pkgs/ubootRaspberryPi4_64bit { };
@@ -57,10 +57,10 @@
browserpass-extension = prev.callPackage ../pkgs/browserpass-extension { };
gopass-native-messaging-host = prev.callPackage ../pkgs/gopass-native-messaging-host { };
tokodon = prev.libsForQt5.callPackage ../pkgs/tokodon { };
# provided by nixpkgs patch or upstream preview
# splatmoji = prev.callPackage ../pkgs/splatmoji { };
# signaldctl = prev.callPackage ../pkgs/signaldctl { };
signaldctl = prev.callPackage ../pkgs/signaldctl { };
splatmoji = prev.callPackage ../pkgs/splatmoji { };
# trust-dns = prev.callPackage ../pkgs/trust-dns { };
# kaiteki = prev.kaiteki;
};
in sane // { inherit sane; }
)

View File

@@ -1,13 +1,14 @@
{ stdenv, tow-boot-rpi4, raspberrypifw, raspberrypi-armstubs }:
{ stdenv, tow-boot-rp4, raspberrypifw, raspberrypi-armstubs }:
stdenv.mkDerivation rec {
pname = "bootpart-tow-boot-rpi-aarch64";
version = "1";
buildInputs = [
buildInputs = with [
tow-boot-rpi4 # for Tow-Boot.*.bin
raspberrypifw # for bootcode.bin, *.dat, *.elf, *.dtb
raspberrypi-armstubs # for armstub*
];
src = ./config.txt;

View File

@@ -3,9 +3,9 @@
with lib;
let
base = "6.2.0";
base = "6.1.0";
# set to empty if not a release candidate
rc = "-rc5";
rc = "-rc8";
in buildLinux (args // rec {
version = base + rc;
@@ -24,7 +24,7 @@ in buildLinux (args // rec {
# - specific branches like `pp` (pinephone) are dev branches, and probably less stable.
owner = "megous";
repo = "linux";
rev = "orange-pi-6.2-20230122-1624";
hash = "sha256-Yma9LwlMEnP0QkUZpEl+UkTGvOWOMANBoDsmcTrPb1s=";
rev = "orange-pi-6.1-20221211-1046";
hash = "sha256-TgFXH8bHWHs26rlf7a/zNO9zubFazC8Ie6J1gj4gLgw=";
};
} // (args.argsOverride or { }))

View File

@@ -23,29 +23,21 @@ ENDPOINTS = dict(
class Torrent:
seeders: int
pub_date: datetime
size: int
tracker: str
title: str
magnet: str
def __str__(self) -> str:
return f"{self.seeders}[S]\t{self.pub_date}\t{self.mib}M\t{self.tracker}\t{self.title}\t{self.magnet}"
@property
def mib(self) -> int:
return int(round(self.size / 1024 / 1024))
return f"{self.seeders}[S]\t{self.pub_date}\t{self.title}\t{self.magnet}"
@staticmethod
def from_dict(d: dict) -> 'Torrent':
seeders = d.get("Seeders")
pub_date = d.get("PublishDate")
size = d.get("Size")
tracker = d.get("Tracker")
title = d.get("Title")
magnet = d.get("MagnetUri")
if seeders is not None and pub_date is not None and title is not None and magnet is not None:
pub_date = datetime.fromisoformat(pub_date).astimezone()
return Torrent(seeders, pub_date, size, tracker, title, magnet)
pub_date = datetime.fromisoformat(pub_date)
return Torrent(seeders, pub_date, title, magnet)
class Client:
def __init__(self):
@@ -72,35 +64,10 @@ class Client:
return sorted(torrents, reverse=True)
def parse_args(args: list) -> dict:
options = dict(
full=False,
query="",
)
while args:
arg = args[0]
del args[0]
if arg.startswith('--'):
opt = arg[2:]
if "=" in opt:
name, val = opt.split('=')
else:
name, val = opt, True
options[name] = val
else:
options["query"] = options["query"] + " " + arg if options["query"] else arg
q = " ".join(sys.argv[1:])
return options
def main(args: list):
options = parse_args(args)
query = options["query"]
num_listings = 100 if options["full"] else 5
client = Client()
res = client.query(query)
print(f"found {len(res)} result(s)")
for r in res[:num_listings]:
print(r)
if __name__ == "__main__":
main(sys.argv[1:])
client = Client()
res = client.query(q)
print(f"found {len(res)} result(s)")
for r in res[:5]:
print(r)

View File

@@ -1,21 +1,19 @@
#!/usr/bin/env bash
set -ex
mnt=/mnt/servo-media-wan
# if lan not mounted, then try to mount it
if ! (test -d /mnt/servo-media-lan/Music)
then
sudo mount /mnt/servo-media-lan
fi
# not much reason not to mount the wan while we're here.
if ! (test -d /mnt/servo-media-wan/Music)
then
sudo mount /mnt/servo-media-wan
sudo mount /mnt/servo-media-lan && mnt=/mnt/servo-media-lan
fi
mnt=/mnt/servo-media-wan
# if the LAN is accessible, prefer that
test -d /mnt/servo-media-wan/Music && mnt=/mnt/servo-media-lan
# if the needed mount isn't mounted, mount it
if ! (test -d $mnt/Music)
then
sudo mount $mnt
fi
# symlink the fastest mount point into place
# uncomment if i see the bug again: sudo unlink /mnt/servo-media # XXX ln gets confused if the destination is a symlink to a stale mount
sudo ln -sf --no-dereference $mnt /mnt/servo-media
sudo ln -sf $mnt /mnt/servo-media

View File

@@ -1,21 +1,19 @@
#!/usr/bin/env bash
set -ex
mnt=/mnt/servo-root-wan
# if lan not mounted, then try to mount it
if ! (test -d /mnt/servo-root-lan/nix)
then
sudo mount /mnt/servo-root-lan
fi
# not much reason not to mount the wan while we're here.
if ! (test -d /mnt/servo-root-wan/nix)
then
sudo mount /mnt/servo-root-wan
sudo mount /mnt/servo-root-lan && mnt=/mnt/servo-root-lan
fi
mnt=/mnt/servo-root-wan
# if the LAN is accessible, prefer that
test -d /mnt/servo-root-wan/nix && mnt=/mnt/servo-root-lan
# if the needed mount isn't mounted, mount it
if ! (test -d $mnt/nix)
then
sudo mount $mnt
fi
# symlink the fastest mount point into place
# uncomment if i see the bug again: sudo unlink /mnt/servo-root # XXX ln gets confused if the destination is a symlink to a stale mount
sudo ln -sf --no-dereference $mnt /mnt/servo-root
sudo ln -sf $mnt /mnt/servo-root

View File

@@ -10,4 +10,4 @@ sudo systemctl stop postgresql
sudo systemctl stop duplicity.timer
sudo systemctl stop duplicity
sudo systemctl stop trust-dns
sudo systemctl stop wireguard-wg-ovpns
sudo systemctl stop wireguard-wg0

View File

@@ -1,11 +1,6 @@
{ lib
, bash
, fetchFromGitHub
, fpm
, jq
, pandoc
, shunit2
, stdenv
, fetchFromGitHub
}:
stdenv.mkDerivation rec {
@@ -19,31 +14,17 @@ stdenv.mkDerivation rec {
sha256 = "sha256-fsZ8FhLP3vAalRJWUEi/0fe0DlwAz5zZeRZqAuwgv/U=";
};
nativeBuildInputs = [
bash
fpm
jq
pandoc
shunit2
];
postPatch = ''
patchShebangs ./build.sh
patchShebangs ./test/unit_tests
'';
buildPhase = ''
./build.sh ${version} dir
'';
dontBuild = true;
# TODO: generate a wrapper so that bin/lib, bin/data aren't linked into the environment?
installPhase = ''
mkdir -p $out
cp -R build/usr/* $out
mkdir -p $out/bin
cp splatmoji $out/bin
cp -R lib $out/bin/lib
cp -R data $out/bin/data
cp splatmoji.config $out/bin
patchShebangs $out/bin/splatmoji
# splatmoji refers to its lib and data by absolute path
sed -i "s:/usr/lib/splatmoji:$out/lib/splatmoji:g" $out/bin/splatmoji
sed -i -r "s:/usr/share/+splatmoji:$out/share/splatmoji:g" $out/lib/splatmoji/functions
'';
meta = with lib; {
@@ -51,6 +32,6 @@ stdenv.mkDerivation rec {
homepage = "https://github.com/cspeterson/splatmoji";
license = licenses.mit;
maintainers = with maintainers; [ colinsane ];
platforms = platforms.linux;
platforms = with platforms; linux;
};
}
}

View File

@@ -127,10 +127,10 @@ python3Packages.buildPythonApplication rec {
dataclasses-json
deepdiff
fuzzywuzzy
levenshtein
mpv
peewee
pygobject3
python-Levenshtein
python-dateutil
requests
semver
@@ -144,8 +144,7 @@ python3Packages.buildPythonApplication rec {
sed -i "/--cov/d" setup.cfg
sed -i "/--no-cov-on-fail/d" setup.cfg
substituteInPlace pyproject.toml \
--replace 'deepdiff = "^5.8.1"' 'deepdiff = ">=5.8.1"' \
--replace 'python-Levenshtein = "^0.12.0"' 'levenshtein = ">=0.12.0"'
--replace 'deepdiff = "^5.8.1"' 'deepdiff = ">=5.8.1"'
'';
# hook for gobject-introspection doesn't like strictDeps

View File

@@ -0,0 +1,33 @@
{ lib
, fetchFromGitHub
, openssl
, pkg-config
, rustPlatform
}:
rustPlatform.buildRustPackage rec {
pname = "trust-dns";
version = "0.22.0";
src = fetchFromGitHub {
owner = "bluejekyll";
repo = "trust-dns";
rev = "v${version}";
sha256 = "sha256-b9tK1JbTwB3ZuRPh0wb3cOFj9dMW7URXIaFzUq0Yipw=";
};
cargoHash = "sha256-mpobdeTRWJzIEmhwtcM6UE66qRD5ot/0yLeQM6Tec+0=";
buildInputs = [ openssl ];
nativeBuildInputs = [ pkg-config ];
# tests expect internet connectivity to query real nameservers like 8.8.8.8
doCheck = false;
meta = with lib; {
description = "A Rust based DNS client, server, and resolver";
homepage = "https://trust-dns.org/";
maintainers = with maintainers; [ colinsane ];
platforms = platforms.linux;
license = with licenses; [ asl20 mit ];
};
}

View File

@@ -60,8 +60,8 @@ sops:
cWplOHBNWjlJdGI3ZWtJc0t4Mk9URG8KE+9IPGYZsIs2PaDJ2AUE4gB4QEj5zo6P
aZVbubu6Tbg+tD/98RkfWAkNvoVeDYuLNPDNgqOL0UgCQiTrPPaTjw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-01-20T07:08:51Z"
mac: ENC[AES256_GCM,data:EqVTjLmDLjAxMWvJKIqDjpUKj7oVArFSQzygVZVCYHQTp0v+EGxpn1cP8x+6frQHx8EZts090iqCpcSicwGefAe6VBVvdf408YgB9+qm6QawUMaqDypoM1q4RdOjJEKxyZ408RYorQP6OA/3yctOk39P8RbMUUBlnLvqn38mFeY=,iv:wpDcFZKRGhhoHLno1IvppCz4HUAZb4atX1mUvYZbjg4=,tag:X4BdSfGE1kWFjs4T8YZR0A==,type:str]
lastmodified: "2022-12-15T09:12:44Z"
mac: ENC[AES256_GCM,data:QQiTsQogs6MP9X0lrpf2FeSia6SeQP5/9dtUrWQOd2Vh/s0fBJfIGUdLeLgt5itvaD5QywY6lN9Rsx++BUN0rrwUu/uF42KOMC7wjHdSv07CYuDfvlFZItuIo5eWlfcEq9+p6/VwUXY0TU3M6Ex+mABT5XK67tnLuh/SoHUl+DA=,iv:12sa+wFdO5T7pZrLM3mnEwoJ0WmXZZLKpucEgMYQHMI=,tag:zZEz6+vTma6KDMwXi/fNZA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

View File

@@ -1,32 +0,0 @@
{
"data": "ENC[AES256_GCM,data:5n4FNKyblSOQCC17LmLNfF49+z6ZxX9bAv/xTsyQTR+NglhEtUa+JFziu2Il0w2pscAO37sBvE9SvsM9jNG0v4GxlxlLrgEuam6Tf7Ch71lDdxDXJWMTR032WqMF7q6rYbflw8D4fkpQ9yDbgDJUErrds1JvbNhcv6oqoJ/TuhiQZLakNTprtRkw4gCDJDsyDakhv440EK80o/O1CnO+xnSmBj6mLxljQ0EeFzwhjVr1UlhWJ4wQC8TNAAvYN5gILYP0U11kROI=,iv:JZougqWF29K9mDE0kwe03FGad1CglSlxQt5xM9l7wK8=,tag:DQXUPqMvvnqP2kyYikI2ZQ==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2M01sL1JsODFvVWRHOVZX\nTk1wQlRkclFVZnlKK2lBOUQ1M053SUZxUVYwCjVkVmoxdkRvd3YvQmxvMmd6Ly9k\nWlZGc3M1Yi9lZ3ZRUFJiYWNlRjZ6M2cKLS0tIElTRnplV25wTmFkSVU1clRNa0NZ\nNW5IaDJWYVNCdDNhYTFSU0J6RUJQN28K4XJGpANIuIfHZuk4cinpsPeZ8mMI2jBH\nT2JGyRNm9Jyr3muV8oC/I22fAKLev8f9Svc+o/VAO4R6ZTWmTwk+dA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkQnpqLy83eW9HaExkYWxL\nMHRKY3FsemZQcmVwVWx0a0YvRCtCclZrT1ZRCjJ6UVVjSm85TnVTaHFMRlg0YkNa\nOEQ4eUNyV0lEalVXbi9TVDZLUEVvaXcKLS0tICtvaHhHdmRIY2NNTFBZZ2taS0lX\nak45eW5oT2tIWVNRNmkxbUQ5K2lublUKkLfW5vRfjTpfTOeirLXRik9SJDm92pUX\nXcv9L5klKUb0O3+T0pwb9rYFfhk4eGSxS6ZFQnGrLv0lLTRZq6eocw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhM25NNlRaNDJYZlJkMjVh\nelZPekdjSHJ4ZnZEbnBCZGV4OVN2RVJCOHpNCnVFWFBNTkd4SkJ0SkdvcUdYUzRF\ncnpPUUQyWEpMU0FqQyszTXp0ZFhQeFkKLS0tIDFua2dscEtxQmdUTm14OWlqMjBI\nSXY5cTJEajd3WmNMNlB1eGtQN3RHUEEK3+zoziFJq/rzpnz8ROL5oGqnHUpJTXG8\nhCQEIOA6dO6PjoXUKd6B8bVPzlDLO5daPh0TS5NGiMlZ8qQe706Syw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByc1EzcmVzeHYyTkQ3N2Uw\nTERtdENyeGNONVpjU0FKRE1wR0RlSnhNUjM0ClU4MGwvQjFhM2xXYkNITjFMUHdF\naU50YWVjU08zWXhweXVOWU13enpMQlUKLS0tIDdIRm5GV2IxU1AxcFZldDBBeTBt\nZnRJV25IbGo5R1RySmx4ampnNzdYU0EK7PF9BEGfX6T+1Wit9MG+02sGZTXRUR0M\noVC+oHsCAojhnMP17xyDosnJQqwrNKFwKMQbH7mqBW5Ku4hGy56cGQ==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2023-01-16T11:17:12Z",
"mac": "ENC[AES256_GCM,data:SqOusB8Hd713NYDOkRq2Ju6q4ClN0zOeeCTCAAv+EorKHN7vgz15LuCNWj7iLX4EWrWufzHhG7JFtm6q5h64hxlfzisx3JCtMLRlb40PkDip+2gShH7X4eWcdsRw7/a40e2Qnp/hiXrhH11P1pMqbn6drUPmLy307CyRzThVrcw=,iv:gFcF4i4dqk4rOus4ZKUojD/AAkIuWzGDfqEQTej83Co=,tag:AYknOJm7QTEBR6OzN8dsiw==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.7.3"
}
}

View File

@@ -90,8 +90,8 @@ sops:
YmhsY0FaSW5oWVNJMlhUSDRCeWQ4KzAKaQp321XYtAZ98f4QMl5PxivAYm6VMF43
wCThiQgvYAP59jvVDTZngvfWAD5PyWVVvMNbjHGvAzK5WnsTPmxlsg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-01-20T06:57:29Z"
mac: ENC[AES256_GCM,data:J/yLlcmlX6st/d6c8eL/6DKZiHAELb0/zj+5qOjoE2uAgTTFnojaP4ssrmt7BaLQF1MQNnvkchvuwRv+dAVTXkuYPuDWS3YriAKQIXUx9sHIEoY6Aqa37eBwUNUBuxoR6FvfOGtXrIZuS0f7hZr+ddBZgCSBBE54yeH68Va1tZk=,iv:Y/T8qykrqRVQ8eMkNH2DZa6XoGd5nL18h/2SJucVAD8=,tag:OwZfOyLc29c1bJJIA9IW3Q==,type:str]
lastmodified: "2022-12-26T08:04:00Z"
mac: ENC[AES256_GCM,data:zUXMF1Rwuf3ruypEqTxCPXidMERGVp/rx8kfHhEeEmcs61ejf6M1gjhXDBLk5A+s4FpVA++aUwn0Oix7FCEor5CUmcckITgLoZfQGhjz3kuxZ+fsUnJ7Cgp/+oQYsgsntVCVMKoE7u1D4IQt7PWyrJ9Ye0HVsN50y47jTsLKsKU=,iv:NZUnhxz5WVFvORIffynFLV6xRLdZgEoLW0T2D5yQ3Ac=,tag:IQ8Qq9/T49U+aQDjqvIEjA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3