forked from tuxcord/tuxcord.nix
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
833a21b1c1
|
|||
|
82c76dc390
|
|||
| edf7aab2f0 | |||
|
760c5c8284
|
|||
|
3a5d5d27f4
|
|||
|
015bbc3d66
|
|||
|
dc374e8c04
|
|||
|
a708c04a9a
|
|||
| a2534a3dab | |||
| b78c41a5f7 | |||
| e1f2dc3161 | |||
|
f1c5f038ec
|
|||
|
ae0d4f5958
|
|||
|
ded0374c57
|
|||
|
ab0f9a2ff2
|
|||
| fb9526fec2 | |||
|
0692e680b8
|
|||
|
3a940586d5
|
|||
| 7e7097f457 | |||
| 22b3a95bf8 | |||
| de4b8833bd | |||
| ac9b80573f | |||
| 66a15a5d19 | |||
| 7e331f5e1a | |||
| a8374e231f | |||
| 27b861d5a5 | |||
| 6a29ac005c | |||
|
0b9f76dcb4
|
|||
| cc52b0e6cb | |||
|
d4d560c30f
|
@@ -0,0 +1,20 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Wl2fDA 7PqbYWjorqzuPIDZgOZGIMzZa/P89aGzvORfMAeePRU
|
||||
J+gesdnj8VwqJSfD1ohDTSp7nBXdM4nEEB5/7aA1PMc
|
||||
-> ssh-ed25519 zNC8SA z47u0fUlGVYiQr4/S0lLh6WEj7gyedjWsq4fUk5Z1CY
|
||||
6qR4zdA1gQqpAcm5Q5AZJgn3ZnafXL4OeHfU4WJae40
|
||||
-> ssh-ed25519 EiAAKw 8mPi6HaHW+oFZHZ0Y2fJ2XISgarW3i/yLKD2QJleFGs
|
||||
Mch7D28T9eiJm8hmSuI7Wm/rjjT+EzzER9vQ7T6rA3k
|
||||
-> ssh-rsa eFi+Zw
|
||||
d3mwAM+p4yz/UK5g4+0WyeOPyEVHQEyzGSB+pPDf6IIXxGbh613h1WD5j3AQQXdH
|
||||
178Es9PhkiZcy0Y0IsQt4dyqDzuqMMwzLLvLKgsfliFsPBcdo93V5r9rWtFi3+9S
|
||||
jAfhsFzVUj3KhuBY+xsgBtHpLe5CVV52NnEzXkoJw1wbdunNi62QZvyyC+0NixFV
|
||||
HW1lxan6g6XXPrXWWrLbZWvpuqvPV6DoLsofzkMm0nd1DhkeHRU1WU8ucnPaETrJ
|
||||
E5G3YrlfhftwRzp/QzeoSFREmdAJca7ycIJaJuG8QIszTZLOOQBUAxg7sonATGUc
|
||||
Zutg1lJEfaQSe8oG1iMrJlshGspuSmBc1Ki4iQJjhQnYzvkV+Th9trG3QGq5ur9O
|
||||
RYCxqjMMzbp6kR2GdJorSM7P5fpzt0sSv2mxd+nQpMoyvOVfbBjmEbiuWrKSlIl0
|
||||
tXYrI6723mRNsbtmodUdDttaDFnr2r0MWbpHPn/K6y422GEoAiKE96Z7Pcxo2+Ml
|
||||
|
||||
--- ILGiZiEBKY+7nych4vWMVWgiFNhF3eP7mtCvJ/JImxM
|
||||
jFÍ%aë;¸8Œõl�Ë�Ô é‚YÊ×ö…›�´töÐ:Â÷ì®û¦#í õÞ(¹ðÂV°;ê[Ç`üØë:tžS#ˆ
|
||||
@²ãÒk7²àFž¿ÓEn®†!ÉlÈ¥ÛšŽÃ�7°!•Òï‡êY3:+mzÕÒÈö
|
||||
@@ -0,0 +1,19 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Wl2fDA sLlStq5Hzb2JNQubLtMk5/kyIp81aTyjUB/Ysv1gRR0
|
||||
lTLWsvT5Oxk8ut/g+o9o0DMOIQVDmi9o4EO0fYeIToo
|
||||
-> ssh-ed25519 zNC8SA G0XcS2gzF0RopI2DqkWaTYXwjUpkVtdrxSQ+p8bfE0w
|
||||
pZVIg/1P8BbnpRfV5F0FG3xgLSiA8M+nosQ8iNeYmcU
|
||||
-> ssh-ed25519 EiAAKw qWmO0IjKoUFVxbxFUx36JIhME2PU7lkD+3agKO7+6nA
|
||||
yEIw8IzQmM8C9dZoPajtvdUOF5kJ/C+rtgLczcmP1bs
|
||||
-> ssh-rsa eFi+Zw
|
||||
O5XRvS+Y/1mm9nQ7IZmxEp7RmFjAH0OTKPkRTME7BybnePPZLL0l6wMP26hx88Nv
|
||||
dOqdaS07Xb26EIgCS/4xCY4sPWZNEfAfnDVoF4/SNbmfbN0XpNpR981AWcxiTL35
|
||||
Fngk0lPa1NtuUH4S4zTda21kXHE0zv2mYLNMuek8dTrUd2piC+Z0WJJdrG1LK0hN
|
||||
dDuLzX/mNibNXDvYxyD6mtkO2S1wO9QL88ucNZptT29vcaD48EZM/SsAwgf3OoqH
|
||||
kd7jSTTdZ/yk8ccTMiT5eskQ3ZZcqc7JaF+M2d88DP6LcSaJnNzyVSEMAHHfpoY1
|
||||
/kHxZ88/ehwPDXrp0bL448jdPuWqPSerzCWyyZFbc8Jj6zRUtC5joL0Vq2Rqs+EH
|
||||
rmKMfi1l2+utleGYfCyHI5/czsMhJ2jXLGPguWQQdixNtb/RWFw6DeRP9xdO9QJR
|
||||
LkoAFgv0ykP+L+C6sA7bpJqIGNftl4x8OUQxrKtf3YQ8K2LhUZb23JPn4Ob/QXo/
|
||||
|
||||
--- W7eUDhB/RBUYV1gaM4ktPEOVU6l5IRgOoRDpKKpvAnM
|
||||
O\òŒMúOýJä ÍÅ!ÒHûËÄpK¥Õ:gßÙ[6™M¡VÞÃbYæÌí;è€F'¡#ä7&Žs1„ 󨱉6º�²5_nÂ’mõÔ.¼qñ'à˜ƒq®6Êf-ÖÄW™w›½ß#5³¯6ˆ¼ŸêªrÒð�„Ð#œÅÄ€=�4EÎËlžÕÿ[
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Wl2fDA 3CWPYLgoTMGb9gBbDzZIQxYJ9Gfm49g6lqQyqlegUDQ
|
||||
ryhsPP5+Byus2e5GSXDJlKYX1o3HfQ87CLRv2htU4n4
|
||||
-> ssh-ed25519 EiAAKw B2uGdkeC3OZISN2iH2DR1J7L3/mbuFvebzqaTdAURCw
|
||||
ze0X/MmHP78rRqAn0O3VBtnMJsiOXPk8RIe82tdQMeg
|
||||
--- kLBxPuJdbPmJ1Lz3iBu8EPItdZtpNHIyV6pz1QzhcUY
|
||||
ä3ÛÿÉèŸP>gòh@ö•AZ’üz-í6R€¸zèÚ¢[ÇÝÍPÂòㆿy?•ÉŽU�SNÝ©&ú#}ÝR+o?.B¶&´5]ÇW€OΉPuh‹½ŽÞ=t¶5|¿×“s×€ú&!‰Î-�æTÝSÆfÕ™-j"#žiÂwzºš›ãjö¯“HŒí�
|
||||
@@ -0,0 +1,19 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Wl2fDA XXuM89kA+Hnc4nKJ005H+IDYV5qk4nEx/IUWk/CbKiM
|
||||
sPJrUh6RI+Anzwy/nSR/dbCkZQvpJ3dGYSkChfJEv2Q
|
||||
-> ssh-ed25519 zNC8SA mg1uB6DPLT/3DE2Hh+EIGv9N4ZmDSi1w7UeW91u0cHs
|
||||
qBAmL0fgdRNuM4VYiDx0g6T2ZJFiqhgXpC/4C/RsVqU
|
||||
-> ssh-ed25519 EiAAKw EL0tfmXf6b2DWA3Ty4fhYdJL6AYdvknGv/To81dJ2zU
|
||||
KtZZx4//yDaAU6bt9JWYdBRbpqn79YHAu46857SBBPI
|
||||
-> ssh-rsa eFi+Zw
|
||||
jDWmTVRF7H9rhPAVEV2HkHtXpc/g16jlPDxvxzfnftyGF6aGfgoRwKtOwtqZtaB/
|
||||
UDE6Pzo3n5yg5/B8d0JhabBMfZpSJ8xiJcJfti8sY5tno97HhL0Fzd2r/0VM74iO
|
||||
TZ/ZA8xJACFfm9VclUz3gZWNG7qU4CrMYXQxWcwacphCiIFyFJVuaQEDf1rQnqEd
|
||||
3C8bMYxgRmUI64lLaRHdYD84hQ49xXrtuEQbJu6e/B3zCWsAMzpVciE/maDBBBGz
|
||||
EFRhhvP3Y8riBt4FLgYRVpvwge44LrX0N9NHeOyFmgP/S62ShDP+xLBnw9V3Tcuz
|
||||
9iuyJS4lz/mSWE9ISa1y21emQAuXOwdMkFM0b6tSCBL1zwKUNAzmEV/S4BMydNex
|
||||
/1m1ZaWDrOpfrBzRU+kN02a5sCHNGjO2/4T0dCjoGOeHUvpOw0IxniSQiKZj03nQ
|
||||
mWnWDp1sA/DK0ySs0AcYXJUs9EoeDQ1ny6tQ1Loc9xzX6uMFnFLfYIWXiI4erldl
|
||||
|
||||
--- 9ryp8lwLiw/0MYGf1zSVR8ML6l5h83D0Flaks10d7Yg
|
||||
¹´m“Õ¶œK[.›šLÛãKÜ Õr'4†ÿÎÂû*«ÖÜý¬ßÏñ-¨À–T,Cê$ЦŸ�Vئf·E:pu*wdwe[óR¦ŒëëwŸP§Qøhªi½è0L×0J"�©e�þD÷l‡‡gõ®’üœ’ù„&9õ™5éÑjZÀÞÇ«ßd
|
||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Wl2fDA 86jJdtfiJBUnXAh0R+VjMeX5NTB+kGQlOioe/9Us6GI
|
||||
i0EPVHWazwgTCracN1bn9mvbpynd1x+XNE+5Hh09bKM
|
||||
-> ssh-ed25519 zNC8SA hL+Axpc8Qy8iosArb+JdAaQdf6gPlUaLRQ0w4YJJU1c
|
||||
k4prWpg+pyuykv8N2RjQQT7Ow53QjXBYxsqBwjtgFjw
|
||||
-> ssh-ed25519 EiAAKw /+UyD03g2OVWeJzooMrMxNH0otkY6Km9BDSJ+f8zVGQ
|
||||
kFSmApLaIFQ1F1ZaLThFlb7ZOfIDWDYZByuYfEvn2FU
|
||||
-> ssh-rsa eFi+Zw
|
||||
p5uxnSM+9jojTeHlzDycwEKqklY6F1oDU87e0pn/WhNBtSo3SzNI0aHtwKDLN548
|
||||
m4RQNQ6wKWAl36VvQDJmWiP6LJNKx5oQvgCLqqJ+fGTAx1mUUL+hpVC+Y2siONbN
|
||||
WWbFXVD1FHk+enHkRA9ZERiVPqV7Zg5b55t+E2dwRh2fas8IlOwBEEceIggYKi85
|
||||
Dywr8dhdL1VeAHG1l4fdkgn9A3oLqMHIw0oUHX16CawCYrQZt9bezDR6mb8HuEdM
|
||||
KVHSd6y+Aq0wYgcmGEkknw45VlG9Mjor0qhW9y+cJQ941niiPr1Q7LPcpdLAUmHP
|
||||
KbGDnnt/vvMEXaa5G1HDytvedHbAygx/fWGfm3Ngq8qUAV7kEHz2kUclJ5OOBTRm
|
||||
M0081XNKZF2QdmN+O8eMFMor1OcKsNe3Ril0Y8rPtMd+iwOulLbbV3b8LZ/Jd1+9
|
||||
ePUoOyj0wP4gVzXo5INiNVtYK+sK6Ek1Gt+UCHhAlJwj5RulmIvEzISZjHJAt4yU
|
||||
|
||||
--- hljwKKncDABYcm9RHZtEdHhRlKqSFtoE6GihIfBqowU
|
||||
ošã…ŒüFÔÑr u·«¢sð(�ÿg»NÇšØÄø¬äƒÇ¤g�Isã„ý¡^•Õíõ‚›�Ò1¼ÁQé¥]¶aE”^Áœiw«Ne2:4Ì ö®bH†ŠŽÆyf¸ nü‰$+ÉÃ_Ö¶•éjòê4Ý>Þ $?”<“³·IЍ……‘˜'±
|
||||
+18
-15
@@ -1,17 +1,20 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Wl2fDA JMymqEdh+xJbl8VcL5wg7Y2Dk4667DzNO85RCskX+0Q
|
||||
ZQqF0eYpvrLujGdIvAMbfwPnKGa+mfNvAhHGMdXiYaI
|
||||
-> ssh-ed25519 zNC8SA UCQhQA4f3OiNoxejDBMabnls3LjS0GQmvIqPpjB/FH8
|
||||
0qvv6W1heZiE1DDYEj1U5N2e99DZLxlJ6A8EoZ31DhM
|
||||
-> ssh-rsa 3G83yA
|
||||
Gnpw8t6njIXGm98jTS47Afx6TogPnIJP59rapF0CkYkDXZNrW7WK+fcERHLN2+a+
|
||||
PSkjwkql3LfAtCNqrIJZwWLj/URnKQF5N3ZKwOa1+wsM3GeUzjvaQwPZunj4jyFs
|
||||
IJlL+ika2sBk/HvOa1r6ntj2cvLM1fIhbs9bOEZW3br3M3sfXk386TgrytqzM248
|
||||
3xS2iIwIBmBiI5Xem8KO2+J/2Vk9Px/ZPkBpdIAaZAmihe3g/VWNKHhXrwdM9ZA7
|
||||
tHgw5ohK8ug88ep9XCIFD75DPeK/60wqAdkGs4PE6THcsKqhN061TAEq3SWRl8wp
|
||||
Kd17yAzHDLhsbdWXT/Q912Y4YJCB3TnD0MFGzPF7sks2NknB6yowwjnCGlqzf5rW
|
||||
RBKHp6PTM+x/eDi89vS+uIBtyGFaFU7wBTl4FzJpKoOsRIDYNktGkJSxdTzrMO1n
|
||||
XqXtJtqZaXN7UExA+ko9ln446I7RG8c3hNGx4A4bR1xUEUE8WD/TMhjzrbzysYSl
|
||||
-> ssh-ed25519 Wl2fDA 8rfiRx7+Gr9BtiSXsVEs2W+pXoms6ynODC1TL90+Wi4
|
||||
/uMnYMJovbaPjwX1qCAtIokov40RYIAm2Mup5XKBJvw
|
||||
-> ssh-ed25519 zNC8SA FlxMK7kMYnKHY9MBJ+HYDI4GNS0nSgZxVuRe4yTWBgg
|
||||
HPOV31k8Ueb1W5usG7iLXDQxyAlISrgHThddHpGY2+s
|
||||
-> ssh-ed25519 EiAAKw Bu7+NJXivoRA07glNWUlBGu03J0ueth7XDU7SWQYT30
|
||||
r/DBmf4TRDJBgFF0KdeHuKL5hLdU1z6HtfAAVbc6Y0I
|
||||
-> ssh-rsa eFi+Zw
|
||||
Nu4gAM/vbh0kpEUIaT4P6iTe9qFFM/9IVxiiKPYHdPnCmPJHrug1afLLFrrrpqkd
|
||||
o1NrfYIM9gW6jl5QMCcP5DpzMTppokX0P1Tz1ZeOEtZUVtGeZ7Q2wmL4zftwmG9J
|
||||
qoDjsCd0z6MPDUdU46qc7kjQBhOwGLfHXTfGLXGNZxqj0oLvEoEKpdvFNBvMSyxK
|
||||
oGZRwGsHQcUXKhCPtf6PVtSkHMABzpUAhgS8oqjp4RVurD0lcrPgsx8pSRRarfyE
|
||||
ll1QbFCjftuJfeIEshgRkaLGjIQpZDFA3w2XMqDddFz5H/9Ak+F8/rkNnUrN2x4M
|
||||
amca8s4Sbls6RjyysarIytilCtpaKEI2sgkD2fERao6ayTSnWF45qqh635OLaP5A
|
||||
b7qcru9gO0C3Ik+UuiZMgovxo/+yBYe3+8x8q/uKR4apPAkt/2q28Uilw1WboIEB
|
||||
rIjBr0BN1JeHvkiyljJGcvGf5jHdmOrpQu/L1xuSDjsTnh+U6BshQC8bbkJNsVoL
|
||||
|
||||
--- BuKW3bW48i1OD38J2bj5sRkn+zg/WKiLtf8zgycCr2A
|
||||
g©2Ôkâ5 ÀóìØ!]0kÉW€³�ÍØ¡t>éQžk[I3Vâ4EÔàwc`L;UvžVe)m©mé¿€Û¸
|
||||
--- GCTLfa/BICL9AWTaqGC13M101Z8sqSqPP4ysJVv5zvg
|
||||
]
|
||||
ý¢Ôÿi¹‡7c·f`b@%X”¿J�)û[<+;x-ÇKmTõ@ãÌ„�ýŸK]7sc*럇¼2Ý®5
|
||||
+20
-2
@@ -1,8 +1,26 @@
|
||||
let
|
||||
users = import ../lib/ssh/keys.nix;
|
||||
inherit (import ../lib)
|
||||
users
|
||||
adminSSHKeys
|
||||
attrsToList
|
||||
getSSHKeys
|
||||
;
|
||||
|
||||
tuxcord-ca = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPxiko5Csyq9UODglYzLBvRfxkhQu9GXP7SH2BpC8G/7";
|
||||
in
|
||||
{
|
||||
"ntfy.age".publicKeys = [ tuxcord-ca ] ++ builtins.attrValues users;
|
||||
"ntfy.age".publicKeys = [ tuxcord-ca ] ++ adminSSHKeys;
|
||||
"authentik.age".publicKeys = [ tuxcord-ca ] ++ adminSSHKeys;
|
||||
|
||||
# tsig-keygen etc.sub.domain.tld.
|
||||
"dns/tuxcord.net/tuxcord.net.key.age".publicKeys = [ tuxcord-ca ] ++ adminSSHKeys;
|
||||
"dns/nix.tuxcord.net/nix.tuxcord.net.key.age".publicKeys = [ tuxcord-ca ] ++ adminSSHKeys;
|
||||
"dns/tuxcord.test/tuxcord.test.key.age".publicKeys = [ tuxcord-ca ] ++ adminSSHKeys;
|
||||
"dns/tuxcord.test/sub.tuxcord.test.key.age".publicKeys = [ tuxcord-ca ] ++ adminSSHKeys;
|
||||
}
|
||||
// builtins.listToAttrs (
|
||||
map (user: {
|
||||
name = "dns/tuxcord.net/${user.name}.tuxcord.net.key.age";
|
||||
value.publicKeys = [ tuxcord-ca ] ++ getSSHKeys user.name;
|
||||
}) (builtins.filter (user: user.value.ddns or false) (attrsToList users))
|
||||
)
|
||||
|
||||
@@ -16,13 +16,19 @@ To test the environment, you can launch a virtualized NixOS system derived from
|
||||
nix run '.#nixosConfigurations.<system>.config.system.build.vm'
|
||||
```
|
||||
|
||||
Here, `<system>` refers to the hostname of the system you want to test (e.g., tuxcord-ca).
|
||||
Here, `<system>` refers to the hostname of the system you want to test (e.g., tuxcord-test).
|
||||
|
||||
Note that this will create a `qcow2` image file in the current directory. Nix will automatically manage changes to the configuration and update the image file accordingly while keeping part of its mutable state (e.g., root bash history).
|
||||
|
||||
> [!WARNING]
|
||||
> Not all changes are applied automatically. Updates such as user passwords changes or modifications to the filesystem layout will require deleting the image file so that Nix can re-create it from scratch.
|
||||
|
||||
# Access
|
||||
|
||||
The initial password for the `root` account is `tuxcord`.
|
||||
|
||||
SSH login is enabled for the configured user keys, if using the VM test configuration, yo will have to use the bridged IP.
|
||||
|
||||
# Tooling
|
||||
|
||||
Tooling used to aid in development.
|
||||
|
||||
+9
-1
@@ -42,7 +42,15 @@ Host specific configuration can be found at `nixos/hosts/tuxcord-XX`. This is us
|
||||
|
||||
To learn how to get started, refer to the [Getting Started guide](./GETTING_STARTED.md).
|
||||
|
||||
The guide contains basic instructions as to how to use Nix for this repository, as well as tools to help in certain tasks.
|
||||
The guide contains basic instructions as to how to use Nix for this repository, as well as tools to help in certain tasks, some of this tools might be assumed across document resources.
|
||||
|
||||
It might also be useful to read the [installation section](#installation) to learn how to configure your testing environment.
|
||||
|
||||
# Installation
|
||||
|
||||
Though the nix configuration already does most heavy-lifting already. There's some minor configuration that has to be done to the mutable state of the machine.
|
||||
|
||||
Each aspect of it should be carefully explained in the [Setup Guide](./SETUP.md).
|
||||
|
||||
# Contributions
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# Secrets
|
||||
|
||||
Secrets are managed with `agenix` in the `agenix/` directory. This allows to declaratively define secrets as well as which keys are allowed to decrypt them.
|
||||
|
||||
# Usage
|
||||
|
||||
The `agenix` help menu is already very helpful, but here you have a survival guide:
|
||||
|
||||
- `agenix` commands should run relative to the `agenix/` directory.
|
||||
- `agenix -d` allows you to descrypt such file if you possess any of the decryption keys.
|
||||
- `agenix -e` decrypts (if present) and opens the file in your editor to re-encrypt when exited.
|
||||
- `agenix -r` re-encypts `*.age` files in the case you ever change its decryption keys.
|
||||
|
||||
# Secrets
|
||||
|
||||
There is a `ntfy.age` secret file which contents look like:
|
||||
|
||||
```sh
|
||||
NTFY_TOPIC=readable-name_XXXXXXXXXX
|
||||
```
|
||||
|
||||
This secret file is meant to be sources by shells before using [ntfy.sh](<https://ntfy.sh/>) to push important notifications. This topic could contain sensitive information and must be kept secret amongst administrators.
|
||||
|
||||
## DNS TSIG Keys
|
||||
|
||||
The DNS server takes zone updates through `nsupdate` with symmetric TSIG keys.
|
||||
|
||||
These keys can be generated using `tsig-keygen <key-name>` (historically they were done with `dnssec-keygen` and `HMAC` algorithms, but this is no longer supported).
|
||||
|
||||
When DNS is enabled for a host, it will look for `dns/${fqdn}/${zone}.key` secrets.
|
||||
|
||||
- The key whose zone matches the `${fqdn}` will be allowed to tramit updates for all the domain.
|
||||
- Keys restrained to a specific `${zone}` will only be allowed to edit records of such zone.
|
||||
- All keys must be named with the zone they affect, final dot included, so that (e.g. `tuxcord.net/javalsai.tuxcord.net.key` must be generated by `tsig-keygen javalsai.tuxcord.net.`).
|
||||
@@ -0,0 +1,66 @@
|
||||
# Setup Steps
|
||||
|
||||
The first configuration of the server needs some configuration of its mutable state:
|
||||
|
||||
Setup also heavily relies on the secrets configured, make sure you [understand agenix](./SECRETS.md) good enough.
|
||||
|
||||
# Root Password
|
||||
|
||||
The `root` password is `tuxcord` by default on all system configurations. For security, it's important to remember to change it as soon as an installation is done.
|
||||
|
||||
The root account is intended to be kept active in case there ever is the need to perform a TTY login. But this will be rare so do keep a security complex password saved somewhere and don't share it beyond the necessary amount.
|
||||
|
||||
# SSH Keys
|
||||
|
||||
Most agenix secrets have to be decrypted by the machine nixos is being installed to. For this, agenix uses the ssh host keys.
|
||||
|
||||
This also means that no secrets will be accessible on the host right after a base installation, with the default fresh ssh keys.
|
||||
|
||||
Will will need to either migrate ssh keys from another host, if you are doing a migration, or take the public keys of the new host out to encrypt agenix secrets against them. These keys, both public and private are present in `/etc/ssh/ssh_host_*`, we have a strong preference in favor of elliptic curve cryptography.
|
||||
|
||||
Also note that ssh keys are persistent and will be saved across machine boots and virtual machine rebuilds, so you don't need to repeat this process every time.
|
||||
|
||||
# DNS SOA Record
|
||||
|
||||
If the DNS server is enabled for the host (`dns.enable`), the host will have a DNS server for itself that can take updates with `nsupdate`.
|
||||
|
||||
This section assumes surface-level knowledge of DNS records, as well as a IPv4-only server.
|
||||
|
||||
First of all, make sure that the secrets for `nsudpate` ([DNS TSIG Keys](./SECRETS.md)) are in place, otherwise the server won't be able to take updates and will remain on an empty useless state.
|
||||
|
||||
You need to tell it it has authority over itself (`SOA` -> `Start Of Authority`) for it to take updates and serve changes properly, as well as configure the base `A` records.
|
||||
|
||||
`/var/dns/${fqdn}.zone`:
|
||||
|
||||
```zone
|
||||
$ORIGIN ${fqdn}.
|
||||
$TTL 14400 ; 4 hours
|
||||
@ IN SOA ${fqdn}. ${adminEmail} (
|
||||
2026050301 ; serial
|
||||
3600 ; refresh (1 hour)
|
||||
1800 ; retry (30 minutes)
|
||||
604800 ; expire (1 week)
|
||||
86400 ; minimum (1 day)
|
||||
)
|
||||
|
||||
@ A ${ip}
|
||||
|
||||
ns1 A ${ip}
|
||||
@ NS ns1
|
||||
ns2 A ${ip}
|
||||
@ NS ns2
|
||||
|
||||
* CNAME ${fqdn}.
|
||||
```
|
||||
|
||||
Note the template variables:
|
||||
|
||||
- You need to place your FQDN in `${fqdn}` (there are shorter ways, but this guarantees functionality even if the hostname and domain don't match).
|
||||
- Also an IPv4 address at `${ip}`.
|
||||
- And lastly, `${adminEmail}` the SOA record has a `RNAME` field that takes the administrator's email address with dot notation (`test@example.com` would be written as `test.example.com.`).
|
||||
- The values related to serial number and lifetimes can and should be tweaked depending on the use-case. Especially `serial`, note that it resembles a date.
|
||||
|
||||
Then restart bind with `systemctl restart bind`. Make sure that the file is owned by `named:named`.
|
||||
|
||||
> [!NOTE]
|
||||
> This file is **mutable**, bind can and **will** change it with `nsupdate`s, it also tends to format and compact this template into a certain layout.
|
||||
Generated
+276
-12
@@ -23,6 +23,67 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"authentik-go": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1771856219,
|
||||
"narHash": "sha256-zTEmvxe+BpfWYvAl675PnhXCH4jV4GUTFb1MrQ1Eyno=",
|
||||
"owner": "goauthentik",
|
||||
"repo": "client-go",
|
||||
"rev": "4c1444ee54d945fbcc5ae107b4f191ca0352023d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "goauthentik",
|
||||
"repo": "client-go",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"authentik-nix": {
|
||||
"inputs": {
|
||||
"authentik-go": "authentik-go",
|
||||
"authentik-src": "authentik-src",
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-parts": "flake-parts",
|
||||
"flake-utils": "flake-utils",
|
||||
"napalm": "napalm",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pyproject-build-systems": "pyproject-build-systems",
|
||||
"pyproject-nix": "pyproject-nix",
|
||||
"systems": "systems_2",
|
||||
"uv2nix": "uv2nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1776085803,
|
||||
"narHash": "sha256-JvvWVbXJYSY8qOReMbAOD4lxcN2cjKV6lg/jLz8CEuY=",
|
||||
"owner": "nix-community",
|
||||
"repo": "authentik-nix",
|
||||
"rev": "4370b561c8bafb59773ce3a518506bcf1161dbdb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "authentik-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"authentik-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1775573258,
|
||||
"narHash": "sha256-Xq7JGI/8ppIydIuWd9KRJKUrh7UpeniwvZ4NAtXbYJ4=",
|
||||
"owner": "goauthentik",
|
||||
"repo": "authentik",
|
||||
"rev": "5249546862986202b901c2afd860992ec48c6ef6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "goauthentik",
|
||||
"ref": "version/2026.2.2",
|
||||
"repo": "authentik",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"darwin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@@ -46,6 +107,7 @@
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1767039857,
|
||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||
@@ -61,6 +123,21 @@
|
||||
}
|
||||
},
|
||||
"flake-compat_2": {
|
||||
"locked": {
|
||||
"lastModified": 1767039857,
|
||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_3": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1767039857,
|
||||
@@ -80,6 +157,24 @@
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_2": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1777678872,
|
||||
"narHash": "sha256-EPIFsulyon7Z1vLQq5Fk64GR8L7cQsT+IPhcsukVbgk=",
|
||||
@@ -94,6 +189,27 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": [
|
||||
"authentik-nix",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"git-hooks-nix": {
|
||||
"inputs": {
|
||||
"flake-compat": [
|
||||
@@ -188,9 +304,35 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"napalm": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"authentik-nix",
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"authentik-nix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1725806412,
|
||||
"narHash": "sha256-lGZjkjds0p924QEhm/r0BhAxbHBJE1xMOldB/HmQH04=",
|
||||
"owner": "willibutz",
|
||||
"repo": "napalm",
|
||||
"rev": "b492440d9e64ae20736d3bec5c7715ffcbde83f5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "willibutz",
|
||||
"ref": "avoid-foldl-stack-overflow",
|
||||
"repo": "napalm",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-alien": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-compat": "flake-compat_2",
|
||||
"nix-index-database": [
|
||||
"nix-index-database"
|
||||
],
|
||||
@@ -234,12 +376,12 @@
|
||||
},
|
||||
"nix-super": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_2",
|
||||
"flake-compat": "flake-compat_3",
|
||||
"flake-parts": [
|
||||
"flake-parts"
|
||||
],
|
||||
"git-hooks-nix": "git-hooks-nix",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs-23-11": "nixpkgs-23-11",
|
||||
"nixpkgs-regression": "nixpkgs-regression"
|
||||
},
|
||||
@@ -259,15 +401,18 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1771903837,
|
||||
"narHash": "sha256-jEA8WggGKtMFeNeCKq3NK8cLEjJmG6/RLUElYYbBZ0E=",
|
||||
"rev": "e764fc9a405871f1f6ca3d1394fb422e0a0c3951",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/25.11/nixos-25.11.6495.e764fc9a4058/nixexprs.tar.xz"
|
||||
"lastModified": 1771848320,
|
||||
"narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2fc6539b481e1d2569f25f8799236694180c0993",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixos-25.11/nixexprs.tar.xz"
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-23-11": {
|
||||
@@ -287,6 +432,21 @@
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1769909678,
|
||||
"narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "72716169fe93074c333e8d0173151350670b824c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib_2": {
|
||||
"locked": {
|
||||
"lastModified": 1777168982,
|
||||
"narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=",
|
||||
@@ -318,6 +478,19 @@
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1771903837,
|
||||
"narHash": "sha256-jEA8WggGKtMFeNeCKq3NK8cLEjJmG6/RLUElYYbBZ0E=",
|
||||
"rev": "e764fc9a405871f1f6ca3d1394fb422e0a0c3951",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/25.11/nixos-25.11.6495.e764fc9a4058/nixexprs.tar.xz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixos-25.11/nixexprs.tar.xz"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1777428379,
|
||||
"narHash": "sha256-ypxFOeDz+CqADEQNL72haqGjvZQdBR5Vc7pyx2JDttI=",
|
||||
@@ -333,15 +506,66 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pyproject-build-systems": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"authentik-nix",
|
||||
"nixpkgs"
|
||||
],
|
||||
"pyproject-nix": [
|
||||
"authentik-nix",
|
||||
"pyproject-nix"
|
||||
],
|
||||
"uv2nix": [
|
||||
"authentik-nix",
|
||||
"uv2nix"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771423342,
|
||||
"narHash": "sha256-7uXPiWB0YQ4HNaAqRvVndYL34FEp1ZTwVQHgZmyMtC8=",
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "build-system-pkgs",
|
||||
"rev": "04e9c186e01f0830dad3739088070e4c551191a4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "build-system-pkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pyproject-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"authentik-nix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771518446,
|
||||
"narHash": "sha256-nFJSfD89vWTu92KyuJWDoTQJuoDuddkJV3TlOl1cOic=",
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "pyproject.nix",
|
||||
"rev": "eb204c6b3335698dec6c7fc1da0ebc3c6df05937",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "pyproject.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"agenix": "agenix",
|
||||
"flake-parts": "flake-parts",
|
||||
"authentik-nix": "authentik-nix",
|
||||
"flake-parts": "flake-parts_2",
|
||||
"impermanence": "impermanence",
|
||||
"nix-alien": "nix-alien",
|
||||
"nix-index-database": "nix-index-database",
|
||||
"nix-super": "nix-super",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
@@ -358,6 +582,46 @@
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1689347949,
|
||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"uv2nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"authentik-nix",
|
||||
"nixpkgs"
|
||||
],
|
||||
"pyproject-nix": [
|
||||
"authentik-nix",
|
||||
"pyproject-nix"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772187362,
|
||||
"narHash": "sha256-gCojeIlQ/rfWMe3adif3akyHsT95wiMkLURpxTeqmPc=",
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "uv2nix",
|
||||
"rev": "abe65de114300de41614002fe9dce2152ac2ac23",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "pyproject-nix",
|
||||
"repo": "uv2nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
||||
@@ -31,6 +31,13 @@
|
||||
url = "github:privatevoid-net/nix-super";
|
||||
inputs.flake-parts.follows = "flake-parts";
|
||||
};
|
||||
|
||||
authentik-nix = {
|
||||
url = "github:nix-community/authentik-nix";
|
||||
|
||||
# inputs.nixpkgs.follows = "nixpkgs"
|
||||
# inputs.flake-parts.follows = "flake-parts"
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
@@ -52,6 +59,11 @@
|
||||
formatter = pkgs.nixfmt;
|
||||
};
|
||||
|
||||
flake = {
|
||||
lib = import ./lib;
|
||||
pins = import ./npins;
|
||||
};
|
||||
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
rec {
|
||||
toList = x: if builtins.isList x then x else [ x ];
|
||||
|
||||
nameValuePair = name: value: { inherit name value; };
|
||||
|
||||
mapAttrsToList = f: attrs: builtins.attrValues (builtins.mapAttrs f attrs);
|
||||
|
||||
attrsToList = mapAttrsToList nameValuePair;
|
||||
|
||||
getSSHKeys =
|
||||
username:
|
||||
if (builtins.hasAttr "ssh" users.${username}) then
|
||||
toList users.${username}.ssh
|
||||
else
|
||||
builtins.warn "user ${username} declared without ssh keys" [ ];
|
||||
|
||||
users = import ./users.nix;
|
||||
|
||||
adminSSHKeys = builtins.concatLists (
|
||||
map (user: getSSHKeys user.name) (
|
||||
builtins.filter (user: user.value.admin or false) (attrsToList users)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
error = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDzdpxex2GlFVf5G2qsh3Ixa/XCMjnbq4JSTmAev7WYJ error.nointernet@gmail.com";
|
||||
javalsai = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCufzCHLqMfuHpKKisd9Y+3l6hudbQQyaHg1lgQs5XEO58f0dIoUK3gc8iVO6dGGeY5q2o0cDcildHiT0PYc96rq7WJLCY00mAuclEuhmRSPjsei2IT3rWTawIheD2tWq+vAQjIBKibYWnVYwNOsbR3Zz1uKG/LNqqDnyYO/t4iMmhO1qcl6j8dRVBtzWYu3TnTrwx45sj54Y9hqZZiwB1xlzhHznSw6YPOe51hUO/yUtXKF2FCyfG7LHELZBMXkPQD6h4mDu+QNPN2D5RGd+Q5WzHcXcrXH/DvogVW6g3YGpBjTNKllCjGJYdYgjcjzQOS3I8ZOL6CUQzcZt2QwO3P42s4cjGzBwIub2zFnMOCyGgbKCYh3G7KKcde9qAX0yl8k+XNPIletJAV7pDrivzmgRLdy3iWud+q8TytkDLhcd/7g+pE6FE8y3IbejwXGNUn8CXJOKWH5zk0MVWSpNqz+6rlV43iPb4yuO7TFVnzuw/wKyOoc8RlFGEb/XLXwPs=";
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
error = {
|
||||
ssh = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDzdpxex2GlFVf5G2qsh3Ixa/XCMjnbq4JSTmAev7WYJ error.nointernet@gmail.com";
|
||||
admin = true;
|
||||
ddns = true;
|
||||
};
|
||||
|
||||
javalsai = {
|
||||
ssh = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFjavnLqxIzFLIUpUWDOwhlYeoII4Qk1/9e0yWWxD/P";
|
||||
admin = true;
|
||||
ddns = true;
|
||||
};
|
||||
|
||||
max = {
|
||||
ssh = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDxVfJhzPDZ108UjB3Vj/akzlzYn27kyAw29AuYAr7gvG5vrqhLUYYmK8t+ZVWVpc1g6cK7OF1oUn2E5Qfmy6wqyZQXftAZ4OcRS0MB71W1bAcRq3rGe6KQDm8RSEeygX+zO+2Z6zQmVWgPr/I+JFQZ8wiWdP8X8djqTRdhqUD+SR3ZgTcnY3aLmeB/I56rcZQ3lKIeg/pEsyQ8weptlV0rTWamna6Z7Nw48VwWNSI+6EqfW2/4/edm0Ue8jMNqNZ0yx+kHJbudPgZgSR1SiR2rqlEEUaiQJQQV3VdY4DhGm7143ZSKUxyKlfTuQ7qR1zSIg6f5V71A37ik9YiSbBlOZO86swR4qHESoMNf608IuqRt2NdALHwozFPUCu16qnhu5JTk8twSAzrAhOk5zWQj1LYMoQEBhcFSmwir/1gE71NSjYtqXGVAdfkVmZ4uqG5+a1D7H3VXWOqu/j839M045O1ZBY6X3lKDsEJ1Z1+LCl/NojWnvPtJUHYI6+SdQ6k=";
|
||||
admin = true;
|
||||
};
|
||||
|
||||
vectorum = {
|
||||
ssh = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCwfPaylCSN7ZqB6Trz8CmQlyzf0NUIy06uschdIOkdzjUNe/dPGbyEFZy/4SDBhg585x8hwfhfYjLGrneYq+O42DBDTDKxduWnIdl5zgPRqt7jB59jkukf9WUdpUdZsKCM5K97HCnizNEKGRnYllVPVQSapPhOm5dZlUD9YVv1UqbDuxtWOLvArkL52e9T+yL6FagRg6NPqA70MXPMk+S2H7lotFVxP2Eg//BCaQ0/H1vhNy6P4N6LLq3sVK1DSJyd2v8zHkdb2Zo0/Ygukol10KizSsEcihm8+bXp699uSgWIsaIQgDZlE1yx2iabmzQST1kL9+USnZZBZ+KxwtLCCI8mpCv6sxlhq2Zzim5HvsyMYM+zdHWIn1s2c6mEl4ntBAB4s5wAggS5Gjh/BfJLSvGsTFMC/XYX4gWFXynY5NlcopeENL2Afg4gbQvKkxYkWB/TMZWuqj5c5kCy+7F0881DpYxapq6kQ6IE4gkGiEQdhVFGWEFoV/k9iHrl6aanqvFtvuBHHgkXAGPpHAZDVZdp9lU0tqNQIM/eGINq4Or6wd9XDYyj5ezDEBxx1pPgweUDZrNe9+vKR+3AwbzB/XQPxTCcjd4d7Yx58jPLflFP1dDYT+3bvp+vA7UpHcJnISbVNu0SiSaIqLYhwDj1od5l6JDfRCqnMF1T59nRCQ==";
|
||||
};
|
||||
|
||||
pickzelle = {
|
||||
ssh = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPUYQUWoL8iGc+PSrRrHyNwcOcmgGwPvJAM9HRJkPqcW pixel@DOOM-Machine";
|
||||
};
|
||||
}
|
||||
+16
-6
@@ -4,6 +4,7 @@
|
||||
lib,
|
||||
pkgs,
|
||||
self,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
@@ -17,6 +18,7 @@ in
|
||||
agenix.nixosModules.default
|
||||
impermanence.nixosModules.default
|
||||
nix-index-database.nixosModules.nix-index
|
||||
authentik-nix.nixosModules.default
|
||||
|
||||
./hardware.nix
|
||||
./impermanence.nix
|
||||
@@ -27,6 +29,8 @@ in
|
||||
./vm.nix
|
||||
];
|
||||
|
||||
age.secrets.ntfy.file = "${self}/agenix/ntfy.age";
|
||||
|
||||
nix = {
|
||||
package = inputs'.nix-super.packages.default;
|
||||
|
||||
@@ -92,13 +96,19 @@ in
|
||||
networking = {
|
||||
networkmanager.enable = true;
|
||||
|
||||
firewall = {
|
||||
enable = true;
|
||||
firewall.enable = true;
|
||||
|
||||
allowedTCPPorts = [
|
||||
22
|
||||
];
|
||||
};
|
||||
extraHosts =
|
||||
let
|
||||
subdomains = [ "git" "auth" ];
|
||||
|
||||
inherit (config.networking) fqdn;
|
||||
hosts = [ fqdn ] ++ map (sub: "${sub}.${fqdn}") subdomains;
|
||||
in
|
||||
lib.concatMapStrings (host: ''
|
||||
127.0.0.1 ${host}
|
||||
::1 ${host}
|
||||
'') hosts;
|
||||
};
|
||||
|
||||
virtualisation.podman.enable = true;
|
||||
|
||||
@@ -31,5 +31,8 @@ in
|
||||
{
|
||||
flake.nixosConfigurations = {
|
||||
tuxcord-ca = mkSystem "tuxcord-ca" "x86_64-linux";
|
||||
|
||||
tuxcord-test = mkSystem "tuxcord-test" "x86_64-linux";
|
||||
tuxcord-acmetest = mkSystem "tuxcord-acmetest" "x86_64-linux";
|
||||
};
|
||||
}
|
||||
|
||||
+4
-1
@@ -15,7 +15,10 @@
|
||||
"xhci_pci"
|
||||
];
|
||||
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
kernelModules = [
|
||||
"kvm-amd"
|
||||
"kvm-intel"
|
||||
];
|
||||
};
|
||||
|
||||
hardware = {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
imports = [
|
||||
./storage.nix
|
||||
];
|
||||
|
||||
networking.fqdn = "nix.tuxcord.net";
|
||||
|
||||
acme.rfc2136.nameserver = "tuxcord.net";
|
||||
dns.enable = true;
|
||||
|
||||
services.getty.autologinUser = "root";
|
||||
|
||||
time.timeZone = "Europe/Madrid";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
fileSystems."/" = {
|
||||
device = "/dev/vda";
|
||||
fsType = "ext4";
|
||||
};
|
||||
}
|
||||
@@ -4,5 +4,13 @@
|
||||
./storage.nix
|
||||
];
|
||||
|
||||
acme = {
|
||||
enable = true;
|
||||
useSelfDns = true;
|
||||
};
|
||||
|
||||
dns.enable = true;
|
||||
networking.fqdn = "tuxcord.net";
|
||||
|
||||
time.timeZone = "Canada/Eastern";
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
device = "/dev/xvda2";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@persist" ] ++ defaultOptions;
|
||||
neededForBoot = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
imports = [
|
||||
./storage.nix
|
||||
];
|
||||
|
||||
networking.fqdn = "tuxcord.test";
|
||||
|
||||
acme.enable = false;
|
||||
dns.enable = true;
|
||||
|
||||
services.getty.autologinUser = "root";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
fileSystems."/" = {
|
||||
device = "/dev/vda";
|
||||
fsType = "ext4";
|
||||
};
|
||||
}
|
||||
@@ -55,8 +55,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
fileSystems."/persist".neededForBoot = true;
|
||||
|
||||
environment.persistence."/persist" = {
|
||||
enable = true;
|
||||
hideMounts = true;
|
||||
@@ -72,10 +70,6 @@
|
||||
];
|
||||
files = [
|
||||
"/etc/machine-id"
|
||||
"/etc/ssh/ssh_host_ed25519_key"
|
||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
||||
"/etc/ssh/ssh_host_rsa_key"
|
||||
"/etc/ssh/ssh_host_rsa_key.pub"
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.acme;
|
||||
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkEnableOption
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
inherit (config.networking) fqdn;
|
||||
in
|
||||
{
|
||||
# we'll only support rfc2136 based challenges
|
||||
options.acme = {
|
||||
enable = mkEnableOption "" // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
useSelfDns = mkOption {
|
||||
default = false;
|
||||
description = "Sets values of the self DNS if enabled, otherwise requires manual `rfc2136` nameserver and key values.";
|
||||
};
|
||||
|
||||
rfc2136 = {
|
||||
key = mkOption {
|
||||
type = types.path;
|
||||
default = config.age.secrets."dns/${fqdn}.key.age".path;
|
||||
};
|
||||
|
||||
nameserver = mkOption {
|
||||
type = types.str;
|
||||
default = if cfg.useSelfDns then fqdn else null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = with cfg.rfc2136; nameserver != null && key != null;
|
||||
message = "ACME needs rfc2136 parameters to work, consider using `useSelfDns` option.";
|
||||
}
|
||||
];
|
||||
|
||||
environment.persistence."/persist".directories = [
|
||||
{
|
||||
directory = "/var/lib/acme";
|
||||
group = "acme";
|
||||
user = "acme";
|
||||
}
|
||||
];
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
|
||||
defaults = {
|
||||
email = "error@tuxcord.net";
|
||||
reloadServices = [ "nginx" ];
|
||||
postRun = ''
|
||||
source ${config.age.secrets.ntfy.path}
|
||||
${pkgs.ntfy-sh}/bin/ntfy publish -T recycle -t "${config.host.name}" "HTTPS certificate has been renewed"
|
||||
'';
|
||||
};
|
||||
|
||||
certs."${fqdn}" = {
|
||||
dnsProvider = "rfc2136";
|
||||
environmentFile =
|
||||
with cfg.rfc2136;
|
||||
builtins.toFile "dns-01-challenge.cfg" ''
|
||||
RFC2136_NAMESERVER=${nameserver}
|
||||
RFC2136_TSIG_FILE="${key}"
|
||||
'';
|
||||
extraDomainNames = [
|
||||
"*.${fqdn}"
|
||||
"${fqdn}"
|
||||
];
|
||||
|
||||
inherit (config.services.nginx) group;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{ config, self, ... }:
|
||||
let
|
||||
inherit (config.networking) fqdn;
|
||||
in
|
||||
{
|
||||
age.secrets.authentik.file = "${self}/agenix/authentik.age";
|
||||
|
||||
services.authentik = {
|
||||
enable = true;
|
||||
environmentFile = config.age.secrets.authentik.path; # just trust, this specifies port 3001
|
||||
# nginx = {
|
||||
# enable = true;
|
||||
# enableACME = true;
|
||||
# host = "auth.${fqdn}";
|
||||
# };
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
{
|
||||
imports = [
|
||||
./acme.nix
|
||||
./authentik.nix
|
||||
./dns.nix
|
||||
./fail2ban.nix
|
||||
./sysctl.nix
|
||||
./gitea.nix
|
||||
./host.nix
|
||||
./nginx.nix
|
||||
./snapper.nix
|
||||
./substituters.nix
|
||||
./sysctl.nix
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.dns;
|
||||
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkIf
|
||||
strings
|
||||
;
|
||||
|
||||
inherit (config.networking) fqdn;
|
||||
|
||||
agenixDnsDir = "${self}/agenix/dns/${fqdn}";
|
||||
agenixKeys = builtins.attrNames (builtins.readDir agenixDnsDir);
|
||||
|
||||
keys = map (
|
||||
filename:
|
||||
let
|
||||
zonesub = _: "zonesub";
|
||||
subdomain = name: "subdomain ${name}";
|
||||
|
||||
zoneDomain =
|
||||
if strings.hasSuffix ".key.age" filename then
|
||||
strings.removeSuffix ".key.age" filename
|
||||
else
|
||||
throw "${filename} is not a `.key.age` file";
|
||||
in
|
||||
{
|
||||
inherit (config.age.secrets."dns/${filename}") path;
|
||||
name = zoneDomain;
|
||||
type = if zoneDomain == fqdn then zonesub else subdomain;
|
||||
}
|
||||
) agenixKeys;
|
||||
in
|
||||
{
|
||||
options.dns = {
|
||||
enable = mkEnableOption "" // {
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
age.secrets = builtins.listToAttrs (
|
||||
map (
|
||||
filename:
|
||||
let
|
||||
path = "${agenixDnsDir}/${filename}";
|
||||
in
|
||||
{
|
||||
name = "dns/${filename}";
|
||||
value = {
|
||||
file = path;
|
||||
group = "named";
|
||||
owner = if config.acme.enable then "acme" else "named";
|
||||
mode = "440";
|
||||
};
|
||||
}
|
||||
) agenixKeys
|
||||
);
|
||||
|
||||
services.bind = {
|
||||
enable = true;
|
||||
|
||||
extraConfig = builtins.concatStringsSep "\n" (map (key: "include \"${key.path}\";") keys);
|
||||
|
||||
zones."${fqdn}" = {
|
||||
# grant "tuxcord.net" zonesub ANY;
|
||||
extraConfig = ''
|
||||
update-policy {
|
||||
${builtins.concatStringsSep "\n" (
|
||||
map (key: "grant \"${key.name}\" ${key.type key.name} ANY;") keys
|
||||
)}
|
||||
};
|
||||
'';
|
||||
file = "/var/dns/${fqdn}.zone"; # need to put default stuff
|
||||
master = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = [
|
||||
{
|
||||
directory = "/var/dns";
|
||||
group = "named";
|
||||
user = "named";
|
||||
}
|
||||
];
|
||||
|
||||
networking.firewall =
|
||||
let
|
||||
ports = [ config.services.bind.listenOnPort ];
|
||||
in
|
||||
{
|
||||
allowedTCPPorts = ports;
|
||||
allowedUDPPorts = ports;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{ config, ... }:
|
||||
let
|
||||
inherit (config.networking) fqdn;
|
||||
|
||||
acmeEnabled = config.acme.enable;
|
||||
in
|
||||
{
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
|
||||
appName = "TuxCord Gitea";
|
||||
database.type = "mysql";
|
||||
|
||||
lfs.enable = true;
|
||||
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = fqdn;
|
||||
ROOT_URL = "${if acmeEnabled then "https" else "http"}://${fqdn}/";
|
||||
HTTP_PORT = 3000;
|
||||
};
|
||||
|
||||
service = {
|
||||
DISABLE_REGISTRATION = true;
|
||||
REQUIRE_SIGNIN_VIEW = false;
|
||||
};
|
||||
|
||||
repository = {
|
||||
ENABLE_PUSH_CREATE_USER = true;
|
||||
ENABLE_PUSH_CREATE_ORG = true;
|
||||
DEFAULT_BRANCH = "main";
|
||||
};
|
||||
|
||||
# ui.DEFAULT_THEME = "...";
|
||||
|
||||
# TODO: once we have email setup this would be nice
|
||||
mailer.ENABLED = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
{ config, self, ... }:
|
||||
let
|
||||
inherit (config.networking) fqdn;
|
||||
|
||||
mkVhost =
|
||||
attrs: locations:
|
||||
let
|
||||
acmeEnabled = config.acme.enable;
|
||||
in
|
||||
{
|
||||
forceSSL = acmeEnabled;
|
||||
useACMEHost = if acmeEnabled then fqdn else null;
|
||||
|
||||
locations = {
|
||||
"= /robots.txt" = {
|
||||
alias = disallowedRobotsTxt;
|
||||
};
|
||||
}
|
||||
// locations;
|
||||
}
|
||||
// attrs;
|
||||
|
||||
mkProxy = port: {
|
||||
proxyPass = "http://127.0.0.1:${toString port}/";
|
||||
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
'';
|
||||
};
|
||||
|
||||
mkSsi = webRoot: {
|
||||
root = webRoot;
|
||||
|
||||
extraConfig = ''
|
||||
ssi on;
|
||||
'';
|
||||
};
|
||||
|
||||
disallowedRobotsTxt = builtins.toFile "robots.txt" ''
|
||||
User-agent: *
|
||||
Disallow: /
|
||||
'';
|
||||
in
|
||||
{
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
|
||||
virtualHosts = {
|
||||
"${fqdn}" = mkVhost { default = true; } {
|
||||
"/" = mkSsi "${self.pins.website}/web-root";
|
||||
};
|
||||
|
||||
"git.${fqdn}" = mkVhost { } {
|
||||
"/" = mkProxy config.services.gitea.settings.server.HTTP_PORT;
|
||||
};
|
||||
|
||||
"auth.${fqdn}" = mkVhost { } {
|
||||
"/" = mkProxy 3001;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
];
|
||||
}
|
||||
+3
-4
@@ -1,17 +1,16 @@
|
||||
{ self, ... }:
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
ClientAliveInterval = 300;
|
||||
X11Forwarding = true;
|
||||
|
||||
KbdInteractiveAuthentication = false;
|
||||
PasswordAuthentication = false;
|
||||
PermitRootLogin = "no";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys = builtins.attrValues {
|
||||
inherit (import "${self}/lib/ssh/keys.nix") error javalsai;
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 22 ];
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ in
|
||||
environment.systemPackages = with pkgs; [
|
||||
atop
|
||||
bat
|
||||
bind
|
||||
btdu
|
||||
btop
|
||||
compsize
|
||||
|
||||
+26
-32
@@ -1,22 +1,6 @@
|
||||
{ lib, self, ... }:
|
||||
let
|
||||
users = [
|
||||
{
|
||||
name = "error";
|
||||
options.admin = true;
|
||||
}
|
||||
{
|
||||
name = "javalsai";
|
||||
options.admin = true;
|
||||
}
|
||||
{
|
||||
name = "max";
|
||||
options.admin = true;
|
||||
}
|
||||
{
|
||||
name = "vectorum";
|
||||
}
|
||||
];
|
||||
inherit (self.lib) users;
|
||||
|
||||
adminGroups = [
|
||||
"adm"
|
||||
@@ -27,20 +11,12 @@ let
|
||||
"wheel"
|
||||
];
|
||||
|
||||
mkUser = name: uid: options: {
|
||||
mkUser = name: uid: admin: {
|
||||
users.users.${name} = {
|
||||
isNormalUser = true;
|
||||
extraGroups = lib.optionals (options.admin or false) adminGroups;
|
||||
inherit uid;
|
||||
|
||||
openssh.authorizedKeys.keys =
|
||||
let
|
||||
keys = import "${self}/lib/ssh/keys.nix";
|
||||
in
|
||||
if (builtins.hasAttr name keys) then
|
||||
[ keys.${name} ]
|
||||
else
|
||||
lib.warn "user ${name} declared without ssh key" [ ];
|
||||
isNormalUser = true;
|
||||
extraGroups = lib.optionals admin adminGroups;
|
||||
openssh.authorizedKeys.keys = self.lib.getSSHKeys name;
|
||||
};
|
||||
|
||||
systemd.slices."user-${builtins.toString uid}".sliceConfig = {
|
||||
@@ -57,15 +33,33 @@ in
|
||||
lib.recursiveUpdate
|
||||
(builtins.foldl'
|
||||
(attrs: user: {
|
||||
options = lib.recursiveUpdate attrs.options (mkUser user.name attrs.uid (user.options or { }));
|
||||
options = lib.recursiveUpdate attrs.options (
|
||||
mkUser user.name attrs.uid (user.value.admin or false)
|
||||
);
|
||||
uid = attrs.uid + 1;
|
||||
})
|
||||
{
|
||||
options = { };
|
||||
uid = 1000;
|
||||
}
|
||||
users
|
||||
(lib.attrsToList users)
|
||||
).options
|
||||
{
|
||||
users.users.root.initialPassword = "tuxcord";
|
||||
users = {
|
||||
motd = ''
|
||||
__ __ __
|
||||
---------/\ \__ /\ \ /\ \__
|
||||
---------\ \ ,_\ __ __ __ _ ___ ___ _ __ \_\ \ ___ __\ \ ,_\
|
||||
----------\ \ \/ /\ \/\ \/\ \/'\ /'___\ / __`\/\`'__\/'_` \ /'_ `\ /'__`\ \ \/
|
||||
-----------\ \ \_\ \ \_\ \/> <//\ \__//\ \L\ \ \ \//\ \L\ \ __/\ \/\ \/\ __/\ \ \_
|
||||
------------\ \__\\ \____//\_/\_\ \____\ \____/\ \_\\ \___,_\/\_\ \_\ \_\ \____\\ \__\
|
||||
-------------\/__/ \/___/ \//\/_/\/____/\/___/ \/_/ \/__,_ /\/_/\/_/\/_/\/____/ \/__/
|
||||
A friendly Linux community - est. July 2023
|
||||
'';
|
||||
|
||||
users.root = {
|
||||
initialPassword = "tuxcord";
|
||||
openssh.authorizedKeys.keys = self.lib.adminSSHKeys;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
virtualisation.vmVariant.virtualisation = {
|
||||
cores = 2;
|
||||
diskSize = 8192;
|
||||
graphics = false;
|
||||
memorySize = 4096;
|
||||
|
||||
qemu.networkingOptions = lib.mkForce [
|
||||
"-nic bridge,br=virbr0,id=hn0,model=virt-net-pci,helper=\${QEMU_BRIDGE_HELPER_PATH}"
|
||||
"-device virtio-net-pci,netdev=hn0,id=nic1,\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
This file is provided under the MIT licence:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
# Generated by npins. Do not modify; will be overwritten regularly
|
||||
let
|
||||
data = builtins.fromJSON (builtins.readFile ./sources.json);
|
||||
version = data.version;
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
|
||||
range =
|
||||
first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1);
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
|
||||
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
|
||||
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
|
||||
concatMapStrings = f: list: concatStrings (map f list);
|
||||
concatStrings = builtins.concatStringsSep "";
|
||||
|
||||
# If the environment variable NPINS_OVERRIDE_${name} is set, then use
|
||||
# the path directly as opposed to the fetched source.
|
||||
# (Taken from Niv for compatibility)
|
||||
mayOverride =
|
||||
name: path:
|
||||
let
|
||||
envVarName = "NPINS_OVERRIDE_${saneName}";
|
||||
saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name;
|
||||
ersatz = builtins.getEnv envVarName;
|
||||
in
|
||||
if ersatz == "" then
|
||||
path
|
||||
else
|
||||
# this turns the string into an actual Nix path (for both absolute and
|
||||
# relative paths)
|
||||
builtins.trace "Overriding path of \"${name}\" with \"${ersatz}\" due to set \"${envVarName}\"" (
|
||||
if builtins.substring 0 1 ersatz == "/" then
|
||||
/. + ersatz
|
||||
else
|
||||
/. + builtins.getEnv "PWD" + "/${ersatz}"
|
||||
);
|
||||
|
||||
mkSource =
|
||||
name: spec:
|
||||
assert spec ? type;
|
||||
let
|
||||
path =
|
||||
if spec.type == "Git" then
|
||||
mkGitSource spec
|
||||
else if spec.type == "GitRelease" then
|
||||
mkGitSource spec
|
||||
else if spec.type == "PyPi" then
|
||||
mkPyPiSource spec
|
||||
else if spec.type == "Channel" then
|
||||
mkChannelSource spec
|
||||
else if spec.type == "Tarball" then
|
||||
mkTarballSource spec
|
||||
else
|
||||
builtins.throw "Unknown source type ${spec.type}";
|
||||
in
|
||||
spec // { outPath = mayOverride name path; };
|
||||
|
||||
mkGitSource =
|
||||
{
|
||||
repository,
|
||||
revision,
|
||||
url ? null,
|
||||
submodules,
|
||||
hash,
|
||||
branch ? null,
|
||||
...
|
||||
}:
|
||||
assert repository ? type;
|
||||
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
|
||||
# In the latter case, there we will always be an url to the tarball
|
||||
if url != null && !submodules then
|
||||
builtins.fetchTarball {
|
||||
inherit url;
|
||||
sha256 = hash; # FIXME: check nix version & use SRI hashes
|
||||
}
|
||||
else
|
||||
let
|
||||
url =
|
||||
if repository.type == "Git" then
|
||||
repository.url
|
||||
else if repository.type == "GitHub" then
|
||||
"https://github.com/${repository.owner}/${repository.repo}.git"
|
||||
else if repository.type == "GitLab" then
|
||||
"${repository.server}/${repository.repo_path}.git"
|
||||
else
|
||||
throw "Unrecognized repository type ${repository.type}";
|
||||
urlToName =
|
||||
url: rev:
|
||||
let
|
||||
matched = builtins.match "^.*/([^/]*)(\\.git)?$" url;
|
||||
|
||||
short = builtins.substring 0 7 rev;
|
||||
|
||||
appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else "";
|
||||
in
|
||||
"${if matched == null then "source" else builtins.head matched}${appendShort}";
|
||||
name = urlToName url revision;
|
||||
in
|
||||
builtins.fetchGit {
|
||||
rev = revision;
|
||||
inherit name;
|
||||
# hash = hash;
|
||||
inherit url submodules;
|
||||
};
|
||||
|
||||
mkPyPiSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchurl {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
mkChannelSource =
|
||||
{ url, hash, ... }:
|
||||
builtins.fetchTarball {
|
||||
inherit url;
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
mkTarballSource =
|
||||
{
|
||||
url,
|
||||
locked_url ? url,
|
||||
hash,
|
||||
...
|
||||
}:
|
||||
builtins.fetchTarball {
|
||||
url = locked_url;
|
||||
sha256 = hash;
|
||||
};
|
||||
in
|
||||
if version == 5 then
|
||||
builtins.mapAttrs mkSource data.pins
|
||||
else
|
||||
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"pins": {
|
||||
"website": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
"type": "Git",
|
||||
"url": "https://git.javalsai.tuxcord.net/tuxcord/website.git"
|
||||
},
|
||||
"branch": "main",
|
||||
"submodules": false,
|
||||
"revision": "b18dd7b863644debb0a843a5b21bb490bfe7d048",
|
||||
"url": null,
|
||||
"hash": "18czfxaldy0zhjprdsqzxnzj3p9qlc4canwigr13iw2wisi4ww5y"
|
||||
}
|
||||
},
|
||||
"version": 5
|
||||
}
|
||||
+18
-1
@@ -5,6 +5,24 @@
|
||||
{
|
||||
devShells.default = pkgs.mkShell {
|
||||
name = "configuration.nix";
|
||||
|
||||
shellHook = ''
|
||||
for path in \
|
||||
/usr/lib/qemu/qemu-bridge-helper \
|
||||
/run/wrappers/bin/qemu-bridge-helper
|
||||
do
|
||||
if [ -x "$path" ]; then
|
||||
export QEMU_BRIDGE_HELPER_PATH="$path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$QEMU_BRIDGE_HELPER_PATH" ]; then
|
||||
printf "\033[1;33m%s\033[0m\n" \
|
||||
"WARN: 'qemu-bridge-helper' not found, make sure it is installed and the nix shell hook is looking for it" >&2
|
||||
fi
|
||||
'';
|
||||
|
||||
packages = with pkgs; [
|
||||
bat
|
||||
cachix
|
||||
@@ -13,7 +31,6 @@
|
||||
git
|
||||
inputs.agenix.packages.${stdenv.hostPlatform.system}.default
|
||||
jujutsu
|
||||
neovim
|
||||
nix-output-monitor
|
||||
nixfmt
|
||||
npins
|
||||
|
||||
Reference in New Issue
Block a user