Compare commits

...

117 Commits

Author SHA1 Message Date
0db7f0857a moby: reduce the number of configurations we keep in /boot 2022-12-21 06:33:50 +00:00
38befe502c new script to free space in /boot 2022-12-21 06:29:13 +00:00
2de6f7d364 fix i2p to build on aarch64 2022-12-20 03:10:05 +00:00
c66699b697 update nixpkgs: 2022-12-11 -> 2022-12-18; sops-nix
```
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/64e0bf055f9d25928c31fb12924e59ff8ce71e60' (2022-12-11)
  → 'github:NixOS/nixpkgs/04f574a1c0fde90b51bf68198e2297ca4e7cccf4' (2022-12-18)
• Updated input 'nixpkgs-stable':
    'github:NixOS/nixpkgs/06278c77b5d162e62df170fec307e83f1812d94b' (2022-12-12)
  → 'github:NixOS/nixpkgs/0938d73bb143f4ae037143572f11f4338c7b2d1c' (2022-12-17)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/da98a111623101c64474a14983d83dad8f09f93d' (2022-12-04)
  → 'github:Mic92/sops-nix/32840f16ffa0856cdf9503a8658f2dd42bf70342' (2022-12-19)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/86370507cb20c905800527539fc049a2bf09c667' (2022-12-04)
  → 'github:NixOS/nixpkgs/87b58217c9a05edcf7630b9be32570f889217aef' (2022-12-19)
```
2022-12-19 22:42:58 +00:00
97044bf70e trust-dns: port to dyn-dns for determining WAN IP
although the systemd wantedBy directive is working,
`before` seems to be ignored when the unit fails. so on first run,
dyn-dns runs, fails (poor net connectivity), then trust-dns starts
(fails), then they both restart 10s later.

it's not great, but good enough. also, wan IP is persisted, so this
likely won't happen much in practice.
2022-12-19 13:12:23 +00:00
3122334a41 dyn-dns: fix to only react when the IP actually changes 2022-12-19 11:54:27 +00:00
0b2faef989 /etc/ssh/host_keys: fix endlessly stacked mounts
i believe this was mounting a new /etc/ssh/host_keys on every
activation, resulting in literally thousands of mounts and slowing down
later activations
2022-12-19 11:18:08 +00:00
8acd6ca4f1 create sane.services.dyn-dns to manage dynamic DNS stuff
not yet integrated into servo
2022-12-19 11:16:30 +00:00
8169f7c6b2 ddns-trust-dns: use ddns from router rather than ipinfo.io 2022-12-19 08:24:11 +00:00
cd1aa0b376 sane-vpn-*: reference sane-ip-check instead of duplicating 2022-12-19 06:19:13 +00:00
72b627100c sane-scripts: simplify recursively referencing sane scripts 2022-12-19 06:18:44 +00:00
567c08460a add sane-ip-check-router-wan to query WAN with a more trustworthy source 2022-12-19 05:59:44 +00:00
9b66aecf1b trust-dns: port the remaining records to a structured format
SRV and MX _could_ have more structure (priority, etc).
not sure the best path there (option submodule, i guess).
2022-12-19 04:38:43 +00:00
16cb3b83a2 trust-dns: more idiomatic way to define SOA records 2022-12-19 04:00:27 +00:00
970438be8a trust-dns: rename records option -> extraConfig
i'll be adding special options for records
2022-12-19 03:12:32 +00:00
51da29555e sane-ip-reconnect: fix issue where we'd reconnect to the existing, subpar network 2022-12-19 01:47:30 +00:00
8a745a9b8a ejabberd: enable STUN (with partial discovery support)
discovery is probably not working:
```
Won't auto-announce STUN/TURN service on port 3478 (udp) without public IP address, please specify 'turn_ipv4_address' and optionally 'turn_ipv6_address'
Won't auto-announce STUN/TURN service on port 3478 (tcp) without public IP address, please specify 'turn_ipv4_address' and optionally 'turn_ipv6_address'
```

no messages for the TLS implementation, so maybe that's working?
2022-12-19 01:22:20 +00:00
3505f3b9f3 ejabberd: provision cert for conference.xmpp.uninsane.org
i guess the cert already had that because of legacy prosody setup (?),
but we weren't setup so that new requests would work, i expect.

either that or all of these nginx entries aren't necessary?
2022-12-19 01:22:20 +00:00
444595e847 disable HE and afraid DDNS 2022-12-19 01:22:20 +00:00
3e1407c30b new script to reconnect to best wifi network 2022-12-19 00:29:48 +00:00
0a744117a4 rename sane-check-ip -> sane-ip-check 2022-12-18 23:54:41 +00:00
a2935cedaa snippets: add wikipedia search 2022-12-18 22:58:53 +00:00
22e46d52c2 trust-dns: distribute records across service files 2022-12-17 01:29:12 +00:00
1e0c213adf split webconfig into each service file 2022-12-17 00:52:48 +00:00
3e1340ed61 enable i2p in firefox 2022-12-16 22:15:19 +00:00
341dd3f2b2 new zsh alias: ref -> cd ~/ref 2022-12-16 20:56:48 +00:00
1c9caa40bd snippets: update nixos wiki to include search param 2022-12-16 20:35:33 +00:00
3be15c6d05 podcasts: add Michael Malice (is it any good? we'll see.) 2022-12-16 08:04:28 +00:00
8e8168ec28 add splatmoji package and sway config 2022-12-16 07:46:06 +00:00
28397807fc gpt2tc: disable, because the mirror is unreliable 2022-12-16 07:08:55 +00:00
42ebb9a155 sane-private-do: run a command with the private store unlocked; then re-lock it 2022-12-16 06:10:44 +00:00
a8a4b8e739 kiwix: serve the full english Wikipedia 2022-12-16 05:58:51 +00:00
2550601179 serve w.uninsane.org through kiwix-serve 2022-12-16 02:25:57 +00:00
199a49755a create a kiwix-serve service 2022-12-16 02:15:17 +00:00
8c7700688f nixpatches: add kiwix-tools package that's being upstreamed 2022-12-16 01:22:38 +00:00
8fe304d6c1 trust-dns: split the service into a generic config interface 2022-12-15 11:17:50 +00:00
700fef7df3 servo: mediawiki: remove dead commented-out code 2022-12-15 11:17:50 +00:00
01db7e1f23 servo: install mediawiki 2022-12-15 11:17:50 +00:00
df6e8f1562 Merge branch 'master' of git.uninsane.org:colin/nix-files 2022-12-15 09:59:53 +00:00
1f0a40c81f snippets: add nixos wiki 2022-12-15 09:54:32 +00:00
995b41d1e8 flake: update nixpkgs-stable 22.05 -> 22.11 2022-12-14 22:32:41 +00:00
7674735d42 Merge branch 'master' of git.uninsane.org:colin/nix-files 2022-12-14 12:28:58 +00:00
329693c9ce pin grpc & users, until the grpc aarch64 build is fixed 2022-12-14 12:27:24 +00:00
5ae3bb2f6c sane-rcp: allow a destination 2022-12-14 10:07:02 +00:00
e0b1aef127 snippets: add sci-hub 2022-12-14 09:52:07 +00:00
9b8363dfb4 firefox addons: bypass-paywalls-clean: update hash 2022-12-14 08:00:42 +00:00
58ad87df8e vpns: add us-mi[ami] 2022-12-13 04:26:00 +00:00
5fc894cda9 vpn: fix us-atlanta -> us-atl to match interface length limit 2022-12-13 04:13:01 +00:00
07e6ec2533 sane-scripts: better vpn factoring 2022-12-13 04:11:58 +00:00
005a79e680 vpn: factor out more helpers 2022-12-13 03:55:18 +00:00
0f5279bbca add us-atlanta VPN 2022-12-13 03:26:23 +00:00
e9b3b7ebab simplify ovpn impl 2022-12-13 03:17:27 +00:00
7a83c1d6df trust-dns: use upstream build 2022-12-13 02:03:09 +00:00
46788fe565 servo: make uninsane.org NS records consistent with upstream 2022-12-13 01:00:16 +00:00
a473ef6db3 flake update: nixpkgs: 2022-12-02 -> 2022-12-11; others
```
• Updated input 'mobile-nixos':
    'github:nixos/mobile-nixos/25eec596116553112681d72ee4880107fc3957fa' (2022-11-19)
  → 'github:nixos/mobile-nixos/5ee45cc1f8e43f4af14ee17ccef9156b0db8cd77' (2022-12-04)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/b72b8b94cf0c012b0252a9100a636cad69696666' (2022-12-02)
  → 'github:NixOS/nixpkgs/64e0bf055f9d25928c31fb12924e59ff8ce71e60' (2022-12-11)
• Updated input 'nixpkgs-stable':
    'github:NixOS/nixpkgs/5d7d1d5f742e6bb57dd2e3d7b433fb4010c7af22' (2022-12-02)
  → 'github:NixOS/nixpkgs/7b9eeb856cbf976482fa8d1cb295ea03fb3e1277' (2022-12-10)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/8295b8139ef7baadeb90c5cad7a40c4c9297ebf7' (2022-11-29)
  → 'github:Mic92/sops-nix/da98a111623101c64474a14983d83dad8f09f93d' (2022-12-04)
• Removed input 'sops-nix/nixpkgs-22_05'
• Added input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/86370507cb20c905800527539fc049a2bf09c667' (2022-12-04)
```
2022-12-13 00:52:54 +00:00
3627d47f12 firefox: add uBlacklist 2022-12-13 00:44:38 +00:00
115f8d7054 servo: vpn services are part of 'wireguard-wg0'
this makes it so if we restart the wireguard connection, the services
themeselves _also_ restart. that should avoid leaving any of them in an
orphaned namespace
2022-12-12 11:53:34 +00:00
ac44b04d99 servo: trust-dns: note about maybe using dig instead of diff'ing the config 2022-12-12 11:35:47 +00:00
afff0aff19 servo: trust-dns: fix up the timers/ddns reliability 2022-12-12 11:33:20 +00:00
f0086dc5bd servo: trust-dns: implement some dynamic DNS shim 2022-12-12 10:30:08 +00:00
acabd34f28 servo: net: forward http requests from vpn -> host w/o NATing the source address
this ensures we have access to the source IP in our host-side logs
2022-12-12 05:21:29 +00:00
d0e6b82739 make it so wireguard-wg0 is restartable 2022-12-11 17:07:53 +00:00
dc09b7b9b2 Merge branch 'master' of git.uninsane.org:colin/nix-files 2022-12-11 16:48:16 +00:00
38c5b82a08 servo: fold wg0 setup into one single service
it doesn't restart cleanly (maybe i can't kill a netns while stuff lives
inside it?). problem for another day.
2022-12-11 16:46:55 +00:00
89def1a073 servo: remove dead net code 2022-12-11 16:15:43 +00:00
ad2ed370d9 servo: split the firewall rules across services 2022-12-11 16:12:23 +00:00
3e8f7a9ba2 servo: use ISP-provided DNS resolvers by default
this is really hacky and i hate it, but there's not a lot of good
options.
2022-12-11 16:03:41 +00:00
028ecfe93f snippets: add HN 2022-12-11 13:14:24 +00:00
c5ac792c13 servo: connect wg0 via IP addr instead of hostname
i think this fixes the connectivity issues i've seen.
2022-12-11 12:48:50 +00:00
bd1624bef9 servo: un-firewall tcp port 53 to fix trust-dns over TCP 2022-12-11 12:48:11 +00:00
3ae53d7f32 services: add RestartSec to anything which auto-restarts
this is to prevent rapid restart failures from killing the service
permanently.
2022-12-10 13:28:46 +00:00
e7f2d41b1f servo: forward DNS to root ns without NAT'ing the source address 2022-12-10 13:28:19 +00:00
3394a79e2b trust-dns: restart on failure
if the network isn't up, won't be able to bind to eth, and fails.
2022-12-10 13:02:17 +00:00
b01501663d trust-dns: listen on each address explicitly 2022-12-10 12:29:10 +00:00
cbd5ccd1c8 desko: disable wifi 2022-12-10 12:27:02 +00:00
cf857eaf9f zsh: more cd aliases (knowledge, secrets) 2022-12-10 12:16:16 +00:00
3a7eb294c7 servo: fix jackett DNS entry 2022-12-10 09:47:28 +00:00
2ccb470adc packages: add tcpdump 2022-12-10 02:56:00 +00:00
0a2a929507 Merge branch 'master' of git.uninsane.org:colin/nix-files 2022-12-09 14:18:40 +00:00
2014d5ce77 servo: bridge port 80/53 from ovpns to native using iptables instead of socat
i should probably narrow the rules to match specifically things destined
for the ovpns address, but for now this should work.
2022-12-09 14:16:48 +00:00
041adb7092 snippets: add nixos search URL 2022-12-09 01:25:24 +00:00
a979521a98 servo: enable ddns against freedns.afraid.org 2022-12-08 14:30:17 +00:00
77881be955 trust-dns: document SOA parameters 2022-12-08 14:23:35 +00:00
0450b4d9a6 trust-dns: fix SOA 2022-12-08 00:46:32 +00:00
edea64a41c trust-dns: move nameserver to subdomain ns1,ns2 2022-12-08 00:39:22 +00:00
90e479592f trust-dns: enable port 53 forward 2022-12-08 00:06:20 +00:00
62d83d94f2 add script to query public IP 2022-12-07 23:39:20 +00:00
52bbe4e9f4 trust-dns: don't restart on failure
for in case anything goes wrong
2022-12-07 12:17:03 +00:00
ab176b8d4b servo: enable trust-dns (experimental) 2022-12-07 12:15:35 +00:00
62df4492a3 Merge branch 'master' of git.uninsane.org:colin/nix-files 2022-12-07 09:47:03 +00:00
f4ed194abc package trust-dns 2022-12-07 09:45:11 +00:00
6420c9fd16 packages: add gajim (at least temporarily, for debugging) 2022-12-07 08:02:14 +00:00
86245b460b Merge branch 'master' of git.uninsane.org:colin/nix-files 2022-12-07 07:41:58 +00:00
bf1ba786b3 packages: add imagemagick (for convert) 2022-12-07 07:41:05 +00:00
35a896a3e2 shell aliases to cd to common places 2022-12-07 07:40:52 +00:00
b4314bd919 mess with XMPP stuff. ejabberd: enable mam, some other acl's that probably aren't used
prosody is still broken
2022-12-07 01:31:17 +00:00
4696209822 nixpatches: update aerc fix hash 2022-12-07 01:14:24 +00:00
c3957d81c2 ejabberd: enable MUC 2022-12-07 00:08:08 +00:00
8a5be00c93 sway: define a "snippets.txt" file for e.g. browser bookmarks 2022-12-06 11:12:27 +00:00
c2db9fe28e periodically archive my torrents so i don't lose them again 2022-12-06 07:17:19 +00:00
ccaac901f7 Merge branch 'master' of git.uninsane.org:colin/nix-files 2022-12-06 07:06:32 +00:00
7f285a8254 ejabberd: enable some more modules which don't conflict 2022-12-06 07:05:59 +00:00
b0b82a3d88 feeds: add Matrix Live podcast
haven't listened. just searching.
2022-12-06 06:58:59 +00:00
b0664d81ab ejabberd: enable mod_pubsub, mod_avatar
i'm able to do this without breaking federation now,
but it doesn't seem to fullly work.
2022-12-05 02:37:35 +00:00
8ba52bb9cd ejabberd: enable mod_{carboncopy,last,offline,private,stream_mgmt} 2022-12-05 02:16:28 +00:00
20f0a19e25 ejabberd: fix federation: disable mod_pubsub and mod_avatar
now i can send messages FROM uninsane.org again
2022-12-05 00:47:48 +00:00
9dc17a3874 ejabberd: enable avatar support
haven't tested that it federates properly -- only that Dino is able to
set it.
2022-12-04 12:38:47 +00:00
2992644901 bluetooth: persist bluetooth earbuds connection 2022-12-04 11:33:03 +00:00
d5d89a10b9 bluetooth: add key for connecting to my car 2022-12-04 10:56:50 +00:00
f7d9fdfe04 packages: add pstree 2022-12-04 03:42:54 +00:00
c42aa2847b aerc: apply patch to fix awk / message reading 2022-12-04 02:48:37 +00:00
768c5c910f update nixpkgs: 2022-11-27 -> 2022-12-02
```
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/a115bb9bd56831941be3776c8a94005867f316a7' (2022-11-27)
  → 'github:NixOS/nixpkgs/b72b8b94cf0c012b0252a9100a636cad69696666' (2022-12-02)
• Updated input 'nixpkgs-stable':
    'github:NixOS/nixpkgs/fecf05d4861f3985e8dee73f08bc82668ef75125' (2022-11-27)
  → 'github:NixOS/nixpkgs/5d7d1d5f742e6bb57dd2e3d7b433fb4010c7af22' (2022-12-02)
```
2022-12-03 22:56:00 +00:00
8790a7d9fd note about persisting bluetooth config 2022-12-03 11:35:03 +00:00
7c36a0d522 bluetooth: share connections across machines 2022-12-03 11:05:09 +00:00
977a80d59e Merge branch 'staging/moby-6.1.0-rc7' 2022-12-03 09:05:13 +00:00
63c92a44ed servo: ejabberd: enable file uploads 2022-12-03 08:57:10 +00:00
bf838ea203 packages: add tree as system package 2022-12-03 08:56:26 +00:00
69 changed files with 2018 additions and 453 deletions

60
flake.lock generated
View File

@@ -54,11 +54,11 @@
"mobile-nixos": {
"flake": false,
"locked": {
"lastModified": 1668897543,
"narHash": "sha256-1bjvy5zi/6KDzhN3ihOUEA6y5FFEOf5xvIbf65RWIh0=",
"lastModified": 1670131242,
"narHash": "sha256-T/o1/3gffr010fsqgNshs1NJJjsnUYvQnUZgm6hilsY=",
"owner": "nixos",
"repo": "mobile-nixos",
"rev": "25eec596116553112681d72ee4880107fc3957fa",
"rev": "5ee45cc1f8e43f4af14ee17ccef9156b0db8cd77",
"type": "github"
},
"original": {
@@ -69,11 +69,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1669542132,
"narHash": "sha256-DRlg++NJAwPh8io3ExBJdNW7Djs3plVI5jgYQ+iXAZQ=",
"lastModified": 1671359686,
"narHash": "sha256-3MpC6yZo+Xn9cPordGz2/ii6IJpP2n8LE8e/ebUXLrs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a115bb9bd56831941be3776c8a94005867f316a7",
"rev": "04f574a1c0fde90b51bf68198e2297ca4e7cccf4",
"type": "github"
},
"original": {
@@ -82,37 +82,37 @@
"type": "indirect"
}
},
"nixpkgs-22_05": {
"locked": {
"lastModified": 1669513802,
"narHash": "sha256-AmTRNi8bHgJlmaNe3r5k+IMFbbXERM/KarqveMAZmsY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6649e08812f579581bfb4cada3ba01e30485c891",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-22.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1669546925,
"narHash": "sha256-Gvtk9agz88tBgqmCdHl5U7gYttTkiuEd8/Rq1Im0pTg=",
"lastModified": 1671313200,
"narHash": "sha256-itZTrtHeDJjV696+ur0/TzkTqb5y3Eb57WRLRPK3rwA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fecf05d4861f3985e8dee73f08bc82668ef75125",
"rev": "0938d73bb143f4ae037143572f11f4338c7b2d1c",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-22.05",
"ref": "nixos-22.11",
"type": "indirect"
}
},
"nixpkgs-stable_2": {
"locked": {
"lastModified": 1671459584,
"narHash": "sha256-6wRK7xmeHfClJ0ICOkax1avLZVGTDqBodQlkl/opccY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "87b58217c9a05edcf7630b9be32570f889217aef",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-22.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"home-manager": "home-manager",
@@ -129,14 +129,14 @@
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-22_05": "nixpkgs-22_05"
"nixpkgs-stable": "nixpkgs-stable_2"
},
"locked": {
"lastModified": 1669714206,
"narHash": "sha256-9aiMbzRL8REsyi9U0eZ+lT4s7HaILA1gh9n2apKzLxU=",
"lastModified": 1671472949,
"narHash": "sha256-9iHSGpljCX+RypahQssBXPwkru9onfKfceCTeVrMpH4=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "8295b8139ef7baadeb90c5cad7a40c4c9297ebf7",
"rev": "32840f16ffa0856cdf9503a8658f2dd42bf70342",
"type": "github"
},
"original": {

View File

@@ -4,7 +4,7 @@
{
inputs = {
nixpkgs-stable.url = "nixpkgs/nixos-22.05";
nixpkgs-stable.url = "nixpkgs/nixos-22.11";
nixpkgs.url = "nixpkgs/nixos-unstable";
mobile-nixos = {
url = "github:nixos/mobile-nixos";
@@ -38,7 +38,10 @@
patchedPkgs = system: nixpkgs.legacyPackages.${system}.applyPatches {
name = "nixpkgs-patched-uninsane";
src = nixpkgs;
patches = import ./nixpatches/list.nix nixpkgs.legacyPackages.${system}.fetchpatch;
patches = import ./nixpatches/list.nix {
inherit (nixpkgs.legacyPackages.${system}) fetchpatch;
inherit (nixpkgs.lib) fakeHash;
};
};
# return something which behaves like `pkgs`, for the provided system
# `local` = architecture of builder. `target` = architecture of the system beying deployed to
@@ -69,8 +72,15 @@
# the config can explicitly pull such packages from `pkgs.cross` to do more efficient cross-compilation.
cross = (nixpkgsFor local target) // (customPackagesFor local target);
stable = import nixpkgs-stable { system = target; };
# cross-compatible packages
# gocryptfs = cross.gocryptfs;
# pinned packages:
# 2022/12/13: grpc does not build on aarch64-linux. https://github.com/NixOS/nixpkgs/issues/205887
grpc = stable.grpc;
# depends on grpc, so pinned.
duplicity = stable.duplicity;
})
];
}

View File

@@ -0,0 +1,32 @@
{ lib, pkgs, ... }:
{
# TODO: don't need to depend on binsh if we were to use a nix-style shebang
system.activationScripts.linkBluetoothKeys = let
unwrapped = ../../scripts/install-bluetooth;
install-bluetooth = pkgs.writeShellApplication {
name = "install-bluetooth";
runtimeInputs = with pkgs; [ coreutils gnused ];
text = ''${unwrapped} "$@"'';
};
in (lib.stringAfter
[ "setupSecrets" "binsh" ]
''
${install-bluetooth}/bin/install-bluetooth /run/secrets/bt
''
);
# TODO: use a glob, or a list, or something?
sops.secrets."bt/car" = {
sopsFile = ../../secrets/universal/bt/car.bin;
format = "binary";
};
sops.secrets."bt/earbuds" = {
sopsFile = ../../secrets/universal/bt/earbuds.bin;
format = "binary";
};
sops.secrets."bt/portable-speaker" = {
sopsFile = ../../secrets/universal/bt/portable-speaker.bin;
format = "binary";
};
}

View File

@@ -1,8 +1,10 @@
{ pkgs, ... }:
{
imports = [
./bluetooth.nix
./fs.nix
./hardware
./i2p.nix
./machine-id.nix
./net.nix
./secrets.nix

4
hosts/common/i2p.nix Normal file
View File

@@ -0,0 +1,4 @@
{ ... }:
{
services.i2p.enable = true;
}

View File

@@ -76,4 +76,8 @@
sopsFile = ../../secrets/universal/net/iphone.psk.bin;
format = "binary";
};
sops.secrets."router_passwd" = {
sopsFile = ../../secrets/universal.yaml;
};
}

View File

@@ -11,7 +11,12 @@
# since that also depends on `users`.
system.activationScripts.persist-ssh-host-keys.text = ''
mkdir -p /etc/ssh/host_keys
mount --bind /nix/persist/etc/ssh/host_keys /etc/ssh/host_keys
if ! (mountpoint /etc/ssh/host_keys)
then
# avoid mounting the keys more than once, otherwise we have a million _stacked_ entries.
# TODO: should we just symlink? or find a way to make sure the existing mount is correct.
mount --bind /nix/persist/etc/ssh/host_keys /etc/ssh/host_keys
fi
'';
services.openssh.hostKeys = [

View File

@@ -1,58 +1,69 @@
{ config, ... }:
{ config, lib, ... }:
{
networking.wg-quick.interfaces.ovpnd-us = {
# to add a new OVPN VPN:
# - generate a privkey `wg genkey`
# - add this key to `sops secrets/universal.yaml`
# - upload pubkey to OVPN.com
# - generate config @ OVPN.com
# - copy the Address, PublicKey, Endpoint from OVPN's config
# N.B.: maximum interface name in Linux is 15 characters.
let
def-ovpn = name: { endpoint, publicKey, address }: {
networking.wg-quick.interfaces."ovpnd-${name}" = {
inherit address;
privateKeyFile = config.sops.secrets."wg_ovpnd_${name}_privkey".path;
dns = [
"46.227.67.134"
"192.165.9.158"
];
peers = [
{
allowedIPs = [
"0.0.0.0/0"
"::/0"
];
inherit endpoint publicKey;
}
];
# to start: `systemctl start wg-quick-ovpnd-${name}`
autostart = false;
};
sops.secrets."wg_ovpnd_${name}_privkey" = {
sopsFile = ../../secrets/universal.yaml;
};
};
in lib.mkMerge [
(def-ovpn "us" {
endpoint = "vpn31.prd.losangeles.ovpn.com:9929";
publicKey = "VW6bEWMOlOneta1bf6YFE25N/oMGh1E1UFBCfyggd0k=";
address = [
"172.27.237.218/32"
"fd00:0000:1337:cafe:1111:1111:ab00:4c8f/128"
];
dns = [
"46.227.67.134"
"192.165.9.158"
})
# NB: us-* share the same wg key and link-local addrs, but distinct public addresses
(def-ovpn "us-atl" {
endpoint = "vpn18.prd.atlanta.ovpn.com:9929";
publicKey = "Dpg/4v5s9u0YbrXukfrMpkA+XQqKIFpf8ZFgyw0IkE0=";
address = [
"172.21.182.178/32"
"fd00:0000:1337:cafe:1111:1111:cfcb:27e3/128"
];
peers = [
{
allowedIPs = [
"0.0.0.0/0"
"::/0"
];
endpoint = "vpn31.prd.losangeles.ovpn.com:9929";
publicKey = "VW6bEWMOlOneta1bf6YFE25N/oMGh1E1UFBCfyggd0k=";
}
})
(def-ovpn "us-mi" {
endpoint = "vpn34.prd.miami.ovpn.com:9929";
publicKey = "VtJz2irbu8mdkIQvzlsYhU+k9d55or9mx4A2a14t0V0=";
address = [
"172.21.182.178/32"
"fd00:0000:1337:cafe:1111:1111:cfcb:27e3/128"
];
privateKeyFile = config.sops.secrets.wg_ovpnd_us_privkey.path;
# to start: `systemctl start wg-quick-ovpnd-us`
autostart = false;
};
networking.wg-quick.interfaces.ovpnd-ukr = {
})
(def-ovpn "ukr" {
endpoint = "vpn96.prd.kyiv.ovpn.com:9929";
publicKey = "CjZcXDxaaKpW8b5As1EcNbI6+42A6BjWahwXDCwfVFg=";
address = [
"172.18.180.159/32"
"fd00:0000:1337:cafe:1111:1111:ec5c:add3/128"
];
dns = [
"46.227.67.134"
"192.165.9.158"
];
peers = [
{
allowedIPs = [
"0.0.0.0/0"
"::/0"
];
endpoint = "vpn96.prd.kyiv.ovpn.com:9929";
publicKey = "CjZcXDxaaKpW8b5As1EcNbI6+42A6BjWahwXDCwfVFg=";
}
];
privateKeyFile = config.sops.secrets.wg_ovpnd_ukr_privkey.path;
# to start: `systemctl start wg-quick-ovpnd-ukr`
autostart = false;
};
sops.secrets."wg_ovpnd_us_privkey" = {
sopsFile = ../../secrets/universal.yaml;
};
sops.secrets."wg_ovpnd_ukr_privkey" = {
sopsFile = ../../secrets/universal.yaml;
};
}
})
]

View File

@@ -25,6 +25,9 @@
neededForUsers = true;
};
# don't enable wifi by default: it messes with connectivity.
systemd.services.iwd.enable = false;
# default config: https://man.archlinux.org/man/snapper-configs.5
# defaults to something like:
# - hourly snapshots

View File

@@ -40,7 +40,9 @@
boot.loader.efi.canTouchEfiVariables = false;
# /boot space is at a premium. default was 20.
boot.loader.generic-extlinux-compatible.configurationLimit = 10;
# even 10 can be too much
# TODO: compress moby kernels!
boot.loader.generic-extlinux-compatible.configurationLimit = 8;
# mobile.bootloader.enable = false;
# mobile.boot.stage-1.enable = false;
# boot.initrd.systemd.enable = false;

View File

@@ -14,9 +14,8 @@
pkgs.freshrss
];
sane.impermanence.enable = true;
sane.services.dyn-dns.enable = true;
# sane.services.duplicity.enable = true; # TODO: re-enable after HW upgrade
sane.services.nixserve.enable = true;
sane.services.nixserve.sopsFile = ../../secrets/servo.yaml;
boot.loader.efi.canTouchEfiVariables = false;
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];

View File

@@ -13,83 +13,145 @@
# networking.firewall.enable = false;
networking.firewall.enable = true;
# TODO: split these into the submodules
networking.firewall.allowedTCPPorts = [
25 # SMTP
80 # HTTP
143 # IMAP
443 # HTTPS
465 # SMTPS
587 # SMTPS/submission
993 # IMAPS
4001 # IPFS
];
networking.firewall.allowedUDPPorts = [
1900 7359 # DLNA: https://jellyfin.org/docs/general/networking/index.html
4001 # IPFS
# this is needed to forward packets from the VPN to the host
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
# unless we add interface-specific settings for each VPN, we have to define nameservers globally.
# networking.nameservers = [
# "1.1.1.1"
# "9.9.9.9"
# ];
# use systemd's stub resolver.
# /etc/resolv.conf isn't sophisticated enough to use different servers per net namespace (or link).
# instead, running the stub resolver on a known address in the root ns lets us rewrite packets
# in the ovnps namespace to use the provider's DNS resolvers.
# a weakness is we can only query 1 NS at a time (unless we were to clone the packets?)
# there also seems to be some cache somewhere that's shared between the two namespaces.
# i think this is a libc thing. might need to leverage proper cgroups to _really_ kill it.
# - getent ahostsv4 www.google.com
# - try fix: <https://serverfault.com/questions/765989/connect-to-3rd-party-vpn-server-but-dont-use-it-as-the-default-route/766290#766290>
services.resolved.enable = true;
networking.nameservers = [
# use systemd-resolved resolver
# full resolver (which understands /etc/hosts) lives on 127.0.0.53
# stub resolver (just forwards upstream) lives on 127.0.0.54
"127.0.0.53"
];
# we need to use externally-visible nameservers in order for VPNs to be able to resolve hosts.
networking.nameservers = [
"1.1.1.1"
"9.9.9.9"
];
# services.resolved.extraConfig = ''
# # docs: `man resolved.conf`
# # DNS servers to use via the `wg0` interface.
# # i hope that from the root ns, these aren't visible.
# 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-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.wg0 = {
networking.wireguard.interfaces.wg0 = let
ip = "${pkgs.iproute2}/bin/ip";
in-ns = "${ip} netns exec ovpns";
iptables = "${pkgs.iptables}/bin/iptables";
veth-host-ip = "10.0.1.5";
veth-local-ip = "10.0.1.6";
vpn-ip = "185.157.162.178";
# DNS = 46.227.67.134, 192.165.9.158, 2a07:a880:4601:10f0:cd45::1, 2001:67c:750:1:cafe:cd45::1
vpn-dns = "46.227.67.134";
in {
privateKeyFile = config.sops.secrets.wg_ovpns_privkey.path;
# wg is active only in this namespace.
# run e.g. ip netns exec ovpns <some command like ping/curl/etc, it'll go through wg>
# sudo ip netns exec ovpns ping www.google.com
# note: without the namespace, you'll need to add a specific route through eth0 for the peer (185.157.162.178/32)
interfaceNamespace = "ovpns";
preSetup = "${pkgs.iproute2}/bin/ip netns add ovpns || true";
postShutdown = "${pkgs.iproute2}/bin/ip netns delete ovpns";
ips = [
"185.157.162.178/32"
];
peers = [
{
publicKey = "SkkEZDCBde22KTs/Hc7FWvDBfdOCQA4YtBEuC3n5KGs=";
endpoint = "vpn36.prd.amsterdam.ovpn.com:9930";
endpoint = "185.157.162.10:9930";
# alternatively: use hostname, but that presents bootstrapping issues (e.g. if host net flakes)
# endpoint = "vpn36.prd.amsterdam.ovpn.com:9930";
allowedIPs = [ "0.0.0.0/0" ];
# nixOS says this is important for keeping NATs active
persistentKeepalive = 25;
# re-executes wg this often. docs hint that this might help wg notice DNS/hostname changes.
# so, maybe that helps if we specify endpoint as a domain name
# dynamicEndpointRefreshSeconds = 30;
# when refresh fails, try it again after this period instead.
# TODO: not avail until nixpkgs upgrade
# dynamicEndpointRefreshRestartSeconds = 5;
}
];
preSetup = "" + ''
${ip} netns add ovpns || echo "ovpns already exists"
'';
postShutdown = "" + ''
${in-ns} ip link del ovpns-veth-b || echo "couldn't delete ovpns-veth-b"
${ip} link del ovpns-veth-a || echo "couldn't delete ovpns-veth-a"
${ip} netns delete ovpns || echo "couldn't delete ovpns"
# restore rules/routes
${ip} rule del from ${veth-host-ip} lookup ovpns pref 50 || echo "couldn't delete init -> ovpns rule"
${ip} route del default via ${veth-local-ip} dev ovpns-veth-a proto kernel src ${veth-host-ip} metric 1002 table ovpns || echo "couldn't delete init -> ovpns route"
${ip} rule add from all lookup local pref 0
${ip} rule del from all lookup local pref 100
'';
postSetup = "" + ''
# DOCS:
# - some of this approach is described here: <https://josephmuia.ca/2018-05-16-net-namespaces-veth-nat/>
# - iptables primer: <https://danielmiessler.com/study/iptables/>
# create veth pair
${ip} link add ovpns-veth-a type veth peer name ovpns-veth-b
${ip} addr add ${veth-host-ip}/24 dev ovpns-veth-a
${ip} link set ovpns-veth-a up
# mv veth-b into the ovpns namespace
${ip} link set ovpns-veth-b netns ovpns
${in-ns} ip addr add ${veth-local-ip}/24 dev ovpns-veth-b
${in-ns} ip link set ovpns-veth-b up
# make it so traffic originating from the host side of the veth
# is sent over the veth no matter its destination.
${ip} rule add from ${veth-host-ip} lookup ovpns pref 50
# for traffic originating at the host veth to the WAN, use the veth as our gateway
# not sure if the metric 1002 matters.
${ip} route add default via ${veth-local-ip} dev ovpns-veth-a proto kernel src ${veth-host-ip} metric 1002 table ovpns
# give the default route lower priority
${ip} rule add from all lookup local pref 100
${ip} rule del from all lookup local pref 0
# bridge HTTP traffic:
# any external port-80 request sent to the VPN addr will be forwarded to the rootns.
# this exists so LetsEncrypt can procure a cert for the MX over http.
# TODO: we could use _acme_challence.mx.uninsane.org CNAME to avoid this forwarding
# - <https://community.letsencrypt.org/t/where-does-letsencrypt-resolve-dns-from/37607/8>
${in-ns} ${iptables} -A PREROUTING -t nat -p tcp --dport 80 -m iprange --dst-range ${vpn-ip} \
-j DNAT --to-destination ${veth-host-ip}:80
# we also bridge DNS traffic
${in-ns} ${iptables} -A PREROUTING -t nat -p udp --dport 53 -m iprange --dst-range ${vpn-ip} \
-j DNAT --to-destination ${veth-host-ip}:53
${in-ns} ${iptables} -A PREROUTING -t nat -p tcp --dport 53 -m iprange --dst-range ${vpn-ip} \
-j DNAT --to-destination ${veth-host-ip}:53
# in order to access DNS in this netns, we need to route it to the VPN's nameservers
# - alternatively, we could fix DNS servers like 1.1.1.1.
${in-ns} ${iptables} -A OUTPUT -t nat -p udp --dport 53 -m iprange --dst-range 127.0.0.53 \
-j DNAT --to-destination ${vpn-dns}:53
'';
};
systemd.services.wg0veth = {
description = "veth pair to allow communication between host and wg0 netns";
after = [ "wireguard-wg0.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = with pkgs; writeScript "wg0veth-start" ''
#!${bash}/bin/bash
# create veth pair
${iproute2}/bin/ip link add ovpns-veth-a type veth peer name ovpns-veth-b
${iproute2}/bin/ip addr add 10.0.1.5/24 dev ovpns-veth-a
${iproute2}/bin/ip link set ovpns-veth-a up
# mv veth-b into the ovpns namespace
${iproute2}/bin/ip link set ovpns-veth-b netns ovpns
${iproute2}/bin/ip -n ovpns addr add 10.0.1.6/24 dev ovpns-veth-b
${iproute2}/bin/ip -n ovpns link set ovpns-veth-b up
# forward HTTP traffic, which we need for letsencrypt to work
${iproute2}/bin/ip netns exec ovpns ${socat}/bin/socat TCP4-LISTEN:80,reuseaddr,fork,su=nobody TCP4:10.0.1.5:80 &
'';
ExecStop = with pkgs; writeScript "wg0veth-stop" ''
#!${bash}/bin/bash
${iproute2}/bin/ip -n wg0 link del ovpns-veth-b
${iproute2}/bin/ip link del ovpns-veth-a
'';
};
};
# 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
'';
networking.iproute2.enable = true;
sops.secrets."wg_ovpns_privkey" = {
sopsFile = ../../secrets/servo.yaml;

View File

@@ -0,0 +1,31 @@
{ config, lib, pkgs, ... }:
# using manual ddns now
lib.mkIf false
{
systemd.services.ddns-afraid = {
description = "update dynamic DNS entries for freedns.afraid.org";
serviceConfig = {
EnvironmentFile = config.sops.secrets.ddns_afraid.path;
# TODO: ProtectSystem = "strict";
# TODO: ProtectHome = "full";
# TODO: PrivateTmp = true;
};
script = let
curl = "${pkgs.curl}/bin/curl -4";
in ''
${curl} "https://freedns.afraid.org/dynamic/update.php?$AFRAID_KEY"
'';
};
systemd.timers.ddns-afraid = {
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnStartupSec = "2min";
OnUnitActiveSec = "10min";
};
};
sops.secrets."ddns_afraid" = {
sopsFile = ../../../secrets/servo.yaml;
};
}

View File

@@ -1,5 +1,7 @@
{ config, pkgs, ... }:
{ config, lib, pkgs, ... }:
# we use manual DDNS now
lib.mkIf false
{
systemd.services.ddns-he = {
description = "update dynamic DNS entries for HurricaneElectric";

View File

@@ -1,6 +1,7 @@
{ ... }:
{
imports = [
./ddns-afraid.nix
./ddns-he.nix
./ejabberd.nix
./freshrss.nix
@@ -9,13 +10,17 @@
./ipfs.nix
./jackett.nix
./jellyfin.nix
./kiwix-serve.nix
./matrix
./navidrome.nix
./nixserve.nix
./nginx.nix
./pleroma.nix
./postfix.nix
./postgres.nix
./prosody.nix
./transmission.nix
./trust-dns.nix
./wikipedia.nix
];
}

View File

@@ -1,23 +1,76 @@
# docs:
# - <https://docs.ejabberd.im/admin/configuration/basic>
# example configs:
# - <https://github.com/vkleen/machines/blob/138a2586ce185d7cf201d4e1fe898c83c4af52eb/hosts/europium/ejabberd.nix>
# - <https://github.com/Mic92/stockholm/blob/675ef0088624c9de1cb531f318446316884a9d3d/tv/3modules/ejabberd/default.nix>
# - <https://github.com/buffet/tararice/blob/bc5b65509f4e622313af3f1f4be690628123f1f3/programs/ejabberd.nix>
# - enables STUN and TURN
# - uses stun_disco module (but with no options)
# - <https://github.com/leo60228/dotfiles/blob/39b3abba3009bdc31413d4757ca2f882a33eec8b/files/ejabberd.yml>
# - <https://github.com/Mic92/dotfiles/blob/ddf0f4821f554f7667fc803344657367c55fb9e6/nixos/eve/modules/ejabberd.nix>
# - <nixpkgs:nixos/tests/xmpp/ejabberd.nix>
# - 2013: <https://github.com/processone/ejabberd/blob/master/ejabberd.yml.example>
{ lib, ... }:
# XXX disabled: fails to start because of `mnesia_tm` dependency
# XXX: avatar support works in MUCs but not DMs
# lib.mkIf false
{
sane.impermanence.service-dirs = [
{ user = "ejabberd"; group = "ejabberd"; directory = "/var/lib/ejabberd"; }
];
networking.firewall.allowedTCPPorts = [
3478 # STUN
5222 # XMPP client -> server
5269 # XMPP server -> server
5280 # bosh
5281 # bosh (https) ??
5349 # STUN (TLS)
5443 # web services (file uploads, websockets, admin)
];
networking.firewall.allowedUDPPorts = [
3478 # STUN
];
# provide access to certs
users.users.ejabberd.extraGroups = [ "nginx" ];
security.acme.certs."uninsane.org".extraDomainNames = [
"conference.xmpp.uninsane.org"
"pubsub.xmpp.uninsane.org"
"upload.xmpp.uninsane.org"
"vjid.xmpp.uninsane.org"
];
# exists so the XMPP server's cert can obtain altNames for all its resources
services.nginx.virtualHosts."conference.xmpp.uninsane.org" = {
useACMEHost = "uninsane.org";
};
services.nginx.virtualHosts."pubsub.xmpp.uninsane.org" = {
useACMEHost = "uninsane.org";
};
services.nginx.virtualHosts."upload.xmpp.uninsane.org" = {
useACMEHost = "uninsane.org";
};
services.nginx.virtualHosts."vjid.xmpp.uninsane.org" = {
useACMEHost = "uninsane.org";
};
sane.services.trust-dns.zones."uninsane.org".inet = {
# XXX: toplevel xmpp might not actually be used/needed.
CNAME."xmpp" = [ "native" ];
CNAME."conference.xmpp" = [ "native" ];
CNAME."pubsub.xmpp" = [ "native" ];
CNAME."upload.xmpp" = [ "native" ];
CNAME."vjid.xmpp" = [ "native" ];
# _Service._Proto.Name TTL Class SRV Priority Weight Port Target
SRV."_xmpp-client._tcp" = [ "0 0 5222 native" ];
SRV."_xmpp-server._tcp" = [ "0 0 5269 native" ];
SRV."_stun._udp" = [ "0 0 3478 native" ];
SRV."_stun._tcp" = [ "0 0 3478 native" ];
SRV."_stuns._tcp" = [ "0 0 5349 native" ];
};
# TODO: allocate UIDs/GIDs ?
services.ejabberd.enable = true;
services.ejabberd.configFile = builtins.toFile "ejabberd.yaml" ''
@@ -35,9 +88,39 @@
pam_userinfotype: jid
acl:
admin:
user:
- "colin@uninsane.org"
local:
user_regexp: ""
loopback:
ip:
- 127.0.0.0/8
- ::1/128
access_rules:
local:
allow: local
c2s_access:
allow: all
announce:
allow: admin
configure:
allow: admin
muc_create:
allow: local
pubsub_createnode_access:
allow: local
trusted_network:
allow: loopback
# docs: <https://docs.ejabberd.im/admin/configuration/basic/#shaper-rules>
shaper_rules:
max_s2s_connections: 3
# setting this to above 1 may break outgoing messages
# - maybe some servers rate limit? or just don't understand simultaneous connections?
max_s2s_connections: 1
max_user_sessions: 10
max_user_offline_messages: 5000
c2s_shaper:
fast: all
@@ -59,26 +142,156 @@
# - burst_size: 5000000
# see: <https://docs.ejabberd.im/admin/configuration/listen/>
# TODO: host web admin panel
s2s_use_starttls: true
# s2s_use_starttls: true
s2s_use_starttls: optional
# lessens 504: remote-server-timeout errors
# see: <https://github.com/processone/ejabberd/issues/3105#issuecomment-562182967>
negotiation_timeout: 60
listen:
-
port: 5222
module: ejabberd_c2s
shaper: c2s_shaper
starttls: true
access: c2s_access
-
port: 5269
module: ejabberd_s2s_in
shaper: s2s_shaper
-
port: 5280
port: 5443
module: ejabberd_http
tls: true
request_handlers:
/admin: ejabberd_web_admin
/api: mod_http_api
/admin: ejabberd_web_admin # TODO: ensure this actually works
/api: mod_http_api # ejabberd API endpoint (to control server)
/bosh: mod_bosh
/upload: mod_http_upload
/ws: ejabberd_http_ws
# /.well-known/host-meta: mod_host_meta
# /.well-known/host-meta.json: mod_host_meta
-
port: 3478
module: ejabberd_stun
transport: tcp
-
port: 3478
module: ejabberd_stun
transport: udp
-
port: 5349
module: ejabberd_stun
transport: tcp
tls: true
# TODO: enable mod_client_state for net optimization
# TODO: enable mod_fail2ban
# TODO(low): look into mod_http_fileserver for serving macros?
modules:
# mod_adhoc: {}
# mod_announce:
# access: admin
# allows users to set avatars in vCard
# - <https://docs.ejabberd.im/admin/configuration/modules/#mod-avatar>
mod_avatar: {}
mod_caps: {} # for mod_pubsub
mod_carboncopy: {} # allows multiple clients to receive a user's message
# mod_conversejs: TODO: enable once on 21.12
# allows clients like Dino to discover where to upload files
mod_disco:
server_info:
-
modules: all
name: abuse-addresses
urls:
- "mailto:admin.xmpp@uninsane.org"
- "xmpp:colin@uninsane.org"
-
modules: all
name: admin-addresses
urls:
- "mailto:admin.xmpp@uninsane.org"
- "xmpp:colin@uninsane.org"
mod_http_upload:
host: upload.xmpp.uninsane.org
hosts:
- upload.xmpp.uninsane.org
put_url: "https://@HOST@:5443/upload"
dir_mode: "0750"
file_mode: "0750"
rm_on_unregister: false
# allow discoverability of BOSH and websocket endpoints
# TODO: enable once on ejabberd 22.05 (presently 21.04)
# mod_host_meta: {}
mod_jidprep: {} # probably not needed: lets clients normalize jids
mod_last: {} # allow other users to know when i was last online
mod_mam:
# Mnesia is limited to 2GB, better to use an SQL backend
# For small servers SQLite is a good fit and is very easy
# to configure. Uncomment this when you have SQL configured:
# db_type: sql
assume_mam_usage: true
default: always
mod_muc:
access:
- allow
access_admin:
- allow: admin
access_create: muc_create
access_persistent: muc_create
access_mam:
- allow
history_size: 100 # messages to show new participants
host: conference.xmpp.uninsane.org
hosts:
- conference.xmpp.uninsane.org
default_room_options:
anonymous: false
lang: en
persistent: true
mam: true
mod_muc_admin: {}
mod_offline: # store messages for a user when they're offline (TODO: understand multi-client workflow?)
access_max_user_messages: max_user_offline_messages
store_groupchat: true
mod_ping: {}
mod_privacy: {} # deprecated, but required for `ejabberctl export_piefxis`
mod_private: {} # allow local clients to persist arbitrary data on my server
mod_roster:
versioning: true
# docs: <https://docs.ejabberd.im/admin/configuration/modules/#mod-s2s-dialback>
# mod_s2s_dialback: {} # XXX: MIGHT need to enable this to federate with some servers
mod_shared_roster: {} # creates groups for @all, @online, and anything manually administered?
mod_stream_mgmt:
resend_on_timeout: if_offline # resend undelivered messages if the origin client is offline
# fallback for when DNS-based STUN discovery is unsupported.
# - see: <https://xmpp.org/extensions/xep-0215.html>
# docs: <https://docs.ejabberd.im/admin/configuration/modules/#mod-stun-disco>
# people say to just keep this defaulted (i guess ejabberd knows to return its `host` option of uninsane.org?)
mod_stun_disco: {}
# docs: <https://docs.ejabberd.im/admin/configuration/modules/#mod-vcard>
mod_vcard:
allow_return_all: true # all users are discoverable (?)
host: vjid.xmpp.uninsane.org
hosts:
- vjid.xmpp.uninsane.org
search: true
mod_vcard_xupdate: {} # needed for avatars
# docs: <https://docs.ejabberd.im/admin/configuration/modules/#mod-pubsub>
mod_pubsub: # needed for avatars
access_createnode: pubsub_createnode_access
host: pubsub.xmpp.uninsane.org
hosts:
- pubsub.xmpp.uninsane.org
plugins:
- pep
# - flat
force_node_config:
# avoid buggy clients to make their bookmarks public
# XXX: not sure if this is necessary: copying config from examples
storage:bookmarks:
access_model: whitelist
mod_version: {}
'';
}

View File

@@ -49,4 +49,13 @@
# the default ("*:0/5") is to run every 5 minutes.
# `systemctl list-timers` to show
systemd.services.freshrss-updater.startAt = lib.mkForce "*:3/30";
services.nginx.virtualHosts."rss.uninsane.org" = {
addSSL = true;
enableACME = true;
# inherit kTLS;
# the routing is handled by services.freshrss.virtualHost
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."rss" = [ "native" ];
}

View File

@@ -72,4 +72,18 @@
"/var/lib/gitea"
];
};
# hosted git (web view and for `git <cmd>` use
# TODO: enable publog?
services.nginx.virtualHosts."git.uninsane.org" = {
forceSSL = true; # gitea complains if served over a different protocol than its config file says
enableACME = true;
# inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:3000";
};
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."git" = [ "native" ];
}

View File

@@ -25,6 +25,7 @@
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
Type = "simple";
Restart = "on-failure";
RestartSec = "10s";
# hardening
WorkingDirectory = "/tmp";
@@ -42,4 +43,26 @@
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
};
# server statistics
services.nginx.virtualHosts."sink.uninsane.org" = {
addSSL = true;
enableACME = true;
# inherit kTLS;
root = "/var/lib/uninsane/sink";
locations."/ws" = {
proxyPass = "http://127.0.0.1:7890";
# XXX not sure how much of this is necessary
extraConfig = ''
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_read_timeout 7d;
'';
};
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."sink" = [ "native" ];
}

View File

@@ -14,6 +14,28 @@ lib.mkIf false # i don't actively use ipfs anymore
# TODO: mode? could be more granular
{ user = "261"; group = "261"; directory = "/var/lib/ipfs"; }
];
networking.firewall.allowedTCPPorts = [ 4001 ];
networking.firewall.allowedUDPPorts = [ 4001 ];
services.nginx.virtualHosts."ipfs.uninsane.org" = {
# don't default to ssl upgrades, since this may be dnslink'd from a different domain.
# ideally we'd disable ssl entirely, but some places assume it?
addSSL = true;
enableACME = true;
# inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:8080";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Ipfs-Gateway-Prefix "";
'';
};
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."ipfs" = [ "native" ];
# services.ipfs.enable = true;
services.kubo.localDiscovery = true;
services.kubo.settings = {

View File

@@ -7,12 +7,26 @@
];
services.jackett.enable = true;
systemd.services.jackett.after = ["wg0veth.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";
# patch jackett to listen on the public interfaces
# ExecStart = lib.mkForce "${pkgs.jackett}/bin/Jackett --NoUpdates --DataFolder /var/lib/jackett/.config/Jackett --ListenPublic";
};
# jackett torrent search
services.nginx.virtualHosts."jackett.uninsane.org" = {
forceSSL = true;
enableACME = true;
# inherit kTLS;
locations."/" = {
# proxyPass = "http://ovpns.uninsane.org:9117";
proxyPass = "http://10.0.1.6:9117";
};
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."jackett" = [ "native" ];
}

View File

@@ -1,14 +1,69 @@
{ config, ... }:
{ config, lib, ... }:
# TODO: re-enable after migrating media dir to /var/lib/uninsane/media
# else it's too spammy
lib.mkIf false
{
networking.firewall.allowedUDPPorts = [
1900 7359 # DLNA: https://jellyfin.org/docs/general/networking/index.html
];
sane.impermanence.service-dirs = [
# TODO: mode? could be more granular
{ user = "jellyfin"; group = "jellyfin"; directory = "/var/lib/jellyfin"; }
];
# Jellyfin multimedia server
# this is mostly taken from the official jellfin.org docs
services.nginx.virtualHosts."jelly.uninsane.org" = {
addSSL = true;
enableACME = true;
# inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:8096";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;
'';
};
# locations."/web/" = {
# proxyPass = "http://127.0.0.1:8096/web/index.html";
# extraConfig = ''
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Forwarded-Protocol $scheme;
# proxy_set_header X-Forwarded-Host $http_host;
# '';
# };
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096";
extraConfig = ''
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
'';
};
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."jelly" = [ "native" ];
# users.users.jellyfin.uid = config.sane.allocations.jellyfin-uid;
# users.groups.jellyfin.gid = config.sane.allocations.jellyfin-gid;
# TODO: re-enable after migrating media dir to /var/lib/uninsane/media
# else it's too spammy
# services.jellyfin.enable = true;
services.jellyfin.enable = true;
}

View File

@@ -0,0 +1,17 @@
{ ... }:
{
sane.services.kiwix-serve = {
enable = true;
port = 8013;
zimPaths = [ "/var/lib/uninsane/www-archive/wikipedia_en_all_maxi_2022-05.zim" ];
};
services.nginx.virtualHosts."w.uninsane.org" = {
forceSSL = true;
enableACME = true;
# inherit kTLS;
locations."/".proxyPass = "http://127.0.0.1:8013";
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."w" = [ "native" ];
}

View File

@@ -1,6 +1,6 @@
# docs: https://nixos.wiki/wiki/Matrix
# docs: https://nixos.org/manual/nixos/stable/index.html#module-services-matrix-synapse
{ config, lib, ... }:
{ config, lib, pkgs, ... }:
{
imports = [
@@ -77,6 +77,55 @@
# create a token with limited uses:
# curl -d '{ "uses_allowed": 1 }' --header "Authorization: Bearer <my_token>" localhost:8008/_synapse/admin/v1/registration_tokens/new
# matrix chat server
# TODO: was `publog`
services.nginx.virtualHosts."matrix.uninsane.org" = {
addSSL = true;
enableACME = true;
# inherit kTLS;
# TODO colin: replace this with something helpful to the viewer
# locations."/".extraConfig = ''
# return 404;
# '';
locations."/" = {
proxyPass = "http://127.0.0.1:8008";
};
# redirect browsers to the web client.
# i don't think native matrix clients ever fetch the root.
# ideally this would be put behind some user-agent test though.
locations."= /" = {
return = "301 https://web.matrix.uninsane.org";
};
# locations."/_matrix" = {
# proxyPass = "http://127.0.0.1:8008";
# };
};
# matrix web client
# docs: https://nixos.org/manual/nixos/stable/index.html#module-services-matrix-element-web
services.nginx.virtualHosts."web.matrix.uninsane.org" = {
forceSSL = true;
enableACME = true;
# inherit kTLS;
root = pkgs.element-web.override {
conf = {
default_server_config."m.homeserver" = {
"base_url" = "https://matrix.uninsane.org";
"server_name" = "uninsane.org";
};
};
};
};
sane.services.trust-dns.zones."uninsane.org".inet = {
CNAME."matrix" = [ "native" ];
CNAME."web.matrix" = [ "native" ];
};
sops.secrets.matrix_synapse_secrets = {
sopsFile = ../../../../secrets/servo.yaml;

View File

@@ -14,4 +14,13 @@
AutoImportPlaylists = false;
ScanSchedule = "@every 1h";
};
services.nginx.virtualHosts."music.uninsane.org" = {
forceSSL = true;
enableACME = true;
# inherit kTLS;
locations."/".proxyPass = "http://127.0.0.1:4533";
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."music" = [ "native" ];
}

View File

@@ -9,9 +9,12 @@ let
'';
};
kTLS = true; # in-kernel TLS for better perf
# kTLS = true; # in-kernel TLS for better perf
in
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx.enable = true;
services.nginx.appendConfig = ''
# use 1 process per core.
@@ -45,7 +48,7 @@ in
# and things don't look right. so force SSL.
forceSSL = true;
enableACME = true;
inherit kTLS;
# inherit kTLS;
# for OCSP stapling
sslTrustedCertificate = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
@@ -93,246 +96,6 @@ in
# };
};
# server statistics
services.nginx.virtualHosts."sink.uninsane.org" = {
addSSL = true;
enableACME = true;
inherit kTLS;
root = "/var/lib/uninsane/sink";
locations."/ws" = {
proxyPass = "http://127.0.0.1:7890";
# XXX not sure how much of this is necessary
extraConfig = ''
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_read_timeout 7d;
'';
};
};
# Pleroma server and web interface
services.nginx.virtualHosts."fed.uninsane.org" = publog {
forceSSL = true; # pleroma redirects to https anyway
enableACME = true;
inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:4000";
# documented: https://git.pleroma.social/pleroma/pleroma/-/blob/develop/installation/pleroma.nginx
extraConfig = ''
# XXX colin: this block is in the nixos examples: i don't understand all of it
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
if ($request_method = OPTIONS) {
return 204;
}
add_header X-XSS-Protection "1; mode=block";
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy same-origin;
add_header X-Download-Options noopen;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# proxy_set_header Host $http_host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# colin: added this due to Pleroma complaining in its logs
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 16m;
'';
};
};
# transmission web client
services.nginx.virtualHosts."bt.uninsane.org" = {
# basicAuth is literally cleartext user/pw, so FORCE this to happen over SSL
forceSSL = true;
enableACME = true;
inherit kTLS;
locations."/" = {
# proxyPass = "http://ovpns.uninsane.org:9091";
proxyPass = "http://10.0.1.6:9091";
};
};
# jackett torrent search
services.nginx.virtualHosts."jackett.uninsane.org" = {
forceSSL = true;
enableACME = true;
inherit kTLS;
locations."/" = {
# proxyPass = "http://ovpns.uninsane.org:9117";
proxyPass = "http://10.0.1.6:9117";
};
};
# matrix chat server
services.nginx.virtualHosts."matrix.uninsane.org" = publog {
addSSL = true;
enableACME = true;
inherit kTLS;
# TODO colin: replace this with something helpful to the viewer
# locations."/".extraConfig = ''
# return 404;
# '';
locations."/" = {
proxyPass = "http://127.0.0.1:8008";
};
# redirect browsers to the web client.
# i don't think native matrix clients ever fetch the root.
# ideally this would be put behind some user-agent test though.
locations."= /" = {
return = "301 https://web.matrix.uninsane.org";
};
# locations."/_matrix" = {
# proxyPass = "http://127.0.0.1:8008";
# };
};
# matrix web client
# docs: https://nixos.org/manual/nixos/stable/index.html#module-services-matrix-element-web
services.nginx.virtualHosts."web.matrix.uninsane.org" = {
forceSSL = true;
enableACME = true;
inherit kTLS;
root = pkgs.element-web.override {
conf = {
default_server_config."m.homeserver" = {
"base_url" = "https://matrix.uninsane.org";
"server_name" = "uninsane.org";
};
};
};
};
# hosted git (web view and for `git <cmd>` use
services.nginx.virtualHosts."git.uninsane.org" = publog {
forceSSL = true; # gitea complains if served over a different protocol than its config file says
enableACME = true;
inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:3000";
};
};
# Jellyfin multimedia server
# this is mostly taken from the official jellfin.org docs
services.nginx.virtualHosts."jelly.uninsane.org" = {
addSSL = true;
enableACME = true;
inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:8096";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;
'';
};
# locations."/web/" = {
# proxyPass = "http://127.0.0.1:8096/web/index.html";
# extraConfig = ''
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Forwarded-Protocol $scheme;
# proxy_set_header X-Forwarded-Host $http_host;
# '';
# };
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096";
extraConfig = ''
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
'';
};
};
services.nginx.virtualHosts."music.uninsane.org" = {
forceSSL = true;
enableACME = true;
inherit kTLS;
locations."/".proxyPass = "http://127.0.0.1:4533";
};
services.nginx.virtualHosts."rss.uninsane.org" = {
addSSL = true;
enableACME = true;
inherit kTLS;
# the routing is handled by freshrss.nix
};
services.nginx.virtualHosts."ipfs.uninsane.org" = {
# don't default to ssl upgrades, since this may be dnslink'd from a different domain.
# ideally we'd disable ssl entirely, but some places assume it?
addSSL = true;
enableACME = true;
inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:8080";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Ipfs-Gateway-Prefix "";
'';
};
};
# exists only to manage certs for dovecot
services.nginx.virtualHosts."imap.uninsane.org" = {
forceSSL = true;
enableACME = true;
};
# exists only to manage certs for Postfix
services.nginx.virtualHosts."mx.uninsane.org" = {
forceSSL = true;
enableACME = true;
};
services.nginx.virtualHosts."nixcache.uninsane.org" = {
addSSL = true;
enableACME = true;
inherit kTLS;
# serverAliases = [ "nixcache" ];
locations."/".extraConfig = ''
proxy_pass http://localhost:${toString config.services.nix-serve.port};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
'';
};
# serve any site not listed above, if it's static.
# because we define it dynamically, SSL isn't trivial. support only http

View File

@@ -0,0 +1,21 @@
{ config, ... }:
{
services.nginx.virtualHosts."nixcache.uninsane.org" = {
addSSL = true;
enableACME = true;
# inherit kTLS;
# serverAliases = [ "nixcache" ];
locations."/".extraConfig = ''
proxy_pass http://localhost:${toString config.services.nix-serve.port};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
'';
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."nixcache" = [ "native" ];
sane.services.nixserve.enable = true;
sane.services.nixserve.sopsFile = ../../../secrets/servo.yaml;
}

View File

@@ -127,6 +127,7 @@
systemd.services.pleroma.serviceConfig = {
# postgres can be slow to service early requests, preventing pleroma from starting on the first try
Restart = "on-failure";
RestartSec = "10s";
};
# systemd.services.pleroma.serviceConfig = {
@@ -136,6 +137,50 @@
# CapabilityBoundingSet = lib.mkForce "~";
# };
# Pleroma server and web interface
# TODO: enable publog?
services.nginx.virtualHosts."fed.uninsane.org" = {
forceSSL = true; # pleroma redirects to https anyway
enableACME = true;
# inherit kTLS;
locations."/" = {
proxyPass = "http://127.0.0.1:4000";
# documented: https://git.pleroma.social/pleroma/pleroma/-/blob/develop/installation/pleroma.nginx
extraConfig = ''
# XXX colin: this block is in the nixos examples: i don't understand all of it
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
if ($request_method = OPTIONS) {
return 204;
}
add_header X-XSS-Protection "1; mode=block";
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy same-origin;
add_header X-Download-Options noopen;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# proxy_set_header Host $http_host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# colin: added this due to Pleroma complaining in its logs
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 16m;
'';
};
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."fed" = [ "native" ];
sops.secrets.pleroma_secrets = {
sopsFile = ../../../secrets/servo.yaml;
owner = config.users.users.pleroma.name;

View File

@@ -25,6 +25,61 @@ in
# "/var/lib/dhparams" # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/dhparams.nix
# "/var/lib/dovecot"
];
networking.firewall.allowedTCPPorts = [
25 # SMTP
143 # IMAP
465 # SMTPS
587 # SMTPS/submission
993 # IMAPS
];
# exists only to manage certs for dovecot
services.nginx.virtualHosts."imap.uninsane.org" = {
enableACME = true;
};
# exists only to manage certs for Postfix
services.nginx.virtualHosts."mx.uninsane.org" = {
enableACME = true;
};
sane.services.trust-dns.zones."uninsane.org".inet = {
MX."@" = [ "10 mx.uninsane.org." ];
# XXX: RFC's specify that the MX record CANNOT BE A CNAME
A."mx" = [ "185.157.162.178" ];
CNAME."imap" = [ "native" ];
# Sender Policy Framework:
# +mx => mail passes if it originated from the MX
# +a => mail passes if it originated from the A address of this domain
# +ip4:.. => mail passes if it originated from this IP
# -all => mail fails if none of these conditions were met
TXT."@" = [ "v=spf1 a mx -all" ];
# DKIM public key:
TXT."mx._domainkey" = [
"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkSyMufc2KrRx3j17e/LyB+3eYSBRuEFT8PUka8EDX04QzCwDPdkwgnj3GNDvnB5Ktb05Cf2SJ/S1OLqNsINxJRWtkVfZd/C339KNh9wrukMKRKNELL9HLUw0bczOI4gKKFqyrRE9qm+4csCMAR79Te9FCjGV/jVnrkLdPT0GtFwIDAQAB"
];
# DMARC fields <https://datatracker.ietf.org/doc/html/rfc7489>:
# p=none|quarantine|reject: what to do with failures
# sp = p but for subdomains
# rua = where to send aggregrate reports
# ruf = where to send individual failure reports
# fo=0|1|d|s controls WHEN to send failure reports
# (1=on bad alignment; d=on DKIM failure; s=on SPF failure);
# Additionally:
# adkim=r|s (is DKIM relaxed [default] or strict)
# aspf=r|s (is SPF relaxed [default] or strict)
# pct = sampling ratio for punishing failures (default 100 for 100%)
# rf = report format
# ri = report interval
TXT."_dmarc" = [
"v=DMARC1;p=quarantine;sp=reject;rua=mailto:admin+mail@uninsane.org;ruf=mailto:admin+mail@uninsane.org;fo=1:d:s"
];
};
services.postfix.enable = true;
services.postfix.hostname = "mx.uninsane.org";
services.postfix.origin = "uninsane.org";
@@ -55,7 +110,8 @@ in
services.postfix.enableSubmissions = true;
services.postfix.submissionsOptions = submissionOptions;
systemd.services.postfix.after = [ "wg0veth.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";
@@ -76,7 +132,8 @@ in
# keeping this the same as the hostname seems simplest
services.opendkim.selector = "mx";
systemd.services.opendkim.after = [ "wg0veth.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";

View File

@@ -1,3 +1,5 @@
# example configs:
# - <https://github.com/kittywitch/nixfiles/blob/main/services/prosody.nix>
# create users with:
# - `sudo -u prosody prosodyctl adduser colin@uninsane.org`
@@ -13,7 +15,7 @@ lib.mkIf false
networking.firewall.allowedTCPPorts = [
5222 # XMPP client -> server
5269 # XMPP server -> server
5280 # Prosody HTTP port (necessary?)
5280 # bosh
5281 # Prosody HTTPS port (necessary?)
];
@@ -34,7 +36,7 @@ lib.mkIf false
# c2s_require_encryption = true
# '';
# extraModules = [ "private" "vcard" "privacy" "compression" "component" "muc" "pep" "adhoc" "lastactivity" "admin_adhoc" "blocklist"];
extraModules = [ "private" "vcard" "privacy" "compression" "component" "muc" "pep" "adhoc" "lastactivity" "admin_adhoc" "blocklist"];
ssl.cert = "/var/lib/acme/uninsane.org/fullchain.pem";
ssl.key = "/var/lib/acme/uninsane.org/key.pem";
@@ -51,7 +53,7 @@ lib.mkIf false
domain = "localhost";
enabled = true;
};
"uninsane.org" = {
"xmpp.uninsane.org" = {
domain = "uninsane.org";
enabled = true;
ssl.cert = "/var/lib/acme/uninsane.org/fullchain.pem";

View File

@@ -1,4 +1,4 @@
{ ... }:
{ pkgs, ... }:
{
sane.impermanence.service-dirs = [
@@ -40,11 +40,41 @@
# transmission will by default not allow the world to read its files.
services.transmission.downloadDirPermissions = "775";
systemd.services.transmission.after = ["wg0veth.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";
LogLevelMax = "warning";
};
# service to automatically backup torrents i add to transmission
systemd.services.backup-torrents = {
description = "archive torrents to storage not owned by transmission";
script = ''
${pkgs.rsync}/bin/rsync -arv /var/lib/transmission/.config/transmission-daemon/torrents/ /var/backup/torrents/
'';
};
systemd.timers.backup-torrents = {
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnStartupSec = "11min";
OnUnitActiveSec = "240min";
};
};
# transmission web client
services.nginx.virtualHosts."bt.uninsane.org" = {
# basicAuth is literally cleartext user/pw, so FORCE this to happen over SSL
forceSSL = true;
enableACME = true;
# inherit kTLS;
locations."/" = {
# proxyPass = "http://ovpns.uninsane.org:9091";
proxyPass = "http://10.0.1.6:9091";
};
};
sane.services.trust-dns.zones."uninsane.org".inet.CNAME."bt" = ["native"];
}

View File

@@ -0,0 +1,69 @@
{ config, pkgs, ... }:
{
sane.services.trust-dns.enable = true;
sane.services.trust-dns.listenAddrsIPv4 = [
# specify each address explicitly, instead of using "*".
# this ensures responses are sent from the address at which the request was received.
"192.168.0.5"
"10.0.1.5"
];
sane.services.trust-dns.zones."uninsane.org".TTL = 900;
# SOA record structure: <https://en.wikipedia.org/wiki/SOA_record#Structure>
# SOA MNAME RNAME (... rest)
# MNAME = Master name server for this zone. this is where update requests should be sent.
# RNAME = admin contact (encoded email address)
# Serial = YYYYMMDDNN, where N is incremented every time this file changes, to trigger secondary NS to re-fetch it.
# Refresh = how frequently secondary NS should query master
# Retry = how long secondary NS should wait until re-querying master after a failure (must be < Refresh)
# Expire = how long secondary NS should continue to reply to queries after master fails (> Refresh + Retry)
sane.services.trust-dns.zones."uninsane.org".inet = {
SOA."@" = [''
ns1.uninsane.org. admin-dns.uninsane.org. (
2022121601 ; Serial
4h ; Refresh
30m ; Retry
7d ; Expire
5m) ; Negative response TTL
''];
TXT."rev" = [ "2022121801" ];
# XXX NS records must also not be CNAME
# it's best that we keep this identical, or a superset of, what org. lists as our NS.
# so, org. can specify ns2/ns3 as being to the VPN, with no mention of ns1. we provide ns1 here.
# A."ns1" = [ "%NATIVE%" ];
A."ns2" = [ "185.157.162.178" ];
A."ns3" = [ "185.157.162.178" ];
A."ovpns" = [ "185.157.162.178" ];
NS."@" = [
"ns1.uninsane.org."
"ns2.uninsane.org."
"ns3.uninsane.org."
];
};
sane.services.trust-dns.zones."uninsane.org".include = [
"/var/lib/trust-dns/native.uninsane.org.zone"
];
systemd.services.trust-dns.preStart = let
sed = "${pkgs.gnused}/bin/sed";
zone-dir = "/var/lib/trust-dns";
zone-out = "${zone-dir}/native.uninsane.org.zone";
zone-template = pkgs.writeText "native.uninsane.org.zone.in" ''
@ A %NATIVE%
ns1 A %NATIVE%
native A %NATIVE%
'';
in ''
# make WAN records available to trust-dns
mkdir -p ${zone-dir}
ip=$(cat '${config.sane.services.dyn-dns.ipPath}')
${sed} s/%NATIVE%/$ip/ ${zone-template} > ${zone-out}
'';
sane.services.dyn-dns.restartOnChange = [ "trust-dns.service" ];
}

View File

@@ -0,0 +1,33 @@
# docs: <https://nixos.wiki/wiki/MediaWiki>
{ config, lib, ... }:
# XXX: working to host wikipedia with kiwix instead of mediawiki
# mediawiki does more than i need and isn't obviously superior in any way
# except that the dumps are more frequent/up-to-date.
lib.mkIf false
{
sops.secrets."mediawiki_pw" = {
owner = config.users.users.mediawiki.name;
sopsFile = ../../../secrets/servo.yaml;
};
users.users.mediawiki.uid = config.sane.allocations.mediawiki-uid;
services.mediawiki.enable = true;
services.mediawiki.name = "Uninsane Wiki";
services.mediawiki.passwordFile = config.sops.secrets.mediawiki_pw.path;
services.mediawiki.extraConfig = ''
# Disable anonymous editing
$wgGroupPermissions['*']['edit'] = false;
'';
services.mediawiki.virtualHost.listen = [
{
ip = "127.0.0.1";
port = 8013;
ssl = false;
}
];
services.mediawiki.virtualHost.hostName = "w.uninsane.org";
services.mediawiki.virtualHost.adminAddr = "admin+mediawiki@uninsane.org";
# services.mediawiki.extensions = TODO: wikipedia sync extension?
}

View File

@@ -23,8 +23,10 @@ in
sane.allocations.greeter-uid = mkId 999;
sane.allocations.greeter-gid = mkId 999;
# new servo users
sane.allocations.freshrss-uid = mkId 2401;
sane.allocations.freshrss-gid = mkId 2401;
sane.allocations.mediawiki-uid = mkId 2402;
sane.allocations.colin-uid = mkId 1000;
sane.allocations.guest-uid = mkId 1100;

9
modules/gui/snippets.txt Normal file
View File

@@ -0,0 +1,9 @@
https://search.nixos.org/packages?channel=unstable&query=
https://nixos.wiki/index.php?go=Go&search=
https://github.com/nixos/nixpkgs/pulls?q=
https://w.uninsane.org/viewer#search?books.name=wikipedia_en_all_maxi_2022-05&pattern=
https://fed.uninsane.org
https://jackett.uninsane.org
https://bt.uninsane.org
https://sci-hub.se
https://news.ycombinator.com

View File

@@ -81,8 +81,25 @@ in
sane.home-manager.windowManager.sway = {
enable = true;
wrapperFeatures.gtk = true;
config = rec {
terminal = "${pkgs.kitty}/bin/kitty";
config = let
fuzzel = "${pkgs.fuzzel}/bin/fuzzel";
wtype = "${pkgs.wtype}/bin/wtype";
kitty = "${pkgs.kitty}/bin/kitty";
lock-cmd = "${pkgs.swaylock}/bin/swaylock --indicator-idle-visible --indicator-radius 100 --indicator-thickness 30";
vol-up-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5";
vol-down-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5";
mute-cmd = "${pkgs.pulsemixer}/bin/pulsemixer --toggle-mute";
brightness-up-cmd = "${pkgs.brightnessctl}/bin/brightnessctl set +2%";
brightness-down-cmd = "${pkgs.brightnessctl}/bin/brightnessctl set 2%-";
screenshot-cmd = "${pkgs.sway-contrib.grimshot}/bin/grimshot copy area";
# "bookmarking"/snippets inspired by Luke Smith:
# - <https://www.youtube.com/watch?v=d_11QaTlf1I>
snip-file = ./snippets.txt;
snip-cmd = "${wtype} $(cat ${snip-file} | ${fuzzel} -d -i)";
# TODO: next splatmoji release should allow `-s none` to disable skin tones
emoji-cmd = "${pkgs.splatmoji}/bin/splatmoji -s medium-light type";
in rec {
terminal = kitty;
window = {
border = 3; # pixel boundary between windows
hideEdgeBorders = "smart"; # don't show border if only window on workspace
@@ -103,7 +120,7 @@ in
modifier = "Mod1";
# list of launchers: https://www.reddit.com/r/swaywm/comments/v39hxa/your_favorite_launcher/
# menu = "${pkgs.dmenu}/bin/dmenu_path";
menu = "${pkgs.fuzzel}/bin/fuzzel";
menu = fuzzel;
# menu = "${pkgs.albert}/bin/albert";
left = "h";
down = "j";
@@ -114,7 +131,9 @@ in
"${modifier}+Return" = "exec ${terminal}";
"${modifier}+Shift+q" = "kill";
"${modifier}+d" = "exec ${menu}";
"${modifier}+l" = "exec ${pkgs.swaylock}/bin/swaylock --indicator-idle-visible --indicator-radius 100 --indicator-thickness 30";
"${modifier}+s" = "exec ${snip-cmd}";
"${modifier}+l" = "exec ${lock-cmd}";
"${modifier}+slash" = "exec ${emoji-cmd}";
# "${modifier}+${left}" = "focus left";
# "${modifier}+${down}" = "focus down";
@@ -141,7 +160,7 @@ in
"${modifier}+f" = "fullscreen toggle";
"${modifier}+a" = "focus parent";
"${modifier}+s" = "layout stacking";
# "${modifier}+s" = "layout stacking";
"${modifier}+w" = "layout tabbed";
"${modifier}+e" = "layout toggle split";
@@ -185,19 +204,20 @@ in
"exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
"${modifier}+r" = "mode resize";
} // {
# media keys
XF86MonBrightnessDown = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set 2%-"'';
XF86MonBrightnessUp = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set +2%"'';
XF86MonBrightnessDown = "exec ${brightness-down-cmd}";
XF86MonBrightnessUp = "exec ${brightness-up-cmd}";
XF86AudioRaiseVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5'";
XF86AudioLowerVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5'";
XF86AudioMute = "exec '${pkgs.pulsemixer}/bin/pulsemixer --toggle-mute'";
# TODO: hook into a visual prompt to display volume?
XF86AudioRaiseVolume = "exec ${vol-up-cmd}";
XF86AudioLowerVolume = "exec ${vol-down-cmd}";
XF86AudioMute = "exec ${mute-cmd}";
"${modifier}+Page_Up" = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5'";
"${modifier}+Page_Down" = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5'";
"${modifier}+Page_Up" = "exec ${vol-up-cmd}";
"${modifier}+Page_Down" = "exec ${vol-down-cmd}";
"${modifier}+Print" = "exec '${pkgs.sway-contrib.grimshot}/bin/grimshot copy area'";
"${modifier}+Print" = "exec ${screenshot-cmd}";
};
# mostly defaults:

View File

@@ -26,6 +26,7 @@ in
./mpv.nix
./nb.nix
./neovim.nix
./splatmoji.nix
./ssh.nix
./sublime-music.nix
./vlc.nix

View File

@@ -63,6 +63,10 @@ in rec {
(mkPod "https://www.cbsnews.com/latest/rss/60-minutes" // pol // infrequent)
## The Verge - Decoder
(mkPod "https://feeds.megaphone.fm/recodedecode" // tech // weekly)
## Matrix (chat) Live
(mkPod "https://feed.podbean.com/matrixlive/feed.xml" // tech // weekly)
## Michael Malice - Your Welcome
(mkPod "https://www.podcastone.com/podcast?categoryID2=2232" // pol // weekly)
];
texts = [

View File

@@ -43,6 +43,7 @@ let
addon = name: extid: hash: pkgs.fetchFirefoxAddon {
inherit name hash;
url = "https://addons.mozilla.org/firefox/downloads/latest/${name}/latest.xpi";
# extid can be found by unar'ing the above xpi, and copying browser_specific_settings.gecko.id field
fixedExtid = extid;
};
localAddon = pkg: pkgs.fetchFirefoxAddon {
@@ -51,11 +52,16 @@ let
fixedExtid = pkg.extid;
};
in [
# get names from:
# - ~/ref/nix-community/nur-combined/repos/rycee/pkgs/firefox-addons/generated-firefox-addons.nix
# `wget ...xpi`; `unar ...xpi`; `cat */manifest.json | jq '.browser_specific_settings.gecko.id'`
(addon "ublock-origin" "uBlock0@raymondhill.net" "sha256-+xc4lcdsOwXxMsr4enFsdePbIb6GHq0bFLpqvH5xXos=")
(addon "sponsorblock" "sponsorBlocker@ajay.app" "sha256-30F8oDIgshXVY7YKgnfoc1tUTHfgeFbzXISJuVJs0AM=")
(addon "bypass-paywalls-clean" "{d133e097-46d9-4ecc-9903-fa6a722a6e0e}" "sha256-aDBRpcOeMyROnXjmveHKm9zsPC+LzXCG0uhAqI1EWf0=")
(addon "bypass-paywalls-clean" "{d133e097-46d9-4ecc-9903-fa6a722a6e0e}" "sha256-7ZDkG8O1rEYdh/La0PLi9tp92JxYeQvaOFt/BmnDv3U=")
(addon "sidebery" "{3c078156-979c-498b-8990-85f7987dd929}" "sha256-YONfK/rIjlsrTgRHIt3km07Q7KnpIW89Z9r92ZSCc6w=")
(addon "ether-metamask" "webextension@metamask.io" "sha256-G+MwJDOcsaxYSUXjahHJmkWnjLeQ0Wven8DU/lGeMzA=")
(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

@@ -0,0 +1,20 @@
# borrows from:
# - default config: <https://github.com/cspeterson/splatmoji/blob/master/splatmoji.config>
# - wayland: <https://github.com/cspeterson/splatmoji/issues/32#issuecomment-830862566>
{ pkgs, ... }:
{
home-manager.users.colin = {
xdg.configFile."splatmoji/splatmoji.config".text = ''
history_file=/home/colin/.local/state/splatmoji/history
history_length=5
# TODO: wayland equiv
paste_command=xdotool key ctrl+v
# rofi_command=${pkgs.wofi}/bin/wofi --dmenu --insensitive --cache-file /dev/null
rofi_command=${pkgs.fuzzel}/bin/fuzzel -d -i -w 80
xdotool_command=${pkgs.wtype}/bin/wtype
# TODO: wayland equiv
xsel_command=xsel -b -i
'';
};
}

View File

@@ -59,5 +59,12 @@ lib.mkIf config.sane.home-manager.enable
# common typos
"cd.." = "cd ..";
"cd../" = "cd ../";
# convenient `cd`-isms
"knowledge" = "cd ~/knowledge";
"nixos" = "cd ~/nixos";
"nixpkgs" = "cd ~/dev/3rd/nixpkgs";
"ref" = "cd ~/ref";
"secrets" = "cd ~/knowledge/secrets";
"uninsane" = "cd ~/dev/uninsane";
};
}

View File

@@ -50,6 +50,7 @@ in
# "/var/lib/AccountsService" # not sure what this is, but it's empty
"/var/lib/alsa" # preserve output levels, default devices
# "/var/lib/blueman" # files aren't human readable
# TODO: if we changed the bluetooth installer to auto-discover the host MAC address, we could de-persist this
"/var/lib/bluetooth" # preserve bluetooth handshakes
"/var/lib/colord" # preserve color calibrations (?)
# "/var/lib/dhclient" # empty on lappy; dunno about desko

View File

@@ -4,6 +4,11 @@ with lib;
with pkgs;
let
cfg = config.sane.packages;
imagemagick = pkgs.imagemagick.override {
ghostscriptSupport = true;
};
consolePkgs = [
backblaze-b2
cdrtools
@@ -12,11 +17,13 @@ let
efivar
flashrom
fwupd
ghostscript # TODO: imagemagick wrapper should add gs to PATH
gnupg
gocryptfs
gopass
gopass-jsonapi
ifuse
imagemagick
ipfs
libimobiledevice
libsecret # for managing user keyrings
@@ -80,6 +87,7 @@ let
# then reboot (so that libsecret daemon re-loads the keyring...?)
{ pkg = fractal-next; private = ".local/share/fractal"; }
gajim # XMPP client
gimp # broken on phosh
gnome.cheese
gnome.dconf-editor
@@ -153,7 +161,7 @@ let
# kaiteki # Pleroma client
# gnome.zenity # for kaiteki (it will use qarma, kdialog, or zenity)
gpt2tc
# gpt2tc # XXX: unreliable mirror
logseq
losslesscut-bin
@@ -203,11 +211,14 @@ let
parted
pciutils
powertop
pstree
ripgrep
screen
smartmontools
socat
strace
tcpdump
tree
usbutils
wget
];

View File

@@ -2,6 +2,9 @@
{
imports = [
./duplicity.nix
./dyn-dns.nix
./kiwix-serve.nix
./nixserve.nix
./trust-dns.nix
];
}

View File

@@ -0,0 +1,91 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.sane.services.dyn-dns;
in
{
options = {
sane.services.dyn-dns = {
enable = mkOption {
default = false;
type = types.bool;
};
ipPath = mkOption {
default = "/var/lib/uninsane/wan.txt";
type = types.str;
description = "where to store the latest WAN IPv4 address";
};
ipCmd = mkOption {
default = "${pkgs.sane-scripts}/bin/sane-ip-check-router-wan";
type = types.path;
description = "command to run to query the current WAN IP";
};
interval = mkOption {
type = types.str;
default = "10min";
description = "systemd time string for how frequently to re-check the IP";
};
restartOnChange = mkOption {
type = types.listOf types.str;
default = [];
description = "list of systemd unit files to restart when the IP changes";
};
};
};
config = mkIf cfg.enable {
systemd.services.dyn-dns = {
description = "update this host's record of its WAN IP";
serviceConfig.Type = "oneshot";
restartTriggers = [(builtins.toJSON cfg)];
after = [ "network.target" ];
wantedBy = cfg.restartOnChange;
before = cfg.restartOnChange;
script = ''
mkdir -p "$(dirname '${cfg.ipPath}')"
newIp=$(${cfg.ipCmd})
oldIp=$(cat '${cfg.ipPath}' || true)
# systemd path units are triggered on any file write action,
# regardless of content change. so only update the file if our IP *actually* changed
if [ "$newIp" != "$oldIp" ]
then
echo "$newIp" > '${cfg.ipPath}'
echo "WAN ip changed $oldIp -> $newIp"
fi
exit $(test -f '${cfg.ipPath}')
'';
};
systemd.timers.dyn-dns = {
# if anything wants dyn-dns.service, they surely want the timer too.
wantedBy = [ "dyn-dns.service" ];
timerConfig = {
OnUnitActiveSec = cfg.interval;
};
};
systemd.paths.dyn-dns-watcher = {
before = [ "dyn-dns.timer" ];
wantedBy = [ "dyn-dns.timer" ];
pathConfig = {
Unit = "dyn-dns-reactor.service";
PathChanged = [ cfg.ipPath ];
};
};
systemd.services.dyn-dns-reactor = {
description = "react to the system's WAN IP changing";
serviceConfig.Type = "oneshot";
script = if cfg.restartOnChange != [] then ''
${pkgs.systemd}/bin/systemctl restart ${toString cfg.restartOnChange}
'' else "${pkgs.coreutils}/bin/true";
};
};
}

View File

@@ -0,0 +1,55 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.sane.services.kiwix-serve;
in
{
options = {
sane.services.kiwix-serve = {
enable = mkOption {
default = false;
type = types.bool;
};
package = mkOption {
type = types.package;
default = pkgs.kiwix-tools;
defaultText = literalExpression "pkgs.kiwix-tools";
description = lib.mdDoc ''
The package that provides `bin/kiwix-serve`.
'';
};
port = mkOption {
type = types.port;
default = 80;
description = lib.mdDoc "Port number to listen on.";
};
listenAddress = mkOption {
type = types.nullOr types.str;
default = null;
description = lib.mdDoc ''
IP address to listen on. Listens on all available addresses if unspecified.
'';
};
zimPaths = mkOption {
type = types.nonEmptyListOf (types.either types.str types.path);
description = lib.mdDoc "ZIM file path(s)";
};
};
};
config = mkIf cfg.enable {
systemd.services.kiwix-serve = {
description = "Deliver ZIM file(s) articles via HTTP";
serviceConfig = let
maybeListenAddress = lib.optionals (cfg.listenAddress != null) ["-l" cfg.listenAddress];
args = maybeListenAddress ++ ["-p" cfg.port] ++ cfg.zimPaths;
in {
ExecStart = "${cfg.package}/bin/kiwix-serve ${lib.escapeShellArgs args}";
Type = "simple";
};
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
};
};
}

View File

@@ -0,0 +1,144 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.sane.services.trust-dns;
toml = pkgs.formats.toml { };
fmtRecord = proto: rrtype: name: value: "${name}\t${proto}\t${rrtype}\t${value}";
fmtRecordList = proto: rrtype: name: values: concatStringsSep
"\n"
(map (fmtRecord proto rrtype name) values)
;
fmtRecordAttrs = proto: rrtype: rrAttrs:
concatStringsSep
"\n"
(
attrValues (
mapAttrs
(name: fmtRecordList proto rrtype name)
rrAttrs
)
);
fmtIncludes = paths: concatStringsSep
"\n"
(map (path: "$INCLUDE ${path}") paths);
configFile = toml.generate "trust-dns.toml" {
listen_addrs_ipv4 = cfg.listenAddrsIPv4;
zones = attrValues (
mapAttrs (zone: zcfg: {
inherit zone;
zone_type = "Primary";
file = pkgs.writeText "${zone}.zone" ''
$TTL ${toString zcfg.TTL}
${fmtRecordAttrs "IN" "SOA" zcfg.inet.SOA}
${fmtRecordAttrs "IN" "A" zcfg.inet.A}
${fmtRecordAttrs "IN" "CNAME" zcfg.inet.CNAME}
${fmtRecordAttrs "IN" "MX" zcfg.inet.MX}
${fmtRecordAttrs "IN" "NS" zcfg.inet.NS}
${fmtRecordAttrs "IN" "SRV" zcfg.inet.SRV}
${fmtRecordAttrs "IN" "TXT" zcfg.inet.TXT}
${fmtIncludes zcfg.include}
${zcfg.extraConfig}
'';
}) cfg.zones
);
};
in
{
options = {
sane.services.trust-dns = {
enable = mkOption {
default = false;
type = types.bool;
};
listenAddrsIPv4 = mkOption {
type = types.listOf types.str;
default = [];
description = "array of ipv4 addresses on which to listen for DNS queries";
};
# reference <nixpkgs:nixos/modules/services/web-servers/nginx/vhost-options.nix>
zones = mkOption {
type = types.attrsOf (types.submodule {
options = {
TTL = mkOption {
type = types.int;
description = "default TTL";
default = 3600;
};
include = mkOption {
type = types.listOf types.str;
description = "paths of other zone files to $INCLUDE into this one";
default = [];
};
extraConfig = mkOption {
type = types.lines;
description = "extra lines to append to the zone file";
default = "";
};
inet = {
SOA = mkOption {
type = types.attrsOf (types.listOf types.str);
description = "Start of Authority record(s)";
default = {};
};
A = mkOption {
type = types.attrsOf (types.listOf types.str);
description = "IPv4 address record(s)";
default = {};
};
CNAME = mkOption {
type = types.attrsOf (types.listOf types.str);
description = "canonical name record(s)";
default = {};
};
MX = mkOption {
type = types.attrsOf (types.listOf types.str);
description = "mail exchanger record(s)";
default = {};
};
NS = mkOption {
type = types.attrsOf (types.listOf types.str);
description = "name server record(s)";
default = {};
};
SRV = mkOption {
type = types.attrsOf (types.listOf types.str);
description = "service record(s)";
default = {};
};
TXT = mkOption {
type = types.attrsOf (types.listOf types.str);
description = "text record(s)";
default = {};
};
};
};
});
default = {};
description = "Declarative zone config";
};
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [ 53 ];
networking.firewall.allowedUDPPorts = [ 53 ];
systemd.services.trust-dns = {
description = "trust-dns DNS server";
serviceConfig = {
ExecStart = ''
${pkgs.trust-dns}/bin/named \
--config ${configFile} \
--zonedir /
'';
Type = "simple";
Restart = "on-failure";
RestartSec = "10s";
# TODO: hardening (like, don't run as root!)
};
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
};
};
}

View File

@@ -0,0 +1,26 @@
diff --git a/pkgs/tools/networking/i2p/default.nix b/pkgs/tools/networking/i2p/default.nix
index e835007fdc5..1406486c7d4 100644
--- a/pkgs/tools/networking/i2p/default.nix
+++ b/pkgs/tools/networking/i2p/default.nix
@@ -50,7 +50,7 @@ stdenv.mkDerivation rec {
binaryBytecode # source bundles dependencies as jars
];
license = licenses.gpl2;
- platforms = [ "x86_64-linux" "i686-linux" ];
+ platforms = [ "x86_64-linux" "i686-linux" "aarch64-linux" ];
maintainers = with maintainers; [ joelmo ];
};
}
diff --git a/pkgs/tools/system/java-service-wrapper/default.nix b/pkgs/tools/system/java-service-wrapper/default.nix
index 93d86a75d18..ab563085f93 100644
--- a/pkgs/tools/system/java-service-wrapper/default.nix
+++ b/pkgs/tools/system/java-service-wrapper/default.nix
@@ -44,7 +44,7 @@ stdenv.mkDerivation rec {
homepage = "https://wrapper.tanukisoftware.com/";
changelog = "https://wrapper.tanukisoftware.com/doc/english/release-notes.html#${version}";
license = licenses.gpl2Only;
- platforms = [ "x86_64-linux" "i686-linux" ];
+ platforms = [ "x86_64-linux" "i686-linux" "aarch64-linux" ];
maintainers = [ maintainers.suhr ];
};
}

View File

@@ -1,4 +1,4 @@
fetchpatch: [
{ fakeHash, fetchpatch }: [
# librewolf: build with `MOZ_REQUIRE_SIGNING=false`
(fetchpatch {
url = "https://github.com/NixOS/nixpkgs/pull/199134.diff";
@@ -6,6 +6,21 @@ fetchpatch: [
sha256 = "sha256-Ne4hyHQDwBHUlWo8Z3QyRdmEv1rYGOjFGxSfOAcLUvQ=";
})
# trust-dns: init at 0.22.0
(fetchpatch {
# https://git.uninsane.org/colin/nixpkgs/compare/master...pr-trust-dns.diff
url = "https://git.uninsane.org/colin/nixpkgs/commit/feee7e0357a74ab0510b2d113a3bdede1d509759.diff";
sha256 = "sha256-t4sG+xLDaxbJ/mV5G18N4ag8EC3IXPgtN5FJGANh1Dc=";
})
# kiwix-tools: init at 3.4.0
(fetchpatch {
url = "https://github.com/NixOS/nixpkgs/pull/206254.diff";
sha256 = "sha256-Z4V9mOv4HYg3kDnWoYcxz3ch03I/1USrLjzlq4X9YqI=";
})
./2022-12-19-i2p-aarch64.patch
# # kaiteki: init at 2022-09-03
# vendorHash changes too frequently (might not be reproducible).
# using local package defn until stabilized

View File

@@ -45,6 +45,8 @@
browserpass-extension = prev.callPackage ./browserpass-extension { };
gopass-native-messaging-host = prev.callPackage ./gopass-native-messaging-host { };
tokodon = prev.libsForQt5.callPackage ./tokodon { };
splatmoji = prev.callPackage ./splatmoji { };
# trust-dns = prev.callPackage ./trust-dns { };
# kaiteki = prev.kaiteki;
})

View File

@@ -18,16 +18,23 @@ resholve.mkDerivation {
scripts = [ "bin/*" ];
interpreter = "${pkgs.bash}/bin/bash";
inputs = with pkgs; [
coreutils
# string is interpreted as relative path from @OUT@.
# this lets our scripts reference eachother.
# see: <https://github.com/abathur/resholve/issues/26>
"bin"
coreutils-full
curl
duplicity
file
findutils
gnugrep
gnused
gocryptfs
ifuse
inetutils
inotify-tools
iwd
jq
ncurses
oath-toolkit
openssh
@@ -36,6 +43,7 @@ resholve.mkDerivation {
ssh-to-age
sops
sudo
systemd
util-linux
which
];
@@ -49,33 +57,47 @@ resholve.mkDerivation {
fake = {
external = [
# https://github.com/abathur/resholve/issues/29
"umount"
# "umount"
# "/run/wrappers/bin/sudo"
"sudo"
# these are used internally; probably a better fix
"sane-mount-servo"
"sane-private-unlock"
];
};
fix = {
# this replaces umount with the non-setuid-wrapper umount.
# not sure if/where that lack of suid causes problems.
umount = true;
};
# prologue is broken; see <https://github.com/abathur/resholve/issues/89>
# prologue = "bin/prologue";
# list of programs which *can* or *cannot* exec their arguments
execer = with pkgs; [
"cannot:${duplicity}/bin/duplicity"
"cannot:${gocryptfs}/bin/gocryptfs"
"cannot:${ifuse}/bin/ifuse"
"cannot:${iwd}/bin/iwctl"
"cannot:${oath-toolkit}/bin/oathtool"
"cannot:${openssh}/bin/ssh-keygen"
"cannot:${rmlint}/bin/rmlint"
"cannot:${rsync}/bin/rsync"
"cannot:${sops}/bin/sops"
"cannot:${ssh-to-age}/bin/ssh-to-age"
"cannot:${systemd}/bin/systemctl"
];
};
};
patchPhase = ''
# remove python scripts
# TODO: figure out how to make resholve process only shell scripts
rm sane-reclaim-boot-space
'';
installPhase = ''
mkdir -p "$out/bin"
cp -R * "$out"/bin/
mkdir -p $out/bin
cp -R * $out/bin/
# allow scripts to make use of sudo, umount wrappers
sed -i '3iPATH=$PATH:/run/wrappers/bin' $out/bin/*;
'';
meta = {

View File

@@ -0,0 +1,3 @@
#!/usr/bin/env bash
curl https://ipinfo.io/ip
echo

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# query the WAN IP address OF MY ROUTER
# requires creds
passwd=$(sudo cat /run/secrets/router_passwd)
cookie=$(mktemp)
# authenticate
curl -s --insecure --cookie-jar $cookie \
--data "username=admin&password=$passwd" \
https://192.168.0.1
# query the WAN IP
curl -s --insecure --cookie $cookie \
-H "X-Requested-With: XMLHttpRequest" \
"https://192.168.0.1/cgi/cgi_action?Action=GetConnectionStatus" \
| jq -r .wan_status.ipaddr

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# reconnect to best wifi network.
# lappy frequently DCs from the ideal network
set -ex
sudo iwctl station wlan0 scan
sleep 5
# get networks. remove control characters (colors), then leading info, then take the top-rated network
networks=$(iwctl station wlan0 get-networks rssi-dbms | sed 's/\[[0-9;]*m//g' | sed 's/ [ >]*/ /g' | sed 's/^ //' | tail -n +5)
strengths=$(echo "$networks" | grep -o '\-[0-9][0-9]* *$')
best_strength=$(echo "$strengths" | sort -h | tail -n 1)
best_line=$(echo "$networks" | grep -- "$best_strength$")
# network names could have spaces in them if someone's evil, so rather than `cut`, we trim the `psk` and `db` columnds
best_network=$(echo "$best_line" | sed 's/ [a-z][a-z]* -[0-9][0-9]* *$//g')
sudo iwctl station wlan0 connect "$best_network"

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
# unlock the ~/private store, run some command, and then re-lock the store
set -x
external_cmd=$@
sane-private-unlock
$external_cmd
exec sane-private-lock

View File

@@ -2,8 +2,7 @@
set -ex
# configure persistent, encrypted storage that is auto-mounted on login.
# this is a one-time setup and user should log out/back in after running it.
# mounts ~/private
mount=/home/colin/private
cipher="/nix/persist$mount"

View File

@@ -1,3 +1,10 @@
#!/usr/bin/env sh
# copy some remote file(s) to the working directory, with sane defaults
rsync -arv --progress --append-verify "$@" .
# rsync, with sane defaults
# + verbosity
# + default to cwd as destination if none is provided
dest=
if (( $# <= 1 )); then
# rsync to the current directory by default
dest='.'
fi
rsync -arv --progress --append-verify "$@" $dest

View File

@@ -0,0 +1,194 @@
#!/usr/bin/env python3
import os
import os.path
import subprocess
import sys
EXTLINUX_CONF = "/boot/extlinux/extlinux.conf"
class ConfItem:
pass
class ConfLine:
""" uninteresting line in the config """
def __init__(self, line: str):
self.line = line
def __str__(self) -> str:
return self.line
class ConfEntry:
""" boot entry, with label/linux/etc """
menu = linux = initrd = append = fdtdir = None
def __init__(self, label: str):
self.label = label
def format_attr(self, attr_name: str) -> str:
attr_val = getattr(self, attr_name)
assert attr_val is not None, f"not set: {attr_name}"
return f"{attr_name.upper()} {attr_val}"
def __str__(self) -> str:
return f"""
{self.format_attr("label")}
{self.format_attr("menu")}
{self.format_attr("linux")}
{self.format_attr("initrd")}
{self.format_attr("append")}
{self.format_attr("fdtdir")}
""".strip()
def parse(self, line: str) -> None:
split_at = line.index(" ")
directive, contents = line[:split_at], line[1+split_at:]
self.setattr(directive.lower(), contents)
def setattr(self, directive: str, contents: str) -> None:
assert getattr(self, directive) is None, f"attr already set: {directive} = {contents!r}"
setattr(self, directive, contents)
class UseTracker:
def __init__(self):
self.linux = []
self.initrd = []
self.fdtdir = []
self.sizes = {} # item: str -> [num_using, bytes]
@staticmethod
def from_items(entries: list) -> 'UseTracker':
me = UseTracker()
me.populate_from_fs()
for i in entries:
me.track(i)
return me
def populate_from_fs(self) -> None:
for entry in os.listdir("/boot/nixos"):
item = os.path.join("../nixos", entry)
self.sizes[item] = [0, self._get_size(item)]
def append_unique(self, list_: list, item: str) -> None:
if item not in list_:
list_.append(item)
self.sizes[item][0] += 1
def track(self, entry: ConfItem) -> None:
if isinstance(entry, ConfEntry):
self.append_unique(self.linux, entry.linux)
self.append_unique(self.initrd, entry.initrd)
self.append_unique(self.fdtdir, entry.fdtdir)
def get_use_count(self, item: str) -> int:
return self.sizes[item][0]
def get_size(self, item: str) -> int:
return self.sizes[item][1]
def used_size(self) -> int:
return sum(i[1] for i in self.sizes.values() if i[0] != 0)
def get_unused(self) -> list:
return [i for (i, v) in self.sizes.items() if v[0] == 0]
def unused_size(self) -> int:
return sum(self.get_size(i) for i in self.get_unused())
def _get_size(self, item: str) -> int:
path = os.path.join("/boot/extlinux", item)
du_output = subprocess.check_output(["du", "-b", "-c", path], text=True).strip()
last = du_output.split("\n")[-1]
size, label = last.split("\t")
assert label == "total", f"unexpected du output: {last}"
return int(size)
def print_use_by_cat(tracker: UseTracker, label: str) -> None:
items = getattr(tracker, label)
formatted_items = []
for item in items:
count, size = tracker.get_use_count(item), tracker.get_size(item)
formatted_items.append(f"\n {item}\n {count}x {size}")
print(f" {label}:{''.join(formatted_items)}")
def print_tracker_use(tracker: UseTracker) -> None:
print("in use:")
print_use_by_cat(tracker, "linux")
print_use_by_cat(tracker, "initrd")
print_use_by_cat(tracker, "fdtdir")
print("unused:")
for i in tracker.get_unused():
print(f" {i}\n {tracker.get_size(i)}")
print(f"used space: {tracker.used_size()}")
def delete_unused_from_disk(tracker: UseTracker) -> None:
for f in tracker.get_unused():
path = os.path.join("/boot/extlinux", f)
cmd = ["rm", "-r", "-f", path]
print(" ".join(cmd))
subprocess.check_output(cmd)
def parse_extlinux(contents: str) -> list:
items = []
active_entry = None
for line in contents.split("\n"):
if line.startswith("#") or line == "" or line.startswith("DEFAULT ") or line.startswith("MENU ") or line.startswith("TIMEOUT "):
items.append(ConfLine(line))
elif line.startswith("LABEL "):
items.append(ConfEntry(line[len("LABEL "):]))
elif line.startswith(" "):
items[-1].parse(line[2:])
else:
assert False, f"unknown directive {line!r}"
return items
def write_extlinux(contents: str) -> None:
with open(EXTLINUX_CONF, "r+") as new:
# backup file
with open("./extlinux.conf.back", "w") as back:
back.write(new.read())
new.seek(0)
new.write(new_extlinux)
new.truncate()
def dump_items(items: list) -> str:
return "\n".join(str(i) for i in items)
def prompt_continue() -> None:
if input("continue? [y/N] ").lower() != "y":
print("aborting")
sys.exit(0)
orig_extlinux = open(EXTLINUX_CONF, "r").read()
items = parse_extlinux(orig_extlinux)
tracker = UseTracker.from_items(items)
print_tracker_use(tracker)
print()
if tracker.get_unused():
print(f"recommended to delete unused items from disk to save {tracker.unused_size()}b")
prompt_continue()
else:
orig_tracker = tracker
rmcount = 0
while tracker.used_size() == orig_tracker.used_size():
item = items.pop()
rmcount += isinstance(item, ConfEntry)
tracker = UseTracker.from_items(items)
orig_size = orig_tracker.used_size()
new_size = tracker.used_size()
print(f"recommended to delete {rmcount} oldest entries to save {orig_size - new_size}b")
print_tracker_use(tracker)
prompt_continue()
print()
new_extlinux = dump_items(items)
print(f"new contents:\n{new_extlinux}")
prompt_continue()
write_extlinux(new_extlinux)
delete_unused_from_disk(tracker)

View File

@@ -8,4 +8,4 @@ sudo systemctl stop nginx
sudo systemctl stop postgresql
sudo systemctl stop duplicity.timer
sudo systemctl stop duplicity
sudo systemctl stop wg0veth wireguard-wg0
sudo systemctl stop wireguard-wg0

View File

@@ -2,15 +2,18 @@
# first arg should be the region, e.g. `us` or `ukr`
case $1 in
ukr)
iface=wg-quick-ovpnd-ukr;;
us)
iface=wg-quick-ovpnd-us;;
*)
echo "invalid vpn name '$1'"; exit 1;;
esac
vpns=$(systemctl list-unit-files | grep wg-quick-ovpnd- | cut -f 1 -d ' ' | sed s'/^wg-quick-ovpnd-\([a-zA-Z-]*\)\.service$/\1/g')
echo vpn: $(curl https://ipinfo.io/ip)
if ! [ $(echo "$vpns" | grep "^$1$") ]
then
echo "invalid vpn name '$1'"
echo "choices:"
echo "$vpns"
exit 1
fi
iface=wg-quick-ovpnd-$1.service
echo vpn: $(sane-ip-check)
sudo systemctl stop $iface
echo plain: $(curl https://ipinfo.io/ip)
echo plain: $(sane-ip-check)

View File

@@ -2,15 +2,18 @@
# first arg should be the region, e.g. `us` or `ukr`
case $1 in
ukr)
iface=wg-quick-ovpnd-ukr;;
us)
iface=wg-quick-ovpnd-us;;
*)
echo "invalid vpn name '$1'"; exit 1;;
esac
vpns=$(systemctl list-unit-files | grep wg-quick-ovpnd- | cut -f 1 -d ' ' | sed s'/^wg-quick-ovpnd-\([a-zA-Z-]*\)\.service$/\1/g')
echo plain: $(curl https://ipinfo.io/ip)
if ! [ $(echo "$vpns" | grep "^$1$") ]
then
echo "invalid vpn name '$1'"
echo "choices:"
echo "$vpns"
exit 1
fi
iface=wg-quick-ovpnd-$1.service
echo plain: $(sane-ip-check)
sudo systemctl start $iface
echo vpn: $(curl https://ipinfo.io/ip)
echo vpn: $(sane-ip-check)

View File

@@ -0,0 +1,37 @@
{ lib
, stdenv
, fetchFromGitHub
}:
stdenv.mkDerivation rec {
pname = "splatmoji";
version = "1.2.0";
src = fetchFromGitHub {
owner = "cspeterson";
repo = "splatmoji";
rev = "v${version}";
sha256 = "sha256-fsZ8FhLP3vAalRJWUEi/0fe0DlwAz5zZeRZqAuwgv/U=";
};
dontBuild = true;
# TODO: generate a wrapper so that bin/lib, bin/data aren't linked into the environment?
installPhase = ''
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
'';
meta = with lib; {
description = "Quickly look up and input emoji and/or emoticons/kaomoji on your GNU/Linux desktop via pop-up menu";
homepage = "https://github.com/cspeterson/splatmoji";
license = licenses.mit;
maintainers = with maintainers; [ colinsane ];
platforms = with platforms; linux;
};
}

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 ];
};
}

25
scripts/install-bluetooth Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/sh
# usage: install-bluetooth <source_dir> <dest_dir>
# source_dir contains plain-text files of any filename.
# for each file, this extracts the MAC and creates a symlink in dest_dir which
# points to the original file, using the MAC name as file path
#
# bluetooth connection structure is /var/lib/bluetooth/<HOST_MAC>/<DEVICE_MAX>/{attributes,info}
#
set -ex
src_dir="$1"
dest_dir="$2"
if [ "x$dest_dir" = "x" ]
then
# default to the first MAC address on the host
dest_dir="/var/lib/bluetooth/$(ls /var/lib/bluetooth)"
fi
for f in $(ls "$src_dir")
do
mac=$(sed -rn 's/# MAC=(.*)/\1/p' "$src_dir/$f")
mkdir -p "$dest_dir/$mac"
ln -sf "$src_dir/$f" "$dest_dir/$mac/info"
done

View File

@@ -1,5 +1,9 @@
mediawiki_pw: ENC[AES256_GCM,data:g7qM+CMU12apnGQ=,iv:q5K8sBAaUi47Hr0DAWiU1o5CVIO6zkdVVGJ5Zk4P9HA=,tag:CFpSmsflkNFG4kIBzrr5yQ==,type:str]
duplicity_passphrase: ENC[AES256_GCM,data:LgPORB0HhIAfpJdQrwjS+/TWdOeddQ2YNYqfRbWhhuNlImuOlniPzrPaaFv+Mfght7OHs7rnuVr3tOHfeIEBo9S2z05ABOulttHEyeuyJZPE1/0t8IBz2gcNNWs4nhCYbVX3y/rSAG8bhz1Vdb2B/MiCicfJEZAqpXkRilQELXTR5cF5NnmEcR7zOso=,iv:NvwZhBbkYnTDt3izwwQPj4U4XAmiOD5Dv3sF50JA97o=,tag:HSJ5xr/WXn6MQdyV8QYWYw==,type:str]
#ENC[AES256_GCM,data:5uf2kYCg8ZqoOLv50QNI73MYV0HDl4ML2xEKHPOEvCf/Z3aeM6ED,iv:ljqw6IBTPDodejMO2dcjLYyv+LlS/7r9nQ7RyiKC2Dg=,tag:Jko9tIhER4ByDbv5qhsfaQ==,type:comment]
ddns_he: ENC[AES256_GCM,data:zAKbEAIMIsENUctG9bNAAjAty6g+w3QW5VM=,iv:ncIjblXnTiU3TQcHJutz9lCl0wBdWs+FybY0sZcnaH0=,tag:7O6EIob2/if1fcVDVEkVzQ==,type:str]
#ENC[AES256_GCM,data:s9NlxWPP5H3OV0PNEWz81XuPX3EXCz7GWcoJcicXpMatLM8d7MvvUJzTWCX29KIcpfXnN/ASjhML+SnAN4l+JLm2ltTJbcIVnpcWvcQ=,iv:9q73OtDm2o0YwpOYB5x5NH1Wr+QQN4lmbgJkCY/UW2c=,tag:qO6UvqGQCCl04pr2nNFauw==,type:comment]
ddns_afraid: ENC[AES256_GCM,data:fTjwU7DoPDXulmjUNXSe5FVLGv4DvPvIHYCLwagVmKXlWOc39Rsco2YGf/kcoAk5oXqUdtdwuA==,iv:x0QwZb2xne8w7BaOXq4Srh5YbFldwLFsgdfK7WE2LGI=,tag:s8QyDBma/ljcSzAY4V1vkA==,type:str]
#ENC[AES256_GCM,data:LMfqz2Rih6CR7RcCbA==,iv:MQ7z93Mhus2Z2q7HZMk4BzkkY/apBIR+9hIiZlknolc=,tag:HU5McecdYk12I3AcvVHEBw==,type:comment]
#ENC[AES256_GCM,data:zhL2iNWZ8xPbBneffWcc93ZCW/SDv5FH,iv:P3a8+oucJRM8o7hnHUxAvefHdZEAbKJKhK2Y1+r75GA=,tag:VFvFucE5c780RmspW7p8Qg==,type:comment]
#ENC[AES256_GCM,data:N0wn6NUjQKXFbSULhrKzqDc4bHVbM3JLWJwOu5Zoi00gCKSiMA==,iv:9NhoT+OM+bjz4DwRRm2c4rTBZ3Jr6eMOY7F1l4WeE1k=,tag:inkd6kw8HvT5Tz3UAbIklw==,type:comment]
@@ -56,8 +60,8 @@ sops:
cWplOHBNWjlJdGI3ZWtJc0t4Mk9URG8KE+9IPGYZsIs2PaDJ2AUE4gB4QEj5zo6P
aZVbubu6Tbg+tD/98RkfWAkNvoVeDYuLNPDNgqOL0UgCQiTrPPaTjw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-11-16T03:02:50Z"
mac: ENC[AES256_GCM,data:0/lDp6jWueeF4TPfB5rSoEzEF8QVw815DYEHRRea+SrYXGHJT80eK5sqUz00m6adG8aaSlNMAD8d2/nClar6VJKKOHdY+oN8hLztxNGQraMo107d8XOMMycj9vA4IGkCbnlng0cZTB2jsPV6Mfkmf5v+PN4N9F0bQ9W50V1Pf40=,iv:slFJjjlyCyk8aAwfRbiZ/2SKLmUGZE4OvpfrrvSJw3g=,tag:X+057fZLJnDW7CAka8+pCw==,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,5 +1,16 @@
#ENC[AES256_GCM,data:3Swm4ixzL+sg9UVl0VWUq5HmXoLFFY2tkfCLeACB,iv:brZxrQmInGekhv+sX72Ne2ow1katiT4upDBuTPStLuA=,tag:ORcRds8Fo86S5DkAHeeGKw==,type:comment]
#ENC[AES256_GCM,data:LA3vDETFSVN8HZ9dieFHAvV3oP4lmG2Hpiz50MF6NHpSf7mCLbgikTv7UFohKM3vLpU=,iv:rby8r8+ELAV5ZSxALxbRTeXn0u+gv8b5wlxLwbwHt2o=,tag:50csomwWpHmSvLEGiPBAdA==,type:comment]
#ENC[AES256_GCM,data:03yoGnxvrxifgY2sPWVo4AoqJzOfmDw4dGG+/gfbdhnymsYK7MC8Dr9g6sAdXk2r22rtPh97Wz+lkKekAxB8EX6/XIQMvUSFoAOFOKjOyC43hl0=,iv:9QKJNnZT9joQJ0klbluaVc3V3KcgqfJgrX+yn0/VgkM=,tag:TKNubbb0yGFyAbXenUvtbg==,type:comment]
#ENC[AES256_GCM,data:UfEMJoxSCGajodTRERNT9UWHIw==,iv:dG/UI4AW8ZwmI0fr8dAOWRkSyrNwX1GOI1MCYcIVBy8=,tag:rONazGrpRolwttbTEX3Y1A==,type:comment]
#ENC[AES256_GCM,data:NQA7bJoU,iv:nufPTe+1v70yQhznqJ/rf9C4p8oFYZDTDMsR0yrLp7U=,tag:MAG3g70Rxu9QEQilC/Ij1w==,type:comment]
#ENC[AES256_GCM,data:IK/8v+Y=,iv:hhqaIkH13dFmTUPjkS5OEvR93ymDj9zKsOBlMNOgiq4=,tag:sCR4a5pJBhQIFTZnI8awzw==,type:comment]
#ENC[AES256_GCM,data:O1Unbl8lDfY8,iv:u7V1SQQ7Z0D6D077yJdVjg7mMqAc1RLnj3YjLTD62b0=,tag:VNQDVP3YTur674N0tQzFRw==,type:comment]
wg_ovpnd_us_privkey: ENC[AES256_GCM,data:5YkQ4r7HNWiRr/5pa1XfexxtJAz6kDjX+hNiZcheUWCXVIuK0/AuyzcdQ/0=,iv:vr1UHSlsWFnTwEfZj3pBLxvaibQxhSum3SL0Uaqtceo=,tag:dN2U+TkQAgJejgDDYIWdOA==,type:str]
wg_ovpnd_us-atl_privkey: ENC[AES256_GCM,data:NMguzx35VvOAo37U9pGD5bYa/ghWeSK5tVh2XRNsfKjMPhMa44lm3pTscdU=,iv:f9hBhMksL0VGT8k2RsztU9AjR2AIIL+Z2Ls24UOPeNA=,tag:C46xDGb2d32mmHWl7WQb2g==,type:str]
wg_ovpnd_us-mi_privkey: ENC[AES256_GCM,data:uEC3UOOqn1l7KwGmOxKvXccPR9Gu8/BNTlpXxXlNWf19/pIX1CLPORUWme0=,iv:cnPGghGBAsIsR86F1hPZawLWlY/pLCNF/1cg6gjrIKE=,tag:LqMbpGklQH0GX7dNNV3/8Q==,type:str]
wg_ovpnd_ukr_privkey: ENC[AES256_GCM,data:5zfhsZnBk0Kb9Nb/3igsV/fN0ZDjwTAGTKyMLMly/l7MlJe6MEmd5Lv+JT8=,iv:Mov9eUP8WfvzfZ6NljgLolJ49GSqR7eSV+k0dgE1+1I=,tag:O9UtGX2qt+qEvabcsA0vIA==,type:str]
#ENC[AES256_GCM,data:qlF8rpSMUv6Z/YrOTp7WYs0lcpmSIi/r+gCuiw==,iv:cneNp/0av/ttQvnW4JVX9mj3261QFAzkLIzEMwiKwE8=,tag:FFsPUQBsSeImtymawY4eSg==,type:comment]
router_passwd: ENC[AES256_GCM,data:Tya3Pd75Yu4=,iv:lqi7SavFnymL+uOQXDEzGxgikB6/ckNOBifjhyjXn1Q=,tag:HG3kf6e2g53uNUGI9FXyqQ==,type:str]
sops:
kms: []
gcp_kms: []
@@ -78,8 +89,8 @@ sops:
YmhsY0FaSW5oWVNJMlhUSDRCeWQ4KzAKaQp321XYtAZ98f4QMl5PxivAYm6VMF43
wCThiQgvYAP59jvVDTZngvfWAD5PyWVVvMNbjHGvAzK5WnsTPmxlsg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-09T07:48:24Z"
mac: ENC[AES256_GCM,data:j5Rvh2EcWyi42lWhiKF5/t6isowgPZPqwHQIW+H6T7eb1YCRUusqnK69KSIBUvk/19ZXQXxcYqFSxilAEiuinKglXqmK5Tq2hSF+vJjqW9cunuPgeQl58GeA9PyjxrRo+HNjsXqGND9/fcZf+cqvZEQnhQdPE7mCzZaJ3kAXMKY=,iv:BsDIVtzO8nSStlKYYoFktZs2sRwVk5EgQ3GBkCk+1UE=,tag:pxQyFn6Y8bbDF9hQMJqTvA==,type:str]
lastmodified: "2022-12-19T05:49:20Z"
mac: ENC[AES256_GCM,data:sFi/oip78pnd7hKK3L8ExBPt0/QYh1Vl68uLIOKiKBoKpk/mPGBgHAP5jGCWiSG+X6GCe5DpztremmkJhuCyMVcurS/ynZKpXpMuomy2QxLHQnvXXwF4MrqPBGheITczY07J6mJJ3tGI65+NdzCyjb9kE+YfWWMkUHv4PDUT9Mk=,iv:qjxFrkLYcbtox0maq4MyA+VLeTyQxcno5lc6fXnyPiU=,tag:6nqEZPfnllQ4N+Q6Gs6lFA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

View File

@@ -0,0 +1,48 @@
{
"data": "ENC[AES256_GCM,data:+AGpYL+H20r13Ynl0r1w2wmk9t1vI8gxuedfXeWSrt/aa6isCiWC23+NpqZxfzHk8BihTdQ2MAi75tUSaE0QHlaMI15igtEOTjKo6KU1XkdUn1Lz79Z4jE11Ug6+IgwOXIdXEaoqot9KPUBy+/jBsZ4GaFJSHtAvnRiJZFTvVZDOHeJFknkhaFOl6fAPvf4QSX4Fg9FLSGONsShjPXX34HHiXoeyQmLUXnmc/eFhDX2BQDe+fs3AmLR0UT7H4zRmOzToChiSuXSHZIpc24c20orEpqANRRe6ghPW+26VJvVxSbAmd7aMZfTGgEUZ1hchEJkaHHyeU22Ao5MKuMniHFay4u3liYCHZAufym0VB8tpeCpLT8CxS9/rhsJaH4AcvERCjCSR1uoWq/8lbzdmcg0X9yTIbcVOMLkvn2CjqvuOHkKZqw9WKm+jh5DdmvVHGyfq8PQpOjox4vMTm6p4Dzi36sburCMW3eZNkVf+A0oXL+R1bRWERJTnEQ==,iv:bbYhaZibN8YjcrLHKk/p67p9dsAH2NPDMvNrMxp6EXs=,tag:Srcq9V+niuMC04bdGIxT1g==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhRW1DZmVTVCs0Ym9vLytG\nUm1DWGZHaUhsZkNSTW9RWURDWmxhRFY4QkRZCkMvbExwWGplTFFnQUdDdG5RdFhY\nYWNEM1cxR0hIQS90dS9nVE1rMmhSdDAKLS0tIDFjcEVTZ3pQc2pwVU5yeEJDQjFl\nUmFLZGlQN29saTlramcxejFaWDcyamsKX3GnzkjF3Yqc3T2g0sw+8d0MHUCUDaGg\nG/HBpGBS2ESTH+jAVxv5PFbnS5VFpf4nlPxhUzdE3j7KTikvmAJoAA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6eWhOc0xNTDY4YUdyYmcv\nQWQ4WEFFcVpmZEhNbGthRVlVcVM1RzQraFZvCmN5L00zTTV2MXFTcWxaWC8ydytu\nQ0NTbDVsRXBaWTVMSzI2VTFCWGFxZFUKLS0tIFoxSTUvREVreEo5dmdmYmExSDB1\nckp5ZnUrOGZxSjB0SHFMaTB2VFFEUVEKqn/1aXfZ/WHtDDVOmGjOT/PUas+5eZ/S\n+QY0qc6mjeJ8yn8ULOmm9M1E4zk5dJGiOIHzJ/rSFZDO0ayR0tcbwg==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiay9zZ3lCYk9oOVk1bzVi\naEhCeU9WOHFMdE5xb0RxeEhoTEpPT3B4em5RClhrWjN3YXRsd1E4WTVVc2RPMzJ1\nai94Y0RsUUxOSTlCTSs0SXdTL3ROVGMKLS0tIHBIcXFGc2h4WmtPZGxNM1hQamFt\nM1I3U1cySWtGK29BS0lXZ3paRXhVVFUKf/blwoKGYVgb1YbvDU8/gZbcQJaArKTw\n6oFb7R4bVAkmTtTuSEjRylGomu4tde562zuT3IiZ/ReNnNdcQOSi2g==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1zsrsvd7j6l62fjxpfd2qnhqlk8wk4p8r0dtxpe4sdgnh2474095qdu7xj9",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSaVpFTHVlTjJYdEJVVVp0\ndTZobFc2dlorTUx5STd4c3k3K2VzTTVSMlVjCnBtaDdaMjAzOUQ1ejlUMGFmQjJO\nM1hPSXJMa0NmYmgza0lYeWRkaHc1VWMKLS0tIFZJTTM1TFRSZU5GejlRSTQxMlVW\nMXJ3VTNzUjJET1dpaEg5emk0T0xrbEUKBBYPgzSCKXU9jMD9Sc5YRNqBxoxN340R\njf4sBD2LWTofriB1E+ltrd82o0Gz3+JH21/+0cEI0MTD8H5o1r6Sqg==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMOVR3S1pDZzlmZVJibENs\nU0k0M1NEQWRacW1oOXY3eVREWE5LVkNaN0NVCk9DNE5CVnpvcGFGSWxZOUFCQ1hn\nS1BQdXBVWm9ta1pMWFZlMm43Zm44WGMKLS0tIDViYmdYWENhc3Y1eDdXYXFDWUR1\na1dBQWtHRTJRTjFySytzSHliaGJ0MlEKKN+Nrqi2NHhV9debUfIIbgYo0eClSUkY\nb24VJc1vj9WBHu6xP0fOfhDaue5oOk0g+7w1RQE7yI5lYBR7DQyxJA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6U1B4aHRyem9INTIzU3py\nby9OS1AxYkRlbVlHSTFCVVdRU21INGdVclY4CllvQVZWTVVPajUrSDBFaFdPaGFR\naVhRU0xpNExreVFQZUNzVUlyTzdTbU0KLS0tICtCVVBCWndGNTQvSm1naGY2OVZ4\nY3BDMzZuek5XeXIySEI3MEF2eHhNOUkKPVFHVOVyatt141Nb4EMXR7KdrVIIoDNI\njb86cX3Nq4CyrajmnXKJmBbNoSMHdiehUEaFoimMccnTmQhhxtXKVw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtbFNpQy9XWTlJTThOUmFD\nMWYyNEs5ZkVESkp3TFVPOXpIRUJrYTkzRXlvCndzZ1JsOXphZkRSY1BPd3NWdjFB\nY1dzQ3FZVi9rM21QNE9wRnVKdzB0a1EKLS0tIEsycmRiYTJGRFVUNTVoU1N5c0RZ\nTDlKclFZQVkrYXVaWEJtenRXcW5hOEEKFhbLhR2HH5j8iId1PEt2Qr4uLIcSSoiP\nmka7YtK2fe1W9012xKUqKtqZvjtbuFrHb/L7p+UfvCxBXy2c+bXG8w==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age18vq5ktwgeaysucvw9t67drqmg5zd5c5k3le34yqxckkfj7wqdqgsd4ejmt",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDQW52MVVRell4eWVnMzZt\nenFqbnVtVGpGRlpVR0NnNkVvUk9Ed25qTXpZCjhlaTFzZXlUZHRsS3dHWDNUMUVI\nOVlmbkdiZnN2RnhVY3F2OWRqQUJBQzgKLS0tIHRJMHJ2d3RJV0JUVUdJTmMxYk1U\nTjQrUkZuQ0xVbWQxZm8xMm5RYzB1WGsKovG+0ueoZS0CQbTsC44upsX1tAXBtxn/\nxgdkUe7EiDX5QLq+AldVc0UzvEY5/ROBBf4d2LzSqp3jJPtEJbYc9Q==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2022-12-04T10:55:44Z",
"mac": "ENC[AES256_GCM,data:AIFVCniHkBJex0u6LTKj6CmxH92qc7JlRIGFWDGIFqG0LhvHbHdtRq3asT6N557ZiCbZCt+tCe+bcEDTsZrYqzE2BIdTa3qtW5ofmfaB9UXt1qcNAKRAy4LWYAwAGLRjXtgbnRINgaD/NCmOVf/+g7/VkigYXkWHLBLVRAmS1Io=,iv:eVQYqQrDPPyvsOYDRzcZUWqh11KuAcR4+ZPaNGup0LU=,tag:Cje0SL8sxlTbu3BaBc0ogg==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.7.3"
}
}

View File

@@ -0,0 +1,48 @@
{
"data": "ENC[AES256_GCM,data:IGm1odrTgOg5GAJFpyWgVbQMC5FEDukW1k8kgWgIEnBPvCsamDyFC07EZD2uMuP0KEs7VLxhE2c+mJN9BdnFd8TJocy2JtHoizzvv6leTxO4YRx8rHBXutGI9FdUeeI/Sv+1V9hiLfVCxQPnvyBpvThfddKSfg7vjdgkEHMixnipCrUQZaRyCW2lByEoAe0WzzpmLtdJ0HBiyZQ6PKzQ+05gA7dwqOaK4ZYLh39cEzAqGVYxzPastxAqxXOIt+4pL5THwnwdfhqfb/buntj4VpA+avePRexMVbY/JmJx+hQpdvZKx17PFVzhlqCZJefsgglObDRrSyTsGkmkkdTch6SPtnymLlI97FYat+V3wFUGo2uwkZVSfSEuXjpwnM0y3hx9C2OlkR1sYCM8cLVQkAqR13x87Uvdq3O4qo48IOM6Zu1lBwL9AblxgCHHfK7DzomcF41VF/pI0yZltEwATOiqvr2ir41uFKLxZ+fw/O3oOjv/jEap/7UFTgx4ShFAAP6vCs54iAGmgh/7b+YnA3ec59bzpXzFC9lZZt1RJyoXnAl+ADev53Q=,iv:ZfxmfvSqWj0IbNJeRGayapUYEznXMD7hhmBhzNPwMuA=,tag:YsjgEJ5p2GXqnzQeGaRX1Q==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrVGl5WEhVWEtGMjNZSUMx\nMStIUGpaQ2ttdmxjNUtyS1J0bVViY1k3Snk0CkhZMmhMQVQrM0lQL05hcFlTOTdv\ncFU2N01VNmlwWS9Tczd1aVlkUUpRem8KLS0tIDNXQ0xLVmUwYW5Edy8rSW9CaWhW\ndUVYRFdGMjVwV2w0My9PT0NHS1JtakEK/KjEcC0Ubci8hInUqc2G6uFs2hd9TN76\nPgMDTi8Mt1dM1cGNj7uiPeTo8/ft26yuAtikybpLGMdayuEXp6aTPA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCTkNzYVowcGxwek4rdUow\nc3VYbndpSWVscVdmaXB2VFdVS3JpYWdPbGprCmtiQUJzSStjeTVpdGRodDRjcVlQ\nb2NFczZjUzNxSVd3Y0puYUV5WnM1V28KLS0tIC9HdlgxUVBFZ2hPdlBVcVRha05v\nb05hbmRqV29scGE5bjltVVNHZ2V5UU0KfKu9wvY0EfTxUB8Qiy7jc4eI5zoUBtIT\nDUdb6MO7OUHJxtq5YzVJcPui5krR4ehJI7vB5IRWXxT/Yx+BjUd2qw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzUEZmNHBmTlUrSVNON0Vx\nU0kwRTNyQTY0UTdjaDVwUjZFSzdPaWgyL2trCkJCZU1MdFlhSndHNjZZb3VBdE9V\na3Iza3FyTUhEcTB3azBURXJKS3dkakkKLS0tIFNMNkZtWXNralFRM1FKVlZuL09p\ncHJGeUJxSXFSMDA4MU1lNU9jWWl4OXcKK71tw9/Xg9uCANFgDQ+kC9sgVP5UEa9S\nqaWPn+VGCMMiGb3TAb9BoRonfmj9eI+NxA/er5jpyT5g2GxKymTN9w==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1zsrsvd7j6l62fjxpfd2qnhqlk8wk4p8r0dtxpe4sdgnh2474095qdu7xj9",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwUThqL2k0ZW9maHMzSVhm\nbFBBUEl1Vzh0ZW52S1ZxM1BBTG1ZdUxFQ0ZzClV6aE4zTzlkbW4vMjczMHBJNjRS\nUEs2a21xMndxK1FDMDZqN2xUTHFka0EKLS0tIG5paTZCUmJnN2Z2Y3JncWxPWTli\nSmd3dHZzT3l4MDBIeS9FMC9Bc1F2c0EK4jplLargqOCN5eSpsAqU7zmdEvZzN6Bd\nTLgiuOPwFeQwCJ28lPFXNtPYFQzXhoASatd4Sn/MOKWCQJeVJOhDog==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSb1hNd1k2ZUM3U1REVTlo\ndkhLUG81WGFxQlRVd2cvUU9WVmNSb09Ub1RFCmhINEdhT1I2WS9rUE9CNlppbDRa\nVlgwNzB6RmIra2NRUjU0Ni9abVNSd1kKLS0tIG5pbityUFc2RVJGQTlTend1YTV0\nbStYSWIxSjdGYU0rMHQrTHFkSGNjd2sKBymQa50r5Uo727VI+nM+qc3YAGzM+ZDI\nU6T+MA8L5noCb/ZzKYZFAEN8z8a/xHT7nRiqp8NWQ8OJ0KJDzQvE3w==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxSHJtWVpWVE5mVmZ4RVV0\nS3J6MGhQY3NsYTk2S2FFbGJTQTBjaUlaNWc4CmZRamZmZ2l2OENKZWpOWU1IQXdo\nN29TSVM4dUJXbmZISkVyL0RCTFBrZ1UKLS0tIHY2SDBndG1PRVZqcGxJSjNXUWU5\nL3RyZ0JIblJPS0lmc1pDc2pGK2dTeHMKB1T/43hZDb4lP+seHsKt+aB1TdNyP6FZ\nOt8rezQZqeJ+GnHwV6qsdEtX1DE30niqe3upUS+igkHJ65RGd5TAuQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFOU9TWXlCRFh3Sk9aZkF3\nTDVUMWhzQkQ2OW1YbVlQSHUvdHBIWGx1R2tnCi9ubVJyV0lnUHYreDQwNFYxNTM0\nMEk0M1ZRQmliL0ZUVlZlYTM3aG01eXcKLS0tIDZxR3V1ZVpEWHRJajdCcU16NUZS\nNFpGanJxNlpKcm1VS1cxWHNieHVmbTgK0ggrvlCvK+j8F77b4gl1RsWGDfGiFmg/\ns0cMGtIflPT/0D43R/jczrJ/Xp1aBL0TeHyf9YxZu254QeZ5ZPa5kQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age18vq5ktwgeaysucvw9t67drqmg5zd5c5k3le34yqxckkfj7wqdqgsd4ejmt",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXTVg0YTFFL1owd1RNUEEx\nMWJOeGttbTI1elhZMTU1VXcwcWt4ZzdJSW5VCnlQRk5OakJJU0grczlHRnhJTWxI\nd21pTDdVTk1vc0dsdVpuWGNrVUpEVDAKLS0tIGNYQVNjellNajR3czlKc0ZYbWpL\nbkt6QnZ1MGRGL0hSS2F6aktXMzB3aVEKb/XnuAMiB6Zn2Hr+LUlPdCii5G7TKYgp\njE7Loh9mPY/WPK2KvCAPYFcjNCmu0JYzCYgpU/i+4Wm7ObsrXh+lGw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2022-12-04T11:32:25Z",
"mac": "ENC[AES256_GCM,data:UIyF5JSi+GZqch1cPgmgrdZ1ImicdrzVTwYudwKhHDvfXXHzFG+I+1MGRRim872XbImc2EJRBSe27vhyum8pDc7y8cQVepecfqkeEdD66IxEbwx9Wt5ZW9X4nPlj+vobSHjjyV+0Wpmy9pgsfLiQzT+9S8jE4H0FgZv89MNNmCA=,iv:s9V7SDMhttZ1iFk3xNTrnNgMGnn+5LW3G/ORI66QHqY=,tag:+O3YRbsMuz+M+pzrk8zhiQ==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.7.3"
}
}

View File

@@ -0,0 +1,48 @@
{
"data": "ENC[AES256_GCM,data:639/SycbUOC4kwBAJvk2sQCBfnXZrYDzucXFXysOW8DOPU7nZwsdWKmB+41zvLg3vS5GyPTzMco/EaytPbGj+HvRqyKEYCJvBY/ZOoPpAZKltqMkkIS449OFy3vuOS46TPLQ1c5AgsBnHuSFrGGcVXRs+yP1A4rRcn5Au3Z7hPujZA/W3lUR+/Cp4UYc2tk1w2kpWD/SXLqkSX2XTRNPXb1rOva6xxllUiFuG7Yt1a7KfjrkaF4GJK5TNWgGVrY1N7IKzC75Sh1x5wvumF7A1mwLE1I+sa55Sn9qtGsmWwfsDBN+9SRg7uCUipTCrAEAgJK07QdN5P0ZFrQlxqNGn0i5BvKSxn+GK+f7xJIHjb+sexQgNMFQ56V83Zej8U5HQ9vyrx7EHpE44UneUQQ8FkckQVWyhSGs3MVSkfbznb3L2WnOCEogb0xft56pXPOG/K4q7uLkOwUtgcq0Jlf+gZZmuXRoVnNQc//o0u296CF8AFnxA/MJJc67bkONITjlekB7f23NFoywhzyX4RYjjbflRkMF8BRu0RDuynGu0xLZLLlK8QM4uJfpPyH8L2ThiKRbYO7OGaKCYJy6fYx+ViUVsRf3hpHMiDn8yGHxrqABOTv6HSIZvIKo3G4Kn5iF/GPxWQISTZxE7YdYhgUf61UpZEfkgw==,iv:jqWb8k8f8jKscWPwcZy9o9QmOJKG38m9ukbeBDX3IN8=,tag:vZh6J2mtUhaoiwpn17l80g==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqTXp0RHN2bW9wUDdvWlJa\nNFhyMEJ0OUhSS2RvLyswejc3ZUx2SW1rdDFVCmtZVG9wZitidEZMaE1rdjZSZito\nclB1N2s2bU93S0IwK1UrYlk4NjU1UFUKLS0tIEdvcytSOElhRHlKY1FyRTlTYUlR\najdHeGh6d2FROUJab3d1cExkYlJLQUEKJQUv1/2YuAOEQGaaJ5itEtXrfwB18RcI\nC3V0MXuLqpQpVzsMz6tBU66+343gPTVMZXi/cLLKjpzARKUCPJ3ghA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNdmtuT0NaUEplbzQ0WWV2\nQUsrOFRYN0ZET2lwNkhMeTE3bTV6OUUzWW5jCmtsT3dNbXdlSFQyTmlNdndqT0V6\nSGFDM3BaY1plUVYrRkZRSXQ3eno4dWsKLS0tIGRBSzQzVVdCQ3Q2WGpwdTlsSHJO\nZGR5NjRrbW1lWW80NCtVUWtIUEhGcTAKSRPJHEUFWCCe4v2nLnaDY3FIeWvc75jd\nMb8+grC61jBRO3kpMLrHb5dn3/okLX33nZtJNnkCA8jDlR1tyCXUuA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvRWZFWkVWVWlpWjBWenE3\naHp2d1RVcmNrQVVYNkVuWHRUcGRBNTBFbmdNCk4zUGFFSm5lWXhzR05RelNvbnBX\neHhoZDZjZTJPWndQT0dJajh0K2xhWGsKLS0tIHIyeUVoQ0szZHpBQkdBc0hVbFVF\nU29JWFNPT2VtaEFTSTc0OEpsYVVRbWMKLq33uUYhelMgkz/zuI3wmYTPbn+fv4uB\nkwUX2KDOzunPkfznFJ0/uGDHBRgTj5kYKid53IPPAByCGrWemXbbBA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1zsrsvd7j6l62fjxpfd2qnhqlk8wk4p8r0dtxpe4sdgnh2474095qdu7xj9",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVNlFGNGZyZWdLQnRkSE1z\nTUgwOWFvL2ZQSWVOVTBBOHJOM0RSaHNFOWlBCmljOTdKQzB1UTU3ZFFENDJFRnps\nYi8xa0czTTNvTFFGc2QydWVmTmN2bEUKLS0tIFJQMkNQOUhDazlsRTlrRDR3TFJP\nLzl3UGRSakhITXdnYzEvMXdsZ3M2RjgKbXJw6e5aFsrL52zknH5vva3y7sLvqVTd\nsyOnStwaTwBWEMRAvG+vtEhgLIJDVCJGEYqKIBzzoOOujJ9ojuzOqw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRRmh3R05RNXhjclRHYnB6\ndmxIV1dPQTNud0htRFFHN3ZveUd3NSt1RENRCkRmQzJvNUxZQzc3enlvZjRGTE9x\nWmFxaGRrYzNTUm5WNUtkaHJzbmo1Q3cKLS0tIFVJdXliL0xnZHRnYVBwYkcrTnhx\nc1M2bzQvNmxHcEsyZmZNVUYycDh5QTQKyOSJlIwrwUaglkvdAw24NxxdZnmy88J5\nNWo04oEImdlMCEZQBQ3/o1xyftU8BNY+ovNy7Nym0darKM9f8ka1PA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiR3VhRUZybjJuVVFrNXVo\nMkJwNDgweFFmb3BIeEhSZ01RNWk0dEQ1bHlVCkI5Wm42d3haTms3bjlJdldpSGtW\nSGN5cnlkZmlpSm11VjBFeHI4blI0aUkKLS0tIHhESkdjbGFPZis4V0tQcUpXaVJ1\nTEpadHlVL3NUeUZudU15WldZWlpKNXMKVxsLBUb7BwJJ0lJRQk1ZppMID8bt/cbC\namvKeagoT6QDR42FyA6W2Rp8+tBrrkBD3CGRAcXMfUSPIzN9p6kcQg==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPSXRPbW9OeGFpYng5RXR4\nT3BUMDZmOTRoNlVsVlp3endKOEJCWno2TjFZClpYWklWbDU3OGoySFFJUkRjS2tw\nUFhtZ0puTkV2ckRPMUhLY01MVW1kR2MKLS0tIGJkdHhaNzQ3WG9JRXF6OTNMNnF5\nQ3FVU2FVVDJyYUNqaVlhSkEyZmd6RGcKMRxyVMpxCYxoWXK6zlAPyo3YcPJtTWIO\no2RUlS8oSTB05G7sGkjq3VSFRSgNnekvXOBE513Qmym/cDDbusxpAQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age18vq5ktwgeaysucvw9t67drqmg5zd5c5k3le34yqxckkfj7wqdqgsd4ejmt",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzYnMxbDNUR2xyV3B5VzFQ\nM1IxQzV5OXM5L1VYdFRYWUt0cWl4ZUdsQVNJCmRjUjdPMmhoaEFmUUxrVmJCRlFl\nNzZqY3p0YUF3T2lYdysvakx4WVg0bFUKLS0tIFFlazJzb3hmVXNyUU5leUFKL3p0\nNlN0TGxVbGtoUHFtK3hBS2RiYUViVFEKii4w04zeDD6HWURzmAhJdxNdNmQgsPw/\nawI6HSVbbmEGXyL23Pe0oultY8k/ZVE4oHRKBkHh00XoCZM/Ye6neA==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2022-12-03T10:23:14Z",
"mac": "ENC[AES256_GCM,data:KBm0rXwAGPa0ZkqGI9K3rW5B4vJ1FLmITa8xV5WR1SG2MlSqvCqSj4Qe5kxcIc3AqqHF2W+LDaJ0f1fXOCVqWRe1mi/LJyYgPERL5Hn3iOHty9g984Q/QSGvH13O7eY/Fuk2h0mpIX4pOhdpW74qlp1zYDXqUswsKW7ERTTRf6E=,iv:maE+9/OgdgYNX4F/MrzIpJr+/XXyFSayC1YX382oc2Y=,tag:NmrKXA9AjnoTXrQThnvxvg==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.7.3"
}
}