11 Commits

Author SHA1 Message Date
javalsai 64c1ea18e0 docs: document installation, secrets and setup steps
Check / Nix flake (push) Failing after 8s
Lint / Nix expressions (push) Failing after 10s
2026-05-03 19:13:21 -04:00
javalsai 1a866719ea nixos/services: make dns configuration easier 2026-05-03 19:13:21 -04:00
javalsai a0125116cd nixos/service: add dns (bind named server) 2026-05-03 19:12:19 -04:00
javalsai 2c6ea390f0 nixos/programs: add bind utils 2026-05-03 18:25:42 -04:00
javalsai 78df628955 nixos/services: add gitea server
Check / Nix flake (push) Failing after 9s
Lint / Nix expressions (push) Failing after 11s
2026-05-03 18:25:42 -04:00
javalsai fae8f3580a nixos/services: add nginx base configuration 2026-05-03 18:25:42 -04:00
javalsai b6e8297085 nixos/networking: add own fqdn to extraHosts 2026-05-03 13:38:03 -04:00
javalsai 8864af1ddf nixos/hosts: add tuxcord-vm host configuration 2026-05-03 13:37:25 -04:00
ErrorNoInternet 5942c97c1c nixos: separate openssh firewall port
Check / Nix flake (push) Failing after 8s
Lint / Nix expressions (push) Failing after 11s
2026-05-03 11:29:25 -04:00
javalsai 1c2f11debc lib/ssh: add more ssh keys
Check / Nix flake (push) Failing after 9s
Lint / Nix expressions (push) Failing after 10s
2026-05-02 19:13:36 -04:00
javalsai 4d55336eeb nixos/vm: enable qemu netork bridge 2026-05-02 18:01:29 -04:00
21 changed files with 426 additions and 52 deletions
Binary file not shown.
@@ -0,0 +1,34 @@
age-encryption.org/v1
-> ssh-ed25519 Wl2fDA ChDpKnwSPrXx13z22y4Q7+E6T+6Jr6pL6ZCxGidDhz4
VqzsCq9P5KSFRoKu+LR02VwR1qO8tbVyPnOf0dUw0HQ
-> ssh-ed25519 zNC8SA MQvBihnVCRdXg4PdrTZ3mhvzwyJeACVXfPNawPsRMl4
8HOZLbg9FuKD9k+0lS+3FksXMhLYXVOaa/7zzTgX+jc
-> ssh-ed25519 EiAAKw pxeU5N5J9ItEXP3Q2mOvWEjOe552atnfEMw1m/scbws
kswNWzaK5cKuyWeuRMxizL1tR63IaAbxkT6Yk2hplkc
-> ssh-rsa eFi+Zw
otzKOxpWdae4NnDceLHW6bYlZaXWYb2N2A6PLp6CJ/TRzT4F6aKO9oIG3dyGyVy6
JYNYDCrqgr0OrJdBB1pADbrhXxlaTlMW3K/5FkhPj4GOJQqYR/7148EHtv721eDi
mqJExC7lbEzO7ZcWT5ohPT8hP2Gv9xcKCRiAVrybo0HR4+tQrYDpr9PTrYy0lTOE
e9Ik3eT3+ub9FdJhgfKaGJVQS9cpuyghXN1AlO0EPTVwiOoYLZ/KSmrV+2hxaaui
KJ7VVjhWrbcFq0zDuZaxS93Ot3MN91TjOTqWewuj/Ahnl/pxOPzsy8zTN0FwkIXh
6dvM21kQQg/r5Lq40yQYxk6HA2vkzZm4PYFbuEegG0XG3CoLcvPme2hWec6fbbL4
0M3RsIKS5yLNdgtB4r6uzjyqaOO6TYP1Yndb7wd7befwoNkPXBfEfxvChoZEoXCF
/IlFtUqOcZLTLkL+yfqU60RRkvurbZVYtMI7yTpCAKUsMMJoD6ZA49E/1FSVkFxR
-> ssh-ed25519 QovoLQ P6/XAKtF+DGLR6VhsHV8/LwAacQj4TySaH/A+c7qW1A
NrZTXLxCCDqTV3FHg9P4FyJ+3Up7Nm+Docrv/YKxDYA
-> ssh-rsa OFkEIg
qABFIWIcl7Qq8UXzxwXyVJQRgCxxXWDr4nUyOExxuVZcksDJPHN1VN1lbizEFXtN
eIujZ2PodAuy05NKP0k+BhV9PH7NoXzpgKYD3mVFU8xJo/3gytUgbIg2EHAUmctK
PAwdCbA8hT5T7KZV17hGNEkVjV8h6haRYuKCZIYkwIwFGRC++OqMZSOSB+2iAFSA
QBGQCn835EjE57M+yCOVvSQagqoaimNKx7Idtkjqvx3wOvuy4Px2FxtE4PloW9i2
zR2NH9NAsGcUA+i8eFO3KKtXFoKm6QsRUPVn0o3nsxDXjYO/OSB6yS7GNjLJSkfO
n+UcKy5/lHNQqtBSLg+OLH0ZSj+nyHX5Dk1Cq+MB0J0KbcXA6XVm6+hhQE5xzegP
RSzgKxmqCEAcSGD4Li4nJJK3bwB971njDVyIaNBRC+7T8zY6h7LIZlB7Bq2SQ3Wb
tsnYHOldgfkkAEqkS8oQzxNMe94BzsfL5/JuPHF5+gx9ljLB1kOk5a0B6YWiVCyE
Iy/PH2ikTa3CYcNOfGnlkfBsk7Sf6C5ZvYaVWrb13Cxh5DZFGg4HIc58pmKkvq4B
o07/I6nA8Dw/j0hX/wtF8h8CsASTkRlu09GIPimV1f3gAALFwmYOEFjSEJ4tE++O
Dz/v5lzBUw7TDYGrylLLerOd+mH5FYl8ai2OFu9dtsE
--- oWcM9irmHBy2/btfhFIoLfsdkQQV1GFY4q0wy3q9h4U
F(è«BFÛR‡QíC¯÷
æ-%wâzJAv‰CaŸ.ñØ,v¢+EðÂQÐ{®·â]
Binary file not shown.
+32 -15
View File
@@ -1,17 +1,34 @@
age-encryption.org/v1
-> ssh-ed25519 Wl2fDA JMymqEdh+xJbl8VcL5wg7Y2Dk4667DzNO85RCskX+0Q
ZQqF0eYpvrLujGdIvAMbfwPnKGa+mfNvAhHGMdXiYaI
-> ssh-ed25519 zNC8SA UCQhQA4f3OiNoxejDBMabnls3LjS0GQmvIqPpjB/FH8
0qvv6W1heZiE1DDYEj1U5N2e99DZLxlJ6A8EoZ31DhM
-> ssh-rsa 3G83yA
Gnpw8t6njIXGm98jTS47Afx6TogPnIJP59rapF0CkYkDXZNrW7WK+fcERHLN2+a+
PSkjwkql3LfAtCNqrIJZwWLj/URnKQF5N3ZKwOa1+wsM3GeUzjvaQwPZunj4jyFs
IJlL+ika2sBk/HvOa1r6ntj2cvLM1fIhbs9bOEZW3br3M3sfXk386TgrytqzM248
3xS2iIwIBmBiI5Xem8KO2+J/2Vk9Px/ZPkBpdIAaZAmihe3g/VWNKHhXrwdM9ZA7
tHgw5ohK8ug88ep9XCIFD75DPeK/60wqAdkGs4PE6THcsKqhN061TAEq3SWRl8wp
Kd17yAzHDLhsbdWXT/Q912Y4YJCB3TnD0MFGzPF7sks2NknB6yowwjnCGlqzf5rW
RBKHp6PTM+x/eDi89vS+uIBtyGFaFU7wBTl4FzJpKoOsRIDYNktGkJSxdTzrMO1n
XqXtJtqZaXN7UExA+ko9ln446I7RG8c3hNGx4A4bR1xUEUE8WD/TMhjzrbzysYSl
-> ssh-ed25519 Wl2fDA dM0TgKtswZcbEV9tGGY26YCksV2xadHWXv7D/KksAWk
1vCcuHmVP2xiHd/7hh0z2Hiq/EeA8uvdsRtQReC5hNY
-> ssh-ed25519 zNC8SA uTO/3ePjgiKqk3jeRGZX5D3LjzhSBlp2rD2ZakKmfX0
tVkEEcP/KfD9x52l7iz5F3hKK0LSckjXWK5YP2aeBt4
-> ssh-ed25519 EiAAKw Etu0I4IzJ3BB2SzCeiexx+dhcLUO5d2Ws+WiJyLk/Sw
9GBcZPsIXO3mXbri3lFYjtBBu0wFYul6hKsCvBKVLFs
-> ssh-rsa eFi+Zw
uOZsBC+IMHdX2h9Jq/CF/L3BsxDW+dULk04JQbDeM85Mrxxdrv2X3w7AW8YU2KS+
Xg8LnzH01z4Nfs89uysM/lsWptc9qMeaK9o0oHC+tSJH4Ch43MejbmFYjFibHaCm
krQM7dAGIJwc/o0+ykaCrbXSvXAyfd6Nw1izou2ZcDRI7mTipOZO8F949SIk//Rc
UJgPLqpGwScEfrHf4f6tySC4LmD0bPIV1xDpmmXcS7c83E9+iVOtb5Y1In6CQrF1
XZQCb9MkPySbuicwR022CySb+lc7Ru44RdqBgV1e+wphyZCoqCk09i18egV3hNs6
iEul3M8dqV27yRKrWIUD5jT2tUszTNJfreiuZl9eDmLkcVWExkWzqWPUFJ48hQiZ
89Z4Evn04vZGoeL67K5q93lSRHz109zT/KIJSQMZpbaecGAoiZDM8Mdq3KzawGSG
ENQazx6lnGoMccvxFhjrVqfYj3U4S/pnCow5fatvkBQSyysL63UxE5ivcFUHHppB
--- BuKW3bW48i1OD38J2bj5sRkn+zg/WKiLtf8zgycCr2A
g­©2Ôkâ5 ÀóìØ!]0kÉW€³ÍØ¡t>éQžk[I3Vâ4EÔàwc`L;UvžVe)m©mé¿€ Û¸
-> ssh-ed25519 QovoLQ wgg0cFlYEVafE3rXK4GrID3RTatZdKPYzsjT18WskFM
bgv+7an3xgdqf6WaiB1FFkXObcykUnvH6lJmX5gFJkQ
-> ssh-rsa OFkEIg
IIQbFB6VUwbB+ZtKR7Ayg9Im6vMU1AzqHT8CBagA5fwJ7Vp1GuX1X9SxL9hMPkd3
4osEbSu3JJDMwfC6AfFtcEjmxjmRYyiYlzmIjhVEsaTlwyeucAPd+fdj+TPjHidZ
dffizNEOiENY49jlmWTjMqYKnBsSP9GfH4ZsKpCaWMm2h9p687weuXFfbYfjYMII
a3C4iG8m+mZ4crYTKZu6WPbnHn9g0pMxZBs4v6MnBHk6eEJ0uiJvrzYApoFE5om7
9AknL27ra/+A1UQl+1kzLT+IivJa8FCfZ+zF1RYLRvSATlIzCqCiBiayAsVtQg5O
girBRnlAJTPisszyoAhsqbECvD6bJfwlTW0STg/M1u3ZPMTGL4V0gJgynANmjb7Y
TXd11zuhjRYgOBAj09trQFTmmwIgPvvu8+VXNDNPAp02ffBT8kMUvSEik98/35x1
Dwvm38t05O6nqyHUF957CRVTzPQPAnb5Cd+Rw/joID2YPyFN9IZwE4mi2Bf3zdZo
roxtqCupmWkpxMNN7GZJrmCE/Lh6YV4DgUd6VNQc7QlGsq5K4XRT7aa+s+17cC8e
HCxQfGM8sMe9T6IK+K4p6qTqluyI/X0r95kGfzhNmgzufc44i6X497i3fDSVoLpx
Uo7Ao3QRNPyaUXcqTTIg8Kx9YiLQC3tDblVJjIZU89o
--- Vb9o/bhuN6XXjfK04haEEUXnuIA02j4GH9PmAh0ayN8
óE¬dGs;’ްÀ± ü
ñ,OHˆÿœˆ{²¶>ú*wAÃLÌÄ\©0SQöÖ*{6fô‰+Xš¨.
+7
View File
@@ -5,4 +5,11 @@ let
in
{
"ntfy.age".publicKeys = [ tuxcord-ca ] ++ builtins.attrValues users;
# tsig-keygen etc.sub.domain.tld.
"dns/tuxcord.net/tuxcord.net.key.age".publicKeys = [ tuxcord-ca ] ++ [ users.error users.javalsai ];
# "dns/tuxcord.net/XXX.tuxcord.net.key.age".publicKeys = [ tuxcord-ca ] ++ [ users.XXX ];
"dns/tuxcord.test/tuxcord.test.key.age".publicKeys = [ tuxcord-ca ] ++ builtins.attrValues users;
"dns/tuxcord.test/sub.tuxcord.test.key.age".publicKeys = [ tuxcord-ca ] ++ builtins.attrValues users;
}
+9 -1
View File
@@ -42,7 +42,15 @@ Host specific configuration can be found at `nixos/hosts/tuxcord-XX`. This is us
To learn how to get started, refer to the [Getting Started guide](./GETTING_STARTED.md).
The guide contains basic instructions as to how to use Nix for this repository, as well as tools to help in certain tasks.
The guide contains basic instructions as to how to use Nix for this repository, as well as tools to help in certain tasks, some of this tools might be assumed accross document resources.
It might also be useful to read the [installation section](#installation) to learn how to configure your testing environment.
# Installation
Though the nix configuration already does most heavy-lifting already. There's some minor configuration that has to be done to the mutable state of the machine.
Each aspect of it should be carefully explained in the [Setup Guide](./SETUP.md).
# Contributions
+28
View File
@@ -0,0 +1,28 @@
# Secrets
Secrets are managed with `agenix` in the `agenix/` directory. This allows to declaratively define secrets as well as which keys are allowed to decrypt them.
# Usage
The `agenix` help menu is already very helpful, but here you have a survival guide:
- `agenix` commands should run relative to the `agenix/` direcotry.
- `agenix -d` allows you to descrypt such file if you possess any of the decryption keys.
- `agenix -e` decrypts (if present) and opens the file in your editor to re-encrypt when exited.
- `agenix -r` re-encypts `*.age` files in the case you ever change its decryption keys.
# Secrets
<!-- TODO: missing ntfy.sh secret docs -->
## DNS TSIG Keys
The DNS server takes zone updates through `nsupdate` with symmetric TSIG keys.
These keys can be generated using `tsig-keygen <key-name>` (historically they were done with `dnssec-keygen` and `HMAC` algorithms, but this is no longer supported).
When DNS is enabled for a host, it will look for `dns/${fqdn}/${zone}.key` secrets.
- The key whose zone matches the `${fqdn}` will be allowed to tramit updates for all the domain.
- Keys restrained to a specific `${subdomain}` will only be allowed to edit records of such subdomain.
- All keys must be named with the zone they affect, final dot included, so that (e.g. `tuxcord.net/javalsai.tuxcord.net.key` must be generated by `tsig-keygen javalsai.tuxcord.net.`).
+60
View File
@@ -0,0 +1,60 @@
# Setup Steps
The first configuration of the server needs some configuration of its mutable state:
Setup also heavily relies on the secrets configured, make sure you [undestand agenix](./SECRETS.md) good enough.
# SSH Keys
Most agenix secrets have to be decrypted by the machine nixos is being installed to. For this, agenix uses the ssh host keys.
This also means that no secrets will be accessible on the host right after a base installation, with the default fresh ssh keys.
Will will need to either migrate ssh keys from another host, if you are doing a migration, or take the public keys of the new host out to encrypt agenix secrets against them. These keys, both public and private are present in `/etc/ssh/ssh_host_*`, we have a strong preference in favor of elliptic curve cryptography.
Also note that ssh keys are persistent and will be saved across machine boots and virtual machine rebuilds, so you don't need to repeat this process every time.
# DNS SOA Record
If the DNS server is enabled for the host (`dns.enable`), the host will have a DNS server for itself that can take updates with `nsupdate`.
This section assumes surface-level knowledge of DNS records, as well as a IPv4-only server.
First of all, make sure that the secrets for `nsudpate` ([DNS TSIG Keys](./SECRETS.md)) are in place, otherwise the server won't be able to take updates and will remain on an empty useless state.
You need to tell it it has authority over itself (`SOA` -> `Start Of Authority`) for it to take updates and serve changes properly, as well as configure the base `A` records.
`/var/dns/${fqdn}.zone`:
```zone
$ORIGIN ${fqdn}.
$TTL 14400 ; 4 hours
@ IN SOA ${fqdn}. ${adminEmail} (
2026050301 ; serial
3600 ; refresh (1 hour)
1800 ; retry (30 minutes)
604800 ; expire (1 week)
86400 ; minimum (1 day)
)
@ A ${ip}
ns1 A ${ip}
@ NS ns1
ns2 A ${ip}
@ NS ns2
* CNAME ${fqdn}.
```
Note the template variables:
- You need to place your FQDN in `${fqdn}` (there are shorter ways, but this guarantees functionality even if the hostname and domain don't match).
- Also an IPv4 address at `${ip}`.
- And lastly, `${adminEmail}` the SOA record has a `RNAME` field that takes the administrator's email address with dot notation (`test@example.com` would be written as `test.example.com.`).
- The values related to serial number and lifetimes can and should be tweaked depending on the use-case. Especially `serial`, note that it resembles a date.
Then restart bind with `systemctl restart bind`. Make sure that the file is owned by `named:named`.
> [!NOTE]
> This file is **mutable**, bind can and **will** change it with `nsupdate`s, it also tends to format and compact this template into a certain layout.
+5 -1
View File
@@ -1,4 +1,8 @@
{
error = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDzdpxex2GlFVf5G2qsh3Ixa/XCMjnbq4JSTmAev7WYJ error.nointernet@gmail.com";
javalsai = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCufzCHLqMfuHpKKisd9Y+3l6hudbQQyaHg1lgQs5XEO58f0dIoUK3gc8iVO6dGGeY5q2o0cDcildHiT0PYc96rq7WJLCY00mAuclEuhmRSPjsei2IT3rWTawIheD2tWq+vAQjIBKibYWnVYwNOsbR3Zz1uKG/LNqqDnyYO/t4iMmhO1qcl6j8dRVBtzWYu3TnTrwx45sj54Y9hqZZiwB1xlzhHznSw6YPOe51hUO/yUtXKF2FCyfG7LHELZBMXkPQD6h4mDu+QNPN2D5RGd+Q5WzHcXcrXH/DvogVW6g3YGpBjTNKllCjGJYdYgjcjzQOS3I8ZOL6CUQzcZt2QwO3P42s4cjGzBwIub2zFnMOCyGgbKCYh3G7KKcde9qAX0yl8k+XNPIletJAV7pDrivzmgRLdy3iWud+q8TytkDLhcd/7g+pE6FE8y3IbejwXGNUn8CXJOKWH5zk0MVWSpNqz+6rlV43iPb4yuO7TFVnzuw/wKyOoc8RlFGEb/XLXwPs=";
javalsai = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFjavnLqxIzFLIUpUWDOwhlYeoII4Qk1/9e0yWWxD/P";
max = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDxVfJhzPDZ108UjB3Vj/akzlzYn27kyAw29AuYAr7gvG5vrqhLUYYmK8t+ZVWVpc1g6cK7OF1oUn2E5Qfmy6wqyZQXftAZ4OcRS0MB71W1bAcRq3rGe6KQDm8RSEeygX+zO+2Z6zQmVWgPr/I+JFQZ8wiWdP8X8djqTRdhqUD+SR3ZgTcnY3aLmeB/I56rcZQ3lKIeg/pEsyQ8weptlV0rTWamna6Z7Nw48VwWNSI+6EqfW2/4/edm0Ue8jMNqNZ0yx+kHJbudPgZgSR1SiR2rqlEEUaiQJQQV3VdY4DhGm7143ZSKUxyKlfTuQ7qR1zSIg6f5V71A37ik9YiSbBlOZO86swR4qHESoMNf608IuqRt2NdALHwozFPUCu16qnhu5JTk8twSAzrAhOk5zWQj1LYMoQEBhcFSmwir/1gE71NSjYtqXGVAdfkVmZ4uqG5+a1D7H3VXWOqu/j839M045O1ZBY6X3lKDsEJ1Z1+LCl/NojWnvPtJUHYI6+SdQ6k=";
vectorum = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCwfPaylCSN7ZqB6Trz8CmQlyzf0NUIy06uschdIOkdzjUNe/dPGbyEFZy/4SDBhg585x8hwfhfYjLGrneYq+O42DBDTDKxduWnIdl5zgPRqt7jB59jkukf9WUdpUdZsKCM5K97HCnizNEKGRnYllVPVQSapPhOm5dZlUD9YVv1UqbDuxtWOLvArkL52e9T+yL6FagRg6NPqA70MXPMk+S2H7lotFVxP2Eg//BCaQ0/H1vhNy6P4N6LLq3sVK1DSJyd2v8zHkdb2Zo0/Ygukol10KizSsEcihm8+bXp699uSgWIsaIQgDZlE1yx2iabmzQST1kL9+USnZZBZ+KxwtLCCI8mpCv6sxlhq2Zzim5HvsyMYM+zdHWIn1s2c6mEl4ntBAB4s5wAggS5Gjh/BfJLSvGsTFMC/XYX4gWFXynY5NlcopeENL2Afg4gbQvKkxYkWB/TMZWuqj5c5kCy+7F0881DpYxapq6kQ6IE4gkGiEQdhVFGWEFoV/k9iHrl6aanqvFtvuBHHgkXAGPpHAZDVZdp9lU0tqNQIM/eGINq4Or6wd9XDYyj5ezDEBxx1pPgweUDZrNe9+vKR+3AwbzB/XQPxTCcjd4d7Yx58jPLflFP1dDYT+3bvp+vA7UpHcJnISbVNu0SiSaIqLYhwDj1od5l6JDfRCqnMF1T59nRCQ==";
pickzelle = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPUYQUWoL8iGc+PSrRrHyNwcOcmgGwPvJAM9HRJkPqcW pixel@DOOM-Machine";
}
+19 -5
View File
@@ -4,6 +4,7 @@
lib,
pkgs,
self,
config,
...
}:
let
@@ -92,13 +93,26 @@ in
networking = {
networkmanager.enable = true;
firewall = {
enable = true;
firewall.enable = true;
allowedTCPPorts = [
22
extraHosts =
let
subdomains = [
""
".git"
];
};
in
builtins.foldl' (
hosts-acc: domain-prefix:
let
host = "${domain-prefix}${config.networking.fqdn}";
in
hosts-acc
+ ''
127.0.0.1 ${host}
::1 ${host}
''
) "" subdomains;
};
virtualisation.podman.enable = true;
+2
View File
@@ -31,5 +31,7 @@ in
{
flake.nixosConfigurations = {
tuxcord-ca = mkSystem "tuxcord-ca" "x86_64-linux";
tuxcord-test = mkSystem "tuxcord-test" "x86_64-linux";
};
}
+2
View File
@@ -4,5 +4,7 @@
./storage.nix
];
dns.enable = true;
networking.fqdn = "tuxcord.net";
time.timeZone = "Canada/Eastern";
}
+4
View File
@@ -0,0 +1,4 @@
{
dns.enable = true;
networking.fqdn = "tuxcord.test";
}
+4 -1
View File
@@ -1,9 +1,12 @@
{
imports = [
./dns.nix
./fail2ban.nix
./sysctl.nix
./gitea.nix
./host.nix
./nginx.nix
./snapper.nix
./substituters.nix
./sysctl.nix
];
}
+100
View File
@@ -0,0 +1,100 @@
{ config, lib, ... }:
let
agenixDnsDir = ../../agenix/dns + "/${config.dns.domain}";
agenixKeys = builtins.attrNames (builtins.readDir agenixDnsDir);
keys = map (
filename:
let
zonesub = _: "zonesub";
subdomain = name: "subdomain ${name}";
zoneDomain =
if lib.strings.hasSuffix ".key.age" filename then
lib.strings.removeSuffix ".key.age" filename
else
throw "${filename} is not a `.key.age` file";
in
{
name = zoneDomain;
path = config.age.secrets."dns/${filename}".path;
type = if zoneDomain == config.dns.domain then zonesub else subdomain;
}
) agenixKeys;
cfg = config.dns;
inherit (lib)
mkEnableOption
mkOption
mkIf
;
in
{
options.dns = {
enable = mkEnableOption "" // {
default = true;
};
domain = mkOption {
type = with lib.types; str;
default = config.networking.fqdn;
};
};
config = mkIf cfg.enable {
age.secrets = builtins.listToAttrs (
map (
filename:
let
path = "${agenixDnsDir}/${filename}";
in
{
name = "dns/${filename}";
value = {
file = path;
group = "named";
owner = "named";
};
}
) agenixKeys
);
services.bind = {
enable = true;
extraConfig = builtins.concatStringsSep "\n" (map (key: "include \"${key.path}\";") keys);
zones = {
"${config.dns.domain}" = {
# grant "tuxcord.net" zonesub ANY;
extraConfig = ''
update-policy {
${builtins.concatStringsSep "\n" (
map (key: "grant \"${key.name}\" ${key.type key.name} ANY;") keys
)}
};
'';
file = "/var/dns/${config.dns.domain}.zone"; # need to put default stuff
master = true;
};
};
};
environment.persistence."/persist".directories = [
{
directory = "/var/dns";
group = "named";
user = "named";
}
];
networking.firewall =
let
ports = [ config.services.bind.listenOnPort ];
in
{
allowedTCPPorts = ports;
allowedUDPPorts = ports;
};
};
}
+27
View File
@@ -0,0 +1,27 @@
{ config, lib, ... }:
{
services.gitea = {
enable = true;
appName = "Tuxcord's Gitea";
database.type = "mysql";
lfs.enable = true;
settings.server.DOMAIN = config.networking.fqdn;
# settings.server.ROOT_URL = "https://git.tuxcord.net/"; ? would also depend on ssl status
settings.server.HTTP_PORT = 3000;
settings.service.DISABLE_REGISTRATION = true;
settings.service.REQUIRE_SIGNIN_VIEW = false;
settings.repository.ENABLE_PUSH_CREATE_USER = true;
settings.repository.ENABLE_PUSH_CREATE_ORG = true;
settings.repository.DEFAULT_BRANCH = "main";
# settings.ui.DEFAULT_THEME = "...";
# TODO: once we have email setup this would be nice
settings.mailer.ENABLED = true;
};
}
+41
View File
@@ -0,0 +1,41 @@
{ config, ... }:
let
inherit (config.networking) fqdn;
mkVhost =
attrs:
{
forceSSL = false; # TODO: tweak per host
}
// attrs;
mkProxy = port: {
proxyPass = "http://127.0.0.1:${toString port}/";
};
in
{
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
# services.nginx.virtualHosts."${fqdn}" = {
# addSSL = true;
# root = "/var/www/myhost.org";
# default = true;
# };
virtualHosts."git.${fqdn}" = mkVhost {
locations."/" = mkProxy config.services.gitea.settings.server.HTTP_PORT;
};
};
networking.firewall.allowedTCPPorts = [
80
443
];
}
+2 -4
View File
@@ -1,17 +1,15 @@
{ self, ... }:
{
services.openssh = {
enable = true;
settings = {
ClientAliveInterval = 300;
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
users.users.root.openssh.authorizedKeys.keys = builtins.attrValues {
inherit (import "${self}/lib/ssh/keys.nix") error javalsai;
};
networking.firewall.allowedTCPPorts = [ 22 ];
}
+1
View File
@@ -41,6 +41,7 @@ in
environment.systemPackages = with pkgs; [
atop
bat
bind
btdu
btop
compsize
+29 -11
View File
@@ -16,6 +16,9 @@ let
{
name = "vectorum";
}
{
name = "pickzelle";
}
];
adminGroups = [
@@ -27,20 +30,29 @@ let
"wheel"
];
mkUser = name: uid: options: {
getSSHKeys =
username:
let
sshKeys = import "${self}/lib/ssh/keys.nix";
in
if (builtins.hasAttr username sshKeys) then
lib.lists.toList sshKeys.${username}
else
lib.warn "user ${username} declared without ssh key" [ ];
mkUser =
name: uid: options:
let
admin = options.admin or false;
in
{
users.users.${name} = {
isNormalUser = true;
extraGroups = lib.optionals (options.admin or false) adminGroups;
extraGroups = lib.optionals admin adminGroups;
inherit uid;
openssh.authorizedKeys.keys =
let
keys = import "${self}/lib/ssh/keys.nix";
in
if (builtins.hasAttr name keys) then
[ keys.${name} ]
else
lib.warn "user ${name} declared without ssh key" [ ];
openssh.authorizedKeys.keys = getSSHKeys name;
};
systemd.slices."user-${builtins.toString uid}".sliceConfig = {
@@ -67,5 +79,11 @@ lib.recursiveUpdate
users
).options
{
users.users.root.initialPassword = "tuxcord";
users.users.root = {
initialPassword = "tuxcord";
openssh.authorizedKeys.keys = lib.lists.concatLists (
map (user: getSSHKeys user.name) (builtins.filter (user: user.options.admin or false) users)
);
};
}
+6
View File
@@ -1,8 +1,14 @@
{ lib, ... }:
{
virtualisation.vmVariant.virtualisation = {
cores = 2;
diskSize = 8192;
graphics = false;
memorySize = 4096;
qemu.networkingOptions = lib.mkForce [
"-net nic,netdev=user.0,model=virtio"
"-netdev user,id=user.0,\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}"
];
};
}