Compare commits

...

285 Commits

Author SHA1 Message Date
chn
d53c5493e1 port change from main 2023-11-15 19:29:14 +08:00
chn
8750ee1b8b 修正 addAuth 2023-11-15 19:24:03 +08:00
chn
1f529b55e1 nginx https support cgi 2023-11-12 23:35:08 +08:00
chn
888f438031 add fcgiwrap 2023-11-12 22:13:01 +08:00
chn
7aadd673cd 打包 mirism 2023-11-12 21:59:03 +08:00
chn
f227925d38 fix php user group 2023-11-12 20:47:29 +08:00
chn
90839e445d Merge branch 'ua' 2023-11-12 20:29:27 +08:00
chn
57d07fc326 add ua 2023-11-12 20:29:16 +08:00
chn
91228c3053 allow disable sddm autostart 2023-11-12 20:15:44 +08:00
chn
3e8237286d docker only persist volumes
rollRootfs chattr +C
2023-11-12 19:35:09 +08:00
chn
3f670636e8 huginn: do not create database 2023-11-12 19:28:07 +08:00
chn
8191eec21e mariadb uses password auth only 2023-11-12 19:15:29 +08:00
chn
fed092c67c mariadb: fix user creation 2023-11-12 17:59:49 +08:00
chn
44ee17f2ff init huginn 2023-11-12 16:56:58 +08:00
chn
a898902f9e fix frp tls config 2023-11-11 20:27:12 +08:00
chn
00dd5ae7ad update frp 2023-11-11 20:14:37 +08:00
chn
d274730437 pc: frp add stcp 2023-11-11 19:13:16 +08:00
chn
333ed600ef xray 使用 nginx 的设置 2023-11-11 01:33:46 +08:00
chn
05cd6dd1c8 enable proxyProtocol as default 2023-11-11 00:57:49 +08:00
chn
b1e2497054 allow send to be forwarded 2023-11-10 23:57:13 +08:00
chn
0e56ee4293 fix send websocket 2023-11-10 23:52:43 +08:00
chn
0294805326 add send 2023-11-10 23:37:16 +08:00
chn
218b6c6140 暂存 localPackages.send 2023-11-10 20:47:05 +08:00
chn
f908883f18 fix nextcloud config 2023-11-10 19:30:37 +08:00
chn
4d81aa8ca7 fix nginx listen 2023-11-10 19:16:55 +08:00
chn
98fafdd331 add two xray user 2023-11-10 18:24:43 +08:00
chn
2549be1e55 所有机器都可以编译通过 2023-11-10 12:39:55 +08:00
chn
3d261febd2 Merge branch 'main' into nginx 2023-11-09 23:04:41 +08:00
chn
12cdc43f17 可以编译通过 2023-11-09 23:04:28 +08:00
chn
fd799befd3 全部修改完成 2023-11-09 22:19:37 +08:00
chn
69cb43e6f5 整理 vaultwarden 2023-11-09 21:02:08 +08:00
chn
7122474023 整理 synapse 2023-11-09 20:52:15 +08:00
chn
ebc8f80476 整理 photoprism 2023-11-09 20:43:25 +08:00
chn
855d24c1ea 整理 nextcloud 2023-11-09 20:32:13 +08:00
chn
aa74e0911c 修正misskey 2023-11-09 12:41:25 +08:00
chn
ad4f316339 packages: add jabref 2023-11-09 12:02:39 +08:00
chn
f8c0295bd5 修正 element 2023-11-09 12:02:05 +08:00
chn
72801ad14c minor fixes 2023-11-09 00:51:45 +08:00
chn
c975bcba51 重写nginx模块 2023-11-08 23:44:19 +08:00
chn
967f7f155e acme可以直接设置组 2023-11-08 23:18:19 +08:00
chn
bc351ff0d4 fix nginx type check 2023-11-07 16:16:04 +08:00
chn
35c183f9dc fix freshrss 2023-11-07 15:14:06 +08:00
chn
90a3604ac7 vps7: enable freshrss 2023-11-07 13:48:38 +08:00
chn
dd1ac653a3 fix synapse-admin 2023-11-07 13:40:22 +08:00
chn
8a88c8f6a7 mariadb: backup using singleTransaction 2023-11-07 13:34:14 +08:00
chn
ad6e94ec09 vps6: add synapse-admin service 2023-11-07 13:27:47 +08:00
chn
6b384443e2 confix xray for xmupc1 2023-11-06 20:11:18 +08:00
chn
21080d7d61 fix frp 2023-11-06 19:47:00 +08:00
chn
8a3b3313f7 fix freshrss 2023-11-06 19:41:31 +08:00
chn
7b3a23d19f frp: add stcp support 2023-11-06 19:41:05 +08:00
chn
dea55cdc70 freshrss do not auto enable nginx 2023-11-06 18:49:20 +08:00
chn
1216a2c674 Merge branch 'vps7-freshrss' 2023-11-06 18:30:00 +08:00
chn
3de91db3fd add freshrss 2023-11-06 18:29:46 +08:00
chn
297fcee5df vps6: disable beesd, enable autoOptimiseStore 2023-11-06 13:48:29 +08:00
chn
95e42f969c localPackages.misskey: update 2023-11-06 09:21:10 +08:00
chn
2ae484fcc9 packages.zsh: try to workaround bug 2023-11-05 23:08:32 +08:00
chn
4d0cc3e30c pc: use single swap partition 2023-11-05 12:45:09 +08:00
chn
09a687f65a change disk 2023-11-04 21:08:30 +08:00
chn
8f7c6db841 packages.ssh: add nas ip 2023-11-04 16:47:51 +08:00
chn
d225de887d packages: add reptyr 2023-11-04 12:43:30 +08:00
chn
ed98f26185 mount everything with noatime 2023-11-02 16:41:49 +08:00
chn
f1173b45b4 remove nvme bug workaround 2023-11-02 16:25:53 +08:00
chn
0204420d4f remove bfq scheduler 2023-11-02 16:24:46 +08:00
chn
c991429151 try to fix nvme bug 2023-11-02 15:54:05 +08:00
chn
7c391d6666 localPackages: fix misskey 2023-11-02 15:50:33 +08:00
chn
6beec31dc1 remove yoga from default systems 2023-11-02 12:11:04 +08:00
chn
0e4d8368e9 fix iwlwifi after hibernate 2023-10-31 17:36:53 +08:00
chn
36f71df435 Merge branch 'next' 2023-10-30 19:53:15 +08:00
chn
7b73bdb9f3 prepare merge into main 2023-10-30 19:53:08 +08:00
chn
4e05896b4f services.noisetorch: init 2023-10-30 19:13:15 +08:00
chn
44d8553aef Revert "remove big-parallel from system-features"
This reverts commit dfe5f20346.
2023-10-30 12:07:09 +08:00
chn
dfe5f20346 remove big-parallel from system-features 2023-10-30 11:23:30 +08:00
chn
42162dc08c local.pkgs: update rsshub typora 2023-10-28 21:24:56 +08:00
chn
9ef9c4daa7 packages: allow zotero 2023-10-28 12:07:46 +08:00
chn
7afa093d25 packages: permit electron_24 2023-10-28 12:04:14 +08:00
chn
c26ea843eb yubikey TOTP use home-manager module 2023-10-27 22:42:57 +08:00
chn
2b73a6549e packages: remove firefoxpwa 2023-10-27 22:25:06 +08:00
chn
ad12157fe1 update everything 2023-10-27 22:24:44 +08:00
chn
f628e55fab nas: mount /nix/backup 2023-10-27 12:15:47 +08:00
chn
2444ff5d27 system.fileSystems: rollingRootFs use subvolume id as suffix 2023-10-27 00:01:58 +08:00
chn
97ec3061e7 localPackages: add latex-citation-style-language 2023-10-25 16:03:43 +08:00
chn
e2c61c6aaa add nixpkgs-unstable to registry 2023-10-25 14:01:30 +08:00
chn
550ef39dcf Revert "packages: texlive use ubstable"
This reverts commit b2ef263267.
2023-10-25 13:59:57 +08:00
chn
b2ef263267 packages: texlive use ubstable 2023-10-25 13:57:34 +08:00
chn
a686d8259b packages: add microsoft-edge 2023-10-24 11:17:59 +08:00
chn
057e5a5d51 pc: remove modprobe config about iwlwifi 2023-10-23 17:12:08 +08:00
chn
9e36962acb pc: use last kernle 2023-10-23 17:11:35 +08:00
chn
0941aaf2ee pc: remove nvme workaround 2023-10-23 17:10:43 +08:00
chn
3197b26b10 fstrim: exclude bind mounts 2023-10-23 10:36:19 +08:00
chn
ea4b2cbeb8 system.fstrim: set interval to hourly 2023-10-22 20:34:58 +08:00
chn
65bd74aa2d 写入 knownHosts 2023-10-22 13:28:15 +08:00
chn
00572e7b29 packages: add try 2023-10-22 12:15:35 +08:00
chn
5be30df0af add haskell patch to nixpkgs-unstable 2023-10-22 00:30:20 +08:00
chn
e4219ddefb packages: add fastfetch 2023-10-21 20:22:37 +08:00
chn
108cf36835 packages.chromium: add MetaMask 2023-10-21 19:56:29 +08:00
chn
5645c3d1bd vps6: fix xlog proxy 2023-10-21 15:35:14 +08:00
chn
4a56408a7a local.pkgs.misskey: update 2023-10-21 14:23:24 +08:00
chn
c8d6ed06a6 vps6: enable forward for xlog 2023-10-21 14:05:37 +08:00
chn
b6122fde21 packages: add electrum 2023-10-21 11:07:03 +08:00
chn
85ed0026cb packages.vscode: add todo-tree 2023-10-20 20:52:10 +08:00
chn
7ef8b41350 yoga: workaround bugs 2023-10-19 20:08:33 +08:00
chn
856ccc5281 typo 2023-10-19 19:58:44 +08:00
chn
fb924cd8e0 fix lenovo-yogabook module not found for kernel-lts 2023-10-18 21:45:28 +08:00
chn
66e602e750 pc: use lts kernel 2023-10-18 21:15:37 +08:00
chn
570b82015e system.gui: disable plasma-nm when gui is not preferred 2023-10-18 20:57:58 +08:00
chn
eaa5a7f7a3 try workaround nvme bug 2023-10-16 10:43:09 +08:00
chn
f38b2b3596 update misskey 2023-10-15 18:06:26 +08:00
chn
c1eb35b7d8 bug.nvme: use software iommu 2023-10-15 14:40:31 +08:00
chn
0b90b9831f packages: add ydict 2023-10-15 14:02:50 +08:00
chn
a56011bf6d fix biu 2023-10-14 23:19:32 +08:00
chn
4bb77b3351 update libbiu 2023-10-14 22:51:07 +08:00
chn
2982615a25 nas: fix swap 2023-10-14 21:29:00 +08:00
chn
279483923e Revert "services.misskey: temporarily disable redis"
This reverts commit 1334fe2b47.
2023-10-14 19:57:17 +08:00
chn
1334fe2b47 services.misskey: temporarily disable redis 2023-10-14 19:30:00 +08:00
chn
954dd962bc vps7.services.meilisearch: do not limit io 2023-10-14 17:49:18 +08:00
chn
62255316be services.misskey: do not limit runtime 2023-10-14 17:48:23 +08:00
chn
b2aa00afa6 add libbiu 2023-10-14 16:20:48 +08:00
chn
41d14eff54 add tgbot-cpp 2023-10-14 14:23:12 +08:00
chn
97e25871ae add localPackages overlay 2023-10-13 21:13:28 +08:00
chn
b59f68d3b1 systemd coredump write to rootfs 2023-10-11 22:24:08 +08:00
chn
dc4a836bbb sysreq use 438 2023-10-11 19:27:44 +08:00
chn
a6cddb2f7f fix cjktty 2023-10-09 12:11:14 +08:00
chn
f05d75d041 add yogabook kmod 2023-10-09 11:56:54 +08:00
chn
df76f20ff5 try to get halo keyboard working 2023-10-08 23:19:09 +08:00
chn
7133b45ffe try to fix touch keyboard 2023-10-08 19:27:16 +08:00
chn
4370b99ee6 fix touch keyboard 2023-10-08 19:09:45 +08:00
chn
bfd47d1dcf yoga: enable halo-keyboard 2023-10-08 19:04:39 +08:00
chn
9b89e61f20 yoga: disable smartd 2023-10-08 19:03:18 +08:00
chn
f1e4bfd9bc fix halo-keyboard service 2023-10-08 19:01:26 +08:00
chn
62aa651c15 add chromiumos-touch-keyboard 2023-10-08 17:00:27 +08:00
chn
5ffdec57c0 add propagatedBuildInputs 2023-10-08 13:34:38 +08:00
chn
e20527b4cd add glad 2023-10-08 13:33:32 +08:00
chn
be54e681c3 add yoga to default 2023-10-08 11:55:20 +08:00
chn
fe9c7b9363 system: adjust swappiness 2023-10-08 11:35:53 +08:00
chn
62c3c6ab29 add checks 2023-10-08 10:57:57 +08:00
chn
f97db074e6 services.misskey: fix postgresql.enable 2023-10-08 10:53:28 +08:00
chn
22ef0c27f5 local.pkgs.matplotplusplus: enable opengl 2023-10-07 22:11:22 +08:00
chn
f6a5022aca merge next 2023-10-07 20:41:14 +08:00
chn
53020f6373 allow deploy to yoga 2023-10-07 19:46:39 +08:00
chn
089fd25d8c nas: enable swap 2023-10-07 19:14:59 +08:00
chn
effb920c82 Merge branch 'main' into next 2023-10-07 11:41:19 +08:00
chn
a2c316a6f7 fix aagl build failed 2023-10-06 16:58:30 +08:00
chn
857625884d system: enable fstrim 2023-10-06 16:24:06 +08:00
chn
56a63df3c2 add pslist 2023-10-06 11:54:49 +08:00
chn
fee894fa0a anime-game use native package 2023-10-05 21:30:59 +08:00
chn
723e859079 update everything 2023-10-05 21:14:51 +08:00
chn
864b4c06eb fix 2023-10-05 19:21:12 +08:00
chn
9ec12f8bfc Merge branch 'nas-beesd' 2023-10-05 19:16:26 +08:00
chn
27515d37fe nas: enable beesd 2023-10-05 19:16:12 +08:00
chn
cbec6f8d8d add jupyterlab 2023-10-05 18:58:02 +08:00
chn
4a7c532b31 Merge branch 'vps7-beesd' 2023-10-05 16:47:15 +08:00
chn
50aba26cfc vps7: enable beesd 2023-10-05 16:46:59 +08:00
chn
d7a781ad1a Merge branch 'vps6-beesd' 2023-10-05 16:17:24 +08:00
chn
625c3264af services.nextcloud: disable update checker 2023-10-05 16:12:53 +08:00
chn
9f78a34e6a vps6: enable beesd 2023-10-05 15:55:39 +08:00
chn
b72c8a43fa vps7: prepare for beesd 2023-10-05 15:52:39 +08:00
chn
286fc162c9 vps6: prepare for beesd 2023-10-05 15:45:30 +08:00
chn
47126a7429 local.pkgs: update rsshub 2023-10-05 11:30:12 +08:00
chn
be3c0e5821 services.nextcloud: add app 2023-10-04 21:06:35 +08:00
chn
14f62cf255 Revert "services.nextcloud: enable appstore"
This reverts commit 60f3ccc506.
2023-10-04 20:45:05 +08:00
chn
60f3ccc506 services.nextcloud: enable appstore 2023-10-04 20:38:20 +08:00
chn
2bac21f4cf services.nextcloud: fix mail 2023-10-04 20:06:45 +08:00
chn
ea02adcf4d vps6: enable nextcloud 2023-10-04 19:51:48 +08:00
chn
7fb51ba080 fix nextcloud mail config 2023-10-04 16:19:57 +08:00
chn
6020e071c0 fix 2023-10-04 15:56:11 +08:00
chn
c83c90050a fix 2023-10-04 15:51:11 +08:00
chn
15d89d99ad fix 2023-10-04 15:46:55 +08:00
chn
4b5078a76c fix 2023-10-04 15:42:34 +08:00
chn
073aa595d3 vps7: enable nextcloud 2023-10-04 15:41:00 +08:00
chn
2b5349ae06 services.nextcloud: init 2023-10-04 15:40:28 +08:00
chn
3f62ee0dcd fix 2023-10-04 12:11:40 +08:00
chn
b9f5478c26 vps6: enable photoprism
vps7: enable photoprism
2023-10-04 12:09:01 +08:00
chn
11ee42d876 fix 2023-10-04 12:04:54 +08:00
chn
d7adea94eb services.mariadb: fix user password and permissions 2023-10-04 11:48:39 +08:00
chn
990a5cf0be services.photoprism: init 2023-10-04 11:15:23 +08:00
chn
2cbe5945b7 services.mariadb: init 2023-10-04 10:13:56 +08:00
chn
e06623ce79 move zsh history 2023-10-04 00:35:59 +08:00
chn
4eeae31498 vps6: enable element-web 2023-10-03 21:47:46 +08:00
chn
9c75d2ac8d fix 2023-10-03 20:41:09 +08:00
chn
f2b88fa5a3 services.nginx.http: rename from httpProxy, allow static site 2023-10-03 20:34:54 +08:00
chn
259a1cc6f9 move xxx-proxy to nginx 2023-10-03 20:11:43 +08:00
chn
e4d1320373 restore old misskey 2023-10-03 19:00:33 +08:00
chn
4f24bcce18 vps7: migrate misskey 2023-10-03 11:44:31 +08:00
chn
e3336b95f8 fix 2023-10-02 22:27:35 +08:00
chn
97952ec828 service.misskey: allow multiple instances 2023-10-02 21:38:06 +08:00
chn
66bcb54311 prepare beesd for nas 2023-10-02 16:21:18 +08:00
chn
a0ef3198c2 fix remote-decrypt 2023-10-02 14:20:21 +08:00
chn
68b94f7216 nas: add networking driver into initrd 2023-10-02 14:10:23 +08:00
chn
b533b80f31 nas: enable sshd in initrd 2023-10-02 13:55:40 +08:00
chn
a7315cd8b5 fix initrd.nas.chn.moe 2023-10-02 13:52:32 +08:00
chn
0a6a8fdd7b fix remote-decrypt 2023-10-02 13:49:26 +08:00
chn
d6d0a0e230 nas: enable remote decryption 2023-10-02 13:36:27 +08:00
chn
8d583b626f nas.snapper: disable 2023-10-02 11:41:04 +08:00
chn
14ef69b54a pc.services.snapper: enable
pc.services.beesd: adjust
2023-10-02 09:54:58 +08:00
chn
b69d4648b5 Revert "services.beesd: use 4 threads"
This reverts commit 70e6430750.
2023-10-02 00:28:47 +08:00
chn
2efb0afcfe system.kernel: update to 6.4.15 2023-10-01 23:41:31 +08:00
chn
70e6430750 services.beesd: use 4 threads 2023-10-01 23:35:50 +08:00
chn
3dc8a2d73a bugs: add nvme 2023-10-01 23:12:34 +08:00
chn
795d55baee services.beesd: use 8 threads 2023-10-01 22:46:56 +08:00
chn
705d279a94 system.fileSystems.rollingRootfs: fix 2023-10-01 22:46:11 +08:00
chn
d88610f3b7 services.beesd: more threads 2023-10-01 19:54:14 +08:00
chn
e832412f3b system.fileSystems.rollingRootFs: make old rootfs readonly 2023-10-01 19:15:32 +08:00
chn
78b27d3ae5 system.impermanence: kvm image save to nodatacow 2023-10-01 18:29:27 +08:00
chn
a694ada2ee Revert "pc.services.beesd: disable"
This reverts commit bacfb9ccf2.
2023-10-01 18:01:40 +08:00
chn
bacfb9ccf2 pc.services.beesd: disable
pc.services.snapper: enable
2023-10-01 17:49:09 +08:00
chn
fbe4c21e9a Revert "services.beesd: adjust thread count"
This reverts commit 4340106787.
2023-10-01 17:45:38 +08:00
chn
4340106787 services.beesd: adjust thread count 2023-10-01 17:33:21 +08:00
chn
f42e1df555 services.snapper: remove patch 2023-10-01 17:08:11 +08:00
chn
63664f4fc7 pc.services.beesd: larger hash table size
pc.snapper: disable
2023-10-01 17:04:04 +08:00
chn
33b96bd46f pc: enable beesd 2023-10-01 16:25:25 +08:00
chn
106112d16f local.pkgs.misskey: fix 2023-10-01 16:11:46 +08:00
chn
38b6378160 services.beesd: disable 2023-10-01 09:22:08 +08:00
chn
33f7702330 packages: fix octave gui 2023-09-30 15:50:11 +08:00
chn
556ac1994d local.pkgs.misskey: 2023.9.1 -> 2023.9.3 2023-09-30 10:59:38 +08:00
chn
99aa6ecbf7 Revert "local.pkgs.misskey: use symlink for pnpm store"
This reverts commit fde802ebfc.
2023-09-30 10:54:41 +08:00
chn
fde802ebfc local.pkgs.misskey: use symlink for pnpm store 2023-09-30 10:51:37 +08:00
chn
1118e86d62 services.beesd: do not deduplicate snapshots 2023-09-30 10:45:57 +08:00
chn
ca59f06646 services.beesd: disable for boot 2023-09-29 18:33:35 +08:00
chn
9eec3611d4 services.beesd: set hashTableSizeMB 2023-09-29 10:52:14 +08:00
chn
3f54c4256c services.beesd: use only one thread 2023-09-29 09:38:44 +08:00
chn
91d7ab5b8f services.beesd: lower io priority 2023-09-29 01:02:39 +08:00
chn
dcf7f8ace0 system.nix: disable auto-optimise-store 2023-09-29 00:33:31 +08:00
chn
b7d524671a enable beesd for all machines 2023-09-29 00:32:48 +08:00
chn
f9a5581410 add beesd 2023-09-28 23:44:04 +08:00
chn
8c70c96d8e add nameof 2023-09-28 11:17:50 +08:00
chn
1957d68247 add eigen 2023-09-28 10:06:06 +08:00
chn
ceb91a8ed8 add btrfs-assistant 2023-09-28 00:41:49 +08:00
chn
093b27a225 system.networking.nebula: try to fix nebula at boot 2023-09-26 17:49:36 +08:00
chn
79cad7f58a users.yxy: add yxy_id_rsa.pub 2023-09-26 17:47:49 +08:00
chn
84ad6e3ae4 packages: prebuild unstablePackages.gcc13Stdenv 2023-09-26 13:52:38 +08:00
chn
6318b938c2 concurrencpp: fix cmake 2023-09-26 12:40:32 +08:00
chn
e21c7a916a add zpp-bits 2023-09-25 21:26:20 +08:00
chn
bdd8e82b4c services.misskey: fix version and add passthru 2023-09-25 16:33:18 +08:00
chn
e967a2511f services: misskey: update 2023-09-25 16:31:22 +08:00
chn
b509fd7a51 ssh: fix hpc ls color 2023-09-25 15:46:18 +08:00
chn
0259ee11ec services: misskey: fix build 2023-09-24 23:23:35 +08:00
chn
473c4f4d17 services: misskey: update 2023-09-24 21:42:40 +08:00
chn
469b765f99 meilisearch: add io limit 2023-09-24 20:47:46 +08:00
chn
ad7be5bc2b matplotplusplus: fix build 2023-09-23 18:44:19 +08:00
chn
fefd22a7eb matplotplusplus: fix build 2023-09-23 18:20:59 +08:00
chn
e4076219e1 add matplotplusplus 2023-09-23 17:33:17 +08:00
chn
8dc5b34cc1 packages: fix p10k instant prompt 2023-09-22 16:48:26 +08:00
chn
4f39c1a1f3 virtualisation: kvmHost: parallel shutdown 2023-09-21 15:46:58 +08:00
chn
cf6e8dff66 packages: update rsshub 2023-09-21 15:33:44 +08:00
chn
cb9665bbb6 Merge branch 'next' 2023-09-21 15:31:19 +08:00
chn
a419838515 ready to merge into main 2023-09-21 15:28:19 +08:00
chn
164c5737d2 packages: zsh: p10k instant prompt set to quiet 2023-09-21 14:06:05 +08:00
chn
91ba3d8ec2 openexr: fix build 2023-09-21 14:03:06 +08:00
chn
9fd8c2d7c6 system: impermanence: clear /home/chn/.cache 2023-09-21 00:10:52 +08:00
chn
11efee5bb3 packages: phonopy: update 2023-09-20 21:36:57 +08:00
chn
677e8111bf flake: default package do not build yoga 2023-09-20 16:52:45 +08:00
chn
d48beec819 system: networking: nebula: always restart 2023-09-20 16:51:46 +08:00
chn
6bf6eabaa3 meilisearch: allow to use 16G memory 2023-09-20 09:18:45 +08:00
chn
273fcbb7c5 packages: enable p10k instant prompt 2023-09-19 21:36:30 +08:00
chn
22aadba0da packages: add eigengdb 2023-09-19 19:47:42 +08:00
chn
5555396f5d vscode: add native debugger 2023-09-19 19:05:40 +08:00
chn
d935330515 lock: downgrade nix-vscode-extensions 2023-09-19 18:51:36 +08:00
chn
a215b50761 vscode: use stable version 2023-09-19 18:44:03 +08:00
chn
52fd57469e packages: update vscode 2023-09-19 18:36:49 +08:00
chn
b003a1be43 packages: add gdb 2023-09-19 16:52:49 +08:00
chn
4bd0b01d9b nixpkgs: currently do not use ccache 2023-09-19 14:29:33 +08:00
chn
c3901eeeb8 packages: add hdfview 2023-09-19 13:15:58 +08:00
chn
77c4a604e9 nixpkgs: enable ccache 2023-09-19 12:33:08 +08:00
chn
7c361dab09 chromium: enable ccache 2023-09-19 12:31:05 +08:00
chn
b9efd5eb70 update everything 2023-09-19 00:41:46 +08:00
chn
1a2d11cef8 nix-store: fix 2023-09-18 23:45:11 +08:00
chn
bfec0e24a0 nginx: externalIp allow multiple ips 2023-09-18 23:33:40 +08:00
chn
de9945635b pc: enable nginx transparent proxy 2023-09-18 23:29:41 +08:00
chn
915fcc348d vps7: enable fontconfig 2023-09-18 21:30:02 +08:00
chn
91475e40d3 security: disable u2f auth for backup key 2023-09-18 20:59:50 +08:00
chn
565b7dd6bc sshd: use key without fido2 pin 2023-09-18 20:46:49 +08:00
chn
5a2b46898d sshd: remove ca key support 2023-09-18 20:25:17 +08:00
chn
3850b9bc05 删除 docker huginn linger
太难搞了,一年之内不再搞
2023-09-18 20:02:33 +08:00
chn
fb8c3cf89d add docker 2023-09-18 19:21:04 +08:00
chn
df5be06957 users: enable linger 2023-09-18 19:08:04 +08:00
chn
894607b933 users: root: enable autoSubUidGidRange 2023-09-18 14:03:17 +08:00
chn
aec4d38497 清理,放弃使用 rootless docker 2023-09-18 14:02:05 +08:00
chn
2312a8398c temp 2023-09-18 06:47:49 +08:00
chn
2e4a542c06 system: set home-manager state version 2023-09-18 05:45:56 +08:00
chn
69c7177b73 users: minor fix 2023-09-18 05:40:04 +08:00
chn
981643af44 users: add linger option 2023-09-18 05:35:56 +08:00
chn
5f88cd5cf5 users: manually import sharedModules 2023-09-18 05:28:02 +08:00
chn
a519053c2a 整理 users 2023-09-18 05:16:38 +08:00
chn
34c0ee6ced add wine-staging 2023-09-17 18:50:42 +08:00
chn
bdc7945e71 Revert "暂存"
This reverts commit beffb2bb95.
2023-09-17 12:48:11 +08:00
96 changed files with 3552 additions and 2013 deletions

151
flake.lock generated
View File

@@ -8,11 +8,11 @@
]
},
"locked": {
"lastModified": 1693886279,
"narHash": "sha256-oVCA5yz6zcsFzGCCwRpVDuDml7Z0sWQqW1fEWWcC0xM=",
"lastModified": 1696252780,
"narHash": "sha256-sQEjVzzstiaNLyiFJ19EMwwbDSSNDyQZIbPiLonlDCQ=",
"owner": "ezKEa",
"repo": "aagl-gtk-on-nix",
"rev": "8fc45fabbedef44a481c3bcabd9512732c0ade91",
"rev": "0c9d93bdb311f7948f9fb0e98d869316d78eec12",
"type": "github"
},
"original": {
@@ -30,11 +30,11 @@
"utils": "utils"
},
"locked": {
"lastModified": 1694158470,
"narHash": "sha256-yWx9eBDHt6WR3gr65+J85KreHdMypty/P6yM35tIYYM=",
"lastModified": 1695052866,
"narHash": "sha256-agn7F9Oww4oU6nPiw+YiYI9Xb4vOOE73w8PAoBRP4AA=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "d0cfc042eba92eb206611c9e8784d41a2c053bab",
"rev": "e3f41832680801d0ee9e2ed33eb63af398b090e9",
"type": "github"
},
"original": {
@@ -197,11 +197,11 @@
"flake-compat_4": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
@@ -285,11 +285,11 @@
]
},
"locked": {
"lastModified": 1693611461,
"narHash": "sha256-aPODl8vAgGQ0ZYFIRisxYG5MOGSkIczvu2Cd8Gb9+1Y=",
"lastModified": 1696343447,
"narHash": "sha256-B2xAZKLkkeRFG5XcHHSXXcP7To9Xzr59KXeZiRf4vdQ=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "7f53fdb7bdc5bb237da7fefef12d099e4fd611ca",
"rev": "c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4",
"type": "github"
},
"original": {
@@ -347,11 +347,11 @@
]
},
"locked": {
"lastModified": 1657226504,
"narHash": "sha256-GIYNjuq4mJlFgqKsZ+YrgzWm0IpA4axA3MCrdKYj7gs=",
"lastModified": 1696331477,
"narHash": "sha256-YkbRa/1wQWdWkVJ01JvV+75KIdM37UErqKgTf0L54Fk=",
"owner": "gytis-ivaskevicius",
"repo": "flake-utils-plus",
"rev": "2bf0f91643c2e5ae38c1b26893ac2927ac9bd82a",
"rev": "bfc53579db89de750b25b0c5e7af299e0c06d7d3",
"type": "github"
},
"original": {
@@ -398,11 +398,11 @@
"systems": "systems_4"
},
"locked": {
"lastModified": 1689068808,
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
@@ -449,11 +449,11 @@
"systems": "systems_6"
},
"locked": {
"lastModified": 1692799911,
"narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=",
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
@@ -528,11 +528,11 @@
]
},
"locked": {
"lastModified": 1689397210,
"narHash": "sha256-fVxZnqxMbsDkB4GzGAs/B41K0wt/e+B/fLxmTFF/S20=",
"lastModified": 1697031886,
"narHash": "sha256-oTMPX8dGC7yxSwrbF4NuPNQsUEcHB1dusW2yEbFD5zg=",
"owner": "hercules-ci",
"repo": "hercules-ci-effects",
"rev": "0a63bfa3f00a3775ea3a6722b247880f1ffe91ce",
"rev": "178b36dc3a75c96efc25477d45eafc37ba1fafc3",
"type": "github"
},
"original": {
@@ -548,11 +548,11 @@
]
},
"locked": {
"lastModified": 1693208669,
"narHash": "sha256-hHFaaUsZ860wvppPeiu7nJn/nXZjJfnqAQEu9SPFE9I=",
"lastModified": 1695108154,
"narHash": "sha256-gSg7UTVtls2yO9lKtP0yb66XBHT1Fx5qZSZbGMpSn2c=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "5bac4a1c06cd77cf8fc35a658ccb035a6c50cd2c",
"rev": "07682fff75d41f18327a871088d20af2710d4744",
"type": "github"
},
"original": {
@@ -564,11 +564,11 @@
},
"impermanence": {
"locked": {
"lastModified": 1690797372,
"narHash": "sha256-GImz19e33SeVcIvBB7NnhbJSbTpFFmNtWLh7Z85Y188=",
"lastModified": 1697303681,
"narHash": "sha256-caJ0rXeagaih+xTgRduYtYKL1rZ9ylh06CIrt1w5B4g=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "e3a7acd113903269a1b5c8b527e84ce7ee859851",
"rev": "0f317c2e9e56550ce12323eb39302d251618f5b5",
"type": "github"
},
"original": {
@@ -682,17 +682,18 @@
"inputs": {
"flake-compat": "flake-compat_4",
"flake-utils": "flake-utils_4",
"nix-filter": "nix-filter",
"nix-index-database": [
"nix-index-database"
],
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1693880502,
"narHash": "sha256-krCRVLNdlCI7l7F1Bb2ovkgac8hoz015LyYvm/+aYZw=",
"lastModified": 1698367638,
"narHash": "sha256-8g4HAU+kwTxb/RZBFxJw3wLckMGpKdN+7yDbTIGupVU=",
"owner": "thiagokokada",
"repo": "nix-alien",
"rev": "0fbd284930bcf1a5d1e3d07f2973e6f1738505cc",
"rev": "7b3be1a706c8db4dcca777b6638bdb2ca4849176",
"type": "github"
},
"original": {
@@ -701,6 +702,21 @@
"type": "github"
}
},
"nix-filter": {
"locked": {
"lastModified": 1694857738,
"narHash": "sha256-bxxNyLHjhu0N8T3REINXQ2ZkJco0ABFPn6PIe2QUfqo=",
"owner": "numtide",
"repo": "nix-filter",
"rev": "41fd48e00c22b4ced525af521ead8792402de0ea",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "nix-filter",
"type": "github"
}
},
"nix-index-database": {
"inputs": {
"nixpkgs": [
@@ -708,11 +724,11 @@
]
},
"locked": {
"lastModified": 1693711723,
"narHash": "sha256-5QmlVzskLciJ0QzYmZ6ULvKA7bP6pgV9wwrLBB0V3j0=",
"lastModified": 1697946153,
"narHash": "sha256-7k7qIwWLaYPgQ4fxmEdew3yCffhK6rM4I4Jo3X/79DA=",
"owner": "Mic92",
"repo": "nix-index-database",
"rev": "aca56a79afb82208af2b39d8459dd29c10989135",
"rev": "5a2006282caaf32663cdcd582c5b18809c7d7d8d",
"type": "github"
},
"original": {
@@ -730,16 +746,17 @@
]
},
"locked": {
"lastModified": 1694222210,
"narHash": "sha256-PzfwrGQMEpJk4lMK2a47bFbJpJFlAG/ihvZsL9U1Lik=",
"lastModified": 1693358717,
"narHash": "sha256-OYGe2Yay1QoodZZmvPYBFGAoTrRfyKLzFs2vON4gRek=",
"owner": "nix-community",
"repo": "nix-vscode-extensions",
"rev": "5a63908466573a4a1c0466e38f33c42c73ec5136",
"rev": "50c4bce16b93e7ca8565d51fafabc05e9f0515da",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-vscode-extensions",
"rev": "50c4bce16b93e7ca8565d51fafabc05e9f0515da",
"type": "github"
}
},
@@ -751,11 +768,11 @@
]
},
"locked": {
"lastModified": 1693052712,
"narHash": "sha256-7wrP6s4OEuR7BUasy76n7j+c09rp7wyOq7YVYviXw9s=",
"lastModified": 1697038389,
"narHash": "sha256-hbzFPXyQQxJObRdb+CsylUXii29UfFV7866WWgWYs6Y=",
"owner": "nix-community",
"repo": "nixd",
"rev": "f88accc8a8231efdae900ff6a14cb6301a73cff9",
"rev": "29904e121cc775e7caaf4fffa6bc7da09376a43b",
"type": "github"
},
"original": {
@@ -794,11 +811,11 @@
]
},
"locked": {
"lastModified": 1694192131,
"narHash": "sha256-nt5ypVXKh65lQFqKqWgytEzI841yUhpl6E291Briu+g=",
"lastModified": 1697683120,
"narHash": "sha256-sd0bjuGoUroCTkwjY2p1FwBPgAitK4qsN/P3jXk7rz0=",
"owner": "nixpak",
"repo": "nixpak",
"rev": "16bd2860238c53bb7a31f745693d7d3c33a1490c",
"rev": "6b0b69f793390b4fe12821588b6c254b462a3e85",
"type": "github"
},
"original": {
@@ -893,11 +910,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1694398355,
"narHash": "sha256-pUthVGI70SDT4M7FDihBuu4PDOmfySaUSjfY/QI6Y3Y=",
"lastModified": 1698416297,
"narHash": "sha256-Ne6TWm5lOaQAjT8aLimLmCufJbPAr8Z3GdPZNIj2HeA=",
"owner": "CHN-beta",
"repo": "nixpkgs",
"rev": "4944d71d43387083e6b7c7530caf3b1902c5eb27",
"rev": "4a5eef80f12698646b237de30d94fc1556eccaee",
"type": "github"
},
"original": {
@@ -909,16 +926,16 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1692007866,
"narHash": "sha256-X8w0vPZjZxMm68VCwh/BHDoKRGp+BgzQ6w7Nkif6IVM=",
"lastModified": 1697723726,
"narHash": "sha256-SaTWPkI8a5xSHX/rrKzUe+/uVNy6zCGMXgoeMb7T9rg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "de2b8ddf94d6cc6161b7659649594c79bd66c13b",
"rev": "7c9cc5a6e5d38010801741ac830a3f8fd667a7a0",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
@@ -941,11 +958,11 @@
},
"nixpkgs_4": {
"locked": {
"lastModified": 1694882942,
"narHash": "sha256-J99E0D5LQn8gMWm9r3lGAvPDF7vHyzMxvyHfo3HmXhs=",
"lastModified": 1699782692,
"narHash": "sha256-oB8PrzbdOj2BLMkbVtV1UgSnyVedeRY57tZAsGUPFSM=",
"owner": "CHN-beta",
"repo": "nixpkgs",
"rev": "8eebdf8cffabee8bfb9b054759a5569dbd6de551",
"rev": "963d5addeb1fd398abba2ad704d724c78e145b57",
"type": "github"
},
"original": {
@@ -957,11 +974,11 @@
},
"nur": {
"locked": {
"lastModified": 1694237951,
"narHash": "sha256-6gql7EJIWwn3mUvG/RHf1iGUA3Ptfmalz9WdgX3noSY=",
"lastModified": 1698414381,
"narHash": "sha256-dqeFzaYrkL3swiQFY919hSqmd2D6D0AFBT6zvk/EUUE=",
"owner": "nix-community",
"repo": "NUR",
"rev": "19674a713837dcfbef704a16815a4bbc462cd57a",
"rev": "55831c4f594b877658d454d2a51aa06b989d79cc",
"type": "github"
},
"original": {
@@ -980,11 +997,11 @@
"nvfetcher": "nvfetcher"
},
"locked": {
"lastModified": 1694239804,
"narHash": "sha256-C5ERSMRp8kQEqyKS2yggXSqaKZUgnNyQD+zjy6iqXm0=",
"lastModified": 1698390460,
"narHash": "sha256-BSIac9PrpXaX6iFnUAljrHlFhx/+QhvUzY9Ublw1t1M=",
"owner": "xddxdd",
"repo": "nur-packages",
"rev": "ce48d1df62cab988a5e8eefdf97bec8bdc46392f",
"rev": "6f9992fe054792014bda7355f60f470956c1fe84",
"type": "github"
},
"original": {
@@ -1065,11 +1082,11 @@
]
},
"locked": {
"lastModified": 1693829707,
"narHash": "sha256-nBFIF+a1aqDIzmi+1Hue3zVXI4V4tK5R4aW2lyNXIXs=",
"lastModified": 1698164032,
"narHash": "sha256-YzlHV9N22v8WRTCyt/kMlAX7ntJGboHOh8heaPMfbG0=",
"owner": "Nix-QChem",
"repo": "NixOS-QChem",
"rev": "ac7ffea07370d0df2c2b934ea582f0cc8acd0ae1",
"rev": "77633a73b12ee27b9c64dcbbb627a91a904efad9",
"type": "github"
},
"original": {
@@ -1113,11 +1130,11 @@
]
},
"locked": {
"lastModified": 1693898833,
"narHash": "sha256-OIrMAGNYNeLs6IvBynxcXub7aSW3GEUvWNsb7zx6zuU=",
"lastModified": 1698273636,
"narHash": "sha256-swsqg/ckSVJnravx7ie9NFQSKIH27owtlk0wh4+xStk=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "faf21ac162173c2deb54e5fdeed002a9bd6e8623",
"rev": "014e44d334a39481223a5d163530d4c4ca2e75cb",
"type": "github"
},
"original": {

242
flake.nix
View File

@@ -17,7 +17,11 @@
nur.url = "github:nix-community/NUR";
nixos-cn = { url = "github:nixos-cn/flakes"; inputs.nixpkgs.follows = "nixpkgs"; };
nur-xddxdd = { url = "github:xddxdd/nur-packages"; inputs.nixpkgs.follows = "nixpkgs"; };
nix-vscode-extensions = { url = "github:nix-community/nix-vscode-extensions"; inputs.nixpkgs.follows = "nixpkgs"; };
nix-vscode-extensions =
{
url = "github:nix-community/nix-vscode-extensions?rev=50c4bce16b93e7ca8565d51fafabc05e9f0515da";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-alien = { url = "github:thiagokokada/nix-alien"; inputs.nix-index-database.follows = "nix-index-database"; };
impermanence.url = "github:nix-community/impermanence";
qchem = { url = "github:Nix-QChem/NixOS-QChem"; inputs.nixpkgs.follows = "nixpkgs"; };
@@ -40,7 +44,7 @@
default = inputs.nixpkgs.legacyPackages.x86_64-linux.writeText "systems"
(builtins.concatStringsSep "\n" (builtins.map
(system: builtins.toString inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel)
[ "pc" "vps6" "vps7" "nas" "yoga" ]));
[ "pc" "vps6" "vps7" "nas" ]));
}
// (
builtins.listToAttrs (builtins.map
@@ -92,10 +96,9 @@
decrypt.auto =
{
"/dev/disk/by-uuid/55fdd19f-0f1d-4c37-bd4e-6df44fc31f26" = { mapper = "root"; ssd = true; };
"/dev/md/swap" = { mapper = "swap"; ssd = true; before = [ "root" ]; };
"/dev/disk/by-uuid/4be45329-a054-4c20-8965-8c5b7ee6b35d" =
{ mapper = "swap"; ssd = true; before = [ "root" ]; };
};
mdadm =
"ARRAY /dev/md/swap metadata=1.2 name=pc:swap UUID=2b546b8d:e38007c8:02990dd1:df9e23a4";
swap = [ "/dev/mapper/swap" ];
resume = "/dev/mapper/swap";
rollingRootfs = { device = "/dev/mapper/root"; path = "/nix/rootfs"; };
@@ -123,11 +126,7 @@
};
nixpkgs = { march = "alderlake"; cudaSupport = true; };
gui = { enable = true; preferred = true; };
kernel =
{
patches = [ "cjktty" "preempt" ];
modules.modprobeConfig = [ "options iwlmvm power_scheme=1" "options iwlwifi uapsd_disable=1" ];
};
kernel.patches = [ "cjktty" "preempt" ];
impermanence.enable = true;
networking =
{ hostname = "pc"; nebula = { enable = true; lighthouse = "vps6.chn.moe"; useRelay = true; }; };
@@ -194,24 +193,24 @@
"debug.mirism.one" = "127.0.0.1";
"initrd.vps6.chn.moe" = "74.211.99.69";
"nix-store.chn.moe" = "127.0.0.1";
"initrd.nas.chn.moe" = "192.168.1.185";
};
};
};
firewall.trustedInterfaces = [ "virbr0" "waydroid0" ];
acme = { enable = true; certs = [ "debug.mirism.one" ]; };
acme = { enable = true; cert."debug.mirism.one" = {}; };
frpClient =
{
enable = true;
serverName = "frp.chn.moe";
user = "pc";
tcp.store = { localPort = 443; remotePort = 7676; };
stcpVisitor."yy.vnc".localPort = 6187;
};
nix-serve = { enable = true; hostname = "nix-store.chn.moe"; };
smartd.enable = true;
nginx = { enable = true; transparentProxy.enable = false; };
misskey = { enable = true; hostname = "xn--qbtm095lrg0bfka60z.chn.moe"; };
misskey-proxy."xn--qbtm095lrg0bfka60z.chn.moe" = {};
huginn.enable = true;
nginx.transparentProxy.externalIp = [ "192.168.82.3" ];
misskey.instances.misskey.hostname = "xn--qbtm095lrg0bfka60z.chn.moe";
beesd = { enable = true; instances.root = { device = "/"; hashTableSizeMB = 2048; }; };
};
bugs =
[
@@ -247,7 +246,11 @@
};
grub.installDevice = "/dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:0";
nixpkgs.march = "sandybridge";
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
nix =
{
substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
autoOptimiseStore = true;
};
initrd =
{
network.enable = true;
@@ -267,35 +270,36 @@
frpServer = { enable = true; serverName = "frp.chn.moe"; };
nginx =
{
enable = true;
transparentProxy =
{
externalIp = "74.211.99.69";
externalIp = [ "74.211.99.69" "192.168.82.1" ];
map =
{
"ng01.mirism.one" = 7411;
"beta.mirism.one" = 9114;
};
};
streamProxy =
streamProxy.map =
{
enable = true;
map =
{
"nix-store.chn.moe" = { upstream = "internal.pc.chn.moe"; rewriteHttps = true; };
"anchor.fm" = { upstream = "anchor.fm:443"; rewriteHttps = true; };
"podcasters.spotify.com" = { upstream = "podcasters.spotify.com:443"; rewriteHttps = true; };
};
"anchor.fm" = { upstream = "anchor.fm:443"; proxyProtocol = false; };
"podcasters.spotify.com" = { upstream = "podcasters.spotify.com:443"; proxyProtocol = false; };
"xlog.chn.moe" = { upstream = "cname.xlog.app:443"; proxyProtocol = false; };
"nix-store.chn.moe".upstream.address = "internal.pc.chn.moe";
"xn--qbtm095lrg0bfka60z.chn.moe".upstream.address = "internal.pc.chn.moe";
"xn--s8w913fdga.chn.moe".upstream.address = "internal.vps7.chn.moe";
"misskey.chn.moe".upstream.address = "internal.vps7.chn.moe";
"synapse.chn.moe".upstream.address = "internal.vps7.chn.moe";
"send.chn.moe".upstream.address = "internal.vps7.chn.moe";
};
applications =
{
element.instances."element.chn.moe" = {};
synapse-admin.instances."synapse-admin.chn.moe" = {};
};
};
misskey-proxy =
{
"xn--qbtm095lrg0bfka60z.chn.moe".upstream.address = "internal.pc.chn.moe";
"xn--s8w913fdga.chn.moe".upstream.address = "internal.vps7.chn.moe";
};
coturn.enable = true;
synapse-proxy."synapse.chn.moe".upstream.address = "internal.vps7.chn.moe";
vaultwarden-proxy = { enable = true; upstream.address = "internal.vps7.chn.moe"; };
httpua.enable = true;
fcgiwrap.enable = true;
};
};})
];
@@ -345,18 +349,25 @@
services =
{
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
fontconfig.enable = true;
sshd.enable = true;
rsshub.enable = true;
nginx = { enable = true; transparentProxy.externalIp = "95.111.228.40"; };
nginx.transparentProxy.externalIp = [ "95.111.228.40" "192.168.82.2" ];
wallabag.enable = true;
misskey = { enable = true; hostname = "xn--s8w913fdga.chn.moe"; };
misskey-proxy."xn--s8w913fdga.chn.moe" = {};
misskey.instances =
{
misskey.hostname = "xn--s8w913fdga.chn.moe";
misskey-old = { port = 9727; redis.port = 3546; meilisearch.enable = false; };
};
synapse.enable = true;
synapse-proxy."synapse.chn.moe" = {};
xrdp = { enable = true; hostname = "vps7.chn.moe"; };
xrdp = { enable = true; hostname = [ "vps7.chn.moe" ]; };
vaultwarden.enable = true;
vaultwarden-proxy.enable = true;
# huginn.enable = true;
beesd = { enable = true; instances.root = { device = "/"; hashTableSizeMB = 1024; }; };
photoprism.enable = true;
nextcloud.enable = true;
freshrss.enable = true;
send.enable = true;
huginn.enable = true;
};
};})
];
@@ -381,17 +392,29 @@
"/nix/persistent" = "/nix/persistent";
"/nix/nodatacow" = "/nix/nodatacow";
"/nix/rootfs/current" = "/";
"/nix/backup" = "/nix/backup";
};
};
};
decrypt.auto =
decrypt.manual =
{
"/dev/disk/by-uuid/5cf1d19d-b4a5-4e67-8e10-f63f0d5bb649".mapper = "root1";
"/dev/disk/by-uuid/aa684baf-fd8a-459c-99ba-11eb7636cb0d".mapper = "root2";
"/dev/disk/by-uuid/a779198f-cce9-4c3d-a64a-9ec45f6f5495" = { mapper = "nix"; ssd = true; };
enable = true;
devices =
{
"/dev/disk/by-uuid/5cf1d19d-b4a5-4e67-8e10-f63f0d5bb649".mapper = "root1";
"/dev/disk/by-uuid/aa684baf-fd8a-459c-99ba-11eb7636cb0d".mapper = "root2";
"/dev/disk/by-uuid/a779198f-cce9-4c3d-a64a-9ec45f6f5495" = { mapper = "nix"; ssd = true; };
};
delayedMount = [ "/" "/nix" ];
};
swap = [ "/nix/swap/swap" ];
rollingRootfs = { device = "/dev/mapper/root1"; path = "/nix/rootfs"; };
};
initrd =
{
network.enable = true;
sshd = { enable = true; hostKeys = [ "/nix/persistent/etc/ssh/initrd_ssh_host_ed25519_key" ]; };
};
grub.installDevice = "efi";
nixpkgs.march = "silvermont";
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
@@ -433,131 +456,24 @@
xrdp = { enable = true; hostname = [ "nas.chn.moe" "office.chn.moe" ]; };
groupshare.enable = true;
smartd.enable = true;
};
users = [ "root" "chn" "xll" "zem" "yjq" "yxy" ];
};})
];
"xmupc1" =
[
(inputs: { config.nixos =
{
system =
{
fileSystems =
{
mount =
{
vfat."/dev/disk/by-uuid/3F57-0EBE" = "/boot/efi";
btrfs =
{
"/dev/disk/by-uuid/02e426ec-cfa2-4a18-b3a5-57ef04d66614"."/" = "/boot";
"/dev/mapper/root" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
};
};
decrypt.auto =
{
"/dev/disk/by-uuid/55fdd19f-0f1d-4c37-bd4e-6df44fc31f26" = { mapper = "root"; ssd = true; };
"/dev/md/swap" = { mapper = "swap"; ssd = true; before = [ "root" ]; };
};
mdadm =
"ARRAY /dev/md/swap metadata=1.2 name=pc:swap UUID=2b546b8d:e38007c8:02990dd1:df9e23a4";
swap = [ "/dev/mapper/swap" ];
resume = "/dev/mapper/swap";
rollingRootfs = { device = "/dev/mapper/root"; path = "/nix/rootfs"; };
};
grub.installDevice = "efi";
nixpkgs = { march = "znver3"; cudaSupport = true; };
nix =
{
marches =
[
"znver3" "znver2"
# PREFETCHW RDRND XSAVE XSAVEOPT PTWRITE SGX GFNI-SSE MOVDIRI MOVDIR64B CLDEMOTE WAITPKG LZCNT
# PCONFIG SERIALIZE HRESET KL WIDEKL AVX-VNNI
"alderlake"
# SAHF FXSR XSAVE
"sandybridge"
# SAHF FXSR PREFETCHW RDRND
"silvermont"
];
substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
};
gui.enable = true;
kernel =
{
patches = [ "cjktty" "preempt" ];
modules.modprobeConfig = [ "options iwlmvm power_scheme=1" "options iwlwifi uapsd_disable=1" ];
};
impermanence.enable = true;
networking.hostname = "xmupc1";
sops = { enable = true; keyPathPrefix = "/nix/persistent"; };
};
hardware =
{
cpus = [ "intel" ];
gpus = [ "intel" "nvidia" ];
bluetooth.enable = true;
joystick.enable = true;
printer.enable = true;
sound.enable = true;
prime =
{ enable = true; mode = "offload"; busId = { intel = "PCI:0:2:0"; nvidia = "PCI:1:0:0"; };};
};
packages.packageSet = "workstation";
virtualization =
{
docker.enable = true;
kvmHost = { enable = true; gui = true; };
};
services =
{
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
fontconfig.enable = true;
samba =
beesd =
{
enable = true;
hostsAllowed = "192.168. 127.";
shares =
instances =
{
media.path = "/run/media/chn";
home.path = "/home/chn";
mnt.path = "/mnt";
share.path = "/home/chn/share";
root = { device = "/"; hashTableSizeMB = 2048; };
nix = { device = "/nix"; hashTableSizeMB = 128; };
};
};
sshd.enable = true;
xrayClient =
{
enable = true;
serverAddress = "74.211.99.69";
serverName = "vps6.xserver.chn.moe";
dns =
{
extraInterfaces = [ "docker0" ];
hosts =
{
"mirism.one" = "216.24.188.24";
"beta.mirism.one" = "216.24.188.24";
"ng01.mirism.one" = "216.24.188.24";
"debug.mirism.one" = "127.0.0.1";
"initrd.vps6.chn.moe" = "74.211.99.69";
"nix-store.chn.moe" = "127.0.0.1";
};
};
};
firewall.trustedInterfaces = [ "virbr0" ];
frpClient =
{
enable = true;
serverName = "frp.chn.moe";
user = "xmupc1";
tcp.store = { localPort = 443; remotePort = 7676; };
user = "nas";
stcp.hpc = { localIp = "hpc.xmu.edu.cn"; localPort = 22; };
};
smartd.enable = true;
nginx = { enable = true; transparentProxy.enable = false; };
postgresql.enable = true;
};
bugs = [ "xmunet" "firefox" "embree" ];
users.users = [ "root" "chn" "xll" "zem" "yjq" "yxy" ];
};})
];
"yoga" =
@@ -599,6 +515,7 @@
joystick.enable = true;
printer.enable = true;
sound.enable = true;
halo-keyboard.enable = true;
};
packages.packageSet = "desktop";
virtualization.docker.enable = true;
@@ -615,8 +532,8 @@
dns.extraInterfaces = [ "docker0" ];
};
firewall.trustedInterfaces = [ "virbr0" ];
smartd.enable = true;
};
bugs = [ "xmunet" "firmware-unstable" ];
};})
];
}));
@@ -655,7 +572,10 @@
inputs.self.nixosConfigurations.${node};
};
})
[ "vps6" "vps7" "nas" ]);
[ "vps6" "vps7" "nas" "yoga" ]);
};
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks inputs.self.deploy) inputs.deploy-rs.lib;
overlays.default = final: prev:
{ localPackages = (import ./local/pkgs { inherit (inputs) lib; pkgs = final; }); };
};
}

View File

@@ -0,0 +1,17 @@
{
stdenv, fetchFromGitHub, cmake, pkg-config, ninja,
fmt, boost, magic-enum, libbacktrace, concurrencpp, tgbot-cpp, nameof, eigen, range-v3
}: stdenv.mkDerivation rec
{
name = "libbiu";
src = fetchFromGitHub
{
owner = "CHN-beta";
repo = "biu";
rev = "8ed2e52968f98d3a6ddbd01e86e57604ba3a7f54";
sha256 = "OqQ+QkjjIbpve/xn/DJA7ONw/bBg5zGNr+VJjc3o+K8=";
};
nativeBuildInputs = [ cmake pkg-config ninja ];
buildInputs = [ fmt boost magic-enum libbacktrace concurrencpp tgbot-cpp nameof eigen range-v3 ];
propagatedBuildInputs = buildInputs;
}

View File

@@ -0,0 +1,18 @@
{ lib, stdenv, fetchFromGitHub, fetchurl, cmake }: stdenv.mkDerivation rec
{
pname = "chromiumos-touch-keyboard";
version = "1.4.1";
src = fetchFromGitHub
{
owner = "CHN-beta";
repo = "chromiumos_touch_keyboard";
rev = "32b72240ccac751a1b983152f65aa5b19503ffcf";
sha256 = "eFesDSBS2VzTOVfepgXYGynWvkrCSdCV9C/gcG/Ocbg=";
};
cmakeFlags = [ "-DCMAKE_CXX_FLAGS=-Wno-error=stringop-truncation" ];
nativeBuildInputs = [ cmake ];
postInstall =
''
cp $out/etc/touch_keyboard/layouts/YB1-X9x-pc105.csv $out/etc/touch_keyboard/layout.csv
'';
}

View File

@@ -10,9 +10,4 @@
sha256 = "4qT29YVjKEWcMrI5R5Ps8aD4grAAgz5VOxANjpp1oTo=";
};
nativeBuildInputs = [ cmake ];
postInstall =
''
mv $out/include/concurrencpp-${version}/concurrencpp $out/include
rm -rf $out/include/concurrencpp-${version}
'';
}

View File

@@ -0,0 +1,12 @@
diff --git a/lib/static_thread_pool.cpp b/lib/static_thread_pool.cpp
index 989a6a9..0b91b9c 100644
--- a/lib/static_thread_pool.cpp
+++ b/lib/static_thread_pool.cpp
@@ -12,6 +12,7 @@
#include <cassert>
#include <mutex>
#include <chrono>
+#include <utility>
namespace
{

View File

@@ -0,0 +1,13 @@
{ stdenv, fetchFromGitHub, cmake }: stdenv.mkDerivation
{
name = "cppcoro";
src = fetchFromGitHub
{
owner = "Garcia6l20";
repo = "cppcoro";
rev = "e1d53e620b0eee828915ada179cd7ca8e66ca855";
sha256 = "luBkf1x5kqXaVbQM01yWRmA5QvrQNZkFVCjRctJdnXc=";
};
nativeBuildInputs = [ cmake ];
patches = [ ./cppcoro-include-utility.patch ];
}

View File

@@ -0,0 +1,18 @@
{ stdenv, fetchFromGitHub }: stdenv.mkDerivation
{
name = "date";
src = fetchFromGitHub
{
owner = "HowardHinnant";
repo = "date";
rev = "cc4685a21e4a4fdae707ad1233c61bbaff241f93";
sha256 = "KilhBEeLMvHtS76Gu0UhzE8lhS1+sCwQ1UL4pswKXTs=";
};
phases = [ "installPhase" ];
installPhase =
''
runHook preInstall
mkdir -p $out
cp -r $src/{include,src} $out
'';
}

View File

@@ -1,4 +1,4 @@
{ lib, pkgs }: with pkgs;
{ lib, pkgs }: with pkgs; rec
{
typora = callPackage ./typora {};
upho = python3Packages.callPackage ./upho {};
@@ -26,4 +26,24 @@
huginn = callPackage ./huginn {};
v_sim = callPackage ./v_sim {};
concurrencpp = callPackage ./concurrencpp { stdenv = gcc13Stdenv; };
eigengdb = python3Packages.callPackage ./eigengdb {};
nodesoup = callPackage ./nodesoup {};
matplotplusplus = callPackage ./matplotplusplus { inherit nodesoup glad; };
zpp-bits = callPackage ./zpp-bits {};
eigen = callPackage ./eigen {};
nameof = callPackage ./nameof {};
pslist = callPackage ./pslist {};
glad = callPackage ./glad {};
chromiumos-touch-keyboard = callPackage ./chromiumos-touch-keyboard {};
yoga-support = callPackage ./yoga-support {};
tgbot-cpp = callPackage ./tgbot-cpp {};
biu = callPackage ./biu { inherit concurrencpp tgbot-cpp nameof; stdenv = gcc13Stdenv; };
latex-citation-style-language = callPackage ./latex-citation-style-language {};
mirism = callPackage ./mirism
{
inherit cppcoro nameof tgbot-cpp date;
nghttp2 = nghttp2.override { enableAsioLib = true; };
};
cppcoro = callPackage ./cppcoro {};
date = callPackage ./date {};
}

View File

@@ -0,0 +1,12 @@
{ lib, stdenv, fetchFromGitLab, cmake }: stdenv.mkDerivation rec
{
name = "eigen";
src = fetchFromGitLab
{
owner = "libeigen";
repo = name;
rev = "6d829e766ff1b1ab867d93631163cbc63ed5798f";
sha256 = "BXUnizcRPrOyiPpoyYJ4VVOjlG49aj80mgzPKmEYPKU=";
};
nativeBuildInputs = [ cmake ];
}

View File

@@ -0,0 +1,15 @@
{ lib, fetchFromGitHub, buildPythonPackage, numpy, gdb }: buildPythonPackage
{
name = "eigengdb";
src = fetchFromGitHub
{
owner = "dmillard";
repo = "eigengdb";
rev = "c741edef3f07f33429056eff48d79a62733ed494";
sha256 = "MTqOaWsKhWaPs3G5F/6bYZmQI5qS2hEGKGa3mwbgFaY=";
};
doCheck = false;
buildInputs = [ gdb ];
nativeBuildInputs = [ gdb ];
propagatedBuildInputs = [ numpy ];
}

View File

@@ -0,0 +1,14 @@
{ lib, stdenv, fetchFromGitHub, cmake, python3 }: stdenv.mkDerivation rec
{
pname = "glad";
version = "0.1.36";
src = fetchFromGitHub
{
owner = "Dav1dde";
repo = "glad";
rev = "v${version}";
sha256 = "FtkPz0xchwmqE+QgS+nSJVYaAfJSTUmZsObV/IPypVQ=";
};
cmakeFlags = [ "-DGLAD_REPRODUCIBLE=ON" "-DGLAD_INSTALL=ON" ];
nativeBuildInputs = [ cmake python3 ];
}

View File

@@ -0,0 +1,30 @@
{ stdenvNoCC, texlive, fetchFromGitHub }: stdenvNoCC.mkDerivation (finalAttrs: rec
{
pname = "latex-citation-style-language";
version = "0.4.5";
passthru = {
pkgs = [ finalAttrs.finalPackage ];
tlDeps = with texlive; [ latex ];
tlType = "run";
};
src = fetchFromGitHub
{
owner = "zepinglee";
repo = "citeproc-lua";
rev = "v${version}";
sha256 = "XH+GH+t/10hr4bfaod8F9JPxmBnAQlDmpSvQNDQsslM=";
fetchSubmodules = true;
};
nativeBuildInputs = [ texlive.combined.scheme-full ];
dontConfigure = true;
dontBuild = true;
installPhase =
''
runHook preInstall
export TEXMFHOME=$out
l3build install
runHook postInstall
'';
})

View File

@@ -0,0 +1,25 @@
{
stdenv, fetchFromGitHub, cmake, pkg-config, substituteAll,
gnuplot, libjpeg, libtiff, zlib, libpng, lapack, blas, fftw, opencv, nodesoup, cimg, glfw, libGL, python3, glad
}: stdenv.mkDerivation
{
pname = "matplotplusplus";
version = "1.2.0";
src = fetchFromGitHub
{
owner = "alandefreitas";
repo = "matplotplusplus";
rev = "a40344efa9dc5ea0c312e6e9ef4eb7238d98dc12";
sha256 = "6/dH/Rl2aAb8b+Ji5LwzkC+GWPOCBnYCrjy0qk8u/+I=";
};
cmakeFlags =
[
"-DBUILD_SHARED_LIBS=ON" "-DMATPLOTPP_BUILD_SHARED_LIBS=ON" "-DMATPLOTPP_BUILD_EXAMPLES=OFF"
"-DMATPLOTPP_WITH_SYSTEM_NODESOUP=ON" "-DMATPLOTPP_WITH_SYSTEM_CIMG=ON"
"-DMATPLOTPP_BUILD_EXPERIMENTAL_OPENGL_BACKEND=ON" "-DGLAD_REPRODUCIBLE=ON"
];
buildInputs = [ gnuplot libjpeg libtiff zlib libpng lapack blas fftw opencv nodesoup cimg glfw libGL glad ];
nativeBuildInputs = [ cmake pkg-config python3 ];
propagatedBuildInputs = [ libGL glad glfw ];
propagatedNativeBuildInputs = [ python3 ];
}

View File

@@ -0,0 +1,29 @@
{
lib, stdenv, requireFile,
boost, nghttp2, brotli, nameof, cppcoro, tgbot-cpp, libbacktrace, fmt, date
}: stdenv.mkDerivation rec
{
name = "mirism";
# nix-store --query --hash $(nix store add-path . --name 'mirism')
src = requireFile
{
inherit name;
sha256 = "10r40j4d6nnj930c8rw925akpim8f8sixh1lqrwdyp561nw774s4";
hashMode = "recursive";
message = "Source file not found.";
};
buildInputs = [ boost nghttp2.dev brotli nameof cppcoro tgbot-cpp libbacktrace fmt date ];
buildPhase =
''
runHook preBuild
make ng01 beta
runHook postBuild
'';
installPhase =
''
runHook preInstall
mkdir -p $out/bin
cp build/{ng01,beta} $out/bin
runHook postInstall
'';
}

View File

@@ -1,16 +1,16 @@
{
lib, stdenv, mkPnpmPackage, fetchFromGitHub, nodejs_20, writeShellScript, buildFHSEnv,
lib, stdenv, mkPnpmPackage, fetchFromGitHub, fetchurl, nodejs_20, writeShellScript, buildFHSEnv,
bash, cypress, vips, pkg-config
}:
let
pname = "misskey";
version = "13.14.2";
version = "2023.11.0";
src = fetchFromGitHub
{
owner = "CHN-beta";
repo = "misskey";
rev = "e02ecb3819f6f05352d43b64ae59fa1bd683e2e0";
hash = "sha256-zsYM67LYUn+bI6kbdW9blftxw5TUxCdzlfaOOEgZz+Q=";
rev = "aa182cd92ea5dc446f4d1ae2bf942bf46c645811";
sha256 = "hotUhy4Rhm4QWO7oYH3UENr7LewF+/dC8rsaKD0y2uc=";
fetchSubmodules = true;
};
originalPnpmPackage = mkPnpmPackage
@@ -26,14 +26,66 @@ let
export NODE_ENV=production
pnpm run migrateandstart
'';
re2 = stdenv.mkDerivation rec
{
pname = "re2";
version = "1.20.5";
srcs =
[
(fetchurl
{
url = "https://github.com/uhop/node-re2/releases/download/1.20.5/linux-x64-120.br";
sha256 = "07hwfgb7yw7pad2svkmx8qapc490xxxk0bbbx51h3kajckw98b9w";
})
(fetchurl
{
url = "https://github.com/uhop/node-re2/releases/download/1.20.5/linux-x64-120.gz";
sha256 = "0c3z7bw4b1hgafv4n86pkg3z627zsmlzaghbzpyb81pilf1hzn8z";
})
(fetchurl
{
url = "https://github.com/uhop/node-re2/releases/download/1.20.5/linux-x64-115.br";
sha256 = "17sbfx0dbfqc42qsxbqnn94a3vsih4mc06d8svbarvx5b5x0mg31";
})
(fetchurl
{
url = "https://github.com/uhop/node-re2/releases/download/1.20.5/linux-x64-115.gz";
sha256 = "1lnmad2vqhjck0fjs55z74jm9psl1p81g84k2nn9gxbqnk2lxsjd";
})
(fetchurl
{
url = "https://github.com/uhop/node-re2/releases/download/1.20.5/linux-x64-108.br";
sha256 = "1c605zipadwbd8z3mzvjzw4x9v89jdq19m4hmd6bqbrcz3qbgg4n";
})
(fetchurl
{
url = "https://github.com/uhop/node-re2/releases/download/1.20.5/linux-x64-108.gz";
sha256 = "0sqsn3rdlg8abqcn7i9gyhpsd1znfj1x2bxm1nj222g0svp1mry3";
})
];
phases = [ "installPhase" ];
installPhase =
''
mkdir -p $out/${version}
for i in $srcs
do
cp $i $out/${version}/''${i#*-}
done
'';
};
in
stdenv.mkDerivation
stdenv.mkDerivation rec
{
inherit version src pname;
nativeBuildInputs =
[ bash nodejs_20 nodejs_20.pkgs.typescript nodejs_20.pkgs.pnpm nodejs_20.pkgs.gulp cypress vips pkg-config ];
buildInputs =
[
bash nodejs_20 nodejs_20.pkgs.typescript nodejs_20.pkgs.pnpm nodejs_20.pkgs.gulp cypress vips pkg-config
];
nativeBuildInputs = buildInputs;
CYPRESS_RUN_BINARY = "${cypress}/bin/Cypress";
NODE_ENV = "production";
RE2_DOWNLOAD_MIRROR = "${re2}";
RE2_DOWNLOAD_SKIP_PATH = "true";
configurePhase =
''
export HOME=$NIX_BUILD_TOP # Some packages need a writable HOME
@@ -67,4 +119,8 @@ in
mkdir -p $out/files
runHook postInstall
'';
passthru =
{
inherit originalPnpmPackage startScript re2;
};
}

View File

@@ -0,0 +1,20 @@
{ lib, stdenv, fetchFromGitHub }: stdenv.mkDerivation rec
{
pname = "nameof";
version = "0.10.3";
src = fetchFromGitHub
{
owner = "Neargye";
repo = pname;
rev = "v${version}";
sha256 = "eHG0Y/BQGbwTrBHjq9SeSiIXaVqWp7PxIq7vCIECYPk=";
};
phases = [ "installPhase" ];
installPhase =
''
runHook preInstall
mkdir -p $out
cp -r $src/include $out
runHook postInstall
'';
}

View File

@@ -0,0 +1,13 @@
{ stdenv, fetchFromGitHub, cmake, pkg-config, cairo, pcre2, xorg }: stdenv.mkDerivation rec
{
name = "nodesoup";
src = fetchFromGitHub
{
owner = "olvb";
repo = "nodesoup";
rev = "3158ad082bb0cd1abee75418b12b35522dbca74f";
sha256 = "tFLq6QC3U3uvcuWsdRy2wnwcmAfH2MkI2oMcAiUBHSo=";
};
buildInputs = [ cairo pcre2.dev xorg.libXdmcp.dev ];
nativeBuildInputs = [ cmake pkg-config ];
}

View File

@@ -0,0 +1,27 @@
# http://launchpadlibrarian.net/632309499/pslist_1.4.0-4_all.deb
# https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/pslist/1.4.0-4/pslist_1.4.0.orig.tar.xz
{ lib, stdenv, fetchzip, perl, procps }: stdenv.mkDerivation
{
pname = "pslist";
version = "1.4.0";
src = fetchzip
{
url = "https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/pslist/1.4.0-4/pslist_1.4.0.orig.tar.xz";
sha256 = "1sp1h7ccniz658ms331npffpa9iz8llig43d9mlysll420nb3xqv";
};
buildInstall = [ perl procps ];
installPhase =
''
mkdir -p $out/bin
cp $src/pslist $out/bin
ln -s pslist $out/bin/rkill
ln -s pslist $out/bin/rrenice
mkdir -p $out/share/man/man1
cp $src/pslist.1 $out/share/man/man1
ln -s pslist.1 $out/share/man/man1/rkill.1
ln -s pslist.1 $out/share/man/man1/rrenice.1
sed -i 's|/usr/bin/perl|${perl}/bin/perl|' $out/bin/pslist
sed -i 's|/bin/ps|${procps}/bin/ps|' $out/bin/pslist
'';
}

View File

@@ -3,21 +3,20 @@
chromium, bash
}:
let
pname = "rsshub";
version = "20230829";
name = "rsshub";
src = fetchFromGitHub
{
owner = "DIYgod";
repo = "RSSHub";
rev = "afcf9774260dc6505263cf0428970e890f2f7b1d";
hash = "sha256-BQFE0Z5DsFTf0tylQ0NN89hCdXT/Y2M+YPa/10ccOVg=";
rev = "4356fad91a268c81b8dacd2e3d9d07dbdce231a0";
sha256 = "rUfXHtePIkBGF1U/tqrXHEsYC5jah2A7hoJZfEAnCoQ=";
};
originalPnpmPackage = mkPnpmPackage { inherit pname version src nodejs; };
originalPnpmPackage = mkPnpmPackage { inherit name src nodejs; };
nodeModules = originalPnpmPackage.nodeModules.overrideAttrs { PUPPETEER_SKIP_DOWNLOAD = true; };
rsshub-unwrapped = stdenv.mkDerivation
{
inherit version src;
pname = "${pname}-unwrapped";
inherit src;
name = "${name}-unwrapped";
configurePhase =
''
export HOME=$NIX_BUILD_TOP # Some packages need a writable HOME
@@ -44,9 +43,9 @@ let
export CHROMIUM_EXECUTABLE_PATH=chromium
pnpm start
'';
in stdenv.mkDerivation rec
in stdenv.mkDerivation
{
inherit pname version;
inherit name;
phases = [ "installPhase" ];
installPhase =
''

View File

@@ -1,4 +1,4 @@
{ buildNpmPackage, fetchFromGitHub, nodejs-16_x }:
{ buildNpmPackage, fetchFromGitHub, nodejs-16_x, nodePackages }:
buildNpmPackage.override { nodejs = nodejs-16_x; }
{
pname = "send";
@@ -8,8 +8,14 @@ buildNpmPackage.override { nodejs = nodejs-16_x; }
owner = "timvisee";
repo = "send";
rev = "6ad2885a168148fb996d3983457bc39527c7c8e5";
hash = "sha256-/w9KhktDVSAmp6EVIRHFM63mppsIzYSm5F7CQQd/2+E=";
sha256 = "AdwYNfTMfEItC4kBP+YozUQSBVnu/uzZvGta4wfwv0I=";
leaveDotGit = true;
};
npmDepsHash = "sha256-r1iaurKuhpP0sevB5pFdtv9j1ikM1fKL7Jgakh4FzTI=";
makeCacheWritable = true;
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = "1";
NODE_OPTIONS = "--openssl-legacy-provider";
dontNpmInstall = true;
NODE_ENV = "production";
nativeBuildInputs = with nodePackages; [ rimraf webpack webpack-cli copy-webpack-plugin webpack-manifest-plugin ];
}

View File

@@ -0,0 +1,15 @@
{ stdenv, fetchFromGitHub, cmake, pkg-config, boost, openssl, zlib, curl }: stdenv.mkDerivation rec
{
pname = "tgbot-cpp";
version = "1.7.2";
src = fetchFromGitHub
{
owner = "reo7sp";
repo = "tgbot-cpp";
rev = "v${version}";
sha256 = "TKirSxEUqFB1WtzNEfU4EJK3p7V5xcFIvA2+QVX7TlA=";
};
nativeBuildInputs = [ cmake pkg-config ];
buildInputs = [ boost openssl zlib curl.dev ];
propagatedBuildInputs = buildInputs;
}

View File

@@ -3,11 +3,11 @@ let
typora-dist = stdenv.mkDerivation rec
{
pname = "typora-dist";
version = "1.6.6";
version = "1.7.6";
src = fetchurl
{
url = "https://download.typora.io/linux/typora_${version}_amd64.deb";
sha256 = "sha256-77mCgmsROLhfuOmOOyl2C5Ug2NfqEvcD+kMA3aiAQtA=";
sha256 = "19xgv83zk3mhniswwrb341sr9j4sb9pqy47jamrmkc3w8famxpd3";
};
dontFixup = true;

View File

@@ -0,0 +1,24 @@
{ lib, stdenv, fetchFromGitHub, python3 }:
let
python = python3.withPackages (ps: with ps; [ evdev pyudev ]);
in stdenv.mkDerivation
{
name = "yogabook-support";
src = fetchFromGitHub
{
owner = "jekhor";
repo = "yogabook-support";
rev = "8ecf7861e469ba4094115fff0e81d537135e3f22";
sha256 = "4UtiQooCaeUDHc9YE9EQRJ2MNKvOqqCv85k0YyI2BO4=";
};
buildInputs = [ python ];
installPhase =
''
mkdir -p $out/bin
cp pen-key-handler yogabook-modes-handler $out/bin
mkdir -p $out/lib/udev/rules.d
cp 61-sensor-yogabook.rules $out/lib/udev/rules.d
mkdir -p $out/lib/udev/hwdb.d
cp 61-sensor-yogabook.hwdb $out/lib/udev/hwdb.d
'';
}

View File

@@ -0,0 +1,18 @@
{ stdenv, fetchFromGitHub }: stdenv.mkDerivation rec
{
pname = "zpp-bits";
version = "4.4.19";
src = fetchFromGitHub
{
owner = "eyalz800";
repo = "zpp_bits";
rev = "v${version}";
sha256 = "ejIwrvCFALuBQbQhTfzjBb11oMR/akKnboB60GWbjlQ=";
};
phases = [ "installPhase" ];
installPhase =
''
mkdir -p $out/include
cp $src/zpp_bits.h $out/include
'';
}

View File

@@ -14,18 +14,23 @@ inputs:
HibernateMode=shutdown
'';
# reload iwlwifi after resume from hibernate
hibernate-iwlwifi.systemd.services.reload-iwlwifi-after-hibernate =
hibernate-iwlwifi =
{
description = "reload iwlwifi after resume from hibernate";
after = [ "systemd-hibernate.service" ];
serviceConfig.Type = "oneshot";
script = let modprobe = "${inputs.pkgs.kmod}/bin/modprobe"; in
''
${modprobe} -r iwlwifi
${modprobe} iwlwifi
echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
'';
wantedBy = [ "systemd-hibernate.service" ];
systemd.services.reload-iwlwifi-after-hibernate =
{
description = "reload iwlwifi after resume from hibernate";
after = [ "systemd-hibernate.service" ];
serviceConfig.Type = "oneshot";
script = let modprobe = "${inputs.pkgs.kmod}/bin/modprobe"; in
''
${modprobe} -r iwlwifi
${modprobe} iwlwifi
echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
'';
wantedBy = [ "systemd-hibernate.service" ];
};
nixos.system.kernel.modules.modprobeConfig =
[ "options iwlmvm power_scheme=1" "options iwlwifi uapsd_disable=1" ];
};
# disable wakeup on lid open
suspend-lid-no-wakeup.systemd.services.lid-no-wakeup =
@@ -46,10 +51,8 @@ inputs:
wantedBy = [ "multi-user.target" ];
};
# xmunet use old encryption
xmunet.nixpkgs.config.packageOverrides = pkgs:
{
wpa_supplicant = pkgs.wpa_supplicant.overrideAttrs (attrs: { patches = attrs.patches ++ [ ./xmunet.patch ];});
};
xmunet.nixpkgs.config.packageOverrides = pkgs: { wpa_supplicant = pkgs.wpa_supplicant.overrideAttrs
(attrs: { patches = attrs.patches ++ [ ./xmunet.patch ];}); };
suspend-hibernate-waydroid.systemd.services =
let
systemctl = "${inputs.pkgs.systemd}/bin/systemctl";
@@ -75,6 +78,8 @@ inputs:
firefox.programs.firefox.enable = inputs.lib.mkForce false;
embree.nixpkgs.overlays =
[(final: prev: { embree = prev.embree.override { stdenv = final.genericPackages.stdenv; }; })];
firmware-unstable.nixpkgs.overlays =
[ (final: prev: { linux-firmware = final.unstablePackages.linux-firmware; }) ];
};
in
{

View File

@@ -21,6 +21,7 @@ inputs:
topInputs.napalm.overlays.default
topInputs.pnpm2nix-nzbr.overlays.default
topInputs.lmix.overlays.default
(final: prev: topInputs.aagl.overlays.default {} final.unstablePackages)
(import "${topInputs.dguibert-nur-packages}/overlays/nvhpc-overlay")
(final: prev:
{

View File

@@ -15,6 +15,7 @@ inputs:
busId = mkOption { type = types.attrsOf types.str; default = {}; };
};
gamemode.drmDevice = mkOption { type = types.int; default = 0; };
halo-keyboard.enable = mkOption { type = types.bool; default = false; };
};
config =
let
@@ -142,5 +143,51 @@ inputs:
}
)
{ programs.gamemode.settings.gpu.gpu_device = "${toString hardware.gamemode.drmDevice}"; }
# halo-keyboard
(mkIf hardware.halo-keyboard.enable
(
let
keyboard = inputs.pkgs.localPackages.chromiumos-touch-keyboard;
support = inputs.pkgs.localPackages.yoga-support;
in
{
services.udev.packages = [ keyboard support ];
systemd.services =
{
touch-keyboard-handler.serviceConfig =
{
Type = "simple";
WorkingDirectory = "/etc/touch_keyboard";
# ExecStartPre = let sh = "${inputs.pkgs.bash}/bin/sh"; in
# [
# ''-${sh} -c "echo 0 > /sys/class/pwm/pwmchip1/export"''
# ''${sh} -c "echo 0 > /sys/class/pwm/pwmchip1/pwm0/enable"''
# ''${sh} -c "echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable"''
# ];
ExecStart = "${keyboard}/bin/touch_keyboard_handler";
};
yogabook-modes-handler =
{
wantedBy = [ "default.target" ];
serviceConfig =
{
Type = "simple";
ExecStart = "${support}/bin/yogabook-modes-handler";
StandardOutput = "journal";
};
};
monitor-sensor =
{
wantedBy = [ "default.target" ];
serviceConfig =
{
Type = "simple";
ExecStart = "${inputs.pkgs.iio-sensor-proxy}/bin/monitor-sensor --hinge";
};
};
};
environment.etc."touch_keyboard".source = "${keyboard}/etc/touch_keyboard";
}
))
];
}

File diff suppressed because it is too large Load Diff

View File

@@ -1686,7 +1686,7 @@
# - verbose: Enable instant prompt and print a warning when detecting console output during
# zsh initialization. Choose this if you've never tried instant prompt, haven't
# seen the warning, or if you are unsure what this all means.
typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose
typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet
# Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized.
# For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload

View File

@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=

View File

@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDkkl7A9kWWBoi4b5g6Vus70ja1KhPfcZZjeU1/QbYdN8PRRw/hsGklrhefslKRbym/TMFS0ko0g5WUi9G5vbGw=

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgs8MvV2nczjGMZ548tuAhgvCEd4uHu0VhLDSwQG7Nh/UR4Pgc5T9Nf7Vfwg96Lah/pwD5my4RaWis6bLMmlkYyDBKFBOsGYQUe5J5XfZdxk8pz+7L0Hq6gPfAZAdNlUiuFVKsvkE+NF42NgJyXSYQicPbu5LQiFwZGXlW20+LO8uBQ1y1xabKVpg8XGwordduL99VepwEzeLK/st+UVfW+mKgxkf9TuxvD2fuYIDZM7y2rXqcjf4/6OXA5kACsYK1MgZSFxgO/m6+1uCC1qBDseMTA3D+Tsjf9VtcqUE9dMd/dJ/uuILHJ0+oIqkykTCecPLgJY3Vh8rAtln/lbId

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC0+xafJMnOGCHv6OLljaq8iJ3ZBaIezv7AJ9rVWJXFg/QJRYBwct35c4zaVom7If8F+Ss+BTLMp33HZ8gLpoat6LkjARjy65Ycog3NOnEposX2JjZEYXDbovxEmcJkDXAIVmnaBUi3r22z4UI8OqsHPeRXj017O0yQrQQYEAw/IO/tSNQZt2k8JHxAX50UTqGFdgkriO1fYHBocq48m0nn3sXrMuM3yBe5zy3NngOHxMn7UxjECmAElsuu/nu1x083pRnv5NSa+JxDGJ+S6Zhj3nGGNwZesa51I4cJjsYLxgmO/NxL1J86bDp6HhK9C9799ruG60pGTw6HcvbKTgx7klUgn4936wsy7qukWqp53MvqrLSJkRb/HHU9zZqvzcjbwet+Iv1OAAok5QC88j7Jgenk3nbZw4BNFd2r/8rOZuXheDnMKOa61dXxnvoAO3Euk0RPdZqW1slT/DDyD/kB6TPY7yOywNURNnrwzfSsmravKi6bGA5t2Ehhpf2LETM=

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDOyU7VvusseL2tDp7JkIXKGxRGQNHpYWVAPraUj17Xls7Z9e7HO6+GBiGP+bB9tZbzsoTNGHdXg8VaJmf98QAhhg0FcUb6IvWmfmPWzQ0MC8L+USqdDpaH7s9SOZF/yveNYCR5GOMmFdSW4OPVYIOrjPltDIe5S1SN2nOXvjxbLmuoMjg+5U4F0ii0ZaCRuMVDskeift+Amxe7iRnSzeDbECd0rJhaUb8gf3shz0Hp9lRUMej7cJH8LLP3m0s3Vk+kasKntz18MpJ6/3n+fR2aK75qkcq9FZaFA4tSIabh9eKoxlRCy7g8Qj6nNStW+ys/a1UYBFgAoTyE7e47o3dpcxR5oMLbeDwhOstWL0YOjEH1K5Wyj3eEOT71C6kuQBPcCJQ9q9hknRpW0mWe9Q6qaAzTgE9LLssijr/yTfYQk7zKEyo0i4f6buOfmyYZfnzfnCB3LiJKa98TVEEzrKYHIO44LwIkNf/YHOMDknzjYpav6HfDy+AebRHZFYhGax1YP/tP0Ve/FSq5rh6Vwuqa/zyfFUPZmZVf+EYXK7DdyuBhEZhBEu6QrjY60NRMTMLpnUZMcZXRAz9byMpAGcCYQv6gjU99ps8AkRjZNkn+FpAtDGT+oJxixQwyZMSxZ+ZuzkZGyBMeMplZXMMLICGZ2LRAgT0bxXLZUxHJBLwwnw==

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDYiP+ELuG5KTmafVjBkY0ZSggJg+mDkvZpF8d7NljMst0YwKWV3IgHnkAGXdTd7jlRgm9HH6oc8rP2R6Q8EJmfr+xcL1IQIWKuYAoddHlpe2Ds4EE74xbgm5Elf7FpdYNHUH9XyVmMmIhVSpLw2N10jUhvYqw+h+xC2nObEKZuBOt/lqrTGbC/EMv3+sDv0ApBh8lKt2yfjt88pnAj1LKPANDgIYSyQOllHQWeUY/eD/5Qc9XWR3uWclslVaxriRmEA0sNZlOFCeRIyDbYpSzQBdcnojkwt7Z5kjhaqGlT9g00fdiqO0OMaeY/G8ki3QxqjONqTEDqK+DpEZFO6jyZARcY6ki0ANc0AO4qosEC3gEbAvVwyPwDFtyDggMTHlTzaw8iakMGSDEk10zKaUOgZYLzC2yCWYYQS5mae9wC1gkXIGD51/laeq2E7NpM+nha6kp9weLVyvwf0DLfwsiP+0qlCLrxBLTSRa0HQ+BnQMi4r16Ss7YJwLf/oXrbOVk=

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDFwb7qi9/DvhpMvu43LRlTEC+3kPAA0KNeyk4FT4HlpRE/yxMxN6tgrP9vcx2c6TMfkRwIJKDcBuVVtKOVx+SDZo+nQBxpSz73v1qSmqlsy8D4gCk0a7cLgStb3Cvh0UZjJ5nVnxjzqY2CFnpnKYGmxL+a3qTj1KYPuA2wSsxkYVcHUfDj/uTtEDdRPaNTACsUxe1a57T/Tsjp+321+zKldYreozaABEBsexf9Z34+3vZvyQcfDB3QuxlBRPJBLik80QllpNpE1bqol8swoGEPbl/Ac7tNy+GtlwTG9SH1povmoT9K+8tjJaG2pD+z+vvgZQtJQh+aczYmEBJRZp3ksw1JH4eGqTWG/SDat9Isnx2NDhJe12b9izniDciuBScNySAazIDPidsCMUYjc9kgWdSOiODOtodj5IB+KazFVJgfpmzPv97LHVdjvR74usrgbFw2mYCw2YEiL3xjDYpQGmXSNklsQLwJiBe59oyS4QNpNYQzYD9StjgRIdvtmiM=

View File

@@ -3,10 +3,18 @@ inputs:
options.nixos.services.acme = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
certs = mkOption
cert = mkOption
{
type = types.listOf (types.oneOf [ types.nonEmptyStr (types.listOf types.nonEmptyStr) ]);
default = [];
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
domains = mkOption
{
type = types.nonEmptyListOf types.nonEmptyStr;
default = [ submoduleInputs.config._module.args.name ];
};
group = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
};}));
default = {};
};
};
config =
@@ -14,6 +22,7 @@ inputs:
inherit (inputs.lib) mkIf;
inherit (inputs.config.nixos.services) acme;
inherit (builtins) map listToAttrs;
inherit (inputs.localLib) attrsToList;
in mkIf acme.enable
{
security.acme =
@@ -23,16 +32,17 @@ inputs:
certs = listToAttrs (map
(cert:
{
name = if builtins.typeOf cert == "string" then cert else builtins.elemAt cert 0;
name = builtins.elemAt cert.value.domains 0;
value =
{
dnsResolver = "8.8.8.8";
dnsProvider = "cloudflare";
credentialsFile = inputs.config.sops.secrets."acme/cloudflare.ini".path;
extraDomainNames = if builtins.typeOf cert == "string" then [] else builtins.tail cert;
extraDomainNames = builtins.tail cert.value.domains;
group = mkIf (cert.value.group != null) cert.value.group;
};
})
acme.certs);
(attrsToList acme.cert));
};
sops.secrets."acme/cloudflare.ini" = {};
};

View File

@@ -0,0 +1,50 @@
inputs:
{
options.nixos.services.beesd = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
instances = mkOption
{
type = types.attrsOf (types.oneOf
[
types.nonEmptyStr
(types.submodule { options =
{
device = mkOption { type = types.nonEmptyStr; };
hashTableSizeMB = mkOption { type = types.int; };
};})
]);
default = {};
};
};
config =
let
inherit (inputs.config.nixos.services) beesd;
inherit (inputs.lib) mkIf;
inherit (builtins) map listToAttrs;
inherit (inputs.localLib) attrsToList;
in mkIf beesd.enable
{
services.beesd.filesystems = listToAttrs (map
(instance:
{
inherit (instance) name;
value =
{
spec = instance.value.device or instance.value;
hashTableSizeMB = instance.value.hashTableSizeMB or 1024;
extraOptions = [ "--thread-count" "1" "--scan-mode" "3" ];
};
})
(attrsToList beesd.instances));
systemd.slices.system-beesd.sliceConfig =
{
CPUSchedulingPolicy = "idle";
IOSchedulingClass = "idle";
IOSchedulingPriority = 4;
IOAccounting = true;
IOWeight = 1;
Nice = 19;
};
};
}

View File

@@ -25,8 +25,11 @@ inputs:
no-cli = true;
};
sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
nixos.services.acme = { enable = true; certs = [ coturn.hostname ]; };
security.acme.certs.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
nixos.services.acme =
{
enable = true;
cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
};
networking.firewall = with inputs.config.services.coturn;
{
allowedUDPPorts = [ listening-port tls-listening-port ];

View File

@@ -6,7 +6,7 @@ inputs:
./redis.nix
./rsshub.nix
./misskey.nix
./nginx.nix
./nginx
./meilisearch.nix
./xray.nix
./coturn.nix
@@ -19,27 +19,26 @@ inputs:
./sshd.nix
./vaultwarden.nix
./frp.nix
./docker.nix
./beesd.nix
./snapper.nix
./mariadb.nix
./photoprism.nix
./nextcloud.nix
./freshrss.nix
./kmscon.nix
./fontconfig.nix
./nix-serve.nix
./send.nix
./huginn.nix
./httpua
./fcgiwrap.nix
];
options.nixos.services = let inherit (inputs.lib) mkOption types; in
{
snapper =
{
enable = mkOption { type = types.bool; default = false; };
configs = mkOption { type = types.attrsOf types.nonEmptyStr; default = {}; };
};
kmscon.enable = mkOption { type = types.bool; default = false; };
fontconfig.enable = mkOption { type = types.bool; default = false; };
firewall.trustedInterfaces = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
nix-serve =
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; };
};
smartd.enable = mkOption { type = types.bool; default = false; };
fileshelter.enable = mkOption { type = types.bool; default = false; };
wallabag.enable = mkOption { type = types.bool; default = false; };
noisetorch.enable = mkOption { type = types.bool; default = inputs.config.nixos.system.gui.preferred; };
};
config =
let
@@ -49,81 +48,7 @@ inputs:
inherit (builtins) map listToAttrs toString;
in mkMerge
[
(
mkIf services.snapper.enable
{
services.snapper.configs =
let
f = (config:
{
inherit (config) name;
value =
{
SUBVOLUME = config.value;
TIMELINE_CREATE = true;
TIMELINE_CLEANUP = true;
TIMELINE_MIN_AGE = 1800;
TIMELINE_LIMIT_HOURLY = "10";
TIMELINE_LIMIT_DAILY = "7";
TIMELINE_LIMIT_WEEKLY = "1";
TIMELINE_LIMIT_MONTHLY = "0";
TIMELINE_LIMIT_YEARLY = "0";
};
});
in
listToAttrs (map f (attrsToList services.snapper.configs));
nixpkgs.config.packageOverrides = pkgs:
{
snapper = pkgs.snapper.overrideAttrs (attrs:
{
patches = (if (attrs ? patches) then attrs.patches else []) ++ [ ./snapper.patch ];
});
};
}
)
(
mkIf services.kmscon.enable
{
services.kmscon =
{
enable = true;
fonts = [{ name = "FiraCode Nerd Font Mono"; package = inputs.pkgs.nerdfonts; }];
};
}
)
(
mkIf services.fontconfig.enable
{
fonts =
{
fontDir.enable = true;
fonts = with inputs.pkgs;
[ noto-fonts source-han-sans source-han-serif source-code-pro hack-font jetbrains-mono nerdfonts ];
fontconfig.defaultFonts =
{
emoji = [ "Noto Color Emoji" ];
monospace = [ "Noto Sans Mono CJK SC" "Sarasa Mono SC" "DejaVu Sans Mono"];
sansSerif = [ "Noto Sans CJK SC" "Source Han Sans SC" "DejaVu Sans" ];
serif = [ "Noto Serif CJK SC" "Source Han Serif SC" "DejaVu Serif" ];
};
};
}
)
{ networking.firewall.trustedInterfaces = services.firewall.trustedInterfaces; }
(
mkIf services.nix-serve.enable
{
services.nix-serve =
{
enable = true;
openFirewall = true;
secretKeyFile = inputs.config.sops.secrets."store/signingKey".path;
};
sops.secrets."store/signingKey" = {};
nixos.services.nginx.httpProxy.${services.nix-serve.hostname} =
{ rewriteHttps = true; locations."/".upstream = "http://127.0.0.1:5000"; };
}
)
(mkIf services.smartd.enable { services.smartd.enable = true; })
(
mkIf services.wallabag.enable
@@ -143,11 +68,6 @@ inputs:
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
environmentFiles = [ inputs.config.sops.templates."wallabag/env".path ];
};
# systemd.services.docker-wallabag.serviceConfig =
# {
# User = "wallabag";
# Group = "wallabag";
# };
sops =
{
templates."wallabag/env".content =
@@ -171,33 +91,7 @@ inputs:
# SYMFONY__ENV__MAILER_DSN=smtp://bot%%40chn.moe@${placeholder."mail/bot-encoded"}:mail.chn.moe
# SYMFONY__ENV__FROM_EMAIL=bot@chn.moe
# SYMFONY__ENV__TWOFACTOR_SENDER=bot@chn.moe
secrets =
{
"redis/wallabag".owner = inputs.config.users.users.redis-wallabag.name;
"postgresql/wallabag" = {};
"mail/bot-encoded" = {};
};
};
services =
{
redis.servers.wallabag =
{
enable = true;
bind = null;
port = 8790;
requirePassFile = inputs.config.sops.secrets."redis/wallabag".path;
};
postgresql =
{
ensureDatabases = [ "wallabag" ];
ensureUsers =
[{
name = "wallabag";
ensurePermissions."DATABASE \"wallabag\"" = "ALL PRIVILEGES";
}];
# ALTER DATABASE db_name OWNER TO new_owner_name
# sudo docker exec -t wallabag /var/www/wallabag/bin/console wallabag:install --env=prod --no-interaction
};
secrets."mail/bot-encoded" = {};
};
nixos =
{
@@ -206,22 +100,16 @@ inputs:
nginx =
{
enable = true;
httpProxy."wallabag.chn.moe" =
{
rewriteHttps = true;
locations."/" = { upstream = "http://127.0.0.1:4398"; setHeaders.Host = "wallabag.chn.moe"; };
};
https."wallabag.chn.moe".location."/".proxy.upstream = "http://127.0.0.1:4398";
};
postgresql.enable = true;
postgresql = { enable = true; instances.wallabag = {}; };
redis.instances.wallabag = { user = "root"; port = 8790; };
};
# TODO: root docker use config of rootless docker?
virtualization.docker.enable = true;
};
# users =
# {
# users.wallabag = { isSystemUser = true; group = "wallabag"; autoSubUidGidRange = true; };
# groups.wallabag = {};
# };
}
)
(mkIf services.noisetorch.enable { programs.noisetorch.enable = true; })
];
}

View File

@@ -1,133 +0,0 @@
inputs:
{
options.nixos.services.docker = let inherit (inputs.lib) mkOption types; in mkOption
{
type = types.attrsOf (types.submodule (inputs: { options =
{
user = mkOption { type = types.nonEmptyStr; default = inputs.config._module.args.name; };
image = mkOption { type = types.package; };
imageName =
mkOption { type = types.nonEmptyStr; default = with inputs.config.image; (imageName + ":" + imageTag); };
ports = mkOption
{
type = types.listOf (types.oneOf
[
types.ints.unsigned
types.submodule (inputs: { options =
{
hostIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
hostPort = mkOption { type = types.ints.unsigned; };
containerPort = mkOption { type = types.ints.unsigned; };
protocol = mkOption { type = types.enum [ "tcp" "udp" ]; default = "tcp"; };
};})
]);
default = [];
};
environmentFile = mkOption { type = types.oneOf [ types.bool types.nonEmptyStr ]; default = false; };
};}));
default = {};
};
config =
let
inherit (inputs.lib) mkIf;
inherit (builtins) listToAttrs map concatLists;
inherit (inputs.localLib) attrsToList;
inherit (inputs.config.nixos.services) docker;
in mkIf (docker != {})
{
virtualisation.oci-containers.containers = listToAttrs (map
(container:
{
name = "${container.name}";
value =
{
image = container.value.imageName;
imageFile = container.value.image;
ports = map
(port:
(
if builtins.typeOf port == "int" then toString port
else ("${port.value.hostIp}:${toString port.value.hostPort}"
+ ":${toString port.value.containerPort}/${port.value.protocol}")
))
container.value.ports;
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
environmentFiles =
if builtins.typeOf container.value.environmentFile == "bool" && container.value.environmentFile
then [ inputs.config.sops.templates."${container.name}.env".path ]
else if builtins.typeOf container.value.environmentFile == "bool" then []
else [ container.value.environmentFile ];
};
})
(attrsToList docker));
systemd =
{
services = listToAttrs (concatLists (map
(container: let user = container.value.user; in
[
{
name = "docker-${user}-daemon";
value = let originalService = inputs.config.systemd.user.services.docker; in
{
wantedBy = [ "multi-user.target" ];
inherit (originalService) description path;
environment.XDG_RUNTIME_DIR = "/run/docker-rootless/${user}";
serviceConfig = originalService.serviceConfig //
{
User = user;
Group = user;
# AmbientCapabilities = "CAP_NET_BIND_SERVICE";
ExecStart = originalService.serviceConfig.ExecStart
+ " -H unix:///var/run/docker-rootless/${user}/docker.sock";
};
unitConfig = { inherit (originalService.unitConfig) StartLimitInterval; };
};
}
{
name = "docker-${container.name}";
value =
{
requires = [ "docker-${user}-daemon.service" ];
after = [ "docker-${user}-daemon.service" ];
environment =
{
XDG_RUNTIME_DIR = "/run/docker-rootless/${user}";
DOCKER_HOST = "unix:///run/docker-rootless/${user}/docker.sock";
};
serviceConfig =
{
User = user;
Group = user;
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
};
};
}
])
(attrsToList docker)));
tmpfiles.rules = map
(container: with container.value; "d /run/docker-rootless/${user} 0755 ${user} ${user}")
(attrsToList docker);
};
nixos.virtualization.docker.enable = true;
users =
{
users = listToAttrs (map
(container:
{
name = container.value.user;
value =
{
isSystemUser = true;
group = container.value.user;
autoSubUidGidRange = true;
home = "/run/docker-rootless/${container.value.user}";
};
})
(attrsToList docker));
groups = listToAttrs (map
(container: { name = container.value.user; value = {}; })
(attrsToList docker));
};
};
}

View File

@@ -0,0 +1,21 @@
inputs:
{
options.nixos.services.fcgiwrap = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
};
config =
let
inherit (inputs.config.nixos.services) fcgiwrap;
inherit (inputs.lib) mkIf;
in mkIf fcgiwrap.enable
{
nixos.services.nginx.enable = true;
services.fcgiwrap =
{
enable = true;
user = inputs.config.users.users.nginx.name;
group = inputs.config.users.users.nginx.group;
};
};
}

View File

@@ -0,0 +1,27 @@
inputs:
{
options.nixos.services.fontconfig = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
};
config =
let
inherit (inputs.lib) mkIf;
inherit (inputs.config.nixos.services) fontconfig;
in mkIf fontconfig.enable
{
fonts =
{
fontDir.enable = true;
fonts = with inputs.pkgs;
[ noto-fonts source-han-sans source-han-serif source-code-pro hack-font jetbrains-mono nerdfonts ];
fontconfig.defaultFonts =
{
emoji = [ "Noto Color Emoji" ];
monospace = [ "Noto Sans Mono CJK SC" "Sarasa Mono SC" "DejaVu Sans Mono"];
sansSerif = [ "Noto Sans CJK SC" "Source Han Sans SC" "DejaVu Sans" ];
serif = [ "Noto Serif CJK SC" "Source Han Serif SC" "DejaVu Serif" ];
};
};
};
}

View File

@@ -0,0 +1,60 @@
inputs:
{
options.nixos.services.freshrss = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.str; default = "freshrss.chn.moe"; };
};
config =
let
inherit (inputs.config.nixos.services) freshrss;
inherit (inputs.lib) mkIf;
in mkIf freshrss.enable
{
services.freshrss =
{
enable = true;
baseUrl = "https://${freshrss.hostname}";
defaultUser = "chn";
passwordFile = inputs.config.sops.secrets."freshrss/chn".path;
database =
{
type = "mysql";
passFile = inputs.config.sops.secrets."freshrss/db".path;
};
virtualHost = null;
};
sops.secrets =
{
"freshrss/chn".owner = inputs.config.users.users.freshrss.name;
"freshrss/db" =
{
owner = inputs.config.users.users.freshrss.name;
key = "mariadb/freshrss";
};
};
systemd.services.freshrss-config.after = [ "mysql.service" ];
nixos.services =
{
mariadb = { enable = true; instances.freshrss = {}; };
nginx.https.${freshrss.hostname} =
{
location =
{
"/".static =
{
root = "${inputs.pkgs.freshrss}/p";
index = [ "index.php" ];
tryFiles = [ "$uri" "$uri/" "$uri/index.php" ];
};
"~ ^.+?\.php(/.*)?$".php =
{
root = "${inputs.pkgs.freshrss}/p";
fastcgiPass =
"unix:${inputs.config.services.phpfpm.pools.${inputs.config.services.freshrss.pool}.socket}";
};
};
};
};
};
}

View File

@@ -1,3 +1,5 @@
# TODO: update to json config at 23.11
# TODO: switch to module in nixpkgs
inputs:
{
options.nixos.services = let inherit (inputs.lib) mkOption types; in
@@ -21,6 +23,30 @@ inputs:
}));
default = {};
};
stcp = mkOption
{
type = types.attrsOf (types.submodule (inputs:
{
options =
{
localIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
localPort = mkOption { type = types.ints.unsigned; };
};
}));
default = {};
};
stcpVisitor = mkOption
{
type = types.attrsOf (types.submodule (inputs:
{
options =
{
localIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
localPort = mkOption { type = types.ints.unsigned; };
};
}));
default = {};
};
};
frpServer =
{
@@ -31,6 +57,7 @@ inputs:
config =
let
inherit (inputs.lib) mkMerge mkIf;
inherit (inputs.lib.strings) splitString;
inherit (inputs.localLib) attrsToList;
inherit (inputs.config.nixos.services) frpClient frpServer;
inherit (builtins) map listToAttrs;
@@ -42,7 +69,7 @@ inputs:
systemd.services.frpc =
let
frpc = "${inputs.pkgs.frp}/bin/frpc";
config = inputs.config.sops.templates."frpc.ini";
config = inputs.config.sops.templates."frpc.json";
in
{
description = "Frp Client Service";
@@ -61,40 +88,58 @@ inputs:
};
sops =
{
templates."frpc.ini" =
templates."frpc.json" =
{
owner = inputs.config.users.users.frp.name;
group = inputs.config.users.users.frp.group;
content = inputs.lib.generators.toINI {}
(
{
common =
{
server_addr = frpClient.serverName;
server_port = 7000;
token = inputs.config.sops.placeholder."frp/token";
user = frpClient.user;
tls_enable = true;
};
}
// (listToAttrs (map
content = builtins.toJSON
{
auth.token = inputs.config.sops.placeholder."frp/token";
user = frpClient.user;
serverAddr = frpClient.serverName;
serverPort = 7000;
proxies =
(map
(tcp:
{
name = tcp.name;
value =
{
type = "tcp";
local_ip = tcp.value.localIp;
local_port = tcp.value.localPort;
remote_port = tcp.value.remotePort;
use_compression = true;
};
type = "tcp";
transport.useCompression = true;
inherit (tcp.value) localIp localPort remotePort;
})
(attrsToList frpClient.tcp))
)
);
++ (map
(stcp:
{
name = stcp.name;
type = "stcp";
transport.useCompression = true;
secretKey = inputs.config.sops.placeholder."frp/stcp/${stcp.name}";
inherit (stcp.value) localIp localPort;
})
(attrsToList frpClient.stcp));
visitors = map
(stcp:
{
name = stcp.name;
type = "stcp";
transport = { useCompression = true; tls.enable = true; };
secretKey = inputs.config.sops.placeholder."frp/stcp/${stcp.name}";
serverUser = builtins.elemAt (splitString "." stcp.name) 0;
serverName = builtins.elemAt (splitString "." stcp.name) 1;
bindAddr = stcp.value.localIp;
bindPort = stcp.value.localPort;
})
(attrsToList frpClient.stcpVisitor);
};
};
secrets."frp/token" = {};
secrets = listToAttrs
(
[{ name = "frp/token"; value = {}; }]
++ (map
(stcp: { name = "frp/stcp/${stcp.name}"; value = {}; })
(attrsToList (with frpClient; stcp // stcpVisitor)))
);
};
users = { users.frp = { isSystemUser = true; group = "frp"; }; groups.frp = {}; };
}
@@ -105,7 +150,7 @@ inputs:
systemd.services.frps =
let
frps = "${inputs.pkgs.frp}/bin/frps";
config = inputs.config.sops.templates."frps.ini";
config = inputs.config.sops.templates."frps.json";
in
{
description = "Frp Server Service";
@@ -124,28 +169,29 @@ inputs:
};
sops =
{
templates."frps.ini" =
templates."frps.json" =
{
owner = inputs.config.users.users.frp.name;
group = inputs.config.users.users.frp.group;
content = inputs.lib.generators.toINI {}
content = builtins.toJSON
{
common = let cert = inputs.config.security.acme.certs.${frpServer.serverName}.directory; in
auth.token = inputs.config.sops.placeholder."frp/token";
transport.tls = let cert = inputs.config.security.acme.certs.${frpServer.serverName}.directory; in
{
bind_port = 7000;
bind_udp_port = 7000;
token = inputs.config.sops.placeholder."frp/token";
tls_cert_file = "${cert}/full.pem";
tls_key_file = "${cert}/key.pem";
tls_only = true;
user_conn_timeout = 30;
force = true;
certFile = "${cert}/full.pem";
keyFile = "${cert}/key.pem";
serverName = frpServer.serverName;
};
};
};
secrets."frp/token" = {};
};
nixos.services.acme = { enable = true; certs = [ frpServer.serverName ]; };
security.acme.certs.${frpServer.serverName}.group = "frp";
nixos.services.acme =
{
enable = true;
cert.${frpServer.serverName}.group = "frp";
};
users = { users.frp = { isSystemUser = true; group = "frp"; }; groups.frp = {}; };
networking.firewall.allowedTCPPorts = [ 7000 ];
}

View File

@@ -20,6 +20,7 @@ inputs:
(user:
[
"d /var/lib/groupshare/${user} 2750 ${user} groupshare"
# TODO: auto set 'X' bit in 23.11
# systemd 253 does not support 'X' bit, it should be manually set
# sudo setfacl -m 'xxx' dir
# ("a /var/lib/groupshare/${user} - - - - "
@@ -30,7 +31,12 @@ inputs:
(mountPoint:
{
name = mountPoint;
value = { device = "/var/lib/groupshare"; options = [ "bind" ]; depends = [ "/home" "/var/lib" ]; };
value =
{
device = "/var/lib/groupshare";
options = [ "bind" "private" "x-gvfs-hide" "X-fstrim.notrim" ];
depends = [ "/home" "/var/lib" ];
};
})
groupshare.mountPoints);
};

View File

@@ -0,0 +1,25 @@
inputs:
{
options.nixos.services.httpua = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; default = "ua.chn.moe"; };
};
config =
let
inherit (inputs.config.nixos.services) httpua;
inherit (inputs.lib) mkIf;
inherit (builtins) toString;
in mkIf httpua.enable
{
nixos.services =
{
phpfpm.instances.httpua = {};
nginx.http.${httpua.hostname}.php =
{
root = toString ./.;
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpua.fastcgi;
};
};
};
}

View File

@@ -0,0 +1,25 @@
inputs:
{
options.nixos.services.httpua = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; default = "ua.chn.moe"; };
};
config =
let
inherit (inputs.config.nixos.services) httpua;
inherit (inputs.lib) mkIf;
inherit (builtins) toString;
in mkIf httpua.enable
{
nixos.services =
{
phpfpm.instances.httpua = {};
nginx.http.${httpua.hostname}.php =
{
root = toString ./.;
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpua.fastcgi;
};
};
};
}

View File

@@ -0,0 +1 @@
<?php echo $_SERVER['HTTP_USER_AGENT']; ?>

View File

@@ -3,56 +3,65 @@ inputs:
options.nixos.services.huginn = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; default = "huginn.chn.moe"; };
};
config =
let
inherit (inputs.lib) mkIf;
inherit (inputs.config.nixos.services) huginn;
inherit (builtins) listToAttrs;
in mkIf huginn.enable
{
nixos.services =
virtualisation.oci-containers.containers.huginn =
{
docker.huginn =
image = "huginn/huginn:2d5fcafc507da3e8c115c3479e9116a0758c5375";
imageFile = inputs.pkgs.dockerTools.pullImage
{
image = inputs.pkgs.dockerTools.pullImage
{
imageName = "huginn/huginn";
imageDigest = "sha256:dbe871597d43232add81d1adfc5ad9f5cf9dcb5e1f1ba3d669598c20b96ab6c1";
sha256 = "sha256-P8bfzjW5gHCVv0kaEAi9xAe5c0aQXypJkYUfFtE8SVM=";
finalImageName = "huginn/huginn";
finalImageTag = "2d5fcafc507da3e8c115c3479e9116a0758c5375";
};
ports = [ 3000 ];
environmentFile = true;
imageName = "ghcr.io/huginn/huginn";
imageDigest = "sha256:aa694519b196485c6c31582dde007859fc8b8bbe9b1d4d94c6db8558843d0458";
sha256 = "0471v20d7ilwx81kyrxjcb90nnmqyyi9mwazbpy3z4rhnzv7pz76";
finalImageName = "huginn/huginn";
finalImageTag = "2d5fcafc507da3e8c115c3479e9116a0758c5375";
};
postgresql = { enable = true; instances.huginn = {}; };
ports = [ "127.0.0.1:3000:3000/tcp" ];
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
environmentFiles = [ inputs.config.sops.templates."huginn/env".path ];
};
sops =
{
templates."huginn.env" =
templates."huginn/env".content = let placeholder = inputs.config.sops.placeholder; in
''
MYSQL_PORT_3306_TCP_ADDR=host.docker.internal
HUGINN_DATABASE_NAME=huginn
HUGINN_DATABASE_USERNAME=huginn
HUGINN_DATABASE_PASSWORD=${placeholder."mariadb/huginn"}
DOMAIN=${huginn.hostname}
RAILS_ENV=production
FORCE_SSL=true
INVITATION_CODE=${placeholder."huginn/invitationCode"}
SMTP_DOMAIN=mail.chn.moe
SMTP_USER_NAME=bot@chn.moe
SMTP_PASSWORD="${placeholder."mail/bot"}"
SMTP_SERVER=mail.chn.moe
SMTP_SSL=true
EMAIL_FROM_ADDRESS=bot@chn.moe
TIMEZONE=Beijing
DO_NOT_CREATE_DATABASE=true
'';
secrets = { "huginn/invitationCode" = {}; "mail/bot" = {}; };
};
nixos =
{
services =
{
content = let placeholder = inputs.config.sops.placeholder; in
''
MYSQL_PORT_3306_TCP_ADDR=host.docker.internal
HUGINN_DATABASE_NAME=huginn
HUGINN_DATABASE_USERNAME=huginn
HUGINN_DATABASE_PASSWORD=${placeholder."postgresql/huginn"}
DOMAIN=huginn.chn.moe
RAILS_ENV=production
FORCE_SSL=true
INVITATION_CODE=${placeholder."huginn/invitation_code"}
SMTP_DOMAIN=mail.chn.moe
SMTP_USER_NAME=bot@chn.moe
SMTP_PASSWORD="${placeholder."mail/bot"}"
SMTP_SERVER=mail.chn.moe
SMTP_SSL=true
EMAIL_FROM_ADDRESS=bot@chn.moe
TIMEZONE=Beijing
'';
owner = inputs.config.users.users.huginn.name;
nginx =
{
enable = true;
https."${huginn.hostname}".location."/".proxy = { upstream = "http://127.0.0.1:3000"; websocket = true; };
};
mariadb.instances.huginn = {};
};
secrets = listToAttrs (map (secret: { name = secret; value = {}; }) [ "huginn/invitation_code" "mail/bot" ]);
# TODO: root docker use config of rootless docker?
virtualization.docker.enable = true;
};
};
}

View File

@@ -0,0 +1,19 @@
inputs:
{
options.nixos.services.kmscon = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
};
config =
let
inherit (inputs.lib) mkIf;
inherit (inputs.config.nixos.services) kmscon;
in mkIf kmscon.enable
{
services.kmscon =
{
enable = true;
fonts = [{ name = "FiraCode Nerd Font Mono"; package = inputs.pkgs.nerdfonts; }];
};
};
}

View File

@@ -0,0 +1,63 @@
inputs:
{
options.nixos.services.mariadb = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
instances = mkOption
{
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
database = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
user = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
passwordFile = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
};}));
default = {};
};
};
config =
let
inherit (inputs.config.nixos.services) mariadb;
inherit (inputs.lib) mkAfter mkIf;
inherit (inputs.localLib) attrsToList;
inherit (builtins) map listToAttrs concatStringsSep filter;
in mkIf mariadb.enable
{
services =
{
mysql =
{
enable = true;
package = inputs.pkgs.mariadb;
settings.mysqld.skip_name_resolve = true;
ensureDatabases = map (db: db.value.database) (attrsToList mariadb.instances);
ensureUsers = map
(db:
{
name = db.value.user;
ensurePermissions."${db.value.database}.*" = "ALL PRIVILEGES";
})
(attrsToList mariadb.instances);
};
mysqlBackup =
{
enable = true;
singleTransaction = true;
databases = map (db: db.value.database) (attrsToList mariadb.instances);
};
};
systemd.services.mysql.postStart = mkAfter (concatStringsSep "\n" (map
(db:
let
passwordFile =
if db.value.passwordFile or null != null then db.value.passwordFile
else inputs.config.sops.secrets."mariadb/${db.value.user}".path;
mysql = "${inputs.config.services.mysql.package}/bin/mysql";
in
# force user use password auth
''echo "ALTER USER '${db.value.user}' IDENTIFIED BY '$(cat ${passwordFile})';" | ${mysql} -N'')
(attrsToList mariadb.instances)));
sops.secrets = listToAttrs (map
(db: { name = "mariadb/${db.value.user}"; value.owner = inputs.config.users.users.mysql.name; })
(filter (db: db.value.passwordFile == null) (attrsToList mariadb.instances)));
};
}

View File

@@ -11,6 +11,7 @@ inputs:
};}));
default = {};
};
ioLimitDevice = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
};
config =
let
@@ -60,7 +61,15 @@ inputs:
IOWeight = 1;
Nice = 19;
Slice = "-.slice";
};
}
// (if meilisearch.ioLimitDevice != null then
{
IOReadBandwidthMax = "${meilisearch.ioLimitDevice} 20M";
IOWriteBandwidthMax = "${meilisearch.ioLimitDevice} 20M";
# iostat -dx 1
IOReadIOPSMax = "${meilisearch.ioLimitDevice} 100";
IOWriteIOPSMax = "${meilisearch.ioLimitDevice} 100";
} else {});
};
})
(attrsToList meilisearch.instances));
@@ -89,10 +98,10 @@ inputs:
env = "production"
dump_dir = "/var/lib/meilisearch/${instance.name}/dumps"
log_level = "INFO"
max_indexing_memory = "8Gb"
max_indexing_memory = "16Gb"
max_indexing_threads = 1
'';
owner = inputs.config.users.users.misskey.name;
owner = instance.value.user;
};
})
(attrsToList meilisearch.instances));

View File

@@ -1,157 +1,176 @@
inputs:
{
options.nixos.services = let inherit (inputs.lib) mkOption types; in
options.nixos.services.misskey.instances = let inherit (inputs.lib) mkOption types; in mkOption
{
misskey =
type = types.attrsOf (types.submodule { options =
{
enable = mkOption { type = types.bool; default = false; };
autoStart = mkOption { type = types.bool; default = true; };
port = mkOption { type = types.ints.unsigned; default = 9726; };
hostname = mkOption { type = types.str; default = "misskey.chn.moe"; };
};
misskey-proxy = mkOption
{
type = types.attrsOf (types.submodule (submoduleInputs: { options =
redis.port = mkOption { type = types.ints.unsigned; default = 3545; };
hostname = mkOption { type = types.nonEmptyStr; default = "misskey.chn.moe"; };
meilisearch =
{
hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
upstream = mkOption
{
type = types.oneOf [ types.nonEmptyStr (types.submodule { options =
{
address = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
port = mkOption { type = types.ints.unsigned; default = 9726; };
};})];
default = "127.0.0.1:9726";
};
};}));
default = {};
};
enable = mkOption { type = types.bool; default = true; };
port = mkOption { type = types.ints.unsigned; default = 7700; };
};
};});
default = {};
};
config =
let
inherit (inputs.config.nixos.services) misskey misskey-proxy;
inherit (inputs.localLib) stripeTabs attrsToList;
inherit (inputs.lib) mkIf mkMerge;
inherit (builtins) map listToAttrs toString replaceStrings;
in mkMerge
[
(mkIf misskey.enable
{
systemd =
inherit (inputs.config.nixos.services) misskey;
inherit (inputs.localLib) attrsToList;
inherit (inputs.lib) mkMerge mkIf;
inherit (builtins) map listToAttrs toString replaceStrings filter;
in
{
systemd = mkMerge (map
(instance:
{
services.misskey =
services."misskey-${instance.name}" = rec
{
description = "misskey";
after = [ "network.target" "redis-misskey.service" "postgresql.service" "meilisearch-misskey.service" ];
requires = [ "network.target" "redis-misskey.service" "postgresql.service" "meilisearch-misskey.service" ];
enable = instance.value.autoStart;
description = "misskey ${instance.name}";
after = [ "network.target" "redis-misskey-${instance.name}.service" "postgresql.service" ]
++ (if instance.value.meilisearch.enable then [ "meilisearch-misskey-${instance.name}.service" ]
else []);
requires = after;
wantedBy = [ "multi-user.target" ];
environment.MISSKEY_CONFIG_YML = inputs.config.sops.templates."misskey/default.yml".path;
environment.MISSKEY_CONFIG_YML = inputs.config.sops.templates."misskey/${instance.name}.yml".path;
serviceConfig = rec
{
User = inputs.config.users.users.misskey.name;
Group = inputs.config.users.users.misskey.group;
WorkingDirectory = "/var/lib/misskey/work";
User = inputs.config.users.users."misskey-${instance.name}".name;
Group = inputs.config.users.users."misskey-${instance.name}".group;
WorkingDirectory = "/var/lib/misskey/${instance.name}/work";
ExecStart = "${WorkingDirectory}/bin/misskey";
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
Restart = "always";
RuntimeMaxSec = "1d";
};
};
tmpfiles.rules = [ "d /var/lib/misskey/files 0700 misskey misskey" ];
};
fileSystems =
tmpfiles.rules =
[ "d /var/lib/misskey/${instance.name}/files 0700 misskey-${instance.name} misskey-${instance.name}" ];
})
(attrsToList misskey.instances));
fileSystems = mkMerge (map
(instance:
{
"/var/lib/misskey/work" =
"/var/lib/misskey/${instance.name}/work" =
{
device = "${inputs.pkgs.localPackages.misskey}";
options = [ "bind" "private" "x-gvfs-hide" ];
options = [ "bind" "private" "x-gvfs-hide" "X-fstrim.notrim" ];
};
"/var/lib/misskey/work/files" =
"/var/lib/misskey/${instance.name}/work/files" =
{
device = "/var/lib/misskey/files";
options = [ "bind" "private" "x-gvfs-hide" ];
device = "/var/lib/misskey/${instance.name}/files";
options = [ "bind" "private" "x-gvfs-hide" "X-fstrim.notrim" ];
};
};
sops.templates."misskey/default.yml" =
})
(attrsToList misskey.instances));
sops.templates = listToAttrs (map
(instance:
{
content =
let
placeholder = inputs.config.sops.placeholder;
misskey = inputs.config.nixos.services.misskey;
redis = inputs.config.nixos.services.redis.instances.misskey;
in
''
url: https://${misskey.hostname}/
port: ${toString misskey.port}
db:
host: 127.0.0.1
port: 5432
db: misskey
user: misskey
pass: ${placeholder."postgresql/misskey"}
extra:
statement_timeout: 60000
dbReplications: false
redis:
host: 127.0.0.1
port: ${toString redis.port}
pass: ${placeholder."redis/misskey"}
meilisearch:
host: 127.0.0.1
port: 7700
apiKey: ${placeholder."meilisearch/misskey"}
ssl: false
index: misskey
scope: global
id: 'aid'
proxyBypassHosts:
- api.deepl.com
- api-free.deepl.com
- www.recaptcha.net
- hcaptcha.com
- challenges.cloudflare.com
proxyRemoteFiles: true
signToActivityPubGet: true
maxFileSize: 1073741824
'';
owner = inputs.config.users.users.misskey.name;
};
users =
name = "misskey/${instance.name}.yml";
value =
{
content =
let
placeholder = inputs.config.sops.placeholder;
redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}";
meilisearch = inputs.config.nixos.services.meilisearch.instances."misskey-${instance.name}";
in
''
url: https://${instance.value.hostname}/
port: ${toString instance.value.port}
db:
host: 127.0.0.1
port: 5432
db: misskey_${replaceStrings [ "-" ] [ "_" ] instance.name}
user: misskey_${replaceStrings [ "-" ] [ "_" ] instance.name}
pass: ${placeholder."postgresql/misskey_${replaceStrings [ "-" ] [ "_" ] instance.name}"}
extra:
statement_timeout: 60000
dbReplications: false
redis:
host: 127.0.0.1
port: ${toString redis.port}
pass: ${placeholder."redis/misskey-${instance.name}"}
id: 'aid'
proxyBypassHosts:
- api.deepl.com
- api-free.deepl.com
- www.recaptcha.net
- hcaptcha.com
- challenges.cloudflare.com
proxyRemoteFiles: true
signToActivityPubGet: true
maxFileSize: 1073741824
''
+ (if instance.value.meilisearch.enable then
''
meilisearch:
host: 127.0.0.1
port: ${toString meilisearch.port}
apiKey: ${placeholder."meilisearch/misskey-${instance.name}"}
ssl: false
index: misskey
scope: globa
'' else "");
owner = inputs.config.users.users."misskey-${instance.name}".name;
};
})
(attrsToList misskey.instances));
users = mkMerge (map
(instance:
{
users.misskey = { isSystemUser = true; group = "misskey"; home = "/var/lib/misskey"; createHome = true; };
groups.misskey = {};
};
nixos.services =
{
redis.instances.misskey.port = 3545;
postgresql = { enable = true; instances.misskey = {}; };
meilisearch.instances.misskey = { user = inputs.config.users.users.misskey.name; port = 7700; };
};
})
(mkIf (misskey-proxy != {})
users."misskey-${instance.name}" =
{
isSystemUser = true;
group = "misskey-${instance.name}";
home = "/var/lib/misskey/${instance.name}";
createHome = true;
};
groups."misskey-${instance.name}" = {};
})
(attrsToList misskey.instances));
nixos.services =
{
nixos.services.nginx =
redis.instances = listToAttrs (map
(instance:
{
name = "misskey-${instance.name}";
value.port = instance.value.redis.port;
})
(attrsToList misskey.instances));
postgresql =
{
enable = true;
httpProxy = listToAttrs (map
(proxy: with proxy.value;
enable = mkIf (misskey.instances != {}) true;
instances = listToAttrs (map
(instance: { name = "misskey_${replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
(attrsToList misskey.instances));
};
meilisearch.instances = listToAttrs (map
(instance:
{
name = "misskey-${instance.name}";
value =
{
user = inputs.config.users.users."misskey-${instance.name}".name;
port = instance.value.meilisearch.port;
};
})
(filter (instance: instance.value.meilisearch.enable) (attrsToList misskey.instances)));
nginx =
{
enable = mkIf (misskey.instances != {}) true;
https = listToAttrs (map
(instance: with instance.value;
{
name = hostname;
value =
{
rewriteHttps = true;
locations."/" =
{
upstream = if builtins.typeOf upstream == "string" then "http://${upstream}"
else "http://${upstream.address}:${toString upstream.port}";
websocket = true;
setHeaders.Host = hostname;
};
};
value.location."/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
})
(attrsToList misskey-proxy));
(attrsToList misskey.instances));
};
})
];
};
};
}

View File

@@ -0,0 +1,94 @@
inputs:
{
options.nixos.services.nextcloud = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; default = "nextcloud.chn.moe"; };
};
config =
let
inherit (inputs.config.nixos.services) nextcloud;
inherit (inputs.localLib) attrsToList;
inherit (inputs.lib) mkIf mkMerge;
inherit (builtins) map listToAttrs toString replaceStrings filter toJSON;
in mkIf nextcloud.enable
{
services.nextcloud =
{
enable = true;
hostName = nextcloud.hostname;
appstoreEnable = false;
https = true;
package = inputs.pkgs.nextcloud27;
maxUploadSize = "10G";
config =
{
dbtype = "pgsql";
dbpassFile = inputs.config.sops.secrets."nextcloud/postgresql".path;
dbport = 5432;
adminuser = "admin";
adminpassFile = inputs.config.sops.secrets."nextcloud/admin".path;
overwriteProtocol = "https";
defaultPhoneRegion = "CN";
};
configureRedis = true;
extraOptions =
{
mail_domain = "chn.moe";
mail_from_address = "bot";
mail_smtphost = "mail.chn.moe";
mail_smtpport = 465;
mail_smtpsecure = "ssl";
mail_smtpauth = true;
mail_smtpname = "bot@chn.moe";
updatechecker = false;
};
secretFile = inputs.config.sops.templates."nextcloud/secret".path;
extraApps =
{
maps = inputs.pkgs.fetchNextcloudApp
{
url = "https://github.com/nextcloud/maps/releases/download/v1.1.1/maps-1.1.1.tar.gz";
sha256 = "1rcmqnm5364h5gaq1yy6b6d7k17napgn0yc9ymrnn75bps9s71v9";
};
phonetrack = inputs.pkgs.fetchNextcloudApp
{
url = "https://github.com/julien-nc/phonetrack/releases/download/v0.7.6/phonetrack-0.7.6.tar.gz";
sha256 = "1p15vw7c5c1h08czyxi1r6svjd5hjmnc0i6is4vl3xq2kfjmcyyx";
};
twofactor_webauthn = inputs.pkgs.fetchNextcloudApp
{
url = "https://github.com/nextcloud-releases/twofactor_webauthn/releases/download/v1.2.0/twofactor_webauthn-v1.2.0.tar.gz";
sha256 = "1lqcw74rsnl8c4sirw9208ra3c8zl8zp93scs7y8fv2n4n60l465";
};
};
};
nixos.services =
{
postgresql = { enable = true; instances.nextcloud = {}; };
redis.instances.nextcloud.port = 3499;
nginx =
{
enable = true;
https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
};
};
sops =
{
templates."nextcloud/secret" =
{
content = toJSON
{
redis.password = inputs.config.sops.placeholder."redis/nextcloud";
mail_smtppassword = inputs.config.sops.placeholder."mail/bot";
};
owner = inputs.config.users.users.nextcloud.name;
};
secrets =
{
"nextcloud/postgresql" = { key = "postgresql/nextcloud"; owner = inputs.config.users.users.nextcloud.name; };
"nextcloud/admin".owner = inputs.config.users.users.nextcloud.name;
};
};
};
}

View File

@@ -1,338 +0,0 @@
inputs:
{
options.nixos.services.nginx = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
transparentProxy =
{
enable = mkOption { type = types.bool; default = true; };
externalIp = mkOption { type = types.nonEmptyStr; };
map = mkOption { type = types.attrsOf types.ints.unsigned; default = {};};
};
httpProxy = mkOption
{
type = types.attrsOf (types.submodule { options =
{
rewriteHttps = mkOption { type = types.bool; default = false; };
http2 = mkOption { type = types.bool; default = true; };
addAuth = mkOption { type = types.bool; default = false; };
detectAuth = mkOption { type = types.bool; default = false; };
locations = mkOption
{
type = types.attrsOf (types.submodule { options =
{
upstream = mkOption { type = types.nonEmptyStr; };
websocket = mkOption { type = types.bool; default = false; };
setHeaders = mkOption { type = types.attrsOf types.str; default = {}; };
};});
};
};});
default = {};
};
streamProxy =
{
enable = mkOption { type = types.bool; default = false; };
port = mkOption { type = types.ints.unsigned; default = 5575; };
map = mkOption
{
type = types.attrsOf (types.oneOf
[
types.nonEmptyStr
(types.submodule { options =
{
upstream = mkOption { type = types.nonEmptyStr; };
rewriteHttps = mkOption { type = types.bool; default = false; };
};})
]);
default = {};
};
};
};
config =
let
inherit (inputs.lib) mkMerge mkIf;
inherit (inputs.localLib) stripeTabs attrsToList;
inherit (inputs.config.nixos.services) nginx;
inherit (builtins) map listToAttrs concatStringsSep toString filter attrValues;
in mkMerge
[
(mkIf nginx.enable
{
services =
{
nginx =
{
enable = true;
enableReload = true;
eventsConfig =
''
worker_connections 524288;
use epoll;
'';
commonHttpConfig =
''
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}
log_format http '[$time_local] $remote_addr-$geoip2_data_country_code "$host"'
' $request_length $bytes_sent $status "$request" referer: "$http_referer" ua: "$http_user_agent"';
access_log syslog:server=unix:/dev/log http;
proxy_ssl_server_name on;
proxy_ssl_session_reuse off;
send_timeout 10m;
'';
proxyTimeout = "10m";
virtualHosts = listToAttrs (map
(site:
{
inherit (site) name;
value =
{
serverName = site.name;
listen = [ { addr = "127.0.0.1"; port = (if site.value.http2 then 443 else 3065); ssl = true; } ]
++ (if site.value.rewriteHttps then [ { addr = "0.0.0.0"; port = 80; } ] else []);
useACMEHost = site.name;
locations = listToAttrs (map
(location:
{
inherit (location) name;
value =
{
proxyPass = location.value.upstream;
proxyWebsockets = location.value.websocket;
recommendedProxySettings = false;
recommendedProxySettingsNoHost = true;
extraConfig = concatStringsSep "\n"
(
(map
(header: ''proxy_set_header ${header.name} "${header.value}";'')
(attrsToList location.value.setHeaders))
++ (if site.value.detectAuth then ["proxy_hide_header Authorization;"] else [])
++ (
if site.value.addAuth then
["include ${inputs.config.sops.templates."nginx/addAuth/${site.name}-template".path};"]
else [])
);
};
})
(attrsToList site.value.locations));
forceSSL = site.value.rewriteHttps;
http2 = site.value.http2;
basicAuthFile =
if site.value.detectAuth then inputs.config.sops.secrets."nginx/detectAuth/${site.name}".path
else null;
};
})
(attrsToList nginx.httpProxy));
recommendedZstdSettings = true;
recommendedTlsSettings = true;
recommendedProxySettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedBrotliSettings = true;
clientMaxBodySize = "0";
package =
let
nginx-geoip2 =
{
name = "ngx_http_geoip2_module";
src = inputs.pkgs.fetchFromGitHub
{
owner = "leev";
repo = "ngx_http_geoip2_module";
rev = "a607a41a8115fecfc05b5c283c81532a3d605425";
hash = "sha256-CkmaeEa1iEAabJEDu3FhBUR7QF38koGYlyx+pyKZV9Y=";
};
meta.license = [];
};
in
(inputs.pkgs.nginxMainline.override (prev: { modules = prev.modules ++ [ nginx-geoip2 ]; }))
.overrideAttrs (prev: { buildInputs = prev.buildInputs ++ [ inputs.pkgs.libmaxminddb ]; });
streamConfig =
''
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb
{
$geoip2_data_country_code country iso_code;
}
resolver 8.8.8.8;
'';
# todo: use host dns
resolver.addresses = [ "8.8.8.8" ];
};
geoipupdate =
{
enable = true;
settings =
{
AccountID = 901296;
LicenseKey = inputs.config.sops.secrets."nginx/maxmind-license".path;
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
};
};
};
sops =
{
templates = listToAttrs (map
(site:
{
name = "nginx/addAuth/${site.name}-template";
value =
{
content =
let placeholder = inputs.config.sops.placeholder."nginx/addAuth/${site.name}";
in ''proxy_set_header Authorization "Basic ${placeholder}";'';
owner = inputs.config.users.users.nginx.name;
};
})
(filter (site: site.value.addAuth) (attrsToList nginx.httpProxy)));
secrets = { "nginx/maxmind-license".owner = inputs.config.users.users.nginx.name; }
// (listToAttrs (map
(site: { name = "nginx/detectAuth/${site.name}"; value.owner = inputs.config.users.users.nginx.name; })
(filter (site: site.value.detectAuth) (attrsToList nginx.httpProxy))))
// (listToAttrs (map
(site: { name = "nginx/addAuth/${site.name}"; value = {}; })
(filter (site: site.value.addAuth) (attrsToList nginx.httpProxy))));
};
systemd.services.nginx.serviceConfig =
{
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
LimitNPROC = 65536;
LimitNOFILE = 524288;
};
nixos.services.acme =
{
enable = true;
certs = map (cert: cert.name) (attrsToList nginx.httpProxy);
};
security.acme.certs = listToAttrs (map
(cert: { inherit (cert) name; value.group = inputs.config.services.nginx.group; })
(attrsToList nginx.httpProxy));
})
(mkIf nginx.transparentProxy.enable
{
services.nginx.streamConfig =
''
log_format transparent_proxy '[$time_local] $remote_addr-$geoip2_data_country_code '
'"$ssl_preread_server_name"->$transparent_proxy_backend $bytes_sent $bytes_received';
map $ssl_preread_server_name $transparent_proxy_backend
{
${concatStringsSep "\n" (map
(x: '' "${x.name}" 127.0.0.1:${toString x.value};'')
(
(attrsToList nginx.transparentProxy.map)
++ (map
(site: { name = site.name; value = (if site.value.http2 then 443 else 3065); })
(attrsToList nginx.httpProxy)
)
))}
default 127.0.0.1:443;
}
server
{
listen ${nginx.transparentProxy.externalIp}:443;
ssl_preread on;
proxy_bind $remote_addr transparent;
proxy_pass $transparent_proxy_backend;
proxy_connect_timeout 1s;
proxy_socket_keepalive on;
proxy_buffer_size 128k;
access_log syslog:server=unix:/dev/log transparent_proxy;
}
'';
networking.firewall.allowedTCPPorts = [ 80 443 ];
systemd.services.nginx-proxy =
let
ipset = "${inputs.pkgs.ipset}/bin/ipset";
iptables = "${inputs.pkgs.iptables}/bin/iptables";
ip = "${inputs.pkgs.iproute}/bin/ip";
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
(
''
${ipset} create nginx_proxy_port bitmap:port range 0-65535
${iptables} -t mangle -N nginx_proxy_mark
${iptables} -t mangle -A OUTPUT -j nginx_proxy_mark
${iptables} -t mangle -A nginx_proxy_mark -s 127.0.0.1 -p tcp \
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
${iptables} -t mangle -N nginx_proxy
${iptables} -t mangle -A PREROUTING -j nginx_proxy
${iptables} -t mangle -A nginx_proxy -s 127.0.0.1 -p tcp \
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
${ip} rule add fwmark 2/2 table 200
${ip} route add local 0.0.0.0/0 dev lo table 200
''
+ concatStringsSep "\n" (map
(port: ''${ipset} add nginx_proxy_port ${toString port}'')
(inputs.lib.unique ((attrValues nginx.transparentProxy.map) ++ [ 443 3065 ])))
);
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
''
${iptables} -t mangle -F nginx_proxy_mark
${iptables} -t mangle -D OUTPUT -j nginx_proxy_mark
${iptables} -t mangle -X nginx_proxy_mark
${iptables} -t mangle -F nginx_proxy
${iptables} -t mangle -D PREROUTING -j nginx_proxy
${iptables} -t mangle -X nginx_proxy
${ip} rule del fwmark 2/2 table 200
${ip} route del local 0.0.0.0/0 dev lo table 200
${ipset} destroy nginx_proxy_port
'';
in
{
description = "nginx transparent proxy";
after = [ "network.target" ];
serviceConfig =
{
Type = "simple";
RemainAfterExit = true;
ExecStart = start;
ExecStop = stop;
};
wants = [ "network.target" ];
wantedBy= [ "multi-user.target" ];
};
})
(mkIf nginx.streamProxy.enable
{
services.nginx =
{
streamConfig =
''
log_format stream_proxy '[$time_local] $remote_addr-$geoip2_data_country_code '
'"$ssl_preread_server_name"->$stream_proxy_backend $bytes_sent $bytes_received';
map $ssl_preread_server_name $stream_proxy_backend
{
${concatStringsSep "\n" (map
(x: '' "${x.name}" "${x.value.upstream or x.value}";'')
(attrsToList nginx.streamProxy.map))}
}
server
{
listen 127.0.0.1:${toString nginx.streamProxy.port};
ssl_preread on;
proxy_pass $stream_proxy_backend;
proxy_connect_timeout 10s;
proxy_socket_keepalive on;
proxy_buffer_size 128k;
access_log syslog:server=unix:/dev/log stream_proxy;
}
'';
virtualHosts = listToAttrs (map
(site:
{
inherit (site) name;
value =
{
serverName = site.name;
listen = [ { addr = "0.0.0.0"; port = 80; } ];
locations."/".return = "301 https://${site.name}$request_uri";
};
})
(filter (site: site.value.rewriteHttps or false) (attrsToList nginx.streamProxy.map)));
};
nixos.services.nginx.transparentProxy.map = listToAttrs (map
(site: { name = site.name; value = nginx.streamProxy.port; })
(attrsToList nginx.streamProxy.map));
})
];
}

View File

@@ -0,0 +1,8 @@
inputs:
{
imports = inputs.localLib.mkModules
[
./element.nix
./synapse-admin.nix
];
}

View File

@@ -0,0 +1,37 @@
inputs:
{
options.nixos.services.nginx.applications.element.instances = let inherit (inputs.lib) mkOption types; in mkOption
{
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
defaultServer = mkOption { type = types.nullOr types.nonEmptyStr; default = "element.chn.moe"; };
};}));
default = {};
};
config =
let
inherit (inputs.config.nixos.services.nginx.applications.element) instances;
inherit (inputs.localLib) attrsToList;
inherit (builtins) map listToAttrs toString;
in
{
nixos.services.nginx.https = listToAttrs (map
(instance: with instance.value;
{
name = hostname;
value.location."/".static.root =
if defaultServer == null then toString inputs.pkgs.element-web
else toString (inputs.pkgs.element-web.override { conf =
{
default_server_config."m.homeserver" =
{
base_url = "https://${defaultServer}";
server_name = defaultServer;
};
disable_guests = false;
};});
})
(attrsToList instances));
};
}

View File

@@ -0,0 +1,25 @@
inputs:
{
options.nixos.services.nginx.applications.synapse-admin.instances =
let inherit (inputs.lib) mkOption types; in mkOption
{
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{ hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; }; };}));
default = {};
};
config =
let
inherit (inputs.config.nixos.services.nginx.applications.synapse-admin) instances;
inherit (inputs.localLib) attrsToList;
inherit (builtins) map listToAttrs;
in
{
nixos.services.nginx.https = listToAttrs (map
(site: with site.value;
{
name = hostname;
value.location."/".static.root = "${inputs.pkgs.synapse-admin}";
})
(attrsToList instances));
};
}

View File

@@ -0,0 +1,763 @@
inputs:
{
imports = inputs.localLib.mkModules
[
./applications
];
options.nixos.services.nginx = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
# transparentProxy -> https(with proxyProtocol) or transparentProxy -> streamProxy -> https(with proxyProtocol)
# https without proxyProtocol listen on private ip, with proxyProtocol listen on all ip
# streamProxy listen on private ip
# transparentProxy listen on public ip
global = mkOption
{
type = types.anything;
readOnly = true;
default =
{
httpsPort = 3065;
httpsPortShift = { http2 = 1; proxyProtocol = 2; };
httpsLocationTypes = [ "proxy" "static" "php" "return" "cgi" ];
httpTypes = [ "rewriteHttps" "php" ];
streamPort = 5575;
streamPortShift = { proxyProtocol = 1; };
};
};
transparentProxy =
{
# only disable in some rare cases
enable = mkOption { type = types.bool; default = true; };
externalIp = mkOption { type = types.listOf types.nonEmptyStr; };
# proxy to 127.0.0.1:${specified port}
map = mkOption { type = types.attrsOf types.ints.unsigned; default = {}; };
};
streamProxy =
{
map = mkOption
{
type = types.attrsOf (types.oneOf
[
# proxy to specified ip:port without proxyProtocol
types.nonEmptyStr
(types.submodule { options =
{
upstream = mkOption
{
type = types.oneOf
[
# proxy to specified ip:port with or without proxyProtocol
types.nonEmptyStr
(types.submodule { options =
{
address = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
# if port not specified, guess from proxyProtocol enabled or not, assume http2 enabled
port = mkOption { type = types.nullOr types.ints.unsigned; default = null; };
};})
];
default = {};
};
proxyProtocol = mkOption { type = types.bool; default = true; };
addToTransparentProxy = mkOption { type = types.bool; default = true; };
rewriteHttps = mkOption { type = types.bool; default = true; };
};})
]);
default = {};
};
};
https = mkOption
{
type = types.attrsOf (types.submodule (siteSubmoduleInputs: { options =
{
global =
{
configName = mkOption
{
type = types.nonEmptyStr;
default = "https:${siteSubmoduleInputs.config._module.args.name}";
};
root = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
index = mkOption { type = types.nullOr (types.nonEmptyListOf types.nonEmptyStr); default = null; };
detectAuth = mkOption
{
type = types.nullOr (types.submodule { options =
{
text = mkOption { type = types.nonEmptyStr; default = "Restricted Content"; };
users = types.nonEmptyListOf types.nonEmptyStr;
};});
default = null;
};
rewriteHttps = mkOption { type = types.bool; default = true; };
};
listen = mkOption
{
type = types.attrsOf (types.submodule { options =
{
http2 = mkOption { type = types.bool; default = true; };
proxyProtocol = mkOption { type = types.bool; default = true; };
# if proxyProtocol not enabled, add to transparentProxy only
# if proxyProtocol enabled, add to transparentProxy and streamProxy
addToTransparentProxy = mkOption { type = types.bool; default = true; };
};});
default.main = {};
};
location = mkOption
{
type = types.attrsOf (types.submodule { options =
let
genericOptions =
{
# should be set to non null value if global root is null
root = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
# htpasswd -n username
detectAuth = mkOption
{
type = types.nullOr (types.submodule { options =
{
text = mkOption { type = types.nonEmptyStr; default = "Restricted Content"; };
users = types.nonEmptyListOf types.nonEmptyStr;
};});
default = null;
};
};
in
{
# only one should be specified
proxy = mkOption
{
type = types.nullOr (types.submodule { options =
{
inherit (genericOptions) detectAuth;
upstream = mkOption { type = types.nonEmptyStr; };
websocket = mkOption { type = types.bool; default = false; };
setHeaders = mkOption
{
type = types.attrsOf types.str;
default.Host = siteSubmoduleInputs.config._module.args.name;
};
# echo -n "username:password" | base64
addAuth = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
};});
default = null;
};
static = mkOption
{
type = types.nullOr (types.submodule { options =
{
inherit (genericOptions) detectAuth root;
index = mkOption { type = types.listOf types.nonEmptyStr; default = [ "index.html" ]; };
tryFiles = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
};});
default = null;
};
php = mkOption
{
type = types.nullOr (types.submodule { options =
{
inherit (genericOptions) detectAuth root;
fastcgiPass = mkOption { type = types.nonEmptyStr; };
};});
default = null;
};
return.return = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
cgi = mkOption
{
type = types.nullOr (types.submodule { options =
{
inherit (genericOptions) detectAuth root;
};});
default = null;
};
};});
default = {};
};
};}));
default = {};
};
http = mkOption
{
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
rewriteHttps = mkOption
{
type = types.nullOr (types.submodule { options =
{
hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
};});
default = null;
};
php = mkOption
{
type = types.nullOr (types.submodule { options =
{
root = mkOption { type = types.nonEmptyStr; };
fastcgiPass = mkOption { type = types.nonEmptyStr; };
};});
default = null;
};
};}));
default = {};
};
};
config =
let
inherit (inputs.lib) mkMerge mkIf mkDefault;
inherit (inputs.lib.strings) escapeURL;
inherit (inputs.localLib) attrsToList;
inherit (inputs.config.nixos.services) nginx;
inherit (builtins) map listToAttrs concatStringsSep toString filter attrValues concatLists;
concatAttrs = list: listToAttrs (concatLists (map (attrs: attrsToList attrs) list));
in mkIf nginx.enable (mkMerge
[
# generic config
{
services =
{
nginx =
{
enable = true;
enableReload = true;
eventsConfig =
''
worker_connections 524288;
use epoll;
'';
commonHttpConfig =
''
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}
log_format http '[$time_local] $remote_addr-$geoip2_data_country_code "$host"'
' $request_length $bytes_sent $status "$request" referer: "$http_referer" ua: "$http_user_agent"';
access_log syslog:server=unix:/dev/log http;
proxy_ssl_server_name on;
proxy_ssl_session_reuse off;
send_timeout 10m;
'';
proxyTimeout = "10m";
recommendedZstdSettings = true;
recommendedTlsSettings = true;
recommendedProxySettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedBrotliSettings = true;
clientMaxBodySize = "0";
package =
let
nginx-geoip2 =
{
name = "ngx_http_geoip2_module";
src = inputs.pkgs.fetchFromGitHub
{
owner = "leev";
repo = "ngx_http_geoip2_module";
rev = "a607a41a8115fecfc05b5c283c81532a3d605425";
hash = "sha256-CkmaeEa1iEAabJEDu3FhBUR7QF38koGYlyx+pyKZV9Y=";
};
meta.license = [];
};
in
(inputs.pkgs.nginxMainline.override (prev: { modules = prev.modules ++ [ nginx-geoip2 ]; }))
.overrideAttrs (prev: { buildInputs = prev.buildInputs ++ [ inputs.pkgs.libmaxminddb ]; });
streamConfig =
''
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}
resolver 8.8.8.8;
'';
# todo: use host dns
resolver.addresses = [ "8.8.8.8" ];
};
geoipupdate =
{
enable = true;
settings =
{
AccountID = 901296;
LicenseKey = inputs.config.sops.secrets."nginx/maxmind-license".path;
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
sops.secrets = { "nginx/maxmind-license".owner = inputs.config.users.users.nginx.name; };
systemd.services.nginx.serviceConfig =
{
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
LimitNPROC = 65536;
LimitNOFILE = 524288;
};
}
# transparentProxy
(mkIf nginx.transparentProxy.enable
{
services.nginx.streamConfig =
''
log_format transparent_proxy '[$time_local] $remote_addr-$geoip2_data_country_code '
'"$ssl_preread_server_name"->$transparent_proxy_backend $bytes_sent $bytes_received';
map $ssl_preread_server_name $transparent_proxy_backend {
${concatStringsSep "\n " (map
(x: ''"${x.name}" 127.0.0.1:${toString x.value};'')
(attrsToList nginx.transparentProxy.map))}
default 127.0.0.1:${toString (with nginx.global; (httpsPort + httpsPortShift.http2))};
}
server {
${concatStringsSep "\n " (map (ip: "listen ${ip}:443;") nginx.transparentProxy.externalIp)}
ssl_preread on;
proxy_bind $remote_addr transparent;
proxy_pass $transparent_proxy_backend;
proxy_connect_timeout 1s;
proxy_socket_keepalive on;
proxy_buffer_size 128k;
access_log syslog:server=unix:/dev/log transparent_proxy;
}
'';
systemd.services.nginx-proxy =
let
ipset = "${inputs.pkgs.ipset}/bin/ipset";
iptables = "${inputs.pkgs.iptables}/bin/iptables";
ip = "${inputs.pkgs.iproute}/bin/ip";
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
(
''
${ipset} create nginx_proxy_port bitmap:port range 0-65535
${iptables} -t mangle -N nginx_proxy_mark
${iptables} -t mangle -A OUTPUT -j nginx_proxy_mark
${iptables} -t mangle -A nginx_proxy_mark -s 127.0.0.1 -p tcp \
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
${iptables} -t mangle -N nginx_proxy
${iptables} -t mangle -A PREROUTING -j nginx_proxy
${iptables} -t mangle -A nginx_proxy -s 127.0.0.1 -p tcp \
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
${ip} rule add fwmark 2/2 table 200
${ip} route add local 0.0.0.0/0 dev lo table 200
''
+ concatStringsSep "\n " (map
(port: ''${ipset} add nginx_proxy_port ${toString port}'')
(inputs.lib.unique (attrValues nginx.transparentProxy.map)))
);
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
''
${iptables} -t mangle -F nginx_proxy_mark
${iptables} -t mangle -D OUTPUT -j nginx_proxy_mark
${iptables} -t mangle -X nginx_proxy_mark
${iptables} -t mangle -F nginx_proxy
${iptables} -t mangle -D PREROUTING -j nginx_proxy
${iptables} -t mangle -X nginx_proxy
${ip} rule del fwmark 2/2 table 200
${ip} route del local 0.0.0.0/0 dev lo table 200
${ipset} destroy nginx_proxy_port
'';
in
{
description = "nginx transparent proxy";
after = [ "network.target" ];
serviceConfig =
{
Type = "simple";
RemainAfterExit = true;
ExecStart = start;
ExecStop = stop;
};
wants = [ "network.target" ];
wantedBy= [ "multi-user.target" ];
};
})
# streamProxy
{
services.nginx.streamConfig =
''
log_format stream_proxy '[$time_local] $remote_addr-$geoip2_data_country_code '
'"$ssl_preread_server_name"->$stream_proxy_backend $bytes_sent $bytes_received';
map $ssl_preread_server_name $stream_proxy_backend {
${concatStringsSep "\n " (map
(x:
let
upstream =
if (builtins.typeOf x.value.upstream == "string") then
x.value.upstream
else
let
port = with nginx.global;
if x.value.upstream.port == null then
httpsPort + httpsPortShift.http2
+ (if x.value.proxyProtocol then httpsPortShift.proxyProtocol else 0)
else x.value.upstream.port;
in "${x.value.upstream.address}:${toString port}";
in ''"${x.name}" "${upstream}";'')
(attrsToList nginx.streamProxy.map))}
}
server {
listen 127.0.0.1:${toString nginx.global.streamPort};
ssl_preread on;
proxy_pass $stream_proxy_backend;
proxy_connect_timeout 10s;
proxy_socket_keepalive on;
proxy_buffer_size 128k;
access_log syslog:server=unix:/dev/log stream_proxy;
}
server {
listen 127.0.0.1:${toString (with nginx.global; (streamPort + streamPortShift.proxyProtocol))};
proxy_protocol on;
ssl_preread on;
proxy_pass $stream_proxy_backend;
proxy_connect_timeout 10s;
proxy_socket_keepalive on;
proxy_buffer_size 128k;
access_log syslog:server=unix:/dev/log stream_proxy;
}
'';
nixos.services.nginx =
{
transparentProxy.map = listToAttrs
(
(map
(site: { inherit (site) name; value = nginx.global.streamPort; })
(filter
(site: (!(site.value.proxyProtocol or false) && (site.value.addToTransparentProxy or true)))
(attrsToList nginx.streamProxy.map)))
++ (map
(site: { inherit (site) name; value = with nginx.global; streamPort + streamPortShift.proxyProtocol; })
(filter
(site: ((site.value.proxyProtocol or false) && (site.value.addToTransparentProxy or true)))
(attrsToList nginx.streamProxy.map)))
);
http = listToAttrs (map
(site: { inherit (site) name; value.rewriteHttps = {}; })
(filter (site: site.value.rewriteHttps or false) (attrsToList nginx.streamProxy.map)));
};
}
# https assertions
{
# only one type should be specified in each location
assertions =
(
(map
(location:
{
assertion = (inputs.lib.count
(x: x != null)
(map (type: location.value.${type}) nginx.global.httpsLocationTypes)) <= 1;
message = "Only one type shuold be specified in ${location.name}";
})
(concatLists (map
(site: (map
(location: { inherit (location) value; name = "${site.name} ${location.name}"; })
(attrsToList site.value.location)))
(attrsToList nginx.https))))
# root should be specified either in global or in each location
++ (map
(location:
{
assertion = (location.value.root or "") != null;
message = "Root should be specified in ${location.name}";
})
(concatLists (map
(site: (map
(location: { inherit (location) value; name = "${site.name} ${location.name}"; })
(attrsToList site.value.location)))
(filter (site: site.value.global.root == null) (attrsToList nginx.https)))))
);
}
# https
(
let
# merge different types of locations
sites = map
(site:
{
inherit (site) name;
value =
{
inherit (site.value) global;
listens = attrValues site.value.listen;
locations = map
(location:
{
inherit (location) name;
value =
let _ = builtins.head (filter (type: type.value != null) (attrsToList location.value));
in _.value // { type = _.name; };
})
(attrsToList site.value.location);
};
})
(attrsToList nginx.https);
in
{
services =
{
nginx.virtualHosts = listToAttrs (map
(site:
{
name = site.value.global.configName;
value =
{
serverName = site.name;
root = mkIf (site.value.global.root != null) site.value.global.root;
basicAuthFile = mkIf (site.value.global.detectAuth != null)
inputs.config.sops.templates."nginx/templates/detectAuth/${escapeURL site.name}-global".path;
extraConfig = concatStringsSep "\n"
(
let inherit (site.value.global) index; in
if (index != null) then [ "index ${concatStringsSep " " index};" ] else []
)
++ (
let inherit (site.value.global) detectAuth; in
if (detectAuth != null) then [ ''auth_basic "${detectAuth.text}"'' ] else []
);
listen = map
(listen:
{
addr = if listen.proxyProtocol then "0.0.0.0" else "127.0.0.1";
port = with nginx.global; httpsPort
+ (if listen.http2 then httpsPortShift.http2 else 0)
+ (if listen.proxyProtocol then httpsPortShift.proxyProtocol else 0);
ssl = true;
# TODO: use proxy_protocol in 23.11
extraParameters =
(if listen.proxyProtocol then [ "proxy_protocol" ] else [])
++ (if listen.http2 then [ "http2" ] else []);
})
site.value.listens;
# do not automatically add http2 listen
http2 = false;
onlySSL = true;
# TODO: disable well-known in 23.11
useACMEHost = site.name;
locations = listToAttrs (map
(location:
{
inherit (location) name;
value =
{
basicAuthFile = mkIf (location.value.detectAuth or null != null)
inputs.config.sops.templates
."nginx/templates/detectAuth/${escapeURL site.name}/${escapeURL location.name}".path;
root = mkIf (location.value.root or null != null) location.value.root;
}
// {
proxy =
{
proxyPass = location.value.upstream;
proxyWebsockets = location.value.websocket;
recommendedProxySettings = false;
recommendedProxySettingsNoHost = true;
extraConfig = concatStringsSep "\n"
(
(map
(header: ''proxy_set_header ${header.name} "${header.value}";'')
(attrsToList location.value.setHeaders))
++ (
if location.value.detectAuth != null || site.value.global.detectAuth != null
then [ "proxy_hide_header Authorization;" ]
else []
)
++ (
if location.value.addAuth != null then
let authFile = "nginx/templates/addAuth/${location.value.addAuth}";
in [ "include ${inputs.config.sops.templates.${authFile}.path};" ]
else [])
);
};
static =
{
index = mkIf (location.value.index != []) (concatStringsSep " " location.value.index);
tryFiles = mkIf (location.value.tryFiles != []) (concatStringsSep " " location.value.tryFiles);
};
php.extraConfig =
''
fastcgi_pass ${location.value.fastcgiPass};
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
include ${inputs.config.services.nginx.package}/conf/fastcgi.conf;
'';
return.return = location.value.return;
cgi.extraConfig =
''
include ${inputs.config.services.nginx.package}/conf/fastcgi.conf;
fastcgi_pass unix:${inputs.config.services.fcgiwrap.socketAddress};
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
'';
}.${location.value.type};
})
site.value.location);
};
})
sites);
fcgiwrap = mkIf
(
filter (site: site != []) (map
(site: filter (location: location.value.type == "cgi") (attrsToList site.value.locations))
sites)
!= []
)
{
enable = true;
user = inputs.config.users.users.nginx.name;
group = inputs.config.users.users.nginx.group;
};
};
nixos.services =
{
nginx =
let
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
listens = filter
(listen: listen.value.addToTransparentProxy)
(concatLists (map
(site: map
(listen: { inherit (site) name; value = listen; })
site.value.listens)
sites));
in
{
transparentProxy.map = listToAttrs (map
(site:
{
inherit (site) name;
value = with nginx.global; httpsPort + (if site.value.http2 then httpsPortShift.http2 else 0);
})
(filter (listen: !listen.value.proxyProtocol) listens));
streamProxy.map = listToAttrs (map
(site:
{
inherit (site) name;
value =
{
upstream.port = with nginx.global; httpsPort + httpsPortShift.proxyProtocol
+ (if site.value.http2 then httpsPortShift.http2 else 0);
proxyProtocol = true;
rewriteHttps = mkDefault false;
};
})
(filter (listen: listen.value.proxyProtocol) listens));
http = listToAttrs (map
(site: { inherit (site) name; value.rewriteHttps = {}; })
(filter (site: site.value.global.rewriteHttps) sites));
};
acme =
{
enable = true;
cert = listToAttrs (map
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
sites);
};
fcgiwrap.enable =
filter (site: site != []) (map
(site: filter (location: location.type == "cgi") site.value.locations)
sites)
!= [];
};
sops =
let
detectAuthUsers = concatLists (map
(site:
(
(map
(location:
{
name = "${escapeURL site.name}/${escapeURL location.name}";
value = location.value.detectAuth.users;
})
(filter (location: location.value.detectAuth or null != null) site.value.locations))
++ (if site.value.global.detectAuth != null then
[ { name = "${escapeURL site.name}-global"; value = site.value.global.detectAuth.users; } ]
else [])
))
sites);
addAuth = concatLists (map
(site: map
(location:
{
name = "${escapeURL site.name}/${escapeURL location.name}";
value = location.value.addAuth;
})
(filter (location: location.value.addAuth != null) site.value.locations)
)
sites);
in
{
templates = listToAttrs
(
(map
(detectAuth:
{
name = "nginx/templates/detectAuth/${detectAuth.name}";
value =
{
owner = inputs.config.users.users.nginx.name;
content = concatStringsSep "\n" (map
(user: "${user}:{PLAIN}${inputs.config.sops.placeholder."nginx/detectAuth/${user}"}")
detectAuth.value);
};
})
detectAuthUsers)
++ (map
(addAuth:
{
name = "nginx/templates/addAuth/${addAuth.name}";
value =
{
owner = inputs.config.users.users.nginx.name;
content =
let placeholder = inputs.config.sops.placeholder."nginx/addAuth/${addAuth.value}";
in ''proxy_set_header Authorization "Basic ${placeholder}";'';
};
})
addAuth)
);
secrets = listToAttrs
(
(map
(secret: { name = "nginx/detectAuth/${secret}"; value = {}; })
(inputs.lib.unique (concatLists (map (detectAuth: detectAuth.value) detectAuthUsers))))
++ (map
(secret: { name = "nginx/addAuth/${secret}"; value = {}; })
(inputs.lib.unique (map (addAuth: addAuth.value) addAuth)))
);
};
}
)
# http
{
assertions = map
(site:
{
assertion = (inputs.lib.count (x: x != null) (map (type: site.value.${type}) nginx.global.httpTypes)) <= 1;
message = "Only one type shuold be specified in ${site.name}";
})
(attrsToList nginx.http);
services.nginx.virtualHosts = listToAttrs (map
(site:
{
name = "http.${site.name}";
value =
{
serverName = site.name;
listen = [ { addr = "0.0.0.0"; port = 80; } ];
}
// (if site.value.rewriteHttps != null then
{ locations."/".return = "301 https://${site.value.rewriteHttps.hostname}$request_uri"; }
else {})
// (if site.value.php != null then
{
extraConfig = "index index.php;";
root = site.value.php.root;
locations."~ ^.+?.php(/.*)?$".extraConfig =
''
fastcgi_pass ${site.value.php.fastcgiPass};
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
include ${inputs.config.services.nginx.package}/conf/fastcgi.conf;
'';
}
else {});
})
(attrsToList nginx.http));
}
]);
}

View File

@@ -0,0 +1,29 @@
inputs:
{
options.nixos.services.nix-serve = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; };
};
config =
let
inherit (inputs.lib) mkMerge mkIf;
inherit (inputs.localLib) stripeTabs attrsToList;
inherit (inputs.config.nixos.services) nix-serve;
inherit (builtins) map listToAttrs toString;
in mkIf nix-serve.enable
{
services.nix-serve =
{
enable = true;
openFirewall = true;
secretKeyFile = inputs.config.sops.secrets."store/signingKey".path;
};
sops.secrets."store/signingKey" = {};
nixos.services.nginx =
{
enable = true;
https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000";
};
};
}

View File

@@ -0,0 +1,59 @@
inputs:
{
options.nixos.services.photoprism = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; default = "photoprism.chn.moe"; };
port = mkOption { type = types.ints.unsigned; default = 2342; };
};
config =
let
inherit (inputs.lib) mkIf;
inherit (inputs.config.nixos.services) photoprism;
in mkIf photoprism.enable
{
services.photoprism =
{
enable = true;
originalsPath = inputs.config.services.photoprism.storagePath + "/originals";
settings =
{
PHOTOPRISM_SITE_URL = "https://${photoprism.hostname}";
PHOTOPRISM_HTTP_PORT = "${toString photoprism.port}";
PHOTOPRISM_DISABLE_TLS = "true";
PHOTOPRISM_DETECT_NSFW = "true";
PHOTOPRISM_UPLOAD_NSFW = "true";
PHOTOPRISM_DATABASE_DRIVER = "mysql";
PHOTOPRISM_DATABASE_SERVER = "127.0.0.1:3306";
};
};
systemd.services.photoprism =
{
after = [ "mariadb.service" ];
requires = [ "mariadb.service" ];
serviceConfig.EnvironmentFile = inputs.config.sops.templates."photoprism/env".path;
};
sops =
{
templates."photoprism/env".content = let placeholder = inputs.config.sops.placeholder; in
''
PHOTOPRISM_ADMIN_PASSWORD=${placeholder."photoprism/adminPassword"}
PHOTOPRISM_DATABASE_PASSWORD=${placeholder."mariadb/photoprism"}
'';
secrets."photoprism/adminPassword" = {};
};
nixos.services =
{
mariadb = { enable = true; instances.photoprism = {}; };
nginx =
{
enable = true;
https.${photoprism.hostname}.location."/".proxy =
{
upstream = "http://127.0.0.1:${toString photoprism.port}";
websocket = true;
};
};
};
};
}

View File

@@ -8,7 +8,13 @@ inputs:
{
user = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
group = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
package = mkOption { type = types.nullOr types.package; default = null; };
package = mkOption { type = types.nullOr types.package; default = inputs.pkgs.php; };
fastcgi = mkOption
{
type = types.nonEmptyStr;
readOnly = true;
default = "unix:${inputs.config.services.phpfpm.pools.${submoduleInputs.config._module.args.name}.socket}";
};
};}));
default = {};
};
@@ -28,13 +34,15 @@ inputs:
{
user = if pool.value.user == null then pool.name else pool.value.user;
group = if pool.value.group == null then inputs.config.users.users.${user}.group else pool.value.group;
phpPackage = if pool.value.package == null then inputs.pkgs.php else pool.value.package;
phpPackage = pool.value.package;
settings =
{
"pm" = "ondemand";
"pm.max_children" = 4;
"pm.process_idle_timeout" = "60s";
"pm.max_requests" = 128;
"listen.owner" = inputs.config.services.nginx.user;
"listen.group" = inputs.config.services.nginx.group;
};
};
})
@@ -42,18 +50,10 @@ inputs:
users =
{
users = listToAttrs (map
(pool:
{
inherit (pool) name;
value = { isSystemUser = true; group = pool.name; };
})
(pool: { inherit (pool) name; value = { isSystemUser = true; group = pool.name; extraGroups = [ "nginx" ]; }; })
(filter (pool: pool.value.user == null) (attrsToList phpfpm.instances)));
groups = listToAttrs (map
(pool:
{
inherit (pool) name;
value = {};
})
(pool: { inherit (pool) name; value = {}; })
(filter (pool: pool.value.user == null) (attrsToList phpfpm.instances)));
};
};

View File

@@ -17,8 +17,8 @@ inputs:
config =
let
inherit (inputs.config.nixos.services) postgresql;
inherit (inputs.lib) mkMerge mkAfter concatStringsSep mkIf;
inherit (inputs.localLib) stripeTabs attrsToList;
inherit (inputs.lib) mkAfter concatStringsSep mkIf;
inherit (inputs.localLib) attrsToList;
inherit (builtins) map listToAttrs filter;
in mkIf postgresql.enable
{
@@ -71,6 +71,7 @@ inputs:
in
# set user password
"$PSQL -tAc \"ALTER USER ${db.value.user} with encrypted password '$(cat ${passwordFile})'\""
# TODO: still needed in 23.11?
# set db owner
+ "\n"
+ "$PSQL -tAc \"select pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d"

View File

@@ -39,7 +39,7 @@ inputs:
})
(attrsToList redis.instances));
sops.secrets = listToAttrs (map
(server: { name = "redis/${server.name}"; value.owner = inputs.config.users.users.${server.name}.name; })
(server: { name = "redis/${server.name}"; value.owner = inputs.config.users.users.${server.value.user}.name; })
(filter (server: server.value.passwordFile == null) (attrsToList redis.instances)));
};
}

View File

@@ -4,12 +4,11 @@ inputs:
{
enable = mkOption { type = types.bool; default = false; };
port = mkOption { type = types.ints.unsigned; default = 5221; };
hostname = mkOption { type = types.str; default = "rsshub.chn.moe"; };
hostname = mkOption { type = types.nonEmptyStr; default = "rsshub.chn.moe"; };
};
config =
let
inherit (inputs.config.nixos.services) rsshub;
inherit (inputs.localLib) stripeTabs;
inherit (inputs.lib) mkIf;
inherit (builtins) map listToAttrs toString;
in mkIf rsshub.enable
@@ -60,12 +59,7 @@ inputs:
nginx =
{
enable = true;
httpProxy.${rsshub.hostname} =
{
rewriteHttps = true;
locations."/" =
{ upstream = "http://127.0.0.1:${toString rsshub.port}"; setHeaders.Host = rsshub.hostname; };
};
https.${rsshub.hostname}.location."/".proxy.upstream = "http://127.0.0.1:${toString rsshub.port}";
};
};
};

56
modules/services/send.nix Normal file
View File

@@ -0,0 +1,56 @@
inputs:
{
options.nixos.services.send = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; default = "send.chn.moe"; };
};
config =
let
inherit (inputs.lib) mkIf;
inherit (inputs.config.nixos.services) send;
in mkIf send.enable
{
virtualisation.oci-containers.containers.send =
{
image = "timvisee/send:1ee4951";
imageFile = inputs.pkgs.dockerTools.pullImage
{
imageName = "registry.gitlab.com/timvisee/send";
imageDigest = "sha256:1ee495161f176946e6e4077e17be2b8f8634c2d502172cc530a8cd5affd7078f";
sha256 = "1dimqga35c2ka4advhv3v60xcsdrhc6c4hh21x36fbyhk90n2vzs";
finalImageName = "timvisee/send";
finalImageTag = "1ee4951";
};
ports = [ "127.0.0.1:1443:1443/tcp" ];
volumes = [ "send:/uploads" ];
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
environmentFiles = [ inputs.config.sops.templates."send/env".path ];
};
sops =
{
templates."send/env".content =
''
BASE_URL=https://${send.hostname}
MAX_FILE_SIZE=17179869184
REDIS_HOST=host.docker.internal
REDIS_PORT=9184
REDIS_PASSWORD=${inputs.config.sops.placeholder."redis/send"}
'';
};
nixos =
{
services =
{
nginx =
{
enable = true;
https."${send.hostname}".location."/".proxy = { upstream = "http://127.0.0.1:1443"; websocket = true; };
};
redis.instances.send = { user = "root"; port = 9184; };
};
# TODO: root docker use config of rootless docker?
virtualization.docker.enable = true;
};
};
}

View File

@@ -0,0 +1,37 @@
inputs:
{
options.nixos.services.snapper = let inherit (inputs.lib) mkOption types; in
{
enable = mkOption { type = types.bool; default = false; };
configs = mkOption { type = types.attrsOf types.nonEmptyStr; default = {}; };
};
config =
let
inherit (inputs.lib) mkMerge mkIf;
inherit (inputs.localLib) stripeTabs attrsToList;
inherit (inputs.config.nixos) services;
inherit (builtins) map listToAttrs toString;
in mkIf services.snapper.enable
{
services.snapper.configs =
let
f = (config:
{
inherit (config) name;
value =
{
SUBVOLUME = config.value;
TIMELINE_CREATE = true;
TIMELINE_CLEANUP = true;
TIMELINE_MIN_AGE = 1800;
TIMELINE_LIMIT_HOURLY = "10";
TIMELINE_LIMIT_DAILY = "7";
TIMELINE_LIMIT_WEEKLY = "1";
TIMELINE_LIMIT_MONTHLY = "0";
TIMELINE_LIMIT_YEARLY = "0";
};
});
in
listToAttrs (map f (attrsToList services.snapper.configs));
};
}

View File

@@ -1,13 +0,0 @@
diff --git a/snapper/FileUtils.cc b/snapper/FileUtils.cc
index 9da572f..48f60fa 100644
--- a/snapper/FileUtils.cc
+++ b/snapper/FileUtils.cc
@@ -424,7 +424,7 @@ namespace snapper
v /= 62;
}
- int fd = open(name, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, S_IRUSR | S_IWUSR);
+ int fd = open(name, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd >= 0)
return fd;
else if (errno != EEXIST)

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDV9egbTbIbVCV4TNr6IgvXw7fMEK4v/WKAHddkX4uvysL7l+H1cLM0TRDvGefUFoU7eYcEIRV9lwvjMo/xy0GKao76fylQ03gkrzTiPvztThpAfKKOIniXvzWoIP7/fzNwuW6GgUiM4JKvgJEieRTybclLRgauy2gqiwVZMAFksxG1fAPYGXIrhtVQ+WjN+0IIiayNlj1J6tJ9fQWc+BkNsoJJZBADf+qjTsqsVHjcABoo2vYRTYnSVzrsnjSu6ivGjSY0ImG+ASPqyluA7eSXe4XQkyxjuyBVTwwqTpZ0Y+DMESr/Fd5rQ3N/iylLcUVGexl7gHHFtJGiERloG8Bv Public key for Digital Signature

View File

@@ -17,19 +17,11 @@ inputs:
settings =
{
X11Forwarding = true;
TrustedUserCAKeys = "${./ssh-ca.pub}";
ChallengeResponseAuthentication = false;
PasswordAuthentication = sshd.passwordAuthentication;
KbdInteractiveAuthentication = false;
UsePAM = true;
};
extraConfig =
''
Match User root
PasswordAuthentication no
Match User chn
PasswordAuthentication no
'';
};
};
}

View File

@@ -1,150 +1,111 @@
inputs:
{
options.nixos.services = let inherit (inputs.lib) mkOption types; in
options.nixos.services.synapse = let inherit (inputs.lib) mkOption types; in
{
synapse =
{
enable = mkOption { type = types.bool; default = false; };
autoStart = mkOption { type = types.bool; default = true; };
port = mkOption { type = types.ints.unsigned; default = 8008; };
hostname = mkOption { type = types.str; default = "synapse.chn.moe"; };
};
synapse-proxy = mkOption
{
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
upstream = mkOption
{
type = types.oneOf [ types.nonEmptyStr (types.submodule { options =
{
address = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
port = mkOption { type = types.ints.unsigned; default = 8008; };
};})];
default = "127.0.0.1:8008";
};
};}));
default = {};
};
enable = mkOption { type = types.bool; default = false; };
autoStart = mkOption { type = types.bool; default = true; };
port = mkOption { type = types.ints.unsigned; default = 8008; };
hostname = mkOption { type = types.nonEmptyStr; default = "synapse.chn.moe"; };
};
config =
let
inherit (inputs.config.nixos.services) synapse synapse-proxy;
inherit (inputs.localLib) attrsToList;
inherit (inputs.lib) mkIf mkMerge;
inherit (inputs.config.nixos.services) synapse;
inherit (inputs.lib) mkIf;
inherit (builtins) map listToAttrs;
in mkMerge
[
(mkIf synapse.enable
in mkIf synapse.enable
{
services.matrix-synapse =
{
services.matrix-synapse =
enable = true;
settings =
{
enable = true;
settings =
server_name = synapse.hostname;
listeners =
[{
bind_addresses = [ "0.0.0.0" ];
port = 8008;
resources = [{ names = [ "client" "federation" ]; compress = false; }];
tls = false;
type = "http";
x_forwarded = true;
}];
database.name = "psycopg2";
admin_contact = "mailto:chn@chn.moe";
enable_registration = true;
registrations_require_3pid = [ "email" ];
turn_uris = [ "turns:coturn.chn.moe" "turn:coturn.chn.moe" ];
max_upload_size = "1024M";
web_client_location = "https://element.chn.moe/";
serve_server_wellknown = true;
report_stats = true;
trusted_key_servers = [{ server_name = "matrix.org"; }];
suppress_key_server_warning = true;
log_config = (inputs.pkgs.formats.yaml {}).generate "log.yaml"
{
server_name = synapse.hostname;
listeners =
[{
bind_addresses = [ "0.0.0.0" ];
port = 8008;
resources = [{ names = [ "client" "federation" ]; compress = false; }];
tls = false;
type = "http";
x_forwarded = true;
}];
database.name = "psycopg2";
admin_contact = "mailto:chn@chn.moe";
enable_registration = true;
registrations_require_3pid = [ "email" ];
turn_uris = [ "turns:coturn.chn.moe" "turn:coturn.chn.moe" ];
max_upload_size = "1024M";
web_client_location = "https://element.chn.moe/";
serve_server_wellknown = true;
report_stats = true;
trusted_key_servers = [{ server_name = "matrix.org"; }];
suppress_key_server_warning = true;
log_config = (inputs.pkgs.formats.yaml {}).generate "log.yaml"
version = 1;
formatters.precise.format =
"%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s";
handlers.console = { class = "logging.StreamHandler"; formatter = "precise"; };
root = { level = "INFO"; handlers = [ "console" ]; };
disable_existing_loggers = true;
};
};
extraConfigFiles = [ inputs.config.sops.templates."synapse/password.yaml".path ];
};
sops =
{
templates."synapse/password.yaml" =
{
owner = inputs.config.systemd.services.matrix-synapse.serviceConfig.User;
group = inputs.config.systemd.services.matrix-synapse.serviceConfig.Group;
content = builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "password.yaml"
{
database =
{
version = 1;
formatters.precise.format =
"%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s";
handlers.console = { class = "logging.StreamHandler"; formatter = "precise"; };
root = { level = "INFO"; handlers = [ "console" ]; };
disable_existing_loggers = true;
name = "psycopg2";
args =
{
user = "synapse";
password = inputs.config.sops.placeholder."postgresql/synapse";
database = "synapse";
host = "127.0.0.1";
port = "5432";
};
allow_unsafe_locale = true;
};
};
extraConfigFiles = [ inputs.config.sops.templates."synapse/password.yaml".path ];
};
sops =
{
templates."synapse/password.yaml" =
{
owner = inputs.config.systemd.services.matrix-synapse.serviceConfig.User;
group = inputs.config.systemd.services.matrix-synapse.serviceConfig.Group;
content = builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "password.yaml"
turn_shared_secret = inputs.config.sops.placeholder."synapse/coturn";
registration_shared_secret = inputs.config.sops.placeholder."synapse/registration";
macaroon_secret_key = inputs.config.sops.placeholder."synapse/macaroon";
form_secret = inputs.config.sops.placeholder."synapse/form";
signing_key_path = inputs.config.sops.secrets."synapse/signing-key".path;
email =
{
database =
{
name = "psycopg2";
args =
{
user = "synapse";
password = inputs.config.sops.placeholder."postgresql/synapse";
database = "synapse";
host = "127.0.0.1";
port = "5432";
};
allow_unsafe_locale = true;
};
turn_shared_secret = inputs.config.sops.placeholder."synapse/coturn";
registration_shared_secret = inputs.config.sops.placeholder."synapse/registration";
macaroon_secret_key = inputs.config.sops.placeholder."synapse/macaroon";
form_secret = inputs.config.sops.placeholder."synapse/form";
signing_key_path = inputs.config.sops.secrets."synapse/signing-key".path;
email =
{
smtp_host = "mail.chn.moe";
smtp_port = 25;
smtp_user = "bot@chn.moe";
smtp_pass = inputs.config.sops.placeholder."mail/bot";
require_transport_security = true;
notif_from = "Your Friendly %(app)s homeserver <bot@chn.moe>";
app_name = "Haonan Chen's synapse";
};
});
};
secrets = (listToAttrs (map
(secret: { name = "synapse/${secret}"; value = {}; })
[ "coturn" "registration" "macaroon" "form" ]))
// { "synapse/signing-key".owner = inputs.config.systemd.services.matrix-synapse.serviceConfig.User; }
// { "mail/bot" = {}; };
smtp_host = "mail.chn.moe";
smtp_port = 25;
smtp_user = "bot@chn.moe";
smtp_pass = inputs.config.sops.placeholder."mail/bot";
require_transport_security = true;
notif_from = "Your Friendly %(app)s homeserver <bot@chn.moe>";
app_name = "Haonan Chen's synapse";
};
});
};
nixos.services.postgresql = { enable = true; instances.synapse = {}; };
systemd.services.matrix-synapse.enable = synapse.autoStart;
})
(mkIf (synapse-proxy != {})
secrets = (listToAttrs (map
(secret: { name = "synapse/${secret}"; value = {}; })
[ "coturn" "registration" "macaroon" "form" ]))
// { "synapse/signing-key".owner = inputs.config.systemd.services.matrix-synapse.serviceConfig.User; }
// { "mail/bot" = {}; };
};
nixos.services =
{
nixos.services.nginx =
postgresql = { enable = true; instances.synapse = {}; };
nginx =
{
enable = true;
httpProxy = listToAttrs (map
(proxy: with proxy.value;
{
name = hostname;
value =
{
rewriteHttps = true;
locations."/" =
{
upstream = if builtins.typeOf upstream == "string" then "http://${upstream}"
else "http://${upstream.address}:${toString upstream.port}";
websocket = true;
setHeaders.Host = hostname;
};
};
})
(attrsToList synapse-proxy));
https.${synapse.hostname}.location."/".proxy =
{ upstream = "http://127.0.0.1:${toString synapse.port}"; websocket = true; };
};
})
];
};
systemd.services.matrix-synapse.enable = synapse.autoStart;
};
}

View File

@@ -1,117 +1,102 @@
inputs:
{
options.nixos.services = let inherit (inputs.lib) mkOption types; in
options.nixos.services.vaultwarden = let inherit (inputs.lib) mkOption types; in
{
vaultwarden =
{
enable = mkOption { type = types.bool; default = false; };
autoStart = mkOption { type = types.bool; default = true; };
port = mkOption { type = types.ints.unsigned; default = 8000; };
websocketPort = mkOption { type = types.ints.unsigned; default = 3012; };
hostname = mkOption { type = types.str; default = "vaultwarden.chn.moe"; };
};
vaultwarden-proxy =
{
enable = mkOption { type = types.bool; default = false; };
hostname = mkOption { type = types.nonEmptyStr; default = "vaultwarden.chn.moe"; };
upstream = mkOption
{
type = types.oneOf [ types.nonEmptyStr (types.submodule { options =
{
address = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
port = mkOption { type = types.ints.unsigned; default = 8000; };
websocketPort = mkOption { type = types.ints.unsigned; default = 3012; };
};})];
default = {};
};
};
enable = mkOption { type = types.bool; default = false; };
autoStart = mkOption { type = types.bool; default = true; };
port = mkOption { type = types.ints.unsigned; default = 8000; };
websocketPort = mkOption { type = types.ints.unsigned; default = 3012; };
hostname = mkOption { type = types.nonEmptyStr; default = "vaultwarden.chn.moe"; };
};
config =
let
inherit (inputs.config.nixos.services) vaultwarden vaultwarden-proxy;
inherit (builtins) listToAttrs;
inherit (inputs.lib) mkIf mkMerge;
in mkMerge
[
(
mkIf vaultwarden.enable
inherit (inputs.config.nixos.services) vaultwarden;
inherit (builtins) listToAttrs toString;
inherit (inputs.lib) mkIf;
in mkIf vaultwarden.enable
{
services.vaultwarden =
{
enable = true;
dbBackend = "postgresql";
config =
{
services.vaultwarden =
DATA_FOLDER = "/var/lib/vaultwarden";
WEB_VAULT_ENABLED = true;
WEBSOCKET_ENABLED = true;
ROCKET_PORT = vaultwarden.port;
WEBSOCKET_PORT = toString vaultwarden.websocketPort;
SIGNUPS_VERIFY = true;
DOMAIN = "https://${vaultwarden.hostname}";
SMTP_HOST = "mail.chn.moe";
SMTP_FROM = "bot@chn.moe";
SMTP_FROM_NAME = "vaultwarden";
SMTP_SECURITY = "force_tls";
SMTP_USERNAME = "bot@chn.moe";
};
environmentFile = inputs.config.sops.templates."vaultwarden.env".path;
};
sops =
{
templates."vaultwarden.env" =
let
serviceConfig = inputs.config.systemd.services.vaultwarden.serviceConfig;
placeholder = inputs.config.sops.placeholder;
in
{
enable = true;
dbBackend = "postgresql";
config =
{
DATA_FOLDER = "/var/lib/vaultwarden";
WEB_VAULT_ENABLED = true;
WEBSOCKET_ENABLED = true;
ROCKET_PORT = vaultwarden.port;
WEBSOCKET_PORT = toString vaultwarden.websocketPort;
SIGNUPS_VERIFY = true;
DOMAIN = "https://${vaultwarden.hostname}";
SMTP_HOST = "mail.chn.moe";
SMTP_FROM = "bot@chn.moe";
SMTP_FROM_NAME = "vaultwarden";
SMTP_SECURITY = "force_tls";
SMTP_USERNAME = "bot@chn.moe";
};
environmentFile = inputs.config.sops.templates."vaultwarden.env".path;
owner = serviceConfig.User;
group = serviceConfig.Group;
content =
''
DATABASE_URL=postgresql://vaultwarden:${placeholder."postgresql/vaultwarden"}@localhost/vaultwarden
ADMIN_TOKEN=${placeholder."vaultwarden/admin_token"}
SMTP_PASSWORD=${placeholder."mail/bot"}
'';
};
sops =
{
templates."vaultwarden.env" =
let
serviceConfig = inputs.config.systemd.services.vaultwarden.serviceConfig;
placeholder = inputs.config.sops.placeholder;
in
{
owner = serviceConfig.User;
group = serviceConfig.Group;
content =
''
DATABASE_URL=postgresql://vaultwarden:${placeholder."postgresql/vaultwarden"}@localhost/vaultwarden
ADMIN_TOKEN=${placeholder."vaultwarden/admin_token"}
SMTP_PASSWORD=${placeholder."mail/bot"}
'';
};
secrets = listToAttrs (map
(secret: { name = secret; value = {}; })
[ "vaultwarden/admin_token" "mail/bot" ]);
};
systemd.services.vaultwarden =
{
enable = vaultwarden.autoStart;
after = [ "postgresql.service" ];
};
nixos.services.postgresql = { enable = true; instances.vaultwarden = {}; };
}
)
(
mkIf vaultwarden-proxy.enable
secrets = listToAttrs (map
(secret: { name = secret; value = {}; })
[ "vaultwarden/admin_token" "mail/bot" ]);
};
systemd.services.vaultwarden =
{
enable = vaultwarden.autoStart;
after = [ "postgresql.service" ];
};
nixos.services =
{
postgresql = { enable = true; instances.vaultwarden = {}; };
nginx =
{
nixos.services.nginx =
enable = true;
https.${vaultwarden.hostname} =
{
enable = true;
httpProxy."${vaultwarden-proxy.hostname}" =
{
rewriteHttps = true;
locations = let upstream = vaultwarden-proxy.upstream; in (listToAttrs (map
(location: { name = location; value =
location = listToAttrs
(
(map
(location:
{
upstream = "http://${upstream.address or upstream}:${builtins.toString upstream.port or 8000}";
setHeaders = { Host = vaultwarden-proxy.hostname; Connection = ""; };
};})
[ "/" "/notifications/hub/negotiate" ]))
// { "/notifications/hub" =
name = location;
value.proxy =
{
upstream = "http://127.0.0.1:${toString vaultwarden.port}";
setHeaders = { Host = vaultwarden.hostname; Connection = ""; };
};
})
[ "/" "/notifications/hub/negotiate" ])
++ (map
(location:
{
upstream =
"http://${upstream.address or upstream}:${builtins.toString upstream.websocketPort or 3012}";
websocket = true;
setHeaders.Host = vaultwarden-proxy.hostname;
};};
};
name = location;
value.proxy =
{
upstream = "http://127.0.0.1:${toString vaultwarden.websocketPort}";
websocket = true;
};
})
[ "/notifications/hub" ])
);
};
}
)
];
};
};
};
}

View File

@@ -319,19 +319,7 @@ inputs:
(
mkIf xrayServer.enable (let userList = genList (n: n) 30; in
{
services =
{
xray = { enable = true; settingsFile = inputs.config.sops.templates."xray-server.json".path; };
nginx.virtualHosts.xray =
{
serverName = xrayServer.serverName;
default = true;
listen = [{ addr = "127.0.0.1"; port = 7233; ssl = true; }];
useACMEHost = xrayServer.serverName;
onlySSL = true;
locations."/".return = "400";
};
};
services.xray = { enable = true; settingsFile = inputs.config.sops.templates."xray-server.json".path; };
sops =
{
templates."xray-server.json" =
@@ -343,39 +331,45 @@ inputs:
log.loglevel = "warning";
inbounds =
[
{
port = 4726;
listen = "127.0.0.1";
protocol = "vless";
settings =
(
let
fallbackPort = toString
(with inputs.config.nixos.services.nginx.global; httpsPort + httpsPortShift.http2);
in
{
clients = map
(n:
{
id = inputs.config.sops.placeholder."xray-server/clients/user${toString n}";
flow = "xtls-rprx-vision";
email = "${toString n}@xray.chn.moe";
})
userList;
decryption = "none";
fallbacks = [{ dest = "127.0.0.1:7233"; }];
};
streamSettings =
{
network = "tcp";
security = "reality";
realitySettings =
port = 4726;
listen = "127.0.0.1";
protocol = "vless";
settings =
{
dest = "127.0.0.1:7233";
serverNames = [ xrayServer.serverName ];
privateKey = inputs.config.sops.placeholder."xray-server/private-key";
minClientVer = "1.8.0";
shortIds = [ "" ];
clients = map
(n:
{
id = inputs.config.sops.placeholder."xray-server/clients/user${toString n}";
flow = "xtls-rprx-vision";
email = "${toString n}@xray.chn.moe";
})
userList;
decryption = "none";
fallbacks = [{ dest = "127.0.0.1:${fallbackPort}"; }];
};
};
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; routeOnly = true; };
tag = "in";
}
streamSettings =
{
network = "tcp";
security = "reality";
realitySettings =
{
dest = "127.0.0.1:${fallbackPort}";
serverNames = [ xrayServer.serverName ];
privateKey = inputs.config.sops.placeholder."xray-server/private-key";
minClientVer = "1.8.0";
shortIds = [ "" ];
};
};
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; routeOnly = true; };
tag = "in";
}
)
{
port = 4638;
listen = "127.0.0.1";
@@ -512,10 +506,18 @@ inputs:
users = { users.v2ray = { isSystemUser = true; group = "v2ray"; }; groups.v2ray = {}; };
nixos.services =
{
acme = { enable = true; certs = [ xrayServer.serverName ]; };
nginx.transparentProxy.map."${xrayServer.serverName}" = 4726;
acme = { enable = true; cert.${xrayServer.serverName}.group = inputs.config.users.users.nginx.group; };
nginx =
{
enable = true;
transparentProxy.map."${xrayServer.serverName}" = 4726;
https."${xrayServer.serverName}" =
{
listen.main = { proxyProtocol = false; addToTransparentProxy = false; };
location."/".return.return = "400";
};
};
};
security.acme.certs.${xrayServer.serverName}.group = inputs.config.users.users.nginx.group;
}
))
];

View File

@@ -6,7 +6,7 @@ inputs:
port = mkOption { type = types.ints.unsigned; default = 3389; };
hostname = mkOption
{
type = types.nullOr (types.oneOf [ types.nonEmptyStr (types.listOf types.nonEmptyStr) ]);
type = types.nullOr (types.nonEmptyListOf types.nonEmptyStr);
default = null;
};
};
@@ -29,14 +29,21 @@ inputs:
mkIf (xrdp.hostname != null)
(
let
mainDomain = if builtins.typeOf xrdp.hostname == "string" then xrdp.hostname
else builtins.elemAt xrdp.hostname 0;
mainDomain = builtins.elemAt xrdp.hostname 0;
in
{
services.xrdp = let keydir = inputs.config.security.acme.certs.${mainDomain}.directory; in
{ sslCert = "${keydir}/full.pem"; sslKey = "${keydir}/key.pem"; };
nixos.services.acme = { enable = true; certs = [ xrdp.hostname ]; };
security.acme.certs.${mainDomain}.group = inputs.config.systemd.services.xrdp.serviceConfig.Group;
services.xrdp =
let keydir = inputs.config.security.acme.certs.${mainDomain}.directory;
in { sslCert = "${keydir}/full.pem"; sslKey = "${keydir}/key.pem"; };
nixos.services.acme =
{
enable = true;
cert.${mainDomain} =
{
domains = xrdp.hostname;
group = inputs.config.systemd.services.xrdp.serviceConfig.Group;
};
};
}
)
)

View File

@@ -3,7 +3,7 @@ inputs:
imports = inputs.localLib.mkModules
[
./nix.nix
./fileSystems.nix
./fileSystems
./grub.nix
./initrd.nix
./kernel.nix
@@ -19,22 +19,18 @@ inputs:
{
services =
{
udev.extraRules =
''
ACTION=="add|change", KERNEL=="[sv]d[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="bfq"
ACTION=="add|change", KERNEL=="nvme[0-9]n[0-9]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="bfq"
'';
dbus.implementation = "broker";
fstrim = { enable = true; interval = "daily"; };
};
time.timeZone = "Asia/Shanghai";
boot =
{
kernel.sysctl =
{
"vm.swappiness" = 10;
"vm.oom_kill_allocating_task" = true;
"vm.oom_dump_tasks" = false;
"vm.overcommit_memory" = 1;
"kernel.sysrq" = 438;
};
supportedFilesystems = [ "ntfs" ];
consoleLogLevel = 7;
@@ -66,5 +62,6 @@ inputs:
# environment.variables.CPATH = "/run/current-system/sw/include";
# environment.variables.LIBRARY_PATH = "/run/current-system/sw/lib";
virtualisation.oci-containers.backend = "docker";
home-manager.sharedModules = [{ home.stateVersion = "22.11"; }];
};
}

View File

@@ -39,6 +39,11 @@ inputs:
});
default = {};
};
keyFile = mkOption
{
type = types.path;
default = ./. + "/${inputs.config.nixos.system.networking.hostname}.key";
};
delayedMount = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
};
};
@@ -82,7 +87,13 @@ inputs:
(device:
{
name = device.value;
value = { device = device.name; fsType = "vfat"; neededForBoot = true; };
value =
{
device = device.name;
fsType = "vfat";
neededForBoot = true;
options = [ "noatime" ];
};
})
(attrsToList fileSystems.mount.vfat));
}
@@ -110,7 +121,7 @@ inputs:
# zstd:15 5m33s 7.16G
# zstd:8 54s 7.32G
# zstd:3 17s 7.52G
options = [ "compress-force=zstd" "subvol=${subvol.name}" "acl" ];
options = [ "compress-force=zstd" "subvol=${subvol.name}" "acl" "noatime" ];
neededForBoot = true;
};
}
@@ -224,24 +235,37 @@ inputs:
(
mkIf (fileSystems.rollingRootfs != null)
{
boot.initrd.systemd.services.roll-rootfs =
boot.initrd.systemd =
{
wantedBy = [ "initrd.target" ];
after = [ "cryptsetup.target" "systemd-hibernate-resume.service" ];
before = [ "local-fs-pre.target" "sysroot.mount" ];
unitConfig.DefaultDependencies = false;
serviceConfig.Type = "oneshot";
script = let inherit (fileSystems.rollingRootfs) device path; in
''
mount ${device} /mnt -m
if [ -f /mnt${path}/current/.timestamp ]
then
mv /mnt${path}/current /mnt${path}/$(cat /mnt${path}/current/.timestamp)
fi
btrfs subvolume create /mnt${path}/current
echo $(date '+%Y%m%d%H%M%S') > /mnt${path}/current/.timestamp
umount /mnt
'';
extraBin =
{
grep = "${inputs.pkgs.gnugrep}/bin/grep";
awk = "${inputs.pkgs.gawk}/bin/awk";
chattr = "${inputs.pkgs.e2fsprogs}/bin/chattr";
};
services.roll-rootfs =
{
wantedBy = [ "initrd.target" ];
after = [ "cryptsetup.target" "systemd-hibernate-resume.service" ];
before = [ "local-fs-pre.target" "sysroot.mount" ];
unitConfig.DefaultDependencies = false;
serviceConfig.Type = "oneshot";
script = let inherit (fileSystems.rollingRootfs) device path; in
''
mount ${device} /mnt -m
if [ -f /mnt${path}/current/.timestamp ]
then
timestamp=$(cat /mnt${path}/current/.timestamp)
subvolid=$(btrfs subvolume show /mnt${path}/current | grep 'Subvolume ID:' | awk '{print $NF}')
mv /mnt${path}/current /mnt${path}/$timestamp-$subvolid
btrfs property set -ts /mnt${path}/$timestamp-$subvolid ro true
fi
btrfs subvolume create /mnt${path}/current
chattr +C /mnt${path}/current
echo $(date '+%Y%m%d%H%M%S') > /mnt${path}/current/.timestamp
umount /mnt
'';
};
};
}
)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -4,6 +4,7 @@ inputs:
{
enable = mkOption { type = types.bool; default = false; };
preferred = mkOption { type = types.bool; default = false; };
autoStart = mkOption { type = types.bool; default = inputs.config.nixos.system.gui.preferred; };
};
config =
let
@@ -18,8 +19,12 @@ inputs:
desktopManager.plasma5.enable = true;
videoDrivers = inputs.config.nixos.hardware.gpus;
};
systemd.services.display-manager.after = [ "network-online.target" ];
environment.sessionVariables."GTK_USE_PORTAL" = "1";
systemd.services.display-manager = { after = [ "network-online.target" ]; enable = gui.autoStart; };
environment =
{
sessionVariables."GTK_USE_PORTAL" = "1";
plasma5.excludePackages = inputs.lib.mkIf (!gui.preferred) [ inputs.pkgs.plasma5Packages.plasma-nm ];
};
xdg.portal.extraPortals = map (p: inputs.pkgs."xdg-desktop-portal-${p}") [ "gtk" "kde" "wlr" ];
i18n.inputMethod =
{

View File

@@ -28,6 +28,7 @@ inputs:
"/var/log"
"/var/spool"
"/var/backup"
{ directory = "/var/lib/docker/volumes"; mode = "0710"; }
];
files =
[
@@ -41,10 +42,25 @@ inputs:
"${impermanence.root}" =
{
hideMounts = true;
directories = []
++ (if inputs.config.services.xserver.displayManager.sddm.enable then
[{ directory = "/var/lib/sddm"; user = "sddm"; group = "sddm"; mode = "0700"; }] else []);
};
directories =
[
"/var/lib/systemd/linger"
"/var/lib/systemd/coredump"
{ directory = "/var/lib/docker"; mode = "0710"; }
]
++ (if inputs.config.services.xserver.displayManager.sddm.enable then
[{ directory = "/var/lib/sddm"; user = "sddm"; group = "sddm"; mode = "0700"; }] else []);
}
// (if builtins.elem "chn" inputs.config.nixos.users.users then
{
users.chn =
{
directories =
[
".cache"
];
};
} else {});
"${impermanence.nodatacow}" =
{
hideMounts = true;
@@ -54,7 +70,17 @@ inputs:
[{ directory = "/var/lib/postgresql"; user = user.name; group = user.group; mode = "0750"; }]
else []
)
++ (if inputs.config.nixos.services.meilisearch.instances != {} then [ "/var/lib/meilisearch" ] else []);
++ (if inputs.config.nixos.services.meilisearch.instances != {} then [ "/var/lib/meilisearch" ] else [])
++ (
if inputs.config.nixos.virtualization.kvmHost.enable then
[{ directory = "/var/lib/libvirt/images"; mode = "0711"; }]
else []
)
++ (
if inputs.config.nixos.services.mariadb.enable then let user = inputs.config.users.users.mysql; in
[{ directory = "/var/lib/mysql"; user = user.name; group = user.group; mode = "0750"; }]
else []
);
};
};
};

View File

@@ -2,6 +2,7 @@ inputs:
{
options.nixos.system.kernel = let inherit (inputs.lib) mkOption types; in
{
useLts = mkOption { type = types.bool; default = false; };
patches = mkOption { type = types.listOf (types.enum [ "cjktty" "preempt" ]); default = []; };
modules =
{
@@ -25,33 +26,37 @@ inputs:
"ahci" "ata_piix" "bfq" "failover" "net_failover" "nls_cp437" "nls_iso8859-1" "nvme" "sdhci_acpi" "sd_mod"
"sr_mod" "usbcore" "usbhid" "usbip-core" "usb-common" "usb_storage" "vhci-hcd" "virtio" "virtio_blk"
"virtio_net" "virtio_pci" "xhci_pci" "virtio_ring" "virtio_scsi" "cryptd" "crypto_simd" "libaes"
] ++ kernel.modules.initrd;
# networking for nas
"igb"
] ++ kernel.modules.initrd ++ (if (!kernel.useLts) then [ "lenovo-yogabook" ] else []);
extraModulePackages = (with inputs.config.boot.kernelPackages; [ v4l2loopback ]) ++ kernel.modules.install;
extraModprobeConfig = builtins.concatStringsSep "\n" kernel.modules.modprobeConfig;
kernelParams = [ "delayacct" "acpi_osi=Linux" ];
kernelPackages = inputs.pkgs.linuxPackagesFor (inputs.pkgs.linuxPackages_xanmod.kernel.override rec
{
src = inputs.pkgs.fetchFromGitHub
{
owner = "xanmod";
repo = "linux";
rev = modDirVersion;
hash = "sha256-EugTfBbeH9VTpIg1aDNfaY57NDCA70QIdsOfzxWMSeA=";
};
version = "6.4.14";
modDirVersion = "6.4.14-xanmod1";
});
kernelPackages = inputs.pkgs."linuxPackages_xanmod${if kernel.useLts then "" else "_latest"}";
kernelPatches =
let
patches =
{
cjktty =
{
patch = inputs.pkgs.fetchurl
{
url = "https://raw.githubusercontent.com/zhmars/cjktty-patches/master/v6.x/cjktty-6.4.patch";
sha256 = "1kvmddg18pw22valbgx2vlxiasgxvszzm5lzkz096xm51sz72rm0";
};
patch =
let
version = builtins.splitVersion inputs.config.boot.kernelPackages.kernel.version;
major = builtins.elemAt version 0;
minor = builtins.elemAt version 1;
in inputs.pkgs.fetchurl
{
url = "https://raw.githubusercontent.com/zhmars/cjktty-patches/master/"
+ "v${major}.x/cjktty-${major}.${minor}.patch";
sha256 =
let
hashes =
{
"6.1" = "11ddiammvjxx2m9v32p25l1ai759a1d6xhdpszgnihv7g2fzigf5";
"6.5" = "0ckmbx53js04lrcvcsf8qk935v2pl9w0af2v1mqghfs0krakfgfh";
};
in hashes."${major}.${minor}";
};
extraStructuredConfig =
{ FONT_CJK_16x16 = inputs.lib.kernel.yes; FONT_CJK_32x32 = inputs.lib.kernel.yes; };
};

View File

@@ -49,5 +49,10 @@ inputs:
secrets."nebula/key" = {};
};
networking.firewall.trustedInterfaces = [ "nebula.nebula" ];
systemd.services."nebula@nebula" =
{
after = [ "network-online.target" ];
serviceConfig.Restart = "always";
};
};
}

View File

@@ -6,6 +6,7 @@ inputs:
marches = mkOption { type = types.nullOr (types.listOf types.nonEmptyStr); default = null; };
keepOutputs = mkOption { type = types.bool; default = false; };
substituters = mkOption { type = types.nullOr (types.listOf types.nonEmptyStr); default = null; };
autoOptimiseStore = mkOption { type = types.bool; default = false; };
};
config =
let
@@ -26,7 +27,7 @@ inputs:
experimental-features = [ "nix-command" "flakes" ];
keep-outputs = nix.keepOutputs;
keep-failed = true;
auto-optimise-store = true;
auto-optimise-store = nix.autoOptimiseStore;
substituters = if nix.substituters == null then [ "https://cache.nixos.org/" ] else nix.substituters;
trusted-public-keys = [ "chn:Cc+nowW1LIpe1kyXOZmNaznFDiH1glXmpb4A+WD/DTE=" ];
show-trace = true;
@@ -39,6 +40,7 @@ inputs:
registry =
{
nixpkgs.flake = inputs.topInputs.nixpkgs;
nixpkgs-unstable.flake = inputs.topInputs.nixpkgs-unstable;
nixos.flake = inputs.topInputs.self;
};
nixPath = [ "nixpkgs=${inputs.topInputs.nixpkgs}" ];
@@ -56,6 +58,7 @@ inputs:
environment.etc =
{
"channels/nixpkgs".source = inputs.topInputs.nixpkgs.outPath;
"channels/nixpkgs-unstable".source = inputs.topInputs.nixpkgs-unstable.outPath;
"nixos".source = inputs.topInputs.self.outPath;
};
# environment.pathsToLink = [ "/include" ];

View File

@@ -33,6 +33,7 @@ inputs:
(
mkConditional (nixpkgs.march != null)
{
programs.ccache.enable = true;
nixpkgs =
{
hostPlatform = { system = "x86_64-linux"; gcc = { arch = nixpkgs.march; tune = nixpkgs.march; }; };

View File

@@ -25,13 +25,6 @@ inputs:
"es256"
"+presence"
])
(builtins.concatStringsSep ","
[
"WgLCnlQcGP4uVHI8OZrJWoLK6ezHtl404NVGsfH2LXsq0TNVZ7l2OidGpbYqIJwTn5yKu6t0MI7KdHYD18T/HA=="
"GVPuwp38yb+A1Uur22hywW7mQJPOxuLXXKLlM9FU2bvVhpwdjWDvg+BB5YFAL9NjTW22V7Hy/a9UuSmZejs7dw=="
"es256"
"+presence"
])
])
]);
};
@@ -39,7 +32,6 @@ inputs:
{
enable = true;
id = "91291";
authFile = inputs.pkgs.writeText "yubikey_mappings" "chn:cccccbgrhnub";
};
};
};

View File

@@ -1,26 +1,33 @@
inputs:
let
inherit (builtins) map attrNames;
inherit (inputs.lib) mkMerge mkIf mkOption types;
users =
allUsers =
{
root =
{
users.users.root =
{
shell = inputs.pkgs.zsh;
autoSubUidGidRange = true;
hashedPassword = "$y$j9T$.UyKKvDnmlJaYZAh6./rf/$65dRqishAiqxCE6LEMjqruwJPZte7uiyYLVKpzdZNH5";
openssh.authorizedKeys.keys =
[
("sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIPLByi05vCA95EfpgrCIXzkuyUWsyh"
+ "+Vso8FsUNFwPXFAAAABHNzaDo= chn@chn.moe")
(builtins.concatStringsSep ""
[
"sk-ssh-ed25519@openssh.com "
"AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEU/JPpLxsk8UWXiZr8CPNG+4WKFB92o1Ep9OEstmPLzAAAABHNzaDo= "
"chn@pc"
])
];
};
home-manager.users.root.programs.git =
home-manager.users.root =
{
extraConfig.core.editor = inputs.lib.mkForce "vim";
userName = "chn";
userEmail = "chn@chn.moe";
imports = inputs.config.nixos.users.sharedModules;
config.programs.git =
{
extraConfig.core.editor = inputs.lib.mkForce "vim";
userName = "chn";
userEmail = "chn@chn.moe";
};
};
};
chn =
@@ -36,87 +43,145 @@ inputs:
hashedPassword = "$y$j9T$xJwVBoGENJEDSesJ0LfkU1$VEExaw7UZtFyB4VY1yirJvl7qS7oiF49KbEBrV0.hhC";
openssh.authorizedKeys.keys =
[
# ykman fido credentials list
# ykman fido credentials delete f2c1ca2d
# ssh-keygen -t ed25519-sk -O resident
# ssh-keygen -K
(builtins.concatStringsSep ""
[
"sk-ssh-ed25519@openssh.com "
"AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIPLByi05vCA95EfpgrCIXzkuyUWsyh+Vso8FsUNFwPXFAAAABHNzaDo= "
"chn@chn.moe"
"AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEU/JPpLxsk8UWXiZr8CPNG+4WKFB92o1Ep9OEstmPLzAAAABHNzaDo= "
"chn@pc"
])
];
};
home-manager.users.chn.programs =
home-manager.users.chn =
{
git =
imports = inputs.config.nixos.users.sharedModules;
config =
{
userName = "chn";
userEmail = "chn@chn.moe";
};
ssh.matchBlocks = builtins.listToAttrs
(
(map
(host:
programs =
{
git =
{
name = host.name;
value = { host = host.name; hostname = host.value; user = "chn"; };
})
(inputs.localLib.attrsToList
{
vps3 = "vps3.chn.moe";
vps4 = "vps4.chn.moe";
vps5 = "vps5.chn.moe";
vps6 = "vps6.chn.moe";
vps7 = "vps7.chn.moe";
}))
++ (map
(host:
{
name = host;
value =
userName = "chn";
userEmail = "chn@chn.moe";
};
ssh.matchBlocks = builtins.listToAttrs
(
(builtins.map
(host:
{
name = host.name;
value = { host = host.name; hostname = host.value; user = "chn"; };
})
(inputs.localLib.attrsToList
{
vps3 = "vps3.chn.moe";
vps4 = "vps4.chn.moe";
vps5 = "vps5.chn.moe";
vps6 = "vps6.chn.moe";
vps7 = "vps7.chn.moe";
}))
++ (builtins.map
(host:
{
name = host;
value =
{
host = host;
hostname = "hpc.xmu.edu.cn";
user = host;
extraOptions =
{
PubkeyAcceptedAlgorithms = "+ssh-rsa";
HostkeyAlgorithms = "+ssh-rsa";
SetEnv = "TERM=chn_unset_ls_colors:xterm-256color";
# in .bash_profile:
# if [[ $TERM == chn_unset_ls_colors* ]]; then
# export TERM=${TERM#*:}
# export CHN_LS_USE_COLOR=1
# fi
# in .bashrc
# [ -n "$CHN_LS_USE_COLOR" ] && alias ls="ls --color=auto"
};
};
})
[ "wlin" "jykang" "hwang" ])
)
// {
xmupc1 =
{
host = host;
hostname = "hpc.xmu.edu.cn";
user = host;
extraOptions = { PubkeyAcceptedAlgorithms = "+ssh-rsa"; HostkeyAlgorithms = "+ssh-rsa"; };
host = "xmupc1";
hostname = "office.chn.moe";
user = "chn";
port = 6007;
};
})
[ "wlin" "jykang" "hwang" ])
)
// {
xmupc1 =
{
host = "xmupc1";
hostname = "office.chn.moe";
user = "chn";
port = 6007;
};
nas =
{
host = "nas";
hostname = "office.chn.moe";
user = "chn";
port = 5440;
};
xmupc1-ext =
{
host = "xmupc1-ext";
hostname = "vps3.chn.moe";
user = "chn";
port = 6007;
};
xmuhk =
{
host = "xmuhk";
hostname = "10.26.14.56";
user = "xmuhk";
# identityFile = "~/.ssh/xmuhk_id_rsa";
};
xmuhk2 =
{
host = "xmuhk2";
hostname = "183.233.219.132";
user = "xmuhk";
port = 62022;
nas =
{
host = "nas";
hostname = "office.chn.moe";
user = "chn";
port = 5440;
};
xmupc1-ext =
{
host = "xmupc1-ext";
hostname = "vps3.chn.moe";
user = "chn";
port = 6007;
};
xmuhk =
{
host = "xmuhk";
hostname = "10.26.14.56";
user = "xmuhk";
# identityFile = "~/.ssh/xmuhk_id_rsa";
};
xmuhk2 =
{
host = "xmuhk2";
hostname = "183.233.219.132";
user = "xmuhk";
port = 62022;
};
};
};
home.packages =
[
(
let
servers = builtins.filter
(system: system.value.enable)
(builtins.map
(system:
{
name = system.config.nixos.system.networking.hostname;
value = system.config.nixos.system.fileSystems.decrypt.manual;
})
(builtins.attrValues inputs.topInputs.self.nixosConfigurations));
cat = "${inputs.pkgs.coreutils}/bin/cat";
gpg = "${inputs.pkgs.gnupg}/bin/gpg";
ssh = "${inputs.pkgs.openssh}/bin/ssh";
in inputs.pkgs.writeShellScriptBin "remote-decrypt" (builtins.concatStringsSep "\n"
(
(builtins.map (system: builtins.concatStringsSep "\n"
[
"decrypt-${system.name}() {"
" key=$(${cat} ${system.value.keyFile} | ${gpg} --decrypt)"
(builtins.concatStringsSep "\n" (builtins.map
(device: " echo $key | ${ssh} root@initrd.${system.name}.chn.moe cryptsetup luksOpen "
+ (if device.value.ssd then "--allow-discards " else "")
+ "${device.name} ${device.value.mapper} -")
(inputs.localLib.attrsToList system.value.devices)))
"}"
])
servers)
++ [ "decrypt-$1" ]
))
)
];
pam.yubico.authorizedYubiKeys.ids = [ "cccccbgrhnub" ];
};
};
nixos.services.groupshare.mountPoints = [ "/home/chn/groupshare" ];
@@ -134,7 +199,7 @@ inputs:
shell = inputs.pkgs.zsh;
autoSubUidGidRange = true;
};
home-manager.users.xll = {};
home-manager.users.xll.imports = inputs.config.nixos.users.sharedModules;
sops.secrets."users/xll".neededForUsers = true;
nixos.services.groupshare.mountPoints = [ "/home/xll/groupshare" ];
};
@@ -151,7 +216,7 @@ inputs:
shell = inputs.pkgs.zsh;
autoSubUidGidRange = true;
};
home-manager.users.zem = {};
home-manager.users.zem.imports = inputs.config.nixos.users.sharedModules;
sops.secrets."users/zem".neededForUsers = true;
nixos.services.groupshare.mountPoints = [ "/home/zem/groupshare" ];
};
@@ -168,7 +233,7 @@ inputs:
shell = inputs.pkgs.zsh;
autoSubUidGidRange = true;
};
home-manager.users.yjq = {};
home-manager.users.yjq.imports = inputs.config.nixos.users.sharedModules;
sops.secrets."users/yjq".neededForUsers = true;
nixos.services.groupshare.mountPoints = [ "/home/yjq/groupshare" ];
};
@@ -181,18 +246,31 @@ inputs:
[ "groupshare" "video" ]
(builtins.attrNames inputs.config.users.groups);
passwordFile = inputs.config.sops.secrets."users/yxy".path;
openssh.authorizedKeys.keys = [ (builtins.readFile ./yxy_id_rsa.pub) ];
shell = inputs.pkgs.zsh;
autoSubUidGidRange = true;
};
home-manager.users.yxy = {};
home-manager.users.yxy.imports = inputs.config.nixos.users.sharedModules;
sops.secrets."users/yxy".neededForUsers = true;
nixos.services.groupshare.mountPoints = [ "/home/yxy/groupshare" ];
};
};
in
{
options.nixos.users = mkOption { type = types.listOf (types.enum (attrNames users)); default = [ "root" "chn" ]; };
config = mkMerge (map (user: mkIf (builtins.elem user inputs.config.nixos.users) users.${user}) (attrNames users));
options.nixos.users = let inherit (inputs.lib) mkOption types; in
{
users = mkOption { type = types.listOf (types.enum (builtins.attrNames allUsers)); default = [ "root" "chn" ]; };
sharedModules = mkOption { type = types.listOf types.anything; default = []; };
};
config =
let
inherit (builtins) map attrNames;
inherit (inputs.lib) mkMerge mkIf;
inherit (inputs.config.nixos) users;
in mkMerge
[
(mkMerge (map (user: mkIf (builtins.elem user users.users) allUsers.${user}) (attrNames allUsers)))
];
}
# environment.persistence."/impermanence".users.chn =
@@ -236,4 +314,4 @@ inputs:
# ".viminfo"
# ".zsh_history"
# ];
# };
# };

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3D1PKR7xwlFBT/XdvGl9JkKTR0opBOQwxokR0Ri+zy0a6PgFFE6/L2NhgbHLQZt96J4lHl9ZxPdRgQ8Tc4+rptJiEX5VvZaNXmOC5wa5fGZuSj93HPEUzrtOv1sFzh2WgAeWd2nf7r/DoSYY91W1Bpsjx1YaeI6KvTHMeqoidTd17CcrMkIcOuYlgAHDeZ+vnxljTOddjK17D+AsG1+ThbDNwd97AlRv/pRkL2BAnHHNvL1UXVKg47IV4+60guB0Xqr947mSdCAomW1Oe9XbYooVRZZaVov1cv6NTQ0dZ6ktV3i+s7VXZh8dNkp46Hw68gI+fHp0I3mze5MblffpaGo2f0qQrJOROQygOyj/ihK1eMkPNKfdJE0odQ0z+1mwnwq5bhP5UPBvz6Z11M9Ez+/VtX3MG27RdVPMtoLSgHV7XwvVsvJQ5V+O+TkdO95IIlPuA2+1wj9O+Tsz4u4IS5xC7XXr9Jo+Mj1gbYnZqmTSldyBIkSUuKRgDF6oC4Fs= yxy@chn-xmupc1

View File

@@ -31,7 +31,7 @@ inputs:
{
features.buildkit = true;
dns = [ "1.1.1.1" ];
storage-driver = "fuse-overlayfs";
storage-driver = "overlay2";
};
};
enableNvidia = builtins.elem "nvidia" inputs.config.nixos.hardware.gpus;
@@ -68,7 +68,14 @@ inputs:
};
virtualisation =
{
libvirtd = { enable = true; qemu.runAsRoot = false; onBoot = "ignore"; onShutdown = "shutdown"; };
libvirtd =
{
enable = true;
qemu.runAsRoot = false;
onBoot = "ignore";
onShutdown = "shutdown";
parallelShutdown = 4;
};
spiceUSBRedirection.enable = true;
};
environment.systemPackages = with inputs.pkgs; [ qemu_full win-spice ] ++

View File

@@ -9,6 +9,10 @@ users:
zem: ENC[AES256_GCM,data:VCVLfGO9a06XhAOBciFf1u7A5jaQikAt2wZf+dCAi1BglXpM6Hof1yAunadYOwLOBFgGlP19kX53CBBlZtaqZFL2GRDzXP0woQ==,iv:AFYtHCCkzNrllN/fjQ8GKYs2TyV3uj3BsU5n1tBQAmM=,tag:5dP7c5N4yG2NS4T+Vg0Zpg==,type:str]
yjq: ENC[AES256_GCM,data:yn6eGrySCxlRsFioaE2p1qlTHkIGC9l64+edjuDvt232xc+iFeD03EYfuulyr0GxYFwnlAwtaJnyMi5eOrSd1W6HeV3Canzdbw==,iv:qTc6vA8uQza8CB+BvffEN9GqHkiwNM4h9RkqQR14ylk=,tag:UZ2GYCJLjcWLuVXlscLviw==,type:str]
yxy: ENC[AES256_GCM,data:71vjvwr29lfPCarnblpbW3WVyJK8EMV+cR4prc4AM3r0PG4z88P6i0IrzSy8XwkVPrEasfYXxn+vDbzXyi7kIWaWXrkjcyGTxg==,iv:LfkinvbIhchvgfgixIY8Wg6esrc+TOS4YWqRTJ0qfvw=,tag:mLPw6z8DOPrHsRpUHn3/gw==,type:str]
frp:
token: ENC[AES256_GCM,data:zYRZoWa3Llv0NiPXtSfhWUn+wt4uIcw8Wa+QBTzn7gLk6UVIA4FD7FLABBKoFbwg62Fo79Nn,iv:YZdOYkJf6BN76Z68nCtetKElJkqKiYmcx6UmLoIXSdo=,tag:5sC2vt3Z21KhgOU9mrfXhg==,type:str]
stcp:
hpc: ENC[AES256_GCM,data:lkpM4nzt8ymQ+5eV,iv:LvSShCSN8w0VsJYjICG9NWCMiw7NSPpoSZ+I2t7uILs=,tag:LLry5z4KpPdnN75x8dANqg==,type:str]
sops:
kms: []
gcp_kms: []
@@ -33,8 +37,8 @@ sops:
by9Rd0U0bzNiK21BQTNxN1RuQ09DQVkKJmSlzV5ppEkZFljsS17ZWmoI++fz4tJh
kTdoAStG1zsKASHyZTsmdm3RBDO3qV1KhQC2gC7d4EiwNZngxOOZJg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-09-14T11:09:58Z"
mac: ENC[AES256_GCM,data:f6D4N+He7Zz0VA2FxUzTARfckidgVlDHE1hZrYW6jDf+v9ZK/c/JAj12zLNiCy9aG6rBz5K0jdWpnTsguMlTYCKUjLcD8MSW4KJErYmeVFLpfuiSBMr0+pcSVA9DpEmekaYl0GbnxrgQKrfEL0dthR6+9m5CsP/1bvEs34XcKGk=,iv:0YVxL5iVOvmFzThk7fua2Cqpty9lTX/tdKNii5gY/UA=,tag:d+NwYbpeDziniYXwQYVCdg==,type:str]
lastmodified: "2023-11-06T11:12:54Z"
mac: ENC[AES256_GCM,data:nMnf+BTle1lrYnd87KZVk+W6N5y/P8SusF1Day7lstNxffPzLwaL+r7D9Lklem5nKPVYPA++ZSNpn2xn39rv24uJDmiI0lbkp/5tFK67flGehJr5YFssHSdsqhTs728IvropKuO3ZgTONVT1J0GSfrJVXNtIMsNgBCGceZ7ZHpM=,iv:2dCzL+do61xX57Do+Bw8gBWgdLgY6gIENdjqosOSGg0=,tag:K+fq9OvNDgwKrlo3InlHpg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

View File

@@ -4,25 +4,20 @@ acme:
cloudflare.ini: ENC[AES256_GCM,data:hPNpTclYvRbcbFO6aR9PNyHt3kDUmjeUgg4NPsr+c/yxKPundoiziNYBRfF7/axlw8Hu32jf/cDlcWaEmqCBQJY=,iv:bdGCD/a6AnGQhiFNyZ+fD1f/rILsEcPXC2qRDsAO4n8=,tag:MLZak9uSqsg/0Ldx2Wgb6A==,type:str]
frp:
token: ENC[AES256_GCM,data:0mE8/cWqHKNquCIiqgbjcNhipKk7KEfbZ+qRYbu+iZr7AH9QjfYZQiMJNp4Aa3JWwBLYAnpf,iv:ID4cc8Tn0H9b1CimXlPamMlhlAkafhRApDHo/CCQ4BE=,tag:BUuU/BCj16R7FlKlpubawA==,type:str]
stcp:
yy.vnc: ENC[AES256_GCM,data:IsZWkNGYHrbQcgvOSURDnA==,iv:4XO8RFBdNopLKYxCACmkXLMPu0wIVx64y0C7m2bsTVA=,tag:fMHzU9aQm0bRr8pTKwpuHQ==,type:str]
store:
signingKey: ENC[AES256_GCM,data:TsB1nA0Rf2AsYyH59WpUK53pTCX2JdrGQjkJ9A9BfWLLmw3EMnPoaLHG12rv1R2/xRU7rP+iVhXb77g60I/Kn4ehun3ogMmK1oEAKyQcxudBUJFk+SeijaQLr2A=,iv:e2rdGBVOPS1nyC3pXhs5r0WyEkqxcpCnX3eAcBCj93M=,tag:HwccjH2Wms5/TevU2IuzNw==,type:str]
nginx:
#ENC[AES256_GCM,data:sHSfWhEO9PHWTY0r,iv:XSyOSkzEVOjMF/9vjEVpcuKH6B2mdE5D7l9VKrSILO0=,tag:2YkAoPW5GqOjFpPF5IvApg==,type:comment]
#ENC[AES256_GCM,data:Oaxg1nXYHLNOAF2V8lNF+4OtJz5bXOdEleXi89AW+dQvDgj0HMAAlxLiixlfhFW48Clcu+C+4opFZUk+4Q3GBePTQWeabgEFAZi+MgnVoiXzfizQpmve,iv:/NyV6W0vaXvS5qFKPw+7Iqe9po1VKQDLbHaC9Fa8Mto=,tag:JiCKJxhpAI9k11N9WxfZew==,type:comment]
maxmind-license: ENC[AES256_GCM,data:PVV4VAvB22KoA8EM8Honb+KWYhydXdmTAVlDw/XnTcbaIY+5Km2gGA==,iv:7PfytRbpW4G2iDNqysvZnB0YsQFVUL5Kr1DNsBzuhCA=,tag:z2J14fdD7AUNabN+6kUojA==,type:str]
postgresql:
misskey: ENC[AES256_GCM,data:KiJ2smpRwJ1pzauCgVsmFH4aCiw4sEkCQ9JSTao5NdI=,iv:jIc0a797dokfByN2vJcYcAFfPC8MP7wCV5qsxoCDxcE=,tag:L5n1/xszwB0lhqYcbLqp2Q==,type:str]
huginn: ENC[AES256_GCM,data:Hb3Lkg==,iv:jhYobzvZUhIF4qzD7bzH0M78HtoQiTUuxqULMkk/i1w=,tag:MKqehVphO+jKb1L6E0c6NQ==,type:str]
misskey_misskey: ENC[AES256_GCM,data:MSDbQffk/WjZ6EYiwVuUMdhdv9VE59ZM7t4XldOKRO0=,iv:J/x9t4Pk5zi7Av9fbzxgAbbtbEUZttSx/JGRmmgmvE4=,tag:CwFR9K++T7YqYR932z3IAg==,type:str]
redis:
misskey: ENC[AES256_GCM,data:SAcZsRrhNB+CjpcvUcWLi5nhEA49bFM+HYHEkszNdZs=,iv:fOLletIWzCrhHZrgwl5dpdCnwUbcEeTaKNosXna8pfU=,tag:EpdBW/RexAoJ0z1G2Emvww==,type:str]
misskey-misskey: ENC[AES256_GCM,data:vcvQ/hs/F3BZd1sfvWwfEeB8vVoqdnprxobcmL6xsmg=,iv:S32yrjrjj56HbxTlfFGjOb+sO2M9KKEDEazCrpQWj6Q=,tag:iwnvqwQEdd6jicx9jJBdbg==,type:str]
meilisearch:
misskey: ENC[AES256_GCM,data:oBYIwQyfPyjsp1dfveVGqO7mY9LO7jaD+Mpe9nTm8Sd8XKgRPJWkce4tnBXBRzkdLURvDDD25uODUekdkkO1gA==,iv:/Gw3PX1w7dWWzEMCWrETGees8CjONwzIpTZSCkQsZXc=,tag:59GHYNPRTv3KFqhpUDXBLg==,type:str]
misskey-misskey: ENC[AES256_GCM,data:/wYR3Bz4LRk/Ks0vizlZS3Ebf5qVfnlBBqZEm/ZIBFdDuhddgu71cqCjTHIKQ6CYh3CoUyguKIIFWku/kOCHKA==,iv:dllKvZwxvZC4pVyEMOB9WNiVBsVxzo5kwbdYKCzzyrY=,tag:MvzqalVvBkyJoLbirN0V8Q==,type:str]
nebula:
key: ENC[AES256_GCM,data:kNm9hwMa/EhDeOCeZw1jEnroolTkeEeAxpSEDko6tHSDHwHbhfjr01ZzHKE=,iv:q2qCi99XgZJvRuF1dm16sK6BFIoa9QUN8p4LSiZq28o=,tag:ApOKdA91LBiWHv6TuXMkpA==,type:str]
huginn:
invitation_code: ENC[AES256_GCM,data:RVvK+w==,iv:lv/d3J2Ua1CcZiMugsbuHsSKHlXt6t7HmeTB+Szk91U=,tag:n3mgg6FabiLxvMIGeOgHIA==,type:str]
mail:
bot: ENC[AES256_GCM,data:+0C08g==,iv:V5BvmArE5+CkhK+yECLQwV4Nxpd/SiUVLj9iTF+kV0s=,tag:58dXyIZx43FOi51jSpWNkA==,type:str]
sops:
kms: []
gcp_kms: []
@@ -47,8 +42,8 @@ sops:
OUlxNjdQaXdXMkZ6bnV1ek4yZ2dpbkEKpKGOAxo5Eef2jtGrg4iSzmGCeg+vTgvu
+K8b+O19MIkGMDBm6UbYUPtc/7eqoEZRiTUzNMTmfkLVS4ul5zou9A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-09-16T11:06:32Z"
mac: ENC[AES256_GCM,data:hZCeW25Tp5+f0pdnysxGIYMBDHC+/nFJTBFvWDrL3s86cyjsrQRcEI8levSHAayEL7eFSD7t1syNSmwD13H74xiWwqroQfRKUfURze1mg8GLkT/sBoL8aw2cZdboE5OE8jfQxGYgovZUuBEtfgVCi6QDR+Q21uXtsDhp3MnwOI0=,iv:shA2SmoVv9LqP5fRvCUNq3Ts8gvuAcOyIARwsXhUPKw=,tag:BEOMEzyeuCAZrCRTxxz8Kg==,type:str]
lastmodified: "2023-11-11T11:10:21Z"
mac: ENC[AES256_GCM,data:ro3ROIx/9+pnS2Cdz44NKYZ0kDDdLPZJyXkBpYSuCrkotLzyDrx9Kjx1FR4CrQQeA4hOPQ9Z5qJVC1shef+UgwDwemiUhR3zq9BQv0PmsRYilT19o2W9tmgfbM0NiXISeN9w0MttlBUASq7mBUDbTFRViL9fAppRixkANLxVxmw=,iv:YR6QQNYQoK3v6RHUUWerM2cXU5oYQkSRfr58QDnw5H4=,tag:6Ig+RlVySAYEEiZTo8bs3A==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

View File

@@ -22,14 +22,23 @@ xray-server:
user7: ENC[AES256_GCM,data:7rxvmKbtYrDKBlo8kZIfd86KLd9EcSWB0ikasIRqfCZ24W0h,iv:Uplz4fnFymmBVZ9YTniHFFY3EVSrTYsg1+CTFqBu1WY=,tag:l3EPeYRHSeRsCyRhqFRrEg==,type:str]
#ENC[AES256_GCM,data:8FxApg==,iv:vPa5p3QVHAvw+ECusWGqx1ugTcHh42CVFDQcMhG59wM=,tag:lHiZtydcYFBQiXnWh8pCrw==,type:comment]
user8: ENC[AES256_GCM,data:FNT3hHMwPJu3iI1LuOP1KvsoOonh+J/ecrNrRQO5TpunDPUq,iv:tTEB0MSUmQ39tNq9v1BTfaEcJY7Y59CPHRASMC1a4U8=,tag:klDm6Isk52hG8ubcFu6yHA==,type:str]
#ENC[AES256_GCM,data:QdaYYH3RGJ4qIg==,iv:79NBTEKCPtgVVv3G7wg+vdoLOWxc+bdqT1lF4HJpTC8=,tag:8mRFGjy7lBrdyGyX9vaSOQ==,type:comment]
user9: ENC[AES256_GCM,data:4BD/4MXAVLhDm3EXdgTiEgPketf0WgflVPGb3/JMWXfycEKY,iv:jwE5sFVxZjORwoqCBdufP2EhetVtFGHyCP58AzJwle0=,tag:OCteA20hDBLI9zt1ET0tUQ==,type:str]
#ENC[AES256_GCM,data:U48hPlrJn2dF9g==,iv:W+6QEgemNa41VCT2OfBvEhuLAucLxfR+YZiDgdkkSnk=,tag:IhVstGnQ4EviT5ctMgyKiA==,type:comment]
user10: ENC[AES256_GCM,data:d9qxJQH9Jo8gJKUi5jjSdVwqzuHG+dj08Tk+TxhczJmlSaFT,iv:DS+9isZX2B9AYAyV4Yle4fpHzA/SHcR56B/GW8QdALw=,tag:9nUQ0OuMCuXGSZs2kjfnIQ==,type:str]
#ENC[AES256_GCM,data:DxZrs2B0LyPdLg==,iv:yZzEjyiY2s6gIPTsALl5xOsI0ByDvSBG4SI2+K6TLzI=,tag:hAniFFNS0SueybUKnRd2YQ==,type:comment]
user11: ENC[AES256_GCM,data:RPIH0DudfPJwPsa0yFLNqUy2EMwQh1bIqkmhCfteVTkUQGWP,iv:NH0aGTZ6nVqz2nn+o1HQS0PKpqHTBMkAhy0oFeyX/8k=,tag:kgd5zkHXW+oxRFC9x2VTUg==,type:str]
#ENC[AES256_GCM,data:aYWIiLxs1UvupQ==,iv:AisokHuAzD5B6fEF6ak8WfAe151CM3a8MsaWC4uJPnw=,tag:cdk5S4n9ulyWrqsD+jcqYg==,type:comment]
user12: ENC[AES256_GCM,data:Q+XcMYPWWeHqXZZt3lf9OurlWwVQGBJWTnRwDUvg7np19g3+,iv:ybREjo5/SFRN5LMSyYdm0ygkYoq/G1uBv9K0iGPqrh4=,tag:g2y8IJeXtHW1XjelOvT+/A==,type:str]
#ENC[AES256_GCM,data:D5xiJW0Oyg==,iv:9a/6myiT9Crf/fff6ZkXj/obW2k95cABUNqQdPmcwcc=,tag:chs8BA8YtVkM9m3Ey9ETlA==,type:comment]
user13: ENC[AES256_GCM,data:IKKk8joJQ5rcSXV84jbYd4uox548czpcgXwTtyK4rFimQIoO,iv:ycVDDSb0qAtZE8WzEdKkaBYKY13JpKj+4xrgkLogikw=,tag:z9ty67NWIgGlh1psbE5qVQ==,type:str]
#ENC[AES256_GCM,data:ujz8CAgN2g==,iv:2KP2DwIfIPPnsyZRSptG6x80n0cQGoiYCFoLRbFeEos=,tag:oITBAiHs1odW3heSEOQAJA==,type:comment]
user14: ENC[AES256_GCM,data:WFhrirjRUEZlOaCLGvHzvRPyp5O+035k0bNFqCvs0UTdT0+y,iv:C2vvOexQwFFkQyvFd8tf7lca2ZZIF3hbSiOHa2RFfGU=,tag:zowYrIut44mRiq6/h0r4fQ==,type:str]
#ENC[AES256_GCM,data:t9mAcEcdBg==,iv:hzqb80+FtfsNP8ofYMyT0PwT8T8B3HYSGZUOrnk3SjM=,tag:0mbDe6S0bqbC/SffMr0AAg==,type:comment]
user15: ENC[AES256_GCM,data:Sfc4BWiQ5dz7K0kwlp/1e8x/ahPTnbTvSvFjz9R5KQL52uaO,iv:kzap3jQgm9P22teMkYJHlySh2azLBBuy/kpm+ylxIhM=,tag:2fOBw+McYdT3r+qoF/Wkzw==,type:str]
#ENC[AES256_GCM,data:S7Iodket2fLLhcDDuWgv6fVAbcg=,iv:2XlrHA0A36xrmEv7kqtL8i8EYnNpq7cjRMmsF+mPu4s=,tag:M6JvHYU6jqqinPoHcgnEZA==,type:comment]
user16: ENC[AES256_GCM,data:ijz4n66TY2tGpKLvGr7I6n+cOP6BfgpJdHmcPy2oTPGCvhR0,iv:RK8wi3Cj9XFVTqqt00DLru12Hiu/WJU8lV/v9MF5deI=,tag:6SHR8Yb2dO1rRY/xV5u9yw==,type:str]
#ENC[AES256_GCM,data:inAhj6SP8p4KahuZ+aSjPfnEcOY=,iv:eB6OvUkQvfdAkNuf95K7jAjZZ8i+nbsnsH3WEdRWFhw=,tag:dgw+RFY2cm6jF+R5z3Z+XA==,type:comment]
user17: ENC[AES256_GCM,data:Wz7tWzASeIKE9TzicUIwyOnjZDDICYvDAUu/scHrQoFjoOlE,iv:A2gPFSiIXaf1dQkFlXjw5yesKtv3qOVcIXzM2QspvDk=,tag:JWCVx2FJS84v2iMdzBxhlQ==,type:str]
user18: ENC[AES256_GCM,data:xQMRt+YC1Kn0Qxtis9QVIypq4uHNLq2sWKxxQe515Kfg+zzw,iv:28nQibxqzx5Q17UkEwK0zYhu6mFJ8LUk78xxlQrIqFY=,tag:B7N/fC81v8VBTsDdIZDvDw==,type:str]
user19: ENC[AES256_GCM,data:Qjajmu6cfACT4eho6BK56zRd7BSXxo4fUeJ2RRawopVFZESJ,iv:QZN81pQxspe76V90NQxzsKmMwtvaC1qwuvd5a6WbrdU=,tag:/+LYeQLqvwM60DgIPtZzKA==,type:str]
@@ -86,8 +95,8 @@ sops:
ZXFTU3ZCaW1pTVh0RUJzdDdGdHlPYTgK2mlgcX2kEc8+2UDdBnhUm6IIuh8V6agW
ooxH9OEPXUVI/4JcDo4v8ZUhAyU1ehLH0Ef7PJCChOZe2KZmWSNbhA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-09-03T08:50:37Z"
mac: ENC[AES256_GCM,data:+w04X4hdgiBO3VpCI5tM2h+X13m3QOQeMdcmKGavqBoC9S+jx9dOoy2H9FdhjyYN/dkhglFqG5LMnHqEsdLGSwSxUsJDmHMm3MvFLJYIybvanNB+Gxb9+ooBNpC/e+d1iLg85mAUTXhLlezw5gaRHtwiQ4llOXZesE+c+Wnbbws=,iv:mM5lw8pFJoqYvz8uIi+oTqJFyIHq6HjspYTaEJp2xzY=,tag:9AqRnzwUxIV/ClJATxz95g==,type:str]
lastmodified: "2023-11-15T03:24:39Z"
mac: ENC[AES256_GCM,data:vUekGOHfSM9qBZCvbUYA/PUZh9zoxDg7EgVsi35jJt+g8EYeG8LGCkEdoHXhoiTayLNUNPpYSLid1xnHGOg43wtpBZfR/UC8OafcOu+hIGdojxTfnEWsQk0lT3Qt/AyYA0PbakDxx6JiH8RRADCb2+ZZ3V2PuB6gE7Rc7tWpvOE=,iv:gIIySdB1CGeSn7tamGa0UxkXtdHfF1J5Ta12BgYB0Yg=,tag:Lqx49Aa/0QbAUwdkm4b0uQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

View File

@@ -1,19 +1,26 @@
acme:
cloudflare.ini: ENC[AES256_GCM,data:PJ3JhdSPCyxzdcRI4UFdESWgyAjIYGyuVaU9l0R3s8mJidtgavvSSMy0hC0G/2fauLB/Eqc3L3NppXFjlKVywVE=,iv:lZVlOf7P/Vs/+u/5YPKFXmdeYV9NP9kcVWd00w1OjB4=,tag:LfWZTvPQH4QPrNrYfZ/Z6Q==,type:str]
nginx:
#ENC[AES256_GCM,data:BwkND2sU5FkdN72C,iv:DNIdyY35BfBYtlJijfI17s7aP8zj5Y/kUAieAYSTr3w=,tag:016xmeOvZC3Grc8JLGcVaQ==,type:comment]
#ENC[AES256_GCM,data:NX8myRAMhMS7qx0T+471E9Wz//AKXt7FoY7P8cUOvJ/Xz+AKkB2VfP45gyPvds6zwwKuYtRLqvPD84afjE/mf2wAij3VEkprJKd5VMl+RQ==,iv:LYdigyW2VUlqo/3IvC7CRaiFsnxMyQIryHf2yFMJ+Yw=,tag:ttNAzJRCz/owZSe/V3eOPw==,type:comment]
#ENC[AES256_GCM,data:Ss47U7TQO6OS21/eLVnLGO/Gpz7V7I1mlQS2SC/6DQk3bySZK0Omyd3Nyctz7FX+ix1RbeRd7//JKNc8Dtj19jpicBFQpZMV,iv:j9QD7TmRvfzFLkLLlRcwrAHcklfGJ0R6Z3cpbli97vk=,tag:lhEkAmm/AV0gTLItdVcZ4A==,type:comment]
maxmind-license: ENC[AES256_GCM,data:9aW4QR3K6S+eTqzIjVlNEwkG0wZ4u5jgRfe7CMwRlJlK4AmcS6c45Q==,iv:cPTN1K4Aag5sohGbCQUZHYTvcwAL7AhF+rrY3OvXGPs=,tag:d9GGUMHnfzRz9Cf2U+dBfw==,type:str]
redis:
rsshub: ENC[AES256_GCM,data:uPnZIjbnRRoWIHlWkZNZkMpIb3Ujnnpb+AisVSVGFv4sfDAuDlAjt39pRdnWkCXJPqtXjJzQ+FeT34cqxTf8Bg==,iv:/jcyAHkxByFnbkmCAYQwda2QRmhW7L/ICoLuCgsVLCI=,tag:M5Q+dh/Bn7FiNpqQGYus4Q==,type:str]
wallabag: ENC[AES256_GCM,data:WkiqS9TOHxYalDp7Ssgg2x7vj4D58psQ5au4a0e3LZBecERwzUKmrhbVKRuDvNTwWbYxSds9SAca0wN+pWmrmA==,iv:QqHlzSXG1I4+p8wd58lcQs8TqAF3foxiYVdgL8L3IpA=,tag:CPtFgIeFL5W25gtd6NFkrg==,type:str]
misskey: ENC[AES256_GCM,data:eT0zEdnFyNNr7G6QMn5JpTa5M+iI9B4HdvPLvfwCGRZ6MyeYrpsO97B2V0YzIaJAi2Md20hMgJdD6BVXcDp9pA==,iv:e/2/ITEHCKATyAtGxWm9hJ8T/pcV6Je/RgU1AowXEfs=,tag:Ohdxg2Y/Hl5ewrv0Kv8ywA==,type:str]
misskey-misskey: ENC[AES256_GCM,data:OHjt9o+m++NT5aaFbwBT/wSMdUdgf4zscd/JxjCo5HDhC3WeWMJV7z//kATI5Dg4BWAhvPlL02Vrly4RraIzLw==,iv:sQB4/D2SsOuDR3bTrmlNg7o+6ehFznDsqVc3BX9pK20=,tag:tcwTBt/JhyW8ZTAIWIkWBA==,type:str]
misskey-misskey-old: ENC[AES256_GCM,data:amUqMycdXUFvjg66pXKnlZqiESBYMci0k8iYzj824SaEqHl3Nq/I0TjYX++xEUg+RGYyTIcSaj96HUANTKpc1A==,iv:ND1mQLHxltRlOdpJ80ywheGo6hkl7OgRyk9TguJMuTw=,tag:dhCCwnCOnyT2iXdEMK0szg==,type:str]
nextcloud: ENC[AES256_GCM,data:jwN/CqwkU/5Rd6w75/bV2Yej9b0CoxZaiJEcZXFx+9XUPY3Xg1tQdEr1SALG8xzOEdoL6WBVs14NvrrL25GeTQ==,iv:p5+0AB52QqScJwMhNIrM/7HAcRPdD9Z8xV6uwIDOwIg=,tag:f1XbNDDRXvGl/dkV9Wp2Ug==,type:str]
send: ENC[AES256_GCM,data:IGxj3cgp+fQBdupfK+IgPEQSPuXdM9LRSLGSATNIkzUWC6sQw1aaKTDuRc8cU2BG6quthRwuWnK/F7k3KrUi8Q==,iv:LI9MkaF4e47FPUyL7AXZpO+CdgF91ScdiqjrE8PZjJ4=,tag:eNugln5M0AhU1xmVWFN7Aw==,type:str]
postgresql:
wallabag: ENC[AES256_GCM,data:ANwvEE3K/W/hU34Y7RvlbUuJNo2bOaRfeusYM9pRxXQOdG4XpwYfd/DprsrVjlkrMFuTurUR5j6UNHWh+ILDbQ==,iv:K8doqhVosz+OosMrLJXrSxairr84EeGs3EWgVQjpkS8=,tag:WjDzy7ubm/GVlBkW0O3znQ==,type:str]
misskey: ENC[AES256_GCM,data:OXKLrkPDgVTdsZolzLVOlkYswLVFy0LSXiGjohic4j3t9cTrMIfBa7LbA5J7VlLryO/ISzLpu8lt9aEsmjYSSw==,iv:V4n3MUkAnbLs5gBOOqCubHxuKJGvfH9dND1YgD1YgCs=,tag:RXiXeekS76pGHUz3oEPQ9w==,type:str]
misskey_misskey: ENC[AES256_GCM,data:lRbSz7bbiWEdK/cRD41fLvFJF4WYsclKHVykFcU3LIz9vnKlR3VdczzznVqpT7JvG6OUi+TmipJii+0KzXHtdA==,iv:8sBKgVwuDJdThup0KQ6cnAV5O2liwVra1yIpDHVfpMI=,tag:DyUpaHai8ZUyllvZBUm8sg==,type:str]
misskey_misskey_old: ENC[AES256_GCM,data:Wwtd+hKI0s7m3PbEPHbnSyTsCkW0x8SYHUiCYuNSNCG8i4RAmiAbONNFfWN2hXnmTmRK79Tx/3GR+L0KMzmNGQ==,iv:BekTELToPQXUdZHyNtkuqKyZeez+moI6k907P7NhA3Q=,tag:A5YB0WIa1RkDCtzeBhiuyA==,type:str]
synapse: ENC[AES256_GCM,data:Orfse2arRGMujA8MloqOp+iVr0+uCVtlMZJNAA36J3UCog5ExE8HE6G5wIvvoP0o/PNToYc9Jgn8T7iWdU6FIA==,iv:XQ6/bDfIRmvZ3VdTqH5Gaiu2emd5kV+q6RjNXDQEtkc=,tag:Yq+w9oxv2yhpsQfMRp4HaQ==,type:str]
vaultwarden: ENC[AES256_GCM,data:Uz8GJMaLUTQ9pQbZyZLWS4bL5wmt9RvbAwNctAIDt9JrV3FaXxgKjE0MJSGklS55yj/Z/wbO6RCuCK2AWR2VKw==,iv:7hA8YcB88M1qCV8EhFYpHbfPmAZ/7xNqvTMJYZ/UcAY=,tag:mkDHJYmRoYZ/Ct0UmOp9FA==,type:str]
huginn: ENC[AES256_GCM,data:s9Y9VGq4UYZael28LEwA0fF97HVZd7neM45zXxZUsRj75WCjif0jcl8nc2cLHhys7yfsZNxNgsDuOmLWX1l8mA==,iv:Hnx8Py6NELPkj0mVn4OQaU8+CIq3FMC/UZElY4WsB08=,tag:+5+Nyqvr2udUprIBm9dsaw==,type:str]
nextcloud: ENC[AES256_GCM,data:5UpYSMsZgUgEJHg0ou9Z1RTE+YFFUKuXwPtc6L5XxD4GNo8Gd3CvcQSNGAol+5DtyPKF3q1+ZgtScWGrqU1RyA==,iv:Zfm+Oa4eON8WiJzYUkMFawafDwo9pOnOpWkwHYLIKkk=,tag:4ECMla1dFfCrn7lILwWFNA==,type:str]
meilisearch:
misskey: ENC[AES256_GCM,data:+oLR/0G6bjSz3jbZxeoGbLd7I4AiJDxodpc8DEHmHjYaNS6UrQEO50ekNSm3DpcK9+bqMJl4q+d1PWXgHRJbIw==,iv:rQcq7LksBhJr26D3112y41ryW3cEwnG6XLgiFhLv3d4=,tag:/PaX7MIERrtqJoayzdf/AA==,type:str]
misskey-misskey: ENC[AES256_GCM,data:4s+qqd6mmstioC0XmG/vA6ED9mzu1vRJVPFFalRiqnnsFy0dYEU87H+y12eOp/KDSLdTNvpp6Z6jCNvxnpDXzQ==,iv:x6L9OPu/dwVsD9pYb4dqavw9NesMbo7LB+rwz6veAR4=,tag:/BBqV2sHIgPas7XsZydh2g==,type:str]
rsshub:
pixiv-refreshtoken: ENC[AES256_GCM,data:EeSOTSAAh+1Dc8+a/AaPJ0aBK5DTa3pdS6DrIMQmRw/n0SRu2QoynIF76w==,iv:dnZxi8jM1I4w3C2duYielpP/8wOAdHDjcqDIrowM0dM=,tag:8irGvLEbRJHV9TB8Jibs9g==,type:str]
youtube-key: ENC[AES256_GCM,data:OEm/ynOUPUq7ZEVzL2jgs9d+utkLTIdNq0MHE0JDujb9ndAwyJJI,iv:RRae6Cg6GdDnXAQOdtBYmcA7ZNuu70VpIg2MEezBn5k=,tag:gX4ZG345cT3Jh3ovUxtLGw==,type:str]
@@ -33,8 +40,18 @@ nebula:
key: ENC[AES256_GCM,data:9o6EkfTWOU0KwnJsgHML4E7VOfzo3LHnlOkV8ubhi6aayXImC3lAaoPrqUI=,iv:KHprijN7z+4FIIW+D5klDM9a9VzMJ5xawPc7jJtbHmk=,tag:0DAmxoz8D5f38ndPbkNW+g==,type:str]
vaultwarden:
admin_token: ENC[AES256_GCM,data:muavuOY88Lm4rSEoCp4IIPp7Z+sqf36VwpnPgf+K6IwwFkUgYM1GO80ogReYWqqUM6ij1Yzl5D9ncUbq+aGTKQ==,iv:jA4MRJlz71CMmPnWjb2tGbbIoMkEsESUowhXDckKKMI=,tag:l0HaJmnU29YeFUxjOgN3Kg==,type:str]
mariadb:
photoprism: ENC[AES256_GCM,data:TF1SZVFnvzyE+7vrHYYUS4Juqhbiw9QcJx7p3Xj88xyBFcTqS1YjzAKs/9GQ1PuzdBrt6hXm/XtJILHiuktnSg==,iv:sd9sQEuIePL6LzUYbFtmdecJ57sMrkF0coalBf8KFqQ=,tag:P/knaKYTJ+aXu4l6IixISA==,type:str]
freshrss: ENC[AES256_GCM,data:ydqCbj3UbsLC1e++p5ixb5Kpmk2BsYd0urcfw8T51Is5N1/gQ7P0zgR33AOteAxw2oj85WQZhxu3eAN7BCXV5A==,iv:1oiMo1wwFNXiTZLsf4UPZSJfKFIWLI3h947TC06CVy4=,tag:Otq1oeKBnWXhqNilfsywPQ==,type:str]
huginn: ENC[AES256_GCM,data:1Tdg1WDwGgFSXdChgif8knWS24BIFYnmaiSjJXxs5uj/v/5fJ1alb4K4XHW/kFRjQbuAOFfJiJ9ogJ1KAyk17A==,iv:qLMaQpVaKrjP7g2lWzhaNLghxwiV4YJmyYY1hrpu5I8=,tag:566JCENvOxgwD7tM3aQBiw==,type:str]
photoprism:
adminPassword: ENC[AES256_GCM,data:gB81joOfS8h05BNy2YmD/N0cpLPa/vAduDcQBeHiY/WkcnvqSXnXsOfnvbP74KQfoP4W35oFkfyGVPUBSB83tg==,iv:AkN2NoqMXVHQA9fHTTR7xbEapEqy/D61mHn7O23hyYk=,tag:WV+siDA3VnRkOYnP4Z9Qhw==,type:str]
nextcloud:
admin: ENC[AES256_GCM,data:1rglLrLtRf3yXQwfHDMZLewk8ueIbMFOC+1mtoAyLKnDmcQAoEQZ1vHw/hpKkFXJQ+QyX3sP8eUjRXuBEIVl3A==,iv:lfEGPEw9ybSdOYLDdaGCLXKgCvgRxn3k9eIy2DJHDYU=,tag:j4qRexbEAgK5HAGhr/wxfA==,type:str]
freshrss:
chn: ENC[AES256_GCM,data:XGcgfuRozJ/xowtmFPSW,iv:yZ9LTuVE8dGyrtE3vxLA2jLErvmt67XC0jefl1njiOM=,tag:J5d+oGFWhfXEFwVOnsJ2iA==,type:str]
huginn:
invitation_code: ENC[AES256_GCM,data:8YxfbtlHhzaQpEXpFua81W/Uifd9b2Pv,iv:7BfoOxA1B0ZzRrhoKG1R1f1nT5GkNqGB/gpgl7oa2oQ=,tag:cKoWVqCuaiwEuQdYUDgbSg==,type:str]
invitationCode: ENC[AES256_GCM,data:+m2AabRzUiCFy3MAKTB8d1IE05WHTcmZ,iv:ccdIPHl9N+bvPR/QCwZUwZOfWTeW6gWhhBjOpL85JRg=,tag:Ir2085K04XUGkAuoCG+7VQ==,type:str]
sops:
kms: []
gcp_kms: []
@@ -59,8 +76,8 @@ sops:
SnFHS1Z0SXUzTFdEd29KTy9DU3Y3R0UKfhh+rUmWDrf+UGjclP57dHipPLFoXSqy
HdelmfV6q4/c7ppx2E+oZw3VNgoZCsrxxzYZfwxHJiZb+5vkE0D8iA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-09-16T10:57:23Z"
mac: ENC[AES256_GCM,data:FXdxVeb2r36ONCfNBUcOOjjcnAx+uIlf1bIDpYdOZHKdVOEx1PMUMgBngnMgzuiMXIILOeH9tFE6gerkaaKnSao1RUE65UScLnqwzpRFlgwqI+gFS+Ng8gWUaZO3qVCr2lQCegYBtevqhAy8+Dmew4EkYEiD0MTIomZgnlPu5+I=,iv:wKqLmD4Vjr5mtA59e3O2dMYMK0LANBODVHAN2R8CEsY=,tag:dFUhQe09u0AAz15CWtiXkQ==,type:str]
lastmodified: "2023-11-12T08:55:55Z"
mac: ENC[AES256_GCM,data:AlydFHt0M965B+1r7HxICO730giPv5hAqQZX0K0hqetmq06Z2hmSFaHdTbZx8nBEqJTbzUekN9w9bckzxnLNf+VGbhdAVzIhvU+zoXs1324UdtJqze2w3kPUYhzyC3ovubb0RRd81pgozvGXRTJ10WVcXpI7j2P1DjpPWp6hmHg=,iv:irfEAtnf0U2oMHdf1oNSLD7eqWKdXiLJBlCmsutnb7k=,tag:VkmZ8hWgOZhwfM7p8V4stA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3