Compare commits

...

78 Commits
hpcstat ... r2s

Author SHA1 Message Date
chn
457bd2571c modules.system.nix-ld: disable for non-x86 2025-08-12 09:49:54 +08:00
chn
599b1e7ac0 modules.packages.minimal: disable rar on non-x86_64 2025-08-12 09:48:17 +08:00
chn
bcafae7509 modules.hardware.cpu: allow null 2025-08-12 09:41:41 +08:00
chn
86ff4c3feb flake.nixos: add r2s 2025-08-12 09:40:22 +08:00
chn
d3e11bae79 update synapse 2025-08-12 09:06:20 +08:00
chn
d6a63ed7e5 init aarch64 support 2025-08-11 12:26:57 +08:00
chn
8fb107b071 modules.system.grub: allow disable grub 2025-08-11 11:42:24 +08:00
chn
c0eed934c7 flake.nixos: add aarch64 support 2025-08-10 22:45:10 +08:00
chn
1498a1989b devices.nas: enable xray server 2025-08-06 12:34:03 +08:00
chn
8e029de511 modules.system.fileSystems: set hibernate mode to reboot 2025-08-04 14:20:28 +08:00
chn
c9a231a4b2 devices.pc: update xray xmu cookie 2025-08-01 15:22:55 +08:00
chn
4c1c00fcc5 modules.services.xray.xmuServer: fix 2025-08-01 14:09:58 +08:00
chn
b0fee64fc7 modules.services.xray.xmuPersist: init 2025-08-01 14:04:54 +08:00
chn
2acd77be56 packages.info: fix 2025-08-01 11:24:35 +08:00
chn
b824220f15 Merge branch 'biu' into production 2025-08-01 11:13:54 +08:00
chn
2150fe6636 packages.info: use biu::exec 2025-08-01 11:12:02 +08:00
chn
8f72efadd3 packages.biu: migrate to process v2 2025-08-01 11:11:57 +08:00
chn
4a5e976d5b modules.packages.desktop: enable localsend 2025-07-31 10:43:58 +08:00
chn
9858c48d90 packages.biu: fix stacktrace on exception throw 2025-07-29 20:13:14 +08:00
chn
2eb6f4ae67 packages.biu: fix stacktrace on exception throw 2025-07-29 20:12:09 +08:00
chn
b4df678546 devices.srv3: nixvirt adjust 2025-07-28 20:06:59 +08:00
chn
8bcecb9d9b modules.services.nixvirt: fix 2025-07-28 10:12:18 +08:00
chn
2f40ba8166 devices.one: switch to default kernel 2025-07-27 22:19:14 +08:00
chn
7483935e93 devices.srv3: nixvirt remove alikia 2025-07-27 15:31:35 +08:00
chn
8db43a7812 devices.srv3: nixvirt yumieko swith to httpProxy 2025-07-27 15:30:10 +08:00
chn
48bab70958 modules.services.nixvirt: allow more web forward 2025-07-26 22:01:49 +08:00
chn
72337e2c7e packages.biu: update to boost 1.87, fix logger 2025-07-26 10:02:50 +08:00
chn
9d0bea2683 packages.biu: update to boost 1.87, fix logger 2025-07-26 10:00:44 +08:00
chn
e4cf0007a3 modules.system.kernel: remove unused kernel module 2025-07-25 22:59:23 +08:00
chn
b745e79f6c devices.one: switch to unstable kernel 2025-07-25 22:59:19 +08:00
chn
6af5814ca6 modules.user.yumieko: init 2025-07-24 21:27:28 +08:00
chn
527e0028de packages.sbatch-tui: use enum instead of string 2025-07-22 17:07:50 +08:00
chn
19c1babd3c module.system.gui: set gtk theme 2025-07-22 16:11:16 +08:00
chn
4e81de1d29 modules.services.nixvirt: allow change iso 2025-07-21 19:03:10 +08:00
chn
80b9ae7d8a lib.buildNixpkgsConfig: fix for non-nixos usage 2025-07-21 18:09:13 +08:00
chn
01bde3548b devices.jykang: set march 2025-07-21 17:57:49 +08:00
chn
8ee26927d0 packages.chn-bsub: cleanup 2025-07-21 17:53:24 +08:00
chn
ce4b8d824a modules.services.nginx/xray: fix transparent proxy 2025-07-21 13:02:16 +08:00
chn
4c398d466a flake.src: downgrade vesta 2025-07-19 16:18:59 +08:00
chn
cba657be2a modules: disable niri-flake cache 2025-07-19 15:41:24 +08:00
chn
e19d24ee28 flake.src: revert vesta version 2025-07-19 15:37:29 +08:00
chn
475a122108 devices.nas: add xray listen interface 2025-07-19 11:16:26 +08:00
chn
ceb1172d69 modules.packages.vasp: add atomkit and atat 2025-07-18 12:18:55 +08:00
chn
2e27420fb6 packages.atomkit: init 2025-07-18 12:17:35 +08:00
chn
5197fb8afe modules.packages.zsh: add hjp 2025-07-18 12:09:15 +08:00
chn
6a1dbc7c3d devices.srv2: enable speedtest 2025-07-17 19:17:26 +08:00
chn
b0d4cb637a modules.user.hjp: limit wheel only in srv2 2025-07-17 19:15:29 +08:00
chn
524953cff7 modules.user.hjp: add atomkit to PATH 2025-07-17 18:34:36 +08:00
chn
04975b986e devices.srv3: nixvirt add yumieko 2025-07-17 17:01:44 +08:00
chn
4b4c883448 packages.atat: init 2025-07-17 16:49:37 +08:00
chn
0cd648767b modules.services.speedtest: init 2025-07-17 13:46:23 +08:00
chn
377a1a9011 modules.system.sops: fix 2025-07-17 10:30:03 +08:00
chn
5385eb7b7a modules.services.nginx.transparentProxy: fix route on systemd-networkd 2025-07-17 09:47:16 +08:00
chn
ffc17cf127 modules.services.xray.client: fix route table on systemd-networkd 2025-07-17 09:27:59 +08:00
chn
df3f1d0ff2 flake.src: fix lumericalLicenseManager image hash 2025-07-17 08:16:06 +08:00
chn
9e59ef502b devices.srv2: 使用有线网 2025-07-16 17:49:37 +08:00
chn
33c47388a8 flake.nixos: remove test devices 2025-07-16 09:19:48 +08:00
chn
8f5567576b flake.packages: 整理 2025-07-16 09:19:41 +08:00
chn
2099aa9e12 modules.hardware.gpu: fix nvidia vram usage 2025-07-15 23:09:54 +08:00
chn
0dfd0219af modules.system.gui: init niri 2025-07-15 18:43:51 +08:00
chn
da4f5fa5c5 Revert "devices.pc: switch to prime"
This reverts commit 505f93053f.
2025-07-15 18:17:43 +08:00
chn
505f93053f devices.pc: switch to prime 2025-07-15 17:57:02 +08:00
chn
ca26d7f8e1 lib.buildNixpkgsConfig: use bees from unstable 2025-07-15 13:58:07 +08:00
chn
3849301a72 devices.nas: more threads 2025-07-14 17:28:37 +08:00
chn
a12ff043e1 devices.srv2-node0: enable bridge 2025-07-14 15:40:17 +08:00
chn
39ed76bae4 modules.system.network: support wifi 4addr 2025-07-14 15:28:20 +08:00
chn
5066a83d6f modules.packages.minimal: add ethtool 2025-07-14 11:27:22 +08:00
chn
f6deb524df modules.services.lumericalLicenseManager: allow disable autostart 2025-07-14 08:55:18 +08:00
chn
7a82f92743 devicesr.srv2: add user zgq 2025-07-13 15:36:42 +08:00
chn
34a444cc94 flake.dns: use self hosted dns server 2025-07-13 10:26:36 +08:00
chn
70f3ebdc42 modules.services.bind: fix 2025-07-13 10:22:21 +08:00
chn
b3802d7ef0 modules.services.xray: fix 2025-07-13 10:01:33 +08:00
chn
eb92fb319e modules.system.sops: fix 2025-07-13 09:54:35 +08:00
chn
0b9ccc9797 modules.serrvices.bind: init 2025-07-13 09:29:35 +08:00
chn
06321475bb modules.services.geoipupdate: split 2025-07-13 08:29:40 +08:00
chn
c21aed27ab devices.srv2: switch to 5G wifi 2025-07-12 12:14:21 +08:00
chn
3e1b621434 modules.system.sops: rewrite 2025-07-12 11:12:24 +08:00
chn
f9dc3d7357 devices.cross.secrets: merge acme 2025-07-11 09:56:46 +08:00
113 changed files with 2175 additions and 1464 deletions

View File

@@ -54,6 +54,3 @@ creation_rules:
- path_regex: devices/cross/secrets/chn.yaml$
key_groups:
- age: [ *chn, *pc, *one, *nas ]
- path_regex: devices/cross/secrets/acme.yaml$
key_groups:
- age: [ *chn, *nas, *pc, *one, *srv3, *vps4, *vps6, *srv2-node0, *srv1-node0 ]

View File

@@ -1,89 +0,0 @@
acme:
token: ENC[AES256_GCM,data:Zm4vCgYbrm8wtYMYqtRkMF7hm8feTcZXITKbJgWsgagWbbHE5Z8zoA==,iv:RSRw188gjoAdhTErApuF8tBSsD+aT3LGhifcy417Qzw=,tag:4ZHfkW8aCJ6BW8mtL261yQ==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1dlVnM2FHWmJNSXpDTzhR
Q2EyK3JENDFGNlFVT0pvYjExd0RDT0VQTUNBCjgwL256NnVGNXBVVG1WdmFVNWRI
NDdLL0hkZU5JRXFYM2ZtZG5pakpVT1kKLS0tIEl3VjA1bE1lbHMwQXpwSjBENnpB
VkpraG8vRFN6RHQ5ZWNrMDFhZGpSaVEKlpOVSF6oFpHIEAnY026JPOmyTB4MGJh1
44R3bbMIA1Zo4uZ/lySvWum/oh9h9UTPZPYybts/0NOiX9gqcBuH7w==
-----END AGE ENCRYPTED FILE-----
- recipient: age19lhcwk37jmvn6z0v4dpdfh0k4u23f76twdjknc0p7atktf37rd7s4t4wj3
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvOTJac2ljQ0FLYXIweFJp
bXM1Sit5WDQ2N0tqdllmc2c1ek9Rd1JJZkg4Cm9sY2JybkVlYlNZSE10ZS9YSU1q
UnRLQzNJWGV0aVUxeFFTV2M3cldJSEUKLS0tIE9MaU1BamhMTmtFQWFFNmZKQ0Jo
WXFtcjZlVVFuVHdLaTVzNnFvYTB6RGsKOondd9JP142bPU0Jl82/LpBiFvLYBlaS
CcP1V7NRC2gQpxHhhYRYN9fuFrWJnUzbAPaIMhMeG3sPIvS2LLwyCA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1ffvr5pqd2lfj24e3fh53s92z6h76fda3du4y4k6r3yjumdwvpfgqzj033a
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBURi9oQ2xvR3l1TU5id2Uw
STZDWjZ6R0sxVkNZZWdYSlRDTENxU1UxKzFrCkI4UWhGZjRIVEhiU250R2VUa21y
OWgzTWs5WEM5ZVFSS01zZHhsUlZVSkEKLS0tICtjOVIrSXcxUW9ReDFpbWtMOTEr
MmhzbEFiVzlobXN4ang0UjZRcHZrOXcKxexbMBS/tTp4MIW93R0K/2+gdIHDYpT6
x13rwFfMo/laZGJmtSwYQyRMacpfgsgzwq36qKCOLJ/J/ESht9AA0A==
-----END AGE ENCRYPTED FILE-----
- recipient: age1m7nrxfw22wvp7pj8y9pdl745w95x89uu8dzl9ppsaazweqf2lqms5yshsp
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1dzZoZ0lzQ0owSXNRcHlm
b1lqL0ZCN21YWFMyNENScnRjR1ZuVEVFWkVVCitxbW1HL3pGVHk3VndKcVpDdC9B
dWJ4MGpZckhYZEdOM1RzNlVqajFocGcKLS0tIC9GcnZyeEtJWHFIanZCTmVuYXRW
VThqakFKWE5tVTduZ1NkQ1h2NDdiSmcKsDg83RzJ33Q5v+DuyhYLaQCHY+bBTlY1
roC7Nic/mTGHV9NikjJpxJUrdIZ9PZcpRFV+7HEteosTNt9WKPWOkg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1n4lhfwv7g0vhx54exmwx9yv2z04m3h2lunzpa5zdzgtcvjjuf5nqc36g8a
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvTVJ3S0sxbXRQd01TeEZX
bEprbTQ3M1BwZy9naWNFQzlqRXdFVVRlNEZvClJyeURyZCtoaU1idlZFU0wySUFm
TTdMM3JsbWZuY1R2TnVON2N5dGN2cVUKLS0tIE5qWmU2d1VDYVlRd09STWtRU1E3
OGhRV29PWlpOdXFhUWU0WTg3Ni9YR0kKmnbM7HuN39AecfIGPIIr+NcNoNBwbtM3
UHgKT6Y6JaCt5BFMFRwvB9hClQn6PUOMjkuIb0BYD2repwP0E3P8qQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1yvrl4y0r6yzcxzzkgfwshlrtsjt8uuya6rfwks09pnft7esfcyvqmrtm5q
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLYkN5ZlBGZ0pSenpIdjBh
SmNHMHk1SzFDWFduSFZYVW5kdUZBdittTlQ4Ci9VRGR2WnRKeUcxdUF5UkZXSmZR
dzRPbG9ITDlSWjk0ZHQ2b2Z0SnRKUFEKLS0tIERxL1NTekJWOVBmVDVIMWpkYjJB
M2xQQnhqbGFWaVhtSnZrZXpBTWNZckEKPGZDtSOZqDhMAG46CZR7Z9TguWC0k8eV
3RK/51cpDRP7CS6cQnYHlQycFjnL+e6sCiKZzWXQXdgoW/1DWysNHQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age164tyqklwhdm57tfm5u863mdt2xrzrrzac4py8a0j9y6kzqcjy9zsp073t6
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHV3hlbFUwQnk1RmROU2Qz
LzhrMDdZcHFrdlF4cGRLL1dmMy92T2Zpc0M0CnJNd3BPdjNLanBCaTY3Y3lsNk9Z
UjVLem1Hell5ZjZsdUE0Z2U4VVk2a1kKLS0tIGJUTFcyZG41T1JsRm9mdHZaYlNs
TlBuY214bHoxcmp6ZnlLQ3Nja1c4L3cKTbEnAk/lRZi27QomwPB+xT4eLDWygDZ/
B6H9JgCdDuh9azNx07GxCpybzMFZUQjqrzzHqfqxYqMoWKMJoHXmyA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1l4stuz0vr7gs7pqwjrmezam44702jp2vmqaqyxw0l0r42kf9updq4dfhrw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBETU85VW9zc3p3SmtaeC9l
TmpyOGE5WEtRUjV2VEdvb2J2aURvZFJLclFvCkt5QnI3THVUK2VHaDdzVjhNRkw2
U25rWU96WmowNk5xTE5odFJqcFI3N1UKLS0tIHhBQ3ZKekZ6d2VSd0NRSHJGdUJV
Y1d4TmRpRGJrUm45ajVHcDRzRG1VbUEKjZcnDgP4JqcUfixQXvwI9XSZMtiX5fwU
FxOyTyRyxaPbS5b8RBBXrRqiIMCaOkggzcU0LZVOs+nBtqiiaqlw1Q==
-----END AGE ENCRYPTED FILE-----
- recipient: age1nzetyehldf3gl6pr6mu5d2cv387p8wjqn6wfpll7a3sl8us6n38s0ds633
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSNlRubFNJNVpKVFU2d2xK
amhYSC9Tem9IeExVT2lSN1VTaUZiZ3NPZmc4CkkrclY4WitoYllsVGdUMGphU0lz
WDhwYk5KckdTa0tlenk4Qk1odHpSb00KLS0tIDNwVnJLaCs0MzhTdVdsZVA1VVhU
RVQ1RFdXVk9TMWFWdHhTZ2dEVU51a28Kx2iABI3gz0lVLfzpnFKJkIxDFgSkOr9M
87HD5YsLAJ1ACiQzC+BONcdW3FZmu2K6xP/dJXgCYU+2iD39p/cJwg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-09T13:04:33Z"
mac: ENC[AES256_GCM,data:xKqvMTW+TTKPtuHh/pSGvxXXIpeKtzVWgwKPibGX9UTIpnDNzfylmkT6OouqQyI/HTQmiL67ch6gaFSMAbXfpw7JA9YpKif6p84rs3RelKzRLKinDpUtcvWhY1DEA2nsNWOdFHxu7EZhHRbXttRoB372kdV5063MJRvwuqslMpo=,iv:T4ff9w1AYGO9JIzuJz6VbPoS19OcIy9zFvOMLp3F2LE=,tag:x5Yk7tVSilKK68ZRhAnsIw==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View File

@@ -36,8 +36,9 @@ telegram:
user:
chn: ENC[AES256_GCM,data:mTt2D+SkvVL8,iv:L0Pk5p46E2kKBdRWCGpwOKS0BsbIhZUslpIFWvkssMY=,tag:+AjbNJ1SW/8Mx1HLpWAd2w==,type:str]
hjp: ENC[AES256_GCM,data:ZXTQhax0gT4PKw==,iv:MerbaWWC4SLazEuuJrxAxf9e5aaX9xpq9St+h9aqvMQ=,tag:x9knShK90OKZPcn9fKzvMA==,type:str]
nginx:
maxmind-license: ENC[AES256_GCM,data:MtmNo6hHlU75N6PvzF7P5i6Q+myV4Keb1JRXVeHxTennNpKfAndsKg==,iv:DqM91JX+1WX8Zqzha2Tm3ztFaSzKYQg+b9NvUm+6jxY=,tag:XnDTBL9MA/B8XfPZqdk7Eg==,type:str]
maxmind: ENC[AES256_GCM,data:KfTXvxX4zzXBfNMPmZY1z5jTHTByGfH9qEo6EUAQqZ1JOtNUomOWNQ==,iv:KcexOWAXFhWfli6bAMZ+61x960trZ3iE9UYMuOtJNms=,tag:reuuIe6MkONpeT44U6yUjQ==,type:str]
acme:
token: ENC[AES256_GCM,data:DrNdcyf2tiZ5nmjYmsG13V63ZuZhNG1c/kkGM7eXQWvRvDbu37nKWA==,iv:xc4gtNvZ/BYG+KmT1XgFfG3Z17bBLURazG8tz4/laxE=,tag:khnYVQWjiiaQC9VsJyLV6A==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
@@ -175,7 +176,7 @@ sops:
UnR5Y24rSTk3WUV1VUgvQUFCVUxPZUEKv/lTy02gZYn4jF1uGtm+LhJd0m59Xe99
+unmqUDh0ZqAhJU8o0jrBiWs1lXOHU7CkIom7tGEMHGUxHkS+Z/6GQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-05T03:46:51Z"
mac: ENC[AES256_GCM,data:5M0XoU1HrzWBkY8N0fObYkeVuF9o8sH4NJAHeCgN5Lqc1gdW+qUnJ4FzJlpPepw87bhWNogXSl4/qRzDFiMpSrDgqaMPhZA0E9eimm659Poe02Rj3LVTOT7UGVaUck+IVgSDx1skQ3hc+yU7ytY5grSoz6rqn4u/uW/prb9BkoQ=,iv:Tt+JNSzZQx9C+FwoCDwctVLQc5rAh5XYOnjsgCSBTJo=,tag:AIz4HnaQ4c7fkdWluiQsYQ==,type:str]
lastmodified: "2025-07-13T00:27:59Z"
mac: ENC[AES256_GCM,data:iBBMsGOD7nDpXDPDlB/ml06y4WVe0uq7dptn5VZSppoxGA7BmRfWq9OKueXykmgfueqC3N45KVeRh3/b+FrsIRuTl1iyKnT3pd/naGTguQBfFewhrbqNc6UaDadpEVSgYiS76A5JwEoemePPHVUboDOSe0ru3uzNk1nDh/85jRg=,iv:8/GpDArKPYPG2O41p97oQZHkmIgIVdB7OWLvMrDXlaI=,tag:sq3B5Zo7XoA151WmgtvMMw==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View File

@@ -5,7 +5,7 @@
let pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
{
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
nixpkgs = { march = null; cuda = null; nixRoot = "/data/gpfs01/jykang/.nix"; };
nixpkgs = { march = "haswell"; cuda = null; nixRoot = "/data/gpfs01/jykang/.nix"; nixos = false; };
});
in pkgs.symlinkJoin
{

View File

@@ -25,8 +25,13 @@ inputs:
services =
{
sshd = {};
xray = { client.dnsmasq.hosts."git.nas.chn.moe" = "127.0.0.1"; xmuServer = {}; };
beesd."/".hashTableSizeMB = 10 * 128;
xray =
{
client.dnsmasq = { extraInterfaces = [ "enp3s0" ]; hosts."git.nas.chn.moe" = "127.0.0.1"; };
xmuServer = {};
server.serverName = "xservernas.chn.moe";
};
beesd."/" = { hashTableSizeMB = 10 * 128; threads = 4; };
nfs."/" = [(inputs.topInputs.self.config.dns."chn.moe".getAddress "wg1.pc")];
};
};

View File

@@ -2,6 +2,11 @@ xray-client:
uuid: ENC[AES256_GCM,data:97aX07G5FPumdWcDxnYOs6fRgljXWuwyNXGg1d7zdbUUfNnb,iv:+wAC/DZXsg+evYFA4DMfLw5Ut3ExQl1RgZ/2AsNQDpo=,tag:ebD77muITHof+FQMydWobg==,type:str]
wireguard: ENC[AES256_GCM,data:JaOSq474mGOoQQcdJ/j9fYo2e1vjXMPxJ69TOd079FrSkbzbIteWww5f8Xo=,iv:uy/NC2+tibL61XJDZK/spKjV9u0oXK4YzjFjYmCAL0k=,tag:en+c8cHaPvDqJL+EpQjr0g==,type:str]
xray-xmu-server: ENC[AES256_GCM,data:3O5rFi5szla70M/c62JV4nGWKPSOREImrOucjeVYf9bde6K8,iv:PGCqlmHtaNuWOtAAeJ6O+CWFpMszijozU1OpUFrftjs=,tag:iGTOoNvQhhZy2FL9jy1KIQ==,type:str]
xray-server:
clients:
#ENC[AES256_GCM,data:gToh4rgMOQ==,iv:A14sSC7ExbSZNOzzz6mOmWalSz9K6ROoSYgCqdF7j4U=,tag:1Jr2FfVQ9L2w+bWHh/NekQ==,type:comment]
user4: ENC[AES256_GCM,data:/ZrgvlpwDlKhcHqkBRsdqqJsNUxtb3ZnC36mc8qlJ+HP4mY3,iv:R5QzXY0mC72TDB0OcF4fJt3bc5L1Z96Q+n9kNbZP7m4=,tag:tjWSEcsG0udvQZZJ/RMTJw==,type:str]
private-key: ENC[AES256_GCM,data:34FOslwr3AZNDg4YrS95S20agGXwGJRNGnpogMR7utbt1ELUxfQkiAU1qw==,iv:4fiJCi6TJM+NIlfI1qFX/eCNhcVaCWGsLA7iMjQpATw=,tag:eLz8HlQMprQNryk5saqyVQ==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
@@ -22,7 +27,7 @@ sops:
by9Rd0U0bzNiK21BQTNxN1RuQ09DQVkKJmSlzV5ppEkZFljsS17ZWmoI++fz4tJh
kTdoAStG1zsKASHyZTsmdm3RBDO3qV1KhQC2gC7d4EiwNZngxOOZJg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-30T10:53:22Z"
mac: ENC[AES256_GCM,data:XJIKLsszOcJfL9RDcFs7nTDfVIxUGtwhKZhkC7eCKni03b3M/sl2cIwAJ/L20Q+riP2HFcS1ljQA+SjlnY29KWr7DqJ1dM0qcqHjMSlWjurMWPgD4Lf8C7kx2J+6naYiQotQb6y7AfRF9XxAJUaHQe9DdlqHT/bmbtVW5VN1tzs=,iv:IhU7Wo19KOsqxdlSuZg3KtDc08E0dUq2Ahb1J09iLK4=,tag:N9TumoFTKEw/4DT51Lyjjg==,type:str]
lastmodified: "2025-08-06T04:33:54Z"
mac: ENC[AES256_GCM,data:DMLcRc1hDS0x5Gt0WA/6kfEi7KKogeKHBfuW9gndj7fPqCyyYFzW9Mn8mZ3UhWB68c25GtKyLdo9T5yFivS90JB74kEWrQn/Nfdy0wW18BOloiRwLdSipoADwYwpJtr+JGNs9R6AqIAoDcbVJrr4q6kZh/Cjue6TJiyBdI4uirU=,iv:YOn7XzKAKtzucq6h0yAgj+Ee6L3srscnvieCOmZjBeo=,tag:lnAfv2pWVf5czeTgL4donQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View File

@@ -30,5 +30,6 @@ inputs:
};
bugs = [ "xmunet" ];
};
specialisation.niri.configuration.nixos.system.gui.implementation = "niri";
};
}

View File

@@ -108,14 +108,14 @@ inputs:
podman = {};
ananicy = {};
keyd = {};
lumericalLicenseManager.macAddress = "74:5d:22:c7:d2:97";
lumericalLicenseManager = { macAddress = "74:5d:22:c7:d2:97"; autoStart = false; };
searx = {};
kvm.aarch64 = true;
nspawn = [ "arch" "ubuntu-22.04" "fedora" ];
nfs."/" = [ "192.168.84.0/24" ];
};
bugs = [ "xmunet" "backlight" "amdpstate" "iwlwifi" ];
packages = { mathematica = {}; vasp = {}; android-studio = {}; };
packages = { mathematica = {}; vasp = {}; android-studio = {}; lumerical = {}; };
};
boot.loader.grub =
{

View File

@@ -15,7 +15,7 @@ searx:
secret-key: ENC[AES256_GCM,data:KhIP+Rz3rMfNgPEGTlKGvm6gl1/ZuPI=,iv:GcaLEJHKJO3n6IaeiFr9PaJ6eNx04/VjX3UgmBF429g=,tag:HkplyH9hTHUaEZ709TyitA==,type:str]
xray-xmu-client:
uuid: ENC[AES256_GCM,data:XiUkReTJLAxZNWFVeD6EiOtUX5tsyPLFi6QyDBdHyB4v5/mD,iv:QppdtP2CFDEVhlrmDJKYBGc1zYGJvpGYxLfsBAMxDSI=,tag:jzMSFRit+aBzWMkaa3+5hA==,type:str]
cookie: ENC[AES256_GCM,data:fx/cqNNpI71FslngfeXFQA==,iv:xZEtOsKgS/8xNqF4B6NKI9+klrpNcraW17KKirMnEfM=,tag:YyczKED2Yo0D6I+RvMjJLg==,type:str]
cookie: ENC[AES256_GCM,data:0jqSEZloX2/c8Zg4WTKkLw==,iv:BKLm1KMoRrH0uO6hPMsv2a7sG0AwNRrdbpmABP4BszA=,tag:pBs+rQIhhNO4Qr6q1V3MUA==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
@@ -36,7 +36,7 @@ sops:
OUlxNjdQaXdXMkZ6bnV1ek4yZ2dpbkEKpKGOAxo5Eef2jtGrg4iSzmGCeg+vTgvu
+K8b+O19MIkGMDBm6UbYUPtc/7eqoEZRiTUzNMTmfkLVS4ul5zou9A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-30T11:24:37Z"
mac: ENC[AES256_GCM,data:V6Gs9hCPIb42nW81Gmy1dz5LFLeX97UuzVbvst/rtuSJHdFzXKxYqIGjHNRK5mGWG/NdTXQ79ELlvpSOgKYAk6gn9ZMn9wCDDbe6spDoGBWL4Ky7mCiSPRcLZ++J+2nP0Q987kZ6IMdMWkFNJmOKWBX/nnp4/aicwyteqNHt4cI=,iv:1wWS0D4RJeWKERfqMQRB75Nh1oKSQzF+r5yOphMrg9Q=,tag:DBPZx1+X7nMLW9xsyEn62A==,type:str]
lastmodified: "2025-08-01T07:22:50Z"
mac: ENC[AES256_GCM,data:f4fultak/52Gq6nn1hJJYw3AMeuR3J6gcxtPDG/WKkNV+B+gtabWp5R8J8wLWFJ4C1ZsGHDYMTvTfSUlDVdm1dGpxJtFzdfoBBdajj8s2mju6nMQUFoNFRmHDZEQBdIzfXpob1+7Rsr+bBmg7HnFvjR0ozuaQP9QHsHEZxJVbnU=,iv:xh4OIom1TFgKralXw6rrOR/1xpD5SpY2tHfJUq6v41o=,tag:0QOtWN6DcGf3/gorusbXtQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

23
devices/r2s/default.nix Normal file
View File

@@ -0,0 +1,23 @@
inputs:
{
config =
{
nixos =
{
model.arch = "aarch64";
system =
{
fileSystems =
{
mount.btrfs."/dev/disk/by-partlabel/r2s-root" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
swap = [ "/nix/swap/swap" ];
};
network = {};
};
services =
{
sshd = {};
};
};
};
}

View File

@@ -76,7 +76,18 @@ inputs:
};
};
packages.vasp = {};
user.users = [ "chn" "xll" "zem" "yjq" "gb" "wp" "hjp" "wm" "lly" "yxf" "hss" "zzn" "zqq" "qmx" ];
user.users =
[
# 组内
"chn" "xll" "zem" "yjq" "gb" "wp" "hjp" "wm" "qmx"
# 组外
"yxf" # 小芳同志
"hss" # 还没见到本人
"zzn" # 张宗南
"zqq" # 庄芹芹
"zgq" # 希望能接好班
"lly" # 这谁?
];
};
};
}

View File

@@ -11,7 +11,6 @@ inputs:
network =
{
static.eno2 = { ip = "192.168.178.1"; mask = 24; };
wireless = [ "409" ];
masquerade = [ "eno2" ];
trust = [ "eno2" ];
};
@@ -28,6 +27,7 @@ inputs:
hpcstat = {};
ollama = {};
sshd = { groupBanner = true; motd = true; };
speedtest = {};
};
};
};

View File

@@ -7,7 +7,7 @@ hpcstat:
key: ENC[AES256_GCM,data:+Z7MRDkLLdUqDwMrkafFKkBjeCkw+zgRoAoiVEwrr+LY0uMeW8nNYoaYrfz6Ig8CMCDgX3n/DMb0ibUeN32j3HShQIStbtUxRPGpQMyH+ealbvgskGriTFpST4VPyQxNACkUpq/e+sh2CmLbKkSxhamkjKOXwsfqrBlgVbEkp7u7HkWGuAaYL1oPGt0Q94fWXwH0UVhRYZYQ2iFA/S6SEZY8gxaTIGDKUdWU9+fOHzPQ5WfhxtKYU4p4ydyfYsAt6ffqnPSx/SI72GsUCOJ4981JX8TuvnEzx3gQLVFYheK6NibTWCy6eODbvguieVOTHSvCPTrHmoP12lHVWU2kKzLwv70Jl7sXyzKHYROG0D+/z/4DKlNeotKM/IA0q2cST08/lwSKN7WDDmrt+O6xXhvwby28ZYKEsSvvrfV+VIKzHPl84ZKbUEX5xv/GHc3THfznUvKKz5PzDiqrkjCkEt5PRMsVW9A6MU1+QEUr+sXLLtcUd2CCL87c8CpwNHJx1us6vJ4ji1gu0PGoT+60,iv:yU6j9W2Hs2D34uHMJqqPFbNy2pNEZY2kzXoNdhPMSmA=,tag:TNvEfMVrhu7HrNxY8qe5mg==,type:str]
wireless:
#ENC[AES256_GCM,data:n9OPSJsB7yNk,iv:xQzKJxqPB7uT83m/B4UoOje6NQbPLhuHR7Hp93oNz8A=,tag:gtsTx6ALnS/7fIDd7VimOg==,type:comment]
"409": ENC[AES256_GCM,data:XJ2apDx9E4RM7YzK6wYzxn4eBkVS3l6LIaMtUai2MZ/W0xkaixyV/g/s+cVQtgph2gEcNoLOWbsxr3h8CsrOTA==,iv:O643ytrgHKB4RM6lZKZcr0fLmS2icRnek9praw43jWc=,tag:6Pk7CmiJyvAeW/1V4mvRJQ==,type:str]
409的5G: ENC[AES256_GCM,data:K9wm3zedoil7jHgTcb+VmbdbkG2dgrMdr3BmDRUHDVADqLANMvnUMSecggYTO4HaiI9q6uv2/BSkluanD5K4Dw==,iv:7dGET3ULKlnaDMVmkuXDek+hQPLZ2VUbPqvEOX+5jlQ=,tag:MBGmQ0NNNqX+T9EsBiWCaw==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
@@ -28,7 +28,7 @@ sops:
M0xoL1dQR0kvMWpzN0RMNWVCTFQxNFUKj9LPjBo5NGOrGYNvu8qZ13PLYjLEWllU
LARzEn4XgkeHckouwvxZYMCx7WxmAruRWaOvnxTIczzSNP7wIrqnkA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-10T10:08:37Z"
mac: ENC[AES256_GCM,data:ELeHLFJuOUs8CFIuu08zqp56AijpxxLKlfUo6cWmqwURy/BC6CTFqkNwsD8NirCzSsNTRnwk3pAVXPjJCrk8rnnH4uqiA639h3qMdEpHJLsVhv2+ounGObW7+R/IYJQaSmBWHzZimQsAbp2eVufu3mnu3wjUOhXM6xs0ofuxLWM=,iv:M7PK2S4Okb0MhsJ6d/bJfkMUOoXUMwbWVsHiuxE6Nt4=,tag:4QwSM0dU0mY5Xs03RS1FUw==,type:str]
lastmodified: "2025-07-12T04:13:47Z"
mac: ENC[AES256_GCM,data:W+e5d1scvV24AdVdl7Pisp9HxsXQ/tPjN2NV/Bd0RXZNBRB7LNQrSfk1GadboBnihW0ctAQOFk66PZsxwE2czfFL2/yzFxm9Cf11Mc822ZL3BwjnQBK4uR9LJrbjL7x1lFUk9v0AIPhjrir8F6dcX8mq6++hHNN0wjGaH3J9E0Y=,iv:RK7e4Dxog+Qsgk6gxK0f8PN8oF9bjWIrTyYK67Cdras=,tag:QSKsETYXbhnvhhjavP4UiA==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View File

@@ -36,12 +36,6 @@ inputs:
sshd = {};
nixvirt.instance =
{
alikia =
{
memory.sizeMB = 1024;
cpu.count = 1;
network = { address = 2; portForward.tcp = [{ host = 5689; guest = 22; }]; };
};
pen =
{
memory.sizeMB = 512;
@@ -59,7 +53,7 @@ inputs:
{ host = 22000; guest = 22000; }
];
udp = [{ host = 22000; guest = 22000; }];
web = [ "natsume.nohost.me" ];
web = { httpsProxy = [ "natsume.nohost.me" ]; httpProxy = [ "natsume.nohost.me" ]; };
};
};
};
@@ -72,7 +66,11 @@ inputs:
{
address = 4;
vnc.openFirewall = false;
portForward = { tcp = [{ host = 5693; guest = 22; }]; web = [ "example.chn.moe" ]; };
portForward =
{
tcp = [{ host = 5693; guest = 22; }];
web = { httpsProxy = [ "example.chn.moe" ]; httpProxy = [ "example.chn.moe" ]; };
};
};
};
reonokiy =
@@ -81,6 +79,21 @@ inputs:
cpu.count = 4;
network = { address = 5; portForward.tcp = [{ host = 5694; guest = 22; }]; };
};
yumieko =
{
memory.sizeMB = 8 * 1024;
cpu.count = 8;
network =
{
address = 6;
portForward =
{
tcp = [{ host = 5695; guest = 22; }];
web = { httpsProxy = [ "littlewing.yumieko.com" ]; httpProxy = [ "littlewing.yumieko.com" ]; };
};
};
storage.iso = "${inputs.topInputs.self.src.guix}";
};
};
rsshub = {};
misskey.instances =
@@ -100,13 +113,13 @@ inputs:
gitea = {};
grafana = {};
fail2ban = {};
xray.server = {};
xray = { server = {}; xmuPersist = {}; };
podman = {};
peertube = {};
nginx.applications.webdav.instances."webdav.chn.moe" = {};
open-webui.ollamaHost = "192.168.83.3";
};
user.users = [ "chn" "aleksana" "alikia" "pen" "reonokiy" ];
user.users = [ "chn" "aleksana" "alikia" "pen" "reonokiy" "yumieko" ];
};
};
}

View File

@@ -1,9 +1,9 @@
wireguard: ENC[AES256_GCM,data:Coe4iIEnJVDb4a9KUVTRkXl4kng5Zo6x1Iyr0ErgR2b9bN287mvO6jPUPSc=,iv:fiNUUKobJjitcoxBemIah5Cl5+dSz2Q7sbiOT8bDrRM=,tag:rHfNeRGTxnyVYAu8P/2ewA==,type:str]
nixvirt:
alikia: ENC[AES256_GCM,data:sP3sWN0RrBU=,iv:TetUcaxsRXl0QsGAyXbVUAW12AXjChVN1/X+ku+3nO4=,tag:kBupoPqVlwHuCnwVdBJBKQ==,type:str]
pen: ENC[AES256_GCM,data:okvzUul3UXk=,iv:hcBhsUMP8jdhhKuKdHD1lZi8ixNAC729HfMQ79UzyNk=,tag:SRRav39ScHn0O/sf86CIOw==,type:str]
test: ENC[AES256_GCM,data:MYlMmzgbW9c=,iv:q1qPAwFTh0fj2IHBIlnrOMbTU2BnwIYzOFUHVqWCY/Q=,tag:Mb2bJJemg/LxpKI5whNvQw==,type:str]
reonokiy: ENC[AES256_GCM,data:J/ZM0Vavmnk=,iv:ZT1cMF/JWLWmXyBx331XkBQerOhLJeOd0a53jcSC4S4=,tag:/WCwzOg5LlAS5ZaiI5DSIw==,type:str]
yumieko: ENC[AES256_GCM,data:Nugm6tP4jxg=,iv:HweUreniPs3eDs1ucu/G/P/JZ4jfSaOAiLD2o5WeOUo=,tag:eoc1cVG7CD5WFoawDUUpnw==,type:str]
nginx:
detectAuth:
chn: ENC[AES256_GCM,data:cek6iIlJXgU191uzq44rTw==,iv:r7aMj5UzH1sbKkxvS8oyw6kpIcpRygD4ype8qkmnNa0=,tag:x2jWZnnFCO0sHj/OS2BQbA==,type:str]
@@ -84,6 +84,8 @@ peertube:
open-webui:
openai: ENC[AES256_GCM,data:5B1wPAOx3GsLDoYBKHWFzoyXFmn93fdcq6UC2rCt/P5zYLA4VNzfsp0=,iv:Y2gTLCmwB5wY4dhN73HRvTqSMVXbAEd+RjRbgUEuTeE=,tag:vcfNhXpG0C3twFBsm7PHwA==,type:str]
webui: ENC[AES256_GCM,data:Lg32DZ5GC+AYzWc4WloNMQlnpsqW67s5/kXzYwE=,iv:ECncgdYoLkX9GUOX26MXFSO8JOZahUDjTdKV87IRNJ8=,tag:J/5tTR3MI0iGIVDrlacYEg==,type:str]
xray-xmu-client:
cookie: ENC[AES256_GCM,data:z1KI3CUfPqyiI/B/qgrNhg==,iv:QEjUlMkkF/fdwwEIGiJJ5UxFGw869qAnpApmWaRn3GY=,tag:EbdJsYEslwJbARxDoEWrDA==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
@@ -104,7 +106,7 @@ sops:
d0h3aDh5QXFZYWJFdmNVYnJxQ3pBeVUKTl0XVvtwJcz+RpSylgDPl/R8msInxvWX
eQGmrDHibeE1V+KSDiuNzC4MVRIrOnh1beHrhnVQ86HwPVgJqs2FoQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-09T01:35:04Z"
mac: ENC[AES256_GCM,data:q2BolEBB6Ik8yx6NHnnE3Wcl2rGVZN86dpfLJrrFOxWd8fZyfBQ/00v4dUZSZw0aQoMj1V2RBDyVtScuRiH0NVb6+RfX+0t3zTEf6guuJdurczLBz9+D51+Th3KE1uk+UjI7J+Q/TOWTvoGMj8P4XZCXQsCDIct/vbLGqNB9CgM=,iv:/6xR7KXXLejm9Iuqcxc/7IqLEckNhmaJTKzJGonSrng=,tag:XdeCoEkHefw2HqTGSchUJA==,type:str]
lastmodified: "2025-08-01T05:55:35Z"
mac: ENC[AES256_GCM,data:MEgCbEJ/bwx3EVWVYQjb1RbNx8OlJkqelHPbMG5DzSRgcBcllptTFCanLIPZrg4FihkHx3b41Q5xsCXbras1njh4R1FeyLVVGZH7pYjZaPF2MRaD8nYeCHKlItWUVvHQTf5bRrTOOQoo4Kmn2by/xdMWwZlZwt0aBoGnEYBxGf0=,iv:lrPlg8cM5qPgQPpIUHF6WBVglTe9YQtI28hfJSgJ1vU=,tag:tjucRsf+tt9F03Mhjf+jeg==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View File

@@ -26,7 +26,7 @@ inputs:
services =
{
sshd = {};
xray.server = {};
xray = { server = {}; xmuPersist = {}; };
nginx =
{
streamProxy.map =
@@ -34,6 +34,7 @@ inputs:
"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; };
"xservernas.chn.moe" = { upstream = "wg0.nas.chn.moe:443"; proxyProtocol = false; };
}
// (builtins.listToAttrs (builtins.map
(site: { name = "${site}.chn.moe"; value.upstream.address = "wg0.pc.chn.moe"; })
@@ -58,6 +59,7 @@ inputs:
mirism = {};
fail2ban = {};
beesd."/" = {};
bind = {};
};
};
networking.nftables.tables.forward =

View File

@@ -44,6 +44,8 @@ send:
coturn:
auth-secret: ENC[AES256_GCM,data:50KqO4GQ1ERbCnK4IjYu6aywT+IPMtVlTzh/TE4MwWApU4pO9yqz25ENGUAKRLi4p+Ecug+Rn3InRl1b+q6bAQ==,iv:SgHkHvHg/+yA1Z5E9effgCnZMVXv5amGNUsVKErai54=,tag:PoYLV9Xr0IXXsA39n7wiTQ==,type:str]
wireguard: ENC[AES256_GCM,data:5M7EAy/6+2UASWkjxE0Jrxwl0aNdAVZaUjQnD1wU3YvOAQ/c2DSL8hVtKf8=,iv:a2tXFf1+aP0JhdNtzP8e82KJ71m2o8nx+G0wIx4VMig=,tag:l4TS4QBz2fIkC9/GnZgHnQ==,type:str]
xray-xmu-client:
cookie: ENC[AES256_GCM,data:RZ2WFnsX7s/PVqA7ZKhGqw==,iv:CknFoAcHIiIwJI1IEXkFdWXcOCAZr50pfwmQN72OI8o=,tag:w2pNU1APxlSQsGMIEdE2OA==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
@@ -64,7 +66,7 @@ sops:
ZXFTU3ZCaW1pTVh0RUJzdDdGdHlPYTgK2mlgcX2kEc8+2UDdBnhUm6IIuh8V6agW
ooxH9OEPXUVI/4JcDo4v8ZUhAyU1ehLH0Ef7PJCChOZe2KZmWSNbhA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-12T23:51:02Z"
mac: ENC[AES256_GCM,data:3QxWxinb3a7jvmHJO1kcePNwd/igurjFWVJw/sGKBuZpo47LU+W8132b9GpKs79AedDa5BM5yu0XN+CPrkviMcNuX5a3lLy8oI22a1N8fuKjEehld1Jq/boitGIsgJgb/M0Hn6yIq1ytuWuxoj2cOvmkEfNuyWRew+htI4DhJ/E=,iv:OyCWfcn218oaA970T9miIWIGSwOFeUbtWI0xO/02Hrw=,tag:c8riJplInFN1ZSPH3ze0QQ==,type:str]
lastmodified: "2025-08-01T05:54:47Z"
mac: ENC[AES256_GCM,data:OtHwr58A1UOfYxQR88ay76fWmAyWPl5YtNbAiv0LXPLZPRtLGBJKuTjMaHr17AMepFZ+u5IPV2r8z1AUDj0opLXlv3Ik/DJ2PCcQTOBH+/lnSgzJKWfdCip9/wFR6N3dT0PKKLuBiURB9ZCYmtnq6E5+Guadc6ATYDSEpwbENZQ=,iv:kXsYMGjAtUlv1UqFU8Xv0zagohnpHkzSI72mq5HKY7k=,tag:KR+1A8l2VvbzDZV/00hbJg==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View File

@@ -3,7 +3,7 @@ let
pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
{
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
nixpkgs = { march = null; cuda = null; nixRoot = "/public/home/xmuhk/.nix"; };
nixpkgs = { march = null; cuda = null; nixRoot = "/public/home/xmuhk/.nix"; nixos = false; };
});
lumericalLicenseManager =
let

159
flake.lock generated
View File

@@ -583,6 +583,62 @@
"type": "github"
}
},
"niri": {
"inputs": {
"niri-stable": "niri-stable",
"niri-unstable": "niri-unstable",
"nixpkgs": "nixpkgs",
"nixpkgs-stable": "nixpkgs-stable",
"xwayland-satellite-stable": "xwayland-satellite-stable",
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
},
"locked": {
"lastModified": 1752569955,
"narHash": "sha256-a21pjNhJYJ+OTQmBJ3NluU65PvMb54/mA7aEWJh5s/4=",
"owner": "sodiboo",
"repo": "niri-flake",
"rev": "8fc18813bf6ceaabb3063050819a20807e11279b",
"type": "github"
},
"original": {
"owner": "sodiboo",
"repo": "niri-flake",
"type": "github"
}
},
"niri-stable": {
"flake": false,
"locked": {
"lastModified": 1748151941,
"narHash": "sha256-z4viQZLgC2bIJ3VrzQnR+q2F3gAOEQpU1H5xHtX/2fs=",
"owner": "YaLTeR",
"repo": "niri",
"rev": "8ba57fcf25d2fc9565131684a839d58703f1dae7",
"type": "github"
},
"original": {
"owner": "YaLTeR",
"ref": "v25.05.1",
"repo": "niri",
"type": "github"
}
},
"niri-unstable": {
"flake": false,
"locked": {
"lastModified": 1752565554,
"narHash": "sha256-BLLMN6oOarMdIm59AX8uypaXZHBhGfd6L3VURfqQTX8=",
"owner": "YaLTeR",
"repo": "niri",
"rev": "007d35541db1bae32b7b43891af88831325ba068",
"type": "github"
},
"original": {
"owner": "YaLTeR",
"repo": "niri",
"type": "github"
}
},
"nix-flatpak": {
"locked": {
"lastModified": 1749394952,
@@ -697,16 +753,16 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1751630609,
"narHash": "sha256-mJ1XnKiLnNapGSUwyGdFD8tmQTzuJm8z3qaFC27guqE=",
"owner": "CHN-beta",
"lastModified": 1752480373,
"narHash": "sha256-JHQbm+OcGp32wAsXTE/FLYGNpb+4GLi5oTvCxwSoBOA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b263408b62d74a1e7a298fc47135653a70c227aa",
"rev": "62e0f05ede1da0d54515d4ea8ce9c733f12d9f08",
"type": "github"
},
"original": {
"owner": "CHN-beta",
"ref": "nixos-25.05",
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
@@ -790,13 +846,29 @@
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1752308619,
"narHash": "sha256-pzrVLKRQNPrii06Rm09Q0i0dq3wt2t2pciT/GNq5EZQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "650e572363c091045cdbc5b36b0f4c1f614d3058",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1750554037,
"narHash": "sha256-XE/lFNhz5lsriMm/yjXkvSZz5DfvKJLUjsS6pP8EC50=",
"lastModified": 1752553852,
"narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
"owner": "CHN-beta",
"repo": "nixpkgs",
"rev": "f6b1f449aa69592d8f9bce2d4141766b667294ac",
"rev": "72d2707fa09a82bae26845eadb136ce94fd96a3e",
"type": "github"
},
"original": {
@@ -806,6 +878,22 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1754960695,
"narHash": "sha256-cv73dyWKY6SBW1ECp0E4v3c51qyYmV+N7NwE0skh/cQ=",
"owner": "CHN-beta",
"repo": "nixpkgs",
"rev": "cc56ae5eb2e7c66d90332ddaa2c50196a66ec02b",
"type": "github"
},
"original": {
"owner": "CHN-beta",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixvirt": {
"inputs": {
"nixpkgs": [
@@ -1080,11 +1168,12 @@
"mumax": "mumax",
"nameof": "nameof",
"nc4nix": "nc4nix",
"niri": "niri",
"nix-flatpak": "nix-flatpak",
"nix-index-database": "nix-index-database",
"nix-vscode-extensions": "nix-vscode-extensions",
"nixos-wallpaper": "nixos-wallpaper",
"nixpkgs": "nixpkgs",
"nixpkgs": "nixpkgs_2",
"nixpkgs-2305": "nixpkgs-2305",
"nixpkgs-2311": "nixpkgs-2311",
"nixpkgs-2411": "nixpkgs-2411",
@@ -1101,6 +1190,7 @@
"rsshub": "rsshub",
"rycee": "rycee",
"sops-nix": "sops-nix",
"speedtest": "speedtest",
"sqlite-orm": "sqlite-orm",
"sticker": "sticker",
"stickerpicker": "stickerpicker",
@@ -1164,6 +1254,22 @@
"type": "github"
}
},
"speedtest": {
"flake": false,
"locked": {
"lastModified": 1739473165,
"narHash": "sha256-QimemnDZXlL5Ip+RFD0uxO21Aaol3kCw6Mf/0E3jHQc=",
"owner": "librespeed",
"repo": "speedtest",
"rev": "a1c43977ad9bf73f09f81e8df3c22ea914ab9131",
"type": "github"
},
"original": {
"owner": "librespeed",
"repo": "speedtest",
"type": "github"
}
},
"sqlite-orm": {
"flake": false,
"locked": {
@@ -1406,6 +1512,39 @@
"type": "github"
}
},
"xwayland-satellite-stable": {
"flake": false,
"locked": {
"lastModified": 1748488455,
"narHash": "sha256-IiLr1alzKFIy5tGGpDlabQbe6LV1c9ABvkH6T5WmyRI=",
"owner": "Supreeeme",
"repo": "xwayland-satellite",
"rev": "3ba30b149f9eb2bbf42cf4758d2158ca8cceef73",
"type": "github"
},
"original": {
"owner": "Supreeeme",
"ref": "v0.6",
"repo": "xwayland-satellite",
"type": "github"
}
},
"xwayland-satellite-unstable": {
"flake": false,
"locked": {
"lastModified": 1752338000,
"narHash": "sha256-Fxlp/yKtynug0jyuauAmvZU2SzHCfwlwWf85j+IvQ0U=",
"owner": "Supreeeme",
"repo": "xwayland-satellite",
"rev": "ba78881a68182ce338041846164cbfed0d70935c",
"type": "github"
},
"original": {
"owner": "Supreeeme",
"repo": "xwayland-satellite",
"type": "github"
}
},
"zpp-bits": {
"flake": false,
"locked": {

View File

@@ -31,6 +31,7 @@
winapps = { url = "github:winapps-org/winapps/feat-nix-packaging"; inputs.nixpkgs.follows = "nixpkgs"; };
nixvirt = { url = "github:CHN-beta/NixVirt"; inputs.nixpkgs.follows = "nixpkgs"; };
buildproxy = { url = "github:polygon/nix-buildproxy"; inputs.nixpkgs.follows = "nixpkgs"; };
niri.url = "github:sodiboo/niri-flake";
misskey = { url = "git+https://github.com/CHN-beta/misskey?submodules=1"; flake = false; };
rsshub = { url = "github:DIYgod/RSSHub"; flake = false; };
@@ -61,6 +62,7 @@
mac-style = { url = "github:SergioRibera/s4rchiso-plymouth-theme?lfs=1"; flake = false; };
phono3py = { url = "github:phonopy/phono3py"; flake = false; };
sticker = { url = "git+https://git.chn.moe/chn/sticker.git?lfs=1"; flake = false; };
speedtest = { url = "github:librespeed/speedtest"; flake = false; };
};
outputs = inputs: let localLib = import ./flake/lib inputs.nixpkgs.lib; in

View File

@@ -9,7 +9,7 @@ let
vps6 =
[
"blog" "catalog" "coturn" "element" "initrd.vps6" "misskey" "sticker" "synapse-admin" "tgapi"
"ua" "xserver2" "xserver2.vps6" ""
"ua" "xserver2" "xserver2.vps6" "" "xservernas"
];
"xlog.autoroute" = [ "xlog" ];
"wg0.srv1-node0" = [ "wg0.srv1" ];
@@ -38,6 +38,7 @@ let
srv1-node1 = "192.168.178.2";
srv1-node2 = "192.168.178.3";
srv2-node1 = "192.168.178.2";
"409test" = "192.168.1.5";
};
wireguard = import ./wireguard.nix;
in
@@ -56,11 +57,7 @@ in
{ type = "TXT"; value = "v=spf1 include:mxlogin.com -all"; }
];
"_xlog-challenge.xlog" = { type = "TXT"; value = "chn"; };
autoroute =
{
type = "NS";
values = builtins.map (suffix: "ns1.huaweicloud-dns.${suffix}.") [ "cn" "com" "net" "org" ];
};
autoroute = { type = "NS"; values = "vps6.chn.moe."; };
"mail" = { type = "CNAME"; value = "tuesday.mxrouting.net."; };
"webmail" = { type = "CNAME"; value = "tuesday.mxrouting.net."; };
"x._domainkey" =

View File

@@ -0,0 +1,13 @@
diff --git a/boost/process/v2/stdio.hpp b/boost/process/v2/stdio.hpp
index 01d0216..4084e46 100644
--- a/boost/process/v2/stdio.hpp
+++ b/boost/process/v2/stdio.hpp
@@ -184,7 +184,7 @@ struct process_io_binding
process_io_binding & operator=(const process_io_binding &) = delete;
process_io_binding(process_io_binding && other) noexcept
- : fd(other.fd), fd_needs_closing(other.fd), ec(other.ec)
+ : fd(other.fd), fd_needs_closing(other.fd_needs_closing), ec(other.ec)
{
other.fd = target;
other.fd_needs_closing = false;

View File

@@ -1,9 +1,13 @@
# inputs = { lib, topInputs, ...}; nixpkgs = { march, cuda, nixRoot };
# inputs = { lib, topInputs, ...}; nixpkgs = { march, cuda, nixRoot, nixos, arch };
{ inputs, nixpkgs }:
let
platformConfig =
if nixpkgs.march == null then { system = "x86_64-linux"; }
else { hostPlatform = { system = "x86_64-linux"; gcc = { arch = nixpkgs.march; tune = nixpkgs.march; }; }; };
if nixpkgs.march == null then { system = "${nixpkgs.arch or "x86_64"}-linux"; }
else
{
${if nixpkgs.nixos then "hostPlatform" else "localSystem"} =
{ system = "${nixpkgs.arch or "x86_64"}-linux"; gcc = { arch = nixpkgs.march; tune = nixpkgs.march; }; };
};
cudaConfig = inputs.lib.optionalAttrs (nixpkgs.cuda != null)
(
{ cudaSupport = true; }
@@ -65,7 +69,9 @@ in platformConfig //
patches = prev.patches or [] ++ [ ./root.patch ];
cmakeFlags = prev.cmakeFlags ++ [ "-DCMAKE_CXX_STANDARD=23" ];
});
boost188 = prev.boost188.overrideAttrs (prev: { patches = prev.patches or [] ++ [ ./boost188.patch ]; });
inherit (final.pkgs-2411) iio-sensor-proxy;
inherit (final.pkgs-unstable) bees;
}
// (
let
@@ -82,7 +88,7 @@ in platformConfig //
};
packages = name: import inputs.topInputs.${source.${name}.source or source.${name}}
{
localSystem = platformConfig.hostPlatform or { inherit (platformConfig) system; };
localSystem = platformConfig.hostPlatform or platformConfig.localSystem or platformConfig;
inherit config;
overlays = [(source.${name}.overlay or (_: _: {}))];
};

View File

@@ -1,6 +1,6 @@
{ inputs, localLib }:
let
singles = [ "nas" "pc" "vps4" "vps6" "one" "srv3" "test" "test-pc" "test-pc-vm" ];
singles = [ "nas" "pc" "vps4" "vps6" "one" "srv3" "r2s" ];
cluster = { srv1 = 3; srv2 = 2; };
deviceModules = builtins.listToAttrs
(
@@ -25,9 +25,9 @@ let
(localLib.attrsToList cluster)))
);
in builtins.mapAttrs
(_: v: inputs.nixpkgs.lib.nixosSystem
(n: v: inputs.nixpkgs.lib.nixosSystem
{
system = "x86_64-linux";
system = null;
specialArgs = { topInputs = inputs; inherit localLib; };
modules = localLib.mkModules v;
})

View File

@@ -3,7 +3,7 @@
pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
{
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
nixpkgs = { march = null; cuda = null; nixRoot = null; };
nixpkgs = { march = null; cuda = null; nixRoot = null; nixos = false; };
});
hpcstat =
let
@@ -36,19 +36,17 @@
else if builtins.isAttrs x then builtins.concatMap getDrv (builtins.attrValues x)
else if builtins.isList x then builtins.concatMap getDrv x
else [];
in pkgs.concatText "src" (getDrv (inputs.self.outputs.src));
in pkgs.writeText "src" (builtins.concatStringsSep "\n" (getDrv inputs.self.outputs.src));
dns-push = pkgs.callPackage ./dns
{
inherit localLib;
tokenPath = inputs.self.nixosConfigurations.pc.config.sops.secrets."acme/token".path;
tokenPath = inputs.self.nixosConfigurations.pc.config.nixos.system.sops.secrets."acme/token".path;
octodns = pkgs.octodns.withProviders (_: with pkgs.octodns-providers; [ cloudflare ]);
};
archive =
let devices =
[ "nas" "one" "pc" "srv1-node0" "srv1-node1" "srv1-node2" "srv2-node0" "srv2-node1" "srv3" "vps4" "vps6" ];
in pkgs.writeText "archive" (builtins.concatStringsSep "\n" (builtins.map
(d: "${inputs.self.outputs.nixosConfigurations.${d}.config.system.build.toplevel}") devices));
archive = pkgs.writeText "archive" (builtins.concatStringsSep "\n" (builtins.concatLists
[
(inputs.nixpkgs.lib.mapAttrsToList (_: v: v.config.system.build.toplevel) inputs.self.outputs.nixosConfigurations)
[ src ]
]));
}
// (builtins.listToAttrs (builtins.map
(system: { inherit (system) name; value = system.value.config.system.build.toplevel; })
(localLib.attrsToList inputs.self.outputs.nixosConfigurations)))
// (builtins.mapAttrs (_: v: v.config.system.build.toplevel) inputs.self.outputs.nixosConfigurations)

View File

@@ -89,7 +89,7 @@
hashMode = "recursive";
message = "Source file not found.";
};
image = "7bb3a43bd1ad6103a57f700b13d11d486b6ea117838201e4a29d79b33ac72e3a";
image = "6803f9562b941c23db81a2eae5914561f96fa748536199a010fe6f24922b2878";
imageFile = pkgs.requireFile
{
name = "lumericalLicenseManager.tar";
@@ -110,13 +110,13 @@
};
};
};
vesta =
vesta = rec
{
version = "3.90.5a";
version = "3.5.8";
src = pkgs.fetchurl
{
url = "https://jp-minerals.org/vesta/archives/testing/VESTA-gtk3-x86_64.tar.bz2";
sha256 = "0y277m2xvjyzx8hncc3ka73lir8x6x2xckjac9fdzg03z0jnpqzf";
url = "https://jp-minerals.org/vesta/archives/${version}/VESTA-gtk3.tar.bz2";
sha256 = "1y4dhqhk0jy7kbkkx2c6lsrm5lirn796mq67r5j1s7xkq8jz1gkq";
};
desktopFile = pkgs.fetchurl
{
@@ -180,7 +180,7 @@
"intel.oneapi.lin.compilers-common,v=2025.1.1+10"
];
};
rsshub = pkgs.dockerTools.pullImage
rsshub = pkgs.dockerTools.pullImage
{
imageName = "diygod/rsshub";
imageDigest = "sha256:1f9d97263033752bf5e20c66a75e134e6045b6d69ae843c1f6610add696f8c22";
@@ -188,4 +188,20 @@
finalImageName = "rsshub";
finalImageTag = "latest";
};
atat = pkgs.fetchurl
{
url = "https://axelvandewalle.github.io/www-avdw/atat/atat3_50.tar.gz";
sha256 = "14sblzqsi5bxfhsjbq256bc2gfd7zrxyf5za0iaw77b592ppjg3m";
};
atomkit = pkgs.fetchurl
{
url = "mirror://sourceforge/atomkit/Binaries/atomkit.0.9.0.linux.x64.tar.gz";
sha256 = "0y9z7wva7zikh83w9q431lgn3bqkh1v5w6iz90dwc75wqwk0w5jr";
};
guix = pkgs.fetchurl
{
url = "https://ci.guix.gnu.org/download/2857";
name = "guix.iso";
sha256 = "0xqabnay8wwqc1a96db8ix1a6bhvgm84s5is1q67rr432q7gqgd4";
};
}

View File

@@ -10,6 +10,8 @@ inputs: let inherit (inputs) topInputs; in
topInputs.catppuccin.nixosModules.catppuccin
topInputs.aagl.nixosModules.default
topInputs.nixvirt.nixosModules.default
topInputs.niri.nixosModules.niri
{ config.niri-flake.cache.enable = false; }
# TODO: Remove after next release
"${topInputs.nixpkgs-unstable}/nixos/modules/services/hardware/lact.nix"
(inputs:

View File

@@ -2,7 +2,7 @@ inputs:
{
options.nixos.hardware.cpu = let inherit (inputs.lib) mkOption types; in mkOption
{
type = types.enum [ "intel" "amd" ];
type = types.nullOr (types.enum [ "intel" "amd" ]);
default = let inherit (inputs.config.nixos.system.nixpkgs) march; in
if march == null then null
else if inputs.lib.hasPrefix "znver" march then "amd"

View File

@@ -31,14 +31,18 @@ inputs:
(
let gpus = inputs.lib.strings.splitString "+" gpu.type; in
{
boot.initrd.availableKernelModules =
let modules =
{
intel = [ "i915" ];
nvidia = []; # early loading breaks resume from hibernation
amd = [];
};
in builtins.concatLists (builtins.map (gpu: modules.${gpu}) gpus);
boot =
{
initrd.availableKernelModules =
let modules =
{
intel = [ "i915" ];
nvidia = []; # early loading breaks resume from hibernation
amd = [];
};
in builtins.concatLists (builtins.map (gpu: modules.${gpu}) gpus);
blacklistedKernelModules = [ "nouveau" ];
};
hardware =
{
graphics =
@@ -66,7 +70,6 @@ inputs:
prime.allowExternalGpu = true;
};
};
boot.blacklistedKernelModules = [ "nouveau" ];
services.xserver.videoDrivers =
let driver = { intel = "modesetting"; amd = "amdgpu"; nvidia = "nvidia"; };
in builtins.map (gpu: driver.${gpu}) gpus;
@@ -78,6 +81,14 @@ inputs:
amd = [];
};
in builtins.concatLists (builtins.map (gpu: packages.${gpu}) gpus);
environment.etc."nvidia/nvidia-application-profiles-rc.d/vram" = inputs.lib.mkIf (builtins.elem "nvidia" gpus)
{
source = inputs.pkgs.writeText "save-vram" (builtins.toJSON
{
rules = [{ pattern = { feature = "true"; matches = ""; }; profile = "save-vram"; }];
profiles = [{ name = "save-vram"; settings = [{ key = "GLVidHeapReuseRatio"; value = 0; }]; }];
});
};
}
)
# nvidia prime offload

View File

@@ -3,6 +3,7 @@ inputs:
options.nixos.model = let inherit (inputs.lib) mkOption types; in
{
hostname = mkOption { type = types.nonEmptyStr; };
arch = mkOption { type = types.nonEmptyStr; default = "x86_64"; };
type = mkOption { type = types.enum [ "minimal" "desktop" "server" ]; default = "minimal"; };
private = mkOption { type = types.bool; default = false; };
cluster = mkOption

View File

@@ -160,6 +160,7 @@ inputs:
honkers-railway-launcher = { enable = true; package = inputs.pkgs.honkers-railway-launcher; };
sleepy-launcher = { enable = true; package = inputs.pkgs.sleepy-launcher; };
alvr = { enable = true; openFirewall = true; };
localsend.enable = true;
};
services = { pcscd.enable = true; lact.enable = true; };
};

View File

@@ -12,7 +12,7 @@ inputs:
beep dos2unix gnugrep pv tmux screen parallel tldr cowsay jq yq ipfetch localPackages.pslist
fastfetch reptyr duc ncdu progress libva-utils ksh neofetch dateutils kitty glib
# lsxx
pciutils usbutils lshw util-linux lsof dmidecode lm_sensors hwloc acpica-tools
pciutils usbutils lshw util-linux lsof dmidecode lm_sensors hwloc acpica-tools ethtool
# top
iotop iftop htop btop powertop s-tui
# editor
@@ -22,11 +22,13 @@ inputs:
# file manager
tree eza trash-cli lsd broot file xdg-ninja mlocate
# compress
pigz upx unzip zip lzip p7zip rar
pigz upx unzip zip lzip p7zip
(if inputs.pkgs.stdenv.hostPlatform.linuxArch == "x86_64" then rar else emptyDirectory)
# file system management
sshfs e2fsprogs compsize exfatprogs
# disk management
smartmontools hdparm gptfdisk megacli
smartmontools hdparm gptfdisk
(if inputs.pkgs.stdenv.hostPlatform.linuxArch == "x86_64" then megacli else emptyDirectory)
# encryption and authentication
apacheHttpd openssl ssh-to-age gnupg age sops pam_u2f yubico-piv-tool libfido2
# networking

View File

@@ -10,6 +10,7 @@ inputs:
[
localPackages.vasp.intel localPackages.vasp.vtst localPackages.vaspkit wannier90
(if inputs.config.nixos.system.nixpkgs.cuda != null then localPackages.vasp.nvidia else emptyDirectory)
localPackages.atomkit (inputs.lib.mkAfter localPackages.atat)
];
_pythonPackages = [(_: [ localPackages.py4vasp ])];
};

View File

@@ -35,7 +35,7 @@ inputs:
}
{
programs.zsh = inputs.lib.mkIf
(builtins.elem home-inputs.config.home.username [ "chn" "root" "aleksana" "alikia" ])
(builtins.elem home-inputs.config.home.username [ "chn" "root" "aleksana" "alikia" "hjp" ])
{
plugins =
[

View File

@@ -34,21 +34,21 @@ inputs:
name = builtins.elemAt cert.value.domains 0;
value =
{
credentialsFile = inputs.config.sops.templates."acme/cloudflare.ini".path;
credentialsFile = inputs.config.nixos.system.sops.templates."acme/cloudflare.ini".path;
extraDomainNames = builtins.tail cert.value.domains;
group = inputs.lib.mkIf (cert.value.group != null) cert.value.group;
};
})
(inputs.localLib.attrsToList acme.cert));
};
sops =
nixos.system.sops =
{
templates."acme/cloudflare.ini".content =
''
CLOUDFLARE_DNS_API_TOKEN=${inputs.config.sops.placeholder."acme/token"}
CLOUDFLARE_DNS_API_TOKEN=${inputs.config.nixos.system.sops.placeholder."acme/token"}
CLOUDFLARE_PROPAGATION_TIMEOUT=300
'';
secrets."acme/token".sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/acme.yaml";
secrets."acme/token" = {};
};
};
}

View File

@@ -15,24 +15,19 @@ inputs:
};
config = let inherit (inputs.config.nixos.services) beesd; in inputs.lib.mkIf (beesd != null)
{
services.beesd.filesystems = builtins.listToAttrs (builtins.map
(fs:
services.beesd.filesystems = inputs.lib.mapAttrs'
(n: v: inputs.lib.nameValuePair (inputs.utils.escapeSystemdPath n)
{
name = inputs.utils.escapeSystemdPath fs.name;
value =
{
spec = fs.name;
inherit (fs.value) hashTableSizeMB;
extraOptions =
[
"--thread-count" "${builtins.toString fs.value.threads}"
"--loadavg-target" "${builtins.toString fs.value.loadAverage}"
"--scan-mode" "3"
"--verbose" "4"
];
};
spec = n;
inherit (v) hashTableSizeMB;
extraOptions =
[
"--thread-count" "${builtins.toString v.threads}"
"--loadavg-target" "${builtins.toString v.loadAverage}"
"--verbose" "4"
];
})
(inputs.localLib.attrsToList beesd));
beesd;
nixos.packages.packages._packages = [ inputs.pkgs.bees ];
};
}

82
modules/services/bind.nix Normal file
View File

@@ -0,0 +1,82 @@
inputs:
{
options.nixos.services.bind = let inherit (inputs.lib) mkOption types; in mkOption
{ type = types.nullOr (types.submodule (submoduleInputs: {})); default = null; };
config = let inherit (inputs.config.nixos.services) bind; in inputs.lib.mkIf (bind != null)
{
services.bind =
let
chinaZone = inputs.pkgs.writeText "autoroute.chn.moe.china.zone"
''
$ORIGIN autoroute.chn.moe.
$TTL 3600
@ IN SOA vps6.chn.moe. chn.chn.moe. (
2024071301 ; serial
3600 ; refresh
600 ; retry
604800 ; expire
300 ; minimum
)
@ IN NS vps6.chn.moe.
@ IN A ${inputs.topInputs.self.config.dns."chn.moe".getAddress "vps6"}
'';
globalZone = inputs.pkgs.writeText "autoroute.chn.moe.zone"
''
$ORIGIN autoroute.chn.moe.
$TTL 3600
@ IN SOA vps6.chn.moe. chn.chn.moe. (
2024071301 ; serial
3600 ; refresh
600 ; retry
604800 ; expire
300 ; minimum
)
@ IN NS vps6.chn.moe.
@ IN A ${inputs.topInputs.self.config.dns."chn.moe".getAddress "srv3"}
'';
nullZone = inputs.pkgs.writeText "null.zone" "";
in
{
enable = true;
package = inputs.pkgs.bind.overrideAttrs
(prev: { buildInputs = prev.buildInputs ++ [ inputs.pkgs.libmaxminddb ]; });
listenOn = [(inputs.topInputs.self.config.dns."chn.moe".getAddress "vps6")];
extraOptions =
''
recursion no;
geoip-directory "${inputs.config.services.geoipupdate.settings.DatabaseDirectory}";
'';
extraConfig =
''
acl "china" {
geoip country CN;
};
view "china" {
match-clients { china; };
zone "autoroute.chn.moe" {
type master;
file "${chinaZone}";
};
zone "." {
type hint;
file "${nullZone}";
};
};
view "global" {
match-clients { any; };
zone "autoroute.chn.moe" {
type master;
file "${globalZone}";
};
zone "." {
type hint;
file "${nullZone}";
};
};
'';
};
nixos.services.geoipupdate = {};
networking.firewall.allowedUDPPorts = [ 53 ];
};
}

View File

@@ -14,14 +14,17 @@ inputs:
{
enable = true;
use-auth-secret = true;
static-auth-secret-file = inputs.config.sops.secrets."coturn/auth-secret".path;
static-auth-secret-file = inputs.config.nixos.system.sops.secrets."coturn/auth-secret".path;
realm = coturn.hostname;
cert = "${keydir}/full.pem";
pkey = "${keydir}/key.pem";
no-cli = true;
};
sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
nixos.services.acme.cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
nixos =
{
system.sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
services.acme.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

@@ -15,19 +15,18 @@ inputs:
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; };
};
sops.secrets =
{
"freshrss/chn".owner = inputs.config.users.users.freshrss.name;
"freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; };
passwordFile = inputs.config.nixos.system.sops.secrets."freshrss/chn".path;
database = { type = "mysql"; passFile = inputs.config.nixos.system.sops.secrets."freshrss/db".path; };
};
systemd.services.freshrss-config.after = [ "mysql.service" ];
nixos.services =
nixos =
{
mariadb = { enable = true; instances.freshrss = {}; };
nginx.https.${freshrss.hostname}.global.configName = "freshrss";
services = { mariadb.instances.freshrss = {}; nginx.https.${freshrss.hostname}.global.configName = "freshrss"; };
system.sops.secrets =
{
"freshrss/chn".owner = inputs.config.users.users.freshrss.name;
"freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; };
};
};
};
}

View File

@@ -0,0 +1,19 @@
inputs:
{
options.nixos.services.geoipupdate = let inherit (inputs.lib) mkOption types; in mkOption
{ type = types.nullOr (types.submodule {}); default = null; };
config = let inherit (inputs.config.nixos.services) geoipupdate; in inputs.lib.mkIf (geoipupdate != null)
{
services.geoipupdate =
{
enable = true;
settings =
{
AccountID = 901296;
LicenseKey = inputs.config.nixos.system.sops.secrets."maxmind".path;
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
};
};
nixos.system.sops.secrets."maxmind" = {};
};
}

View File

@@ -19,9 +19,13 @@ inputs:
{
enable = true;
lfs.enable = true;
mailerPasswordFile = inputs.config.sops.secrets."gitea/mail".path;
mailerPasswordFile = inputs.config.nixos.system.sops.secrets."gitea/mail".path;
database =
{ createDatabase = false; type = "postgres"; passwordFile = inputs.config.sops.secrets."gitea/db".path; };
{
createDatabase = false;
type = "postgres";
passwordFile = inputs.config.nixos.system.sops.secrets."gitea/db".path;
};
settings =
{
session.COOKIE_SECURE = true;
@@ -48,26 +52,29 @@ inputs:
[ "DEFAULT" "MIGRATE" "MIRROR" "CLONE" "PULL" "GC" ]);
};
};
nixos.services =
nixos =
{
nginx.https.${gitea.hostname}.location =
system.sops.secrets =
{
"/".proxy.upstream = "http://127.0.0.1:3002";
"/robots.txt".static.root =
let robotsFile = inputs.pkgs.fetchurl
{
url = "https://gitea.com/robots.txt";
sha256 = "144c5s3la4a85c9lygcnxhbxs3w5y23bkhhqx69fbp9yiqyxdkk2";
};
in "${inputs.pkgs.runCommand "robots.txt" {} "mkdir -p $out; cp ${robotsFile} $out/robots.txt"}";
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
"mail/bot" = {};
};
services =
{
nginx.https.${gitea.hostname}.location =
{
"/".proxy.upstream = "http://127.0.0.1:3002";
"/robots.txt".static.root =
let robotsFile = inputs.pkgs.fetchurl
{
url = "https://gitea.com/robots.txt";
sha256 = "144c5s3la4a85c9lygcnxhbxs3w5y23bkhhqx69fbp9yiqyxdkk2";
};
in "${inputs.pkgs.runCommand "robots.txt" {} "mkdir -p $out; cp ${robotsFile} $out/robots.txt"}";
};
postgresql.instances.gitea = {};
};
postgresql.instances.gitea = {};
};
sops.secrets =
{
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
"mail/bot" = {};
};
};
}

View File

@@ -24,7 +24,7 @@ inputs:
enabled = true;
host = "mail.chn.moe";
user = "bot@chn.moe";
password = "$__file{${inputs.config.sops.secrets."grafana/mail".path}}";
password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/mail".path}}";
from_address = "bot@chn.moe";
ehlo_identity = grafana.hostname;
startTLS_policy = "MandatoryStartTLS";
@@ -32,9 +32,9 @@ inputs:
server = { root_url = "https://${grafana.hostname}"; http_port = 3001; enable_gzip = true; };
security =
{
secret_key = "$__file{${inputs.config.sops.secrets."grafana/secret".path}}";
secret_key = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/secret".path}}";
admin_user = "chn";
admin_password = "$__file{${inputs.config.sops.secrets."grafana/chn".path}}";
admin_password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/chn".path}}";
admin_email = "chn@chn.moe";
};
database =
@@ -42,7 +42,7 @@ inputs:
type = "postgres";
host = "127.0.0.1:5432";
user = "grafana";
password = "$__file{${inputs.config.sops.secrets."grafana/db".path}}";
password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/db".path}}";
};
};
provision =
@@ -78,18 +78,21 @@ inputs:
extraFlags = [ "--storage.tsdb.max-block-chunk-segment-size=16MB" ];
};
};
nixos.services =
nixos =
{
nginx.https.${grafana.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3001"; websocket = true; };
postgresql.instances.grafana = {};
};
sops.secrets = let owner = inputs.config.systemd.services.grafana.serviceConfig.User; in
{
"grafana/mail" = { owner = owner; key = "mail/bot"; };
"grafana/secret".owner = owner;
"grafana/chn".owner = owner;
"grafana/db" = { owner = owner; key = "postgresql/grafana"; };
"mail/bot" = {};
services =
{
nginx.https.${grafana.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3001"; websocket = true; };
postgresql.instances.grafana = {};
};
system.sops.secrets = let owner = inputs.config.systemd.services.grafana.serviceConfig.User; in
{
"grafana/mail" = { owner = owner; key = "mail/bot"; };
"grafana/secret".owner = owner;
"grafana/chn".owner = owner;
"grafana/db" = { owner = owner; key = "postgresql/grafana"; };
"mail/bot" = {};
};
};
environment.persistence."/nix/nodatacow".directories =
[{ directory = "/var/lib/prometheus2"; user = "prometheus"; group = "prometheus"; mode = "0700"; }];

View File

@@ -15,13 +15,13 @@ inputs:
grep = "${inputs.pkgs.gnugrep}/bin/grep";
curl = "${inputs.pkgs.curl}/bin/curl";
cat = "${inputs.pkgs.coreutils}/bin/cat";
token = inputs.config.sops.secrets."telegram/token".path;
chat = inputs.config.sops.secrets."telegram/user/chn".path;
token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
date = "${inputs.pkgs.coreutils}/bin/date";
hpcstat = "${inputs.pkgs.localPackages.hpcstat}/bin/hpcstat";
ssh = "${inputs.pkgs.openssh}/bin/ssh -i ${key} -o StrictHostKeyChecking=no"
+ " -o ForwardAgent=yes -o AddKeysToAgent=yes";
key = inputs.config.sops.secrets."hpcstat/key".path;
key = inputs.config.nixos.system.sops.secrets."hpcstat/key".path;
jykang = "${inputs.topInputs.self}/devices/jykang.xmuhpc/files";
ssh-agent = "${inputs.pkgs.openssh}/bin/ssh-agent";
in
@@ -105,10 +105,10 @@ inputs:
(inputs.localLib.attrsToList calenders));
tmpfiles.rules = [ "d /var/lib/hpcstat 0700 hpcstat hpcstat" ];
};
sops.secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in
nixos.system.sops.secrets =
{
"telegram/token" = { group = "telegram"; mode = "0440"; inherit sopsFile; };
"telegram/user/chn" = { group = "telegram"; mode = "0440"; inherit sopsFile; };
"telegram/token" = { group = "telegram"; mode = "0440"; };
"telegram/user/chn" = { group = "telegram"; mode = "0440"; };
"hpcstat/key" = { owner = "hpcstat"; group = "hpcstat"; };
};
users =

View File

@@ -10,35 +10,37 @@ inputs:
};
config = let inherit (inputs.config.nixos.services) httpapi; in inputs.lib.mkIf (httpapi != null)
{
nixos.services =
nixos =
{
phpfpm.instances.httpapi = {};
nginx.https.${httpapi.hostname}.location =
services =
{
"/files".static.root = "/srv/api";
"/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; };
"/notify.php".php =
phpfpm.instances.httpapi = {};
nginx.https.${httpapi.hostname}.location =
{
root = builtins.dirOf inputs.config.sops.templates."httpapi/notify.php".path;
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpapi.fastcgi;
"/files".static.root = "/srv/api";
"/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; };
"/notify.php".php =
{
root = builtins.dirOf inputs.config.nixos.system.sops.templates."httpapi/notify.php".path;
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpapi.fastcgi;
};
};
};
};
sops =
{
templates."httpapi/notify.php" =
system.sops =
{
owner = inputs.config.users.users.httpapi.name;
group = inputs.config.users.users.httpapi.group;
content =
let
placeholder = inputs.config.sops.placeholder;
request = "https://api.telegram.org/bot${placeholder."telegram/token"}"
+ "/sendMessage?chat_id=${placeholder."telegram/user/chn"}&text=";
in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>'';
templates."httpapi/notify.php" =
{
owner = inputs.config.users.users.httpapi.name;
group = inputs.config.users.users.httpapi.group;
content =
let
inherit (inputs.config.sops) placeholder;
request = "https://api.telegram.org/bot${placeholder."telegram/token"}"
+ "/sendMessage?chat_id=${placeholder."telegram/user/chn"}&text=";
in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>'';
};
secrets = { "telegram/token" = {}; "telegram/user/chn" = {}; };
};
secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in
{ "telegram/token" = { inherit sopsFile; }; "telegram/user/chn" = { inherit sopsFile; }; };
};
systemd.tmpfiles.rules = [ "d /srv/api 0700 nginx nginx" "Z /srv/api - nginx nginx" ];
};

View File

@@ -15,30 +15,7 @@ inputs:
image = "ghcr.io/huginn/huginn:latest";
imageFile = inputs.topInputs.self.src.huginn;
ports = [ "127.0.0.1:3000:3000/tcp" ];
environmentFiles = [ inputs.config.sops.templates."huginn/env".path ];
};
sops =
{
templates."huginn/env".content = let placeholder = inputs.config.sops.placeholder; in
''
MYSQL_PORT_3306_TCP_ADDR=host.containers.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" = {}; };
environmentFiles = [ inputs.config.nixos.system.sops.templates."huginn/env".path ];
};
nixos =
{
@@ -48,6 +25,29 @@ inputs:
mariadb.instances.huginn = {};
podman = {};
};
system.sops =
{
templates."huginn/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
''
MYSQL_PORT_3306_TCP_ADDR=host.containers.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" = {}; };
};
};
};
}

View File

@@ -10,6 +10,7 @@ inputs:
default = if inputs.config.nixos.system.network != null then "00:01:23:45:67:89" else null;
};
createFakeInterface = mkOption { type = types.bool; default = inputs.config.nixos.system.network != null; };
autoStart = mkOption { type = types.bool; default = true; };
};});
default = null;
};
@@ -27,11 +28,16 @@ inputs:
in [ "${license}:/home/ansys_inc/shared_files/licensing/license_files/ansyslmd.lic" ];
};
nixos.services.podman = {};
systemd.network = inputs.lib.mkIf lumericalLicenseManager.createFakeInterface
systemd =
{
netdevs.ensFakeLumerical.netdevConfig = { Kind = "dummy"; Name = "ensFakeLumerical"; };
networks."10-ensFakeLumerical" =
{ matchConfig.Name = "ensFakeLumerical"; linkConfig.MACAddress = lumericalLicenseManager.macAddress; };
network = inputs.lib.mkIf lumericalLicenseManager.createFakeInterface
{
netdevs.ensFakeLumerical.netdevConfig = { Kind = "dummy"; Name = "ensFakeLumerical"; };
networks."10-ensFakeLumerical" =
{ matchConfig.Name = "ensFakeLumerical"; linkConfig.MACAddress = lumericalLicenseManager.macAddress; };
};
services.podman-lumericalLicenseManager.wantedBy =
inputs.lib.mkIf (!lumericalLicenseManager.autoStart) (inputs.lib.mkForce []);
};
};
}

View File

@@ -40,13 +40,13 @@ inputs:
let
passwordFile =
if db.value.passwordFile or null != null then db.value.passwordFile
else inputs.config.sops.secrets."mariadb/${db.value.user}".path;
else inputs.config.nixos.system.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'')
(inputs.localLib.attrsToList mariadb.instances)));
sops.secrets = builtins.listToAttrs (builtins.map
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
(db: { name = "mariadb/${db.value.user}"; value.owner = inputs.config.users.users.mysql.name; })
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList mariadb.instances)));
environment.persistence."/nix/nodatacow".directories =

View File

@@ -22,7 +22,8 @@ inputs:
after = [ "network.target" "redis-misskey-${instance.name}.service" "postgresql.service" ];
requires = after;
wantedBy = [ "multi-user.target" ];
environment.MISSKEY_CONFIG_YML = inputs.config.sops.templates."misskey/${instance.name}.yml".path;
environment.MISSKEY_CONFIG_YML =
inputs.config.nixos.system.sops.templates."misskey/${instance.name}.yml".path;
serviceConfig = rec
{
User = "misskey-${instance.name}";
@@ -53,50 +54,6 @@ inputs:
};
})
(inputs.localLib.attrsToList misskey.instances));
sops.templates = builtins.listToAttrs (builtins.map
(instance:
{
name = "misskey/${instance.name}.yml";
value =
{
content =
let
placeholder = inputs.config.sops.placeholder;
redis = inputs.config.nixos.services.redis.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_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
user: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
pass: ${placeholder."postgresql/misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"}
extra:
statement_timeout: 600000
dbReplications: false
redis:
host: 127.0.0.1
port: ${builtins.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
fulltextSearch:
provider: sqlPgroonga
'';
owner = "misskey-${instance.name}";
};
})
(inputs.localLib.attrsToList misskey.instances));
users = inputs.lib.mkMerge (builtins.map
(instance:
{
@@ -111,19 +68,66 @@ inputs:
groups."misskey-${instance.name}".gid = inputs.config.nixos.user.gid."misskey-${instance.name}";
})
(inputs.localLib.attrsToList misskey.instances));
nixos.services =
nixos =
{
redis.instances = builtins.listToAttrs (builtins.map
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
(inputs.localLib.attrsToList misskey.instances));
postgresql.instances = builtins.listToAttrs (builtins.map
(instance: { name = "misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
(inputs.localLib.attrsToList misskey.instances));
nginx.https = builtins.listToAttrs (builtins.map
(instance: with instance.value;
services =
{
redis.instances = builtins.listToAttrs (builtins.map
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
(inputs.localLib.attrsToList misskey.instances));
postgresql.instances = builtins.listToAttrs (builtins.map
(instance: { name = "misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
(inputs.localLib.attrsToList misskey.instances));
nginx.https = builtins.listToAttrs (builtins.map
(instance: with instance.value;
{
name = hostname;
value.location."/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
})
(inputs.localLib.attrsToList misskey.instances));
};
system.sops.templates = builtins.listToAttrs (builtins.map
(instance:
{
name = hostname;
value.location."/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
name = "misskey/${instance.name}.yml";
value =
{
content =
let
placeholder = inputs.config.nixos.system.sops.placeholder;
redis = inputs.config.nixos.services.redis.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_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
user: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
pass: ${placeholder."postgresql/misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"}
extra:
statement_timeout: 600000
dbReplications: false
redis:
host: 127.0.0.1
port: ${builtins.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
fulltextSearch:
provider: sqlPgroonga
'';
owner = "misskey-${instance.name}";
};
})
(inputs.localLib.attrsToList misskey.instances));
};

View File

@@ -21,9 +21,9 @@ inputs:
config =
{
dbtype = "pgsql";
dbpassFile = inputs.config.sops.secrets."nextcloud/postgresql".path;
dbpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/postgresql".path;
adminuser = "admin";
adminpassFile = inputs.config.sops.secrets."nextcloud/admin".path;
adminpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/admin".path;
};
configureRedis = true;
settings =
@@ -39,7 +39,7 @@ inputs:
overwriteprotocol = "https";
default_phone_region = "CN";
};
secretFile = inputs.config.sops.templates."nextcloud/secret".path;
secretFile = inputs.config.nixos.system.sops.templates."nextcloud/secret".path;
extraApps =
let
version = inputs.lib.versions.major inputs.config.services.nextcloud.package.version;
@@ -59,27 +59,30 @@ inputs:
(package: { name = package; value = inputs.pkgs.fetchNextcloudApp (getInfo package); })
[ "phonetrack" "twofactor_webauthn" "calendar" ]);
};
nixos.services =
nixos =
{
postgresql.instances.nextcloud = {};
redis.instances.nextcloud.port = 3499;
nginx.https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
};
sops =
{
templates."nextcloud/secret" =
system.sops =
{
content = builtins.toJSON
templates."nextcloud/secret" =
{
redis.password = inputs.config.sops.placeholder."redis/nextcloud";
mail_smtppassword = inputs.config.sops.placeholder."mail/bot";
content = builtins.toJSON
{
redis.password = inputs.config.nixos.system.sops.placeholder."redis/nextcloud";
mail_smtppassword = inputs.config.nixos.system.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;
};
owner = inputs.config.users.users.nextcloud.name;
};
secrets =
services =
{
"nextcloud/postgresql" = { key = "postgresql/nextcloud"; owner = inputs.config.users.users.nextcloud.name; };
"nextcloud/admin".owner = inputs.config.users.users.nextcloud.name;
postgresql.instances.nextcloud = {};
redis.instances.nextcloud.port = 3499;
nginx.https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
};
};
systemd.services.nextcloud-setup = rec { requires = [ "postgresql.service" ]; after = requires; };

View File

@@ -25,87 +25,70 @@ inputs:
config = let inherit (inputs.config.nixos.services) nginx; in inputs.lib.mkIf
(nginx.http != {} || nginx.https != {} || nginx.streamProxy.map != {} || nginx.transparentProxy.map != {})
{
services =
services.nginx =
{
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 1d;
# nginx will try to redirect https://blog.chn.moe/docs to https://blog.chn.moe:3068/docs/ in default
# this make it redirect to /docs/ without hostname
absolute_redirect off;
# allow realip module to set ip
set_real_ip_from 0.0.0.0/0;
real_ip_header proxy_protocol;
'';
proxyTimeout = "1d";
recommendedZstdSettings = true;
recommendedTlsSettings = true;
# do not set Host header
recommendedProxySettings = false;
recommendedProxySettingsNoHost = 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;
'';
# anyway to use host dns?
resolver.addresses = [ "8.8.8.8" ];
};
geoipupdate =
{
enable = true;
settings =
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 1d;
# nginx will try to redirect https://blog.chn.moe/docs to https://blog.chn.moe:3068/docs/ in default
# this make it redirect to /docs/ without hostname
absolute_redirect off;
# allow realip module to set ip
set_real_ip_from 0.0.0.0/0;
real_ip_header proxy_protocol;
'';
proxyTimeout = "1d";
recommendedZstdSettings = true;
recommendedTlsSettings = true;
# do not set Host header
recommendedProxySettings = false;
recommendedProxySettingsNoHost = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedBrotliSettings = true;
clientMaxBodySize = "0";
package =
let nginx-geoip2 =
{
AccountID = 901296;
LicenseKey = inputs.config.sops.secrets."nginx/maxmind-license".path;
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
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;
'';
# anyway to use host dns?
resolver.addresses = [ "8.8.8.8" ];
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
sops.secrets."nginx/maxmind-license" =
{
owner = inputs.config.users.users.nginx.name;
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
};
nixos.services.geoipupdate = {};
systemd.services.nginx.serviceConfig =
{
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];

View File

@@ -177,7 +177,7 @@ inputs:
basicAuthFile = inputs.lib.mkIf (site.value.global.detectAuth != null)
(
let secret = "nginx/templates/detectAuth/${inputs.lib.strings.escapeURL site.name}-global";
in inputs.config.sops.templates.${secret}.path
in inputs.config.nixos.system.sops.templates.${secret}.path
);
extraConfig = builtins.concatStringsSep "\n"
(
@@ -227,7 +227,7 @@ inputs:
let
inherit (inputs.lib.strings) escapeURL;
secret = "nginx/templates/detectAuth/${escapeURL site.name}/${escapeURL location.name}";
in inputs.config.sops.templates.${secret}.path
in inputs.config.nixos.system.sops.templates.${secret}.path
);
root = inputs.lib.mkIf (location.value.root or null != null) location.value.root;
}
@@ -247,7 +247,7 @@ inputs:
++ (inputs.lib.optionals (location.value.addAuth != null)
(
let authFile = "nginx/templates/addAuth/${location.value.addAuth}";
in [ "include ${inputs.config.sops.templates.${authFile}.path};" ]
in [ "include ${inputs.config.nixos.system.sops.templates.${authFile}.path};" ]
))
);
};
@@ -285,114 +285,108 @@ inputs:
};
})
sites);
nixos.services =
nixos =
{
nginx =
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
let listens = builtins.filter
(listen: listen.value.addToTransparentProxy)
(builtins.concatLists (builtins.map
(site: builtins.map (listen: { inherit (site) name; value = listen; }) site.value.listens)
sites));
in
{
transparentProxy.map = builtins.listToAttrs (builtins.map
(site:
{
inherit (site) name;
value = with nginx.global; httpsPort + (if site.value.http2 then httpsPortShift.http2 else 0);
})
(builtins.filter (listen: !listen.value.proxyProtocol) listens));
streamProxy.map = builtins.listToAttrs (builtins.map
(site:
{
inherit (site) name;
value =
services =
{
nginx =
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
let listens = builtins.filter
(listen: listen.value.addToTransparentProxy)
(builtins.concatLists (builtins.map
(site: builtins.map (listen: { inherit (site) name; value = listen; }) site.value.listens)
sites));
in
{
transparentProxy.map = builtins.listToAttrs (builtins.map
(site:
{
upstream.port = with nginx.global; httpsPort + httpsPortShift.proxyProtocol
+ (if site.value.http2 then httpsPortShift.http2 else 0);
proxyProtocol = true;
rewriteHttps = inputs.lib.mkDefault false;
};
})
(builtins.filter (listen: listen.value.proxyProtocol) listens));
http = builtins.listToAttrs (builtins.map
(site: { inherit (site) name; value.rewriteHttps = {}; })
(builtins.filter (site: site.value.global.rewriteHttps) sites));
};
acme.cert = builtins.listToAttrs (builtins.map
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
sites);
};
sops =
let
inherit (inputs.lib.strings) escapeURL;
detectAuthUsers = builtins.concatLists (builtins.map
(site:
(
(builtins.map
inherit (site) name;
value = with nginx.global; httpsPort + (if site.value.http2 then httpsPortShift.http2 else 0);
})
(builtins.filter (listen: !listen.value.proxyProtocol) listens));
streamProxy.map = builtins.listToAttrs (builtins.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 = inputs.lib.mkDefault false;
};
})
(builtins.filter (listen: listen.value.proxyProtocol) listens));
http = builtins.listToAttrs (builtins.map
(site: { inherit (site) name; value.rewriteHttps = {}; })
(builtins.filter (site: site.value.global.rewriteHttps) sites));
};
acme.cert = builtins.listToAttrs (builtins.map
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
sites);
};
system.sops =
let
inherit (inputs.lib.strings) escapeURL;
detectAuthUsers = builtins.concatLists (builtins.map
(site:
(
(builtins.map
(location:
{
name = "${escapeURL site.name}/${escapeURL location.name}";
value = location.value.detectAuth.users;
})
(builtins.filter (location: location.value.detectAuth or null != null) site.value.locations))
++ (inputs.lib.optionals (site.value.global.detectAuth != null)
[ { name = "${escapeURL site.name}-global"; value = site.value.global.detectAuth.users; } ])
))
sites);
addAuth = builtins.concatLists (builtins.map
(site: builtins.map
(location:
{
name = "${escapeURL site.name}/${escapeURL location.name}";
value = location.value.detectAuth.users;
value = location.value.addAuth;
})
(builtins.filter (location: location.value.detectAuth or null != null) site.value.locations))
++ (inputs.lib.optionals (site.value.global.detectAuth != null)
[ { name = "${escapeURL site.name}-global"; value = site.value.global.detectAuth.users; } ])
))
sites);
addAuth = builtins.concatLists (builtins.map
(site: builtins.map
(location:
{
name = "${escapeURL site.name}/${escapeURL location.name}";
value = location.value.addAuth;
})
(builtins.filter (location: location.value.addAuth or null != null) site.value.locations)
)
sites);
in
{
templates = builtins.listToAttrs
(
(builtins.map
(detectAuth:
{
name = "nginx/templates/detectAuth/${detectAuth.name}";
value =
(builtins.filter (location: location.value.addAuth or null != null) site.value.locations)
)
sites);
in
{
templates = let inherit (inputs.config.nixos.system.sops) placeholder; in builtins.listToAttrs
(
(builtins.map
(detectAuth: inputs.lib.nameValuePair "nginx/templates/detectAuth/${detectAuth.name}"
{
owner = inputs.config.users.users.nginx.name;
content = builtins.concatStringsSep "\n" (builtins.map
(user: "${user}:{PLAIN}${inputs.config.sops.placeholder."nginx/detectAuth/${user}"}")
(user: "${user}:{PLAIN}${placeholder."nginx/detectAuth/${user}"}")
detectAuth.value);
};
})
detectAuthUsers)
++ (builtins.map
(addAuth:
{
name = "nginx/templates/addAuth/${addAuth.name}";
value =
})
detectAuthUsers)
++ (builtins.map
(addAuth: inputs.lib.nameValuePair "nginx/templates/addAuth/${addAuth.name}"
{
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 = builtins.listToAttrs
(
(builtins.map
(secret: { name = "nginx/detectAuth/${secret}"; value = {}; })
(inputs.lib.unique (builtins.concatLists (builtins.map (detectAuth: detectAuth.value)
detectAuthUsers))))
++ (builtins.map
(secret: { name = "nginx/addAuth/${secret}"; value = {}; })
(inputs.lib.unique (builtins.map (addAuth: addAuth.value) addAuth)))
);
};
''proxy_set_header Authorization "Basic ${placeholder."nginx/addAuth/${addAuth.value}"}";'';
})
addAuth)
);
secrets = builtins.listToAttrs
(
(builtins.map
(secret: { name = "nginx/detectAuth/${secret}"; value = {}; })
(inputs.lib.unique (builtins.concatLists (builtins.map (detectAuth: detectAuth.value)
detectAuthUsers))))
++ (builtins.map
(secret: { name = "nginx/addAuth/${secret}"; value = {}; })
(inputs.lib.unique (builtins.map (addAuth: addAuth.value) addAuth)))
);
};
};
}
)
]);

View File

@@ -38,34 +38,48 @@ inputs:
access_log syslog:server=unix:/dev/log transparent_proxy;
}
'';
# TODO: use existing options
systemd.services.nginx-proxy =
let
ip = "${inputs.pkgs.iproute2}/bin/ip";
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
''
${ip} rule add fwmark 2/2 table 200
${ip} route add local 0.0.0.0/0 dev lo table 200
'';
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
''
${ip} rule del fwmark 2/2 table 200
${ip} route del local 0.0.0.0/0 dev lo table 200
'';
in
systemd =
{
services = inputs.lib.mkIf (inputs.config.nixos.system.network == null)
{
description = "nginx transparent proxy";
after = [ "network.target" ];
serviceConfig =
{
Type = "oneshot";
RemainAfterExit = true;
ExecStart = start;
ExecStop = stop;
};
wants = [ "network.target" ];
wantedBy= [ "multi-user.target" ];
nginx-proxy =
let
ip = "${inputs.pkgs.iproute2}/bin/ip";
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
''
${ip} rule add fwmark 2/2 table 200
${ip} route add local 0.0.0.0/0 dev lo table 200
'';
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
''
${ip} rule del fwmark 2/2 table 200
${ip} route del local 0.0.0.0/0 dev lo table 200
'';
in
{
description = "nginx transparent proxy";
after = [ "network.target" ];
serviceConfig =
{
Type = "oneshot";
RemainAfterExit = true;
ExecStart = start;
ExecStop = stop;
};
wants = [ "network.target" ];
wantedBy= [ "multi-user.target" ];
};
};
network.networks = inputs.lib.mkIf (inputs.config.nixos.system.network != null)
{
"10-custom" =
{
matchConfig.Name = "lo";
routes = [{ Table = 200; Destination = "0.0.0.0/0"; Type = "local"; }];
routingPolicyRules = [{ FirewallMark = "2/2"; Table = 200; }];
};
};
};
networking.nftables.tables.nginx =
{
family = "inet";

View File

@@ -15,12 +15,15 @@ inputs:
enable = true;
package = inputs.pkgs.nix-serve-ng;
openFirewall = true;
secretKeyFile = inputs.config.sops.secrets."store/signingKey".path;
secretKeyFile = inputs.config.nixos.system.sops.secrets."store/signingKey".path;
# curl -L cache.nixos.org/nix-cache-info
# use this cache after official one
extraParams = "--priority 50";
};
sops.secrets."store/signingKey" = {};
nixos.services.nginx.https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000";
nixos =
{
system.sops.secrets."store/signingKey" = {};
services.nginx.https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000";
};
};
}

View File

@@ -22,6 +22,7 @@ inputs:
{
name = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
nodatacow = mkOption { type = types.bool; default = false; };
iso = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
};
memory =
{
@@ -54,7 +55,12 @@ inputs:
default = [];
};
udp = tcp;
web = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
web = rec
{
httpsProxy = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
httpProxy = httpsProxy;
httpRedirect = httpsProxy;
};
};
};
};}));
@@ -83,7 +89,7 @@ inputs:
domains = builtins.map
(vm:
{
definition = inputs.config.sops.templates."nixvirt/${vm.name}.xml".path;
definition = inputs.config.nixos.system.sops.templates."nixvirt/${vm.name}.xml".path;
active = true;
restart = false;
})
@@ -122,146 +128,143 @@ inputs:
vnc_listen = "0.0.0.0"
'';
};
nixos.services =
nixos =
{
nginx =
let hosts = builtins.concatLists (builtins.map
(vm: builtins.map
(domain:
{
inherit domain;
ip = "192.168.${builtins.toString nixvirt.subnet}.${builtins.toString vm.network.address}";
})
vm.network.portForward.web)
(builtins.attrValues nixvirt.instance));
in
{
transparentProxy.map = builtins.listToAttrs (builtins.map
(host: { name = host.domain; value = "${host.ip}" + ":443"; }) hosts);
http = builtins.listToAttrs (builtins.map
(host: { name = host.domain; value.proxy.upstream = "http://${host.ip}" + ":80"; }) hosts);
};
kvm = {};
};
sops =
{
templates = builtins.listToAttrs (builtins.map
(vm:
{
name = "nixvirt/${vm.name}.xml";
value.content = inputs.topInputs.nixvirt.lib.domain.getXML
# port from 8bcc23e27a62297254d0e9c87281e650ff777132
system.sops =
{
templates = inputs.lib.mapAttrs'
(n: v: inputs.lib.nameValuePair "nixvirt/${n}.xml"
{
inherit (vm) name;
inherit (vm.value) uuid;
type = "kvm";
vcpu = { placement = "static"; count = vm.value.cpu.count; };
cputune = inputs.lib.optionalAttrs (vm.value.cpu.set != null)
content = inputs.topInputs.nixvirt.lib.domain.getXML
# port from 8bcc23e27a62297254d0e9c87281e650ff777132
{
vcpupin = builtins.genList
(cpu: { vcpu = cpu; cpuset = builtins.elemAt vm.value.cpu.set cpu; })
vm.value.cpu.count;
};
memory =
{
count = vm.value.memory.sizeMB;
unit = "MiB";
nosharepages = vm.value.memory.dedicated;
locked = vm.value.memory.dedicated;
};
os =
{
type = "hvm";
arch = "x86_64";
machine = "q35";
bootmenu = { enable = true; timeout = 15000; };
loader = { readonly = true; type = "pflash"; path = "/run/libvirt/nix-ovmf/OVMF_CODE.fd"; };
nvram =
name = n;
inherit (v) uuid;
type = "kvm";
vcpu = { placement = "static"; count = v.cpu.count; };
cputune = inputs.lib.optionalAttrs (v.cpu.set != null)
{
template = "/run/libvirt/nix-ovmf/OVMF_VARS.fd";
path = "/var/lib/libvirt/qemu/nvram/${vm.name}_VARS.fd";
templateFormat = "raw";
format = "raw";
vcpupin = builtins.genList (cpu: { vcpu = cpu; cpuset = builtins.elemAt v.cpu.set cpu; }) v.cpu.count;
};
};
features = { acpi = {}; apic = {}; };
cpu =
{
mode = "host-passthrough";
topology =
memory =
{
sockets = 1;
dies = 1;
cores = if vm.value.cpu.hyprthread then vm.value.cpu.count / 2 else vm.value.cpu.count;
threads = if vm.value.cpu.hyprthread then 2 else 1;
count = v.memory.sizeMB;
unit = "MiB";
nosharepages = v.memory.dedicated;
locked = v.memory.dedicated;
};
};
clock =
{
offset = "utc";
timer =
[
{ name = "rtc"; tickpolicy = "catchup"; }
{ name = "pit"; tickpolicy = "delay"; }
{ name = "hpet"; present = false; }
];
};
devices =
{
emulator = "${inputs.config.virtualisation.libvirtd.qemu.package}/bin/qemu-system-x86_64";
disk =
[
os =
{
type = "hvm";
arch = "x86_64";
machine = "q35";
bootmenu = { enable = true; timeout = 15000; };
loader = { readonly = true; type = "pflash"; path = "/run/libvirt/nix-ovmf/OVMF_CODE.fd"; };
nvram =
{
type = "file";
device = "disk";
driver = { name = "qemu"; type = "raw"; cache = "writeback"; discard = "unmap"; };
source.file = "${if vm.value.storage.nodatacow then "/nix/nodatacow" else ""}/var/lib/libvirt/images/"
+ "${vm.value.storage.name}.img";
target = { dev = "vda"; bus = "virtio"; };
boot.order = 1;
}
template = "/run/libvirt/nix-ovmf/OVMF_VARS.fd";
path = "/var/lib/libvirt/qemu/nvram/${n}_VARS.fd";
templateFormat = "raw";
format = "raw";
};
};
features = { acpi = {}; apic = {}; };
cpu =
{
mode = "host-passthrough";
topology =
{
type = "file";
device = "cdrom";
driver = { name = "qemu"; type = "raw"; };
source.file = "${inputs.topInputs.self.src.iso.netboot}";
target = { dev = "sdc"; bus = "sata"; };
readonly = true;
boot.order = 10;
}
];
interface =
{
type = "bridge";
model.type = "virtio";
mac.address = vm.value.network.mac;
source.bridge = if vm.value.network.bridge then "nixvirt" else "virbr0";
sockets = 1;
dies = 1;
cores = if v.cpu.hyprthread then v.cpu.count / 2 else v.cpu.count;
threads = if v.cpu.hyprthread then 2 else 1;
};
};
input =
[
{ type = "tablet"; bus = "usb"; }
{ type = "mouse"; bus = "ps2"; }
{ type = "keyboard"; bus = "ps2"; }
];
graphics =
clock =
{
type = "vnc";
autoport = false;
port = vm.value.network.vnc.port;
listen.type = "address";
passwd = inputs.config.sops.placeholder."nixvirt/${vm.name}";
offset = "utc";
timer =
[
{ name = "rtc"; tickpolicy = "catchup"; }
{ name = "pit"; tickpolicy = "delay"; }
{ name = "hpet"; present = false; }
];
};
devices =
{
emulator = "${inputs.config.virtualisation.libvirtd.qemu.package}/bin/qemu-system-x86_64";
disk =
[
{
type = "file";
device = "disk";
driver = { name = "qemu"; type = "raw"; cache = "writeback"; discard = "unmap"; };
source.file = "${if v.storage.nodatacow then "/nix/nodatacow" else ""}/var/lib/libvirt/images/"
+ "${v.storage.name}.img";
target = { dev = "vda"; bus = "virtio"; };
boot.order = 1;
}
{
type = "file";
device = "cdrom";
driver = { name = "qemu"; type = "raw"; };
source.file =
if v.storage.iso == null then "${inputs.topInputs.self.src.iso.netboot}" else v.storage.iso;
target = { dev = "sdc"; bus = "sata"; };
readonly = true;
boot.order = 10;
}
];
interface =
{
type = "bridge";
model.type = "virtio";
mac.address = v.network.mac;
source.bridge = if v.network.bridge then "nixvirt" else "virbr0";
};
input =
[
{ type = "tablet"; bus = "usb"; }
{ type = "mouse"; bus = "ps2"; }
{ type = "keyboard"; bus = "ps2"; }
];
graphics =
{
type = "vnc";
autoport = false;
port = v.network.vnc.port;
listen.type = "address";
passwd = inputs.config.sops.placeholder."nixvirt/${n}";
};
video.model = { type = "qxl"; ram = 65536; vram = 65536; vgamem = 16384; heads = 1; primary = true; };
rng = { model = "virtio"; backend = { model = "random"; source = /dev/urandom; }; };
};
video.model = { type = "qxl"; ram = 65536; vram = 65536; vgamem = 16384; heads = 1; primary = true; };
rng = { model = "virtio"; backend = { model = "random"; source = /dev/urandom; }; };
};
};
})
(inputs.localLib.attrsToList nixvirt.instance));
secrets = builtins.listToAttrs (builtins.map
(vm: { name = "nixvirt/${vm}"; value = {}; }) (builtins.attrNames nixvirt.instance));
placeholder = builtins.listToAttrs (builtins.map
(vm: { name = "nixvirt/${vm}"; value = builtins.hashString "sha256" "nixvirt/${vm}"; })
(builtins.attrNames nixvirt.instance));
})
nixvirt.instance;
secrets = inputs.lib.mapAttrs' (n: _: inputs.lib.nameValuePair "nixvirt/${n}" {}) nixvirt.instance;
};
services =
{
nginx = inputs.lib.mkMerge (builtins.map
(vm: let ip = "192.168.${builtins.toString nixvirt.subnet}.${builtins.toString vm.network.address}"; in
{
transparentProxy.map = builtins.listToAttrs (builtins.map
(host: inputs.lib.nameValuePair host "${ip}:443")
vm.network.portForward.web.httpsProxy);
http = inputs.lib.mkMerge
[
(builtins.listToAttrs (builtins.map
(host: inputs.lib.nameValuePair host { proxy.upstream = "http://${ip}" + ":80"; })
vm.network.portForward.web.httpProxy))
(builtins.listToAttrs (builtins.map
(host: inputs.lib.nameValuePair host { rewriteHttps = {}; })
vm.network.portForward.web.httpRedirect))
];
})
(builtins.attrValues nixvirt.instance or {}));
kvm = {};
};
};
security.wrappers.vm =
{

View File

@@ -28,19 +28,22 @@ inputs:
ENABLE_IMAGE_GENERATION = "True";
IMAGES_OPENAI_API_BASE_URL = "https://oa.api2d.net/v1";
};
environmentFile = inputs.config.sops.templates."open-webui.env".path;
environmentFile = inputs.config.nixos.system.sops.templates."open-webui.env".path;
};
sops =
nixos =
{
templates."open-webui.env".content = let inherit (inputs.config.sops) placeholder; in
''
OPENAI_API_KEY=${placeholder."open-webui/openai"}
WEBUI_SECRET_KEY=${placeholder."open-webui/webui"}
IMAGES_OPENAI_API_KEY=${placeholder."open-webui/openai"}
'';
secrets = { "open-webui/openai" = {}; "open-webui/webui" = {}; };
system.sops =
{
templates."open-webui.env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
''
OPENAI_API_KEY=${placeholder."open-webui/openai"}
WEBUI_SECRET_KEY=${placeholder."open-webui/webui"}
IMAGES_OPENAI_API_KEY=${placeholder."open-webui/openai"}
'';
secrets = { "open-webui/openai" = {}; "open-webui/webui" = {}; };
};
services.nginx.https."${open-webui.hostname}".location."/".proxy =
{ upstream = "http://127.0.0.1:8080"; websocket = true; };
};
nixos.services.nginx.https."${open-webui.hostname}".location."/".proxy =
{ upstream = "http://127.0.0.1:8080"; websocket = true; };
};
}

View File

@@ -17,48 +17,46 @@ inputs:
listenHttp = 5046;
listenWeb = 443;
enableWebHttps = true;
serviceEnvironmentFile = inputs.config.sops.templates."peertube/env".path;
secrets.secretsFile = inputs.config.sops.secrets."peertube/secrets".path;
serviceEnvironmentFile = inputs.config.nixos.system.sops.templates."peertube/env".path;
secrets.secretsFile = inputs.config.nixos.system.sops.secrets."peertube/secrets".path;
configureNginx = true;
database =
{
createLocally = true;
host = "127.0.0.1";
passwordFile = inputs.config.sops.secrets."peertube/postgresql".path;
passwordFile = inputs.config.nixos.system.sops.secrets."peertube/postgresql".path;
};
redis =
{
host = "127.0.0.1";
port = 7599;
passwordFile = inputs.config.sops.secrets."redis/peertube".path;
};
smtp.passwordFile = inputs.config.sops.secrets."peertube/smtp".path;
settings.smtp =
{
host = "mail.chn.moe";
username = "bot@chn.moe";
from_address = "bot@chn.moe";
passwordFile = inputs.config.nixos.system.sops.secrets."redis/peertube".path;
};
smtp.passwordFile = inputs.config.nixos.system.sops.secrets."peertube/smtp".path;
settings.smtp = { host = "mail.chn.moe"; username = "bot@chn.moe"; from_address = "bot@chn.moe"; };
};
sops =
nixos =
{
templates."peertube/env".content =
''
PT_INITIAL_ROOT_PASSWORD=${inputs.config.sops.placeholder."peertube/password"}
'';
secrets =
system.sops =
{
"peertube/postgresql" = { owner = inputs.config.services.peertube.user; key = "postgresql/peertube"; };
"peertube/password" = {};
"peertube/secrets".owner = inputs.config.services.peertube.user;
"peertube/smtp" = { owner = inputs.config.services.peertube.user; key = "mail/bot"; };
templates."peertube/env".content =
''
PT_INITIAL_ROOT_PASSWORD=${inputs.config.nixos.system.sops.placeholder."peertube/password"}
'';
secrets =
{
"peertube/postgresql" = { owner = inputs.config.services.peertube.user; key = "postgresql/peertube"; };
"peertube/password" = {};
"peertube/secrets".owner = inputs.config.services.peertube.user;
"peertube/smtp" = { owner = inputs.config.services.peertube.user; key = "mail/bot"; };
};
};
services =
{
nginx.https.${peertube.hostname}.global.configName = peertube.hostname;
postgresql.instances.peertube = {};
redis.instances.peertube.port = 7599;
};
};
nixos.services =
{
nginx.https.${peertube.hostname}.global.configName = peertube.hostname;
postgresql.instances.peertube = {};
redis.instances.peertube.port = 7599;
};
systemd.services.peertube.after = [ "redis-peertube.service" ];
};

View File

@@ -23,21 +23,24 @@ inputs:
{
after = [ "mariadb.service" ];
requires = [ "mariadb.service" ];
serviceConfig.EnvironmentFile = inputs.config.sops.templates."photoprism/env".path;
serviceConfig.EnvironmentFile = inputs.config.nixos.system.sops.templates."photoprism/env".path;
};
sops =
nixos =
{
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.instances.photoprism = {};
nginx.https."photoprism.chn.moe".location."/".proxy = { upstream = "http://127.0.0.1:2342"; websocket = true; };
system.sops =
{
templates."photoprism/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
''
PHOTOPRISM_ADMIN_PASSWORD=${placeholder."photoprism/adminPassword"}
PHOTOPRISM_DATABASE_PASSWORD=${placeholder."mariadb/photoprism"}
'';
secrets."photoprism/adminPassword" = {};
};
services =
{
mariadb.instances.photoprism = {};
nginx.https."photoprism.chn.moe".location."/".proxy = { upstream = "http://127.0.0.1:2342"; websocket = true; };
};
};
};
}

View File

@@ -63,7 +63,7 @@ inputs:
let
passwordFile =
if db.value.passwordFile or null != null then db.value.passwordFile
else inputs.config.sops.secrets."postgresql/${db.value.user}".path;
else inputs.config.nixos.system.sops.secrets."postgresql/${db.value.user}".path;
initializeFlag =
if db.value.initializeFlags != {} then
" WITH "
@@ -85,7 +85,7 @@ inputs:
+ " | grep -E '^${db.value.user}$' -q"
+ " || $PSQL -tAc \"ALTER DATABASE ${db.value.database} OWNER TO ${db.value.user}\"")
(inputs.localLib.attrsToList postgresql.instances)));
sops.secrets = builtins.listToAttrs (builtins.map
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
(db: { name = "postgresql/${db.value.user}"; value.owner = inputs.config.users.users.postgres.name; })
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList postgresql.instances)));
environment.persistence."/nix/nodatacow".directories = inputs.lib.mkIf postgresql.nodatacow

View File

@@ -28,12 +28,13 @@ inputs:
# unixSocket = null; # bug
unixSocketPerm = 600;
requirePassFile =
if server.value.passwordFile == null then inputs.config.sops.secrets."redis/${server.name}".path
if server.value.passwordFile == null
then inputs.config.nixos.system.sops.secrets."redis/${server.name}".path
else server.value.passwordFile;
};
})
(inputs.localLib.attrsToList redis.instances));
sops.secrets = builtins.listToAttrs (builtins.map
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
(server: { name = "redis/${server.name}"; value.owner = inputs.config.users.users.${server.value.user}.name; })
(builtins.filter (server: server.value.passwordFile == null) (inputs.localLib.attrsToList redis.instances)));
systemd.services = builtins.listToAttrs (builtins.map

View File

@@ -15,34 +15,37 @@ inputs:
image = "rsshub:latest";
imageFile = inputs.topInputs.self.src.rsshub;
ports = [ "127.0.0.1:5221:5221/tcp" ];
environmentFiles = [ inputs.config.sops.templates."rsshub/env".path ];
environmentFiles = [ inputs.config.nixos.system.sops.templates."rsshub/env".path ];
};
sops =
nixos =
{
templates."rsshub/env".content = let placeholder = inputs.config.sops.placeholder; in
''
PORT=5221
CACHE_TYPE=memory
PIXIV_REFRESHTOKEN='${placeholder."rsshub/pixiv-refreshtoken"}'
YOUTUBE_KEY='${placeholder."rsshub/youtube-key"}'
YOUTUBE_CLIENT_ID='${placeholder."rsshub/youtube-client-id"}'
YOUTUBE_CLIENT_SECRET='${placeholder."rsshub/youtube-client-secret"}'
YOUTUBE_REFRESH_TOKEN='${placeholder."rsshub/youtube-refresh-token"}'
TWITTER_AUTH_TOKEN='${placeholder."rsshub/twitter-auth-token"}'
ZHIHU_COOKIES='${placeholder."rsshub/zhihu-cookies"}'
XDG_CONFIG_HOME='/var/cache/rsshub/chromium'
XDG_CACHE_HOME='/var/cache/rsshub/chromium'
BILIBILI_COOKIE_data0='${placeholder."rsshub/bilibili-cookie"}'
'';
secrets = (builtins.listToAttrs (builtins.map (secret: { name = "rsshub/${secret}"; value = {}; })
[
"pixiv-refreshtoken"
"youtube-key" "youtube-client-id" "youtube-client-secret" "youtube-refresh-token"
"twitter-auth-token"
"bilibili-cookie"
"zhihu-cookies"
]));
system.sops =
{
templates."rsshub/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
''
PORT=5221
CACHE_TYPE=memory
PIXIV_REFRESHTOKEN='${placeholder."rsshub/pixiv-refreshtoken"}'
YOUTUBE_KEY='${placeholder."rsshub/youtube-key"}'
YOUTUBE_CLIENT_ID='${placeholder."rsshub/youtube-client-id"}'
YOUTUBE_CLIENT_SECRET='${placeholder."rsshub/youtube-client-secret"}'
YOUTUBE_REFRESH_TOKEN='${placeholder."rsshub/youtube-refresh-token"}'
TWITTER_AUTH_TOKEN='${placeholder."rsshub/twitter-auth-token"}'
ZHIHU_COOKIES='${placeholder."rsshub/zhihu-cookies"}'
XDG_CONFIG_HOME='/var/cache/rsshub/chromium'
XDG_CACHE_HOME='/var/cache/rsshub/chromium'
BILIBILI_COOKIE_data0='${placeholder."rsshub/bilibili-cookie"}'
'';
secrets = (builtins.listToAttrs (builtins.map (secret: inputs.lib.nameValuePair "rsshub/${secret}" {})
[
"pixiv-refreshtoken"
"youtube-key" "youtube-client-id" "youtube-client-secret" "youtube-refresh-token"
"twitter-auth-token"
"bilibili-cookie"
"zhihu-cookies"
]));
};
services.nginx.https.${rsshub.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5221";
};
nixos.services.nginx.https.${rsshub.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5221";
};
}

View File

@@ -14,16 +14,19 @@ inputs:
{
enable = true;
settings.server = { port = 8081; bind_address = "127.0.0.1"; secret_key = "@SEARX_SECRET_KEY@"; };
environmentFile = inputs.config.sops.templates."searx.env".path;
environmentFile = inputs.config.nixos.system.sops.templates."searx.env".path;
};
sops =
nixos =
{
templates."searx.env".content = let inherit (inputs.config.sops) placeholder; in
''
SEARX_SECRET_KEY=${placeholder."searx/secret-key"}
'';
secrets."searx/secret-key" = {};
system.sops =
{
templates."searx.env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
''
SEARX_SECRET_KEY=${placeholder."searx/secret-key"}
'';
secrets."searx/secret-key" = {};
};
services.nginx.https.${searx.hostname}.location."/".proxy.upstream = "http://127.0.0.1:8081";
};
nixos.services.nginx.https.${searx.hostname}.location."/".proxy.upstream = "http://127.0.0.1:8081";
};
}

View File

@@ -20,7 +20,7 @@ inputs:
createLocally = false;
host = "127.0.0.1";
port = 9184;
passwordFile = inputs.config.sops.secrets."redis/send".path;
passwordFile = inputs.config.nixos.system.sops.secrets."redis/send".path;
};
};
systemd.services.send.after = [ "redis-send.service" ];

View File

@@ -177,7 +177,7 @@ inputs:
# ConstrainDevices=yes
'';
};
munge = { enable = true; password = inputs.config.sops.secrets."munge.key".path; };
munge = { enable = true; password = inputs.config.nixos.system.sops.secrets."munge.key".path; };
};
systemd.services.slurmd.environment =
let gpus = slurm.node.${inputs.config.nixos.model.hostname}.gpus or null;
@@ -186,12 +186,16 @@ inputs:
CUDA_PATH = "${inputs.pkgs.cudatoolkit}";
LD_LIBRARY_PATH = "${inputs.config.hardware.nvidia.package}/lib";
};
sops.secrets."munge.key" =
nixos.system.sops.secrets."munge.key" =
{
format = "binary";
sopsFile = inputs.localLib.mkConditional (inputs.config.nixos.model.cluster == null)
"${builtins.dirOf inputs.config.sops.defaultSopsFile}/munge.key"
"${inputs.config.nixos.system.sops.clusterSopsDir}/munge.key";
sopsFile =
let
devicePath = "${inputs.topInputs.self}/devices";
inherit (inputs.config.nixos) model;
in inputs.localLib.mkConditional (model.cluster == null)
"${devicePath}/${model.hostname}/secrets/munge.key"
"${devicePath}/${model.cluster.clusterName}/secrets/munge.key";
owner = inputs.config.systemd.services.munged.serviceConfig.User;
};
environment.sessionVariables = { SLURM_UNBUFFEREDIO = "1"; SLURM_CPU_BIND = "v"; };
@@ -206,7 +210,7 @@ inputs:
{
enable = true;
dbdHost = "localhost";
storagePassFile = inputs.config.sops.secrets."slurm/db".path;
storagePassFile = inputs.config.nixos.system.sops.secrets."slurm/db".path;
extraConfig =
''
StorageHost=*
@@ -224,24 +228,20 @@ inputs:
services.slurmctld = { after = [ "suid-sgid-wrappers.service" ]; serviceConfig.MemorySwapMax = "0"; };
tmpfiles.rules = [ "d /var/log/slurmctld 700 slurm slurm" ];
};
sops =
nixos.system.sops =
{
secrets = { "slurm/db" = { owner = "slurm"; key = "mariadb/slurm"; }; }
// builtins.listToAttrs (builtins.map
(n:
{
name = "telegram/${n}";
value.sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
})
(n: inputs.lib.nameValuePair "telegram/${n}" {})
[ "token" "user/chn" "user/hjp" ]);
templates."info.yaml" =
{
owner = "slurm";
content = let inherit (inputs.config.sops) placeholder; in builtins.toJSON
content = let inherit (inputs.config.nixos.system.sops) placeholder; in builtins.toJSON
{
token = placeholder."telegram/token";
user = builtins.listToAttrs (builtins.map (n: { name = n; value = placeholder."telegram/user/${n}"; })
[ "chn" "hjp" ]);
user = builtins.listToAttrs (builtins.map
(n: inputs.lib.nameValuePair n placeholder."telegram/user/${n}") [ "chn" "hjp" ]);
slurmConf = "${inputs.config.services.slurm.etcSlurm}/slurm.conf";
};
};
@@ -252,7 +252,7 @@ inputs:
let info = inputs.pkgs.localPackages.info.override
{
slurm = inputs.config.services.slurm.package;
configFile = inputs.config.sops.templates."info.yaml".path;
configFile = inputs.config.nixos.system.sops.templates."info.yaml".path;
};
in "${info}/bin/info";
program = "slurm-info";

View File

@@ -0,0 +1,24 @@
inputs:
{
options.nixos.services.speedtest = let inherit (inputs.lib) mkOption types; in mkOption
{
type = types.nullOr (types.submodule { options =
{
hostname = mkOption { type = types.nonEmptyStr; default = "409test.chn.moe"; };
};});
default = null;
};
config = let inherit (inputs.config.nixos.services) speedtest; in inputs.lib.mkIf (speedtest != null)
{
nixos.services =
{
phpfpm.instances.speedtest = {};
nginx.https.${speedtest.hostname} = let pkg = inputs.pkgs.localPackages.speedtest; in
{
global.root = "${pkg}";
location."~ ^.+?\.php(/.*)?$".php =
{ root = "${pkg}"; fastcgiPass = inputs.config.nixos.services.phpfpm.instances.speedtest.fastcgi; };
};
};
};
}

View File

@@ -43,7 +43,7 @@ inputs:
let
package = inputs.pkgs.matrix-synapse.override
{ extras = [ "url-preview" "postgres" "redis" ]; plugins = []; };
config = inputs.config.sops.templates."synapse/${instance.name}/config.yaml".path;
config = inputs.config.nixos.system.sops.templates."synapse/${instance.name}/config.yaml".path;
homeserver = "${package}/bin/synapse_homeserver";
in
{
@@ -100,143 +100,145 @@ inputs:
];
})
(inputs.localLib.attrsToList synapse.instances));
sops = inputs.lib.mkMerge (builtins.map
(instance:
{
templates."synapse/${instance.name}/config.yaml" =
{
owner = "synapse-${instance.name}";
group = "synapse-${instance.name}";
content =
let
inherit (inputs.config.sops) placeholder;
in builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "${instance.name}.yaml"
{
server_name = instance.value.matrixHostname;
public_baseurl = "https://${instance.value.hostname}/";
listeners =
[{
bind_addresses = [ "127.0.0.1" ];
inherit (instance.value) port;
resources = [{ names = [ "client" "federation" ]; compress = false; }];
tls = false;
type = "http";
x_forwarded = true;
}];
database =
{
name = "psycopg2";
args = let name = "synapse_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; in
{
user = name;
password = placeholder."postgresql/${name}";
database = name;
host = "127.0.0.1";
port = "5432";
};
allow_unsafe_locale = true;
};
redis =
{
enabled = true;
port = instance.value.redisPort;
password = placeholder."redis/synapse-${instance.name}";
};
turn_shared_secret = placeholder."synapse/${instance.name}/coturn";
registration_shared_secret = placeholder."synapse/${instance.name}/registration";
macaroon_secret_key = placeholder."synapse/${instance.name}/macaroon";
form_secret = placeholder."synapse/${instance.name}/form";
signing_key_path = inputs.config.sops.secrets."synapse/${instance.name}/signing-key".path;
email =
{
smtp_host = "mail.chn.moe";
smtp_port = 25;
smtp_user = "bot@chn.moe";
smtp_pass = placeholder."mail/bot";
require_transport_security = true;
notif_from = "Your Friendly %(app)s homeserver <bot@chn.moe>";
app_name = "Haonan Chen's synapse";
};
admin_contact = "mailto:chn@chn.moe";
enable_registration = true;
registrations_require_3pid = [ "email" ];
registration_requires_token = true;
turn_uris = [ "turns:coturn.chn.moe" "turn:coturn.chn.moe" ];
max_upload_size = "1024M";
web_client_location = "https://element.chn.moe/";
report_stats = true;
trusted_key_servers =
[{
server_name = "matrix.org";
verify_keys."ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
}];
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;
};
pid_file = "/run/synapse-${instance.name}.pid";
media_store_path = "/var/lib/synapse/${instance.name}/media_store";
presence.enabled = true;
url_preview_enabled = true;
url_preview_ip_range_blacklist =
[
"10.0.0.0/8" "100.64.0.0/10" "127.0.0.0/8" "169.254.0.0/16" "172.16.0.0/12" "192.0.0.0/24"
"192.0.2.0/24" "192.168.0.0/16" "192.88.99.0/24" "198.18.0.0/15" "198.51.100.0/24" "2001:db8::/32"
"203.0.113.0/24" "224.0.0.0/4" "::1/128" "fc00::/7" "fe80::/10" "fec0::/10" "ff00::/8"
];
max_image_pixels = "32M";
dynamic_thumbnails = false;
# this is required for displaying thumbnails in sticker widgets
enable_authenticated_media = false;
});
};
secrets = (builtins.listToAttrs (builtins.map
(secret: { name = "synapse/${instance.name}/${secret}"; value = {}; })
[ "coturn" "registration" "macaroon" "form" ]))
// { "synapse/${instance.name}/signing-key".owner = "synapse-${instance.name}"; }
// { "mail/bot" = {}; };
})
(inputs.localLib.attrsToList synapse.instances));
nixos.services =
nixos =
{
postgresql.instances = builtins.listToAttrs (builtins.map
system.sops = inputs.lib.mkMerge (builtins.map
(instance:
{
name = "synapse_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}";
value.initializeFlags = { TEMPLATE = "template0"; LC_CTYPE = "C"; LC_COLLATE = "C"; };
})
(inputs.localLib.attrsToList synapse.instances));
redis.instances = builtins.listToAttrs (builtins.map
(instance: { name = "synapse-${instance.name}"; value.port = instance.value.redisPort; })
(inputs.localLib.attrsToList synapse.instances));
nginx.https = builtins.listToAttrs (builtins.map
(instance: with instance.value;
{
name = hostname;
value.location =
templates."synapse/${instance.name}/config.yaml" =
{
"/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
"/.well-known/matrix/server".static =
{
root = builtins.toString (inputs.pkgs.writeTextFile
owner = "synapse-${instance.name}";
content =
let
inherit (inputs.config.nixos.system.sops) placeholder;
in builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "${instance.name}.yaml"
{
name = "server";
text = builtins.toJSON
server_name = instance.value.matrixHostname;
public_baseurl = "https://${instance.value.hostname}/";
listeners =
[{
bind_addresses = [ "127.0.0.1" ];
inherit (instance.value) port;
resources = [{ names = [ "client" "federation" ]; compress = false; }];
tls = false;
type = "http";
x_forwarded = true;
}];
database =
{
"m.server" = "${hostname}:443";
name = "psycopg2";
args = let name = "synapse_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; in
{
user = name;
password = placeholder."postgresql/${name}";
database = name;
host = "127.0.0.1";
port = "5432";
};
allow_unsafe_locale = true;
};
destination = "/.well-known/matrix/server";
redis =
{
enabled = true;
port = instance.value.redisPort;
password = placeholder."redis/synapse-${instance.name}";
};
turn_shared_secret = placeholder."synapse/${instance.name}/coturn";
registration_shared_secret = placeholder."synapse/${instance.name}/registration";
macaroon_secret_key = placeholder."synapse/${instance.name}/macaroon";
form_secret = placeholder."synapse/${instance.name}/form";
signing_key_path = inputs.config.nixos.system.sops.secrets."synapse/${instance.name}/signing-key".path;
email =
{
smtp_host = "mail.chn.moe";
smtp_port = 25;
smtp_user = "bot@chn.moe";
smtp_pass = placeholder."mail/bot";
require_transport_security = true;
notif_from = "Your Friendly %(app)s homeserver <bot@chn.moe>";
app_name = "Haonan Chen's synapse";
};
admin_contact = "mailto:chn@chn.moe";
enable_registration = true;
registrations_require_3pid = [ "email" ];
registration_requires_token = true;
turn_uris = [ "turns:coturn.chn.moe" "turn:coturn.chn.moe" ];
max_upload_size = "1024M";
web_client_location = "https://element.chn.moe/";
report_stats = true;
trusted_key_servers =
[{
server_name = "matrix.org";
verify_keys."ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
}];
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;
};
pid_file = "/run/synapse-${instance.name}.pid";
media_store_path = "/var/lib/synapse/${instance.name}/media_store";
presence.enabled = true;
url_preview_enabled = true;
url_preview_ip_range_blacklist =
[
"10.0.0.0/8" "100.64.0.0/10" "127.0.0.0/8" "169.254.0.0/16" "172.16.0.0/12" "192.0.0.0/24"
"192.0.2.0/24" "192.168.0.0/16" "192.88.99.0/24" "198.18.0.0/15" "198.51.100.0/24" "2001:db8::/32"
"203.0.113.0/24" "224.0.0.0/4" "::1/128" "fc00::/7" "fe80::/10" "fec0::/10" "ff00::/8"
];
max_image_pixels = "32M";
dynamic_thumbnails = false;
# this is required for displaying thumbnails in sticker widgets
enable_authenticated_media = false;
});
};
};
secrets = (builtins.listToAttrs (builtins.map
(secret: { name = "synapse/${instance.name}/${secret}"; value = {}; })
[ "coturn" "registration" "macaroon" "form" ]))
// { "synapse/${instance.name}/signing-key".owner = "synapse-${instance.name}"; }
// { "mail/bot" = {}; };
})
(inputs.localLib.attrsToList synapse.instances));
services =
{
postgresql.instances = builtins.listToAttrs (builtins.map
(instance:
{
name = "synapse_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}";
value.initializeFlags = { TEMPLATE = "template0"; LC_CTYPE = "C"; LC_COLLATE = "C"; };
})
(inputs.localLib.attrsToList synapse.instances));
redis.instances = builtins.listToAttrs (builtins.map
(instance: { name = "synapse-${instance.name}"; value.port = instance.value.redisPort; })
(inputs.localLib.attrsToList synapse.instances));
nginx.https = builtins.listToAttrs (builtins.map
(instance: with instance.value;
{
name = hostname;
value.location =
{
"/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
"/.well-known/matrix/server".static =
{
root = builtins.toString (inputs.pkgs.writeTextFile
{
name = "server";
text = builtins.toJSON
{
"m.server" = "${hostname}:443";
};
destination = "/.well-known/matrix/server";
});
};
};
})
(inputs.localLib.attrsToList synapse.instances));
};
};
};
}

View File

@@ -25,29 +25,32 @@ inputs:
SMTP_SECURITY = "force_tls";
SMTP_USERNAME = "bot@chn.moe";
};
environmentFile = inputs.config.sops.templates."vaultwarden.env".path;
environmentFile = inputs.config.nixos.system.sops.templates."vaultwarden.env".path;
};
sops =
nixos =
{
templates."vaultwarden.env" = let placeholder = inputs.config.sops.placeholder; in
system.sops =
{
owner = "vaultwarden";
group = "vaultwarden";
content =
''
DATABASE_URL=postgresql://vaultwarden:${placeholder."postgresql/vaultwarden"}@localhost/vaultwarden
ADMIN_TOKEN=${placeholder."vaultwarden/admin_token"}
SMTP_PASSWORD=${placeholder."mail/bot"}
'';
templates."vaultwarden.env" = let inherit (inputs.config.nixos.system.sops) placeholder; in
{
owner = "vaultwarden";
group = "vaultwarden";
content =
''
DATABASE_URL=postgresql://vaultwarden:${placeholder."postgresql/vaultwarden"}@localhost/vaultwarden
ADMIN_TOKEN=${placeholder."vaultwarden/admin_token"}
SMTP_PASSWORD=${placeholder."mail/bot"}
'';
};
secrets = { "vaultwarden/admin_token" = {}; "mail/bot" = {}; };
};
services =
{
postgresql.instances.vaultwarden = {};
nginx.https.${vaultwarden.hostname}.location."/".proxy =
{ upstream = "http://127.0.0.1:8000"; websocket = true; };
};
secrets = { "vaultwarden/admin_token" = {}; "mail/bot" = {}; };
};
systemd.services.vaultwarden.after = [ "postgresql.service" ];
nixos.services =
{
postgresql.instances.vaultwarden = {};
nginx.https.${vaultwarden.hostname}.location."/".proxy =
{ upstream = "http://127.0.0.1:8000"; websocket = true; };
};
};
}

View File

@@ -33,7 +33,7 @@ inputs:
{
inherit (wg.value) listenPort;
ips = [ "${wg.value.ip}/${builtins.toString wg.value.netmask}" ];
privateKeyFile = inputs.config.sops.secrets.wireguard.path;
privateKeyFile = inputs.config.nixos.system.sops.secrets.wireguard.path;
peers = builtins.map
(peer:
{
@@ -45,6 +45,6 @@ inputs:
};
})
(inputs.localLib.attrsToList wireguard));
sops.secrets.wireguard = {};
nixos.system.sops.secrets.wireguard = {};
};
}

View File

@@ -43,7 +43,7 @@ inputs:
};
resolved.enable = false;
};
sops =
nixos.system.sops =
{
templates."xray-client.json" =
{
@@ -120,7 +120,7 @@ inputs:
port = 443;
users =
[{
id = inputs.config.sops.placeholder."xray-client/uuid";
id = inputs.config.nixos.system.sops.placeholder."xray-client/uuid";
encryption = "none";
flow = "xtls-rprx-vision-udp443";
}];
@@ -173,45 +173,63 @@ inputs:
};
secrets."xray-client/uuid" = {};
};
systemd.services =
systemd =
{
xray-client =
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script = "exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-client.json".path}";
serviceConfig =
services = inputs.lib.mkMerge
[
{
User = "v2ray";
Group = "v2ray";
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
NoNewPrivileges = true;
LimitNPROC = 65536;
LimitNOFILE = 524288;
CPUSchedulingPolicy = "rr";
};
restartTriggers = [ inputs.config.sops.templates."xray-client.json".file ];
};
v2ray-forwarder =
{
description = "v2ray-forwarder Daemon";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = let ip = "${inputs.pkgs.iproute2}/bin/ip"; in
xray-client =
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script = let config = inputs.config.nixos.system.sops.templates."xray-client.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig =
{
User = "v2ray";
Group = "v2ray";
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
NoNewPrivileges = true;
LimitNPROC = 65536;
LimitNOFILE = 524288;
CPUSchedulingPolicy = "rr";
};
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-client.json".file ];
};
}
(inputs.lib.mkIf (inputs.config.nixos.system.network == null)
{
Type = "oneshot";
RemainAfterExit = true;
ExecStart = inputs.pkgs.writeShellScript "v2ray-forwarder.start"
''
${ip} rule add fwmark 1/1 table 100
${ip} route add local 0.0.0.0/0 dev lo table 100
'';
ExecStop = inputs.pkgs.writeShellScript "v2ray-forwarder.stop"
''
${ip} rule del fwmark 1/1 table 100
${ip} route del local 0.0.0.0/0 dev lo table 100
'';
v2ray-forwarder =
{
description = "v2ray-forwarder Daemon";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = let ip = "${inputs.pkgs.iproute2}/bin/ip"; in
{
Type = "oneshot";
RemainAfterExit = true;
ExecStart = inputs.pkgs.writeShellScript "v2ray-forwarder.start"
''
${ip} rule add fwmark 1/1 table 100
${ip} route add local 0.0.0.0/0 dev lo table 100
'';
ExecStop = inputs.pkgs.writeShellScript "v2ray-forwarder.stop"
''
${ip} rule del fwmark 1/1 table 100
${ip} route del local 0.0.0.0/0 dev lo table 100
'';
};
};
})
];
network.networks = inputs.lib.mkIf (inputs.config.nixos.system.network != null)
{
"10-custom" =
{
matchConfig.Name = "lo";
routes = [{ Table = 100; Destination = "0.0.0.0/0"; Type = "local"; }];
routingPolicyRules = [{ FirewallMark = "1/1"; Table = 100; }];
};
};
};

View File

@@ -10,136 +10,144 @@ inputs:
};
config = let inherit (inputs.config.nixos.services.xray) server; in inputs.lib.mkIf (server != null)
(
let userList = builtins.attrNames
(inputs.pkgs.localPackages.fromYaml (builtins.readFile inputs.config.sops.defaultSopsFile)).xray-server.clients;
let userList = builtins.map (user: builtins.elemAt user 2) (builtins.filter
(user: builtins.length user == 3 && inputs.lib.lists.hasPrefix [ "xray-server" "clients" ] user)
inputs.config.nixos.system.sops.availableKeys);
in
{
sops =
nixos =
{
templates."xray-server.json" =
system.sops =
{
owner = inputs.config.users.users.v2ray.name;
group = inputs.config.users.users.v2ray.group;
content = builtins.toJSON
templates."xray-server.json" =
{
log.loglevel = "warning";
inbounds =
[
(
let fallbackPort = builtins.toString
(with inputs.config.nixos.services.nginx.global; httpsPort + httpsPortShift.http2);
in
owner = inputs.config.users.users.v2ray.name;
group = inputs.config.users.users.v2ray.group;
content = builtins.toJSON
{
log.loglevel = "warning";
inbounds =
[
(
let fallbackPort = builtins.toString
(with inputs.config.nixos.services.nginx.global; httpsPort + httpsPortShift.http2);
in
{
port = 4726;
listen = "127.0.0.1";
protocol = "vless";
settings =
{
clients = builtins.map
(n:
{
id = inputs.config.nixos.system.sops.placeholder."xray-server/clients/${n}";
flow = "xtls-rprx-vision";
email = "${n}@xray.chn.moe";
})
userList;
decryption = "none";
fallbacks = [{ dest = "127.0.0.1:${fallbackPort}"; }];
};
streamSettings =
{
network = "raw";
security = "reality";
realitySettings =
{
dest = "127.0.0.1:${fallbackPort}";
serverNames = [ server.serverName ];
privateKey = inputs.config.nixos.system.sops.placeholder."xray-server/private-key";
minClientVer = "1.8.0";
shortIds = [ "" ];
};
};
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; routeOnly = true; };
tag = "in-legacy";
}
)
{
port = 4726;
port = 4638;
listen = "127.0.0.1";
protocol = "vless";
settings =
{
clients = builtins.map
(n:
{
id = inputs.config.sops.placeholder."xray-server/clients/${n}";
flow = "xtls-rprx-vision";
email = "${n}@xray.chn.moe";
})
userList;
decryption = "none";
fallbacks = [{ dest = "127.0.0.1:${fallbackPort}"; }];
};
streamSettings =
{
network = "raw";
security = "reality";
realitySettings =
{
dest = "127.0.0.1:${fallbackPort}";
serverNames = [ server.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-legacy";
settings = { clients = [{ id = "be01f0a0-9976-42f5-b9ab-866eba6ed393"; }]; decryption = "none"; };
streamSettings.network = "raw";
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; };
tag = "in-localdns";
}
)
{
port = 4638;
listen = "127.0.0.1";
protocol = "vless";
settings = { clients = [{ id = "be01f0a0-9976-42f5-b9ab-866eba6ed393"; }]; decryption = "none"; };
streamSettings.network = "raw";
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; };
tag = "in-localdns";
}
{
listen = "127.0.0.1";
port = 6149;
protocol = "dokodemo-door";
settings.address = "127.0.0.1";
tag = "api";
}
];
outbounds =
[
{ protocol = "freedom"; tag = "freedom"; }
{
protocol = "vless";
settings.vnext =
[{
address = "127.0.0.1";
port = 4638;
users = [{ id = "be01f0a0-9976-42f5-b9ab-866eba6ed393"; encryption = "none"; }];
}];
streamSettings.network = "raw";
tag = "loopback-localdns";
}
];
routing =
{
domainStrategy = "AsIs";
rules = builtins.map (rule: rule // { type = "field"; })
[
{
inboundTag = [ "in-legacy" ];
domain = [ "domain:openai.com" ];
outboundTag = "loopback-localdns";
listen = "127.0.0.1";
port = 6149;
protocol = "dokodemo-door";
settings.address = "127.0.0.1";
tag = "api";
}
{ inboundTag = [ "in-legacy" ]; outboundTag = "freedom"; }
{ inboundTag = [ "in-localdns" ]; outboundTag = "freedom"; }
{ inboundTag = [ "api" ]; outboundTag = "api"; }
];
};
stats = {};
api = { tag = "api"; services = [ "StatsService" ]; };
policy =
{
levels."0" = { statsUserUplink = true; statsUserDownlink = true; };
system =
outbounds =
[
{ protocol = "freedom"; tag = "freedom"; }
{
protocol = "vless";
settings.vnext =
[{
address = "127.0.0.1";
port = 4638;
users = [{ id = "be01f0a0-9976-42f5-b9ab-866eba6ed393"; encryption = "none"; }];
}];
streamSettings.network = "raw";
tag = "loopback-localdns";
}
];
routing =
{
statsInboundUplink = true;
statsInboundDownlink = true;
statsOutboundUplink = true;
statsOutboundDownlink = true;
domainStrategy = "AsIs";
rules = builtins.map (rule: rule // { type = "field"; })
[
{
inboundTag = [ "in-legacy" ];
domain = [ "domain:openai.com" ];
outboundTag = "loopback-localdns";
}
{ inboundTag = [ "in-legacy" ]; outboundTag = "freedom"; }
{ inboundTag = [ "in-localdns" ]; outboundTag = "freedom"; }
{ inboundTag = [ "api" ]; outboundTag = "api"; }
];
};
stats = {};
api = { tag = "api"; services = [ "StatsService" ]; };
policy =
{
levels."0" = { statsUserUplink = true; statsUserDownlink = true; };
system =
{
statsInboundUplink = true;
statsInboundDownlink = true;
statsOutboundUplink = true;
statsOutboundDownlink = true;
};
};
};
};
secrets = builtins.listToAttrs
(builtins.map (n: inputs.lib.nameValuePair "xray-server/clients/${n}" {}) userList)
// (builtins.listToAttrs (builtins.map
(name: inputs.lib.nameValuePair "telegram/${name}" { group = "telegram"; mode = "0440"; })
[ "token" "user/chn" ]))
// { "xray-server/private-key" = {}; };
};
secrets = builtins.listToAttrs
(builtins.map (n: { name = "xray-server/clients/${n}"; value = {}; }) userList)
// (builtins.listToAttrs (builtins.map
(name:
services =
{
acme.cert.${server.serverName}.group = inputs.config.users.users.nginx.group;
nginx =
{
transparentProxy.map.${server.serverName} = 4726;
https.${server.serverName} =
{
name = "telegram/${name}";
value =
{
group = "telegram";
mode = "0440";
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
};
})
[ "token" "user/chn" ]))
// { "xray-server/private-key" = {}; };
listen.main = { proxyProtocol = false; addToTransparentProxy = false; };
location."/".return.return = "400";
};
};
};
};
systemd =
{
@@ -149,8 +157,8 @@ inputs:
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script =
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-server.json".path}";
script = let config = inputs.config.nixos.system.sops.templates."xray-server.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig =
{
User = "v2ray";
@@ -160,7 +168,7 @@ inputs:
LimitNPROC = 65536;
LimitNOFILE = 524288;
};
restartTriggers = [ inputs.config.sops.templates."xray-server.json".file ];
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-server.json".file ];
};
xray-stat =
{
@@ -172,8 +180,8 @@ inputs:
jq = "${inputs.pkgs.jq}/bin/jq";
sed = "${inputs.pkgs.gnused}/bin/sed";
cat = "${inputs.pkgs.coreutils}/bin/cat";
token = inputs.config.sops.secrets."telegram/token".path;
chat = inputs.config.sops.secrets."telegram/user/chn".path;
token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
in
''
message='${inputs.config.nixos.model.hostname} xray:\n'
@@ -216,19 +224,6 @@ inputs:
telegram.gid = inputs.config.nixos.user.gid.telegram;
};
};
nixos.services =
{
acme.cert.${server.serverName}.group = inputs.config.users.users.nginx.group;
nginx =
{
transparentProxy.map.${server.serverName} = 4726;
https.${server.serverName} =
{
listen.main = { proxyProtocol = false; addToTransparentProxy = false; };
location."/".return.return = "400";
};
};
};
}
);
}

View File

@@ -10,7 +10,7 @@ inputs:
};
config = let inherit (inputs.config.nixos.services.xray) xmuClient; in inputs.lib.mkIf (xmuClient != null)
{
sops =
nixos.system.sops =
{
templates."xray-xmu-client.json" =
{
@@ -37,7 +37,8 @@ inputs:
[{
address = "webvpn.xmu.edu.cn";
port = 443;
users = [{ id = inputs.config.sops.placeholder."xray-xmu-client/uuid"; encryption = "none"; }];
users =
[{ id = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/uuid"; encryption = "none"; }];
}];
streamSettings =
{
@@ -45,24 +46,12 @@ inputs:
security = "tls";
xhttpSettings =
{
path =
let
inherit (xmuClient) hostname;
paddedLength = ((builtins.div ((builtins.stringLength hostname) - 1) 16) + 1) * 16;
paddedString = builtins.concatStringsSep ""
(builtins.genList
(n: if n < builtins.stringLength hostname then builtins.substring n 1 hostname else "0")
paddedLength);
paddedHex = inputs.pkgs.localPackages.aes128CfbHex
{ data = hostname; key = "wrdvpnisthebest!"; iv = "wrdvpnisthebest!"; };
prefix = builtins.concatStringsSep "" (builtins.map
(c: inputs.lib.toHexString (inputs.lib.strings.charToInt c))
(inputs.lib.stringToCharacters "wrdvpnisthebest!"));
in "/https/${prefix}${paddedHex}/xsession";
path = "${inputs.pkgs.localPackages.webvpnPath xmuClient.hostname}/xsession";
mode = "packet-up";
security = "tls";
extra.headers.Cookie = "show_vpn=0; heartbeat=1; show_faq=0; "
+ "wengine_vpn_ticketwebvpn_xmu_edu_cn=${inputs.config.sops.placeholder."xray-xmu-client/cookie"}";
extra.headers.Cookie =
let ticket = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/cookie";
in "show_vpn=0; heartbeat=1; show_faq=0; wengine_vpn_ticketwebvpn_xmu_edu_cn=${ticket}";
};
tlsSettings.alpn = [ "http/1.1" ];
};
@@ -77,8 +66,8 @@ inputs:
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script =
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-xmu-client.json".path}";
script = let config = inputs.config.nixos.system.sops.templates."xray-xmu-client.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig =
{
User = "v2ray";
@@ -90,7 +79,7 @@ inputs:
LimitNOFILE = 524288;
CPUSchedulingPolicy = "rr";
};
restartTriggers = [ inputs.config.sops.templates."xray-xmu-client.json".file ];
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-xmu-client.json".file ];
};
};
users =

View File

@@ -0,0 +1,57 @@
inputs:
{
options.nixos.services.xray.xmuPersist = let inherit (inputs.lib) mkOption types; in mkOption
{
type = types.nullOr (types.submodule (submoduleInputs: { options =
{
keepAliveHost = mkOption { type = types.nonEmptyStr; default = "blog.chn.moe"; };
};}));
default = null;
};
config = let inherit (inputs.config.nixos.services.xray) xmuPersist; in inputs.lib.mkIf (xmuPersist != null)
{
nixos.system.sops =
{
templates."xray-xmu-persist-cookie.txt" =
{
owner = inputs.config.users.users.v2ray.name;
group = inputs.config.users.users.v2ray.group;
content = let cookie = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/cookie"; in
''
.webvpn.xmu.edu.cn TRUE / TRUE 0 wengine_vpn_ticketwebvpn_xmu_edu_cn ${cookie}
webvpn.xmu.edu.cn FALSE / TRUE 0 show_vpn 0
webvpn.xmu.edu.cn FALSE / TRUE 0 heartbeat 1
webvpn.xmu.edu.cn FALSE / TRUE 0 show_faq 0
webvpn.xmu.edu.cn FALSE / FALSE 0 refresh 0
'';
};
secrets."xray-xmu-client/cookie" = {};
};
systemd =
{
services.xray-xmu-persist =
{
script =
let
curl = "${inputs.pkgs.curl}/bin/curl";
cookie = inputs.config.nixos.system.sops.templates."xray-xmu-persist-cookie.txt".path;
in
''
${curl} -s -o /dev/null -w "%{http_code}\n" -b ${cookie} \
"https://webvpn.xmu.edu.cn${inputs.pkgs.localPackages.webvpnPath xmuPersist.keepAliveHost}/";
'';
serviceConfig = { Type = "oneshot"; User = "v2ray"; Group = "v2ray"; };
};
timers.xray-xmu-persist =
{
wantedBy = [ "timers.target" ];
timerConfig = { OnCalendar = "*-*-* *:*:00"; Unit = "xray-xmu-persist.service"; };
};
};
users =
{
users.v2ray = { uid = inputs.config.nixos.user.uid.v2ray; group = "v2ray"; isSystemUser = true; };
groups.v2ray.gid = inputs.config.nixos.user.gid.v2ray;
};
};
}

View File

@@ -10,12 +10,11 @@ inputs:
};
config = let inherit (inputs.config.nixos.services.xray) xmuServer; in inputs.lib.mkIf (xmuServer != null)
{
sops =
nixos.system.sops =
{
templates."xray-xmu-server.json" =
{
owner = inputs.config.users.users.v2ray.name;
group = inputs.config.users.users.v2ray.group;
content = builtins.toJSON
{
log.loglevel = "warning";
@@ -24,8 +23,12 @@ inputs:
port = 4727;
listen = "127.0.0.1";
protocol = "vless";
settings = { clients = [{ id = inputs.config.sops.placeholder."xray-xmu-server"; }]; decryption = "none"; };
streamSettings = { network = "xhttp"; xhttpSettings = { mode = "stream-one"; path = "/xsession"; }; };
settings =
{
clients = [{ id = inputs.config.nixos.system.sops.placeholder."xray-xmu-server"; }];
decryption = "none";
};
streamSettings = { network = "xhttp"; xhttpSettings = { mode = "packet-up"; path = "/xsession"; }; };
tag = "in";
}];
outbounds = [{ protocol = "freedom"; tag = "freedom"; }];
@@ -37,8 +40,8 @@ inputs:
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script =
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-xmu-server.json".path}";
script = let config = inputs.config.nixos.system.sops.templates."xray-xmu-server.json".path; in
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
serviceConfig =
{
User = "v2ray";
@@ -49,7 +52,7 @@ inputs:
LimitNPROC = 65536;
LimitNOFILE = 524288;
};
restartTriggers = [ inputs.config.sops.templates."xray-xmu-server.json".file ];
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-xmu-server.json".file ];
};
users =
{

View File

@@ -85,6 +85,7 @@ inputs:
kernelParams = [ "resume_offset=${builtins.toString fileSystems.resume.offset}" ];
};
nixos.system.kernel.patches = [ "hibernate-progress" ];
systemd.sleep.extraConfig = "HibernateMode=reboot";
})
];
}

View File

@@ -1,80 +1,87 @@
inputs:
{
options.nixos.system.grub = let inherit (inputs.lib) mkOption types; in
options.nixos.system.grub = let inherit (inputs.lib) mkOption types; in mkOption
{
timeout = mkOption { type = types.int; default = 15; };
windowsEntries = mkOption { type = types.attrsOf types.nonEmptyStr; default = {}; };
# "efi" using efi, "efiRemovable" using efi with install grub removable, or dev path like "/dev/sda" using bios
installDevice = mkOption { type = types.str; default = "efi"; };
type = types.nullOr (types.submodule { options =
{
timeout = mkOption { type = types.int; default = 15; };
windowsEntries = mkOption { type = types.attrsOf types.nonEmptyStr; default = {}; };
# "efi" using efi, "efiRemovable" using efi with install grub removable, or dev path like "/dev/sda" using bios
installDevice = mkOption { type = types.str; default = "efi"; };
};});
# use grub as default, if disabled, use uboot
default = {};
};
config = let inherit (inputs.config.nixos.system) grub; in inputs.lib.mkMerge
[
# general settings
{ boot.loader.grub = { enable = true; useOSProber = false; }; }
# grub timeout
{ boot.loader.timeout = grub.timeout; }
# grub install
{
boot.loader =
config = let inherit (inputs.config.nixos.system) grub; in inputs.localLib.mkConditional (grub != null)
(inputs.lib.mkMerge
[
# general settings
{ boot.loader.grub = { enable = true; useOSProber = false; }; }
# grub timeout
{ boot.loader.timeout = grub.timeout; }
# grub install
{
grub =
boot.loader =
{
device = if builtins.elem grub.installDevice [ "efi" "efiRemovable" ] then "nodev" else grub.installDevice;
efiSupport = builtins.elem grub.installDevice [ "efi" "efiRemovable" ];
efiInstallAsRemovable = grub.installDevice == "efiRemovable";
grub =
{
device = if builtins.elem grub.installDevice [ "efi" "efiRemovable" ] then "nodev" else grub.installDevice;
efiSupport = builtins.elem grub.installDevice [ "efi" "efiRemovable" ];
efiInstallAsRemovable = grub.installDevice == "efiRemovable";
};
efi.canTouchEfiVariables = grub.installDevice == "efi";
};
efi.canTouchEfiVariables = grub.installDevice == "efi";
};
}
# extra grub entries
{
boot.loader.grub =
}
# extra grub entries
{
memtest86.enable = true;
extraFiles = inputs.lib.mkIf (builtins.elem grub.installDevice [ "efi" "efiRemovable" ])
{ "shell.efi" = "${inputs.pkgs.genericPackages.edk2-uefi-shell}/shell.efi"; };
extraEntries = inputs.lib.mkMerge (builtins.concatLists
[
(builtins.map
(system:
''
menuentry "${system.value}" {
insmod part_gpt
insmod fat
insmod search_fs_uuid
insmod chain
search --fs-uuid --set=root ${system.name}
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
'')
(inputs.localLib.attrsToList grub.windowsEntries))
boot.loader.grub =
{
memtest86.enable = true;
extraFiles = inputs.lib.mkIf (builtins.elem grub.installDevice [ "efi" "efiRemovable" ])
{ "shell.efi" = "${inputs.pkgs.genericPackages.edk2-uefi-shell}/shell.efi"; };
extraEntries = inputs.lib.mkMerge (builtins.concatLists
[
''
menuentry "System shutdown" {
echo "System shutting down..."
halt
}
menuentry "System restart" {
echo "System rebooting..."
reboot
}
''
(
inputs.lib.optionalString (builtins.elem grub.installDevice [ "efi" "efiRemovable" ])
(builtins.map
(system:
''
menuentry 'UEFI Firmware Settings' --id 'uefi-firmware' {
fwsetup
}
menuentry "UEFI Shell" {
menuentry "${system.value}" {
insmod part_gpt
insmod fat
insmod search_fs_uuid
insmod chain
chainloader @bootRoot@/shell.efi
search --fs-uuid --set=root ${system.name}
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
'')
(inputs.localLib.attrsToList grub.windowsEntries))
[
''
menuentry "System shutdown" {
echo "System shutting down..."
halt
}
menuentry "System restart" {
echo "System rebooting..."
reboot
}
''
)
]
]);
};
}
];
(
inputs.lib.optionalString (builtins.elem grub.installDevice [ "efi" "efiRemovable" ])
''
menuentry 'UEFI Firmware Settings' --id 'uefi-firmware' {
fwsetup
}
menuentry "UEFI Shell" {
insmod fat
insmod chain
chainloader @bootRoot@/shell.efi
}
''
)
]
]);
};
}
])
({});
}

View File

@@ -2,7 +2,7 @@ inputs:
{
options.nixos.system.gui = let inherit (inputs.lib) mkOption types; in
{
implementation = mkOption { type = types.enum [ "kde" ]; default = "kde"; };
implementation = mkOption { type = types.enum [ "kde" "niri" ]; default = "kde"; };
};
config = let inherit (inputs.config.nixos.system) gui; in inputs.lib.mkMerge
[
@@ -46,6 +46,7 @@ inputs:
config.gtk =
{
enable = true;
theme.name = "Breeze";
gtk2 =
{
extraConfig = ''gtk-im-module="fcitx"'';
@@ -62,5 +63,10 @@ inputs:
environment.plasma6.excludePackages = inputs.lib.mkIf (gui.implementation == "kde")
[ inputs.pkgs.kdePackages.plasma-nm ];
})
# niri
(inputs.lib.mkIf (gui.implementation == "niri")
{
programs.niri.enable = true;
})
];
}

View File

@@ -4,7 +4,7 @@ inputs:
{
variant = mkOption
{
type = types.nullOr (types.enum [ "nixos" "xanmod-lts" "xanmod-latest" ]);
type = types.nullOr (types.enum [ "nixos" "xanmod-lts" "xanmod-latest" "xanmod-unstable" ]);
default = "xanmod-lts";
};
patches = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
@@ -31,8 +31,6 @@ inputs:
"bnx2x" "tg3"
# network for srv2
"e1000e" "igb" "atlantic" "igc"
# temp wireless for nas
"r8712u"
# network for srv3
"igb"
# touchscreen for one

View File

@@ -25,8 +25,12 @@ inputs:
};});
default = {};
};
# wpa_passphrase SSID(wifi name) PSK(password)
wireless = mkOption { type = types.nullOr (types.listOf types.nonEmptyStr); default = null; };
wireless =
{
# wpa_passphrase SSID(wifi name) PSK(password)
networks = mkOption { type = types.nullOr (types.listOf types.nonEmptyStr); default = null; };
fourAddr = mkOption { type = types.bool; default = false; };
};
trust = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
masquerade = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
};});
@@ -140,27 +144,31 @@ inputs:
networking =
{
useNetworkd = true;
wireless = inputs.lib.mkIf (network.wireless != null)
wireless = inputs.lib.mkIf (network.wireless.networks != null)
{
enable = true;
# wpa_passphrase SSID password
networks = builtins.listToAttrs (builtins.map
(network: { name = network; value.pskRaw = "ext:${network}"; }) network.wireless);
secretsFile = inputs.config.sops.templates."wireless.env".path;
(network: { name = network; value.pskRaw = "ext:${network}"; }) network.wireless.networks);
secretsFile = inputs.config.nixos.system.sops.templates."wireless.env".path;
};
firewall.trustedInterfaces = network.trust;
};
# dnsable dns fallback, use provided dns servers or no dns
services.resolved.fallbackDns = [];
sops = inputs.lib.mkIf (network.wireless != null)
nixos.system.sops = inputs.lib.mkIf (network.wireless.networks != null)
{
templates."wireless.env".content = builtins.concatStringsSep "\n" (builtins.map
(network: "${network}=${inputs.config.sops.placeholder."wireless/${network}"}")
network.wireless);
(network: "${network}=${inputs.config.nixos.system.sops.placeholder."wireless/${network}"}")
network.wireless.networks);
secrets = builtins.listToAttrs (builtins.map
(network: { name = "wireless/${network}"; value = {}; })
network.wireless);
(network: inputs.lib.nameValuePair "wireless/${network}" {})
network.wireless.networks);
};
services.udev.extraRules = inputs.lib.mkIf (network.wireless.fourAddr)
''
ACTION=="add", SUBSYSTEM=="net", ENV{INTERFACE}=="wlp*", RUN+="${inputs.pkgs.iw}/bin/iw dev %k set 4addr on"
'';
})
];
}

View File

@@ -1,7 +1,10 @@
inputs:
{
options.nixos.system.nix-ld = let inherit (inputs.lib) mkOption types; in mkOption
{ type = types.nullOr (types.submodule {}); default = {}; };
{
type = types.nullOr (types.submodule {});
default = if inputs.config.nixos.model.arch == "x86_64" then {} else null;
};
config = let inherit (inputs.config.nixos.system) nix-ld; in inputs.lib.mkIf (nix-ld != null)
{
programs.nix-ld =

View File

@@ -105,26 +105,26 @@ inputs:
protocol = "ssh-ng";
systems = [ "x86_64-linux" ];
sshUser = "nix-ssh";
sshKey = inputs.config.sops.secrets."nix/remote".path;
sshKey = inputs.config.nixos.system.sops.secrets."nix/remote".path;
maxJobs = 1;
mandatoryFeatures = [ "big-parallel" ];
supportedFeatures = builtins.map (f: "gccarch-${f}") v;
})
nix.remote.master.host;
};
sops.secrets."nix/remote" = {};
nixos.system.sops.secrets."nix/remote" = {};
})
(inputs.lib.mkIf nix.githubToken.enable
{
nix.extraOptions = "!include ${inputs.config.sops.templates."nix-github.conf".path}";
sops =
nix.extraOptions = "!include ${inputs.config.nixos.system.sops.templates."nix-github.conf".path}";
nixos.system.sops =
{
templates."nix-github.conf" =
{
content = "access-tokens = github.com=${inputs.config.sops.placeholder."github/token"}";
content = "access-tokens = github.com=${inputs.config.nixos.system.sops.placeholder."github/token"}";
mode = "0444";
};
secrets."github/token".sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml";
secrets."github/token" = {};
};
})
# c++ include path

View File

@@ -15,7 +15,11 @@ inputs:
};
config = let inherit (inputs.config.nixos.system) nixpkgs; in
{
nixpkgs = inputs.localLib.buildNixpkgsConfig { inherit inputs; nixpkgs = nixpkgs // { nixRoot = null; }; };
nixpkgs = inputs.localLib.buildNixpkgsConfig
{
inherit inputs;
nixpkgs = nixpkgs // { nixRoot = null; nixos = true; inherit (inputs.config.nixos.model) arch; };
};
boot.kernelPatches = inputs.lib.mkIf (nixpkgs.march != null)
[{
name = "native kernel";

View File

@@ -2,38 +2,118 @@ inputs:
{
options.nixos.system.sops = let inherit (inputs.lib) mkOption types; in
{
crossSopsDir = mkOption
secrets = mkOption
{
type = types.nonEmptyStr;
default = "${inputs.topInputs.self}/devices/cross/secrets";
readOnly = true;
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
path = mkOption
{
type = types.path;
default = inputs.config.sops.secrets.${submoduleInputs.config._module.args.name}.path;
readOnly = true;
};
key = mkOption { type = types.str; default = submoduleInputs.config._module.args.name; };
format = mkOption { type = types.enum [ "yaml" "binary" ]; default = "yaml"; };
mode = mkOption { type = types.str; default = "0400"; };
owner = mkOption { type = types.nullOr types.str; default = null; };
group = mkOption { type = types.nullOr types.str; default = null; };
sopsFile = mkOption
{
type = types.path;
default =
let secretFileIndex =
inputs.lib.lists.findFirstIndex (x: x) null
(builtins.map
(file: inputs.lib.hasAttrByPath (inputs.lib.splitString "/" submoduleInputs.config.key)
(inputs.pkgs.localPackages.fromYaml (builtins.readFile file)))
inputs.config.nixos.system.sops.defaultSopsFile);
in
if secretFileIndex == null then builtins.abort "No sops file found for ${submoduleInputs.config.key}"
else builtins.elemAt inputs.config.nixos.system.sops.defaultSopsFile secretFileIndex;
};
neededForUsers = mkOption { type = types.bool; default = false; };
};}));
default = {};
};
clusterSopsDir = mkOption
templates = mkOption
{
type = types.nullOr types.nonEmptyStr;
default = if (inputs.config.nixos.model.cluster == null) then null
else "${inputs.topInputs.self}/devices/${inputs.config.nixos.model.cluster.clusterName}/secrets";
type = types.attrsOf (types.submodule (submoduleInputs: { options =
{
content = mkOption { type = types.str; };
path = mkOption
{
type = types.path;
default = inputs.config.sops.templates.${submoduleInputs.config._module.args.name}.path;
readOnly = true;
};
owner = mkOption { type = types.nullOr types.str; default = null; };
group = mkOption { type = types.nullOr types.str; default = null; };
mode = mkOption { type = types.str; default = "0400"; };
file = mkOption
{
type = types.path;
default = inputs.config.sops.templates.${submoduleInputs.config._module.args.name}.file;
readOnly = true;
};
};}));
default = {};
};
# define default in config
placeholder = mkOption { type = types.attrsOf types.str; };
defaultSopsFile = mkOption
{
type = types.nonEmptyListOf types.path;
readOnly = true;
default =
let
defaultSopsFile = path:
if builtins.pathExists "${path}/secrets.yaml" then [ "${path}/secrets.yaml" ]
else if builtins.pathExists "${path}/secrets/default.yaml" then [ "${path}/secrets/default.yaml" ]
else [];
devicePath = "${inputs.topInputs.self}/devices";
inherit (inputs.config.nixos) model;
in
[]
++ (inputs.lib.optionals (model.cluster == null) (defaultSopsFile "${devicePath}/${model.hostname}"))
++ (inputs.lib.optionals (model.cluster != null)
(
(defaultSopsFile "${devicePath}/${model.cluster.clusterName}/${model.cluster.nodeName}")
++ (defaultSopsFile "${devicePath}/${model.cluster.clusterName}")
))
++ (inputs.lib.optionals model.private [ "${devicePath}/cross/secrets/chn.yaml" ])
++ (defaultSopsFile "${devicePath}/cross");
};
availableKeys = mkOption
{
type = types.listOf (types.listOf types.str);
readOnly = true;
default =
let getPath = x:
if builtins.typeOf x == "string" then [[]]
else if builtins.typeOf x == "set"
then builtins.concatLists (inputs.lib.mapAttrsToList (n: v: builtins.map (l: [ n ] ++ l) (getPath v)) x)
# simply ignore list, they are sops metadata
else if builtins.typeOf x == "list" then [[]]
else builtins.abort "Invalid type for availableKeys, get type ${builtins.typeOf x}";
in builtins.concatLists (builtins.map
(f: getPath (inputs.pkgs.localPackages.fromYaml (builtins.readFile f)))
inputs.config.nixos.system.sops.defaultSopsFile);
};
};
config =
{
nixos.system.sops.placeholder = builtins.mapAttrs
(n: _: inputs.lib.mkOptionDefault "sops${builtins.hashString "sha256" n}sops")
inputs.config.nixos.system.sops.secrets;
sops =
{
defaultSopsFile =
let deviceDir =
if (inputs.config.nixos.model.cluster == null) then
"${inputs.topInputs.self}/devices/${inputs.config.nixos.model.hostname}"
else
"${inputs.topInputs.self}/devices/${inputs.config.nixos.model.cluster.clusterName}"
+ "/${inputs.config.nixos.model.cluster.nodeName}";
in inputs.lib.mkMerge
[
(inputs.lib.mkIf (builtins.pathExists "${deviceDir}/secrets.yaml") "${deviceDir}/secrets.yaml")
(inputs.lib.mkIf (builtins.pathExists "${deviceDir}/secrets/default.yaml")
"${deviceDir}/secrets/default.yaml")
];
# sops start before impermanence, so we need to use the absolute path
secrets = builtins.mapAttrs
(n: v: { inherit (v) key format mode owner group sopsFile neededForUsers; })
inputs.config.nixos.system.sops.secrets;
templates = builtins.mapAttrs
(n: v: { inherit (v) content owner group mode; })
inputs.config.nixos.system.sops.templates;
inherit (inputs.config.nixos.system.sops) placeholder;
age.sshKeyPaths = [ "/nix/persistent/etc/ssh/ssh_host_ed25519_key" ];
};
};

View File

@@ -5,12 +5,8 @@ inputs:
home-manager.users.chn = homeInputs:
{
config.xdg.configFile."sops/age/keys.txt".source =
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.sops.secrets."chn/age".path;
};
sops.secrets."chn/age" =
{
owner = "chn";
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml";
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.nixos.system.sops.secrets."chn/age".path;
};
nixos.system.sops.secrets."chn/age".owner = "chn";
};
}

View File

@@ -40,30 +40,23 @@ inputs:
{
name = ".ssh/id_${type}";
value.source = homeInputs.config.lib.file.mkOutOfStoreSymlink
inputs.config.sops.secrets."chn/${type}".path;
inputs.config.nixos.system.sops.secrets."chn/${type}".path;
})
[ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" ]
))
// {
".ssh/xmuhk_id_rsa".source =
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.sops.secrets."chn/xmuhk".path;
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.nixos.system.sops.secrets."chn/xmuhk".path;
}
);
};
};
sops.secrets = inputs.lib.mkIf inputs.config.nixos.model.private (inputs.lib.mkMerge
nixos.system.sops.secrets = inputs.lib.mkIf inputs.config.nixos.model.private (inputs.lib.mkMerge
[
(builtins.listToAttrs (builtins.map
(name:
{
name = "chn/${name}";
value = { owner = "chn"; sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; };
})
(name: inputs.lib.nameValuePair "chn/${name}" { owner = "chn"; })
[ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" "xmuhk" ]))
{
"root/ed25519_sk" =
{ key = "chn/ed25519_sk"; sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; };
}
{ "root/ed25519_sk".key = "chn/ed25519_sk"; }
]);
};
}

View File

@@ -35,6 +35,7 @@ inputs:
zqq = 1021;
zgq = 1022;
qmx = 1023;
yumieko = 1024;
misskey-misskey = 2000;
misskey-misskey-old = 2001;
frp = 2002;
@@ -47,6 +48,7 @@ inputs:
synapse-synapse = 2009;
synapse-matrix = 2010;
hpcstat = 2011;
speedtest = 2012;
};
};
gid = mkOption
@@ -101,17 +103,15 @@ inputs:
}
# set hashedPassword if it exist in secrets
(
let
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
secrets = inputs.pkgs.localPackages.fromYaml (builtins.readFile sopsFile);
hashedPasswordExist = userName: (secrets ? users) && ((secrets.users or {}) ? ${userName});
let hashedPasswordExist = userName: inputs.lib.lists.any
(inputs.lib.lists.hasPrefix [ "users" userName ]) inputs.config.nixos.system.sops.availableKeys;
in
{
users.users = builtins.listToAttrs (builtins.map
(name: { inherit name; value.hashedPasswordFile = inputs.config.sops.secrets."users/${name}".path; })
(builtins.filter (user: hashedPasswordExist user) user.users));
sops.secrets = builtins.listToAttrs (builtins.map
(name: { name = "users/${name}"; value = { neededForUsers = true; inherit sopsFile; }; })
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
(name: inputs.lib.nameValuePair "users/${name}" { neededForUsers = true; })
(builtins.filter (user: hashedPasswordExist user) user.users));
}
)
@@ -143,7 +143,7 @@ inputs:
home.file = inputs.lib.mkIf inputs.config.nixos.model.private
{
".ssh/id_ed25519_sk".source = homeInputs.config.lib.file.mkOutOfStoreSymlink
inputs.config.sops.secrets."root/ed25519_sk".path;
inputs.config.nixos.system.sops.secrets."root/ed25519_sk".path;
};
};
};

View File

@@ -4,9 +4,10 @@ inputs:
{
home-manager.users.hjp.config.programs.zsh.initContent =
''
export PATH=$PATH:/home/hjp/software/intel/oneapi/compiler/latest/bin
export PATH=$PATH:/home/hjp/software/intel/oneapi/compiler/latest/bin:/home/hjp/software/atomkit.0.9.0/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/hjp/software/intel/oneapi/compiler/latest/lib
'';
users.users.hjp.extraGroups = [ "wheel" ];
users.users.hjp.extraGroups = inputs.lib.mkIf (inputs.config.nixos.model.cluster.clusterName or null == "srv2")
[ "wheel" ];
};
}

View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDeTErlX48PWEPz+fO2tvXiYOoOHHxUk5ACoA1zb5zhVBcbXDPTBo31W+nKRqSztOPhR2ABe8zw37eN3cvBtR3XvkZdtKyCd9OGhYI0WTV+97ZxO3Wi5t7hI72gzdPHnPJyK4aZUGEV2b+pSHJ1ONjYX6w6beh8TyZm1ch3Cc95lnOrvGIgWt3d34WVbP/+ubuDXM4Hx2HKBgTvKxmpXIyhXGTC7IF7nT8EX8NcW58w4nTBGBStf4MU1P1lgOJTJlcKJyw2IGxYMJTD9qgYvCQffqmK1mf2eCh+AGA7oqIrzQ1tfF3mp4V91aD3QngXow79lHBPuefGxqGjjMmaKcm6/OuIlPC7HtA2jn+TM32SlRN1mgSkpjiwpneinuFPYSqpcQpRHQDaPWhOC0xMzBXhM+9GXpQc6ntGWYW8inyhY6sDRborQPIFG/dZg8M720mkhP4xOs/7l8hmxk+6uD4dK6yimCvlcMvX7Rk/aJ+Bb8IfCAQSd+xff87w0Z5MpGAKpx0T33vKleSbanTEZh73KZzQvrgoZCuBHUOv/yN/r6s2evIA8lvmDqdbpNsxo7/+avRLyK6cjoj5IipcPNtTwaaNkTGC/YE+TOQI+iBAsMvmr8542m06lQXqkfAElE8TvAmR6BLIFO33Byy31x3L4AVWbWo/uWw9xs8ziir9Jw== minkieyume@gmail.com

18
packages/atat.nix Normal file
View File

@@ -0,0 +1,18 @@
{ stdenv, src, perl, coreutils }: stdenv.mkDerivation
{
name = "atat";
inherit src;
nativeBuildInputs = [ perl ];
configurePhase =
''
patchShebangs src
echo "#!/bin/sh" > safecp
echo "cp \"\$@\"" >> safecp
'';
buildPhase = "make -C src -j$NIX_BUILD_CORES";
installPhase =
''
mkdir -p $out/bin
make -C src BINDIR=$out/bin install
'';
}

16
packages/atomkit.nix Normal file
View File

@@ -0,0 +1,16 @@
{ stdenv, src, autoPatchelfHook, xorg }: stdenv.mkDerivation
{
name = "atomkit";
inherit src;
dontConfigure = true;
dontBuild = true;
buildInputs = [ stdenv.cc.cc xorg.libX11 ];
nativeBuildInputs = [ autoPatchelfHook ];
installPhase =
''
runHook preInstall
mkdir -p $out
cp -r * $out
runHook postInstall
'';
}

View File

@@ -13,7 +13,8 @@ endif()
find_package(magic_enum REQUIRED)
find_package(fmt REQUIRED)
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem system)
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem system process stacktrace_from_exception
stacktrace_backtrace)
find_package(range-v3 REQUIRED)
find_path(NAMEOF_INCLUDE_DIR nameof.hpp REQUIRED)
find_package(Eigen3 REQUIRED)
@@ -35,7 +36,7 @@ target_include_directories(biu PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_D
${LIBBACKTRACE_INCLUDE_DIR} ${POCKETFFT_INCLUDE_DIR})
target_link_libraries(biu PUBLIC magic_enum::magic_enum fmt::fmt Boost::headers Boost::iostreams Boost::filesystem
range-v3::range-v3 Eigen3::Eigen HighFive TgBot::TgBot ${LIBBACKTRACE_LIBRARY} hdf5::hdf5 concurrencpp::concurrencpp
yaml-cpp::yaml-cpp glaze::glaze)
yaml-cpp::yaml-cpp glaze::glaze Boost::process Boost::stacktrace_from_exception Boost::stacktrace_backtrace)
target_compile_features(biu PUBLIC cxx_std_23)
target_compile_options(biu PUBLIC -Wno-gnu-string-literal-operator-template)
install(TARGETS biu EXPORT biuTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -56,6 +57,7 @@ set_property(TARGET test-serialize PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRE
add_test(NAME test-serialize COMMAND test-serialize)
add_executable(test-process test/process.cpp)
target_link_libraries(test-process PRIVATE biu)
target_compile_definitions(test-process PRIVATE BIU_LOGGER_SOURCE_ROOT="${CMAKE_CURRENT_SOURCE_DIR}")
set_property(TARGET test-process PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
add_test(NAME test-process COMMAND test-process)
add_executable(test-eigen test/eigen.cpp)
@@ -84,7 +86,7 @@ set_property(TARGET test-yaml PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
add_test(NAME test-yaml COMMAND test-yaml)
add_executable(test-logger test/logger.cpp)
target_link_libraries(test-logger PRIVATE biu)
target_compile_definitions(test-logger PRIVATE BIU_LOGGER_DEBUG BIU_LOGGER_SOURCE_ROOT="${CMAKE_CURRENT_SOURCE_DIR}")
target_compile_definitions(test-logger PRIVATE BIU_LOGGER_SOURCE_ROOT="${CMAKE_CURRENT_SOURCE_DIR}")
set_property(TARGET test-logger PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
add_test(NAME test-logger COMMAND test-logger)
add_executable(test-glaze test/glaze.cpp)

View File

@@ -1,7 +1,8 @@
include("${CMAKE_CURRENT_LIST_DIR}/biuTargets.cmake")
find_package(magic_enum REQUIRED)
find_package(fmt REQUIRED)
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem system)
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem system process stacktrace_from_exception
stacktrace_backtrace)
find_package(range-v3 REQUIRED)
find_path(NAMEOF_INCLUDE_DIR nameof.hpp REQUIRED)
find_package(Eigen3 REQUIRED)

View File

@@ -8,8 +8,8 @@
src = ./.;
buildInputs =
[
magic-enum fmt boost range-v3 nameof zpp-bits eigen highfive tgbot-cpp libbacktrace hdf5
concurrencpp pocketfft yaml-cpp glaze
magic-enum fmt boost range-v3 nameof zpp-bits eigen libbacktrace hdf5
concurrencpp pocketfft yaml-cpp glaze (highfive.override { inherit boost; }) (tgbot-cpp.override { inherit boost; })
];
propagatedBuildInputs = buildInputs;
nativeBuildInputs = [ cmake ];

View File

@@ -17,3 +17,4 @@
# include <biu/serialize.tpp>
# include <biu/glaze.tpp>
# include <range/v3/all.hpp>
# include <biu/process.tpp>

View File

@@ -37,7 +37,7 @@ namespace biu
public: ValueType get(this auto&& self);
public: operator ValueType(this auto&& self);
protected: template <bool Throw = false> auto lock_(this auto&& self, auto&& condition_function, auto timeout);
protected: template <bool Throw> auto lock_(this auto&& self, auto&& condition_function, auto timeout);
// Apply a function to stored value.
// Wait for some time (if provided) until condition funciton returns true (if provided)
@@ -45,6 +45,7 @@ namespace biu
// NoReturn: throw exception if timeout, ignore function result, and return *this, if true;
// return bool or std::optional wrapped result of function, if false.
// Useful when chaining multiple apply() calls.
// timeout 只考虑 condition_function 的超时,不考虑锁本身的超时。
public: template <bool NoReturn = false> decltype(auto) apply
(this auto&& self, auto&& function, auto&& condition_function, auto&& timeout);
public: template <bool NoReturn = false> decltype(auto) apply
@@ -54,8 +55,7 @@ namespace biu
// Wait until condition funciton returns true or *this, with an optional timeout
public: template <bool NoReturn = false> decltype(auto) wait
(this auto&& self, auto&& condition_function, auto timeout);
public: template <bool NoReturn = false> decltype(auto) wait
(this auto&& self, auto&& condition_function);
public: decltype(auto) wait(this auto&& self, auto&& condition_function);
// Attain lock from outside when constructing, and release when destructing.
// Throw: same effect as NoReturn.

View File

@@ -41,8 +41,11 @@ namespace biu
(this auto&& self, auto&& condition_function, auto timeout)
{
if constexpr (Nullptr<decltype(condition_function)>)
{
static_assert(Nullptr<decltype(timeout)>);
return Guard<std::is_const_v<decltype(self)>>
(std::unique_lock{self.Mutex_}, std::experimental::make_observer(&self), {});
}
else if constexpr (Nullptr<decltype(timeout)>)
{
std::unique_lock lock(self.Mutex_);
@@ -70,28 +73,35 @@ namespace biu
using function_return_type = std::invoke_result_t<decltype(function), MoveQualifiers<decltype(self), ValueType>>;
auto&& lock = std::forward<decltype(self)>(self).template lock_<NoReturn>
(std::forward<decltype(condition_function)>(condition_function), timeout);
// 如果得到的是 optional
// 如果 lock 是 optional
if constexpr (SpecializationOf<std::remove_cvref_t<decltype(lock)>, std::optional>)
// 如果超时了,返回 false 或者对应的 nullopt
// 如果超时了,这时 NoReturn 一定是 false返回 false 或者对应的 nullopt
if (!lock)
{
static_assert(!NoReturn);
if constexpr (std::is_void_v<function_return_type>) return false;
else return std::optional<function_return_type>();
}
// 否则,执行函数
else
// 如果函数本身返回 void则返回 true 或者 *this
if constexpr (std::is_void_v<function_return_type>)
{
std::forward<decltype(function)>(function)
(std::forward<MoveQualifiers<decltype(self), ValueType>>(self.Value_));
// 如果函数本身返回 void 并且不可能超时,返回 *this否则返回 true
if constexpr (Nullptr<decltype(condition_function)> || Nullptr<decltype(timeout)>)
return std::forward<decltype(self)>(self);
// 如果要求不返回结果,则返回 *this
if constexpr (NoReturn) return std::forward<decltype(self)>(self);
// 否则,返回 true
else return true;
}
// 否则,返回函数的返回值或者 std::optional 包装的结果
else
{
auto&& result = std::forward<decltype(function)>(function)
(std::forward<MoveQualifiers<decltype(self), ValueType>>(self.Value_));
return std::make_optional(std::forward<decltype(result)>(result));
if constexpr (NoReturn)
return std::forward<decltype(self)>(self);
else return std::make_optional(std::forward<decltype(result)>(result));
}
// 否则,说明不可能超时,返回函数的返回值或者 *this
else
@@ -125,15 +135,15 @@ namespace biu
template <DecayedType ValueType> template <bool NoReturn> decltype(auto) Atomic<ValueType>::wait
(this auto&& self, auto&& condition_function, auto timeout)
{
auto result = std::forward<decltype(self)>(self).template lock_<NoReturn>
auto&& result = std::forward<decltype(self)>(self).template lock_<NoReturn>
(std::forward<decltype(condition_function)>(condition_function), timeout);
if constexpr (SpecializationOf<decltype(result), std::optional>) return result.has_value();
else return std::forward<decltype(result)>(result);
else return std::forward<decltype(self)>(self);
}
template <DecayedType ValueType> template <bool NoReturn> decltype(auto) Atomic<ValueType>::wait
template <DecayedType ValueType> decltype(auto) Atomic<ValueType>::wait
(this auto&& self, auto&& condition_function)
{
return std::forward<decltype(self)>(self).template wait<NoReturn>
return std::forward<decltype(self)>(self).template wait<false>
(std::forward<decltype(condition_function)>(condition_function), nullptr);
}

View File

@@ -74,27 +74,6 @@ namespace biu
template <typename T, typename Fallback = void> using FallbackIfNoTypeDeclared
= typename detail_::FallbackIfNoTypeDeclaredHelper<T, Fallback>::Type;
namespace detail_
{
struct ExecMode { bool DirectStdin = false, DirectStdout = false, DirectStderr = false, SearchPath = false; };
template <ExecMode Mode> struct ExecResult
{
int ExitCode;
std::conditional_t<Mode.DirectStdout, Empty, std::string> Stdout;
std::conditional_t<Mode.DirectStderr, Empty, std::string> Stderr;
operator bool() const;
};
template <ExecMode Mode> struct ExecInput
{
std::conditional_t<Mode.SearchPath, std::string, std::filesystem::path> Program;
std::vector<std::string> Args;
std::conditional_t<Mode.DirectStdin, Empty, std::string> Stdin = {};
std::map<std::string, std::string> ExtraEnv = {};
std::optional<std::chrono::milliseconds> Timeout;
};
}
template <detail_::ExecMode Mode = {}> detail_::ExecResult<Mode> exec(detail_::ExecInput<Mode> input);
template <typename Array> concurrencpp::generator<std::pair<Array, std::size_t>> sequence(Array from, Array to);
template <typename Array> concurrencpp::generator<std::pair<Array, std::size_t>> sequence(Array to);
@@ -120,9 +99,11 @@ namespace biu
constexpr detail_::ToLvalueHelper toLvalue;
template <typename Function, typename T, typename... Ts> void for_each(Function&& function, T&& arg, Ts&&... args);
template <typename T> decltype(auto) perfect_return(T&& obj);
}
using common::hash, common::unused, common::block_forever, common::is_interactive, common::env, common::int128_t,
common::uint128_t, common::Empty, common::CaseInsensitiveStringLessComparator, common::RemoveMemberPointer,
common::MoveQualifiers, common::FallbackIfNoTypeDeclared, common::exec, common::sequence, common::read,
common::toLvalue, common::for_each;
common::MoveQualifiers, common::FallbackIfNoTypeDeclared, common::sequence, common::read,
common::toLvalue, common::for_each, common::perfect_return;
}

View File

@@ -75,4 +75,18 @@ namespace biu::common
);
}
}
template <typename T> decltype(auto) perfect_return(T&& obj)
{
// 不允许返回右值引用
static_assert(!std::is_rvalue_reference_v<T>);
// 左值引用则返回左值引用
if constexpr (std::is_lvalue_reference_v<T>) return (obj);
// 否则,假定可以移动,并返回值
else
{
static_assert(std::is_move_constructible_v<std::remove_reference_t<T>>);
return std::move(obj);
}
}
}

View File

@@ -7,6 +7,7 @@
# include <fmt/format.h>
# include <fmt/ostream.h>
# include <yaml-cpp/yaml.h>
# include <boost/stacktrace.hpp>
namespace biu
{
@@ -77,4 +78,6 @@ namespace fmt
: basic_ostream_formatter<Char> {};
template <typename Char> struct formatter<YAML::Node, Char> : basic_ostream_formatter<Char> {};
template <typename Char> struct formatter<boost::stacktrace::basic_stacktrace<>, Char>
: basic_ostream_formatter<Char> {};
}

View File

@@ -1,5 +1,6 @@
# pragma once
# include <map>
# define BOOST_STACKTRACE_USE_BACKTRACE
# include <boost/stacktrace.hpp>
# include <biu/atomic.hpp>
@@ -94,10 +95,10 @@ namespace biu
public: [[gnu::always_inline]] inline void info(const std::string& message) const;
public: [[gnu::always_inline]] inline void debug(const std::string& message) const;
public: template <typename FinalException> [[gnu::always_inline]] void print_exception
public: [[gnu::always_inline]] inline void print_exception
(
const std::string& type, const std::string& message, const boost::stacktrace::stacktrace& stacktrace,
CalledBy<Exception<FinalException>>
std::optional<std::pair<std::string, std::string>> type_and_message,
const boost::stacktrace::stacktrace& stacktrace
) const;
};
friend class Guard;

View File

@@ -1,5 +1,4 @@
# pragma once
# define BOOST_STACKTRACE_USE_BACKTRACE
# include <fmt/chrono.h>
# include <tgbot/tgbot.h>
# include <biu/logger.hpp>
@@ -67,14 +66,20 @@ namespace biu
template <typename FinalException> Logger::Exception<FinalException>::Exception(const std::string& message)
{
Logger::Guard log(message);
log.print_exception<FinalException>(nameof::nameof_full_type<FinalException>(), message, Stacktrace_, {});
log.print_exception
(std::pair<std::string, std::string>(nameof::nameof_full_type<FinalException>(), message), Stacktrace_);
}
template <typename Function> inline void Logger::try_exec(Function&& function)
{
Logger::Guard log;
try { function(); }
catch (...) { log.error(boost::current_exception_diagnostic_information()); }
catch (...)
{
log.error(boost::current_exception_diagnostic_information());
log.print_exception
(std::nullopt, boost::stacktrace::stacktrace::from_current_exception());
}
}
inline thread_local unsigned Logger::Guard::Indent_ = 0;
@@ -115,14 +120,10 @@ namespace biu
void Logger::Guard::operator()() const { debug("reached after {} ms."_f(get_time_ms())); }
template <Logger::Level L> void Logger::Guard::log(const std::string& message) const
{
# ifndef BIU_LOGGER_DEBUG
if constexpr (L == Level::Debug) return;
# endif
if (auto&& lock = LoggerConfig_.lock(); lock->Level >= L)
{
static_assert(std::same_as<std::size_t, std::uint64_t>);
auto time = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
# ifdef BIU_LOGGER_DEBUG
boost::stacktrace::stacktrace stack;
# ifdef BIU_LOGGER_SOURCE_ROOT
auto source_root = std::string_view(BIU_LOGGER_SOURCE_ROOT "/");
@@ -141,11 +142,6 @@ namespace biu
stack[0].source_line() == 0 ? "??"s : "{}"_f(stack[0].source_line()),
stack[0].name()
) << std::flush;
# else
*lock->Stream << "[ {:%T} {:02x} {:02} ] {}\n"_f
(time, get_thread_id() % std::numeric_limits<std::uint16_t>::max(), Indent_, message)
<< std::flush;
# endif
}
}
void Logger::Guard::error(const std::string& message) const { log<Level::Error>(message); }
@@ -158,13 +154,13 @@ namespace biu
return std::forward<T>(value);
}
template <typename FinalException> inline void Logger::Guard::print_exception
inline void Logger::Guard::print_exception
(
const std::string& type, const std::string& message, const boost::stacktrace::stacktrace& stacktrace,
CalledBy<Exception<FinalException>>
std::optional<std::pair<std::string, std::string>> type_and_message,
const boost::stacktrace::stacktrace& stacktrace
) const
{
log<Level::Error>("{}: {}"_f(type, message));
if (type_and_message) log<Level::Error>("{}: {}"_f(type_and_message->first, type_and_message->second));
if (auto&& lock = LoggerConfig_.lock(); lock->Level >= Logger::Level::Error)
{
static_assert(std::same_as<std::size_t, std::uint64_t>);

View File

@@ -0,0 +1,36 @@
# pragma once
# include <biu/common.hpp>
namespace biu
{
namespace process
{
enum class IoType { Direct, Close, String };
namespace detail_
{
struct ExecMode
{
bool SearchPath = false, ModifyEnv = false, Timeout = false;
IoType Stdin = IoType::Direct, Stdout = IoType::Direct, Stderr = IoType::Direct;
};
template <ExecMode Mode> struct ExecResult
{
int ExitCode;
std::conditional_t<Mode.Stdout == IoType::String, std::string, Empty> Stdout;
std::conditional_t<Mode.Stderr == IoType::String, std::string, Empty> Stderr;
operator bool() const;
};
template <ExecMode Mode> struct ExecInput
{
std::conditional_t<Mode.SearchPath, std::string, std::filesystem::path> Program;
std::vector<std::string> Args;
std::conditional_t<Mode.Stdin == IoType::String, std::string, Empty> Stdin = {};
std::conditional_t<Mode.ModifyEnv, std::map<std::string, std::string>, Empty> ExtraEnv = {};
std::conditional_t<Mode.Timeout, std::chrono::milliseconds, Empty> Timeout = {};
};
}
template <detail_::ExecMode Mode = {}, typename... Ts>
detail_::ExecResult<Mode> exec(detail_::ExecInput<Mode> input, Ts&&... args);
}
using process::exec, process::IoType;
}

Some files were not shown because too many files have changed in this diff Show More