Compare commits
860 commits
add_automx
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
b1dc47c5cb | ||
|
3c5a3dc84a | ||
|
f34d3c10cb | ||
|
8b86b74dc6 | ||
|
cd346bb6be | ||
|
32ed44a559 | ||
|
872ccfe62d | ||
249addc5be | |||
|
111c77aa61 | ||
|
f92fea1224 | ||
|
2d9a3cbd11 | ||
70a83bd97b | |||
e012fdf3a7 | |||
|
e478af71a1 | ||
a1c9125397 | |||
67c3787d2e | |||
7799bda982 | |||
af1535b7dc | |||
19a0b8044f | |||
2728487448 | |||
13eba34a56 | |||
1baeb24761 | |||
|
b2297e2843 | ||
|
4f4431cd6d | ||
8c98281eff | |||
45afc95d99 | |||
49d69b1a10 | |||
cb2fba3f81 | |||
6d2a13cf03 | |||
97a062180e | |||
be75fcb296 | |||
50fc679172 | |||
45e9d60967 | |||
59855b06e3 | |||
6d4160fe65 | |||
ff6af9916d | |||
2c196ae87e | |||
c648bded74 | |||
8a85846c0d | |||
5448662230 | |||
50459f7982 | |||
|
c114f31d2e | ||
|
74a3f11f9b | ||
|
87383ccaae | ||
9a8b446497 | |||
2fc07e49aa | |||
|
cd10457035 | ||
|
8e48b61473 | ||
86efe11f83 | |||
1fcfc78c6b | |||
91d76c08f1 | |||
0b0db08f01 | |||
5c5ea3678d | |||
a4be5de575 | |||
ad9e434a28 | |||
51d8a84432 | |||
259a6df8a7 | |||
|
c0aa5c138d | ||
|
e1a3a64a8d | ||
|
542ee2858e | ||
|
df6825cb7e | ||
|
335f2f08f1 | ||
|
d47abf2527 | ||
|
8275f3063b | ||
|
d76d5acbb7 | ||
|
be4f8dbe89 | ||
|
71d6d7555b | ||
|
14334cbee4 | ||
|
181a78286e | ||
|
a6a368457a | ||
|
7eb83514ca | ||
|
743f6faa44 | ||
95e9b971b2 | |||
|
13e9552799 | ||
|
6831976805 | ||
|
103bd93772 | ||
|
8725a9af9d | ||
|
668dd90358 | ||
|
b215f10513 | ||
|
0907c36e18 | ||
|
fdebdb6cc5 | ||
|
839009195a | ||
|
951a72d0a6 | ||
|
5d72d1aa84 | ||
|
5eeda983eb | ||
|
5012dd992f | ||
|
2e06a80dfc | ||
|
65d4a91fa4 | ||
2bcdfb0f83 | |||
8c828738ca | |||
|
7c8d9641b5 | ||
|
97ca87ec11 | ||
|
c692663e0e | ||
|
37c564be74 | ||
|
fdd2c24bbd | ||
|
5d6aec46de | ||
|
32d534be45 | ||
31e7cca4ed | |||
7dcbf88fa4 | |||
|
4b2720df36 | ||
|
5fa1bbd818 | ||
|
a050b6ced7 | ||
38e0322f67 | |||
|
31dc474c84 | ||
|
3347ac8a89 | ||
|
9143fdc77c | ||
|
11d4c2269c | ||
|
4196934565 | ||
35b12b57aa | |||
6c9a852e78 | |||
ddf5a22d8b | |||
287b268161 | |||
|
31c94bc8d2 | ||
|
34ffe6c37f | ||
|
884617ddb7 | ||
|
39fd65d467 | ||
|
ac7db8f099 | ||
99b2ba1477 | |||
36e9e6b76d | |||
|
97d750ac66 | ||
fc78bb7287 | |||
5d93ffb71f | |||
41dd05cd36 | |||
350f4266ed | |||
aefd9bbdb0 | |||
|
598ae73b3e | ||
bf939cc941 | |||
|
4688eec153 | ||
961a35b990 | |||
987db0c6aa | |||
|
6ce2a6337f | ||
deb43c0768 | |||
|
6c9df12566 | ||
|
fb1ef7b66b | ||
75740f9bae | |||
6376e910f1 | |||
|
8e57469ee2 | ||
|
1638e44caa | ||
58800bf7b2 | |||
|
68d5a91b0b | ||
a7b559972b | |||
|
39be11301a | ||
afa3515cd8 | |||
0e5990e563 | |||
|
8302b216e0 | ||
|
9a67dfee37 | ||
|
3997805406 | ||
2d95094fbd | |||
|
692ed8e3f0 | ||
|
04944584c6 | ||
fbff2a4ab2 | |||
|
de72894701 | ||
|
5cdcd97f6b | ||
|
25c4007e3e | ||
|
fea5ec177e | ||
|
f49bf144ae | ||
|
e76262aa43 | ||
|
20f0c16e2f | ||
9c6844fed2 | |||
f61b9c8d6d | |||
|
62115a3d93 | ||
0e7048be31 | |||
c2ace73a9b | |||
9120a81d6b | |||
186833f70c | |||
|
31f54b1e92 | ||
5a21783b63 | |||
529b0e13ec | |||
410017d86f | |||
1fb4318310 | |||
f00ae5bd2d | |||
97d1783561 | |||
98136e802b | |||
86e0c091fb | |||
4f87e56d63 | |||
cd002aec03 | |||
9c7d08c153 | |||
35920eda0c | |||
ba527ead3b | |||
1212ecc7a1 | |||
bbcc8fc1f6 | |||
ba6d831f73 | |||
bd96a84fe8 | |||
d64997991d | |||
537863c913 | |||
ed4dcbc756 | |||
5c6939bc83 | |||
2834fbba8d | |||
c5a651d98e | |||
648b437767 | |||
a4d83fde50 | |||
2a949f8e82 | |||
abdc5b6d50 | |||
c5c44acc8b | |||
1287160cdf | |||
4c8ebb455e | |||
454e58b085 | |||
2a8a7cc7f4 | |||
0b25b5ac54 | |||
356ac2e505 | |||
1a07781c4d | |||
15e534c222 | |||
e9d5985adf | |||
cb0cfbaf4a | |||
b1bd6ca40a | |||
9fb45cba7e | |||
3837ff2dd1 | |||
b6b9ae0579 | |||
|
b7cb7eeade | ||
2a45bc4f70 | |||
e6954d3448 | |||
09e7f8f0d4 | |||
dac45073d6 | |||
9583eaa9be | |||
a0215b2271 | |||
cd13520aba | |||
8009b7c8d1 | |||
|
07cb42dd65 | ||
6229abcefa | |||
|
c197f0df85 | ||
435379e610 | |||
44c81b1f3e | |||
897c52cc3e | |||
7ea813667b | |||
d226e905a2 | |||
40ece2f683 | |||
9b84ff8619 | |||
|
5933cb5dfe | ||
|
c0ddc2d6a9 | ||
9e90553a6b | |||
|
e0a461bb0a | ||
ed331c3f08 | |||
452f33baa8 | |||
|
149b58ce09 | ||
|
1b848029e2 | ||
|
d3030aa2d1 | ||
5c33399d97 | |||
1d3549d541 | |||
5c8dcdef00 | |||
34f8f0eb8c | |||
fee1e34ca8 | |||
69bd2be07c | |||
4b9a743e40 | |||
|
8c96241b67 | ||
672ad2b96e | |||
ce820a5d3c | |||
e94683c3d5 | |||
3d6a1ba696 | |||
8c7f2b5454 | |||
5ba92dcbc1 | |||
7d8833a451 | |||
|
37bfebec20 | ||
|
62fe4a2ba5 | ||
|
b7a5042538 | ||
a156d1ba1e | |||
|
b2ecb14f68 | ||
|
c4e3a41831 | ||
dbf7a4d5d1 | |||
|
991758ef46 | ||
8d60c67722 | |||
cbc5af9b53 | |||
1fb2bba4ce | |||
62d28bab4e | |||
9316caa559 | |||
be9f5084eb | |||
689344e518 | |||
379cb84839 | |||
f8c7860eb5 | |||
54b43c9962 | |||
e156b4ecaf | |||
73a9419798 | |||
449ada5cec | |||
023b491d89 | |||
75f0a17fcb | |||
9eafd6f53e | |||
|
c71b3571ce | ||
a6b070a971 | |||
e7e5d554b2 | |||
f55d23e821 | |||
b545c623d2 | |||
44750155f1 | |||
694cbb2f0b | |||
|
c0816ccce4 | ||
|
889bb0dab6 | ||
f7dd90e92b | |||
147bd86ad5 | |||
|
963a189bcb | ||
9148963c1f | |||
b8c6e153a4 | |||
15271c1d09 | |||
62ead11aad | |||
aba1a41d4d | |||
0f75f11918 | |||
|
03ae1c5101 | ||
|
061453e5d1 | ||
23f77caef6 | |||
|
40e4fe5ac4 | ||
|
fd3beade9b | ||
|
9aeb7313b4 | ||
|
1ea703bfa1 | ||
|
113084148c | ||
|
ca87227571 | ||
|
9b3e7265dd | ||
|
82305d43ff | ||
|
be56e6b9e9 | ||
|
cf600e2dc1 | ||
|
7f5f21dc8a | ||
|
4637777e5c | ||
|
183f5a0e7d | ||
50abdb90ab | |||
|
4ce0f69fb3 | ||
|
2a605151f8 | ||
|
739529caae | ||
|
961509ddc8 | ||
|
70b1d6324d | ||
|
115535c386 | ||
|
519e907278 | ||
867e7a702f | |||
|
1b31b6535d | ||
|
eee9632878 | ||
|
44a7fde53c | ||
63874105a8 | |||
5bf1ddbebe | |||
7408873102 | |||
6ae584c895 | |||
cb6f9c2b8e | |||
|
aec580a93e | ||
210845d2cd | |||
ebefd81def | |||
48e48c43c7 | |||
54606be0df | |||
a4c52ea87c | |||
|
2b09716c4d | ||
|
b1d7c15a4d | ||
|
d48e68d3b3 | ||
|
d73be0c8d3 | ||
|
25f687cacf | ||
|
05ab8b0238 | ||
|
7cd4f9288b | ||
|
57a16a2c8f | ||
|
b343009682 | ||
da721924e4 | |||
|
106485a754 | ||
7e2abcae5b | |||
1197c50962 | |||
f0661ba00f | |||
|
9a4ea6b9fb | ||
4575aabcb2 | |||
54ef36023a | |||
|
04a0a21ac7 | ||
|
ac721c2540 | ||
|
7b3b3b290c | ||
|
fcff34e225 | ||
1790a12360 | |||
|
7031b49599 | ||
90d8a105f7 | |||
a42ac52f9d | |||
|
44f123289f | ||
|
4314d00322 | ||
|
90ac5f41ef | ||
|
d971c2e855 | ||
|
34156ba71f | ||
|
2fcf1f19d8 | ||
|
e77d9e51e8 | ||
|
22cb1bcbd4 | ||
d3e635f2c1 | |||
|
b6ecd5255d | ||
19d94808ed | |||
|
cde7f37455 | ||
|
fa7cbd420e | ||
|
ec254fd6fe | ||
|
b526150547 | ||
|
98886d724d | ||
138fd31a6e | |||
5aca8874b3 | |||
93211d09cc | |||
9932efe593 | |||
a0bb8b479e | |||
5ced7f4fe4 | |||
8d94f0c965 | |||
40f33f28aa | |||
|
7ed840e204 | ||
|
8f60f9dea0 | ||
26e715b2f6 | |||
|
2c3e87b4d8 | ||
|
7ccc78c5bd | ||
6de8f1e963 | |||
ded0dc5394 | |||
2acaf29f63 | |||
|
3c6250f54b | ||
|
e8637b1f39 | ||
6b0507a647 | |||
39594e5973 | |||
46cae94f99 | |||
589ae332e6 | |||
6f9d30cb87 | |||
a7231e0d6d | |||
16bae0bf8f | |||
e7d47fa873 | |||
215ba411fb | |||
c8260ad05e | |||
24018b5400 | |||
ccf090b841 | |||
80c6fac51a | |||
5a9ee7e106 | |||
a355bc81c6 | |||
bb44a38bbb | |||
73330b3f6f | |||
c9d7598827 | |||
2b6e629d30 | |||
c86556bff4 | |||
|
0860c2fde2 | ||
|
575d8dce3c | ||
|
dbfcd6d86a | ||
|
556f3fcd14 | ||
e96ec3023f | |||
fc78cfd83f | |||
5900c41ab7 | |||
a19d1cc915 | |||
c84951252f | |||
08144baa42 | |||
1057bae86e | |||
225033130c | |||
e67595a7c4 | |||
8fecc941c7 | |||
f116c3fb25 | |||
4bcaaa25d7 | |||
61adbabe78 | |||
0fc2b7ee6a | |||
07601f708c | |||
|
f5dcdf7547 | ||
54529e0d21 | |||
351f6b22da | |||
|
f1782633cd | ||
|
9c85fbbc00 | ||
|
bb2a014b29 | ||
440ad7d209 | |||
02dd11c8b4 | |||
7c4e83f60a | |||
93c21d3093 | |||
ca9e1871cc | |||
a8f6c1e80e | |||
1e8b5a3930 | |||
82c0c4ae42 | |||
8e0ec53740 | |||
8d43055ddf | |||
de69ca69c9 | |||
600d1f755f | |||
|
7877cef87c | ||
|
9c30567885 | ||
|
1db618bb80 | ||
a1be738883 | |||
20f9a38aed | |||
03add8f999 | |||
21612fed13 | |||
56bdcb3af8 | |||
56fdff7571 | |||
|
fee6f37fb7 | ||
0a028eaf53 | |||
cbb4100b4e | |||
e42f718ba5 | |||
2989cb5b72 | |||
03ae753b90 | |||
82b0b4aff4 | |||
4c0f3a1645 | |||
4a95e48179 | |||
6ea0240a3a | |||
35f6d63c10 | |||
e810bca085 | |||
09fb8cf56e | |||
c27f1749a2 | |||
29dc2750ae | |||
|
7673bb3fb2 | ||
c53e7ffcf2 | |||
54f54d31b1 | |||
8bb2c26a99 | |||
|
5877f1143c | ||
|
a87c4adf2b | ||
00d3783919 | |||
ac375549d4 | |||
|
4235084eab | ||
|
18086dfba2 | ||
|
4554055518 | ||
f42b5a6359 | |||
9c90aa856a | |||
8e1eb5c192 | |||
2a6e63fcea | |||
8a37a3c42e | |||
a305a1f744 | |||
feb492c0c7 | |||
1dc8e1109d | |||
b1c679c73f | |||
011bc91795 | |||
eebf1845cb | |||
0a89ac4526 | |||
|
64d1054067 | ||
|
f2811f2e04 | ||
|
df46133fca | ||
633f5b4525 | |||
422ee6b2c8 | |||
211050fc27 | |||
a5bf6df79a | |||
b8b7f09b9f | |||
7f64767991 | |||
|
2dcae4df6d | ||
587fb4053a | |||
bb346e294f | |||
|
91f7fec824 | ||
|
e7d1854de4 | ||
d2ece41ace | |||
827b109a25 | |||
53dd24bd1b | |||
13eeead354 | |||
ec3451d2c7 | |||
e1f8d580c7 | |||
badcce6e38 | |||
52e4442226 | |||
263570154f | |||
|
d87a7dcdfe | ||
83b7a142bc | |||
e03e27c894 | |||
9fd4613936 | |||
|
cc99fb92ec | ||
15775a1b5d | |||
0472019016 | |||
|
7f22a9efa9 | ||
|
bb050d57fd | ||
c97ce628ee | |||
|
7edd86046b | ||
ff0ba0ef3a | |||
|
38d309a554 | ||
|
e375a6cbed | ||
|
0b03585a8e | ||
|
d141771f23 | ||
|
4407d37636 | ||
|
97fb80a4fb | ||
|
dd0e55c9d6 | ||
c7faf7734c | |||
1f0cf38c52 | |||
|
118e645b98 | ||
|
75a886b461 | ||
dd10b0f8cb | |||
abac7ef291 | |||
1e0a567bc4 | |||
bea98fc9fc | |||
19a7476278 | |||
487fb3f0bf | |||
|
e679f523fc | ||
d46d42cc48 | |||
fd1a70edc9 | |||
79fcefb378 | |||
34fe15863f | |||
|
6ce481fd2c | ||
|
c9b8f9b641 | ||
8ea737d57b | |||
9f94b5b551 | |||
ff4f0a37b3 | |||
bece34b65e | |||
78ab6de860 | |||
a242b1afcd | |||
|
f2007c1985 | ||
|
8d979dc7fc | ||
|
fcfd87c005 | ||
|
4c3df9ec96 | ||
|
3f38cb643e | ||
|
13a7534848 | ||
c85dfdd3b6 | |||
f7d5a4ec6e | |||
d309cf8b6f | |||
6ce3dc060f | |||
75c4695101 | |||
7e55b1210d | |||
667c335839 | |||
18155ec6e1 | |||
|
01fe89db25 | ||
fa422ce69c | |||
|
e347afcb39 | ||
ec28365122 | |||
510066fa1a | |||
c46e24bbfe | |||
88195b4628 | |||
a24f6ddb59 | |||
042c84c5cc | |||
3dca6add56 | |||
09ccf41717 | |||
2fc64d34b5 | |||
165c4645bf | |||
c87fec1a65 | |||
3860db8098 | |||
|
ad0462cb86 | ||
|
919584ec58 | ||
|
1ac3e52d8a | ||
|
d0751fa594 | ||
7ed6fdeb3b | |||
bd58a6d169 | |||
3e747c9408 | |||
d9664c34fd | |||
1c11038f48 | |||
4e244222ba | |||
54273175c7 | |||
68b7afce1e | |||
dd27f13a08 | |||
3c3a23b12e | |||
cdded657c0 | |||
344b70bf9f | |||
b77c265a12 | |||
70e867acd1 | |||
8c0d217b94 | |||
|
41b707c810 | ||
385059e7b7 | |||
48c271cf3f | |||
|
d8df11dcf1 | ||
|
5c47f15ce6 | ||
|
94baa0ec12 | ||
adb04543da | |||
|
19e325d345 | ||
|
bf2b29a1e4 | ||
|
6de8c15b48 | ||
37fd34358c | |||
de8382c7c9 | |||
f59370c821 | |||
|
7c53f58df9 | ||
|
2fdef2ab47 | ||
|
11d972e9b8 | ||
6c0fe58147 | |||
|
02bbdca372 | ||
|
d54c1551f5 | ||
|
2cbbd35eb6 | ||
|
726d41f4f8 | ||
1de744dbee | |||
04e0712155 | |||
|
3599ea0e24 | ||
|
e7a6beffde | ||
|
0add8625b7 | ||
|
73ab341ad4 | ||
|
dbe7bc1511 | ||
|
22dd65b630 | ||
|
f37e0b6cdd | ||
|
deb13a31f9 | ||
6628eb89cd | |||
|
b75e6c6132 | ||
7f3dc8946e | |||
|
14ae0a9065 | ||
|
238beb19b9 | ||
9c63dac494 | |||
2501979541 | |||
|
4957e04786 | ||
a1b9ce3f2d | |||
|
7120cd09d1 | ||
28253d3527 | |||
|
6392375f61 | ||
22163528d9 | |||
9f42b60940 | |||
ef6096e6e0 | |||
7d7f402b6d | |||
5acbd12960 | |||
efe1fbd140 | |||
6673ba28b1 | |||
a5059e1c28 | |||
563d13e115 | |||
462164a82f | |||
|
61411c7845 | ||
|
edb2a0f40e | ||
|
c12f2920ac | ||
73e7406b37 | |||
4938aee412 | |||
c5c0df3f5e | |||
522efc92cc | |||
def8f46472 | |||
553d34c9cd | |||
|
a31c261224 | ||
|
03dfb4a908 | ||
12ceb2c137 | |||
039764b633 | |||
be4ab47ad8 | |||
bd35b240be | |||
bfc0d81cf1 | |||
|
e954dda3ae | ||
31d2d2e23d | |||
|
04e185a52c | ||
f8c900d66c | |||
|
df462f353e | ||
|
fc852678a4 | ||
|
4a3b319c45 | ||
|
855572e16a | ||
|
5bd3bd01a9 | ||
|
ab662018d8 | ||
|
fc9507ef2a | ||
|
0f1584bc09 | ||
|
16ebdc4665 | ||
|
fccf914f8c | ||
|
c010aadd51 | ||
|
cd4cbe4265 | ||
|
1b28c73406 | ||
7cfd4e22f5 | |||
|
70600857a6 | ||
aeb10f0565 | |||
07474625ba | |||
a8ec66b50d | |||
a395f94aa3 | |||
b7e8718f70 | |||
|
ee4468c03d | ||
12e25162ee | |||
77124de48d | |||
8fb7579b78 | |||
2cb6e26d89 | |||
0bc8e16d87 | |||
b40bb11e4c | |||
cd656549b9 | |||
a2d16e60f4 | |||
fa13fc1397 | |||
a3e8d80c50 | |||
c1573134ea | |||
1b6dd39e71 | |||
e53050aa11 | |||
e9941ddfdd | |||
51c9761380 | |||
8a2c97ab2c | |||
8e489c1616 | |||
d630c72488 | |||
d5b96daa2c | |||
b0d7c51736 | |||
7654485a6d | |||
e9a266e367 | |||
834ec7cf94 | |||
|
a0892b834f | ||
|
53abdb700b | ||
|
f168f1eb8d | ||
|
b383536bbb | ||
a55e963a6f | |||
|
5c62e7ede5 | ||
29c9a6b9af | |||
abdeb5e83e | |||
d4ce54e1eb | |||
33412e4986 | |||
5c41e05c80 | |||
|
2c5c3094f8 | ||
fbb0824627 | |||
19b342b987 | |||
3239516270 | |||
4251032e03 | |||
89dcf295b3 | |||
|
5739518f82 | ||
62689132d3 | |||
ea81827375 | |||
7554003bed | |||
546a6f5cd3 | |||
3521bface9 | |||
2ae70acf56 | |||
abc355d1b6 | |||
cebdb0967d | |||
161b879b5f | |||
6f7f477d01 | |||
acb49a2eb1 | |||
ce0155d6ab | |||
0315320074 | |||
|
4d87146c00 | ||
|
451b16769c | ||
|
d3fc63c870 | ||
|
2b109da1b7 | ||
|
8df24d1dc7 | ||
646a21f098 | |||
37f1f8c5d7 | |||
2ccadb9ae3 | |||
d4e8f11cf9 | |||
9cb9d242ed | |||
5de3b0dc9b | |||
|
7f58f206fe | ||
|
3e15f20b4c | ||
|
103f5337dc | ||
|
2c7ac5b011 | ||
|
d6e6033c22 | ||
0d778fb847 | |||
|
9c323af667 | ||
|
bb665b6bd2 | ||
|
bc00c1eb1e | ||
|
b92f0c87af | ||
|
278d00e6e8 | ||
|
3817eaffe6 | ||
|
3b5cc25012 | ||
|
57ec28c2c3 | ||
|
b1ab5b8c7f | ||
599f403149 | |||
|
d63f630cad | ||
|
6e55898ee3 | ||
|
8a996c9534 | ||
|
f23f0c2d54 | ||
|
092744e471 | ||
396a5e914b | |||
|
20d0b1215d | ||
|
6e70246f9d | ||
|
d282667bf3 | ||
|
71620ff892 | ||
90deec3940 | |||
|
f0bc3eea2e | ||
|
4458d02e60 | ||
|
1766536e56 | ||
|
b0603e18af | ||
|
7a35c8ebe4 | ||
|
7399c8ee85 | ||
759643b8db | |||
|
67edac3316 | ||
|
3be7966bf6 | ||
|
d2741c610d | ||
|
e4bd0da430 | ||
|
c3ab0c4cd9 | ||
7b2db16f08 | |||
806da010c9 | |||
dd4d8e3b00 | |||
3270d3edf4 | |||
b8bf6014cd | |||
|
f2d648a2d4 | ||
|
c74bbf5bbf | ||
|
8962dc3af8 | ||
|
3d30ecc111 | ||
|
e765fa4215 | ||
|
f10feb3882 | ||
|
6749eff73f | ||
|
4097690ca8 | ||
56a93ead8c | |||
47a7a0a7fc | |||
2ebbb2b649 | |||
206f59d0fd | |||
|
a9a286cb0e | ||
|
7772a0daee | ||
|
59c244483a | ||
|
53abaf8795 | ||
|
b67edafaaa | ||
|
1324fd22af | ||
|
402527ad1e | ||
|
aae2dfc84e | ||
|
b1c33296f3 | ||
|
9076334b5f | ||
|
cc55079cf0 | ||
|
7bc17513c4 | ||
|
e145e0bfc6 | ||
|
97af6c9d3c | ||
|
f084baf522 | ||
|
6b940f5693 | ||
|
bba0156cf8 | ||
|
ed3781473e | ||
|
37895e8e38 | ||
|
758ac94af4 | ||
|
945b43dddb | ||
|
dae9549064 | ||
|
55a42967fb | ||
3f2cbee15a | |||
|
283abf41ba | ||
15cd18e5e9 | |||
54e94336f4 | |||
6c19452c33 | |||
e8f9f14dc5 | |||
f4bc8ca6f4 | |||
ed6b61e13f | |||
3465f645b9 | |||
808fc9a2d9 | |||
2dce7a5259 | |||
a45759a086 | |||
9dfb22092e | |||
cd5161645c |
116 changed files with 6714 additions and 2399 deletions
59
.forgejo/workflows/deploy.yaml
Normal file
59
.forgejo/workflows/deploy.yaml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
name: Build_Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: [ "Update_Flake" ]
|
||||||
|
types:
|
||||||
|
- completed
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
paths:
|
||||||
|
- applications/**/*
|
||||||
|
- machines/**/*
|
||||||
|
- secrets/**/*
|
||||||
|
- flake.*
|
||||||
|
- config/**/*
|
||||||
|
- .forgejo/**/*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linter:
|
||||||
|
runs-on: nix
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: nix fmt -- --check .
|
||||||
|
- run: nix --version
|
||||||
|
|
||||||
|
#if: github.repository == 'Skynet/nixos'
|
||||||
|
build:
|
||||||
|
runs-on: nix
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: nix develop -v
|
||||||
|
# - name: Archive Test Results
|
||||||
|
# if: always()
|
||||||
|
# run: sleep 100m
|
||||||
|
# - run: colmena build -v --on @active-dns
|
||||||
|
# - run: colmena build -v --on @active-core
|
||||||
|
# - run: colmena build -v --on @active
|
||||||
|
# - run: colmena build -v --on @active-ext
|
||||||
|
# - run: colmena build -v --on @active-gitlab
|
||||||
|
|
||||||
|
deploy_dns:
|
||||||
|
runs-on: nix
|
||||||
|
needs: [ linter, build ]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: colmena apply -v --on @active-dns --show-trace
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
deploy_active:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
batch: [ active-core, active, active-ext ]
|
||||||
|
runs-on: nix
|
||||||
|
needs: [ deploy_dns ]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: colmena apply -v --on @${{ matrix.batch }} --show-trace
|
||||||
|
shell: bash
|
12
.forgejo/workflows/deploy_forgejo.yaml
Normal file
12
.forgejo/workflows/deploy_forgejo.yaml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
name: Update_Forgejo
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: nix
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: colmena apply -v --on @active-gitlab --show-trace
|
||||||
|
shell: bash
|
31
.forgejo/workflows/update_input.yaml
Normal file
31
.forgejo/workflows/update_input.yaml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
name: Update_Flake
|
||||||
|
|
||||||
|
run-name: "[Update Flake] ${{ inputs.input_to_update }}"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
input_to_update:
|
||||||
|
description: 'Flake input to update'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update:
|
||||||
|
runs-on: nix
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
# Give the default GITHUB_TOKEN write permission to commit and push the
|
||||||
|
# added or changed files to the repository.
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.head_ref }}
|
||||||
|
token: ${{ secrets.PIPELINE_TOKEN }}
|
||||||
|
- run: nix flake update ${{ inputs.input_to_update }}
|
||||||
|
shell: bash
|
||||||
|
- uses: https://github.com/stefanzweifel/git-auto-commit-action@v5
|
||||||
|
with:
|
||||||
|
commit_message: "Updated flake for ${{ inputs.input_to_update }}"
|
6
.gitattributes
vendored
6
.gitattributes
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
# Git config here
|
||||||
|
* text eol=lf
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# Git lfs stuff
|
||||||
|
|
||||||
# Documents
|
# Documents
|
||||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
*.doc filter=lfs diff=lfs merge=lfs -text
|
*.doc filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -4,6 +4,10 @@
|
||||||
# Microsoft office Lockfiles
|
# Microsoft office Lockfiles
|
||||||
~$*
|
~$*
|
||||||
*.tmp
|
*.tmp
|
||||||
|
tmp
|
||||||
|
|
||||||
|
# open office tmp lockfiles
|
||||||
|
.~lock.*
|
||||||
|
|
||||||
# Test files
|
# Test files
|
||||||
test.*
|
test.*
|
||||||
|
@ -22,3 +26,8 @@ test.*
|
||||||
|
|
||||||
# Dealing with Mac users
|
# Dealing with Mac users
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# nixos stuff
|
||||||
|
result
|
||||||
|
/result
|
||||||
|
.gcroots
|
||||||
|
|
176
.gitlab-ci.yml
176
.gitlab-ci.yml
|
@ -1,21 +1,23 @@
|
||||||
# borrowed from https://gitlab.com/nix17/nixos-config/-/blob/main/.gitlab-ci.yml
|
# borrowed from https://gitlab.com/nix17/nixos-config/-/blob/main/.gitlab-ci.yml
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- flake
|
- misc
|
||||||
- test
|
- test
|
||||||
#- deploy
|
- deploy
|
||||||
|
- deploy_gitlab
|
||||||
|
|
||||||
|
# Update the flake for any changes upstream
|
||||||
# Passed in from upstream
|
# Passed in from upstream
|
||||||
# $PACKAGE_NAME = name of the flake that needs to be updated
|
# $PACKAGE_NAME = name of the flake that needs to be updated
|
||||||
# $UPDATE_FLAKE = flag to update the flake
|
# $UPDATE_FLAKE = flag to update the flake
|
||||||
|
|
||||||
update:
|
update:
|
||||||
stage: flake
|
stage: misc
|
||||||
|
tags:
|
||||||
|
- nix
|
||||||
# from https://forum.gitlab.com/t/git-push-from-inside-a-gitlab-runner/30554/5
|
# from https://forum.gitlab.com/t/git-push-from-inside-a-gitlab-runner/30554/5
|
||||||
before_script:
|
before_script:
|
||||||
#- 'which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )'
|
# set teh ssh key for the commit
|
||||||
- eval `ssh-agent -s`
|
- eval $(ssh-agent -s)
|
||||||
# for the deploy
|
|
||||||
- echo "${CI_KEY}" | tr -d '\r' | ssh-add - > /dev/null
|
- echo "${CI_KEY}" | tr -d '\r' | ssh-add - > /dev/null
|
||||||
- mkdir -p ~/.ssh
|
- mkdir -p ~/.ssh
|
||||||
- chmod 700 ~/.ssh
|
- chmod 700 ~/.ssh
|
||||||
|
@ -28,50 +30,142 @@ update:
|
||||||
# the part that updates the flake
|
# the part that updates the flake
|
||||||
- nix --experimental-features 'nix-command flakes' flake lock --update-input $PACKAGE_NAME
|
- nix --experimental-features 'nix-command flakes' flake lock --update-input $PACKAGE_NAME
|
||||||
- git add flake.lock
|
- git add flake.lock
|
||||||
- git commit -m "[skip ci] Updated flake for $PACKAGE_NAME" || echo "No changes, nothing to commit"
|
- git commit -m "Updated flake for $PACKAGE_NAME" || echo "No changes, nothing to commit"
|
||||||
# we have a custom domain
|
# we have a custom domain
|
||||||
- git remote rm origin && git remote add origin ssh://git@gitlab.skynet.ie:2222/compsoc/skynet/nixos.git
|
- git remote rm origin && git remote add origin ssh://git@gitlab.skynet.ie:2222/compsoc1/skynet/nixos.git
|
||||||
- git push origin HEAD:$CI_COMMIT_REF_NAME
|
- git push origin HEAD:$CI_COMMIT_REF_NAME
|
||||||
|
|
||||||
only:
|
only:
|
||||||
refs:
|
refs:
|
||||||
- main
|
- main
|
||||||
variables:
|
variables:
|
||||||
- $UPDATE_FLAKE == "yes"
|
- $UPDATE_FLAKE == "yes"
|
||||||
|
|
||||||
build:
|
sync_repos:
|
||||||
# image: nixos/nix
|
stage: misc
|
||||||
stage: test
|
image: registry.gitlab.com/gitlab-ci-utils/curl-jq:2.0.0
|
||||||
before_script:
|
|
||||||
- . "$HOME/.nix-profile/etc/profile.d/nix.sh"
|
|
||||||
script:
|
script:
|
||||||
- nix --experimental-features 'nix-command flakes' run nixpkgs#colmena -- build
|
- cd sync
|
||||||
|
- chmod +x ./sync.sh
|
||||||
|
- ./sync.sh
|
||||||
|
rules:
|
||||||
|
- if: $UPDATE_FLAKE == "yes"
|
||||||
|
when: never
|
||||||
|
- if: '$CI_PROJECT_NAMESPACE == "compsoc1/skynet" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||||
|
changes:
|
||||||
|
- sync/repos.csv
|
||||||
|
|
||||||
# use ctrl+/ on intellij to mass uncoment
|
.scripts_base: &scripts_base
|
||||||
# set up deployment later
|
# load nix environment
|
||||||
#deploy:
|
- . "$HOME/.nix-profile/etc/profile.d/nix.sh"
|
||||||
# stage: deploy
|
- nix --extra-experimental-features 'nix-command flakes' profile install nixpkgs#colmena
|
||||||
# # from https://forum.gitlab.com/t/git-push-from-inside-a-gitlab-runner/30554/5
|
|
||||||
# before_script:
|
|
||||||
# # Check for ssh-agent + rsync and install if not present
|
|
||||||
# #- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
|
|
||||||
# - eval $(ssh-agent -s)
|
|
||||||
# # Inject the remote's private key
|
|
||||||
# - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
|
|
||||||
# - mkdir -p ~/.ssh
|
|
||||||
# - chmod 700 ~/.ssh
|
|
||||||
# # Append keyscan output into known hosts
|
|
||||||
# - ssh-keyscan $SERVER_IP >> ~/.ssh/known_hosts
|
|
||||||
# - chmod 644 ~/.ssh/known_hosts
|
|
||||||
#
|
|
||||||
# script:
|
|
||||||
# # this will grab a fresh copy of teh repo
|
|
||||||
# - ssh $SERVER_USER@$SERVER_IP "cd /etc/nixos && git stash && git pull origin main && nixos-rebuild switch"
|
|
||||||
#
|
|
||||||
# only:
|
|
||||||
# refs:
|
|
||||||
# - main
|
|
||||||
|
|
||||||
|
.scripts_deploy: &scripts_deploy
|
||||||
|
# setup ssh key
|
||||||
|
- eval $(ssh-agent -s)
|
||||||
|
- echo "$DEPLOY_KEY" | tr -d '\r' | ssh-add - > /dev/null
|
||||||
|
- mkdir -p ~/.ssh
|
||||||
|
- chmod 700 ~/.ssh
|
||||||
|
|
||||||
# only run on $UPDATE_FLAKE
|
.scripts_cache: &scripts_cache
|
||||||
|
- nix --extra-experimental-features 'nix-command flakes' profile install nixpkgs#attic-client
|
||||||
|
- attic login skynet https://nix-cache.skynet.ie/ $CACHE_KEY
|
||||||
|
- attic use skynet-cache
|
||||||
|
# add any new items to the cache
|
||||||
|
- attic watch-store skynet-cache &
|
||||||
|
|
||||||
|
# every commit on main will build and deploy
|
||||||
|
.build_template: &builder
|
||||||
|
tags:
|
||||||
|
- nix
|
||||||
|
before_script:
|
||||||
|
- *scripts_base
|
||||||
|
- *scripts_cache
|
||||||
|
rules:
|
||||||
|
- if: $UPDATE_FLAKE == "yes"
|
||||||
|
when: never
|
||||||
|
- changes:
|
||||||
|
- applications/**/*
|
||||||
|
- machines/**/*
|
||||||
|
- secrets/**/*
|
||||||
|
- flake.*
|
||||||
|
- .gitlab-ci.yml
|
||||||
|
- config/**/*
|
||||||
|
|
||||||
|
# deploy items only run on main
|
||||||
|
.deploy_template: &deployment
|
||||||
|
before_script:
|
||||||
|
- *scripts_deploy
|
||||||
|
- *scripts_base
|
||||||
|
- *scripts_cache
|
||||||
|
rules:
|
||||||
|
- if: $UPDATE_FLAKE == "yes"
|
||||||
|
when: never
|
||||||
|
- if: '$CI_PROJECT_NAMESPACE == "compsoc1/skynet" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||||
|
changes:
|
||||||
|
- flake.nix
|
||||||
|
- flake.lock
|
||||||
|
- applications/**/*
|
||||||
|
- machines/**/*
|
||||||
|
- secrets/**/*
|
||||||
|
- config/**/*
|
||||||
|
|
||||||
|
linter:
|
||||||
|
<<: *builder
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- nix --extra-experimental-features 'nix-command flakes' fmt -- --check .
|
||||||
|
|
||||||
|
build:
|
||||||
|
<<: *builder
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- nix --extra-experimental-features 'nix-command flakes' develop
|
||||||
|
- colmena build -v --on @active-dns
|
||||||
|
- colmena build -v --on @active-core
|
||||||
|
- colmena build -v --on @active
|
||||||
|
- colmena build -v --on @active-ext
|
||||||
|
- colmena build -v --on @active-gitlab
|
||||||
|
|
||||||
|
# dns always has to be deployed first
|
||||||
|
deploy_dns:
|
||||||
|
<<: *builder
|
||||||
|
<<: *deployment
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- colmena apply -v --on @active-dns
|
||||||
|
|
||||||
|
deploy_core:
|
||||||
|
<<: *builder
|
||||||
|
<<: *deployment
|
||||||
|
stage: deploy
|
||||||
|
needs:
|
||||||
|
- deploy_dns
|
||||||
|
script:
|
||||||
|
- colmena apply -v --on @active-core
|
||||||
|
|
||||||
|
deploy_active:
|
||||||
|
<<: *builder
|
||||||
|
<<: *deployment
|
||||||
|
stage: deploy
|
||||||
|
needs:
|
||||||
|
- deploy_dns
|
||||||
|
script:
|
||||||
|
- colmena apply -v --on @active
|
||||||
|
|
||||||
|
# this is just skynet server
|
||||||
|
deploy_ext:
|
||||||
|
<<: *builder
|
||||||
|
<<: *deployment
|
||||||
|
stage: deploy
|
||||||
|
needs:
|
||||||
|
- deploy_dns
|
||||||
|
script:
|
||||||
|
- colmena apply -v --on @active-ext
|
||||||
|
|
||||||
|
deploy_gitlab:
|
||||||
|
<<: *builder
|
||||||
|
<<: *deployment
|
||||||
|
stage: deploy_gitlab
|
||||||
|
script:
|
||||||
|
- colmena apply -v --on @active-gitlab
|
||||||
|
when: manual
|
||||||
|
|
18
.gitlab/issue_templates/ITD_Ticket.md
Normal file
18
.gitlab/issue_templates/ITD_Ticket.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
## Ticket ID
|
||||||
|
|
||||||
|
|
||||||
|
## Ticket URL
|
||||||
|
|
||||||
|
|
||||||
|
## Ticket HTML
|
||||||
|
1. Expand all sections of ticket
|
||||||
|
2. Right click on page
|
||||||
|
3. Save page as
|
||||||
|
4. Web page complete
|
||||||
|
5. Attach file here
|
||||||
|
|
||||||
|
|
||||||
|
## Important
|
||||||
|
* Mark as ``Confidential``
|
||||||
|
* Apply label ``ITD Ticket``
|
||||||
|
* After submission link any relevent issues.
|
1
.mailmap
Normal file
1
.mailmap
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Brendan Golden <silver@skynet.ie> <git_laptop@brendan.ie> <git@brendan.ie>
|
45
ITD/Firewall_Rules.csv
Normal file
45
ITD/Firewall_Rules.csv
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
Rule,Action,Ticket,Status,Source_IP,Source_Server,Destination_IP,Destination_Server,Port_TCP,Port_UDP,Notes
|
||||||
|
SKYNET_FIREWALL_00000,Add,,Complete,VPN,-,93.1.99.71 - 193.1.99.126,All,22,-,sftp/ssh required from vpn to servers for admins
|
||||||
|
SKYNET_FIREWALL_00001,Add,,Complete,All,-,193.1.99.109,SKYNET00004,-,53,Nameserver for skynet.ie
|
||||||
|
SKYNET_FIREWALL_00002,Add,,Complete,All,-,193.1.99.111,SKYNET00005,"80, 443, 8000",-,"ULFM, http(s) for internet streaming, 8000 for connecting to the server."
|
||||||
|
SKYNET_FIREWALL_00003,Add,,Complete,All,-,193.1.99.112,SKYNET00006,"80, 443, 25565",-,"Games host, Minecraft uses 25565 (will have more ports in the future)"
|
||||||
|
SKYNET_FIREWALL_00004,Add,,Complete,All,-,193.1.99.120,SKYNET00002,-,53,Nameserver for skynet.ie
|
||||||
|
SKYNET_FIREWALL_00005,Add,i23-01-19_681,Complete,193.1.99.72,SKYNET00001,All,-,-,-,Allow outbound access
|
||||||
|
SKYNET_FIREWALL_00006,Add,i23-01-19_681,Complete,193.1.99.75,SKYNET00008,All,-,-,-,Allow outbound access
|
||||||
|
SKYNET_FIREWALL_00007,Add,i23-01-19_681,Complete,193.1.99.109,SKYNET00004,All,-,-,-,Allow outbound access
|
||||||
|
SKYNET_FIREWALL_00008,Add,i23-01-19_681,Complete,193.1.99.111,SKYNET00005,All,-,-,-,Allow outbound access
|
||||||
|
SKYNET_FIREWALL_00009,Add,i23-01-19_681,Complete,193.1.99.112,SKYNET00006,All,-,-,-,Allow outbound access
|
||||||
|
SKYNET_FIREWALL_00010,Add,i23-01-19_681,Complete,193.1.99.120,SKYNET00002,All,-,-,-,Allow outbound access
|
||||||
|
SKYNET_FIREWALL_00011,Add,i23-05-18_249,Complete,All,-,193.1.99.75,SKYNET00008,"80, 443",-,For gitlab Access
|
||||||
|
SKYNET_FIREWALL_00012,Add,i23-05-18_249,Complete,193.1.99.72 - 193.1.99.126,-,All,-,-,-,"I would also like to extend the outbound access to cover our entire range (193.1.99.72 to 193.1.99.126) to allow for setup for more servers on those ip's (need to download updates and packages).
|
||||||
|
I have a few servers I plan to setup over the next two weeks, one after another as the later ones depend on earlier ones.
|
||||||
|
In such a case asking for permission for each individual IP would induce several tickets and a few weeks of paperwork going through change control.
|
||||||
|
Only a few of these sevices will need inbound ports opened on ITD's firewall, which can be requested when the systems are up, running and secured."
|
||||||
|
SKYNET_FIREWALL_00013,Add,i23-05-18_249,Complete,All,-,193.1.99.76,SKYNET00009,"143, 993, 587, 465",-,Email Server
|
||||||
|
SKYNET_FIREWALL_00014,Add,i23-06-19_525,Complete,All,-,193.1.99.76,SKYNET00009,"80, 443, 25",-,"Mailserver here, SPF, DKIM and DMARC are all set up"
|
||||||
|
SKYNET_FIREWALL_00015,Add,i23-06-19_525,Complete,All,-,193.1.99.79,SKYNET00011,"80, 443",-,Main Skynet webserver
|
||||||
|
SKYNET_FIREWALL_00016,Add,i23-06-30_024,Complete,All,-,193.1.96.165,SKYNET00012,22,-,"Skynet user's server
|
||||||
|
Outlet is 131 or 132"
|
||||||
|
SKYNET_FIREWALL_00017,Add,i23-06-30_024,Complete,193.1.96.165,SKYNET00012,193.1.99.120,SKYNET00002,-,53,Allow Skynet server to use our own internal DNS
|
||||||
|
SKYNET_FIREWALL_00018,Add,i23-06-30_024,Complete,193.1.96.165,SKYNET00012,193.1.99.74,SKYNET00007,389/636,-,Allow Skynet server to access LDAP
|
||||||
|
,Add,i23-07-28_010,Denied,All,-,193.1.99.74,SKYNET00007,"80, 443",-,Self Service site for Skynet accounts – Only 443 on account modification pages
|
||||||
|
SKYNET_FIREWALL_00019,Add,i23-07-28_010,Complete,All,-,193.1.99.74,SKYNET00007,443,-,Self Service site for Skynet accounts
|
||||||
|
SKYNET_FIREWALL_00020,Add,i23-09-05_639,Complete,All,-,193.1.96.165,SKYNET00012,"80, 443",-,Web hosting for user sites
|
||||||
|
SKYNET_FIREWALL_00021,Add,i23-10-27_014,Complete,All,-,193.1.99.77,SKYNET00014,"80, 443",-,"Nextcloud, selfhosted google services, filestorage and documents"
|
||||||
|
SKYNET_FIREWALL_00022,Add,i24-02-01_102,Complete,193.1.96.165,SKYNET00012,103.1.99.109,SKYNET00004,-,53,Give the Skynet server access to ur secondary DNS
|
||||||
|
SKYNET_FIREWALL_00023,Add,i24-02-01_102,Complete,193.1.99.78,SKYNET00010,193.1.96.165,SKYNET00012,22,-,Allow our gitlab runner to access and deploy to teh external server
|
||||||
|
SKYNET_FIREWALL_00024,Add,i24-02-16_065,Complete,All,-,193.1.99.90,SKYNET00016,"80, 443",-,Games Server Administrative panel
|
||||||
|
SKYNET_FIREWALL_00025,Add,i24-02-16_065,Complete,All,-,193.1.99.91,SKYNET00017,25518-25525,"19132, 24418-24425",Minecraft Games server
|
||||||
|
SKYNET_FIREWALL_00026,Add,i24-06-04_017,Complete,All,-,193.1.99.76,SKYNET00009,4190,-,"Email sieve to allow members to add email filters to their
|
||||||
|
skynet mail."
|
||||||
|
SKYNET_FIREWALL_00027,Add,i24-06-04_017,Complete,All,-,193.1.99.82,SKYNET00018,80/443,-,"Public services such as a binary cache, open governance and keyserver"
|
||||||
|
,Add,i24-06-04_017,Denied,All,-,193.1.99.90,SKYNET00016,8080,-,"Websocket for admin panel on games management server
|
||||||
|
Denied because more information on wat it was for was requested"
|
||||||
|
,Add,i24-06-04_017,Denied,193.1.99.74,SKYNET00007,193.1.96.165,SKYNET00012,9000-9020,-,"Metrics collection, not done because not enough info provided"
|
||||||
|
SKYNET_FIREWALL_00028,Remove,i24-06-04_017,Complete,-,-,193.1.99.112,SKYNET00019,25565,-,No longer the minecraft game host
|
||||||
|
SKYNET_FIREWALL_00029,Add,i24-06-04_017,Complete,All,-,193.1.99.90,SKYNET00016,8080,-,Websocket for admin panel on games management server
|
||||||
|
SKYNET_FIREWALL_00030,Add,i24-06-04_017,Complete,193.1.99.83,SKYNET00020,193.1.96.165,SKYNET00012,9000-9010,-,Metrics Collection
|
||||||
|
SKYNET_FIREWALL_00031,Add,i24-06-04_017,Complete,All,-,193.1.99.83,SKYNET00020,"80, 443",-,Web interface for Metrics server
|
||||||
|
SKYNET_FIREWALL_00032,Remove,i24-06-04_017,Complete,All,-,193.1.99.90,SKYNET00016,8080,-,Had incorrectly opened 8080 on the main panel
|
||||||
|
SKYNET_FIREWALL_00033,Add,i24-06-04_017,Complete,All,-,193.1.99.91,SKYNET00017,8080,-,Websocket for admin panel on games management server
|
||||||
|
,Add,i24-07-15_112,Denied,193.1.99.75,-,-,-,22,-,Response from ITD - 'Our IT Security team have advised that port 22 and port 2222 are only to be allowed through the VPN and will not be opened to allow inbound ssh connections directly from the internet'
|
|
22
ITD/Server_Inventory.csv
Normal file
22
ITD/Server_Inventory.csv
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Index,Name,Status,IP_Address,OS,Description
|
||||||
|
SKYNET00001,agentjones,Active,193.1.99.72,Nixos-24.05,Firewall (currently not active)
|
||||||
|
SKYNET00002,vendetta,Active,193.1.99.120,Nixos-24.05,DNS Nameserver 1
|
||||||
|
SKYNET00003,jarvis,Active,193.1.99.73,Nixos-24.05,VM Host
|
||||||
|
SKYNET00004,vigil,Active,193.1.99.109,Nixos-24.05,DNS Nameserver 2
|
||||||
|
SKYNET00005,galatea,Active,193.1.99.111,Nixos-24.05,ULFM Radio
|
||||||
|
SKYNET00006,optimus,Retired,193.1.99.112,Nixos-24.05,Retired Games server
|
||||||
|
SKYNET00007,kitt,Active,193.1.99.74,Nixos-24.05,"LDAP and Self-Service Password/Account management, also hosts our Discord bot"
|
||||||
|
SKYNET00008,glados,Active,193.1.99.75,Nixos-24.05,Gitlab server
|
||||||
|
SKYNET00009,gir,Active,193.1.99.76,Nixos-24.05,Email and Webmail
|
||||||
|
SKYNET00010,wheatly,Active,193.1.99.78,Nixos-24.05,Gitlab Runner
|
||||||
|
SKYNET00011,earth,Active,193.1.99.79,Nixos-24.05,Offical website host
|
||||||
|
SKYNET00012,skynet,Active,193.1.96.165,Nixos-24.05,Skynet server. (DMZ)
|
||||||
|
SKYNET00013,neuromancer,Active,193.1.99.80,Nixos-24.05,Local Backup Server
|
||||||
|
SKYNET00014,cadie,Active,193.1.99.77,Nixos-24.05,"Services VM, has nextcloud to start with"
|
||||||
|
SKYNET00015,marvin,Active,193.1.99.81,Nixos-24.05,Trainee testing server
|
||||||
|
SKYNET00016,optimus,Active,193.1.99.90,Debian-12,Games server manager (replacing SKYNET00006 soon)
|
||||||
|
SKYNET00017,bumblebee,Active,193.1.99.91,Debian-12,Game server - Minecraft
|
||||||
|
SKYNET00018,calculon,Active,193.1.99.82,Nixos-24.05,"Public Services such as binary cache, Open Governance and Keyserver"
|
||||||
|
SKYNET00019,deepthought,Active,193.1.99.112,Nixos-24.05,Backup Test Server using restic
|
||||||
|
SKYNET00020,ariia,Active,193.1.99.83,Nixos-24.05,"Metrics, Grafana and Prometheus"
|
||||||
|
SKYNET00021,ash,Active,193.1.99.114,NA,Server Room Network access
|
|
6
ITD/VPN_Admins.csv
Normal file
6
ITD/VPN_Admins.csv
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
Index,First Name,Surname,UL Student Email
|
||||||
|
SKYNET_VPN_ADM_001,Brendan,Golden,12136891@studentmail.ul.ie
|
||||||
|
SKYNET_VPN_ADM_002,Evan,Cassidy,External
|
||||||
|
SKYNET_VPN_ADM_003,Eoghan,Conlon,21310262@studentmail.ul.ie
|
||||||
|
SKYNET_VPN_ADM_004,Eliza,Macovei,23382619@studentmail.ul.ie
|
||||||
|
SKYNET_VPN_ADM_005,Daragh,Downes,22351159@studentmail.ul.ie
|
|
7
ITD/VPN_Admins_changes.csv
Normal file
7
ITD/VPN_Admins_changes.csv
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Date,Date Modified,Action,Ticket,ID
|
||||||
|
SKYNET_VPN_ADM_CHANGE_001,2023/04/04,Added,,SKYNET_VPN_ADM_001
|
||||||
|
SKYNET_VPN_ADM_CHANGE_002,2023/04/04,Added,,SKYNET_VPN_ADM_002
|
||||||
|
SKYNET_VPN_ADM_CHANGE_003,2023/04/04,Added,,SKYNET_VPN_ADM_003
|
||||||
|
SKYNET_VPN_ADM_CHANGE_003,2024/07/21,Removed,i24-07-22_760,SKYNET_VPN_ADM_003
|
||||||
|
SKYNET_VPN_ADM_CHANGE_004,2024/07/21,Added,i24-07-22_760,SKYNET_VPN_ADM_004
|
||||||
|
SKYNET_VPN_ADM_CHANGE_005,2024/07/21,Added,i24-07-22_760,SKYNET_VPN_ADM_005
|
|
9
LICENSE
Normal file
9
LICENSE
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Skynet
|
||||||
|
|
||||||
|
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.
|
20
Possible_Server_Names.md
Normal file
20
Possible_Server_Names.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
https://web.archive.org/web/20180815150202/https://wiki.skynet.ie/Admin/SkynetMachines
|
||||||
|
https://en.m.wikipedia.org/wiki/Category:Fictional_artificial_intelligences
|
||||||
|
https://en.wikipedia.org/wiki/List_of_artificial_intelligence_films
|
||||||
|
|
||||||
|
* agentsmith
|
||||||
|
* skynet
|
||||||
|
* caro
|
||||||
|
* Lowe - https://westworld.fandom.com/wiki/Bernard_Lowe
|
||||||
|
* ultron
|
||||||
|
* walle
|
||||||
|
* eve
|
||||||
|
* calculon
|
||||||
|
* deepthought
|
||||||
|
* earth
|
||||||
|
* flexo
|
||||||
|
* bender
|
||||||
|
* marvin
|
||||||
|
* kitt
|
||||||
|
* wopr
|
||||||
|
* wintermute
|
125
README.md
Normal file
125
README.md
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
# Skynet
|
||||||
|
|
||||||
|
This is teh core config for teh skynet cluster which uses [NixOS][1].
|
||||||
|
|
||||||
|
## Dev
|
||||||
|
### Prep
|
||||||
|
|
||||||
|
1. Install [Nix][2]
|
||||||
|
2. Enable [Flakes][3]
|
||||||
|
|
||||||
|
The system ye use does nto matter much, I (@silver) use nix in wsl and it works grand.
|
||||||
|
|
||||||
|
### Shell
|
||||||
|
|
||||||
|
Now ye got nix installed and flakes enabled run ``nix develop`` in the root folder (same place this readme is).
|
||||||
|
The dev dependencies you need to work with the project will be automatically installed.
|
||||||
|
The specific config for this can be found [here][4].
|
||||||
|
|
||||||
|
Specifically it installs [Colmena][5] and [Agenix][6].
|
||||||
|
Colmena is a build and deployment tool, Agenix is for secret management.
|
||||||
|
|
||||||
|
All following commands are inside the shell.
|
||||||
|
### Colmena
|
||||||
|
|
||||||
|
#### Building
|
||||||
|
|
||||||
|
To build all nodes (servers) run:
|
||||||
|
```shell
|
||||||
|
colmena build
|
||||||
|
```
|
||||||
|
|
||||||
|
To build a specific one
|
||||||
|
```shell
|
||||||
|
colmena build --on skynet
|
||||||
|
```
|
||||||
|
|
||||||
|
To build a group (for example the dns servers)
|
||||||
|
```shell
|
||||||
|
colmena build --on @active-dns
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Deploy
|
||||||
|
Deploying is putting (apply-ing) the config tat was built onto the server, there is no need to build first, it will automatically do so.
|
||||||
|
|
||||||
|
While the ***recommended way of deploying is using the CI/CD process*** there are times when you will have to manually deploy the config.
|
||||||
|
One such case is the ``@active-gitlab`` group if either Gitlab or Gitlab-runner got updated.
|
||||||
|
Another is if ye have fecked up DNS.
|
||||||
|
|
||||||
|
Your ``~/.ssh/config`` should be set up as follows and you should be a member of ``skynet-admins-linux``
|
||||||
|
|
||||||
|
```ini
|
||||||
|
Host *.skynet.ie 193.1.99.* 193.1.96.165
|
||||||
|
User username
|
||||||
|
IdentityFile ~/.ssh/skynet/username
|
||||||
|
IdentitiesOnly yes
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can run the following commands like so:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
colmena apply
|
||||||
|
colmena apply --on @active-dns
|
||||||
|
colmena apply --on @active-gitlab
|
||||||
|
```
|
||||||
|
|
||||||
|
The CI/CD pipeline has a manual job that can be triggered to update ``@active-gitlab`` if you know it wont cause issues.
|
||||||
|
|
||||||
|
### Agenix
|
||||||
|
|
||||||
|
Agenix is for storing secrets in an encrypted manner using ssh keys.
|
||||||
|
|
||||||
|
All these commands require you to be in the secrets folder ``cd secrets``
|
||||||
|
|
||||||
|
#### Prep
|
||||||
|
1. Go to yer .ssh folder and see if you have a ``id_ed25519`` key ([tutorial][7])
|
||||||
|
2. Make a pull request to add (``id_ed25519.pub``) to the [secrets config][8].
|
||||||
|
3. An existing admin will pull, run ``agenix --rekey`` and commit changes.
|
||||||
|
4. Once committed and pushed up and merged in, you will be able to edit secrets.
|
||||||
|
|
||||||
|
``id_ed25519`` is preferred due to its neatness and security (Yes @silver is pedantic.)
|
||||||
|
|
||||||
|
#### Editing
|
||||||
|
When editing a terminal editor will open (nano).
|
||||||
|
You must use teh path defined in the ``secrets.nix`` file.
|
||||||
|
|
||||||
|
````shell
|
||||||
|
agenix -e stream_ulfm.age
|
||||||
|
agenix -e ldap/self_service.age
|
||||||
|
agenix -e gitlab/runners/runner01.age
|
||||||
|
````
|
||||||
|
|
||||||
|
### Updating inputs
|
||||||
|
Occasionally you will want to update the inputs for the project.
|
||||||
|
It is best to do this every few months or so, there is always a risk of things changing so a small pain often is better than a nightmare if left longer.
|
||||||
|
As seen in [this merge request][9] the layout of one config changed which had to be fixed.
|
||||||
|
|
||||||
|
We should be updating ``nixpkgs`` at least once a semester, ideally to teh next NixOS release so we cna show ITD our servers are patched and up to date.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
nix flake lock --update-input nixpkgs
|
||||||
|
# newser versions
|
||||||
|
nix flake update nixpkgs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Formatting
|
||||||
|
Formatting helps keep everything nice and consistent.
|
||||||
|
The pipeline will only run if the file is correctly formatted.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
nix fmt
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[1]: https://nixos.org/explore
|
||||||
|
[2]: https://nixos.org/download
|
||||||
|
[3]: https://nixos.wiki/wiki/Flakes
|
||||||
|
[4]: https://gitlab.skynet.ie/compsoc1/skynet/nixos/-/blob/main/flake.nix#L33
|
||||||
|
[5]: https://github.com/zhaofengli/colmena
|
||||||
|
[6]: https://github.com/ryantm/agenix
|
||||||
|
[7]: https://docs.gitlab.com/ee/user/ssh.html#see-if-you-have-an-existing-ssh-key-pair
|
||||||
|
[8]: https://gitlab.skynet.ie/compsoc1/skynet/nixos/-/blob/main/secrets/secrets.nix#L2
|
||||||
|
[9]: https://gitlab.skynet.ie/compsoc1/skynet/nixos/-/merge_requests/4
|
74
applications/_base.nix
Normal file
74
applications/_base.nix
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
# root service
|
||||||
|
cfg = config.services.skynet;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
# every server needs to have a dns record
|
||||||
|
./dns/dns.nix
|
||||||
|
|
||||||
|
# every server should have proper certs
|
||||||
|
./acme.nix
|
||||||
|
./nginx.nix
|
||||||
|
|
||||||
|
# every server may need the firewall config stuff
|
||||||
|
./firewall.nix
|
||||||
|
|
||||||
|
# every server needs teh ldap client for admins
|
||||||
|
./ldap/client.nix
|
||||||
|
|
||||||
|
# every server will need the config to backup to
|
||||||
|
./restic.nix
|
||||||
|
|
||||||
|
# every server will be monitored for grafana
|
||||||
|
./prometheus.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet = {
|
||||||
|
# since we use this basically everywhere provide a standard way to set it
|
||||||
|
host = {
|
||||||
|
ip = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
hostname = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "${cfg.host.name}.skynet.ie";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = cfg.host.name;
|
||||||
|
r_type = "A";
|
||||||
|
value = cfg.host.ip;
|
||||||
|
server = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = cfg.host.ip;
|
||||||
|
r_type = "PTR";
|
||||||
|
value = cfg.host.hostname;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
virtualHosts = {
|
||||||
|
# for every server unless explisitly defined redirect the ip to skynet.ie
|
||||||
|
"${cfg.host.ip}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/".return = "307 https://skynet.ie";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
69
applications/_retired/games.nix
Normal file
69
applications/_retired/games.nix
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "games";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./nginx.nix
|
||||||
|
./games/minecraft.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet Games";
|
||||||
|
|
||||||
|
domain = {
|
||||||
|
tld = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "ie";
|
||||||
|
};
|
||||||
|
|
||||||
|
base = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "skynet";
|
||||||
|
};
|
||||||
|
|
||||||
|
sub = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "games";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
# need a base domain
|
||||||
|
{
|
||||||
|
record = cfg.domain.sub;
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${cfg.domain.sub}.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"${cfg.domain.sub}.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
root = "${inputs.skynet_website_games.defaultPackage.x86_64-linux}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# the minecraft servers
|
||||||
|
services.skynet.games_minecraft = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
domain = {
|
||||||
|
sub = "minecraft.${cfg.domain.sub}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,33 +1,24 @@
|
||||||
{ config, pkgs, lib, inputs, ... }:
|
{
|
||||||
with lib;
|
config,
|
||||||
let
|
pkgs,
|
||||||
cfg = config.services.skynet_games_minecraft;
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "games_minecraft";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
# got tired of how long this is so I created a var for it.
|
# got tired of how long this is so I created a var for it.
|
||||||
short_domain = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}";
|
short_domain = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
in {
|
in {
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
../acme.nix
|
|
||||||
../dns.nix
|
|
||||||
../firewall.nix
|
|
||||||
../nginx.nix
|
|
||||||
inputs.arion.nixosModules.arion
|
inputs.arion.nixosModules.arion
|
||||||
];
|
];
|
||||||
|
|
||||||
options.services.skynet_games_minecraft = {
|
options.services.skynet."${name}" = {
|
||||||
enable = mkEnableOption "Skynet Games Minecraft";
|
enable = mkEnableOption "Skynet Games Minecraft";
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = {
|
domain = {
|
||||||
tld = mkOption {
|
tld = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -48,22 +39,54 @@
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
skynet_firewall.forward = [
|
skynet_firewall.forward = [
|
||||||
"ip daddr ${cfg.host.ip} tcp dport 80 counter packets 0 bytes 0 accept"
|
"ip daddr ${config.services.skynet.host.ip} tcp dport 80 counter packets 0 bytes 0 accept"
|
||||||
"ip daddr ${cfg.host.ip} tcp dport 443 counter packets 0 bytes 0 accept"
|
"ip daddr ${config.services.skynet.host.ip} tcp dport 443 counter packets 0 bytes 0 accept"
|
||||||
"ip daddr ${cfg.host.ip} tcp dport 25565 counter packets 0 bytes 0 accept"
|
"ip daddr ${config.services.skynet.host.ip} tcp dport 25565 counter packets 0 bytes 0 accept"
|
||||||
];
|
];
|
||||||
|
|
||||||
skynet_dns.records = [
|
services.skynet.acme.domains = [
|
||||||
|
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"
|
||||||
|
"*.${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
# the minecraft (web) config server
|
# the minecraft (web) config server
|
||||||
{record="config.${cfg.domain.sub}"; r_type="CNAME"; value=cfg.host.name;}
|
{
|
||||||
|
record = "config.${cfg.domain.sub}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
|
||||||
# our own minecraft hosts
|
# our own minecraft hosts
|
||||||
{record="compsoc_classic.${cfg.domain.sub}"; r_type="CNAME"; value=cfg.host.name;}
|
{
|
||||||
{record="compsoc.${cfg.domain.sub}"; r_type="CNAME"; value=cfg.host.name;}
|
record = "compsoc_classic.${cfg.domain.sub}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "compsoc.${cfg.domain.sub}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
|
||||||
# gsoc servers
|
# gsoc servers
|
||||||
{record="gsoc.${cfg.domain.sub}"; r_type="CNAME"; value=cfg.host.name;}
|
{
|
||||||
{record="gsoc_abridged.${cfg.domain.sub}"; r_type="CNAME"; value=cfg.host.name;}
|
record = "gsoc.${cfg.domain.sub}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "gsoc_abridged.${cfg.domain.sub}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# phildeb
|
||||||
|
{
|
||||||
|
record = "phildeb.${cfg.domain.sub}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
@ -72,7 +95,6 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
services.nginx.virtualHosts = {
|
services.nginx.virtualHosts = {
|
||||||
|
|
||||||
# https://config.minecraft.games.skynet.ie
|
# https://config.minecraft.games.skynet.ie
|
||||||
"config.${short_domain}" = {
|
"config.${short_domain}" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
|
@ -89,7 +111,6 @@
|
||||||
useACMEHost = "skynet";
|
useACMEHost = "skynet";
|
||||||
locations."/map/".alias = "/etc/games/minecraft/craftycontrol/servers/f4c5eb33-c6d6-421c-81ab-ded31f6e8750/plugins/dynmap/web/";
|
locations."/map/".alias = "/etc/games/minecraft/craftycontrol/servers/f4c5eb33-c6d6-421c-81ab-ded31f6e8750/plugins/dynmap/web/";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# arion is one way to use docker on nixos
|
# arion is one way to use docker on nixos
|
||||||
|
@ -98,14 +119,13 @@
|
||||||
virtualisation.arion = {
|
virtualisation.arion = {
|
||||||
backend = "docker";
|
backend = "docker";
|
||||||
projects = {
|
projects = {
|
||||||
|
|
||||||
minecraft.settings.services = {
|
minecraft.settings.services = {
|
||||||
mc_proxy.service = {
|
mc_proxy.service = {
|
||||||
image = "itzg/mc-router:1.18.0";
|
image = "itzg/mc-router:1.18.0";
|
||||||
ports = ["25565:25565/tcp"];
|
ports = ["25565:25565/tcp"];
|
||||||
expose = ["25565"];
|
expose = ["25565"];
|
||||||
command = [
|
command = [
|
||||||
"--mapping=compsoc_classic.${short_domain}=mc_config:20000,compsoc.${short_domain}=mc_config:20001,gsoc.${short_domain}=mc_config:20002,gsoc.${short_domain}=mc_config:20002,gsoc_abridged.${short_domain}=mc_config:20003"
|
"--mapping=compsoc_classic.${short_domain}=mc_config:20000,compsoc.${short_domain}=mc_config:20001,gsoc.${short_domain}=mc_config:20002,gsoc.${short_domain}=mc_config:20002,gsoc_abridged.${short_domain}=mc_config:20003,phildeb.${short_domain}=mc_config:20004"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,6 +153,9 @@
|
||||||
"20001:20001/tcp"
|
"20001:20001/tcp"
|
||||||
# games
|
# games
|
||||||
"20002:20002/tcp"
|
"20002:20002/tcp"
|
||||||
|
"20003:20003/tcp"
|
||||||
|
# phildeb
|
||||||
|
"20004:20004/tcp"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
|
@ -1,4 +1,26 @@
|
||||||
{ config, ... }:{
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "acme";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
in {
|
||||||
|
imports = [];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
domains = lib.mkOption {
|
||||||
|
default = [];
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
description = ''
|
||||||
|
A list of domains to use for this server.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
# group that will own the certificates
|
# group that will own the certificates
|
||||||
users.groups.acme = {};
|
users.groups.acme = {};
|
||||||
|
|
||||||
|
@ -10,19 +32,16 @@
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
email = "admin_acme@skynet.ie";
|
email = "admin_acme@skynet.ie";
|
||||||
|
credentialsFile = config.age.secrets.acme.path;
|
||||||
# we use our own dns authorative server for verifying we own the domain.
|
# we use our own dns authorative server for verifying we own the domain.
|
||||||
dnsProvider = "rfc2136";
|
dnsProvider = "rfc2136";
|
||||||
credentialsFile = config.age.secrets.acme.path;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
certs = {
|
certs = {
|
||||||
"skynet" = {
|
"skynet" = {
|
||||||
domain = "skynet.ie";
|
domain = "skynet.ie";
|
||||||
extraDomainNames = [
|
extraDomainNames = lists.naturalSort cfg.domains;
|
||||||
"*.skynet.ie"
|
};
|
||||||
"*.minecraft.games.skynet.ie"
|
|
||||||
"*.pages.skynet.ie"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
76
applications/bitwarden/bitwarden_sync.nix
Normal file
76
applications/bitwarden/bitwarden_sync.nix
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
user = "bwdc";
|
||||||
|
in {
|
||||||
|
imports = [];
|
||||||
|
|
||||||
|
options = {};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
age.secrets.bitwarden_sync_id = {
|
||||||
|
file = ../../secrets/bitwarden/id.age;
|
||||||
|
owner = user;
|
||||||
|
group = user;
|
||||||
|
};
|
||||||
|
age.secrets.bitwarden_sync_secret = {
|
||||||
|
file = ../../secrets/bitwarden/secret.age;
|
||||||
|
owner = user;
|
||||||
|
group = user;
|
||||||
|
};
|
||||||
|
age.secrets.bitwarden_sync_ldap = {
|
||||||
|
file = ../../secrets/ldap/pw.age;
|
||||||
|
owner = user;
|
||||||
|
group = user;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.bitwarden-directory-connector-cli = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
user = user;
|
||||||
|
|
||||||
|
domain = "https://pw.skynet.ie";
|
||||||
|
|
||||||
|
ldap = {
|
||||||
|
ssl = false;
|
||||||
|
startTls = false;
|
||||||
|
sslAllowUnauthorized = false;
|
||||||
|
ad = false;
|
||||||
|
port = 389;
|
||||||
|
hostname = "account.skynet.ie";
|
||||||
|
rootPath = "dc=skynet,dc=ie";
|
||||||
|
username = "cn=admin,dc=skynet,dc=ie";
|
||||||
|
};
|
||||||
|
|
||||||
|
sync = {
|
||||||
|
removeDisabled = true;
|
||||||
|
overwriteExisting = false;
|
||||||
|
largeImport = false;
|
||||||
|
memberAttribute = "member";
|
||||||
|
creationDateAttribute = "skCreated";
|
||||||
|
|
||||||
|
users = true;
|
||||||
|
userPath = "ou=users";
|
||||||
|
userObjectClass = "inetOrgPerson";
|
||||||
|
userEmailAttribute = "skMail";
|
||||||
|
userFilter = "(|(memberOf=cn=skynet-committee,ou=groups,dc=skynet,dc=ie)(memberOf=cn=skynet-admins,ou=groups,dc=skynet,dc=ie))";
|
||||||
|
|
||||||
|
groups = true;
|
||||||
|
groupPath = "ou=groups";
|
||||||
|
groupObjectClass = "groupOfNames";
|
||||||
|
groupNameAttribute = "cn";
|
||||||
|
};
|
||||||
|
|
||||||
|
secrets = {
|
||||||
|
ldap = config.age.secrets.bitwarden_sync_ldap.path;
|
||||||
|
bitwarden = {
|
||||||
|
client_path_id = config.age.secrets.bitwarden_sync_id.path;
|
||||||
|
client_path_secret = config.age.secrets.bitwarden_sync_secret.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
83
applications/bitwarden/vaultwarden.nix
Normal file
83
applications/bitwarden/vaultwarden.nix
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "vaultwarden";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
|
domain_sub = "pw";
|
||||||
|
domain = "${domain_sub}.skynet.ie";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet VaultWarden server";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
#backups = [ "/etc/silver_ul_ical/database.db" ];
|
||||||
|
|
||||||
|
# Website config
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
domain
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = domain_sub;
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"${domain}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString config.services.vaultwarden.config.ROCKET_PORT}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# has ADMIN_TOKEN and SMTP_PASSWORD
|
||||||
|
age.secrets.bitwarden_details.file = ../../secrets/bitwarden/details.age;
|
||||||
|
|
||||||
|
services.vaultwarden = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
environmentFile = config.age.secrets.bitwarden_details.path;
|
||||||
|
config = {
|
||||||
|
DOMAIN = "https://${domain}";
|
||||||
|
SENDS_ALLOWED = true;
|
||||||
|
SIGNUPS_ALLOWED = false;
|
||||||
|
|
||||||
|
INVITATION_ORG_NAME = "Skyhold";
|
||||||
|
|
||||||
|
ORG_GROUPS_ENABLED = true;
|
||||||
|
|
||||||
|
USE_SENDMAIL = false;
|
||||||
|
|
||||||
|
SMTP_HOST = "mail.skynet.ie";
|
||||||
|
SMTP_FROM = "vaultwarden@skynet.ie";
|
||||||
|
SMTP_FROM_NAME = "Skynet Bitwarden server";
|
||||||
|
SMTP_SECURITY = "starttls";
|
||||||
|
SMTP_PORT = 587;
|
||||||
|
|
||||||
|
SMTP_USERNAME = "vaultwarden@skynet.ie";
|
||||||
|
SMTP_AUTH_MECHANISM = "Login";
|
||||||
|
SMTP_EMBED_IMAGES = true;
|
||||||
|
|
||||||
|
ROCKET_ADDRESS = "127.0.0.1";
|
||||||
|
ROCKET_PORT = 8222;
|
||||||
|
|
||||||
|
ROCKET_LOG = "critical";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
38
applications/discord.nix
Normal file
38
applications/discord.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "discord_bot";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
inputs.skynet_discord_bot.nixosModule."x86_64-linux"
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet LDAP backend server";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
#backups = [ "/etc/silver_ul_ical/database.db" ];
|
||||||
|
|
||||||
|
age.secrets.discord_token.file = ../secrets/discord/token.age;
|
||||||
|
age.secrets.discord_mail.file = ../secrets/email/details.age;
|
||||||
|
age.secrets.discord_wolves.file = ../secrets/wolves/details.age;
|
||||||
|
|
||||||
|
# this is what was imported
|
||||||
|
services.skynet_discord_bot = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
env = {
|
||||||
|
discord = config.age.secrets.discord_token.path;
|
||||||
|
mail = config.age.secrets.discord_mail.path;
|
||||||
|
wolves = config.age.secrets.discord_wolves.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,400 +0,0 @@
|
||||||
{ lib, pkgs, config, nodes, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.skynet_dns;
|
|
||||||
|
|
||||||
# reads that date to a string (will need to be fixed in 2038)
|
|
||||||
current_date = lib.readFile "${pkgs.runCommand "timestamp" {} "echo -n `date +%s` > $out"}";
|
|
||||||
|
|
||||||
# gets a list of records that match this type
|
|
||||||
filter_records_type = r_type: builtins.filter (x: x.r_type == r_type) records;
|
|
||||||
filter_records_server = builtins.filter (x: builtins.hasAttr "server" x && x.server) (filter_records_type "A");
|
|
||||||
filter_records_a = builtins.filter (x: builtins.hasAttr "server" x && !x.server) (filter_records_type "A");
|
|
||||||
|
|
||||||
process_ptr = records: lib.lists.forEach records (x: process_ptr_sub x);
|
|
||||||
process_ptr_sub = record: {record=(builtins.substring 9 3 record.record); r_type="PTR"; value=record.value;};
|
|
||||||
ip_ptr_to_int = ip: lib.strings.toInt (builtins.substring 9 3 ip);
|
|
||||||
|
|
||||||
sort_records_server = builtins.sort (a: b: a.record < b.record) filter_records_server;
|
|
||||||
sort_records_a = builtins.sort (a: b: (ip_ptr_to_int a.value) < (ip_ptr_to_int b.value)) filter_records_a;
|
|
||||||
sort_records_cname = builtins.sort (a: b: a.value < b.value) (filter_records_type "CNAME");
|
|
||||||
sort_records_ptr = builtins.sort (a: b: (lib.strings.toInt a.record) < (lib.strings.toInt b.record)) (process_ptr (filter_records_type "PTR"));
|
|
||||||
sort_records_srv = builtins.sort (a: b: a.record < b.record) (filter_records_type "SRV");
|
|
||||||
|
|
||||||
format_records = records: offset: lib.strings.concatMapStrings (x: "${padString x.record offset} IN ${padString x.r_type 5} ${x.value}\n") records;
|
|
||||||
|
|
||||||
# small function to trim it down a tad
|
|
||||||
padString = text: length: fixedWidthString_post length " " text;
|
|
||||||
|
|
||||||
# like lib.strings.fixedWidthString but postfix
|
|
||||||
fixedWidthString_post = width: filler: str:
|
|
||||||
let
|
|
||||||
strw = lib.stringLength str;
|
|
||||||
reqWidth = width - (lib.stringLength filler);
|
|
||||||
in
|
|
||||||
assert lib.assertMsg (strw <= width) "fixedWidthString_post: requested string length (${toString width}) must not be shorter than actual length (${toString strw})";
|
|
||||||
if strw == width
|
|
||||||
then str
|
|
||||||
else (fixedWidthString_post reqWidth filler str) + filler;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# base config for domains we own (skynet.ie, csn.ul.ie, ulcompsoc.ie)
|
|
||||||
get_config_file = (domain:
|
|
||||||
''$TTL 60 ; 1 minute
|
|
||||||
; hostmaster@${domain} is an email address that recieves stuff related to dns
|
|
||||||
@ IN SOA ${nameserver}.${domain}. hostmaster.${domain}. (
|
|
||||||
; Serial (YYYYMMDDCC) this has to be updated for each time the record is updated
|
|
||||||
${current_date}
|
|
||||||
600 ; Refresh (10 minutes)
|
|
||||||
300 ; Retry (5 minutes)
|
|
||||||
604800 ; Expire (1 week)
|
|
||||||
3600 ; Minimum (1 hour)
|
|
||||||
)
|
|
||||||
|
|
||||||
@ NS ns1.${domain}.
|
|
||||||
@ NS ns2.${domain}.
|
|
||||||
; @ stands for teh root domain so teh A record below is where ${domain} points to
|
|
||||||
;@ A 193.1.99.76
|
|
||||||
;@ MX 5 ${domain}.
|
|
||||||
|
|
||||||
; can have multiple mailserves
|
|
||||||
@ MX 10 mail.${domain}.
|
|
||||||
|
|
||||||
|
|
||||||
; ------------------------------------------
|
|
||||||
; Server Names (A Records)
|
|
||||||
; ------------------------------------------
|
|
||||||
${format_records sort_records_server 11}
|
|
||||||
|
|
||||||
; ------------------------------------------
|
|
||||||
; A (non server names
|
|
||||||
; ------------------------------------------
|
|
||||||
${format_records sort_records_a 18}
|
|
||||||
|
|
||||||
; ------------------------------------------
|
|
||||||
; CNAMES
|
|
||||||
; ------------------------------------------
|
|
||||||
${format_records sort_records_cname 31}
|
|
||||||
|
|
||||||
; ------------------------------------------
|
|
||||||
; TXT
|
|
||||||
; ------------------------------------------
|
|
||||||
${format_records (filter_records_type "TXT") 29}
|
|
||||||
|
|
||||||
; ------------------------------------------
|
|
||||||
; SRV
|
|
||||||
; ------------------------------------------
|
|
||||||
${format_records sort_records_srv 17}
|
|
||||||
|
|
||||||
|
|
||||||
''
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
# https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/4/html/reference_guide/s2-bind-configuration-zone-reverse
|
|
||||||
# config for our reverse dnspointers (not properly working)
|
|
||||||
get_config_file_rev = (domain:
|
|
||||||
''$ORIGIN 99.1.193.in-addr.arpa.
|
|
||||||
$TTL 60 ; 1 minute
|
|
||||||
; hostmaster@skynet.ie is an email address that recieves stuff related to dns
|
|
||||||
@ IN SOA ${nameserver}.skynet.ie. hostmaster.skynet.ie. (
|
|
||||||
; Serial (YYYYMMDDCC) this has to be updated for each time the record is updated
|
|
||||||
${current_date}
|
|
||||||
600 ; Refresh (10 minutes)
|
|
||||||
300 ; Retry (5 minutes)
|
|
||||||
604800 ; Expire (1 week)
|
|
||||||
3600 ; Minimum (1 hour)
|
|
||||||
)
|
|
||||||
|
|
||||||
@ NS ns1.skynet.ie.
|
|
||||||
@ NS ns2.skynet.ie.
|
|
||||||
|
|
||||||
; ------------------------------------------
|
|
||||||
; PTR
|
|
||||||
; ------------------------------------------
|
|
||||||
${format_records sort_records_ptr 3}
|
|
||||||
''
|
|
||||||
);
|
|
||||||
|
|
||||||
# domains we dont have proper ownship over, only here to ensure the logs dont get cluttered.
|
|
||||||
get_config_file_old_domains = (domain:
|
|
||||||
''$TTL 60 ; 1 minute
|
|
||||||
; hostmaster@skynet.ie is an email address that recieves stuff related to dns
|
|
||||||
@ IN SOA ${nameserver}.skynet.ie. hostmaster.skynet.ie. (
|
|
||||||
; Serial (YYYYMMDDCC) this has to be updated for each time the record is updated
|
|
||||||
${current_date}
|
|
||||||
600 ; Refresh (10 minutes)
|
|
||||||
300 ; Retry (5 minutes)
|
|
||||||
604800 ; Expire (1 week)
|
|
||||||
3600 ; Minimum (1 hour)
|
|
||||||
)
|
|
||||||
|
|
||||||
@ NS ns1.skynet.ie.
|
|
||||||
@ NS ns2.skynet.ie.
|
|
||||||
|
|
||||||
''
|
|
||||||
);
|
|
||||||
|
|
||||||
# arrys of teh two nameservers
|
|
||||||
tmp1 = ["193.1.99.109"];
|
|
||||||
tmp2 = ["193.1.99.120"];
|
|
||||||
|
|
||||||
primaries = (if cfg.server.primary then
|
|
||||||
# primary servers have no primaries (ones they listen to)
|
|
||||||
[]
|
|
||||||
else
|
|
||||||
if builtins.elem cfg.server.ip tmp1 then
|
|
||||||
tmp2
|
|
||||||
else
|
|
||||||
tmp1
|
|
||||||
);
|
|
||||||
|
|
||||||
secondaries = (if cfg.server.primary then
|
|
||||||
if builtins.elem cfg.server.ip tmp1 then
|
|
||||||
tmp2
|
|
||||||
else
|
|
||||||
tmp1
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
# small function to tidy up the spam of the cache networks, would use teh subnet except all external traffic has the ip of teh router
|
|
||||||
create_cache_networks = (map (x: "193.1.99.${toString x}/32" ) (lib.lists.range 71 126) );
|
|
||||||
|
|
||||||
|
|
||||||
# standard function to create the etc file, pass in the text and domain and it makes it
|
|
||||||
create_entry_etc_sub = domain: text: {
|
|
||||||
# Creates /etc/skynet/dns/domain
|
|
||||||
"skynet/dns/${domain}" = {
|
|
||||||
user = "named";
|
|
||||||
group = "named";
|
|
||||||
|
|
||||||
# The UNIX file mode bits
|
|
||||||
mode = "0664";
|
|
||||||
|
|
||||||
text = text;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# (text.owned "csn.ul.ie")
|
|
||||||
|
|
||||||
|
|
||||||
# standard function to create the etc file, pass in the text and domain and it makes it
|
|
||||||
create_entry_etc = domain: type:
|
|
||||||
if type == "owned" then
|
|
||||||
create_entry_etc_sub domain (text.owned domain)
|
|
||||||
else if type == "reverse" then
|
|
||||||
create_entry_etc_sub domain (text.reverse domain)
|
|
||||||
else if type == "old" then
|
|
||||||
create_entry_etc_sub domain (text.old domain)
|
|
||||||
else
|
|
||||||
{};
|
|
||||||
|
|
||||||
create_entry_zone = (domain: extraConfig: {
|
|
||||||
"${domain}" = {
|
|
||||||
extraConfig = ''
|
|
||||||
${extraConfig}
|
|
||||||
// for bumping the config
|
|
||||||
// ${current_date}
|
|
||||||
'';
|
|
||||||
# really wish teh nixos config didnt use master/slave
|
|
||||||
master = cfg.server.primary;
|
|
||||||
masters = primaries;
|
|
||||||
slaves = secondaries;
|
|
||||||
# need to write this to a file
|
|
||||||
# using the date in it so it will trigger a restart
|
|
||||||
file = "/etc/skynet/dns/${domain}";
|
|
||||||
# no leading whitespace for first line
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
text = {
|
|
||||||
owned = domain: get_config_file domain;
|
|
||||||
reverse = domain: get_config_file_rev domain;
|
|
||||||
old = domain: get_config_file_old_domains domain;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = {
|
|
||||||
owned =
|
|
||||||
if cfg.server.primary then
|
|
||||||
''
|
|
||||||
allow-update { key rfc2136key.skynet.ie.; };
|
|
||||||
|
|
||||||
dnssec-policy default;
|
|
||||||
inline-signing yes;
|
|
||||||
''
|
|
||||||
else
|
|
||||||
"";
|
|
||||||
|
|
||||||
# no extra config for reverse
|
|
||||||
reverse = "";
|
|
||||||
|
|
||||||
old = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
records = builtins.concatLists (
|
|
||||||
lib.attrsets.mapAttrsToList (key: value:
|
|
||||||
let
|
|
||||||
details_server = value.config.skynet_dns.server;
|
|
||||||
details_records = value.config.skynet_dns.records;
|
|
||||||
in
|
|
||||||
if builtins.hasAttr "skynet_dns" value.config
|
|
||||||
then (
|
|
||||||
# got to handle habing a dns record for the dns serves themselves.
|
|
||||||
if details_server.enable
|
|
||||||
then (
|
|
||||||
if details_server.primary
|
|
||||||
then details_records ++ [ {record="ns1"; r_type="A"; value=details_server.ip; server=false;} ]
|
|
||||||
else details_records ++ [ {record="ns2"; r_type="A"; value=details_server.ip; server=false;} ]
|
|
||||||
)
|
|
||||||
else details_records
|
|
||||||
)
|
|
||||||
else []
|
|
||||||
) nodes
|
|
||||||
);
|
|
||||||
|
|
||||||
nameserver = if cfg.server.primary then "ns1" else "ns2";
|
|
||||||
|
|
||||||
in {
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
../applications/firewall.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
options = {
|
|
||||||
skynet_dns = {
|
|
||||||
server = {
|
|
||||||
enable = lib.mkEnableOption {
|
|
||||||
default = false;
|
|
||||||
description = "Skynet DNS server";
|
|
||||||
type = lib.types.bool;
|
|
||||||
};
|
|
||||||
|
|
||||||
primary = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
ip = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = ''
|
|
||||||
ip of this server
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
records = lib.mkOption {
|
|
||||||
description = "Records, sorted based on therir type";
|
|
||||||
type = with lib.types; listOf (submodule {
|
|
||||||
options = {
|
|
||||||
record = lib.mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
r_type = lib.mkOption {
|
|
||||||
type = enum ["A" "CNAME" "TXT" "PTR" "SRV"];
|
|
||||||
};
|
|
||||||
value = lib.mkOption {
|
|
||||||
type = str;
|
|
||||||
};
|
|
||||||
server = lib.mkOption {
|
|
||||||
description = "Core record for a server";
|
|
||||||
type = bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.server.enable {
|
|
||||||
|
|
||||||
# open the firewall for this
|
|
||||||
skynet_firewall.forward = [
|
|
||||||
"ip daddr ${cfg.server.ip} tcp dport 53 counter packets 0 bytes 0 accept"
|
|
||||||
"ip daddr ${cfg.server.ip} udp dport 53 counter packets 0 bytes 0 accept"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.bind.zones =
|
|
||||||
(create_entry_zone "csn.ul.ie" extraConfig.owned ) //
|
|
||||||
(create_entry_zone "skynet.ie" extraConfig.owned ) //
|
|
||||||
(create_entry_zone "ulcompsoc.ie" extraConfig.owned ) //
|
|
||||||
|
|
||||||
(create_entry_zone "99.1.193.in-addr.arpa" extraConfig.reverse )//
|
|
||||||
|
|
||||||
(create_entry_zone "conradcollins.net" extraConfig.old )//
|
|
||||||
(create_entry_zone "edelharty.net" extraConfig.old );
|
|
||||||
|
|
||||||
environment.etc =
|
|
||||||
(create_entry_etc "csn.ul.ie" "owned") //
|
|
||||||
(create_entry_etc "skynet.ie" "owned") //
|
|
||||||
(create_entry_etc "ulcompsoc.ie" "owned") //
|
|
||||||
|
|
||||||
(create_entry_etc "99.1.193.in-addr.arpa" "reverse") //
|
|
||||||
|
|
||||||
(create_entry_etc "conradcollins.net" "old") //
|
|
||||||
(create_entry_etc "edelharty.net" "old");
|
|
||||||
|
|
||||||
|
|
||||||
# secrets required
|
|
||||||
age.secrets.dns_dnskeys = {
|
|
||||||
file = ../secrets/dns_dnskeys.conf.age;
|
|
||||||
owner = "named";
|
|
||||||
group = "named";
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall = {
|
|
||||||
allowedTCPPorts = [53];
|
|
||||||
allowedUDPPorts = [53];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.bind = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
ipv4Only = true;
|
|
||||||
|
|
||||||
# need to take a look at https://nixos.org/manual/nixos/unstable/#module-security-acme-config-dns
|
|
||||||
extraConfig = ''
|
|
||||||
include "/run/agenix/dns_dnskeys";
|
|
||||||
'';
|
|
||||||
|
|
||||||
# piles of no valid RRSIG resolving 'com/DS/IN' errors
|
|
||||||
extraOptions = ''
|
|
||||||
dnssec-validation yes;
|
|
||||||
'';
|
|
||||||
|
|
||||||
# set the upstream dns servers
|
|
||||||
# overrides the default dns servers
|
|
||||||
forwarders = [
|
|
||||||
# Cloudflare
|
|
||||||
"1.1.1.1"
|
|
||||||
# Google
|
|
||||||
"8.8.8.8"
|
|
||||||
# Quad9
|
|
||||||
"9.9.9.9"
|
|
||||||
];
|
|
||||||
|
|
||||||
cacheNetworks = [
|
|
||||||
# this server itself
|
|
||||||
"127.0.0.0/24"
|
|
||||||
# all of skynet can use this as a resolver
|
|
||||||
/*
|
|
||||||
Origianl idea, however all external traffic had the ip of the router
|
|
||||||
"193.1.99.64/26"
|
|
||||||
|
|
||||||
So to fix this we need to allow smaller ranges? - Didnt work
|
|
||||||
Fallback is explisitly listing each ip we have
|
|
||||||
|
|
||||||
Now have a function for it
|
|
||||||
*/
|
|
||||||
] ++ create_cache_networks;
|
|
||||||
};
|
|
||||||
|
|
||||||
# creates a folder in /etc for the dns to use
|
|
||||||
users.users.named = {
|
|
||||||
createHome = true;
|
|
||||||
home = "/etc/skynet/dns";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
429
applications/dns/dns.nix
Normal file
429
applications/dns/dns.nix
Normal file
|
@ -0,0 +1,429 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
nodes,
|
||||||
|
self,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
name = "dns";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
|
# reads that date to a string (will need to be fixed in 2038)
|
||||||
|
current_date = self.lastModified;
|
||||||
|
|
||||||
|
# this gets a list of all domains we have records for
|
||||||
|
domains = lib.lists.naturalSort (lib.lists.unique (
|
||||||
|
lib.lists.forEach records (x: x.domain)
|
||||||
|
));
|
||||||
|
|
||||||
|
# get the ip's of our servers
|
||||||
|
servers = lib.lists.naturalSort (lib.lists.unique (
|
||||||
|
lib.lists.forEach (sort_records_a_server records) (x: x.value)
|
||||||
|
));
|
||||||
|
|
||||||
|
domains_owned = [
|
||||||
|
# for historic reasons we own this
|
||||||
|
"csn.ul.ie"
|
||||||
|
# the main one we use now
|
||||||
|
"skynet.ie"
|
||||||
|
# a backup
|
||||||
|
"ulcompsoc.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
# gets a list of records that match this type
|
||||||
|
filter_records_type = records: r_type: builtins.filter (x: x.r_type == r_type) records;
|
||||||
|
# Get all the A records that are for servers (base record for them)
|
||||||
|
filter_records_a_server = records: builtins.filter (x: builtins.hasAttr "server" x && x.server) (filter_records_type records "A");
|
||||||
|
# Every other A record
|
||||||
|
filter_records_a = records: builtins.filter (x: builtins.hasAttr "server" x && !x.server) (filter_records_type records "A");
|
||||||
|
|
||||||
|
# These functions are to get the final 3 digits of an IP address so we can use them for reverse pointer
|
||||||
|
process_ptr = records: lib.lists.forEach records (x: process_ptr_sub x);
|
||||||
|
process_ptr_sub = record: {
|
||||||
|
record = builtins.substring 9 3 record.record;
|
||||||
|
r_type = "PTR";
|
||||||
|
value = record.value;
|
||||||
|
};
|
||||||
|
ip_ptr_to_int = ip: lib.strings.toInt (builtins.substring 9 3 ip);
|
||||||
|
|
||||||
|
# filter and sort records so we cna group them in the right place later
|
||||||
|
sort_records_a_server = records: builtins.sort (a: b: a.record < b.record) (filter_records_a_server records);
|
||||||
|
sort_records_a = records: builtins.sort (a: b: (ip_ptr_to_int a.value) < (ip_ptr_to_int b.value)) (filter_records_a records);
|
||||||
|
sort_records_cname = records: builtins.sort (a: b: a.value < b.value) (filter_records_type records "CNAME");
|
||||||
|
sort_records_ptr = records: builtins.sort (a: b: (lib.strings.toInt a.record) < (lib.strings.toInt b.record)) (process_ptr (filter_records_type records "PTR"));
|
||||||
|
sort_records_srv = records: builtins.sort (a: b: a.record < b.record) (filter_records_type records "SRV");
|
||||||
|
|
||||||
|
# a tad overkill but type guarding is useful
|
||||||
|
max = x: y:
|
||||||
|
assert builtins.isInt x;
|
||||||
|
assert builtins.isInt y;
|
||||||
|
if x < y
|
||||||
|
then y
|
||||||
|
else x;
|
||||||
|
|
||||||
|
# get teh max length of a list of strings
|
||||||
|
max_len = records: lib.lists.foldr (a: b: (max a b)) 0 (lib.lists.forEach records (record: lib.strings.stringLength record.record));
|
||||||
|
|
||||||
|
# Now that we can get teh max lenth of a list of strings
|
||||||
|
# we can pad it out to the max len +1
|
||||||
|
# this is so that teh generated file is easier for a human to read
|
||||||
|
format_records = records: let
|
||||||
|
offset = (max_len records) + 1;
|
||||||
|
in
|
||||||
|
lib.strings.concatMapStrings (x: "${padString x.record offset} IN ${padString x.r_type 5} ${x.value}\n") records;
|
||||||
|
|
||||||
|
# small function to add spaces until it reaches teh required length
|
||||||
|
padString = text: length: fixedWidthString_post length " " text;
|
||||||
|
|
||||||
|
# like lib.strings.fixedWidthString but postfix
|
||||||
|
# recursive function to extend a string up to a limit
|
||||||
|
fixedWidthString_post = width: filler: str: let
|
||||||
|
strw = lib.stringLength str;
|
||||||
|
reqWidth = width - (lib.stringLength filler);
|
||||||
|
in
|
||||||
|
# this is here because we were manually setting teh length, now max_len does that for us
|
||||||
|
assert lib.assertMsg (strw <= width) "fixedWidthString_post: requested string length (${toString width}) must not be shorter than actual length (${toString strw})";
|
||||||
|
if strw == width
|
||||||
|
then str
|
||||||
|
else (fixedWidthString_post reqWidth filler str) + filler;
|
||||||
|
|
||||||
|
# base config for domains we own (skynet.ie, csn.ul.ie, ulcompsoc.ie)
|
||||||
|
# ";" are comments in this file
|
||||||
|
get_config_file = (
|
||||||
|
domain: records: ''
|
||||||
|
$TTL 60 ; 1 minute
|
||||||
|
; hostmaster@skynet.ie is an email address that recieves stuff related to dns
|
||||||
|
@ IN SOA ${nameserver}.skynet.ie. hostmaster.skynet.ie. (
|
||||||
|
; Serial (YYYYMMDDCC) this has to be updated for each time the record is updated
|
||||||
|
${toString current_date}
|
||||||
|
600 ; Refresh (10 minutes)
|
||||||
|
300 ; Retry (5 minutes)
|
||||||
|
604800 ; Expire (1 week)
|
||||||
|
3600 ; Minimum (1 hour)
|
||||||
|
)
|
||||||
|
|
||||||
|
; @ stands for teh root domain so teh A record below is where ${domain} points to
|
||||||
|
@ NS ns1.skynet.ie.
|
||||||
|
@ NS ns2.skynet.ie.
|
||||||
|
|
||||||
|
; ------------------------------------------
|
||||||
|
; Server Names (A Records)
|
||||||
|
; ------------------------------------------
|
||||||
|
${format_records (sort_records_a_server records)}
|
||||||
|
|
||||||
|
; ------------------------------------------
|
||||||
|
; A (non server names
|
||||||
|
; ------------------------------------------
|
||||||
|
${format_records (sort_records_a records)}
|
||||||
|
|
||||||
|
; ------------------------------------------
|
||||||
|
; CNAMES
|
||||||
|
; ------------------------------------------
|
||||||
|
${format_records (sort_records_cname records)}
|
||||||
|
|
||||||
|
; ------------------------------------------
|
||||||
|
; TXT
|
||||||
|
; ------------------------------------------
|
||||||
|
${format_records (filter_records_type records "TXT")}
|
||||||
|
|
||||||
|
; ------------------------------------------
|
||||||
|
; MX
|
||||||
|
; ------------------------------------------
|
||||||
|
${format_records (filter_records_type records "MX")}
|
||||||
|
|
||||||
|
; ------------------------------------------
|
||||||
|
; SRV
|
||||||
|
; ------------------------------------------
|
||||||
|
${format_records (sort_records_srv records)}
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
# https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/4/html/reference_guide/s2-bind-configuration-zone-reverse
|
||||||
|
# config for our reverse dns pointers (not properly working)
|
||||||
|
get_config_file_rev = (
|
||||||
|
domain: ''
|
||||||
|
$ORIGIN 64-64.99.1.193.in-addr.arpa.
|
||||||
|
$TTL 60 ; 1 minute
|
||||||
|
; hostmaster@skynet.ie is an email address that recieves stuff related to dns
|
||||||
|
@ IN SOA ${nameserver}.skynet.ie. hostmaster.skynet.ie. (
|
||||||
|
; Serial (YYYYMMDDCC) this has to be updated for each time the record is updated
|
||||||
|
${toString current_date}
|
||||||
|
600 ; Refresh (10 minutes)
|
||||||
|
300 ; Retry (5 minutes)
|
||||||
|
604800 ; Expire (1 week)
|
||||||
|
3600 ; Minimum (1 hour)
|
||||||
|
)
|
||||||
|
|
||||||
|
@ NS ns1.skynet.ie.
|
||||||
|
@ NS ns2.skynet.ie.
|
||||||
|
|
||||||
|
; ------------------------------------------
|
||||||
|
; PTR
|
||||||
|
; ------------------------------------------
|
||||||
|
${format_records (sort_records_ptr records)}
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
# arrays of teh two nameservers
|
||||||
|
nameserver_1 = ["193.1.99.109"];
|
||||||
|
nameserver_2 = ["193.1.99.120"];
|
||||||
|
|
||||||
|
primaries = (
|
||||||
|
if cfg.server.primary
|
||||||
|
then
|
||||||
|
# primary servers have no primaries (ones they listen to)
|
||||||
|
[]
|
||||||
|
else if builtins.elem cfg.server.ip nameserver_1
|
||||||
|
then nameserver_2
|
||||||
|
else nameserver_1
|
||||||
|
);
|
||||||
|
|
||||||
|
secondaries = (
|
||||||
|
if cfg.server.primary
|
||||||
|
then
|
||||||
|
if builtins.elem cfg.server.ip nameserver_1
|
||||||
|
then nameserver_2
|
||||||
|
else nameserver_1
|
||||||
|
else []
|
||||||
|
);
|
||||||
|
|
||||||
|
# small function to tidy up the spam of the cache networks, would use teh subnet except all external traffic has the ip of teh router
|
||||||
|
# now limited explicitly to servers that we are administering
|
||||||
|
# See i24-09-30_050 for more information
|
||||||
|
create_cache_networks = map (x: "${toString x}/32") servers;
|
||||||
|
|
||||||
|
# standard function to create the etc file, pass in the text and domain and it makes it
|
||||||
|
create_entry_etc_sub = domain: text: {
|
||||||
|
# Creates /etc/skynet/dns/domain
|
||||||
|
"skynet/dns/${domain}" = {
|
||||||
|
user = "named";
|
||||||
|
group = "named";
|
||||||
|
|
||||||
|
# The UNIX file mode bits
|
||||||
|
mode = "0664";
|
||||||
|
|
||||||
|
# content of the file
|
||||||
|
text = text;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# standard function to create the etc file, pass in the text and domain and it makes it
|
||||||
|
create_entry_etc = domain: type: let
|
||||||
|
domain_records = lib.lists.filter (x: x.domain == domain) records;
|
||||||
|
in
|
||||||
|
# this is the main type of record that most folks are used to
|
||||||
|
if type == "owned"
|
||||||
|
then create_entry_etc_sub domain (get_config_file domain domain_records)
|
||||||
|
# reverse lookups allow for using an IP to find domains pointing to it
|
||||||
|
else if type == "reverse"
|
||||||
|
then create_entry_etc_sub domain (get_config_file_rev domain)
|
||||||
|
else {};
|
||||||
|
|
||||||
|
create_entry_zone = domain: let
|
||||||
|
if_primary_and_owned =
|
||||||
|
if cfg.server.primary && (lib.lists.any (item: item == domain) domains_owned)
|
||||||
|
then ''
|
||||||
|
allow-update { key rfc2136key.skynet.ie.; };
|
||||||
|
dnssec-policy default;
|
||||||
|
inline-signing yes;
|
||||||
|
''
|
||||||
|
else "";
|
||||||
|
in {
|
||||||
|
"${domain}" = {
|
||||||
|
extraConfig = ''
|
||||||
|
${if_primary_and_owned}
|
||||||
|
// for bumping the config
|
||||||
|
// ${toString current_date}
|
||||||
|
'';
|
||||||
|
# really wish teh nixos config didnt use master/slave
|
||||||
|
master = cfg.server.primary;
|
||||||
|
masters = primaries;
|
||||||
|
slaves = secondaries;
|
||||||
|
# need to write this to a file
|
||||||
|
# using the date in it so it will trigger a restart
|
||||||
|
file = "/etc/skynet/dns/${domain}";
|
||||||
|
# no leading whitespace for first line
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
records =
|
||||||
|
config.skynet.records
|
||||||
|
/*
|
||||||
|
Need to "manually" grab it from each server.
|
||||||
|
Nix is laxy evalusted so if it does not need to open a file it wont.
|
||||||
|
This is to iterate through each server (node) and evaluate the dns records for that server.
|
||||||
|
*/
|
||||||
|
++ builtins.concatLists (
|
||||||
|
lib.attrsets.mapAttrsToList (
|
||||||
|
key: value: value.config.services.skynet.dns.records
|
||||||
|
)
|
||||||
|
nodes
|
||||||
|
);
|
||||||
|
|
||||||
|
nameserver =
|
||||||
|
if cfg.server.primary
|
||||||
|
then "ns1"
|
||||||
|
else "ns2";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
../../config/dns.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
server = {
|
||||||
|
enable = lib.mkEnableOption {
|
||||||
|
default = false;
|
||||||
|
description = "Skynet DNS server";
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
|
||||||
|
primary = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
ip = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
ip of this server
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
records = lib.mkOption {
|
||||||
|
description = "Records, sorted based on therir type";
|
||||||
|
type = lib.types.listOf (lib.types.submodule (import ./options-records.nix {
|
||||||
|
inherit lib;
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.server.enable {
|
||||||
|
# logging
|
||||||
|
services.prometheus.exporters.bind = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# services.skynet.backup.normal.backups = ["/etc/skynet/dns"];
|
||||||
|
|
||||||
|
# open the firewall for this
|
||||||
|
skynet_firewall.forward = [
|
||||||
|
"ip daddr ${cfg.server.ip} tcp dport 53 counter packets 0 bytes 0 accept"
|
||||||
|
"ip daddr ${cfg.server.ip} udp dport 53 counter packets 0 bytes 0 accept"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = nameserver;
|
||||||
|
r_type = "A";
|
||||||
|
value = config.services.skynet.host.ip;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.bind.zones = lib.attrsets.mergeAttrsList (
|
||||||
|
# uses teh domains lsited in teh records
|
||||||
|
(lib.lists.forEach domains (domain: (create_entry_zone domain)))
|
||||||
|
# we have to do a reverse dns
|
||||||
|
++ [
|
||||||
|
(create_entry_zone "64-64.99.1.193.in-addr.arpa")
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
environment.etc = lib.attrsets.mergeAttrsList (
|
||||||
|
# uses teh domains lsited in teh records
|
||||||
|
(lib.lists.forEach domains (domain: (create_entry_etc domain "owned")))
|
||||||
|
# we have to do a reverse dns
|
||||||
|
++ [
|
||||||
|
(create_entry_etc "64-64.99.1.193.in-addr.arpa" "reverse")
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
# secrets required
|
||||||
|
age.secrets.dns_dnskeys = {
|
||||||
|
file = ../../secrets/dns_dnskeys.conf.age;
|
||||||
|
owner = "named";
|
||||||
|
group = "named";
|
||||||
|
};
|
||||||
|
|
||||||
|
# basic but ensure teh dns ports are open
|
||||||
|
networking.firewall = {
|
||||||
|
allowedTCPPorts = [53];
|
||||||
|
allowedUDPPorts = [53];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.bind = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
ipv4Only = true;
|
||||||
|
|
||||||
|
# need to take a look at https://nixos.org/manual/nixos/unstable/#module-security-acme-config-dns
|
||||||
|
extraConfig = ''
|
||||||
|
include "/run/agenix/dns_dnskeys";
|
||||||
|
|
||||||
|
statistics-channels {
|
||||||
|
inet 127.0.0.1 port 8053 allow { 127.0.0.1; };
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
|
||||||
|
# piles of no valid RRSIG resolving 'com/DS/IN' errors
|
||||||
|
extraOptions = ''
|
||||||
|
dnssec-validation yes;
|
||||||
|
'';
|
||||||
|
|
||||||
|
# set the upstream dns servers
|
||||||
|
# overrides the default dns servers
|
||||||
|
forwarders = [
|
||||||
|
# Cloudflare
|
||||||
|
"1.1.1.1"
|
||||||
|
# Google
|
||||||
|
"8.8.8.8"
|
||||||
|
# Quad9
|
||||||
|
"9.9.9.9"
|
||||||
|
];
|
||||||
|
|
||||||
|
cacheNetworks =
|
||||||
|
[
|
||||||
|
# this server itself
|
||||||
|
"127.0.0.0/24"
|
||||||
|
|
||||||
|
# skynet server in the dmz
|
||||||
|
"193.1.96.165/32"
|
||||||
|
# all of skynet can use this as a resolver
|
||||||
|
/*
|
||||||
|
Origianl idea, however all external traffic had the ip of the router
|
||||||
|
"193.1.99.64/26"
|
||||||
|
|
||||||
|
So to fix this we need to allow smaller ranges? - Didnt work
|
||||||
|
Fallback is explisitly listing each ip we have
|
||||||
|
|
||||||
|
Now have a function for it
|
||||||
|
*/
|
||||||
|
]
|
||||||
|
++ create_cache_networks;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.bind = {
|
||||||
|
# deletes teh journal files evey start so it no longer stalls out
|
||||||
|
preStart = ''
|
||||||
|
rm -vf /etc/skynet/dns/*.jnl
|
||||||
|
rm -vf /etc/skynet/dns/*.jbk
|
||||||
|
'';
|
||||||
|
restartTriggers = [
|
||||||
|
"${config.environment.etc."skynet/dns/skynet.ie".source}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# creates a folder in /etc for the dns to use
|
||||||
|
users.groups.named = {};
|
||||||
|
|
||||||
|
users.users.named = {
|
||||||
|
createHome = true;
|
||||||
|
home = "/etc/skynet/dns";
|
||||||
|
group = "named";
|
||||||
|
# X11 is to ensure the directory can be traversed
|
||||||
|
homeMode = "711";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
31
applications/dns/options-records.nix
Normal file
31
applications/dns/options-records.nix
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
Define the options for dns records here.
|
||||||
|
They are imported into anything that needs to use them
|
||||||
|
*/
|
||||||
|
{lib, ...}:
|
||||||
|
with lib; {
|
||||||
|
options = {
|
||||||
|
domain = lib.mkOption {
|
||||||
|
description = "Domain this record is for";
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "skynet.ie";
|
||||||
|
};
|
||||||
|
record = lib.mkOption {
|
||||||
|
description = "What you want to name the subdomain.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
r_type = lib.mkOption {
|
||||||
|
description = "Type of record that this is.";
|
||||||
|
type = lib.types.enum ["A" "CNAME" "TXT" "PTR" "SRV" "MX"];
|
||||||
|
};
|
||||||
|
value = lib.mkOption {
|
||||||
|
description = "What the record points to, normally ip or another record.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
server = lib.mkOption {
|
||||||
|
description = "Core record for a server";
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,39 +1,151 @@
|
||||||
{ config, pkgs, lib, inputs, ...}: with lib;
|
{
|
||||||
let
|
config,
|
||||||
cfg = config.services.skynet_email;
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "email";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
# create teh new strings
|
# create teh new strings
|
||||||
create_filter_array = map (x: "(memberOf=cn=${x},ou=groups,${cfg.ldap.base})");
|
create_filter_array = map (x: "(memberOf=cn=${x},ou=groups,${cfg.ldap.base})");
|
||||||
|
|
||||||
create_filter_join = (x: concatStringsSep "" x);
|
create_filter_join = x: concatStringsSep "" x;
|
||||||
|
|
||||||
# thought you could escape racket?
|
# thought you could escape racket?
|
||||||
create_filter = (groups: create_filter_join (create_filter_array groups) );
|
create_filter = groups: create_filter_join (create_filter_array groups);
|
||||||
|
|
||||||
in {
|
# using +mailbox puts the mail in a seperate folder
|
||||||
|
create_skynet_email_int = accounts: mailbox: (map (account: "${account}@skynet.ie") accounts);
|
||||||
|
groups_to_accounts = groups: builtins.concatMap (x: config.skynet.users.${x}) groups;
|
||||||
|
create_skynet_email_attribute = mailbox: groups: (create_skynet_email_int (groups_to_accounts groups) mailbox) ++ ["int_${mailbox}@skynet.ie"];
|
||||||
|
create_skynet_email = mailbox: groups: {
|
||||||
|
name = "${mailbox}@skynet.ie";
|
||||||
|
value = create_skynet_email_attribute mailbox groups;
|
||||||
|
};
|
||||||
|
create_skynet_service_mailboxes = builtins.listToAttrs (map (mailbox: (create_skynet_email mailbox.account mailbox.members)) service_mailboxes);
|
||||||
|
|
||||||
imports = [
|
create_config_to = concatStringsSep "\",\"" (map (mailbox: "${mailbox.account}") service_mailboxes);
|
||||||
./dns.nix
|
|
||||||
./acme.nix
|
service_mailboxes = [
|
||||||
./nginx.nix
|
{
|
||||||
inputs.simple-nixos-mailserver.nixosModule
|
account = "root";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "abuse";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "accounts";
|
||||||
|
members = ["committee"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "compsoc";
|
||||||
|
members = ["committee"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "contact";
|
||||||
|
members = ["committee"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "dbadmin";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "dnsadm";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "hostmaster";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "intersocsrep";
|
||||||
|
members = ["committee"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "mailman";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "security";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "sysadm";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "webadmin";
|
||||||
|
members = ["admin"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "pycon2023";
|
||||||
|
members = ["committee"];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
account = "skynet_topdesk";
|
||||||
|
members = ["admin" "trainee"];
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
options.services.skynet_email = {
|
sieveConfigFile =
|
||||||
|
# https://doc.dovecot.org/configuration_manual/sieve/examples/#plus-addressed-mail-filtering
|
||||||
|
pkgs.writeText "basic_sieve"
|
||||||
|
''
|
||||||
|
require "copy";
|
||||||
|
require "mailbox";
|
||||||
|
require "imap4flags";
|
||||||
|
require ["fileinto", "reject"];
|
||||||
|
require "variables";
|
||||||
|
require "regex";
|
||||||
|
|
||||||
|
# this should be close to teh last step
|
||||||
|
if allof (
|
||||||
|
address :localpart ["To", "Cc"] ["${toString create_config_to}"],
|
||||||
|
address :domain ["To", "Cc"] "skynet.ie"
|
||||||
|
){
|
||||||
|
if address :matches ["To", "Cc"] "*@skynet.ie" {
|
||||||
|
if header :is "X-Spam" "Yes" {
|
||||||
|
fileinto :create "''${1}.Junk";
|
||||||
|
stop;
|
||||||
|
} else {
|
||||||
|
fileinto :create "''${1}";
|
||||||
|
stop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if allof (
|
||||||
|
address :localpart ["From"] ["${toString create_config_to}"],
|
||||||
|
address :domain ["From"] "skynet.ie"
|
||||||
|
){
|
||||||
|
if address :matches ["From"] "*@skynet.ie" {
|
||||||
|
if header :is "X-Spam" "Yes" {
|
||||||
|
fileinto :create "''${1}.Junk";
|
||||||
|
stop;
|
||||||
|
} else {
|
||||||
|
fileinto :create "''${1}";
|
||||||
|
stop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
inputs.simple-nixos-mailserver.nixosModule
|
||||||
|
|
||||||
|
# for teh config
|
||||||
|
../config/users.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
# options that need to be passed in to make this work
|
# options that need to be passed in to make this work
|
||||||
|
|
||||||
enable = mkEnableOption "Skynet Email";
|
enable = mkEnableOption "Skynet Email";
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "skynet.ie";
|
default = "skynet.ie";
|
||||||
|
@ -63,7 +175,7 @@
|
||||||
hosts = mkOption {
|
hosts = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [
|
default = [
|
||||||
"ldaps://sso.skynet.ie"
|
"ldaps://account.skynet.ie"
|
||||||
];
|
];
|
||||||
description = lib.mdDoc "ldap domains";
|
description = lib.mdDoc "ldap domains";
|
||||||
};
|
};
|
||||||
|
@ -85,58 +197,195 @@
|
||||||
default = "cn=admin,${cfg.ldap.base}";
|
default = "cn=admin,${cfg.ldap.base}";
|
||||||
description = lib.mdDoc "where to find users";
|
description = lib.mdDoc "where to find users";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.skynet_backup.normal.backups = [
|
services.skynet.backup.normal.backups = [
|
||||||
"/var/vmail"
|
#"/var/vmail"
|
||||||
"/var/dkim"
|
"/var/dkim"
|
||||||
];
|
];
|
||||||
|
|
||||||
age.secrets.ldap_pw.file = ../secrets/ldap/pw.age;
|
age.secrets.ldap_pw.file = ../secrets/ldap/pw.age;
|
||||||
|
|
||||||
|
security.acme.certs = {
|
||||||
|
"mail" = {
|
||||||
|
domain = "mail.skynet.ie";
|
||||||
|
extraDomainNames = [
|
||||||
|
"imap.skynet.ie"
|
||||||
|
"pop3.skynet.ie"
|
||||||
|
"smtp.skynet.ie"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
"imap" = {
|
||||||
|
domain = "imap.skynet.ie";
|
||||||
|
extraDomainNames = [
|
||||||
|
"mail.skynet.ie"
|
||||||
|
"pop3.skynet.ie"
|
||||||
|
"smtp.skynet.ie"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
"pop3" = {
|
||||||
|
domain = "pop3.skynet.ie";
|
||||||
|
extraDomainNames = [
|
||||||
|
"imap.skynet.ie"
|
||||||
|
"mail.skynet.ie"
|
||||||
|
"smtp.skynet.ie"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
"smtp" = {
|
||||||
|
domain = "smtp.skynet.ie";
|
||||||
|
extraDomainNames = [
|
||||||
|
"imap.skynet.ie"
|
||||||
|
"pop3.skynet.ie"
|
||||||
|
"mail.skynet.ie"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# to provide the certs
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"mail.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "mail";
|
||||||
|
# override the inbuilt nginx config
|
||||||
|
enableACME = false;
|
||||||
|
serverName = "mail.skynet.ie";
|
||||||
|
};
|
||||||
|
|
||||||
|
"imap.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "imap";
|
||||||
|
# override the inbuilt nginx config
|
||||||
|
enableACME = false;
|
||||||
|
serverName = "imap.skynet.ie";
|
||||||
|
};
|
||||||
|
|
||||||
|
"pop3.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "pop3";
|
||||||
|
# override the inbuilt nginx config
|
||||||
|
enableACME = false;
|
||||||
|
serverName = "pop3.skynet.ie";
|
||||||
|
};
|
||||||
|
|
||||||
|
"smtp.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "smtp";
|
||||||
|
# override the inbuilt nginx config
|
||||||
|
enableACME = false;
|
||||||
|
serverName = "smtp.skynet.ie";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# set up dns record for it
|
# set up dns record for it
|
||||||
skynet_dns.records = [
|
services.skynet.dns.records =
|
||||||
|
[
|
||||||
|
# core record
|
||||||
|
{
|
||||||
|
record = "@";
|
||||||
|
r_type = "MX";
|
||||||
|
# the number is the priority in teh case of multiple mailservers
|
||||||
|
value = "10 mail.${cfg.domain}.";
|
||||||
|
}
|
||||||
|
|
||||||
# basic one
|
# basic one
|
||||||
{record="mail"; r_type="A"; value=cfg.host.ip;}
|
{
|
||||||
|
record = "mail";
|
||||||
|
r_type = "A";
|
||||||
|
value = config.services.skynet.host.ip;
|
||||||
|
}
|
||||||
|
#DNS config for K-9 Mail
|
||||||
|
{
|
||||||
|
record = "imap";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "mail";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "pop3";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "mail";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "smtp";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "mail";
|
||||||
|
}
|
||||||
|
|
||||||
# TXT records, all tehse are inside escaped strings to allow using ""
|
# TXT records, all tehse are inside escaped strings to allow using ""
|
||||||
# SPF record
|
|
||||||
{record="${cfg.domain}."; r_type="TXT"; value=''"v=spf1 a:${cfg.sub}.${cfg.domain} -all"'';}
|
|
||||||
|
|
||||||
# DKIM keys
|
|
||||||
{record="mail._domainkey.skynet.ie."; r_type="TXT"; value=''"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxju1Ie60BdHwyFVPNQKovL/cX9IFPzBKgjnHZf+WBzDCFKSBpf7NvnfXajtFDQN0poaN/Qfifid+V55ZCNDBn8Y3qZa4Y69iNiLw2DdvYf0HdnxX6+pLpbmj7tikGGLJ62xnhkJhoELnz5gCOhpyoiv0tSQVaJpaGZmoll861/QIDAQAB"'';}
|
|
||||||
{record="mail._domainkey.ulcompsoc.ie."; r_type="TXT"; value=''"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDl8ptSASx37t5sfmU2d2Y6yi9AVrsNFBZDmJ2uaLa4NuvAjxGQCw4wx+1Jui/HOuKYLpntLsjN851wgPR+3i51g4OblqBDvcHn9NYgWRZfHj9AASANQjdsaAbkXuyKuO46hZqeWlpESAcD6a4Evam4fkm+kiZC0+rccb4cWgsuLwIDAQAB"'';}
|
|
||||||
|
|
||||||
# DMARC
|
|
||||||
{record="_dmarc.${cfg.domain}."; r_type="TXT"; value=''"v=DMARC1; p=none"'';}
|
|
||||||
|
|
||||||
# reverse pointer
|
# reverse pointer
|
||||||
{record=cfg.host.ip; r_type="PTR"; value="${cfg.sub}.${cfg.domain}.";}
|
{
|
||||||
|
record = config.services.skynet.host.ip;
|
||||||
|
r_type = "PTR";
|
||||||
|
value = "${cfg.sub}.${cfg.domain}.";
|
||||||
|
}
|
||||||
|
|
||||||
# SRV records to help gmail on android etc find the correct mail.skynet.ie domain for config rather than just defaulting to skynet.ie
|
# SRV records to help gmail on android etc find the correct mail.skynet.ie domain for config rather than just defaulting to skynet.ie
|
||||||
# https://serverfault.com/questions/935192/how-to-setup-auto-configure-email-for-android-mail-app-on-your-server/1018406#1018406
|
# https://serverfault.com/questions/935192/how-to-setup-auto-configure-email-for-android-mail-app-on-your-server/1018406#1018406
|
||||||
# response should be:
|
# response should be:
|
||||||
# _imap._tcp SRV 0 1 143 imap.example.com.
|
# _imap._tcp SRV 0 1 143 imap.example.com.
|
||||||
{record="_imaps._tcp"; r_type="SRV"; value="0 1 993 ${cfg.sub}.${cfg.domain}";}
|
{
|
||||||
{record="_imap._tcp"; r_type="SRV"; value="0 1 143 ${cfg.sub}.${cfg.domain}";}
|
record = "_imaps._tcp";
|
||||||
{record="_submissions._tcp"; r_type="SRV"; value="0 1 465 ${cfg.sub}.${cfg.domain}";}
|
r_type = "SRV";
|
||||||
{record="_submission._tcp"; r_type="SRV"; value="0 1 587 ${cfg.sub}.${cfg.domain}";}
|
value = "0 1 993 ${cfg.sub}.${cfg.domain}.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_imap._tcp";
|
||||||
|
r_type = "SRV";
|
||||||
|
value = "0 1 143 ${cfg.sub}.${cfg.domain}.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_submissions._tcp";
|
||||||
|
r_type = "SRV";
|
||||||
|
value = "0 1 465 ${cfg.sub}.${cfg.domain}.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_submission._tcp";
|
||||||
|
r_type = "SRV";
|
||||||
|
value = "0 1 587 ${cfg.sub}.${cfg.domain}.";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# SPF record
|
||||||
|
++ [
|
||||||
|
{
|
||||||
|
record = "${cfg.domain}.";
|
||||||
|
r_type = "TXT";
|
||||||
|
value = ''"v=spf1 a:${cfg.sub}.${cfg.domain} ip4:${config.services.skynet.host.ip} -all"'';
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# DKIM keys
|
||||||
|
++ [
|
||||||
|
{
|
||||||
|
record = "mail._domainkey.skynet.ie.";
|
||||||
|
r_type = "TXT";
|
||||||
|
value = ''"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxju1Ie60BdHwyFVPNQKovL/cX9IFPzBKgjnHZf+WBzDCFKSBpf7NvnfXajtFDQN0poaN/Qfifid+V55ZCNDBn8Y3qZa4Y69iNiLw2DdvYf0HdnxX6+pLpbmj7tikGGLJ62xnhkJhoELnz5gCOhpyoiv0tSQVaJpaGZmoll861/QIDAQAB"'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
domain = "ulcompsoc.ie";
|
||||||
|
record = "mail._domainkey.ulcompsoc.ie.";
|
||||||
|
r_type = "TXT";
|
||||||
|
value = ''"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDl8ptSASx37t5sfmU2d2Y6yi9AVrsNFBZDmJ2uaLa4NuvAjxGQCw4wx+1Jui/HOuKYLpntLsjN851wgPR+3i51g4OblqBDvcHn9NYgWRZfHj9AASANQjdsaAbkXuyKuO46hZqeWlpESAcD6a4Evam4fkm+kiZC0+rccb4cWgsuLwIDAQAB"'';
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# DMARC
|
||||||
|
++ [
|
||||||
|
{
|
||||||
|
record = "_dmarc.${cfg.domain}.";
|
||||||
|
r_type = "TXT";
|
||||||
|
# p : quarantine => sends to spam, reject => never sent
|
||||||
|
# rua : mail that receives reports about DMARC activity
|
||||||
|
# pct : percentage of unathenticated messages that DMARC stops
|
||||||
|
# adkim : alignment policy for DKIM, s => Strict, subdomains arent allowed, r => relaxed, subdomains allowed
|
||||||
|
# aspf : alignment policy for SPF, s => Strict, subdomains arent allowed, r => relaxed, subdomains allowed
|
||||||
|
# sp : DMARC policy for subdomains, none => no action, reports to rua, quarantine => spam, reject => never sent
|
||||||
|
value = ''"v=DMARC1; p=quarantine; rua=mailto:mailman@skynet.ie; pct=100; adkim=s; aspf=s; sp=quarantine"'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
# to provide the certs
|
|
||||||
services.nginx.virtualHosts = {
|
|
||||||
"${cfg.sub}.${cfg.domain}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
useACMEHost = "skynet";
|
|
||||||
# override the inbuilt nginx config
|
|
||||||
enableACME = false;
|
|
||||||
serverName = "${cfg.sub}.${cfg.domain}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#https://nixos-mailserver.readthedocs.io/en/latest/add-roundcube.html
|
#https://nixos-mailserver.readthedocs.io/en/latest/add-roundcube.html
|
||||||
users.groups.nginx = {};
|
users.groups.nginx = {};
|
||||||
users.groups.roundcube = {};
|
users.groups.roundcube = {};
|
||||||
|
@ -157,7 +406,7 @@
|
||||||
$config['login_username_filter'] = "email";
|
$config['login_username_filter'] = "email";
|
||||||
$config['ldap_public']['public'] = array(
|
$config['ldap_public']['public'] = array(
|
||||||
'name' => 'Public LDAP Addressbook',
|
'name' => 'Public LDAP Addressbook',
|
||||||
'hosts' => array('sso.skynet.ie'),
|
'hosts' => 'tls://account.skynet.ie',
|
||||||
'port' => 636 ,
|
'port' => 636 ,
|
||||||
'user_specific' => false,
|
'user_specific' => false,
|
||||||
'base_dn' => 'ou=users,dc=skynet,dc=ie',
|
'base_dn' => 'ou=users,dc=skynet,dc=ie',
|
||||||
|
@ -172,6 +421,9 @@
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# for https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/issues/275
|
||||||
|
services.dovecot2.sieve.extensions = ["fileinto"];
|
||||||
|
|
||||||
mailserver = {
|
mailserver = {
|
||||||
enable = true;
|
enable = true;
|
||||||
fqdn = "${cfg.sub}.${cfg.domain}";
|
fqdn = "${cfg.sub}.${cfg.domain}";
|
||||||
|
@ -179,6 +431,12 @@
|
||||||
cfg.domain
|
cfg.domain
|
||||||
];
|
];
|
||||||
|
|
||||||
|
enableManageSieve = true;
|
||||||
|
|
||||||
|
lmtpSaveToDetailMailbox = "yes";
|
||||||
|
|
||||||
|
extraVirtualAliases = create_skynet_service_mailboxes;
|
||||||
|
|
||||||
# use the letsencrypt certs
|
# use the letsencrypt certs
|
||||||
certificateScheme = "acme";
|
certificateScheme = "acme";
|
||||||
|
|
||||||
|
@ -211,14 +469,48 @@
|
||||||
uidAttribute = "skMail";
|
uidAttribute = "skMail";
|
||||||
mailAttribute = "skMail";
|
mailAttribute = "skMail";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# feckin spammers
|
# feckin spammers
|
||||||
rejectRecipients = [
|
rejectRecipients = [
|
||||||
|
|
||||||
];
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dovecot2.sieve.scripts = {
|
||||||
|
before = sieveConfigFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
# This is to add a bcc to outgoing mail
|
||||||
|
# this then interacts with teh filters to put it in the right folder
|
||||||
|
# we can directly add to the postfix service here
|
||||||
|
services.postfix = let
|
||||||
|
# mostly copied from the upstream mailserver config/functions
|
||||||
|
mappedFile = name: "hash:/var/lib/postfix/conf/${name}";
|
||||||
|
|
||||||
|
sender_bcc_maps_file = let
|
||||||
|
content = lookupTableToString create_skynet_service_bcc;
|
||||||
|
in
|
||||||
|
builtins.toFile "sender_bcc_maps" content;
|
||||||
|
|
||||||
|
lookupTableToString = attrs: let
|
||||||
|
valueToString = value: lib.concatStringsSep ", " value;
|
||||||
|
in
|
||||||
|
lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name} ${valueToString value}") attrs);
|
||||||
|
|
||||||
|
# convert the mailboxes config to something that can be used here
|
||||||
|
create_skynet_email_bcc = mailbox: {
|
||||||
|
name = "${mailbox}@skynet.ie";
|
||||||
|
value = ["${mailbox}@skynet.ie"];
|
||||||
|
};
|
||||||
|
create_skynet_service_bcc = builtins.listToAttrs (map (mailbox: (create_skynet_email_bcc mailbox.account)) service_mailboxes);
|
||||||
|
in {
|
||||||
|
mapFiles."sender_bcc_maps" = sender_bcc_maps_file;
|
||||||
|
|
||||||
|
config = {
|
||||||
|
sender_bcc_maps = [
|
||||||
|
(mappedFile "sender_bcc_maps")
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# tune the spam filter
|
# tune the spam filter
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
{lib, pkgs, config, ...}: {
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
# using https://github.com/greaka/ops/blob/818be4c4dea9129abe0f086d738df4cb0bb38288/apps/restic/options.nix as a base
|
# using https://github.com/greaka/ops/blob/818be4c4dea9129abe0f086d738df4cb0bb38288/apps/restic/options.nix as a base
|
||||||
options = {
|
options = {
|
||||||
skynet_firewall = {
|
skynet_firewall = {
|
||||||
|
@ -42,9 +46,7 @@
|
||||||
A list of UDP ports for the machiene running the firewall
|
A list of UDP ports for the machiene running the firewall
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -56,8 +58,7 @@
|
||||||
|
|
||||||
# fules for the firewall
|
# fules for the firewall
|
||||||
# beware of EOL conversion.
|
# beware of EOL conversion.
|
||||||
networking.nftables.ruleset =
|
networking.nftables.ruleset = ''
|
||||||
''
|
|
||||||
# using https://oxcrag.net/2021/12/25/build-your-own-router-with-nftables-part-1/ as a guide
|
# using https://oxcrag.net/2021/12/25/build-your-own-router-with-nftables-part-1/ as a guide
|
||||||
|
|
||||||
# Clear out any existing rules
|
# Clear out any existing rules
|
||||||
|
@ -165,8 +166,5 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.services.skynet_games;
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
./dns.nix
|
|
||||||
|
|
||||||
./games/minecraft.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
options.services.skynet_games = {
|
|
||||||
enable = mkEnableOption "Skynet Games";
|
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = {
|
|
||||||
tld = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "ie";
|
|
||||||
};
|
|
||||||
|
|
||||||
base = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "skynet";
|
|
||||||
};
|
|
||||||
|
|
||||||
sub = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "games";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
skynet_dns.records = [
|
|
||||||
# need a base domain
|
|
||||||
{record=cfg.domain.sub; r_type="CNAME"; value=cfg.host.name;}
|
|
||||||
];
|
|
||||||
|
|
||||||
# the minecraft servers
|
|
||||||
services.skynet_games_minecraft = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = cfg.host.ip;
|
|
||||||
name = cfg.domain.sub;
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = {
|
|
||||||
sub = "minecraft.${cfg.domain.sub}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
129
applications/git/forgejo.nix
Normal file
129
applications/git/forgejo.nix
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "forgejo";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
|
domain_base = "${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
|
domain_full = "${cfg.domain.sub}.${domain_base}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet Forgejo";
|
||||||
|
|
||||||
|
domain = {
|
||||||
|
tld = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "ie";
|
||||||
|
};
|
||||||
|
|
||||||
|
base = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "skynet";
|
||||||
|
};
|
||||||
|
|
||||||
|
sub = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
forgejo = {
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 3000;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# age.secrets.forgejo-mailer-password = {
|
||||||
|
# file = ../../secrets/forgejo/mailer-password.age;
|
||||||
|
# mode = "400";
|
||||||
|
# owner = "forgejo";
|
||||||
|
# };
|
||||||
|
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"
|
||||||
|
];
|
||||||
|
|
||||||
|
# using https://nixos.org/manual/nixos/stable/index.html#module-services-gitlab as a guide
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = cfg.domain.sub;
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
# main site
|
||||||
|
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString cfg.forgejo.port}";
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 1000M;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# for signing reasons
|
||||||
|
programs.gnupg.agent = {
|
||||||
|
enable = true;
|
||||||
|
enableSSHSupport = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.forgejo;
|
||||||
|
database.type = "sqlite3";
|
||||||
|
# Enable support for Git Large File Storage
|
||||||
|
lfs.enable = true;
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
DOMAIN = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
|
# You need to specify this to remove the port from URLs in the web UI.
|
||||||
|
ROOT_URL = "https://${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}/";
|
||||||
|
HTTP_PORT = cfg.forgejo.port;
|
||||||
|
};
|
||||||
|
|
||||||
|
# You can temporarily allow registration to create an admin user.
|
||||||
|
service.DISABLE_REGISTRATION = true;
|
||||||
|
|
||||||
|
# Add support for actions, based on act: https://github.com/nektos/act
|
||||||
|
actions = {
|
||||||
|
ENABLED = true;
|
||||||
|
DEFAULT_ACTIONS_URL = "github";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Allow for signing off merge requests
|
||||||
|
# "repository.signing" = {
|
||||||
|
# SIGNING_KEY = "5B2DED0FE9F8627A";
|
||||||
|
# SIGNING_NAME = "Skynet";
|
||||||
|
# SIGNING_EMAIL = "forgejo@glados.skynet.ie";
|
||||||
|
# MERGES = "always";
|
||||||
|
# };
|
||||||
|
|
||||||
|
# Sending emails is completely optional
|
||||||
|
# You can send a test email from the web UI at:
|
||||||
|
# Profile Picture > Site Administration > Configuration > Mailer Configuration
|
||||||
|
# mailer = {
|
||||||
|
# ENABLED = true;
|
||||||
|
# SMTP_ADDR = "mail.${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
|
# FROM = "noreply@${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
|
# USER = "noreply@${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
# mailerPasswordFile = config.age.secrets.forgejo-mailer-password.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
159
applications/git/forgejo_runner.nix
Normal file
159
applications/git/forgejo_runner.nix
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "forgejo_runner";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet ForgeJo Runner";
|
||||||
|
|
||||||
|
runner = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = config.networking.hostName;
|
||||||
|
};
|
||||||
|
|
||||||
|
website = mkOption {
|
||||||
|
default = "https://forgejo.skynet.ie";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
default = "gitea-runner";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# https://search.nixos.org/options?from=0&size=50&sort=alpha_desc&type=packages&query=services.gitlab-runner.
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
forgejo-actions-runner
|
||||||
|
];
|
||||||
|
|
||||||
|
age.secrets.forgejo_runner_token = {
|
||||||
|
file = ../../secrets/forgejo/runners/token.age;
|
||||||
|
owner = cfg.runner.user;
|
||||||
|
group = cfg.runner.user;
|
||||||
|
};
|
||||||
|
|
||||||
|
# make sure the ssh config stuff is in teh right palce
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
#"d /home/${cfg.runner.user} 0755 ${cfg.runner.user} ${cfg.runner.user}"
|
||||||
|
"L+ /home/${cfg.runner.user}/.ssh/config 0755 ${cfg.runner.user} ${cfg.runner.user} - ${./ssh_config}"
|
||||||
|
];
|
||||||
|
age.secrets.forgejo_runner_ssh = {
|
||||||
|
file = ../../secrets/forgejo/runners/ssh.age;
|
||||||
|
mode = "600";
|
||||||
|
owner = "${cfg.runner.user}";
|
||||||
|
group = "${cfg.runner.user}";
|
||||||
|
symlink = false;
|
||||||
|
path = "/home/${cfg.runner.user}/.ssh/skynet/root";
|
||||||
|
};
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
settings = {
|
||||||
|
trusted-users = [
|
||||||
|
# allow the runner to build nix stuff and to use the cache
|
||||||
|
"gitea-runner"
|
||||||
|
];
|
||||||
|
trusted-public-keys = [
|
||||||
|
"skynet-cache:zMFLzcRZPhUpjXUy8SF8Cf7KGAZwo98SKrzeXvdWABo="
|
||||||
|
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
|
||||||
|
];
|
||||||
|
substituters = [
|
||||||
|
"https://nix-cache.skynet.ie/skynet-cache/"
|
||||||
|
"https://cache.nixos.org/"
|
||||||
|
];
|
||||||
|
trusted-substituters = [
|
||||||
|
"https://nix-cache.skynet.ie/skynet-cache/"
|
||||||
|
"https://cache.nixos.org/"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# very basic setup to always be watching for changes in teh cache
|
||||||
|
systemd.services.attic-uploader = {
|
||||||
|
enable = true;
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.attic-client}/bin/attic watch-store skynet-cache";
|
||||||
|
User = "root";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# give teh runner user a home to store teh ssh config stuff
|
||||||
|
systemd.services.gitea-runner-default.serviceConfig = {
|
||||||
|
DynamicUser = lib.mkForce false;
|
||||||
|
User = lib.mkForce cfg.runner.user;
|
||||||
|
};
|
||||||
|
users = {
|
||||||
|
groups."${cfg.runner.user}" = {};
|
||||||
|
users."${cfg.runner.user}" = {
|
||||||
|
#isSystemUser = true;
|
||||||
|
isNormalUser = true;
|
||||||
|
group = cfg.runner.user;
|
||||||
|
createHome = true;
|
||||||
|
shell = pkgs.bash;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.kernel.sysctl."net.ipv4.ip_forward" = true; # 1
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
|
||||||
|
# taken from https://github.com/NixOS/nixpkgs/issues/245365#issuecomment-1663854128
|
||||||
|
virtualisation.docker.listenOptions = ["/run/docker.sock" "127.0.0.1:2375"];
|
||||||
|
|
||||||
|
# the actual runner
|
||||||
|
services.gitea-actions-runner = {
|
||||||
|
package = pkgs.forgejo-actions-runner;
|
||||||
|
instances.default = {
|
||||||
|
enable = true;
|
||||||
|
name = cfg.runner.name;
|
||||||
|
url = cfg.runner.website;
|
||||||
|
tokenFile = config.age.secrets.forgejo_runner_token.path;
|
||||||
|
labels = [
|
||||||
|
## optionally provide native execution on the host:
|
||||||
|
"nix:host"
|
||||||
|
"docker:docker://node:22-bookworm"
|
||||||
|
"ubuntu-latest:docker://node:22-bookworm"
|
||||||
|
];
|
||||||
|
|
||||||
|
hostPackages = with pkgs; [
|
||||||
|
# default ones
|
||||||
|
bash
|
||||||
|
coreutils
|
||||||
|
curl
|
||||||
|
gawk
|
||||||
|
git
|
||||||
|
gnused
|
||||||
|
nodejs
|
||||||
|
wget
|
||||||
|
|
||||||
|
# useful to have in path
|
||||||
|
jq
|
||||||
|
which
|
||||||
|
dpkg
|
||||||
|
zip
|
||||||
|
git-lfs
|
||||||
|
|
||||||
|
# used in deployments
|
||||||
|
inputs.colmena.defaultPackage."x86_64-linux"
|
||||||
|
attic-client
|
||||||
|
lix
|
||||||
|
openssh
|
||||||
|
sudo
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,28 +1,22 @@
|
||||||
{ config, pkgs, lib, ... }:
|
{
|
||||||
with lib;
|
config,
|
||||||
let
|
pkgs,
|
||||||
cfg = config.services.skynet_gitlab;
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "gitlab";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
|
domain_base = "${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
|
domain_full = "${cfg.domain.sub}.${domain_base}";
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./acme.nix
|
|
||||||
./dns.nix
|
|
||||||
./firewall.nix
|
|
||||||
./nginx.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
options.services.skynet_gitlab = {
|
options.services.skynet."${name}" = {
|
||||||
enable = mkEnableOption "Skynet Gitlab";
|
enable = mkEnableOption "Skynet Gitlab";
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = {
|
domain = {
|
||||||
tld = mkOption {
|
tld = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -36,12 +30,13 @@
|
||||||
|
|
||||||
sub = mkOption {
|
sub = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "gitlab";
|
default = name;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
# changes teh ssh user
|
||||||
default = "git";
|
default = "git";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,9 +46,7 @@
|
||||||
default = "dc=skynet,dc=ie";
|
default = "dc=skynet,dc=ie";
|
||||||
description = lib.mdDoc "The base address in the ldap server";
|
description = lib.mdDoc "The base address in the ldap server";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
@ -63,41 +56,77 @@
|
||||||
# grep -r --exclude-dir={docker,containers,log,sys,nix,proc} gitlab /
|
# grep -r --exclude-dir={docker,containers,log,sys,nix,proc} gitlab /
|
||||||
|
|
||||||
age.secrets.gitlab_pw = {
|
age.secrets.gitlab_pw = {
|
||||||
file = ../secrets/gitlab/pw.age;
|
file = ../../secrets/gitlab/pw.age;
|
||||||
owner = cfg.user;
|
owner = cfg.user;
|
||||||
group = cfg.user;
|
group = cfg.user;
|
||||||
};
|
};
|
||||||
age.secrets.gitlab_secrets_db = {
|
age.secrets.gitlab_secrets_db = {
|
||||||
file = ../secrets/gitlab/secrets_db.age;
|
file = ../../secrets/gitlab/secrets_db.age;
|
||||||
owner = cfg.user;
|
owner = cfg.user;
|
||||||
group = cfg.user;
|
group = cfg.user;
|
||||||
};
|
};
|
||||||
age.secrets.gitlab_secrets_secret = {
|
age.secrets.gitlab_secrets_secret = {
|
||||||
file = ../secrets/gitlab/secrets_secret.age;
|
file = ../../secrets/gitlab/secrets_secret.age;
|
||||||
owner = cfg.user;
|
owner = cfg.user;
|
||||||
group = cfg.user;
|
group = cfg.user;
|
||||||
};
|
};
|
||||||
age.secrets.gitlab_secrets_otp = {
|
age.secrets.gitlab_secrets_otp = {
|
||||||
file = ../secrets/gitlab/secrets_otp.age;
|
file = ../../secrets/gitlab/secrets_otp.age;
|
||||||
owner = cfg.user;
|
owner = cfg.user;
|
||||||
group = cfg.user;
|
group = cfg.user;
|
||||||
};
|
};
|
||||||
age.secrets.gitlab_secrets_jws = {
|
age.secrets.gitlab_secrets_jws = {
|
||||||
file = ../secrets/gitlab/secrets_jws.age;
|
file = ../../secrets/gitlab/secrets_jws.age;
|
||||||
owner = cfg.user;
|
owner = cfg.user;
|
||||||
group = cfg.user;
|
group = cfg.user;
|
||||||
};
|
};
|
||||||
age.secrets.gitlab_db_pw = {
|
age.secrets.gitlab_db_pw = {
|
||||||
file = ../secrets/gitlab/db_pw.age;
|
file = ../../secrets/gitlab/db_pw.age;
|
||||||
owner = cfg.user;
|
owner = cfg.user;
|
||||||
group = cfg.user;
|
group = cfg.user;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"
|
||||||
|
# Lets Encrypt seems to have a 4 levels limit for certs
|
||||||
|
"*.pages.${cfg.domain.base}.${cfg.domain.tld}"
|
||||||
|
];
|
||||||
|
|
||||||
# using https://nixos.org/manual/nixos/stable/index.html#module-services-gitlab as a guide
|
# using https://nixos.org/manual/nixos/stable/index.html#module-services-gitlab as a guide
|
||||||
skynet_dns.records = [
|
services.skynet.dns.records = [
|
||||||
{record=cfg.domain.sub; r_type="CNAME"; value=cfg.host.name;}
|
{
|
||||||
|
record = cfg.domain.sub;
|
||||||
|
r_type = "A";
|
||||||
|
value = config.services.skynet.host.ip;
|
||||||
|
}
|
||||||
# for gitlab pages
|
# for gitlab pages
|
||||||
{record="*.pages.${cfg.domain.base}.${cfg.domain.tld}."; r_type="A"; value=cfg.host.ip;}
|
{
|
||||||
|
record = "*.pages.${cfg.domain.base}.${cfg.domain.tld}.";
|
||||||
|
r_type = "A";
|
||||||
|
value = config.services.skynet.host.ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
# for email
|
||||||
|
{
|
||||||
|
record = "${cfg.domain.sub}";
|
||||||
|
r_type = "MX";
|
||||||
|
value = ''10 ${domain_full}.'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = config.services.skynet.host.ip;
|
||||||
|
r_type = "PTR";
|
||||||
|
value = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "${domain_full}.";
|
||||||
|
r_type = "TXT";
|
||||||
|
value = ''"v=spf1 a:gitlab.skynet.ie -all"'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_dmarc.${domain_full}.";
|
||||||
|
r_type = "TXT";
|
||||||
|
value = ''"v=DMARC1; p=none"'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
@ -112,7 +141,12 @@
|
||||||
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" = {
|
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
useACMEHost = "skynet";
|
useACMEHost = "skynet";
|
||||||
locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
|
locations."/" = {
|
||||||
|
proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 1000M;
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# pages
|
# pages
|
||||||
|
@ -123,6 +157,13 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# set a valid HELO address
|
||||||
|
services.postfix = {
|
||||||
|
hostname = lib.mkForce domain_full;
|
||||||
|
origin = lib.mkForce domain_full;
|
||||||
|
domain = lib.mkForce domain_base;
|
||||||
|
};
|
||||||
|
|
||||||
services.gitlab = {
|
services.gitlab = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
@ -156,13 +197,11 @@
|
||||||
auth-server = "https://gitlab.example.com";
|
auth-server = "https://gitlab.example.com";
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
#smtp = {
|
|
||||||
# enable = true;
|
# use the local email client
|
||||||
# address = "localhost";
|
smtp.enable = true;
|
||||||
# port = 25;
|
|
||||||
#};
|
|
||||||
secrets = {
|
secrets = {
|
||||||
dbFile = config.age.secrets.gitlab_secrets_db.path;
|
dbFile = config.age.secrets.gitlab_secrets_db.path;
|
||||||
secretFile = config.age.secrets.gitlab_secrets_secret.path;
|
secretFile = config.age.secrets.gitlab_secrets_secret.path;
|
||||||
|
@ -179,7 +218,7 @@
|
||||||
servers = {
|
servers = {
|
||||||
main = {
|
main = {
|
||||||
label = "Skynet";
|
label = "Skynet";
|
||||||
host = "sso.skynet.ie";
|
host = "account.skynet.ie";
|
||||||
port = 636;
|
port = 636;
|
||||||
uid = "uid";
|
uid = "uid";
|
||||||
encryption = "simple_tls";
|
encryption = "simple_tls";
|
||||||
|
@ -205,7 +244,7 @@
|
||||||
# default for pages is set to 8090 but that leaves an "ugly" port in the url,
|
# default for pages is set to 8090 but that leaves an "ugly" port in the url,
|
||||||
# override it here to make it look good
|
# override it here to make it look good
|
||||||
port = 80;
|
port = 80;
|
||||||
#external_http = ["${cfg.host.ip}:80"];
|
#external_http = ["${config.services.skynet.host.ip}:80"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
5
applications/git/ssh_config
Normal file
5
applications/git/ssh_config
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
Host *.skynet.ie 193.1.99.* 193.1.96.165
|
||||||
|
User root
|
||||||
|
IdentityFile ~/.ssh/skynet/root
|
||||||
|
IdentitiesOnly yes
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.services.skynet_gitlab_runner;
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
options.services.skynet_gitlab_runner = {
|
|
||||||
enable = mkEnableOption "Skynet Gitlab Runner";
|
|
||||||
|
|
||||||
runner = {
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
gitlab = mkOption {
|
|
||||||
default = "https://gitlab.skynet.ie";
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
description = mkOption {
|
|
||||||
default = cfg.runner.name;
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
docker = {
|
|
||||||
image = mkOption {
|
|
||||||
default = "alpine:latest";
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
cleanup_dates = mkOption {
|
|
||||||
# https://man.archlinux.org/man/systemd.time.7#CALENDAR_EVENTS
|
|
||||||
# it will use a lot of storage so clear it daily, may change to hourly if required
|
|
||||||
default = "daily";
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
# https://search.nixos.org/options?from=0&size=50&sort=alpha_desc&type=packages&query=services.gitlab-runner.
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.gitlab-runner
|
|
||||||
];
|
|
||||||
|
|
||||||
age.secrets."${cfg.runner.name}".file = ../secrets/gitlab/runners/${cfg.runner.name}.age;
|
|
||||||
|
|
||||||
boot.kernel.sysctl."net.ipv4.ip_forward" = true; # 1
|
|
||||||
|
|
||||||
services.gitlab-runner = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
clear-docker-cache = {
|
|
||||||
enable = true;
|
|
||||||
dates = cfg.runner.docker.cleanup_dates;
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
# might make a function later to have multiple runners, might never need it though
|
|
||||||
"${cfg.runner.name}" = {
|
|
||||||
cloneUrl = cfg.runner.gitlab;
|
|
||||||
description = cfg.runner.description;
|
|
||||||
registrationConfigFile = config.age.secrets."${cfg.runner.name}".path;
|
|
||||||
dockerImage = cfg.runner.docker.image;
|
|
||||||
|
|
||||||
# from https://nixos.wiki/wiki/Gitlab_runner
|
|
||||||
dockerVolumes = [
|
|
||||||
"/nix/store:/nix/store:ro"
|
|
||||||
"/nix/var/nix/db:/nix/var/nix/db:ro"
|
|
||||||
"/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket:ro"
|
|
||||||
];
|
|
||||||
dockerDisableCache = true;
|
|
||||||
preBuildScript = pkgs.writeScript "setup-container" ''
|
|
||||||
mkdir -p -m 0755 /nix/var/log/nix/drvs
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/gcroots
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/profiles
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/temproots
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/userpool
|
|
||||||
mkdir -p -m 1777 /nix/var/nix/gcroots/per-user
|
|
||||||
mkdir -p -m 1777 /nix/var/nix/profiles/per-user
|
|
||||||
mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root
|
|
||||||
mkdir -p -m 0700 "$HOME/.nix-defexpr"
|
|
||||||
. ${pkgs.nix}/etc/profile.d/nix-daemon.sh
|
|
||||||
${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixos-23.05 nixpkgs # 3
|
|
||||||
${pkgs.nix}/bin/nix-channel --update nixpkgs
|
|
||||||
${pkgs.nix}/bin/nix-env -i ${concatStringsSep " " (with pkgs; [ nix cacert git openssh ])}
|
|
||||||
'';
|
|
||||||
environmentVariables = {
|
|
||||||
ENV = "/etc/profile";
|
|
||||||
USER = "root";
|
|
||||||
NIX_REMOTE = "daemon";
|
|
||||||
PATH = "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin";
|
|
||||||
NIX_SSL_CERT_FILE = "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
79
applications/grafana.nix
Normal file
79
applications/grafana.nix
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "grafana";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
port = 4444;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Grafana Server";
|
||||||
|
|
||||||
|
datasource = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
url = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = "${name}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${name}.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
age.secrets.grafana_pw = {
|
||||||
|
file = ../secrets/grafana/pw.age;
|
||||||
|
owner = "grafana";
|
||||||
|
group = "grafana";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.grafana = {
|
||||||
|
enable = true;
|
||||||
|
domain = "${name}.skynet.ie";
|
||||||
|
port = port;
|
||||||
|
|
||||||
|
settings.security.admin_password = "$__file{${config.age.secrets.grafana_pw.path}}";
|
||||||
|
|
||||||
|
provision = {
|
||||||
|
enable = true;
|
||||||
|
datasources.settings.datasources = [
|
||||||
|
{
|
||||||
|
name = "Prometheus";
|
||||||
|
type = "prometheus";
|
||||||
|
url = "http://localhost:${toString config.services.skynet.prometheus.server.port}";
|
||||||
|
isDefault = true;
|
||||||
|
editable = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"${name}.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString port}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
79
applications/ldap/backend.nix
Normal file
79
applications/ldap/backend.nix
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "ldap_backend";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
port_backend = "8087";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
inputs.skynet_ldap_backend.nixosModule."x86_64-linux"
|
||||||
|
../../config/users.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet LDAP backend server";
|
||||||
|
|
||||||
|
domain = {
|
||||||
|
tld = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "ie";
|
||||||
|
};
|
||||||
|
|
||||||
|
base = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "skynet";
|
||||||
|
};
|
||||||
|
|
||||||
|
sub = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "api.account";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
#backups = [ "/etc/silver_ul_ical/database.db" ];
|
||||||
|
|
||||||
|
age.secrets.ldap_details.file = ../../secrets/ldap/details.age;
|
||||||
|
age.secrets.ldap_mail.file = ../../secrets/email/details.age;
|
||||||
|
age.secrets.ldap_wolves.file = ../../secrets/wolves/details.age;
|
||||||
|
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = cfg.domain.sub;
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/".proxyPass = "http://localhost:${port_backend}";
|
||||||
|
};
|
||||||
|
|
||||||
|
# this got imported
|
||||||
|
services.skynet_ldap_backend = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# contains teh password in env form
|
||||||
|
env = {
|
||||||
|
ldap = config.age.secrets.ldap_details.path;
|
||||||
|
mail = config.age.secrets.ldap_mail.path;
|
||||||
|
wolves = config.age.secrets.ldap_wolves.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
host_port = "127.0.0.1:${port_backend}";
|
||||||
|
users = config.skynet.users;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
138
applications/ldap/client.nix
Normal file
138
applications/ldap/client.nix
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "ldap_client";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
|
# always ensure the admin group has access
|
||||||
|
create_filter_check_admin = x:
|
||||||
|
if !(builtins.elem "skynet-admins" x)
|
||||||
|
then x ++ ["skynet-admins"]
|
||||||
|
else x;
|
||||||
|
|
||||||
|
# create teh new strings
|
||||||
|
create_filter_array = map (x: "(skMemberOf=cn=${x},ou=groups,${cfg.base})");
|
||||||
|
|
||||||
|
create_filter_join = x: concatStringsSep "" x;
|
||||||
|
|
||||||
|
# thought you could escape racket?
|
||||||
|
create_filter = x: create_filter_join (create_filter_array (create_filter_check_admin x));
|
||||||
|
|
||||||
|
sudo_create_filter = x: (concatStringsSep ", " (map (x: "cn=${x},ou=groups,${cfg.base}") x));
|
||||||
|
in {
|
||||||
|
# these are needed for teh program in question
|
||||||
|
imports = [];
|
||||||
|
|
||||||
|
# give users access to this server
|
||||||
|
#services.skynet.ldap_client.groups = ["skynet-users-linux"];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
# options that need to be passed in to make this work
|
||||||
|
|
||||||
|
enable = mkEnableOption "Skynet LDAP client";
|
||||||
|
|
||||||
|
address = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "account.skynet.ie";
|
||||||
|
description = lib.mdDoc "The domain the ldap is behind";
|
||||||
|
};
|
||||||
|
|
||||||
|
base = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "dc=skynet,dc=ie";
|
||||||
|
description = lib.mdDoc "The base address in the ldap server";
|
||||||
|
};
|
||||||
|
|
||||||
|
groups = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [
|
||||||
|
"skynet-admins-linux"
|
||||||
|
];
|
||||||
|
description = lib.mdDoc "Groups we want to allow access to the server";
|
||||||
|
};
|
||||||
|
sudo_groups = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [
|
||||||
|
"skynet-admins-linux"
|
||||||
|
];
|
||||||
|
description = lib.mdDoc "Groups we want to allow access to the server";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# this is athe actual configuration that we need to do
|
||||||
|
|
||||||
|
security.sudo.extraRules = [
|
||||||
|
# admin group has sudo access
|
||||||
|
{
|
||||||
|
groups = cfg.sudo_groups;
|
||||||
|
commands = [
|
||||||
|
{
|
||||||
|
command = "ALL";
|
||||||
|
options = ["NOPASSWD"];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
# give users a home dir
|
||||||
|
security.pam.services.sshd.makeHomeDir = true;
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
# only allow ssh keys
|
||||||
|
settings.PasswordAuthentication = false;
|
||||||
|
|
||||||
|
# tell users where tehy cna setup their ssh key
|
||||||
|
banner = ''
|
||||||
|
If you get 'Permission denied (publickey,keyboard-interactive)' you need to add an ssh key on https://${cfg.address}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.sssd = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
sshAuthorizedKeysIntegration = true;
|
||||||
|
|
||||||
|
config = ''
|
||||||
|
[domain/skynet.ie]
|
||||||
|
id_provider = ldap
|
||||||
|
auth_provider = ldap
|
||||||
|
sudo_provider = ldap
|
||||||
|
|
||||||
|
ldap_uri = ldaps://${cfg.address}:636
|
||||||
|
|
||||||
|
ldap_search_base = ${cfg.base}
|
||||||
|
# thank ye https://medium.com/techish-cloud/linux-user-ssh-authentication-with-sssd-ldap-without-joining-domain-9151396d967d
|
||||||
|
ldap_user_search_base = ou=users,${cfg.base}?sub?(|${create_filter cfg.groups})
|
||||||
|
ldap_group_search_base = ou=groups,${cfg.base}
|
||||||
|
# using commas from https://support.hpe.com/hpesc/public/docDisplay?docId=c02793175&docLocale=en_US
|
||||||
|
ldap_sudo_search_base, ${sudo_create_filter cfg.sudo_groups}
|
||||||
|
|
||||||
|
ldap_group_nesting_level = 5
|
||||||
|
|
||||||
|
cache_credentials = false
|
||||||
|
entry_cache_timeout = 1
|
||||||
|
|
||||||
|
ldap_user_member_of = skMemberOf
|
||||||
|
|
||||||
|
[sssd]
|
||||||
|
config_file_version = 2
|
||||||
|
services = nss, pam, sudo, ssh
|
||||||
|
domains = skynet.ie
|
||||||
|
|
||||||
|
[nss]
|
||||||
|
# override_homedir = /home/%u
|
||||||
|
|
||||||
|
[pam]
|
||||||
|
|
||||||
|
[sudo]
|
||||||
|
|
||||||
|
[autofs]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,90 +0,0 @@
|
||||||
{ config, pkgs, lib, inputs, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.services.ldap_backend;
|
|
||||||
port_backend = "8087";
|
|
||||||
in {
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
../acme.nix
|
|
||||||
../dns.nix
|
|
||||||
../nginx.nix
|
|
||||||
inputs.skynet_ldap_backend.nixosModule."x86_64-linux"
|
|
||||||
];
|
|
||||||
|
|
||||||
options.services.ldap_backend = {
|
|
||||||
enable = mkEnableOption "Skynet LDAP backend server";
|
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = {
|
|
||||||
tld = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "ie";
|
|
||||||
};
|
|
||||||
|
|
||||||
base = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "skynet";
|
|
||||||
};
|
|
||||||
|
|
||||||
sub = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "api.sso";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
|
|
||||||
#backups = [ "/etc/silver_ul_ical/database.db" ];
|
|
||||||
|
|
||||||
age.secrets.ldap_self_service.file = ../../secrets/ldap/self_service.age;
|
|
||||||
|
|
||||||
skynet_dns.records = [
|
|
||||||
{record=cfg.domain.sub; r_type="CNAME"; value=cfg.host.name;}
|
|
||||||
];
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" = {
|
|
||||||
forceSSL = true;
|
|
||||||
useACMEHost = "skynet";
|
|
||||||
locations."/".proxyPass = "http://localhost:${port_backend}";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.skynet_ldap_backend = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
# contains teh password in env form
|
|
||||||
envFile = config.age.secrets.ldap_self_service.path;
|
|
||||||
|
|
||||||
ldap = {
|
|
||||||
host = "ldaps://sso.skynet.ie";
|
|
||||||
admin = "cn=admin,dc=skynet,dc=ie";
|
|
||||||
};
|
|
||||||
|
|
||||||
users = {
|
|
||||||
admin = [
|
|
||||||
"silver"
|
|
||||||
"evanc"
|
|
||||||
"eoghanconlon73"
|
|
||||||
];
|
|
||||||
committee = [
|
|
||||||
"silver"
|
|
||||||
"eoghanconlon73"
|
|
||||||
];
|
|
||||||
lifetime = [];
|
|
||||||
banned = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
host_port = "127.0.0.1:${port_backend}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,37 +1,27 @@
|
||||||
/*
|
/*
|
||||||
Gonna use a priper nixos module for this
|
Gonna use a priper nixos module for this
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ config, pkgs, lib, ... }:
|
config,
|
||||||
with lib;
|
pkgs,
|
||||||
let
|
lib,
|
||||||
cfg = config.services.skynet_ldap;
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "ldap";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
domain = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
in {
|
in {
|
||||||
|
|
||||||
# these are needed for teh program in question
|
# these are needed for teh program in question
|
||||||
imports = [
|
imports = [
|
||||||
./acme.nix
|
|
||||||
./dns.nix
|
|
||||||
./nginx.nix
|
|
||||||
./ldap/ldap_backend.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
options.services.skynet_ldap = {
|
|
||||||
# options that need to be passed in to make this work
|
# options that need to be passed in to make this work
|
||||||
|
|
||||||
enable = mkEnableOption "Skynet LDAP service";
|
enable = mkEnableOption "Skynet LDAP service";
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = {
|
domain = {
|
||||||
tld = mkOption {
|
tld = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -45,7 +35,7 @@ Gonna use a priper nixos module for this
|
||||||
|
|
||||||
sub = mkOption {
|
sub = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "sso";
|
default = "account";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,24 +51,24 @@ Gonna use a priper nixos module for this
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
# passthrough to the backend
|
|
||||||
services.ldap_backend = {
|
|
||||||
enable = true;
|
|
||||||
host.ip = cfg.host.ip;
|
|
||||||
host.name = cfg.host.name;
|
|
||||||
};
|
|
||||||
|
|
||||||
# after changing teh password openldap.service has to be restarted
|
# after changing teh password openldap.service has to be restarted
|
||||||
age.secrets.ldap_pw = {
|
age.secrets.ldap_pw = {
|
||||||
file = ../secrets/ldap/pw.age;
|
file = ../../secrets/ldap/pw.age;
|
||||||
mode = "440";
|
mode = "440";
|
||||||
owner = "openldap";
|
owner = "openldap";
|
||||||
group = "openldap";
|
group = "openldap";
|
||||||
};
|
};
|
||||||
|
|
||||||
skynet_dns.records = [
|
services.skynet.acme.domains = [
|
||||||
{record=cfg.domain.sub; r_type="CNAME"; value=cfg.host.name;}
|
domain
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = cfg.domain.sub;
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
# firewall on teh computer itself
|
# firewall on teh computer itself
|
||||||
|
@ -87,6 +77,23 @@ Gonna use a priper nixos module for this
|
||||||
636
|
636
|
||||||
];
|
];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
${domain} = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/" = {
|
||||||
|
root = "${inputs.skynet_ldap_frontend.defaultPackage."x86_64-linux"}";
|
||||||
|
# https://stackoverflow.com/a/38238001
|
||||||
|
extraConfig = ''
|
||||||
|
if ($request_uri ~ ^/(.*)\.html) {
|
||||||
|
return 302 /$1;
|
||||||
|
}
|
||||||
|
try_files $uri $uri.html $uri/ =404;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# using https://nixos.wiki/wiki/OpenLDAP for base config
|
# using https://nixos.wiki/wiki/OpenLDAP for base config
|
||||||
|
|
||||||
systemd.services.openldap = {
|
systemd.services.openldap = {
|
||||||
|
@ -101,14 +108,18 @@ Gonna use a priper nixos module for this
|
||||||
|
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
/* enable plain and secure connections */
|
/*
|
||||||
|
enable plain and secure connections
|
||||||
|
*/
|
||||||
urlList = ["ldap:///" "ldaps:///"];
|
urlList = ["ldap:///" "ldaps:///"];
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
attrs = {
|
attrs = {
|
||||||
olcLogLevel = "conns config";
|
olcLogLevel = "conns config";
|
||||||
|
|
||||||
/* settings for acme ssl */
|
/*
|
||||||
|
settings for acme ssl
|
||||||
|
*/
|
||||||
olcTLSCACertificateFile = "/var/lib/acme/${cfg.domain.base}/full.pem";
|
olcTLSCACertificateFile = "/var/lib/acme/${cfg.domain.base}/full.pem";
|
||||||
olcTLSCertificateFile = "/var/lib/acme/${cfg.domain.base}/cert.pem";
|
olcTLSCertificateFile = "/var/lib/acme/${cfg.domain.base}/cert.pem";
|
||||||
olcTLSCertificateKeyFile = "/var/lib/acme/${cfg.domain.base}/key.pem";
|
olcTLSCertificateKeyFile = "/var/lib/acme/${cfg.domain.base}/key.pem";
|
||||||
|
@ -129,11 +140,10 @@ Gonna use a priper nixos module for this
|
||||||
"${pkgs.openldap}/etc/schema/cosine.ldif"
|
"${pkgs.openldap}/etc/schema/cosine.ldif"
|
||||||
"${pkgs.openldap}/etc/schema/inetorgperson.ldif"
|
"${pkgs.openldap}/etc/schema/inetorgperson.ldif"
|
||||||
"${pkgs.openldap}/etc/schema/nis.ldif"
|
"${pkgs.openldap}/etc/schema/nis.ldif"
|
||||||
./ldap/openssh-lpk.ldif
|
./openssh-lpk.ldif
|
||||||
./ldap/skMemberOf.ldif
|
./skMemberOf.ldif
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
"cn=modules".attrs = {
|
"cn=modules".attrs = {
|
||||||
objectClass = ["olcModuleList"];
|
objectClass = ["olcModuleList"];
|
||||||
cn = "modules";
|
cn = "modules";
|
||||||
|
@ -155,29 +165,40 @@ Gonna use a priper nixos module for this
|
||||||
|
|
||||||
olcSuffix = cfg.base;
|
olcSuffix = cfg.base;
|
||||||
|
|
||||||
/* your admin account, do not use writeText on a production system */
|
/*
|
||||||
|
your admin account, do not use writeText on a production system
|
||||||
|
*/
|
||||||
olcRootDN = "cn=admin,${cfg.base}";
|
olcRootDN = "cn=admin,${cfg.base}";
|
||||||
olcRootPW.path = config.age.secrets.ldap_pw.path;
|
olcRootPW.path = config.age.secrets.ldap_pw.path;
|
||||||
|
|
||||||
#olcOverlay = "memberof";
|
|
||||||
|
|
||||||
olcAccess = [
|
olcAccess = [
|
||||||
/* custom access rules for userPassword attributes */
|
/*
|
||||||
''{0}to attrs=userPassword
|
custom access rules for userPassword attributes
|
||||||
|
*/
|
||||||
|
''
|
||||||
|
{0}to attrs=userPassword
|
||||||
|
by dn.exact="uid=ldap_api,ou=users,dc=skynet,dc=ie" manage
|
||||||
by self write
|
by self write
|
||||||
by anonymous auth
|
by anonymous auth
|
||||||
by * none''
|
by * none
|
||||||
|
''
|
||||||
|
|
||||||
''{1}to attrs=mail,sshPublicKey,cn,sn,skDiscord
|
''
|
||||||
|
{1}to attrs=mail,sshPublicKey,cn,sn
|
||||||
|
by dn.exact="uid=ldap_api,ou=users,dc=skynet,dc=ie" manage
|
||||||
by self write
|
by self write
|
||||||
by * read''
|
by * read
|
||||||
|
''
|
||||||
|
|
||||||
/* allow read on anything else */
|
/*
|
||||||
''{2}to *
|
allow read on anything else
|
||||||
by * read''
|
*/
|
||||||
|
''
|
||||||
|
{2}to *
|
||||||
|
by dn.exact="uid=ldap_api,ou=users,dc=skynet,dc=ie" manage
|
||||||
|
by * read
|
||||||
|
''
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# https://blog.oddbit.com/post/2013-07-22-generating-a-membero/
|
# https://blog.oddbit.com/post/2013-07-22-generating-a-membero/
|
||||||
|
@ -199,10 +220,7 @@ Gonna use a priper nixos module for this
|
||||||
olcMemberOfMemberOfAD = "memberOf";
|
olcMemberOfMemberOfAD = "memberOf";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
|
@ -24,24 +24,12 @@ olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.4.1
|
||||||
EQUALITY caseIgnoreMatch
|
EQUALITY caseIgnoreMatch
|
||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||||
)
|
)
|
||||||
olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.5.1
|
|
||||||
NAME 'skDiscord'
|
|
||||||
DESC 'Discord username'
|
|
||||||
EQUALITY caseIgnoreMatch
|
|
||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
|
||||||
)
|
|
||||||
olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.6.1
|
olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.6.1
|
||||||
NAME 'skCreated'
|
NAME 'skCreated'
|
||||||
DESC 'When the account was created'
|
DESC 'When the account was created'
|
||||||
EQUALITY caseIgnoreMatch
|
EQUALITY caseIgnoreMatch
|
||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
||||||
)
|
)
|
||||||
#olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.7.1
|
|
||||||
# NAME 'skEnabled'
|
|
||||||
# DESC 'TRUE/FALSE'
|
|
||||||
# EQUALITY booleanMatch
|
|
||||||
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
|
|
||||||
# )
|
|
||||||
# https://github.com/variablenix/ldap-mail-schema/blob/master/quota.schema
|
# https://github.com/variablenix/ldap-mail-schema/blob/master/quota.schema
|
||||||
olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.8.1
|
olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.8.1
|
||||||
NAME 'quotaEmail'
|
NAME 'quotaEmail'
|
||||||
|
@ -55,16 +43,10 @@ olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.9.1
|
||||||
EQUALITY caseIgnoreIA5Match
|
EQUALITY caseIgnoreIA5Match
|
||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255}
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255}
|
||||||
)
|
)
|
||||||
olcAttributeTypes: ( 1.3.6.1.4.1.24441.1.10.1
|
|
||||||
NAME 'skSecure'
|
|
||||||
DESC '1 if secure'
|
|
||||||
EQUALITY caseIgnoreMatch
|
|
||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
|
|
||||||
)
|
|
||||||
olcObjectClasses: ( 1.3.6.1.4.1.24441.1.1.1
|
olcObjectClasses: ( 1.3.6.1.4.1.24441.1.1.1
|
||||||
NAME 'skPerson'
|
NAME 'skPerson'
|
||||||
DESC 'skynet person'
|
DESC 'skynet person'
|
||||||
SUP top AUXILIARY
|
SUP top AUXILIARY
|
||||||
MUST ( skMail $ skCreated )
|
MUST ( skMail $ skCreated )
|
||||||
MAY ( skMemberOf $ skID $ skDiscord $ quotaEmail $ quotaDisk $ skSecure )
|
MAY ( skMemberOf $ skID $ quotaEmail $ quotaDisk )
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.services.skynet_ldap_client;
|
|
||||||
|
|
||||||
# always ensure the admin group has access
|
|
||||||
create_filter_check_admin = (x: if !(builtins.elem "skynet-admins" x) then x ++ ["skynet-admins"] else x);
|
|
||||||
|
|
||||||
# create teh new strings
|
|
||||||
create_filter_array = map (x: "(skMemberOf=cn=${x},ou=groups,${cfg.base})");
|
|
||||||
|
|
||||||
create_filter_join = (x: concatStringsSep "" x);
|
|
||||||
|
|
||||||
# thought you could escape racket?
|
|
||||||
create_filter = (x: create_filter_join (create_filter_array (create_filter_check_admin x) ) );
|
|
||||||
|
|
||||||
in {
|
|
||||||
|
|
||||||
# these are needed for teh program in question
|
|
||||||
imports = [];
|
|
||||||
|
|
||||||
# give users access to this server
|
|
||||||
#services.skynet_ldap_client.groups = ["skynet-users-linux"];
|
|
||||||
|
|
||||||
options.services.skynet_ldap_client = {
|
|
||||||
# options that need to be passed in to make this work
|
|
||||||
|
|
||||||
enable = mkEnableOption "Skynet LDAP client";
|
|
||||||
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "sso.skynet.ie";
|
|
||||||
description = lib.mdDoc "The domain the ldap is behind";
|
|
||||||
};
|
|
||||||
|
|
||||||
base = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "dc=skynet,dc=ie";
|
|
||||||
description = lib.mdDoc "The base address in the ldap server";
|
|
||||||
};
|
|
||||||
|
|
||||||
groups = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [
|
|
||||||
"skynet-admins-linux"
|
|
||||||
];
|
|
||||||
description = lib.mdDoc "Groups we want to allow access to the server";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
# this is athe actual configuration that we need to do
|
|
||||||
|
|
||||||
security.sudo.extraRules = [
|
|
||||||
# admin group has sudo access
|
|
||||||
{ groups = [ "skynet-admins-linux" ]; commands = [ { command = "ALL"; options = [ "NOPASSWD" ]; } ]; }
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
# give users a home dir
|
|
||||||
security.pam.services.sshd.makeHomeDir = true;
|
|
||||||
|
|
||||||
services.openssh = {
|
|
||||||
# only allow ssh keys
|
|
||||||
settings.PasswordAuthentication = false;
|
|
||||||
|
|
||||||
# tell users where tehy cna setup their ssh key
|
|
||||||
banner = ''
|
|
||||||
If you get 'Permission denied (publickey,keyboard-interactive)' you need to add an ssh key on https://${cfg.address}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.sssd = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
sshAuthorizedKeysIntegration = true;
|
|
||||||
|
|
||||||
config = ''
|
|
||||||
[domain/skynet.ie]
|
|
||||||
id_provider = ldap
|
|
||||||
auth_provider = ldap
|
|
||||||
sudo_provider = ldap
|
|
||||||
|
|
||||||
ldap_uri = ldaps://${cfg.address}:636
|
|
||||||
|
|
||||||
ldap_search_base = ${cfg.base}
|
|
||||||
# thank ye https://medium.com/techish-cloud/linux-user-ssh-authentication-with-sssd-ldap-without-joining-domain-9151396d967d
|
|
||||||
ldap_user_search_base = ou=users,${cfg.base}?sub?(|${create_filter cfg.groups})
|
|
||||||
ldap_group_search_base = ou=groups,${cfg.base}
|
|
||||||
ldap_sudo_search_base = cn=skynet-admins-linux,ou=groups,${cfg.base}
|
|
||||||
|
|
||||||
ldap_group_nesting_level = 5
|
|
||||||
|
|
||||||
cache_credentials = false
|
|
||||||
entry_cache_timeout = 1
|
|
||||||
|
|
||||||
ldap_user_member_of = skMemberOf
|
|
||||||
|
|
||||||
[sssd]
|
|
||||||
config_file_version = 2
|
|
||||||
services = nss, pam, sudo, ssh
|
|
||||||
domains = skynet.ie
|
|
||||||
|
|
||||||
[nss]
|
|
||||||
# override_homedir = /home/%u
|
|
||||||
|
|
||||||
[pam]
|
|
||||||
|
|
||||||
[sudo]
|
|
||||||
|
|
||||||
[autofs]
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
135
applications/nextcloud.nix
Normal file
135
applications/nextcloud.nix
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "nextcloud";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
domain = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet Nextcloud";
|
||||||
|
|
||||||
|
domain = {
|
||||||
|
tld = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "ie";
|
||||||
|
};
|
||||||
|
|
||||||
|
base = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "skynet";
|
||||||
|
};
|
||||||
|
|
||||||
|
sub = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# shove the entire config file into secrets
|
||||||
|
|
||||||
|
age.secrets.nextcloud_admin_pass = {
|
||||||
|
file = ../secrets/nextcloud/pw.age;
|
||||||
|
owner = "nextcloud";
|
||||||
|
group = "nextcloud";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
domain
|
||||||
|
"onlyoffice.${domain}"
|
||||||
|
"whiteboard.${domain}"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = cfg.domain.sub;
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "onlyoffice.${cfg.domain.sub}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
# {
|
||||||
|
# record = "whiteboard.${cfg.domain.sub}";
|
||||||
|
# r_type = "CNAME";
|
||||||
|
# value = config.services.skynet.host.name;
|
||||||
|
# }
|
||||||
|
];
|
||||||
|
|
||||||
|
# /var/lib/nextcloud/data
|
||||||
|
|
||||||
|
services.nextcloud = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.nextcloud30;
|
||||||
|
hostName = domain;
|
||||||
|
https = true;
|
||||||
|
|
||||||
|
configureRedis = true;
|
||||||
|
|
||||||
|
database.createLocally = true;
|
||||||
|
config = {
|
||||||
|
dbtype = "pgsql";
|
||||||
|
adminpassFile = config.age.secrets.nextcloud_admin_pass.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
appstoreEnable = true;
|
||||||
|
|
||||||
|
extraApps = {
|
||||||
|
inherit (config.services.nextcloud.package.packages.apps) richdocuments;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
trusted_proxies = ["193.1.99.65"];
|
||||||
|
default_phone_region = "IE";
|
||||||
|
mail_smtpmode = "sendmail";
|
||||||
|
mail_sendmailmode = "pipe";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# environment.etc."nextcloud-whiteboard-secret".text = ''
|
||||||
|
# JWT_SECRET_KEY=test123
|
||||||
|
# '';
|
||||||
|
#
|
||||||
|
# services.nextcloud-whiteboard-server = {
|
||||||
|
# enable = true;
|
||||||
|
# settings.NEXTCLOUD_URL = "https://nextcloud.skynet.ie";
|
||||||
|
# secrets = ["/etc/nextcloud-whiteboard-secret"];
|
||||||
|
# };
|
||||||
|
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
# impacted by https://github.com/NixOS /nixpkgs/issues/352443
|
||||||
|
# services.onlyoffice = {
|
||||||
|
# enable = true;
|
||||||
|
# };
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
${domain} = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
};
|
||||||
|
"onlyoffice.${domain}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:8000";
|
||||||
|
};
|
||||||
|
# "whiteboard.${domain}" = {
|
||||||
|
# forceSSL = true;
|
||||||
|
# useACMEHost = "skynet";
|
||||||
|
# locations."/" = {
|
||||||
|
# proxyPass = "http://localhost:3002";
|
||||||
|
# proxyWebsockets = true;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
# using K900's one https://gitlab.com/K900/nix/-/blob/a69502b8bf39fd99a85342b2f7989fe5896a6ae0/applications/base/nginx.nix
|
# using K900's one https://gitlab.com/K900/nix/-/blob/a69502b8bf39fd99a85342b2f7989fe5896a6ae0/applications/base/nginx.nix
|
||||||
|
|
||||||
{pkgs, ...}: {
|
{pkgs, ...}: {
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -10,8 +9,6 @@
|
||||||
recommendedGzipSettings = true;
|
recommendedGzipSettings = true;
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
|
|
||||||
statusPage = true;
|
|
||||||
|
|
||||||
# give Nginx access to our certs
|
# give Nginx access to our certs
|
||||||
group = "acme";
|
group = "acme";
|
||||||
};
|
};
|
||||||
|
|
98
applications/nix_cache/nix_cache.nix
Normal file
98
applications/nix_cache/nix_cache.nix
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
A nix cache for our use
|
||||||
|
|
||||||
|
|
||||||
|
atticd-atticadm make-token --sub "admin_username" --validity "10y" --pull "*" --push "*" --create-cache "*" --delete "*" --configure-cache "*" --configure-cache-retention "*" --destroy-cache "*"
|
||||||
|
|
||||||
|
# for the gitlab runner, done eyarly
|
||||||
|
atticd-atticadm make-token --sub "wheatly-runner" --validity "1y" --pull "skynet-cache" --push "skynet-cache"
|
||||||
|
|
||||||
|
|
||||||
|
Documentation:
|
||||||
|
https://docs.attic.rs/introduction.html
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "nix-cache";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet Nix Cache";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${name}.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = "${name}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
users.groups."nix-serve" = {};
|
||||||
|
users.users."nix-serve" = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "nix-serve";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.atticd = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# Replace with absolute path to your credentials file
|
||||||
|
environmentFile = "/etc/atticd.env";
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
listen = "127.0.0.1:8080";
|
||||||
|
|
||||||
|
# Data chunking
|
||||||
|
#
|
||||||
|
# Warning: If you change any of the values here, it will be
|
||||||
|
# difficult to reuse existing chunks for newly-uploaded NARs
|
||||||
|
# since the cutpoints will be different. As a result, the
|
||||||
|
# deduplication ratio will suffer for a while after the change.
|
||||||
|
chunking = {
|
||||||
|
# The minimum NAR size to trigger chunking
|
||||||
|
#
|
||||||
|
# If 0, chunking is disabled entirely for newly-uploaded NARs.
|
||||||
|
# If 1, all NARs are chunked.
|
||||||
|
nar-size-threshold = 64 * 1024; # 64 KiB
|
||||||
|
|
||||||
|
# The preferred minimum size of a chunk, in bytes
|
||||||
|
min-size = 16 * 1024; # 16 KiB
|
||||||
|
|
||||||
|
# The preferred average size of a chunk, in bytes
|
||||||
|
avg-size = 64 * 1024; # 64 KiB
|
||||||
|
|
||||||
|
# The preferred maximum size of a chunk, in bytes
|
||||||
|
max-size = 256 * 1024; # 256 KiB
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [80 443];
|
||||||
|
services.nginx = {
|
||||||
|
clientMaxBodySize = "500m";
|
||||||
|
virtualHosts = {
|
||||||
|
"${name}.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:8080";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
17
applications/open_governance/README.md
Normal file
17
applications/open_governance/README.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Open Governance
|
||||||
|
|
||||||
|
Started by DCU this is an initiative to make the running of (computer) societies more open and resilient.
|
||||||
|
The goal is to back these up in multiple locations.
|
||||||
|
|
||||||
|
|
||||||
|
| Uni | Tag | Repo | Notes |
|
||||||
|
|-----|----------|----------------------------------------------------------|-------|
|
||||||
|
| DCU | redbrick | https://github.com/redbrick/open-governance | |
|
||||||
|
| UL | skynet | https://gitlab.skynet.ie/compsoc1/compsoc/open-goverance | |
|
||||||
|
| | | | |
|
||||||
|
|
||||||
|
|
||||||
|
## Keys
|
||||||
|
We host our own keyserver: https://keyserver.skynet.ie
|
||||||
|
Use it in commands like so:
|
||||||
|
``gpg --keyserver hkp://keyserver.skynet.ie:80 --send-key KEY_ID``
|
62
applications/open_governance/keyserver.nix
Normal file
62
applications/open_governance/keyserver.nix
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
This file is for hosting teh open governance for other societies
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "keyserver";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
port = 11371;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet Public Keyserver";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${name}.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = "${name}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.hockeypuck = {
|
||||||
|
enable = true;
|
||||||
|
port = port;
|
||||||
|
};
|
||||||
|
|
||||||
|
# hockeypuck needs a database backend
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
ensureDatabases = ["hockeypuck"];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "hockeypuck";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"${name}.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://localhost:${toString port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
61
applications/open_governance/open_governance.nix
Normal file
61
applications/open_governance/open_governance.nix
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
This file is for hosting teh open governance for other societies
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
# - instead of _ for dns reasons
|
||||||
|
name = "open-governance";
|
||||||
|
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
folder = "/var/skynet/${name}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet Open Governance";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${name}.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = "${name}";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
# create a folder to store the archives
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${folder} 0755 ${config.services.nginx.user} ${config.services.nginx.group}"
|
||||||
|
"L+ ${folder}/README.md - - - - ${./README.md}"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"${name}.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
root = folder;
|
||||||
|
locations = {
|
||||||
|
"/".extraConfig = "autoindex on;";
|
||||||
|
|
||||||
|
# show md files as plain text
|
||||||
|
"~ \.md".extraConfig = ''
|
||||||
|
types {
|
||||||
|
text/plain md;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
95
applications/prometheus.nix
Normal file
95
applications/prometheus.nix
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
nodes,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "prometheus";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
|
# dont have to worry about any external addresses for this
|
||||||
|
# create a list of either "ip@port" or ""
|
||||||
|
# the ""s then get filtered out by filter_empty
|
||||||
|
exporters = {
|
||||||
|
dns = (
|
||||||
|
lib.attrsets.mapAttrsToList (
|
||||||
|
key: value:
|
||||||
|
if value.config.services.skynet.dns.server.enable
|
||||||
|
then "${value.config.deployment.targetHost}:${toString value.config.services.prometheus.exporters.bind.port}"
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
nodes
|
||||||
|
);
|
||||||
|
node = lib.attrsets.mapAttrsToList (key: value: "${value.config.deployment.targetHost}:${toString value.config.services.prometheus.exporters.node.port}") nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
# clears any invalid entries
|
||||||
|
filter_empty = inputs: (builtins.filter (value: value != "") inputs);
|
||||||
|
in {
|
||||||
|
imports = [];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
server = {
|
||||||
|
enable = mkEnableOption "Prometheus Server";
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 9001;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
external = {
|
||||||
|
node = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
To add other nodes outside of nix, specify ip and port that server should listen to here
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ports = {
|
||||||
|
node = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 9100;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
{
|
||||||
|
services.prometheus.exporters.node = {
|
||||||
|
enable = true;
|
||||||
|
port = cfg.ports.node;
|
||||||
|
openFirewall = true;
|
||||||
|
# most collectors are on by default see https://github.com/prometheus/node_exporter for more options
|
||||||
|
enabledCollectors = ["systemd" "processes"];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(mkIf cfg.server.enable {
|
||||||
|
services.prometheus = {
|
||||||
|
enable = true;
|
||||||
|
port = cfg.server.port;
|
||||||
|
scrapeConfigs = [
|
||||||
|
{
|
||||||
|
job_name = "node_exporter";
|
||||||
|
static_configs = [
|
||||||
|
{
|
||||||
|
targets = filter_empty (exporters.node ++ cfg.external.node);
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
job_name = "bind";
|
||||||
|
static_configs = [
|
||||||
|
{
|
||||||
|
targets = filter_empty exporters.dns;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
96
applications/proxmox-lxc.nix
Normal file
96
applications/proxmox-lxc.nix
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
Once https://github.com/NixOS/nixpkgs/pull/267764 is merged this can be removed
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; {
|
||||||
|
options.proxmoxLXC = {
|
||||||
|
enable = mkOption {
|
||||||
|
default = true;
|
||||||
|
type = types.bool;
|
||||||
|
description = lib.mdDoc "Whether to enable the Proxmox VE LXC module.";
|
||||||
|
};
|
||||||
|
privileged = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to enable privileged mounts
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
manageNetwork = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to manage network interfaces through nix options
|
||||||
|
When false, systemd-networkd is enabled to accept network
|
||||||
|
configuration from proxmox.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
manageHostName = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to manage hostname through nix options
|
||||||
|
When false, the hostname is picked up from /etc/hostname
|
||||||
|
populated by proxmox.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
cfg = config.proxmoxLXC;
|
||||||
|
in
|
||||||
|
mkIf cfg.enable {
|
||||||
|
system.build.tarball = pkgs.callPackage ../../lib/make-system-tarball.nix {
|
||||||
|
storeContents = [
|
||||||
|
{
|
||||||
|
object = config.system.build.toplevel;
|
||||||
|
symlink = "none";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
contents = [
|
||||||
|
{
|
||||||
|
source = config.system.build.toplevel + "/init";
|
||||||
|
target = "/sbin/init";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
extraCommands = "mkdir -p root etc/systemd/network";
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
isContainer = true;
|
||||||
|
loader.initScript.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
console.enable = true;
|
||||||
|
|
||||||
|
networking = mkIf (!cfg.manageNetwork) {
|
||||||
|
useDHCP = false;
|
||||||
|
useHostResolvConf = false;
|
||||||
|
useNetworkd = true;
|
||||||
|
# pick up hostname from /etc/hostname generated by proxmox
|
||||||
|
hostName = mkIf (!cfg.manageHostName) (mkForce "");
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
enable = mkDefault true;
|
||||||
|
startWhenNeeded = mkDefault true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
mounts = mkIf (!cfg.privileged) [
|
||||||
|
{
|
||||||
|
enable = false;
|
||||||
|
where = "/sys/kernel/debug";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
services."getty@".unitConfig.ConditionPathExists = ["" "/dev/%I"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,9 +1,16 @@
|
||||||
|
|
||||||
# nodes is all the nodes
|
# nodes is all the nodes
|
||||||
{ lib, config, nodes, pkgs, ...}: with lib;
|
{
|
||||||
let
|
lib,
|
||||||
cfg = config.services.skynet_backup;
|
config,
|
||||||
|
nodes,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "backup";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
|
||||||
|
enable_client = cfg.normal.backups != null && cfg.normal.backups != [];
|
||||||
|
|
||||||
# since they should all have the same config we can do this
|
# since they should all have the same config we can do this
|
||||||
base = {
|
base = {
|
||||||
|
@ -29,21 +36,26 @@
|
||||||
# then if the server is enabled,
|
# then if the server is enabled,
|
||||||
# then pull relevant dtails
|
# then pull relevant dtails
|
||||||
ownServers = builtins.listToAttrs (builtins.concatLists (
|
ownServers = builtins.listToAttrs (builtins.concatLists (
|
||||||
lib.attrsets.mapAttrsToList (key: value:
|
lib.attrsets.mapAttrsToList (
|
||||||
let
|
key: value: let
|
||||||
backup = value.config.services.skynet_backup;
|
backup = value.config.services.skynet.backup;
|
||||||
|
backup_host = value.config.services.skynet.host;
|
||||||
in
|
in
|
||||||
if (
|
if
|
||||||
(builtins.hasAttr "skynet_backup" value.config.services)
|
(
|
||||||
|
(builtins.hasAttr "backup" value.config.services.skynet)
|
||||||
&& backup.server.enable
|
&& backup.server.enable
|
||||||
&& backup.host.name != cfg.host.name
|
# chgeck that its not itself
|
||||||
|
&& backup_host.name != config.services.skynet.host.name
|
||||||
&& !backup.server.appendOnly
|
&& !backup.server.appendOnly
|
||||||
)
|
)
|
||||||
then [
|
then [
|
||||||
{
|
{
|
||||||
name = backup.host.name;
|
name = backup_host.name;
|
||||||
value = base // {
|
value =
|
||||||
repositoryFile = "/etc/skynet/restic/${backup.host.name}";
|
base
|
||||||
|
// {
|
||||||
|
repositoryFile = "/etc/skynet/restic/${backup_host.name}";
|
||||||
|
|
||||||
backupPrepareCommand = ''
|
backupPrepareCommand = ''
|
||||||
#!${pkgs.stdenv.shell}
|
#!${pkgs.stdenv.shell}
|
||||||
|
@ -54,36 +66,30 @@
|
||||||
mkdir -p $baseDir
|
mkdir -p $baseDir
|
||||||
cd $baseDir
|
cd $baseDir
|
||||||
|
|
||||||
echo -n "rest:http://root:password@${backup.host.ip}:${toString backup.server.port}/root/${cfg.host.name}" > ${backup.host.name}
|
echo -n "rest:http://root:password@${backup_host.ip}:${toString backup.server.port}/root/${config.services.skynet.host.name}" > ${backup_host.name}
|
||||||
|
|
||||||
# read in teh password
|
# read in teh password
|
||||||
#PW = `cat ${config.age.secrets.restic.path}`
|
#PW = `cat ${config.age.secrets.restic.path}`
|
||||||
line=$(head -n 1 ${config.age.secrets.restic.path})
|
line=$(head -n 1 ${config.age.secrets.restic.path})
|
||||||
|
|
||||||
sed -i "s/password/$line/g" ${backup.host.name}
|
sed -i "s/password/$line/g" ${backup_host.name}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
else []
|
else []
|
||||||
) nodes
|
)
|
||||||
|
nodes
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# using https://github.com/greaka/ops/blob/818be4c4dea9129abe0f086d738df4cb0bb38288/apps/restic/options.nix as a base
|
# using https://github.com/greaka/ops/blob/818be4c4dea9129abe0f086d738df4cb0bb38288/apps/restic/options.nix as a base
|
||||||
# https://git.hrnz.li/Ulli/nixos/src/commit/5edca2dfdab3ce52208e4dfd2b92951e500f8418/profiles/server/restic.nix
|
# https://git.hrnz.li/Ulli/nixos/src/commit/5edca2dfdab3ce52208e4dfd2b92951e500f8418/profiles/server/restic.nix
|
||||||
# will eb enabled on every server
|
# will eb enabled on every server
|
||||||
options.services.skynet_backup = {
|
options.services.skynet."${name}" = {
|
||||||
# backup is enabled by default
|
enable = mkEnableOption "Skynet backup";
|
||||||
# enable = mkEnableOption "Skynet backup";
|
|
||||||
|
|
||||||
# what folders to backup
|
# what folders to backup
|
||||||
normal = {
|
normal = {
|
||||||
|
@ -123,16 +129,6 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
server = {
|
server = {
|
||||||
enable = mkEnableOption "Skynet backup Server";
|
enable = mkEnableOption "Skynet backup Server";
|
||||||
|
|
||||||
|
@ -146,39 +142,22 @@
|
||||||
default = false;
|
default = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
config = {
|
{
|
||||||
# these values are anabled for every client
|
# these values are anabled for every client
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
environment.systemPackages = [
|
restic
|
||||||
# for flakes
|
|
||||||
pkgs.restic
|
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
# A list of all login accounts. To create the password hashes, use
|
(mkIf cfg.server.enable {
|
||||||
# nix-shell -p apacheHttpd
|
|
||||||
# htpasswd -nbB "" "password" | cut -d: -f2
|
|
||||||
|
|
||||||
age.secrets.restic.file = ../secrets/backup/restic.age;
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
networking.firewall.allowedTCPPorts = [
|
||||||
cfg.server.port
|
cfg.server.port
|
||||||
];
|
];
|
||||||
|
|
||||||
services.restic.backups = ownServers // {
|
age.secrets.restic_pw = {
|
||||||
# merge teh two configs together
|
|
||||||
# backblaze = base // {
|
|
||||||
# # backupos for each server are stored in a folder under their name
|
|
||||||
# repository = "b2:NixOS-Main2:/${cfg.host.name}";
|
|
||||||
# #environmentFile = config.age.secrets.backblaze.path;
|
|
||||||
# };
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets.restic_pw = mkIf cfg.server.enable {
|
|
||||||
file = ../secrets/backup/restic_pw.age;
|
file = ../secrets/backup/restic_pw.age;
|
||||||
path = "${config.services.restic.server.dataDir}/.htpasswd";
|
path = "${config.services.restic.server.dataDir}/.htpasswd";
|
||||||
symlink = false;
|
symlink = false;
|
||||||
|
@ -187,13 +166,34 @@
|
||||||
group = "restic";
|
group = "restic";
|
||||||
};
|
};
|
||||||
|
|
||||||
services.restic.server = mkIf cfg.server.enable{
|
services.restic.server = {
|
||||||
enable = true;
|
enable = true;
|
||||||
listenAddress = "${cfg.host.ip}:${toString cfg.server.port}";
|
listenAddress = "${config.services.skynet.host.ip}:${toString cfg.server.port}";
|
||||||
appendOnly = cfg.server.appendOnly;
|
appendOnly = cfg.server.appendOnly;
|
||||||
privateRepos = true;
|
privateRepos = true;
|
||||||
};
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf enable_client {
|
||||||
|
# client stuff here
|
||||||
|
|
||||||
};
|
# A list of all login accounts. To create the password hashes, use
|
||||||
|
# nix-shell -p apacheHttpd
|
||||||
|
# htpasswd -nbB "" "password" | cut -d: -f2
|
||||||
|
|
||||||
|
age.secrets.restic.file = ../secrets/backup/restic.age;
|
||||||
|
|
||||||
|
services.restic.backups = mkMerge [
|
||||||
|
ownServers
|
||||||
|
{
|
||||||
|
# merge teh two configs together
|
||||||
|
# backblaze = base // {
|
||||||
|
# # backupos for each server are stored in a folder under their name
|
||||||
|
# repository = "b2:NixOS-Main2:/${config.services.skynet.host.name}";
|
||||||
|
# #environmentFile = config.age.secrets.backblaze.path;
|
||||||
|
# };
|
||||||
|
}
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
{ config, pkgs, lib, inputs, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.services.skynet;
|
|
||||||
in {
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
./acme.nix
|
|
||||||
./dns.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
options.services.skynet = {
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
skynet_dns.records = [
|
|
||||||
# means root domain, so skynet.ie
|
|
||||||
{record="@"; r_type="A"; value=cfg.host.ip;}
|
|
||||||
{record="2016"; r_type="CNAME"; value="skynet.ie";}
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [80 443];
|
|
||||||
services.httpd = {
|
|
||||||
enable = true;
|
|
||||||
group = "acme";
|
|
||||||
|
|
||||||
virtualHosts = {
|
|
||||||
# main site
|
|
||||||
"skynet.ie" = {
|
|
||||||
forceSSL = true;
|
|
||||||
useACMEHost = "skynet";
|
|
||||||
documentRoot = "${inputs.skynet_website.defaultPackage."x86_64-linux"}";
|
|
||||||
# only on skynet.ie
|
|
||||||
# skynet.ie/~username
|
|
||||||
enableUserDir = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# archive of teh site as it was ~2012 to 2016
|
|
||||||
"2016.skynet.ie" = {
|
|
||||||
forceSSL = true;
|
|
||||||
useACMEHost = "skynet";
|
|
||||||
documentRoot = "${inputs.skynet_website_2016.defaultPackage."x86_64-linux"}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
34
applications/skynet.ie/old_site.nix
Normal file
34
applications/skynet.ie/old_site.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{year}: {
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; {
|
||||||
|
imports = [];
|
||||||
|
|
||||||
|
config = {
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"${year}.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = year;
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
virtualHosts = {
|
||||||
|
"${year}.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
root = "${inputs."skynet_website_${year}".defaultPackage."x86_64-linux"}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
82
applications/skynet.ie/skynet.ie.nix
Normal file
82
applications/skynet.ie/skynet.ie.nix
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "website";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
# import in past website versions, available at $year.skynet.ie
|
||||||
|
# at teh end of teh year add it here
|
||||||
|
(import ./old_site.nix {year = "2023";})
|
||||||
|
(import ./old_site.nix {year = "2017";})
|
||||||
|
(import ./old_site.nix {year = "2009";})
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet Main Website";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"discord.skynet.ie"
|
||||||
|
"public.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
# means root domain, so skynet.ie
|
||||||
|
{
|
||||||
|
record = "@";
|
||||||
|
r_type = "A";
|
||||||
|
value = config.services.skynet.host.ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "discord";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "public";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
virtualHosts = {
|
||||||
|
# main site
|
||||||
|
"skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations = {
|
||||||
|
"/".root = "${inputs.skynet_website.defaultPackage."x86_64-linux"}";
|
||||||
|
|
||||||
|
# this redirects old links to new format
|
||||||
|
"~* ~(?<username>[a-z_0-9]*)(?<files>\\S*)$" = {
|
||||||
|
priority = 1;
|
||||||
|
return = "307 https://$username.users.skynet.ie$files";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# a custom discord url, because we are too cheap otehrwise
|
||||||
|
"discord.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/".return = "307 https://discord.gg/mkuKJkCuyM";
|
||||||
|
};
|
||||||
|
|
||||||
|
"public.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
root = "${inputs.compsoc_public.packages.x86_64-linux.default}";
|
||||||
|
locations."/".extraConfig = "autoindex on;";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
64
applications/skynet.ie/wiki.nix
Normal file
64
applications/skynet.ie/wiki.nix
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "wiki";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet Wiki";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"renew.skynet.ie"
|
||||||
|
"wiki.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = "renew";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "wiki";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
virtualHosts = {
|
||||||
|
"wiki.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
root = "${inputs.skynet_website_wiki.defaultPackage."x86_64-linux"}";
|
||||||
|
# https://stackoverflow.com/a/38238001/11964934
|
||||||
|
extraConfig = ''
|
||||||
|
location / {
|
||||||
|
if ($request_uri ~ ^/(.*)\.html) {
|
||||||
|
return 302 /$1;
|
||||||
|
}
|
||||||
|
try_files $uri $uri.html $uri/ =404;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# redirect old links to the new wiki
|
||||||
|
"renew.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
locations."/".return = "307 https://wiki.skynet.ie";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
138
applications/skynet_users.nix
Normal file
138
applications/skynet_users.nix
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "website_users";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
|
php_pool = name;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.skynet."${name}" = {
|
||||||
|
enable = mkEnableOption "Skynet User Linux Server";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# we havea more limited ports range on the skynet server
|
||||||
|
services.skynet.prometheus.ports = {
|
||||||
|
node = 9000;
|
||||||
|
};
|
||||||
|
|
||||||
|
# allow more than admins access
|
||||||
|
services.skynet.ldap_client = {
|
||||||
|
groups = [
|
||||||
|
"skynet-admins-linux"
|
||||||
|
"skynet-users-linux"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Website config
|
||||||
|
services.skynet.acme.domains = [
|
||||||
|
"users.skynet.ie"
|
||||||
|
"*.users.skynet.ie"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = "users";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "*.users";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
vim
|
||||||
|
php
|
||||||
|
];
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
defaultGateway = {
|
||||||
|
address = lib.mkDefault "193.1.96.161";
|
||||||
|
interface = lib.mkDefault "eth1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# normally services cannot read home dirs
|
||||||
|
systemd.services.nginx.serviceConfig.ProtectHome = "read-only";
|
||||||
|
systemd.services."phpfpm-${php_pool}".serviceConfig.ProtectHome = lib.mkForce "read-only";
|
||||||
|
|
||||||
|
services.phpfpm.pools.${php_pool} = {
|
||||||
|
user = config.services.nginx.user;
|
||||||
|
group = config.services.nginx.group;
|
||||||
|
settings = {
|
||||||
|
"listen.owner" = config.services.nginx.user;
|
||||||
|
"pm" = "dynamic";
|
||||||
|
"pm.max_children" = 32;
|
||||||
|
"pm.max_requests" = 500;
|
||||||
|
"pm.start_servers" = 2;
|
||||||
|
"pm.min_spare_servers" = 2;
|
||||||
|
"pm.max_spare_servers" = 5;
|
||||||
|
"php_admin_value[error_log]" = "stderr";
|
||||||
|
"php_admin_flag[log_errors]" = true;
|
||||||
|
"catch_workers_output" = true;
|
||||||
|
};
|
||||||
|
phpEnv."PATH" = lib.makeBinPath [pkgs.php];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"outinul.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
locations = {
|
||||||
|
"/" = {
|
||||||
|
alias = "/home/outinul/public_html/";
|
||||||
|
index = "index.html";
|
||||||
|
extraConfig = ''
|
||||||
|
autoindex on;
|
||||||
|
'';
|
||||||
|
tryFiles = "$uri$args $uri$args/ /index.html";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# main site
|
||||||
|
"*.users.skynet.ie" = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "skynet";
|
||||||
|
serverName = "~^(?<user>.+)\.users\.skynet\.ie";
|
||||||
|
|
||||||
|
# username.users.skynet.ie/
|
||||||
|
# user goes:
|
||||||
|
# chmod 711 ~
|
||||||
|
# chmod -R 755 ~/public_html
|
||||||
|
|
||||||
|
locations = {
|
||||||
|
"/" = {
|
||||||
|
alias = "/home/$user/public_html/";
|
||||||
|
index = "index.html";
|
||||||
|
extraConfig = ''
|
||||||
|
autoindex on;
|
||||||
|
'';
|
||||||
|
tryFiles = "$uri$args $uri$args/ /index.html";
|
||||||
|
};
|
||||||
|
|
||||||
|
"~ ^(.+\\.php)(.*)$" = {
|
||||||
|
root = "/home/$user/public_html/";
|
||||||
|
index = "index.php";
|
||||||
|
extraConfig = ''
|
||||||
|
autoindex on;
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
|
fastcgi_pass unix:${config.services.phpfpm.pools.${php_pool}.socket};
|
||||||
|
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||||
|
'';
|
||||||
|
tryFiles = "$uri$args $uri$args/ /index.php";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,29 +1,19 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{
|
||||||
with lib;
|
config,
|
||||||
let
|
lib,
|
||||||
cfg = config.services.skynet_ulfm;
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
name = "ulfm";
|
||||||
|
cfg = config.services.skynet."${name}";
|
||||||
in {
|
in {
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
./acme.nix
|
|
||||||
./dns.nix
|
|
||||||
./firewall.nix
|
|
||||||
./nginx.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
options.services.skynet_ulfm = {
|
options.services.skynet."${name}" = {
|
||||||
enable = mkEnableOption "ULFM service";
|
enable = mkEnableOption "ULFM service";
|
||||||
|
|
||||||
host = {
|
|
||||||
ip = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = {
|
domain = {
|
||||||
tld = mkOption {
|
tld = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -43,21 +33,29 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
# shove the entire config file into secrets
|
# TODO: extract this out into its own config
|
||||||
age.secrets.ulfm.file = ../secrets/stream_ulfm.age;
|
age.secrets.ulfm.file = ../secrets/stream_ulfm.age;
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
networking.firewall.allowedTCPPorts = [
|
||||||
8000
|
8000
|
||||||
];
|
];
|
||||||
|
|
||||||
skynet_dns.records = [
|
services.skynet.acme.domains = [
|
||||||
{record=cfg.domain.sub; r_type="CNAME"; value=cfg.host.name;}
|
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.skynet.dns.records = [
|
||||||
|
{
|
||||||
|
record = cfg.domain.sub;
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = config.services.skynet.host.name;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
skynet_firewall.forward = [
|
skynet_firewall.forward = [
|
||||||
"ip daddr ${cfg.host.ip} tcp dport 80 counter packets 0 bytes 0 accept"
|
"ip daddr ${config.services.skynet.host.ip} tcp dport 80 counter packets 0 bytes 0 accept"
|
||||||
"ip daddr ${cfg.host.ip} tcp dport 443 counter packets 0 bytes 0 accept"
|
"ip daddr ${config.services.skynet.host.ip} tcp dport 443 counter packets 0 bytes 0 accept"
|
||||||
"ip daddr ${cfg.host.ip} tcp dport 8000 counter packets 0 bytes 0 accept"
|
"ip daddr ${config.services.skynet.host.ip} tcp dport 8000 counter packets 0 bytes 0 accept"
|
||||||
];
|
];
|
||||||
|
|
||||||
users.groups."icecast" = {};
|
users.groups."icecast" = {};
|
||||||
|
@ -82,12 +80,14 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" = {
|
services.nginx = {
|
||||||
|
virtualHosts = {
|
||||||
|
"${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
useACMEHost = "skynet";
|
useACMEHost = "skynet";
|
||||||
locations."/".proxyPass = "http://localhost:8000";
|
locations."/".proxyPass = "http://localhost:8000";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
113
config/dns.nix
Normal file
113
config/dns.nix
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
{lib, ...}: {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
options.skynet.records = lib.mkOption {
|
||||||
|
description = "Records, sorted based on therir type";
|
||||||
|
type = lib.types.listOf (lib.types.submodule (import ../applications/dns/options-records.nix {
|
||||||
|
inherit lib;
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
skynet.records =
|
||||||
|
[
|
||||||
|
# wifi in server room
|
||||||
|
{
|
||||||
|
record = "ash";
|
||||||
|
r_type = "A";
|
||||||
|
value = "193.1.99.114";
|
||||||
|
server = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "optimus";
|
||||||
|
r_type = "A";
|
||||||
|
value = "193.1.99.90";
|
||||||
|
server = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "panel.games";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "optimus";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "bumblebee";
|
||||||
|
r_type = "A";
|
||||||
|
value = "193.1.99.91";
|
||||||
|
server = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "minecraft.compsoc.games";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "bumblebee";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_minecraft._tcp.minecraft.compsoc.games.skynet.ie.";
|
||||||
|
r_type = "SRV";
|
||||||
|
value = "0 10 25518 bumblebee.skynet.ie.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "minecraft-classic.compsoc.games";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "bumblebee";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_minecraft._tcp.minecraft-classic.compsoc.games.skynet.ie.";
|
||||||
|
r_type = "SRV";
|
||||||
|
value = "0 10 25518 bumblebee.skynet.ie.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "minecraft.gsoc.games";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "bumblebee";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_minecraft._tcp.minecraft.gsoc.games.skynet.ie.";
|
||||||
|
r_type = "SRV";
|
||||||
|
value = "0 10 25521 bumblebee.skynet.ie.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "minecraft.phildeb.games";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "bumblebee";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_minecraft._tcp.minecraft.phildeb.games.skynet.ie.";
|
||||||
|
r_type = "SRV";
|
||||||
|
value = "0 10 25522 bumblebee.skynet.ie.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "minecraft-aged.compsoc.games";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "bumblebee";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
record = "_minecraft._tcp.minecraft-aged.compsoc.games.skynet.ie.";
|
||||||
|
r_type = "SRV";
|
||||||
|
value = "0 10 25519 bumblebee.skynet.ie.";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# non skynet domains
|
||||||
|
++ [
|
||||||
|
{
|
||||||
|
domain = "conradcollins.net";
|
||||||
|
record = "www";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "skynet.skynet.ie.";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
domain = "edelharty.net";
|
||||||
|
record = "www";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "skynet.skynet.ie.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
domain = "damienconroy.com";
|
||||||
|
record = "www";
|
||||||
|
r_type = "CNAME";
|
||||||
|
value = "skynet.skynet.ie.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
408
config/users.nix
Normal file
408
config/users.nix
Normal file
|
@ -0,0 +1,408 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
port_backend = "8087";
|
||||||
|
cfg = config.skynet.users;
|
||||||
|
in {
|
||||||
|
options.skynet = {
|
||||||
|
users = {
|
||||||
|
committee = mkOption rec {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "array of committee members";
|
||||||
|
};
|
||||||
|
admin = mkOption rec {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "array of admins";
|
||||||
|
};
|
||||||
|
trainee = mkOption rec {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "array of trainee admins";
|
||||||
|
};
|
||||||
|
lifetime = mkOption rec {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "array of lifetime users";
|
||||||
|
};
|
||||||
|
banned = mkOption rec {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "array of banned users";
|
||||||
|
};
|
||||||
|
restricted = mkOption rec {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "array of restricted user accounts";
|
||||||
|
};
|
||||||
|
clubs_societies = mkOption rec {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = "array of accounts for Clubs and Societies";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config.skynet = {
|
||||||
|
users = {
|
||||||
|
committee = lib.lists.unique (
|
||||||
|
# Committee - Core
|
||||||
|
[
|
||||||
|
"silver"
|
||||||
|
"eoghanconlon73"
|
||||||
|
"nanda"
|
||||||
|
"emily1999"
|
||||||
|
"dgr"
|
||||||
|
]
|
||||||
|
# Committee - OCM
|
||||||
|
++ [
|
||||||
|
"sidhiel"
|
||||||
|
"skyapples"
|
||||||
|
"eliza"
|
||||||
|
"amymucko"
|
||||||
|
"archiedms"
|
||||||
|
]
|
||||||
|
# Committee - SISTEM
|
||||||
|
++ [
|
||||||
|
"peace"
|
||||||
|
]
|
||||||
|
# Admins are part of Committee as well
|
||||||
|
++ cfg.admin
|
||||||
|
);
|
||||||
|
admin = [
|
||||||
|
"silver"
|
||||||
|
"evanc"
|
||||||
|
"eliza"
|
||||||
|
"esy"
|
||||||
|
];
|
||||||
|
trainee = [];
|
||||||
|
lifetime = [];
|
||||||
|
banned = [];
|
||||||
|
|
||||||
|
clubs_societies = [
|
||||||
|
"outinul"
|
||||||
|
"gamesdev"
|
||||||
|
];
|
||||||
|
|
||||||
|
restricted =
|
||||||
|
[
|
||||||
|
# usernames folks arent allowed to use
|
||||||
|
"contact"
|
||||||
|
"dnsadm"
|
||||||
|
"president"
|
||||||
|
"treasurer"
|
||||||
|
"secretary"
|
||||||
|
"pro"
|
||||||
|
"sysadmin"
|
||||||
|
"root"
|
||||||
|
]
|
||||||
|
++ [
|
||||||
|
# basis comes from https://discord.com/channels/689189992417067052/1126084496710713414/1149072061466169444
|
||||||
|
# start off with compsoc stuff first
|
||||||
|
"competition_www"
|
||||||
|
"demo1"
|
||||||
|
"demouser"
|
||||||
|
"ftp"
|
||||||
|
"lost+found"
|
||||||
|
"postfix"
|
||||||
|
"skynews.old"
|
||||||
|
"system_backup"
|
||||||
|
"test"
|
||||||
|
"test12"
|
||||||
|
"test20202"
|
||||||
|
"test20203"
|
||||||
|
"tmp"
|
||||||
|
"webadm"
|
||||||
|
]
|
||||||
|
++ [
|
||||||
|
# clubs and socs (as far as I can tell
|
||||||
|
"aerosoc"
|
||||||
|
"aikido"
|
||||||
|
"anfocal"
|
||||||
|
"bics"
|
||||||
|
"boarding"
|
||||||
|
"cns"
|
||||||
|
"dev"
|
||||||
|
"filmsoc"
|
||||||
|
"gaa"
|
||||||
|
"german"
|
||||||
|
"golfsoc"
|
||||||
|
"handball"
|
||||||
|
"hispanic"
|
||||||
|
"history"
|
||||||
|
"hockey"
|
||||||
|
"home"
|
||||||
|
"legosoc"
|
||||||
|
"lifesave"
|
||||||
|
"mens_gfc"
|
||||||
|
"musicsoc"
|
||||||
|
"pagansoc"
|
||||||
|
"peacesoc"
|
||||||
|
"physics"
|
||||||
|
"poker"
|
||||||
|
"prolife"
|
||||||
|
"radio"
|
||||||
|
"ragweek"
|
||||||
|
"sinnfein"
|
||||||
|
"soccer"
|
||||||
|
"ulbs"
|
||||||
|
"ulcamogie"
|
||||||
|
"ulcc"
|
||||||
|
"ulgaa"
|
||||||
|
"ulils"
|
||||||
|
"ulladiesfootball"
|
||||||
|
"ullaughinsoc"
|
||||||
|
"ulrfc"
|
||||||
|
"ulriders"
|
||||||
|
"ulssc"
|
||||||
|
"ultennis"
|
||||||
|
"viking"
|
||||||
|
]
|
||||||
|
++ [
|
||||||
|
# remaining, most likely usernames
|
||||||
|
"_9thwonder"
|
||||||
|
"abc"
|
||||||
|
"activate"
|
||||||
|
"aiesec"
|
||||||
|
"air"
|
||||||
|
"aladdin"
|
||||||
|
"alaric"
|
||||||
|
"aldozzie"
|
||||||
|
"allenli"
|
||||||
|
"amg"
|
||||||
|
"amgl"
|
||||||
|
"annette"
|
||||||
|
"annlad"
|
||||||
|
"ards_backup"
|
||||||
|
"arisquez"
|
||||||
|
"arthur"
|
||||||
|
"austin"
|
||||||
|
"beta"
|
||||||
|
"bh"
|
||||||
|
"bigdave"
|
||||||
|
"bios"
|
||||||
|
"bizarroal"
|
||||||
|
"bmacaree"
|
||||||
|
"boardy"
|
||||||
|
"boddah"
|
||||||
|
"bogus.anime.fakh"
|
||||||
|
"bogus.bhudt.dacf"
|
||||||
|
"bogus.citoge.baym"
|
||||||
|
"bogus.electro.ba0a"
|
||||||
|
"bogus.fencing.baw5"
|
||||||
|
"bogus.harry.ba8f"
|
||||||
|
"bogus.hui.hong.baci"
|
||||||
|
"bogus.ironman.baqib"
|
||||||
|
"bogus.joe.bach"
|
||||||
|
"bogus.kenny.bas6"
|
||||||
|
"bogus.kerswin.baybb"
|
||||||
|
"bogus.kravmaga.ba0w"
|
||||||
|
"bogus.methi.baq5"
|
||||||
|
"bogus.nelsonmw.bauc"
|
||||||
|
"bogus.poshea.ba0m"
|
||||||
|
"bogus.redwolf.bawn"
|
||||||
|
"bogus.romanov.baat"
|
||||||
|
"bogus.ryan.bae-"
|
||||||
|
"bogus.rynnea.bask"
|
||||||
|
"bogus.sea.af"
|
||||||
|
"bogus.shane.c.ba8z"
|
||||||
|
"bogus.t1000.baggb"
|
||||||
|
"bogus.ullrugby.ba8p"
|
||||||
|
"brendan"
|
||||||
|
"bubba"
|
||||||
|
"c_material_removed"
|
||||||
|
"ca_worm"
|
||||||
|
"cactus"
|
||||||
|
"carticus"
|
||||||
|
"cathalc"
|
||||||
|
"cathald-broken"
|
||||||
|
"cdschedule"
|
||||||
|
"celtic"
|
||||||
|
"christine"
|
||||||
|
"cian"
|
||||||
|
"ciara"
|
||||||
|
"ciaran"
|
||||||
|
"colin"
|
||||||
|
"cosmo"
|
||||||
|
"counsel"
|
||||||
|
"creosote"
|
||||||
|
"crew"
|
||||||
|
"cues"
|
||||||
|
"cur"
|
||||||
|
"cwhelan"
|
||||||
|
"dac"
|
||||||
|
"daktulu"
|
||||||
|
"datacore"
|
||||||
|
"davec"
|
||||||
|
"daverus"
|
||||||
|
"deano"
|
||||||
|
"deccy"
|
||||||
|
"declanmu"
|
||||||
|
"deiji"
|
||||||
|
"dermotmc"
|
||||||
|
"derrick"
|
||||||
|
"deshocks"
|
||||||
|
"diarmuid"
|
||||||
|
"dippy"
|
||||||
|
"djraptor"
|
||||||
|
"dmackey"
|
||||||
|
"dmir"
|
||||||
|
"dom"
|
||||||
|
"dom_mckay"
|
||||||
|
"donie"
|
||||||
|
"donnacha"
|
||||||
|
"dos30"
|
||||||
|
"drazhar"
|
||||||
|
"duffman"
|
||||||
|
"eas"
|
||||||
|
"electal"
|
||||||
|
"emc"
|
||||||
|
"emilia"
|
||||||
|
"emma"
|
||||||
|
"emmag"
|
||||||
|
"ents"
|
||||||
|
"envcom"
|
||||||
|
"eoinh95"
|
||||||
|
"epgriffin"
|
||||||
|
"equest"
|
||||||
|
"fiacc"
|
||||||
|
"fint"
|
||||||
|
"flanno"
|
||||||
|
"fmannix"
|
||||||
|
"foodcoop"
|
||||||
|
"gamenet"
|
||||||
|
"ganainm"
|
||||||
|
"gar"
|
||||||
|
"ger88"
|
||||||
|
"ghama"
|
||||||
|
"ging"
|
||||||
|
"goborobo"
|
||||||
|
"gooner"
|
||||||
|
"greekweek"
|
||||||
|
"hawking"
|
||||||
|
"hb"
|
||||||
|
"homer"
|
||||||
|
"hoshi"
|
||||||
|
"ian"
|
||||||
|
"ianrice"
|
||||||
|
"ilug"
|
||||||
|
"infinity"
|
||||||
|
"ingenuus"
|
||||||
|
"internat"
|
||||||
|
"jamessy"
|
||||||
|
"jamiebarry"
|
||||||
|
"jbravo"
|
||||||
|
"jdonegan"
|
||||||
|
"joedredd"
|
||||||
|
"johann"
|
||||||
|
"jokill"
|
||||||
|
"jsoccer"
|
||||||
|
"jules"
|
||||||
|
"kate"
|
||||||
|
"katie"
|
||||||
|
"kellyj"
|
||||||
|
"kiely"
|
||||||
|
"koo"
|
||||||
|
"l_d_ablo"
|
||||||
|
"lakes"
|
||||||
|
"laura"
|
||||||
|
"lebowski"
|
||||||
|
"liabraid"
|
||||||
|
"lynn"
|
||||||
|
"mal"
|
||||||
|
"manuel"
|
||||||
|
"maraz"
|
||||||
|
"marieke"
|
||||||
|
"marky"
|
||||||
|
"mature"
|
||||||
|
"mbyrne"
|
||||||
|
"meanturtle"
|
||||||
|
"mickaful"
|
||||||
|
"mickasul"
|
||||||
|
"mikado"
|
||||||
|
"mikeh"
|
||||||
|
"mikkel"
|
||||||
|
"mixiezme"
|
||||||
|
"mmc"
|
||||||
|
"molly"
|
||||||
|
"moochie"
|
||||||
|
"moonser"
|
||||||
|
"mopic"
|
||||||
|
"mp"
|
||||||
|
"nastros"
|
||||||
|
"neutrino"
|
||||||
|
"new"
|
||||||
|
"nezzy"
|
||||||
|
"nkdc"
|
||||||
|
"nmcenroy"
|
||||||
|
"noelle"
|
||||||
|
"nugget"
|
||||||
|
"ob"
|
||||||
|
"omega"
|
||||||
|
"oneillbeano"
|
||||||
|
"pamela"
|
||||||
|
"peterj"
|
||||||
|
"photyl"
|
||||||
|
"plake"
|
||||||
|
"pmcg1986"
|
||||||
|
"pyro"
|
||||||
|
"qubeat"
|
||||||
|
"rachel"
|
||||||
|
"rachelg"
|
||||||
|
"ralmeida"
|
||||||
|
"raymond"
|
||||||
|
"razzlero"
|
||||||
|
"red"
|
||||||
|
"rmacm"
|
||||||
|
"rmorrissey"
|
||||||
|
"robson"
|
||||||
|
"selena"
|
||||||
|
"shark"
|
||||||
|
"shayscannell"
|
||||||
|
"shazlove"
|
||||||
|
"shelley"
|
||||||
|
"shelly"
|
||||||
|
"silver.old"
|
||||||
|
"sirhc"
|
||||||
|
"sithlord"
|
||||||
|
"sk"
|
||||||
|
"sligoer"
|
||||||
|
"slowey"
|
||||||
|
"smallp"
|
||||||
|
"smurfy"
|
||||||
|
"sordfish"
|
||||||
|
"soul98"
|
||||||
|
"soular"
|
||||||
|
"st"
|
||||||
|
"stefanovich"
|
||||||
|
"svp"
|
||||||
|
"szczerba"
|
||||||
|
"tangsoodo"
|
||||||
|
"tc"
|
||||||
|
"tenfor"
|
||||||
|
"teslacut"
|
||||||
|
"theematt"
|
||||||
|
"thomasl"
|
||||||
|
"tockman"
|
||||||
|
"ugm"
|
||||||
|
"vanzan"
|
||||||
|
"volleyb"
|
||||||
|
"warren"
|
||||||
|
"weather"
|
||||||
|
"wiles"
|
||||||
|
"yvonne"
|
||||||
|
"zrahman"
|
||||||
|
]
|
||||||
|
++ [
|
||||||
|
# former aliases
|
||||||
|
"david.dolphin"
|
||||||
|
"cc"
|
||||||
|
"mark.brennan"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
29
dev.nix
29
dev.nix
|
@ -1,29 +0,0 @@
|
||||||
# run with: nix-shell dev.nix
|
|
||||||
# has everything installed for dev
|
|
||||||
|
|
||||||
{ pkgs ? import <nixpkgs> {} }:
|
|
||||||
with pkgs;
|
|
||||||
let
|
|
||||||
imports =
|
|
||||||
let agenixCommit = "42d371d861a227149dc9a7e03350c9ab8b8ddd68";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
agenix = import
|
|
||||||
(builtins.fetchTarball {
|
|
||||||
url = "https://github.com/ryantm/agenix/archive/${agenixCommit}.tar.gz";
|
|
||||||
sha256 = "14sszf5s85i4jd3lc8c167fbxvpj13da45wl1j7wpd20n0fic5c1";
|
|
||||||
})
|
|
||||||
{ inherit pkgs; };
|
|
||||||
};
|
|
||||||
in mkShell {
|
|
||||||
# nativeBuildInputs is usually what you want -- tools you need to run
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.buildPackages.git
|
|
||||||
pkgs.buildPackages.colmena
|
|
||||||
pkgs.buildPackages.nmap
|
|
||||||
];
|
|
||||||
|
|
||||||
buildInputs = [ imports.agenix.agenix ];
|
|
||||||
|
|
||||||
shellHook = ''export EDITOR="${pkgs.nano}/bin/nano --nonewlines"'';
|
|
||||||
}
|
|
1298
flake.lock
1298
flake.lock
File diff suppressed because it is too large
Load diff
118
flake.nix
118
flake.nix
|
@ -1,33 +1,93 @@
|
||||||
{
|
{
|
||||||
|
|
||||||
description = "Deployment for skynet";
|
description = "Deployment for skynet";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
# gonna start off with a fairly modern base
|
# gonna start off with a fairly modern base
|
||||||
nixpkgs.url = "nixpkgs/nixos-23.05";
|
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||||
|
# Return to using unstable once the current master is merged in
|
||||||
|
# nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
|
lix-module = {
|
||||||
|
url = "https://git.lix.systems/lix-project/nixos-module/archive/2.91.1-1.tar.gz";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
# utility stuff
|
# utility stuff
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
agenix.url = "github:ryantm/agenix";
|
agenix.url = "github:ryantm/agenix";
|
||||||
arion.url = "github:hercules-ci/arion";
|
arion.url = "github:hercules-ci/arion";
|
||||||
|
alejandra = {
|
||||||
|
url = "github:kamadorueda/alejandra";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
colmena.url = "github:zhaofengli/colmena";
|
||||||
|
|
||||||
# email
|
# we host our own
|
||||||
# simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-23.05";
|
simple-nixos-mailserver = {
|
||||||
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
url = "git+https://forgejo.skynet.ie/Skynet/misc_nixos-mailserver";
|
||||||
# sso.skynet.ie
|
};
|
||||||
skynet_ldap_backend.url = "gitlab:compsoc%2Fskynet%2Fldap/backend?host=gitlab.skynet.ie";
|
|
||||||
skynet_ldap_frontend.url = "gitlab:compsoc%2Fskynet%2Fldap/frontend?host=gitlab.skynet.ie";
|
######################
|
||||||
|
### skynet backend ###
|
||||||
skynet_website.url = "gitlab:compsoc%2Fskynet%2Fwebsite/2023?host=gitlab.skynet.ie";
|
######################
|
||||||
skynet_website_2016.url = "gitlab:compsoc%2Fskynet%2Fwebsite/2016?host=gitlab.skynet.ie";
|
skynet_ldap_backend.url = "git+https://forgejo.skynet.ie/Skynet/ldap_backend";
|
||||||
|
skynet_ldap_frontend.url = "git+https://forgejo.skynet.ie/Skynet/ldap_frontend";
|
||||||
|
skynet_website_wiki.url = "git+https://forgejo.skynet.ie/Skynet/wiki";
|
||||||
|
skynet_website_games.url = "git+https://forgejo.skynet.ie/Skynet/website_games";
|
||||||
|
skynet_discord_bot.url = "git+https://forgejo.skynet.ie/Skynet/discord-bot";
|
||||||
|
|
||||||
|
#####################
|
||||||
|
### compsoc stuff ###
|
||||||
|
#####################
|
||||||
|
compsoc_public.url = "git+https://forgejo.skynet.ie/Computer_Society/presentations_compsoc";
|
||||||
|
|
||||||
|
#################
|
||||||
|
### skynet.ie ###
|
||||||
|
#################
|
||||||
|
|
||||||
|
# this should always point to teh current website
|
||||||
|
skynet_website.url = "git+https://forgejo.skynet.ie/Skynet/website_2017";
|
||||||
|
|
||||||
|
# these are past versions of teh website
|
||||||
|
skynet_website_2023.url = "git+https://forgejo.skynet.ie/Skynet/website_2017?rev=c4d61c753292bf73ed41b47b1607cfc92a82a191";
|
||||||
|
# this is not 100% right since this is from teh archive from 2022 or so
|
||||||
|
skynet_website_2017.url = "git+https://forgejo.skynet.ie/Skynet/website_2017?rev=edd922c5b13fa1f520e8e265a3d6e4e189852b99";
|
||||||
|
|
||||||
|
# this is more of 2012 than 2009 but started in 2009
|
||||||
|
skynet_website_2009.url = "git+https://forgejo.skynet.ie/Skynet/website_2009";
|
||||||
|
};
|
||||||
|
|
||||||
|
nixConfig = {
|
||||||
|
bash-prompt-suffix = "[Skynet Dev] ";
|
||||||
|
extra-substituters = "https://nix-cache.skynet.ie/skynet-cache";
|
||||||
|
extra-trusted-public-keys = "skynet-cache:zMFLzcRZPhUpjXUy8SF8Cf7KGAZwo98SKrzeXvdWABo=";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = {
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
agenix,
|
||||||
|
alejandra,
|
||||||
|
colmena,
|
||||||
|
...
|
||||||
|
} @ inputs: let
|
||||||
|
pkgs = nixpkgs.legacyPackages.x86_64-linux.pkgs;
|
||||||
|
in {
|
||||||
|
formatter.x86_64-linux = alejandra.defaultPackage."x86_64-linux";
|
||||||
|
|
||||||
|
devShells.x86_64-linux.default = pkgs.mkShell {
|
||||||
|
name = "Skynet build env";
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkgs.buildPackages.git
|
||||||
|
colmena.defaultPackage."x86_64-linux"
|
||||||
|
pkgs.attic-client
|
||||||
|
pkgs.buildPackages.nmap
|
||||||
|
];
|
||||||
|
buildInputs = [agenix.packages.x86_64-linux.default];
|
||||||
|
shellHook = ''export EDITOR="${pkgs.nano}/bin/nano --nonewlines"; unset LD_LIBRARY_PATH;'';
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, ... } @inputs: {
|
|
||||||
# https://github.com/zhaofengli/colmena
|
|
||||||
# colmena apply --on agentjones
|
|
||||||
# colmena apply --on @dns
|
|
||||||
# nix flake lock --update-input skynet_ldap_backend
|
|
||||||
colmena = {
|
colmena = {
|
||||||
meta = {
|
meta = {
|
||||||
nixpkgs = import nixpkgs {
|
nixpkgs = import nixpkgs {
|
||||||
|
@ -35,7 +95,7 @@
|
||||||
overlays = [];
|
overlays = [];
|
||||||
};
|
};
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit inputs self;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,9 +114,6 @@
|
||||||
# icecast - ULFM
|
# icecast - ULFM
|
||||||
galatea = import ./machines/galatea.nix;
|
galatea = import ./machines/galatea.nix;
|
||||||
|
|
||||||
# Game host
|
|
||||||
optimus = import ./machines/optimus.nix;
|
|
||||||
|
|
||||||
# LDAP host
|
# LDAP host
|
||||||
kitt = import ./machines/kitt.nix;
|
kitt = import ./machines/kitt.nix;
|
||||||
|
|
||||||
|
@ -72,10 +129,23 @@
|
||||||
# backup 1
|
# backup 1
|
||||||
neuromancer = import ./machines/neuromancer.nix;
|
neuromancer = import ./machines/neuromancer.nix;
|
||||||
|
|
||||||
# Skynet
|
# Skynet, user ssh access
|
||||||
skynet = import ./machines/skynet.nix;
|
skynet = import ./machines/skynet.nix;
|
||||||
|
|
||||||
};
|
# Main skynet sites
|
||||||
};
|
earth = import ./machines/earth.nix;
|
||||||
|
|
||||||
|
# Nextcloud
|
||||||
|
cadie = import ./machines/cadie.nix;
|
||||||
|
|
||||||
|
# trainee server
|
||||||
|
marvin = import ./machines/marvin.nix;
|
||||||
|
|
||||||
|
# Public Services
|
||||||
|
calculon = import ./machines/calculon.nix;
|
||||||
|
|
||||||
|
# metrics
|
||||||
|
ariia = import ./machines/ariia.nix;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,66 @@
|
||||||
{ pkgs, modulesPath, config, options, inputs, ... }:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
pkgs,
|
||||||
|
modulesPath,
|
||||||
|
config,
|
||||||
|
options,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.skynet;
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
(modulesPath + "/virtualisation/proxmox-lxc.nix")
|
# custom lxc mocule until the patch gets merged in
|
||||||
|
../applications/proxmox-lxc.nix
|
||||||
|
# (modulesPath + "/virtualisation/proxmox-lxc.nix")
|
||||||
|
|
||||||
# for the secrets
|
# for the secrets
|
||||||
inputs.agenix.nixosModule
|
inputs.agenix.nixosModules.default
|
||||||
|
|
||||||
# every sever may need the firewall config stuff
|
# base application config for all servers
|
||||||
../applications/firewall.nix
|
../applications/_base.nix
|
||||||
|
|
||||||
# every sever needs to have a dns record
|
#
|
||||||
../applications/dns.nix
|
inputs.lix-module.nixosModules.default
|
||||||
|
|
||||||
# every server needs teh ldap client for admins
|
|
||||||
../applications/ldap_client.nix
|
|
||||||
|
|
||||||
# every server will need the config to backup to
|
|
||||||
../applications/restic.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
options.skynet = {
|
||||||
|
lxc = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
# most of our servers are lxc so its true by default
|
||||||
|
default = true;
|
||||||
|
description = mdDoc "Is this a Linux Container?";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# if its a lxc enable
|
||||||
|
proxmoxLXC.enable = cfg.lxc;
|
||||||
|
|
||||||
|
nix = {
|
||||||
|
settings = {
|
||||||
# flakes are essensial
|
# flakes are essensial
|
||||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
experimental-features = ["nix-command" "flakes"];
|
||||||
|
trusted-users = [
|
||||||
|
"root"
|
||||||
|
"@skynet-admins-linux"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://nixos.wiki/wiki/Storage_optimization
|
||||||
|
# gc = {
|
||||||
|
# automatic = true;
|
||||||
|
# dates = "weekly";
|
||||||
|
# options = "--delete-older-than 30d";
|
||||||
|
# };
|
||||||
|
|
||||||
|
# to free up to 10GiB whenever there is less than 1GiB left
|
||||||
|
extraOptions = ''
|
||||||
|
min-free = ${toString (1024 * 1024 * 1024)}
|
||||||
|
max-free = ${toString (1024 * 1024 * 1024 * 10)}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
system.stateVersion = "22.11";
|
system.stateVersion = "22.11";
|
||||||
|
|
||||||
|
@ -39,6 +78,9 @@
|
||||||
# Root account
|
# Root account
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK6DjXTAxesXpQ65l659iAjzEb6VpRaWKSg4AXxifPw9 Skynet Admin"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK6DjXTAxesXpQ65l659iAjzEb6VpRaWKSg4AXxifPw9 Skynet Admin"
|
||||||
|
|
||||||
|
# CI/CD key
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBDvexq/JjsMqL0G5P38klzoOkHs3IRyXYO1luEJuB5R colmena_key"
|
||||||
|
|
||||||
# Brendan Golden
|
# Brendan Golden
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEHNLroAjCVR9Tx382cqdxPZ5KY32r/yoQH1mgsYNqpm Silver_Laptop_WSL_Deb"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEHNLroAjCVR9Tx382cqdxPZ5KY32r/yoQH1mgsYNqpm Silver_Laptop_WSL_Deb"
|
||||||
|
|
||||||
|
@ -47,14 +89,17 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
# skynet-admin-linux will always be added, individual servers can override the groups option
|
# skynet-admin-linux will always be added, individual servers can override the groups option
|
||||||
services.skynet_ldap_client.enable = true;
|
services.skynet.ldap_client.enable = true;
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
# every sever needs to be accessable over ssh for admin use at least
|
# every sever needs to be accessable over ssh for admin use at least
|
||||||
firewall.allowedTCPPorts = [22];
|
firewall.allowedTCPPorts = [22];
|
||||||
|
|
||||||
# explisitly stating this is good
|
# explisitly stating this is good
|
||||||
defaultGateway = "193.1.99.65";
|
defaultGateway = {
|
||||||
|
address = "193.1.99.65";
|
||||||
|
interface = "eth0";
|
||||||
|
};
|
||||||
|
|
||||||
# cannot use our own it seems?
|
# cannot use our own it seems?
|
||||||
nameservers = [
|
nameservers = [
|
||||||
|
@ -72,18 +117,23 @@
|
||||||
# use teh above nameservers as the fallback dns
|
# use teh above nameservers as the fallback dns
|
||||||
services.resolved.fallbackDns = config.networking.nameservers;
|
services.resolved.fallbackDns = config.networking.nameservers;
|
||||||
|
|
||||||
environment.systemPackages = [
|
# https://discourse.nixos.org/t/systemd-networkd-wait-online-934764-timeout-occurred-while-waiting-for-network-connectivity/33656/9
|
||||||
|
systemd.network.wait-online.enable = false;
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
# for flakes
|
# for flakes
|
||||||
pkgs.git
|
git
|
||||||
|
git-lfs
|
||||||
# useful tools
|
# useful tools
|
||||||
pkgs.ncdu_2
|
ncdu_2
|
||||||
pkgs.htop
|
htop
|
||||||
pkgs.nano
|
nano
|
||||||
pkgs.nmap
|
nmap
|
||||||
pkgs.bind
|
bind
|
||||||
pkgs.zip
|
zip
|
||||||
pkgs.traceroute
|
traceroute
|
||||||
pkgs.openldap
|
openldap
|
||||||
pkgs.screen
|
screen
|
||||||
];
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,69 +6,56 @@
|
||||||
From: 2011 (?)
|
From: 2011 (?)
|
||||||
Role: Firewall
|
Role: Firewall
|
||||||
Notes: Used to have Agent Smith as a partner but it died (Ironically)
|
Notes: Used to have Agent Smith as a partner but it died (Ironically)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "agentjones";
|
name = "agentjones";
|
||||||
ip_pub = "193.1.99.72";
|
ip_pub = "193.1.99.72";
|
||||||
ip_priv = "193.1.99.125";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./hardware/_base.nix
|
|
||||||
./hardware/RM001.nix
|
./hardware/RM001.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = hostname;
|
targetHost = hostname;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = [ "active" ];
|
# somehow ssh from runner to this fails
|
||||||
|
tags = ["active-firewall"];
|
||||||
};
|
};
|
||||||
|
|
||||||
skynet_dns.records = [
|
services.skynet = {
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
host = host;
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
backup.enable = true;
|
||||||
];
|
|
||||||
|
|
||||||
services.skynet_backup = {
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# keep the wired usb connection alive (front panel)
|
# keep the wired usb connection alive (front panel)
|
||||||
networking.interfaces.enp0s29u1u5u2.useDHCP = true;
|
# networking.interfaces.enp0s29u1u5u2.useDHCP = true;
|
||||||
|
|
||||||
networking.hostName = name;
|
networking.hostName = name;
|
||||||
# this has to be defined for any physical servers
|
# this has to be defined for any physical servers
|
||||||
# vms are defined by teh vm host
|
# vms are defined by teh vm host
|
||||||
networking.interfaces = {
|
networking = {
|
||||||
eno2 = {
|
defaultGateway.interface = lib.mkForce "eno1";
|
||||||
ipv4.addresses = [
|
interfaces.eno1.ipv4.addresses = [
|
||||||
{
|
{
|
||||||
address = ip_pub;
|
address = ip_pub;
|
||||||
prefixLength = 26;
|
prefixLength = 26;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
eno1 = {
|
|
||||||
#useDHCP = false;
|
|
||||||
ipv4.addresses = [
|
|
||||||
{
|
|
||||||
# internal address
|
|
||||||
address = ip_priv;
|
|
||||||
prefixLength = 26;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# this server is teh firewall
|
# this server is teh firewall
|
||||||
skynet_firewall = {
|
skynet_firewall = {
|
||||||
|
@ -86,23 +73,25 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
enable = true;
|
enable = false;
|
||||||
|
|
||||||
# gonna have to get all the
|
# gonna have to get all the
|
||||||
forward = builtins.concatLists (
|
forward = builtins.concatLists (
|
||||||
# using this function "(key: value: value.config.skynet_firewall.forward)" turn the values ointo a list
|
# using this function "(key: value: value.config.skynet_firewall.forward)" turn the values ointo a list
|
||||||
lib.attrsets.mapAttrsToList (key: value:
|
lib.attrsets.mapAttrsToList (
|
||||||
|
key: value:
|
||||||
# make sure that anything running this firewall dosent count (recursion otherewise)
|
# make sure that anything running this firewall dosent count (recursion otherewise)
|
||||||
# firewall may want to open ports in itself but can deal with that later
|
# firewall may want to open ports in itself but can deal with that later
|
||||||
if builtins.hasAttr "skynet_firewall" value.config
|
if builtins.hasAttr "skynet_firewall" value.config
|
||||||
then (
|
then
|
||||||
|
(
|
||||||
if value.config.skynet_firewall.enable
|
if value.config.skynet_firewall.enable
|
||||||
then []
|
then []
|
||||||
else value.config.skynet_firewall.forward
|
else value.config.skynet_firewall.forward
|
||||||
)
|
)
|
||||||
else []
|
else []
|
||||||
) nodes
|
)
|
||||||
|
nodes
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
47
machines/ariia.nix
Normal file
47
machines/ariia.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Name: https://en.wikipedia.org/wiki/Eagle_Eye
|
||||||
|
Why: ARIIA - Autonomous Reconnaissance Intelligence Integration Analyst
|
||||||
|
Type: VM
|
||||||
|
Hardware: -
|
||||||
|
From: 2024
|
||||||
|
Role: Metrics gathering and Analysis
|
||||||
|
Notes:
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
# name of the server, sets teh hostname and record for it
|
||||||
|
name = "ariia";
|
||||||
|
ip_pub = "193.1.99.83";
|
||||||
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
../applications/grafana.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
deployment = {
|
||||||
|
targetHost = hostname;
|
||||||
|
targetPort = 22;
|
||||||
|
targetUser = null;
|
||||||
|
|
||||||
|
tags = ["active-core"];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.skynet = {
|
||||||
|
host = host;
|
||||||
|
backup.enable = true;
|
||||||
|
|
||||||
|
prometheus.server.enable = true;
|
||||||
|
grafana.enable = true;
|
||||||
|
};
|
||||||
|
}
|
47
machines/cadie.nix
Normal file
47
machines/cadie.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Name: https://en.wikipedia.org/wiki/List_of_Google_April_Fools%27_Day_jokes#CADIE
|
||||||
|
Why: CADIE is what google could have been, but they chickened out.
|
||||||
|
Type: VM
|
||||||
|
Hardware: -
|
||||||
|
From: 2023
|
||||||
|
Role: Google but better
|
||||||
|
Notes:
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
# name of the server, sets teh hostname and record for it
|
||||||
|
name = "cadie";
|
||||||
|
ip_pub = "193.1.99.77";
|
||||||
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
../applications/nextcloud.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
deployment = {
|
||||||
|
targetHost = hostname;
|
||||||
|
targetPort = 22;
|
||||||
|
targetUser = null;
|
||||||
|
|
||||||
|
tags = ["active"];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.skynet = {
|
||||||
|
host = host;
|
||||||
|
backup.enable = true;
|
||||||
|
nextcloud.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# this was causing a conflict for some reason
|
||||||
|
systemd.network.enable = lib.mkForce false;
|
||||||
|
}
|
49
machines/calculon.nix
Normal file
49
machines/calculon.nix
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Name: https://futurama.fandom.com/wiki/Calculon
|
||||||
|
Why: Public Service server
|
||||||
|
Type: VM
|
||||||
|
Hardware: -
|
||||||
|
From: 2024
|
||||||
|
Role: Public services such as Nix Cache, Open governance stuff.
|
||||||
|
Notes:
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
nodes,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
name = "calculon";
|
||||||
|
ip_pub = "193.1.99.82";
|
||||||
|
hostname = "${name}.skynet.ie";
|
||||||
|
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
../applications/nix_cache/nix_cache.nix
|
||||||
|
../applications/open_governance/open_governance.nix
|
||||||
|
../applications/open_governance/keyserver.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
deployment = {
|
||||||
|
targetHost = hostname;
|
||||||
|
targetPort = 22;
|
||||||
|
targetUser = null;
|
||||||
|
|
||||||
|
tags = ["active"];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.skynet = {
|
||||||
|
host = host;
|
||||||
|
backup.enable = true;
|
||||||
|
nix-cache.enable = true;
|
||||||
|
open-governance.enable = true;
|
||||||
|
keyserver.enable = true;
|
||||||
|
};
|
||||||
|
}
|
46
machines/earth.nix
Normal file
46
machines/earth.nix
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Name: https://hitchhikers.fandom.com/wiki/Earth
|
||||||
|
Why: Our home(page)
|
||||||
|
Type: VM
|
||||||
|
Hardware: -
|
||||||
|
From: 2023
|
||||||
|
Role: Webserver
|
||||||
|
Notes:
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
nodes,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
name = "earth";
|
||||||
|
ip_pub = "193.1.99.79";
|
||||||
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
../applications/skynet.ie/skynet.ie.nix
|
||||||
|
../applications/skynet.ie/wiki.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
deployment = {
|
||||||
|
targetHost = hostname;
|
||||||
|
targetPort = 22;
|
||||||
|
targetUser = null;
|
||||||
|
|
||||||
|
tags = ["active-core"];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.skynet = {
|
||||||
|
host = host;
|
||||||
|
backup.enable = true;
|
||||||
|
website.enable = true;
|
||||||
|
wiki.enable = true;
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,16 +7,23 @@
|
||||||
From: 2023
|
From: 2023
|
||||||
Role: Icecast server for ULFM
|
Role: Icecast server for ULFM
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, config, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "galatea";
|
name = "galatea";
|
||||||
ip_pub = "193.1.99.111";
|
ip_pub = "193.1.99.111";
|
||||||
ip_priv = "172.20.20.6";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../applications/ulfm.nix
|
../applications/ulfm.nix
|
||||||
|
@ -25,28 +32,14 @@ in {
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = hostname;
|
targetHost = hostname;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = ["active"];
|
tags = ["active"];
|
||||||
};
|
};
|
||||||
|
|
||||||
skynet_dns.records = [
|
services.skynet = {
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
host = host;
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
backup.enable = true;
|
||||||
];
|
ulfm.enable = true;
|
||||||
|
|
||||||
services.skynet_backup = {
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.skynet_ulfm = {
|
|
||||||
enable = true;
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,22 @@
|
||||||
From: 2023
|
From: 2023
|
||||||
Role: Email Server
|
Role: Email Server
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "gir";
|
name = "gir";
|
||||||
ip_pub = "193.1.99.76";
|
ip_pub = "193.1.99.76";
|
||||||
ip_priv = "172.20.20.5";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
#hostname = ip_pub;
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../applications/email.nix
|
../applications/email.nix
|
||||||
|
@ -27,31 +31,14 @@ in {
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = hostname;
|
targetHost = hostname;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = [ "active" ];
|
tags = ["active-core"];
|
||||||
};
|
};
|
||||||
|
|
||||||
# add this server to dns
|
services.skynet = {
|
||||||
skynet_dns.records = [
|
host = host;
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
backup.enable = true;
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
email.enable = true;
|
||||||
];
|
|
||||||
|
|
||||||
services.skynet_backup = {
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# we use this to pass in teh relevent infomation to the
|
|
||||||
services.skynet_email = {
|
|
||||||
enable = true;
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
domain = "skynet.ie";
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,49 +8,40 @@
|
||||||
Role: Git server
|
Role: Git server
|
||||||
Notes: Each user has roughly 20gb os storage
|
Notes: Each user has roughly 20gb os storage
|
||||||
20 * 100 = 2000gb
|
20 * 100 = 2000gb
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "glados";
|
name = "glados";
|
||||||
ip_pub = "193.1.99.75";
|
ip_pub = "193.1.99.75";
|
||||||
ip_priv = "172.20.20.7";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../applications/gitlab.nix
|
../applications/git/gitlab.nix
|
||||||
|
../applications/git/forgejo.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = hostname;
|
targetHost = hostname;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = ["active-gitlab"];
|
tags = ["active-gitlab"];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.skynet = {
|
||||||
skynet_dns.records = [
|
host = host;
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
backup.enable = true;
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
gitlab.enable = true;
|
||||||
];
|
forgejo.enable = true;
|
||||||
|
|
||||||
services.skynet_backup = {
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
services.skynet_gitlab = {
|
|
||||||
enable = true;
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,30 +1,39 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
# and may be overwritten by future invocations. Please make changes
|
# and may be overwritten by future invocations. Please make changes
|
||||||
# to /etc/nixos/configuration.nix instead.
|
# to /etc/nixos/configuration.nix instead.
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
config,
|
||||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
lib,
|
||||||
|
pkgs,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
./_base.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Use the systemd-boot EFI boot loader.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = ["ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod"];
|
boot.initrd.availableKernelModules = ["ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod"];
|
||||||
boot.initrd.kernelModules = [];
|
boot.initrd.kernelModules = [];
|
||||||
boot.kernelModules = [];
|
boot.kernelModules = [];
|
||||||
boot.extraModulePackages = [];
|
boot.extraModulePackages = [];
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" = {
|
||||||
{ device = "/dev/disk/by-uuid/9b177e4a-726e-4e68-a0e1-53837a8cae2e";
|
device = "/dev/disk/by-uuid/f7b9d648-735f-44b7-b439-6af601b234a7";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" = {
|
||||||
{ device = "/dev/disk/by-uuid/41AD-70AF";
|
device = "/dev/disk/by-uuid/679E-C352";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices =
|
swapDevices = [
|
||||||
[ { device = "/dev/disk/by-uuid/c5990c64-077f-45b1-96b5-44ec93e6651f"; }
|
{device = "/dev/disk/by-uuid/b1da9f57-1ed0-4f10-a6c0-6536a0017b2a";}
|
||||||
];
|
];
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
@ -34,7 +43,6 @@
|
||||||
networking.useDHCP = lib.mkDefault true;
|
networking.useDHCP = lib.mkDefault true;
|
||||||
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
|
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
|
||||||
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
|
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
|
||||||
# networking.interfaces.enp0s29u1u1.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
|
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
|
|
@ -1,30 +1,39 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
# and may be overwritten by future invocations. Please make changes
|
# and may be overwritten by future invocations. Please make changes
|
||||||
# to /etc/nixos/configuration.nix instead.
|
# to /etc/nixos/configuration.nix instead.
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
config,
|
||||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
lib,
|
||||||
|
pkgs,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
./_base.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Use the systemd-boot EFI boot loader.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = ["ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod"];
|
boot.initrd.availableKernelModules = ["ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod"];
|
||||||
boot.initrd.kernelModules = [];
|
boot.initrd.kernelModules = [];
|
||||||
boot.kernelModules = [];
|
boot.kernelModules = [];
|
||||||
boot.extraModulePackages = [];
|
boot.extraModulePackages = [];
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" = {
|
||||||
{ device = "/dev/disk/by-uuid/34918a4f-ca27-4070-a309-94bc59bdd743";
|
device = "/dev/disk/by-uuid/5c1a39c9-c458-4518-b75b-5a831bebc204";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" = {
|
||||||
{ device = "/dev/disk/by-uuid/8B03-4D11";
|
device = "/dev/disk/by-uuid/8CBD-7032";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices =
|
swapDevices = [
|
||||||
[ { device = "/dev/disk/by-uuid/c83e65ad-d252-4024-93a9-0253c5d8beac"; }
|
{device = "/dev/disk/by-uuid/515df5d9-abad-4068-bacc-559fb76e1fb1";}
|
||||||
];
|
];
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
@ -34,7 +43,6 @@
|
||||||
networking.useDHCP = lib.mkDefault true;
|
networking.useDHCP = lib.mkDefault true;
|
||||||
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
|
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
|
||||||
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
|
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
|
||||||
# networking.interfaces.enp0s29u1u2.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
|
|
@ -1,30 +1,32 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
# and may be overwritten by future invocations. Please make changes
|
# and may be overwritten by future invocations. Please make changes
|
||||||
# to /etc/nixos/configuration.nix instead.
|
# to /etc/nixos/configuration.nix instead.
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
config,
|
||||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
lib,
|
||||||
|
pkgs,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
./_base.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sr_mod" ];
|
boot.initrd.availableKernelModules = ["ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod"];
|
||||||
boot.initrd.kernelModules = [];
|
boot.initrd.kernelModules = [];
|
||||||
boot.kernelModules = [];
|
boot.kernelModules = [];
|
||||||
boot.extraModulePackages = [];
|
boot.extraModulePackages = [];
|
||||||
|
|
||||||
fileSystems."/" =
|
boot.loader.grub.device = "/dev/sda";
|
||||||
{ device = "/dev/disk/by-uuid/c48817e1-036f-49a7-adae-f63fc6c03cd5";
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-uuid/a6c96ea1-1e66-4ad3-aef6-dd7131c83530";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
swapDevices = [
|
||||||
{ device = "/dev/disk/by-uuid/76CE-C65E";
|
{device = "/dev/disk/by-uuid/5408b486-62ce-45d9-bca5-b458e68ef7f4";}
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices =
|
|
||||||
[ { device = "/dev/disk/by-uuid/eced30bd-b785-43e0-a202-cdaee7e0f4f7"; }
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
|
|
@ -1,17 +1,27 @@
|
||||||
{ config, options, lib, ... }: with lib;
|
{
|
||||||
let
|
config,
|
||||||
|
options,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
# get a list of interfaces
|
# get a list of interfaces
|
||||||
interfaces = attrNames config.networking.interfaces;
|
interfaces = attrNames config.networking.interfaces;
|
||||||
# check if an IP has been assigned
|
# check if an IP has been assigned
|
||||||
has_ip = interface: (length config.networking.interfaces."${interface}".ipv4.addresses) != 0;
|
has_ip = interface: (length config.networking.interfaces."${interface}".ipv4.addresses) != 0;
|
||||||
in {
|
in {
|
||||||
config = {
|
config = {
|
||||||
|
skynet.lxc = false;
|
||||||
|
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertion = lists.any has_ip interfaces;
|
assertion = lists.any has_ip interfaces;
|
||||||
message = "Must have a ip address set";
|
message = "Must have a ip address set";
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
assertion = config.networking.hostName != "nixos";
|
||||||
|
message = "Must have networking.hostName set";
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -7,49 +7,52 @@
|
||||||
From: 2023
|
From: 2023
|
||||||
Role: LDAP Server
|
Role: LDAP Server
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
config,
|
||||||
let
|
pkgs,
|
||||||
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "kitt";
|
name = "kitt";
|
||||||
ip_pub = "193.1.99.74";
|
ip_pub = "193.1.99.74";
|
||||||
ip_priv = "172.20.20.5";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
#hostname = ip_pub;
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../applications/ldap.nix
|
../applications/ldap/server.nix
|
||||||
|
../applications/ldap/backend.nix
|
||||||
|
../applications/discord.nix
|
||||||
|
../applications/bitwarden/vaultwarden.nix
|
||||||
|
../applications/bitwarden/bitwarden_sync.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = hostname;
|
targetHost = hostname;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = [ "active" ];
|
tags = ["active-core"];
|
||||||
};
|
};
|
||||||
|
|
||||||
# add this server to dns
|
services.skynet = {
|
||||||
skynet_dns.records = [
|
host = host;
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
backup.enable = true;
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
|
||||||
];
|
|
||||||
|
|
||||||
services.skynet_backup = {
|
# ldap setup
|
||||||
host = {
|
ldap.enable = true;
|
||||||
ip = ip_pub;
|
ldap_backend.enable = true;
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.skynet_ldap = {
|
# private member services
|
||||||
enable = true;
|
discord_bot.enable = true;
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
# committee/admin services
|
||||||
name = name;
|
vaultwarden.enable = true;
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
61
machines/marvin.nix
Normal file
61
machines/marvin.nix
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Name: https://en.wikipedia.org/wiki/Marvin_the_Paranoid_Android
|
||||||
|
Why: Has terrible pain in all the diodes down its left side
|
||||||
|
Type: VM
|
||||||
|
Hardware: -
|
||||||
|
From: 2023
|
||||||
|
Role: For trainees.
|
||||||
|
Notes:
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
name = "marvin";
|
||||||
|
ip_pub = "193.1.99.81";
|
||||||
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
|
|
||||||
|
groups = [
|
||||||
|
"skynet-admins-linux"
|
||||||
|
"skynet-trainees-linux"
|
||||||
|
];
|
||||||
|
groups_trusted = map (x: "@${x}") groups;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
];
|
||||||
|
|
||||||
|
deployment = {
|
||||||
|
targetHost = hostname;
|
||||||
|
targetPort = 22;
|
||||||
|
targetUser = null;
|
||||||
|
|
||||||
|
# not deployed automatically as its a test server
|
||||||
|
tags = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
# allow trainees to deploy
|
||||||
|
nix.settings.trusted-users =
|
||||||
|
[
|
||||||
|
"root"
|
||||||
|
]
|
||||||
|
++ groups_trusted;
|
||||||
|
|
||||||
|
# allow trainees access
|
||||||
|
services.skynet.ldap_client = {
|
||||||
|
groups = groups;
|
||||||
|
sudo_groups = groups;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.skynet = {
|
||||||
|
host = host;
|
||||||
|
backup.enable = true;
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,53 +7,50 @@
|
||||||
From: 2023
|
From: 2023
|
||||||
Role: Backup Server
|
Role: Backup Server
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "neuromancer";
|
name = "neuromancer";
|
||||||
ip_pub = "193.1.99.80";
|
ip_pub = "193.1.99.80";
|
||||||
ip_priv = "172.20.20.7";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./hardware/_base.nix
|
|
||||||
./hardware/RM007.nix
|
./hardware/RM007.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
networking.hostName = name;
|
networking.hostName = name;
|
||||||
# this has to be defined for any physical servers
|
# this has to be defined for any physical servers
|
||||||
# vms are defined by teh vm host
|
# vms are defined by teh vm host
|
||||||
networking.interfaces.eno1.ipv4.addresses = [
|
networking = {
|
||||||
|
defaultGateway.interface = lib.mkForce "eno1";
|
||||||
|
interfaces.eno1.ipv4.addresses = [
|
||||||
{
|
{
|
||||||
address = ip_pub;
|
address = ip_pub;
|
||||||
prefixLength = 26;
|
prefixLength = 26;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
};
|
||||||
|
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = hostname;
|
targetHost = hostname;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = [ "active" ];
|
tags = ["active-core"];
|
||||||
};
|
};
|
||||||
|
|
||||||
skynet_dns.records = [
|
services.skynet = {
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
host = host;
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
backup.server.enable = true;
|
||||||
];
|
|
||||||
|
|
||||||
services.skynet_backup = {
|
|
||||||
server.enable = true;
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
Name: https://en.wikipedia.org/wiki/Optimus_Prime
|
|
||||||
Why: Created to sell toys so this vm is for games
|
|
||||||
Type: VM
|
|
||||||
Hardware: -
|
|
||||||
From: 2023
|
|
||||||
Role: Game host
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
{ pkgs, lib, nodes, arion, ... }:
|
|
||||||
let
|
|
||||||
# name of the server, sets teh hostname and record for it
|
|
||||||
name = "optimus";
|
|
||||||
ip_pub = "193.1.99.112";
|
|
||||||
ip_priv = "172.20.20.7";
|
|
||||||
hostname = "${name}.skynet.ie";
|
|
||||||
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
../applications/games.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
deployment = {
|
|
||||||
targetHost = hostname;
|
|
||||||
targetPort = 22;
|
|
||||||
targetUser = "root";
|
|
||||||
|
|
||||||
tags = [ "active" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
skynet_dns.records = [
|
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
|
||||||
];
|
|
||||||
|
|
||||||
services.skynet_backup = {
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.skynet_games = {
|
|
||||||
enable = true;
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -7,29 +7,27 @@
|
||||||
From: 2023
|
From: 2023
|
||||||
Role: Wireguard (VPN) Server
|
Role: Wireguard (VPN) Server
|
||||||
Notes: Thius vpn is for admin use only, to give access to all the servers via ssh
|
Notes: Thius vpn is for admin use only, to give access to all the servers via ssh
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "ash";
|
name = "ash";
|
||||||
ip_pub = "193.1.99.75";
|
ip_pub = "193.1.99.75";
|
||||||
ip_priv = "172.20.20.5";
|
ip_priv = "172.20.20.5";
|
||||||
# hostname = "${name}.skynet.ie";
|
# hostname = "${name}.skynet.ie";
|
||||||
hostname = ip_pub;
|
hostname = ip_pub;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
# applications for this particular server
|
|
||||||
../applications/firewall.nix
|
|
||||||
../applications/dns.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = hostname;
|
targetHost = hostname;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
# these two are to be able to add the rules for firewall and dns
|
# these two are to be able to add the rules for firewall and dns
|
||||||
|
@ -38,7 +36,7 @@ in {
|
||||||
"ip daddr ${ip_pub} udp dport 51820 counter packets 0 bytes 0 accept"
|
"ip daddr ${ip_pub} udp dport 51820 counter packets 0 bytes 0 accept"
|
||||||
];
|
];
|
||||||
|
|
||||||
skynet_dns.records = {
|
services.skynet.dns.records = {
|
||||||
external = [
|
external = [
|
||||||
"${name} A ${ip_pub}"
|
"${name} A ${ip_pub}"
|
||||||
];
|
];
|
||||||
|
@ -48,7 +46,6 @@ in {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
age.secrets.wireguard.file = ../secrets/wireguard.age;
|
age.secrets.wireguard.file = ../secrets/wireguard.age;
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
|
@ -74,12 +71,12 @@ in {
|
||||||
privateKeyFile = "/run/agenix/wireguard";
|
privateKeyFile = "/run/agenix/wireguard";
|
||||||
|
|
||||||
peers = [
|
peers = [
|
||||||
{ # silver - Brendan
|
{
|
||||||
|
# silver - Brendan
|
||||||
publicKey = "46jMR/DzJ4rQCR8MBqLMwcyr2tsSII/xeCjihb6EQgQ=";
|
publicKey = "46jMR/DzJ4rQCR8MBqLMwcyr2tsSII/xeCjihb6EQgQ=";
|
||||||
allowedIPs = ["172.20.21.2/32"];
|
allowedIPs = ["172.20.21.2/32"];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,5 +84,4 @@ in {
|
||||||
# needed to generate keys
|
# needed to generate keys
|
||||||
pkgs.wireguard-tools
|
pkgs.wireguard-tools
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
45
machines/retired/optimus.nix
Normal file
45
machines/retired/optimus.nix
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Name: https://en.wikipedia.org/wiki/Optimus_Prime
|
||||||
|
Why: Created to sell toys so this vm is for games
|
||||||
|
Type: VM
|
||||||
|
Hardware: -
|
||||||
|
From: 2023
|
||||||
|
Role: Game host
|
||||||
|
Notes:
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
nodes,
|
||||||
|
arion,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
# name of the server, sets teh hostname and record for it
|
||||||
|
name = "optimus";
|
||||||
|
ip_pub = "193.1.99.112";
|
||||||
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
../applications/games.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
deployment = {
|
||||||
|
targetHost = hostname;
|
||||||
|
targetPort = 22;
|
||||||
|
targetUser = null;
|
||||||
|
|
||||||
|
tags = ["active"];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.skynet = {
|
||||||
|
host = host;
|
||||||
|
backup.enable = true;
|
||||||
|
games.enable = true;
|
||||||
|
};
|
||||||
|
}
|
|
@ -6,70 +6,41 @@
|
||||||
Hardware: -
|
Hardware: -
|
||||||
From: 2023
|
From: 2023
|
||||||
Role: Webserver and member linux box
|
Role: Webserver and member linux box
|
||||||
Notes:
|
Notes: Does not host offical sites
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, inputs, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
# name of the server, sets teh hostname and record for it
|
nodes,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
name = "skynet";
|
name = "skynet";
|
||||||
# DMZ that ITD provided
|
# DMZ that ITD provided
|
||||||
ip_pub = "193.1.96.165";
|
ip_pub = "193.1.96.165";
|
||||||
ip_priv = "193.1.99.79";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
hostname_int = "${name}.int.skynet.ie";
|
|
||||||
|
|
||||||
in {
|
|
||||||
imports = [
|
|
||||||
../applications/skynet.ie.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
deployment = {
|
|
||||||
targetHost = ip_priv;
|
|
||||||
targetPort = 22;
|
|
||||||
targetUser = "root";
|
|
||||||
|
|
||||||
tags = [ "active" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# it has two network devices so two
|
|
||||||
skynet_dns.records = [
|
|
||||||
#{record=name; r_type="A"; value=ip_pub; server=true;}
|
|
||||||
{record=name; r_type="A"; value=ip_priv; server=true;}
|
|
||||||
{record="${name}.int"; r_type="A"; value=ip_priv; server=true;}
|
|
||||||
|
|
||||||
{record=ip_priv; r_type="PTR"; value=hostname_int;}
|
|
||||||
];
|
|
||||||
|
|
||||||
services.skynet_backup = {
|
|
||||||
host = {
|
host = {
|
||||||
ip = ip_pub;
|
ip = ip_pub;
|
||||||
name = name;
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
};
|
};
|
||||||
};
|
in {
|
||||||
|
imports = [
|
||||||
# allow more than admins access
|
../applications/skynet_users.nix
|
||||||
services.skynet_ldap_client = {
|
|
||||||
groups = [
|
|
||||||
"skynet-admins-linux"
|
|
||||||
"skynet-users-linux"
|
|
||||||
];
|
];
|
||||||
};
|
|
||||||
|
|
||||||
proxmoxLXC.manageNetwork = true;
|
deployment = {
|
||||||
networking.hostName = name;
|
targetHost = hostname;
|
||||||
networking.interfaces.eth0.ipv4.addresses = [
|
targetPort = 22;
|
||||||
{
|
targetUser = null;
|
||||||
address = ip_priv;
|
|
||||||
prefixLength = 26;
|
# this one is manually deployed
|
||||||
}
|
tags = ["active-ext"];
|
||||||
];
|
};
|
||||||
|
|
||||||
services.skynet = {
|
services.skynet = {
|
||||||
host = {
|
host = host;
|
||||||
ip = ip_priv;
|
backup.enable = true;
|
||||||
name = name;
|
website_users.enable = true;
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -7,65 +7,59 @@
|
||||||
From: 2011 (?)
|
From: 2011 (?)
|
||||||
Role: DNS Server
|
Role: DNS Server
|
||||||
Notes: Using the server that used to be called Earth
|
Notes: Using the server that used to be called Earth
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "vendetta";
|
name = "vendetta";
|
||||||
ip_pub = "193.1.99.120";
|
ip_pub = "193.1.99.120";
|
||||||
ip_priv = "172.20.20.3";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./hardware/_base.nix
|
|
||||||
./hardware/RM002.nix
|
./hardware/RM002.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
networking.hostName = name;
|
||||||
|
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = ip_pub;
|
targetHost = ip_pub;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = [ "active" "dns" ];
|
tags = ["active-dns" "dns"];
|
||||||
};
|
};
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
# needs to have an address statically assigned
|
# needs to have an address statically assigned
|
||||||
interfaces = {
|
|
||||||
eno1 = {
|
defaultGateway.interface = lib.mkForce "eno1";
|
||||||
ipv4.addresses = [
|
interfaces.eno1.ipv4.addresses = [
|
||||||
{
|
{
|
||||||
address = "193.1.99.120";
|
address = "193.1.99.120";
|
||||||
prefixLength = 26;
|
prefixLength = 26;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.skynet_backup = {
|
services.skynet = {
|
||||||
host = {
|
host = host;
|
||||||
ip = ip_pub;
|
backup.enable = true;
|
||||||
name = name;
|
dns = {
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
skynet_dns = {
|
|
||||||
server = {
|
server = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# primary dns server (ns1)
|
# primary dns server (ns1)
|
||||||
primary = true;
|
primary = true;
|
||||||
ip = ip_pub;
|
ip = ip_pub;
|
||||||
};
|
};
|
||||||
|
|
||||||
records = [
|
|
||||||
# vendetta IN A 193.1.99.120
|
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
|
||||||
# 120 IN PTR vendetta.skynet.ie.
|
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,50 +7,43 @@
|
||||||
From: 2023
|
From: 2023
|
||||||
Role: DNS Server
|
Role: DNS Server
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
name = "vigil";
|
name = "vigil";
|
||||||
ip_pub = "193.1.99.109";
|
ip_pub = "193.1.99.109";
|
||||||
ip_priv = "172.20.20.4";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = ip_pub;
|
targetHost = ip_pub;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = [ "active" "dns" ];
|
tags = ["active-dns" "dns"];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.skynet_backup = {
|
services.skynet = {
|
||||||
host = {
|
host = host;
|
||||||
ip = ip_pub;
|
backup.enable = true;
|
||||||
name = name;
|
dns = {
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
skynet_dns = {
|
|
||||||
server = {
|
server = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# secondary dns server (ns2)
|
# secondary dns server (ns2)
|
||||||
primary = false;
|
primary = false;
|
||||||
ip = ip_pub;
|
ip = ip_pub;
|
||||||
};
|
};
|
||||||
|
|
||||||
# this server will have to have dns records
|
|
||||||
records = [
|
|
||||||
# vigil IN A 193.1.99.109
|
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
|
||||||
# 109 IN PTR vigil.skynet.ie.
|
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,46 +7,38 @@
|
||||||
From: 2023
|
From: 2023
|
||||||
Role: Gitlab Runner
|
Role: Gitlab Runner
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
{ pkgs, lib, nodes, ... }:
|
pkgs,
|
||||||
let
|
lib,
|
||||||
|
nodes,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
# name of the server, sets teh hostname and record for it
|
# name of the server, sets teh hostname and record for it
|
||||||
name = "wheatly";
|
name = "wheatly";
|
||||||
ip_pub = "193.1.99.78";
|
ip_pub = "193.1.99.78";
|
||||||
ip_priv = "172.20.20.7";
|
|
||||||
hostname = "${name}.skynet.ie";
|
hostname = "${name}.skynet.ie";
|
||||||
|
host = {
|
||||||
|
ip = ip_pub;
|
||||||
|
name = name;
|
||||||
|
hostname = hostname;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../applications/gitlab_runner.nix
|
../applications/git/forgejo_runner.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
deployment = {
|
deployment = {
|
||||||
targetHost = hostname;
|
targetHost = hostname;
|
||||||
targetPort = 22;
|
targetPort = 22;
|
||||||
targetUser = "root";
|
targetUser = null;
|
||||||
|
|
||||||
tags = ["active-gitlab"];
|
tags = ["active-gitlab"];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.skynet = {
|
||||||
skynet_dns.records = [
|
host = host;
|
||||||
{record=name; r_type="A"; value=ip_pub; server=true;}
|
backup.enable = true;
|
||||||
{record=ip_pub; r_type="PTR"; value=hostname;}
|
forgejo_runner.enable = true;
|
||||||
];
|
|
||||||
|
|
||||||
services.skynet_backup = {
|
|
||||||
host = {
|
|
||||||
ip = ip_pub;
|
|
||||||
name = name;
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
services.skynet_gitlab_runner = {
|
|
||||||
enable = true;
|
|
||||||
runner.name = "runner01";
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
|
@ -1,13 +1,19 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 V1pwNA 5icNZy9IB42T2Xnph6z0VGznaxiB0MHtC4yBUEOM534
|
-> ssh-ed25519 V1pwNA d/AgQuQidsB5+UMBxg3/YIA/4EVMF9+BeZrEMzgU52Y
|
||||||
avacsmljAR4DA0pdHq42o2YunyLweTjaX91QiuO7/0U
|
gPmTDd4oeIwwJ5ZdnWp/s6cEupsYPY08TBvmL5fe3NE
|
||||||
-> ssh-ed25519 rIwlvw r7IUmFs46NLNgITxj2hNMv2neldFI/OXlzpQOOZ/XD0
|
-> ssh-ed25519 4PzZog iR02KGER5WMrs4djPPpMRc3v5qN5FpcpjTkB+O4GyV0
|
||||||
MkBLRr4uXWXW/xTo0EtkX2y5nbSwEfc6ChkaiIu8VoM
|
ibvzSePq1ruF03QBsHRr40VCZ6ZcnWjvcJzybB5vt4g
|
||||||
-> ssh-ed25519 q8eJgg jetnUDWCkX8P4fcvb3hA12TJolDKO2ZqcdmxUmx5myA
|
-> ssh-ed25519 dA0vRg pVsTTA9yknN8gl6K/CkY/HnUc8eW1F/pSqXq/Upq3SE
|
||||||
Ru2q2Y8+iIe7imaXeb9MTZyOoCv4P45SNgxGGxQlVRI
|
3ymQH0jBAk9ktwBUvth8G9ZdDzr9Ozqi9YNVB8fyvGE
|
||||||
-> ssh-ed25519 mKj+iw wwsRXk+Wn3u+y+b/b3Fg6hSmJiV38tmYgRJqsStMnU0
|
-> ssh-ed25519 5Nd93w fSPTiW3c4va0F5IYoFF+QoN4u1tFGRBrMO9lypICiXo
|
||||||
avS7XgN/GYVi+2pjNTG+CZOLcKo+cPpCEPCVZV3DHF4
|
8MgZPPUXJGGOdmGknXhaV0xgJl76dg9B1e5r0Ud/iW8
|
||||||
-> '$-grease y'
|
-> ssh-ed25519 q8eJgg UFiK3B6YB3YR8fVOWOPLlpGuo5pWpK6b7zteIngC2Cc
|
||||||
VGZ3E4+qHDVztqvY45Bo65M
|
K+e9B1V7AdimOMdy7YCJ7tJnHsHoQChAmWmOJDIdwMU
|
||||||
--- u6b8TLW9fI2nKMvP1HCIRk8vIHWLrY3U1K8wse/s72s
|
-> ssh-ed25519 KVr8rw FeMibaL1ITDNByDL26VRXVz6d2FP13SpKoN87RgTYDo
|
||||||
üvÌTK&|lÿ4.àó~Ìo C§&ñ£0̤Úì9ŹÀúIƈúûïöwÚ<77>^–„ sªÚ÷„H=<3D>3Ã|E-C˜óøÌo×Ó×þCÂõ8Mç¸pø 6Ùk LžoM
|
e0LPmpAe9wRRvgKTYq96Qk+WiUhfixiatuWPPi72Nlk
|
||||||
|
-> ssh-ed25519 fia1eQ i5+7lIZDOm48wywy6CRMOLVhHWnmV71WM0QLSbyhqV4
|
||||||
|
S5nAEPHEmAn3AGxN04FpVKwVHrWtZS2s/dPeVv4ryCE
|
||||||
|
-> ssh-ed25519 3pl/Kw Mhc4y4szabQQaeBWtZ7mVdDnZYRwtninrBhcyHoUm24
|
||||||
|
lQpLgpgU0ak9WDQIJxd5Yz/DUe14szLvsUGxAil+5dk
|
||||||
|
--- eUzkrzEEXETs3FXa2YqSW4yqQiRLFC8Umr1D+Bq334c
|
||||||
|
ڙءm“ }ïÁý9Ž.›û‚”I^éY%Kcö¨SšÒÈ®#ö¤hVó„Á{þ7Z'i¸<¡Z#–s<E28093>íÆ<C3AD>šs. Þ<>„zÒIW=†WÀuþ7ϱÚàX
|
BIN
secrets/bitwarden/details.age
Normal file
BIN
secrets/bitwarden/details.age
Normal file
Binary file not shown.
19
secrets/bitwarden/id.age
Normal file
19
secrets/bitwarden/id.age
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 V1pwNA xqavLiNuEoc7Gn7MchvoSEC2RrsFDrf9MEGFYVf5vEs
|
||||||
|
ZwOkERtRi8yxlZ6sUl+mzJ+YFw/h82vV0WzhRjQOTo0
|
||||||
|
-> ssh-ed25519 4PzZog eiC4yLeOytE1jTUaQDOxtVHsM2jJAvGLrI75XJXRCSA
|
||||||
|
HJg+GqSKlXld1uB2WPTM28XEygsm3+4iObC7SCMWl8c
|
||||||
|
-> ssh-ed25519 dA0vRg rStUstoZRf0i7Ot/0Gn6zd1cQMQjDlLQ8ScEIM3XMXE
|
||||||
|
PR2UGWuO5VOBVee3bndRxipU/m2ZRXMo0HQkX8pvTyk
|
||||||
|
-> ssh-ed25519 5Nd93w hn5Oo+ZoIG+UwAb/DUUJmkDcey35fG5WDBgbe494T2s
|
||||||
|
TxUgeQb8UdxlowGV1/j2Tr7DTNqc6d56NGaFGZfeidQ
|
||||||
|
-> ssh-ed25519 q8eJgg vcWProg0hXGuIRVWXpFSzyS4Ei4YHSdq17A08avwCmI
|
||||||
|
4iKGWyyGfCKEliEa/9r8y+D5LsyLglFvcUeXyzO+FCg
|
||||||
|
-> ssh-ed25519 KVr8rw 2kNscJDgyfKH6WrfSKWnX5dgRM0Kk7FztGhoJ89VUWw
|
||||||
|
/biNgciz7/fDOyY6GfwEI57ESdUyRwmKaI4OG5pJs20
|
||||||
|
-> ssh-ed25519 fia1eQ lv06SnwwoBlmG4AVAeNpeIFgISkt6FktNuRq+P0eJgs
|
||||||
|
VX8O0FYWrEyBVR13t8AkvIq1VpwFdkMX+wBUQHBzXPI
|
||||||
|
-> ssh-ed25519 IzAMqA b0DnkDgWeERguN/u9wgiBB1sbxHaMXmMZdPOJ14/UDg
|
||||||
|
tmKw26Fs6iKbVq7BBK60UoQSjykp4BzLW59/ZbbD0hw
|
||||||
|
--- rR+hloCeC8YmoV34TBL7hLk/4CSfmYKwtAbmtUjHvKE
|
||||||
|
<EFBFBD>7ü¶RHSIΔC#‡Ä/ù:öH•ôImId÷ëójkõlàa˜Ñlõb\ƒL¶²¬6Ø¥†/ôPÜ¢+cº÷’U‰MÅYt©
|
19
secrets/bitwarden/secret.age
Normal file
19
secrets/bitwarden/secret.age
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 V1pwNA LbYb1XP9bLe1lcsAfGwPkK2/r2+TnkkEgfS9fi1YKRo
|
||||||
|
Z20C/zQluu+Qanf4d9GSj4pLirCyqJpa60H9hodMt5k
|
||||||
|
-> ssh-ed25519 4PzZog IFlhg/gbQpiMugcQZUHwfAnSvhxCwW67XmfSNmYOSQE
|
||||||
|
nOp4xPFMvIhUH9OUVz8B3L8GI+Um2egjHV0FgmdNwwM
|
||||||
|
-> ssh-ed25519 dA0vRg OAmV1KiprjoIgOPHCYcme2uLiU1xEdohTWA5CiN0yG8
|
||||||
|
4/LHk5LCGrpMISvpjfo7QuhnRrE3ycFGwGTQ1i6VaZE
|
||||||
|
-> ssh-ed25519 5Nd93w jv27aiNze8Nxp2ohY7NIRtZv5lBxAdKYGWdqWD12zU0
|
||||||
|
E5Rk0r8To4B39UsaZavEkAZlIPiaXswsShMgsyNPMoY
|
||||||
|
-> ssh-ed25519 q8eJgg /o798N6b1KlQfMM9gQf48TF9V7nXORxW4SOpcpYCuhI
|
||||||
|
RVYXWwZLFL6ZUjGbmXBzEj0+Pe2wpZFPIj5yH9kRIwY
|
||||||
|
-> ssh-ed25519 KVr8rw +N2w/8vvD7/uG3TMYb+9vml/vZhLkoS+03KEDlQWNhs
|
||||||
|
Hne+3S6vVc5Sx7QJ+OCrPCt4s5usZ7B7WwusnFQLmSo
|
||||||
|
-> ssh-ed25519 fia1eQ PJYYKfL1GolRt90KC52dvUyZ/HjWRJm9vMTjBvrCOkQ
|
||||||
|
Xc7SpT5TZLTOORLO3uE8tPXKx7thUwaJi3ixngLRljM
|
||||||
|
-> ssh-ed25519 IzAMqA AtoNahZ3dTQasdfP3wf7U1RJyx//Kt82e1TMSIkW6QA
|
||||||
|
neLAeCvnsl4RDq2H1slZJ+5i3JErqy4aRGoscpRUi/0
|
||||||
|
--- W8B6kla08fEkl4Kpp+0eAHj7B1j3WYCDcuwJvAIEW58
|
||||||
|
)8ýG(ž¶ ìò<C3AC><C3B2>žÛær_št¤Ö©zµ¥|>¢od…ð×ù6µø*0j»…r‚´ñTü«\*v^#‚
|
26
secrets/discord/ldap.age
Normal file
26
secrets/discord/ldap.age
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 V1pwNA 6NKUbOSUbwVjzW/ZUpl8qEiUTTegFlji4+tVJyqY3SE
|
||||||
|
fRQvaKnLMkVBboTEriQpWlGY9VBAP3ppsEbAB2QTScs
|
||||||
|
-> ssh-ed25519 4PzZog mp/+b5LpB+DvRduqAZiKWqkZq6+tlyQgVTZz7Oge2Us
|
||||||
|
OycqmZyDr3levWSfRFxypJOkITLDix0Q15Todya6BNc
|
||||||
|
-> ssh-ed25519 dA0vRg yp/4LvS9DbdatHFWFsP5qhH8CP8Bs0IjVSenUtG4+Xs
|
||||||
|
hHiJEtl1ffYXltsJzuEMLGUl2i/i3pFzv4bjbx/cbOI
|
||||||
|
-> ssh-ed25519 5Nd93w BTngmy4NGLGKhC8lPos63QEVBKoQT82KswQ22EypcQQ
|
||||||
|
OCnJMkOwwXQVbtCitUizXM4nynC6a1tiPSkm7MxulWA
|
||||||
|
-> ssh-ed25519 q8eJgg NaEjVcDBVICRgXuJchEdE4vg3qmkNmJAbDDxLq1fX0M
|
||||||
|
YFwUmEPwJIik5YJ2SV5IAmqGlY+h24voJJlrBaoCBwA
|
||||||
|
-> ssh-ed25519 KVr8rw ZnyVITZFkuozEs/rbTdxXDQNS3Nggo+JkBL1Icht2SM
|
||||||
|
B4jVVts5lK1kIlOWMl0eiN7TpsTeJZWIu7NqildxeGE
|
||||||
|
-> ssh-ed25519 fia1eQ kvzARRScl/eypC2a5cY66sXcH+TZqz4sYg4W/k9iJxQ
|
||||||
|
Ga+4TVvXiQ6i5/+fgUQ3E5tJiLqdBsEsXjenXEpRV/A
|
||||||
|
-> ssh-ed25519 IzAMqA 5sizvlhLhAhAR1bViHJtRJ8fAIO56TAuLVSOwE177QE
|
||||||
|
b9oJ8BC2xiBjvc3D0H0EF7bSNDlpvIidyBCTf04ndJI
|
||||||
|
-> ssh-ed25519 uZzB3g g9y66zNmQbqP6Rbhg2t06W3YOgy8DkRvJZbWVegT71s
|
||||||
|
2dH7E76tDMrWQJbLPefyORP66iaPHQnSjwu8NCdSyJo
|
||||||
|
-> ssh-ed25519 Hb0ipQ azOzBLXfshInlFVpV0PzIBidL/VzA/+kKRXFFVD6ZF4
|
||||||
|
iXBF/Wcv4KWo5qUXUlyimuo0l6aClKxOCtkm3MxAIBc
|
||||||
|
-> ssh-ed25519 IzAMqA EWitYyV8RsPIB6HEFE2OI/C1zcC6WfBEeDI62rGVmkk
|
||||||
|
Bk9tdSqIjLjat21J2LM8RXAt9GwdQxYdfPzqDtCjunE
|
||||||
|
--- waY7j+HMEOdqEZs/TcLEhUY9gJs6ZSc51VNfuCmCxJ4
|
||||||
|
Ý;dÙ9A‡vÔé±nq<“ê;TèáƒB؇$ÐGÌvï¯h
|
||||||
|
»\^Žé§lÖ¯`š¼ÄÎ?l¸<0C>au~üЧ×yâ[ךju²üvÂ;]!œ6Ëè±ãXIs4ÇŒ!Ù@ß϶û¬‘|›úïª">eÈÿ[VVŠž´,ÿ5˜ý8N§¹Œh<04><>[ƒ×´ZD,zý&âñíó¡”õIØ>ŠØù¡<C3B9>|ÎézÉm
|
BIN
secrets/discord/token.age
Normal file
BIN
secrets/discord/token.age
Normal file
Binary file not shown.
|
@ -1,27 +1,49 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 V1pwNA 8GOIUD9Kw0Rgk9f0y4X/DAU1CJkIElC+ncXKTZqiI0M
|
-> ssh-ed25519 V1pwNA 5xvtgxFvEOX/bVAOdBBF2Fyb0euGt95YjhOcfpGgHk4
|
||||||
fUaEgN+etR6cCO9RZYlS39sIL+3HoN4vbrNx3frV2MQ
|
6oN4Xba0W5g/d3EX2aC4N6UFVf/oHGgdTxBcMbjIdHo
|
||||||
-> ssh-ed25519 rIwlvw oRJq+SnMgO14Vn9mas+cA7PxRsCTCH7nN1R1UnteXGQ
|
-> ssh-ed25519 4PzZog SjAcOftaZBEAAZ/P+Z9OTira4/QLSMRefC+JkQcf0G8
|
||||||
id5gxG2xpSMFRtv0fuW/4gqYzNVWMnUnZQrHywO0cSo
|
zG0R3/r+PBjWj7WBABmHPXpqx18uLyuFMJKB2az9i2E
|
||||||
-> ssh-ed25519 q8eJgg 3YWRSNOeGqbxfZ5j41DHCjnnH1o7KLZpOZmPgiDTmBE
|
-> ssh-ed25519 dA0vRg k8fekPA7w/QFMVnDfCrpOlfv531/nw9tO7B0d+mWHiA
|
||||||
HFL0tvUPf7ZPgH2e4KOXjQIhDsfU5h1Y/SjCGvnSvU8
|
jp+DndebWEdk9+wt/nvS0LfRsFf8T7+dMffWmx3tPw8
|
||||||
-> ssh-ed25519 XSrA6w y8Gqm8ATfOiWaafVP4a0Ah+KwXZFa767gw79UpFvyFo
|
-> ssh-ed25519 5Nd93w dYe/tZ5qHoacI1IBa7yvDL/grZU7Lc40gU8boQY8Wj0
|
||||||
fGmxf6g/VN/A+fzy+eSkk+H+0nBRPwot1Vev5AU+Otc
|
eBs8fYre18RGW8+RH4J4AleG3kNpCZ0agAfcojSCy2Y
|
||||||
-> ssh-ed25519 DVzSig 9oSFqSbP8NIve7/Li5MO0qoXY/j0mz1LoIi22nzNTmU
|
-> ssh-ed25519 q8eJgg 9UZdBq2oZ29U/kzeNOGn+q8RbkLbJwM0eSJHqSLV6Ek
|
||||||
btg877VtFr/q6rq7KXVRoCIrZig4qYR8CaUCBKEhfWQ
|
vqa610t5XxHiKBSf7veOc09ZFYW7EF1KpIbCpdCsegw
|
||||||
-> ssh-ed25519 SqDBmA PdB0Fa4Lv4tQn2Cw9ClOHRrCNR3igGsSVdMnunDmGBs
|
-> ssh-ed25519 KVr8rw 1CkykLAC3c615TDRlOeI4GHmqu0VT2kclWkr+DT9dSM
|
||||||
7dW8yReE/Ti/9x6OE9xfP5jkm2QLV66lm/kG91AqE0k
|
0MyPNEmkHICQZxpKt0jBZpce13c+jn4WC7IJL4uWZHo
|
||||||
-> ssh-ed25519 IzAMqA yLOTmqlrQ5VB6gCIjfvkCbuejVDRWCGPsJklZExfdnM
|
-> ssh-ed25519 fia1eQ OtFYStmc1y+yqYNaNgHxEheIIVykYAa/uR0dKS4xX3Y
|
||||||
5E4F45VkETQqQWT9cJx4Owl9QxqbfliU4JtV6gj9C3s
|
c2HYDyrD6Db3FNLP8tebLngtS2S8LHsmHovbofsUk3U
|
||||||
-> ssh-ed25519 uZzB3g F0KPMYgCSJMgbh4DBewNHsfT8HtpF/eaces8AV/quF0
|
-> ssh-ed25519 /Gb5gQ rAc4CqbqdkIAFystL0rLqGNH56GrKxOBamqhiIFAY3c
|
||||||
32i2UGD2jRrba5oz9jO2P8uSstTi+FrdTreJh0wyv8c
|
RR+NsZe0HQdQv6SgeIqy9IcIChXdvrsspNDBngW6Byw
|
||||||
-> ssh-ed25519 Hb0ipQ MhOrRdOrE3HF1wlvea6jgcF2H+EvFy0VpwP2UcfA32k
|
-> ssh-ed25519 NtlN/A 93citgkp9Aj1LDK5UdzJqYVVYaWgt/Cc6yMJka+ccyY
|
||||||
JpOvrHJaqP75uzEGuhbuAYrhaQ3mtoZmz1wf5KpfI0Q
|
KTcyd/SygOLp4mPI1zGDTKCNT7LfVUw12Bw/qnTnMpE
|
||||||
-> ssh-ed25519 uZzB3g 2Hv1za/ZTu/pL4F6ER0Q7nOEjfbbtTEyUM5wm/L0lCk
|
-> ssh-ed25519 v2Y09A +fWNE2zU+lz5KGu2Ed2MHb9UXzJPUAUuBWilF/AS1Qo
|
||||||
Fl7UfjUzkPEngUIq700EENUHdsU1cZBwGQVuaBOzl6M
|
UVJWnAjRcD7X6iA/heoWdZTcsUS+1VMG5leIHxWZGNA
|
||||||
-> qY.@U-grease J
|
-> ssh-ed25519 XSrA6w fft3i85PNprS9QqQo2yKr3lx3qHuSVFeVYuT5Gtfyng
|
||||||
zK/SyCeVwFefcB2JLa2au8egE7eHU8oEKKY54WUYfx3oSQqYdZdMTxMjY+97+lYj
|
lNOo2jQXvaMElQawI9x8vnQN5bnnNefEyYXD3YqwOwM
|
||||||
yjGCjir8pM4IQWDC
|
-> ssh-ed25519 DVzSig a5q+imjqWqTzyM3aU+UvvGv3wH3RLTPl+kva+qVSSFs
|
||||||
--- xxKgKXQD88mrgIvmzV50SZw3xDKwEvRkQdaW14FdWOM
|
Pobzi/5ZVyfGhVK4cMqvMqaAol9X4+P3hEaUeHdiacY
|
||||||
(V”xí’<C3AD>§†þ¿pj<08>Ý͆Fj0¢‚\'¹,A›æíößaë(ùâON€_<16>†e5Ì¿Tq<>§\JªÙGTÀò¦³ãâN‚á>»dDÝ¢-Ì®t0Öü$—Xò³×ê¢ywØÕnü¶S„•¬¹Y§ù¬:Ôƒ‚>‰î<`·¨‘zÎ(¶äW#†ùo÷a»YúM(oÅ[D<¥Î‰¿\®M¬|Vœp¥‹·Â'›zÒçXê÷
|
-> ssh-ed25519 uZzB3g B1D2S87+yPr66EikAqLw7s5pazfQeQUxAj4FFnk0nAE
|
||||||
ý54f³þ©·Òò=‚Í¢–D]M.L$í“<cD@
|
3lEw0t99aSGqkZdi+ILl3+s+JWRKpY4BHLXdrHfFxng
|
||||||
|
-> ssh-ed25519 CqOTGQ urZpNzMYvDnGR1UgjgrRYp06gKWcTEWUDjyb4fdDTD0
|
||||||
|
7jeFeoMBitwGFQLSynYVyIYsEhHe7A8mdl65goiX5c8
|
||||||
|
-> ssh-ed25519 IzAMqA QmtcH5afcef4NMRX4AMrUHW1tCPGOlJ+gIhhDFkUCSY
|
||||||
|
I4Yg8vgoYGcsV43qq04+nrhzMJ20eaQjOD4EJM0z2xw
|
||||||
|
-> ssh-ed25519 Hb0ipQ CO7nQSSKrmkQ/C6DuJxesIMJmm99eQytLzJ+3/Q38AI
|
||||||
|
/kBnqeivoQLMaAA7nX0t4/UAvcOIchEu9bJWxIuUOV0
|
||||||
|
-> ssh-ed25519 3pl/Kw qUD++i8FGbEAuqa+/v6f664tlVTwHGYF3AmTo0cuZyA
|
||||||
|
vjImiKQm0SHiuO7jZTKRg/3MKzDExfE+p9ZT2nHZr4M
|
||||||
|
-> ssh-ed25519 SqDBmA BGwTqAeEptBFRbwwVkHZWX+OKQpALqrPvA2+Cl356D4
|
||||||
|
Gg69WAtr+AAfYT1G+WcTSIlCbNqS5DyxsZw81DaBSkk
|
||||||
|
-> ssh-ed25519 UE6fcQ 4JZzLWThfgJQSNDDtDp8ayM7N9o5tQ6PVwKMj28inC8
|
||||||
|
RyEWRmMbuXezYZntsTdVIbjy/YEbrflqMpirdg08UVQ
|
||||||
|
-> ssh-ed25519 YFaxCg LTsikBkuBwOuc2qrnTAMVtRawZyBosZScefH8qWIqzQ
|
||||||
|
aLiVK7XFI8iDRTCGH2yJnUpydjTp7NF1Ygok6D2Fo44
|
||||||
|
-> ssh-ed25519 elCEeg TKQKeAvY3kn5IuvHoS0SWtX647nEn1txDftt7pPQEG8
|
||||||
|
OPAFqPGdSS3Ud+gFtMXG0shrXSmVrIBzvwc19Ac1NJQ
|
||||||
|
-> ssh-ed25519 8vZ9CQ NGLF9epPqcfbQWcbtMeYIcH0jAZMvO4P7UbKtl8lGRY
|
||||||
|
ZJ5afGOI32OYBpWs6pe15z2IB+5xgO04/OsKp6ixT5o
|
||||||
|
-> ssh-ed25519 rmrvjw tfgMxvtTE2vv2qQJtQk1J+YV2UC/2iZSs0nvbVzV1Hc
|
||||||
|
HW86DML/9MXoTs0WWn/zNi4Rh9SBhaHl2WC2bkiLbmw
|
||||||
|
--- Q4amxZgWmdHcf7aqav2TpKA8KX8B8ZHuBhzIcKwbFTs
|
||||||
|
E¾ã™r<0F><\Å?ë @î}ËkRÕ(ƒù;È^3P–ÐJäO“ãSÜ‹Ø â`¶¦ sb?9ø¢¯Âÿx$ñû/<2F>ø~4ÊFŸv_¨þp4{5 GZ²f"’<<3C>x×"q‹ºbj¯:cTuWå>BͶ'<27>ã)/¥×]«ôÁÈëöà•wžÉK%þo B*&Þ׫{\ZŒ•pë£KöŒƒ³Î¯k}ÏåíßÔ}P=Œ¸û·?<õ¬ºyB…‡sbŠ„<C5A0>ÿѪ%â$¢#"
|
Binary file not shown.
BIN
secrets/email/details.age
Normal file
BIN
secrets/email/details.age
Normal file
Binary file not shown.
BIN
secrets/forgejo/runners/ssh.age
Normal file
BIN
secrets/forgejo/runners/ssh.age
Normal file
Binary file not shown.
19
secrets/forgejo/runners/token.age
Normal file
19
secrets/forgejo/runners/token.age
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 V1pwNA 8acWnck16a9QK194orAzlQgQKINum/cyUzJqO6i0rkg
|
||||||
|
In2UpSbBR6QoTMTZR/GpZJN3x+5CK3hZcEvr5fORoOI
|
||||||
|
-> ssh-ed25519 4PzZog /YeuXUmWrWFohgOSEmUygaTax668bLZpYO2T7KXl8n8
|
||||||
|
mgnBBIsPycR6RMhLk4HQei5xQLzVHiBHaooOzZdb4YA
|
||||||
|
-> ssh-ed25519 dA0vRg DidrxIBYvAfPkwNzQXy2+f6inafUafoX8cfUChA7l2Q
|
||||||
|
/wfxyJAyrQ3Uycxwov+0b9pKKOxPP9mySRK5g4BzMnY
|
||||||
|
-> ssh-ed25519 5Nd93w i+oP7x/eHY/Roj4mdpOFHrBe5rxUL7/4617F4O3jPh8
|
||||||
|
yTVD0dR3ljoUSv1qyuKcOvr1fMRm9C8YAZKKjURtCPk
|
||||||
|
-> ssh-ed25519 q8eJgg Y0yxgrLm9/E8nYBg6Yvd0GPbY7PwCJCumQ9CtgWFxxo
|
||||||
|
9BfGPSP7pTTM8Dm9qXagKaw95hbqvvp7qsFkhQgQco4
|
||||||
|
-> ssh-ed25519 KVr8rw pXha2ebkoIFX9dMX3uRz+0rcbwcQ1mwPnLWp/wCzx10
|
||||||
|
BQQ77pXJl75c6myecmKlEpqHtWB/rSdG6Pwpbxzcfbk
|
||||||
|
-> ssh-ed25519 fia1eQ gCgas1CqGNZ7n09J7iXOvh2xeGgoszn36ABZwiskBBw
|
||||||
|
3a7WMN9aB6ZvwFyP98At9V9K99hD1vkvSJgnY16/JKY
|
||||||
|
-> ssh-ed25519 CqOTGQ DU1oon3RPo4MCdzigrM2+b3KnTzzTSG/WDSvtBaF1VE
|
||||||
|
zwKaQnXT004dMojYFXPz9UERL4ULe7mPZ+vwlZMxFvY
|
||||||
|
--- FWICxx8MWe7awI8P5t0XsbA4Ye0zbxCdMbapTs325HI
|
||||||
|
wûùÿŒ-”¥d!Ñ×=gŸ&ÜžH¬©ó?÷IçÛ’ÚᕪªêÏ<C3AA>Ò¢Ù„öLÒLË-<08>Ù¸ÏñU¿? )ûVýJæb®éÄÎC
|
|
@ -1,15 +1,19 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 V1pwNA TjC5DbimRqNNh0UQsk2YMgxoVZOQkWsNB10TmlPZLUM
|
-> ssh-ed25519 V1pwNA To9tGfYsutlmjqXZbFJ+TttdFAnbwY9odSMEOvItmgw
|
||||||
H2H0Jpztcbn15L1Ff1teeWgZaoeKszVWG2GJKkBFuWA
|
Q8cWN1VF4bVisWVMOEA6IXqhe2JzPl/9M9UUXWWV0Bc
|
||||||
-> ssh-ed25519 rIwlvw 9wk9lmhZBsiM5ifMGxlo+8YAKy325ru7u/MZA6gEzng
|
-> ssh-ed25519 4PzZog e3OTx6aEjhNCwyiysZkbwSC8ecVvVaVNfZV/3iNpZCE
|
||||||
cAZ0/OqScj9x6vt4gvsrtqi36iIbT+n+iTySssKh3Fg
|
o8jHkyg0lptJh2Iew9ZtVi3AUOSAtmDzBIz2nE4mj8k
|
||||||
-> ssh-ed25519 q8eJgg Jn7hc5D6m/P7qxdpfQ2hRKKQPchrwtKhV6crxW05RTs
|
-> ssh-ed25519 dA0vRg 7smMdyMEq1stuvSBUsBZXJoeap4Aru6AsljjFPPpfiM
|
||||||
jM16eEteWG2ezgVnBB5t5JrhwnsAKr4cz8srqiWKzR8
|
Ip5qA83bAGtYIeqv1w0yo5obRh+FWYJICgOU5+JoeYQ
|
||||||
-> ssh-ed25519 uZzB3g qC7Mr+9evdjoSka/x5criNYkuha4SuAp/yrCK6dcUWQ
|
-> ssh-ed25519 5Nd93w z16A2vTVGdxgKmgHoSySJ9K8cwrQglflrWDhBvZ7ME0
|
||||||
JPHRq5iV9aP2/tBPAuq8wI3eQN2JHH6jNZfK2Fckshk
|
ILd92pWzyVGnTOXwovlZ3EX7LsFX06hqedW7Ov2CYII
|
||||||
-> ):,9TlwC-grease d?Jj?5><
|
-> ssh-ed25519 q8eJgg Rf7U0SdZsP4NEgiDl8Z99tCoOkIwrrl5s0aYpXOG6yQ
|
||||||
I0u2aN62wlBng0jlPPGRwXz5zJbcxW7PLOwHkRkLuHcNNtimd5QpRcr984eBa2hD
|
tg+Y2WHuokaCVI4CCxuv9UW3GIa8CMuX0JJEWTTkwjU
|
||||||
HF7n
|
-> ssh-ed25519 KVr8rw YUN5VlTaxW7Niwtm9+FTGOILOklbEGL5EVw1BucGvXA
|
||||||
--- 09T0lHOZiky+5dFYWvhtP6iEHrhHaub8bymCKwzOJmY
|
zXYcis5ANsDGPeFoV1aRzTJiOQY2P1ZLHsJDkE9RFT4
|
||||||
`–„¯Äú÷>Äb_x…+{®1ÌìÙd%‚g5li ]yû½ÜŠ!$ºh6AGäïn ¨3¸SwNLRõ1Çòí¾L›ÐŠt
|
-> ssh-ed25519 fia1eQ TnSlOXGQ0BuVk25Yj9YpWWtYmonlM5h+uC9hUq3MM3E
|
||||||
q]A‹arÇÈŽD¦Ôד;MnæÔï§kþ41Wþ¤ÜØŸ•ÖŒc2YÇwoî>}Õ7PW(Ç)M„WʺMʯ€l³s< )øÒE{$jÄ]
|
8KrW7R5AgumY9wLVQyUmKlHD3zcUNIc+VU/X+vvY2LY
|
||||||
|
-> ssh-ed25519 uZzB3g 9ms4lu4KjQED/2AHQwr9oLd/6ws01IxuK7Z05CY6N3U
|
||||||
|
H/4AnWwt5fnZMvWjmXdoe/Os5ttJFYsMmjaHHqBdAxo
|
||||||
|
--- zI2RSKtND2Ep69vshrRkM1KOiReF/m5vdY4jIH7NSvA
|
||||||
|
ûì‹ënà›µ·ÞÒÜ
I¯ü$¨¬Í<C2AC>[ëP…Uó¯"ÕκZX„ñN<C3B1>nNg<19>† àú¶dP}¥GZ?<
/—!«÷c
„= üïhnZ`ß0‘²Âˆª1•nl‘±Üç»vÄÕfw<66>ÄjÓE@2<>1{ßù…ÐúEØØg“|èñQ\2Ðóe¹~ÇšÁ=Ó¬¾]fdRnó¶á¸
|
|
@ -1,14 +1,19 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 V1pwNA D1opPiqtt5raCD0PE2+On/Zgw+lavSHgYKbtJF+1xhc
|
-> ssh-ed25519 V1pwNA aYjPUkjZHoQm86XHx3VbGswLy6VdKNaaHe3f3CGa1ls
|
||||||
jIN+eavLzY3UB8qCBWOOr/r6IZX1MZ0RTlKfJTtSbcE
|
HMuWoZj4tY/nWj1nrgOxob1hJJD/mPD3kQnDgJJafeI
|
||||||
-> ssh-ed25519 rIwlvw z1zGn7NX5x9n75SM8oXOkvRwoAwyCXvzqZhWMXOGImE
|
-> ssh-ed25519 4PzZog GojGaXIg5RK7WjJSCZxJksXvsm9TZTlbHITuksMivBY
|
||||||
NWsqkm+nDv2dQDCnhfaWpKaBaF9nrQA5PKFl3FthtI8
|
4oAuKXtJ4ksvusFX3OM3VpdzfArrglxJTN8kCdhIjrU
|
||||||
-> ssh-ed25519 q8eJgg icVubOVJOSB3Wd7vnvEShwy7CsAMJchY/vuIMt0+p2E
|
-> ssh-ed25519 dA0vRg AzGx90D7iz93gHtSvV5oIbBkwgQEpVY7DTRQIZ16IiQ
|
||||||
OBz5wsfT3STCzzgmBgPdSQWr+xc91Dfo+ulleLK9l1k
|
GlMsor4NxuhHs1HJg62O3ZtPF6CHHFc46din6fm89G8
|
||||||
-> ssh-ed25519 uZzB3g gkyX8KZKJ6NL4OpsxKVKVK37ikAp9yAGxUjd0iLWzXQ
|
-> ssh-ed25519 5Nd93w oAyaZjUSGC9moA7pLR4+dzoKAggFuKUNMnRbn/fm2FQ
|
||||||
Nuk8JFO6wrjmDKiLnDaqBqW+AY7+DHYLSeV9gf5H5Aw
|
eHa/2iLWrqv/pPXjgfxtk68MgBX6EYW1YWfs1kXkazU
|
||||||
-> V8-grease #% :0txQ >
|
-> ssh-ed25519 q8eJgg xBdXNLjZqKi2o+cbCXGdOOSFnlfPgaxjQb+IK60MYHw
|
||||||
CP/AZC0nCj41Lly+GryRa2gmYFG8lsY30DtG7NgqY6AVj0bVHbwwOzx9oGA3xtu1
|
dxV3kTuaJ1ANFgRaYchwAa0kjGZHZ3POc/Wrw/per+w
|
||||||
+KsWhWAcvxc
|
-> ssh-ed25519 KVr8rw TR3AjhWy5K1ntzMx3mZZZWGYi7EvcWiFpTHyU/+pV3Q
|
||||||
--- LL4fxXc9VX5VeGj5epHEIkLmpab/t7x8YMyNgkYsFLQ
|
Y/xu0hrhaFZdO9YY8vINp3796HZ+LAL+QvBmIWmoS7A
|
||||||
Õbëïþ^NX¶q½•ÿƒ´8 Ï*:Ñ¥Ë QYb£Ï~ %¨ñc?ÓbÏ›[‹‘1EŒÐHå؈›ÈC‹ÞÈÿö}+œ0~‘avžPîrj#”KP’`Å<>Å÷‘®;
PÉ13±‚°íˆƒ¯´_mÒ=Lù#dµr†*vúp"ßÕ8Ûë’<<3C>]—thî,D•›¿¸
‡Ø[`á-ˆ
|
-> ssh-ed25519 fia1eQ zF6CArF4sVXzIRenfDq7WHz06WXFdo7vMgD15NI/sR4
|
||||||
|
m3sGJNMtAeY/yIq+D2nNncGNxX+KKXt0wCO1WMZmSTI
|
||||||
|
-> ssh-ed25519 uZzB3g pTocgT3gT7VHD7BWt+rGRIqUZYuh2G+1VeTJxyb7Xxs
|
||||||
|
q5UYfrUVbgaqJCxWKegc0q0PvPR6AZ7AlI5ff4ePfjM
|
||||||
|
--- 9KS9xFBleYVsxyktikZ+TX9++1wqXmDBZxU3g7vwwLU
|
||||||
|
<{r<>U/˜½Œ°ßR¦*°Jd)¥<>“»,#ø9ns!LsÈW#_ÙwÒ<77>¤äÃéÐMÃM‰Ãýð8sÏØ]ß•üƒ—8ð3ˆ¤7@·YNØçXlÿ¸æÜ庚¾Il^0p"aºMf«¬çG SÂdBŸ/»sêéÌ×,¡4!ãÌ<C3A3>rPÖ¢Ñ-Cáòky‚<H˜ƒÆ ÞZì'
|
Binary file not shown.
Binary file not shown.
20
secrets/gitlab/runners/runner02.age
Normal file
20
secrets/gitlab/runners/runner02.age
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 V1pwNA 28zceeGyLaA02L8gNeGtC4kaGMJYZ+ATchzxrI1idAQ
|
||||||
|
G8mCYZvVdVL0ZLdhpsvjreLd7RfOe2iGdEkoVHTddl8
|
||||||
|
-> ssh-ed25519 4PzZog 1Hb7J2Ya0UhC5A8zGDkI4WesR/LrQRrM7hNHtRvUYE4
|
||||||
|
QhviN1YQ63yi32rd3dRX+wYfCjYET+XOq4eRR5nzKmE
|
||||||
|
-> ssh-ed25519 dA0vRg +GHqKkHt/WqrwaZo17FDEtgAOd+pGS4FKWJ8Cbfa/xE
|
||||||
|
1PRGkDWtdFEYQB+0TziC7umhbRBt6PNNTI3YWNBj5Ew
|
||||||
|
-> ssh-ed25519 5Nd93w ebfKVKjzUnyRpNuV0M5vQ5GiU1r2/wQcEVJIyvoykz8
|
||||||
|
KxsegupR/9iIpSXrD1A6FCcSf5mEiVr7DQL2TUXhqaQ
|
||||||
|
-> ssh-ed25519 q8eJgg ul8MazD9isC+MPT1JEAnjL0dZ2r12WUyYwvgPi726j0
|
||||||
|
5Csc4hiPxLaIYK6v+zRZPPctqsLMfJ4U8lKQS082viM
|
||||||
|
-> ssh-ed25519 KVr8rw keye4xiStda7ZUTSAFBFL170jR0b8E3Fj2WpEy66qVM
|
||||||
|
Lxu15JXZWqommKNiqan2uXJj8hSnpBnbNka2rOtH5R8
|
||||||
|
-> ssh-ed25519 fia1eQ bfJsTYdcsdTNqkLd3KKIoH9WqsdrAx3OWlk6wpqm/Sc
|
||||||
|
yXIhT4OX4iaLKttkOP5njFML8ZNCloz8H0pjzF64qWE
|
||||||
|
-> ssh-ed25519 CqOTGQ jx8KLE8ejaRLnhV48jRN4muKClVCiPzFE6ibHzVCayc
|
||||||
|
E3bBriDPT6FLdR8XoDLxkch0Pgroyfk5unZcQu50y9A
|
||||||
|
--- fj3blhJZXxvg8Ecvk5/e4+0Mg6gwRrWlhQ1z0aXExjY
|
||||||
|
4<EFBFBD>æâðJâ˜=ìÏØ/c<>î<EFBFBD>ª’B¶QáȇˆÃúd9«¶<>úúÐ<C3BA>ò»I¼¶¶eëÊ£†IæÌ<õ7VaL~Ÿ¡®âœ”r
|
||||||
|
ŸQ~<7E>Úæ,²anñIl°#NHdª^ª)\Ú<'šwScÏqzÝ
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue