forked from pub-solar/infra
Compare commits
3 commits
main
...
feat/matri
Author | SHA1 | Date | |
---|---|---|---|
977a9c0758 | |||
63041ec805 | |||
f56fd8dccc |
105 changed files with 944 additions and 40501 deletions
.forgejo/workflows
.git-blame-ignore-revs.gitignoreREADME.mddocs
administrative-access.mddeletion-request.mddeploying.mddevelopment-shell.mddns.mddrone-ci.mdforgejo-actions.md
flake.lockflake.nixkeycloak
mediawiki-updates.mdnix-flake-updates.mdprivacy-hardening.mdsecrets.mdssh.mdhosts
default.nix
flora-6
apps
alert-rules.nixcaddy.nixdrone.nixforgejo-actions-runner.nix
configuration.nixdefault.nixhardware-configuration.nixtriton-vmtools.nixwireguard.nixgrafana-dashboards
grafana.nixloki.nixprometheus.nixnachtigall
apps
collabora.nixcoturn.nixforgejo.nixkeycloak.nixmailman.nixmastodon.nix
backups.nixconfiguration.nixdefault.nixhardware-configuration.nixnetworking.nixwireguard.nixmatrix
mediawiki.nixnextcloud-skeleton
nextcloud.nixnginx-mastodon.nixnginx-matrix.nixnginx-prometheus-exporters.nixnginx-website-miom.nixnginx-website.nixnginx.nixowncast.nixprometheus-exporters.nixpromtail.nixsearx.nixtmate.nixlib
logins
modules
overlays
public-keys
secrets
age-yubikey-464-identity.txtage-yubikey-485-identity.txtcoturn-static-auth-secret.agedrone-secrets.ageflora6-wg-private-key.ageforgejo-actions-runner-token.ageforgejo-ssh-private-key.agegrafana-admin-password.agegrafana-keycloak-client-secret.agegrafana-smtp-password.agematrix-hookshot-registration.yaml.agematrix-synapse-secret-config.yaml.agematrix-synapse-sliding-sync-secret.agenachtigall-metrics-nginx-basic-auth.agenachtigall-metrics-prometheus-basic-auth-password.age
|
@ -1,71 +1,17 @@
|
|||
name: Flake checks
|
||||
on: [pull_request]
|
||||
env:
|
||||
USER: ci
|
||||
|
||||
jobs:
|
||||
Check:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: nix-flakes
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: https://code.forgejo.org/actions/checkout@v4
|
||||
|
||||
- uses: https://github.com/nixbuild/nix-quick-install-action@v27
|
||||
with:
|
||||
load_nixConfig: false
|
||||
nix_conf: |
|
||||
substituters = https://cache.nixos.org/ https://nix-community.cachix.org
|
||||
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
|
||||
keep-outputs = true
|
||||
|
||||
- name: Calculate flake.lock hash
|
||||
id: flake-lock-hash
|
||||
run: |
|
||||
echo "hash=$(md5sum flake.lock | awk '{print $1}')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore and cache Nix store
|
||||
uses: https://github.com/nix-community/cache-nix-action@v4.0.3
|
||||
id: nix-store-cache
|
||||
with:
|
||||
key: cache-${{ runner.os }}-nix-store-${{ steps.flake-lock-hash.outputs.hash }}
|
||||
restore-keys: |
|
||||
cache-${{ runner.os }}-nix-store-
|
||||
|
||||
gc-linux: true
|
||||
gc-max-store-size-linux: 10000000000
|
||||
|
||||
purge-caches: true
|
||||
purge-key: cache-${{ runner.os }}-nix-store-
|
||||
purge-created: true
|
||||
purge-created-max-age: 42
|
||||
|
||||
- name: Prepare cachix
|
||||
uses: https://github.com/cachix/cachix-action@v14
|
||||
uses: https://github.com/cachix/cachix-action@v12
|
||||
with:
|
||||
name: pub-solar
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
useDaemon: false
|
||||
|
||||
- name: Run flake checks
|
||||
run: |
|
||||
# Prevent cache garbage collection by creating GC roots
|
||||
for target in $(nix flake show --json --all-systems | jq '
|
||||
.["nixosConfigurations"] |
|
||||
to_entries[] |
|
||||
.key
|
||||
' | tr -d '"'
|
||||
); do
|
||||
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' \
|
||||
build --out-link ./result-$target ".#nixosConfigurations.${target}.config.system.build.toplevel"
|
||||
done
|
||||
|
||||
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' flake check
|
||||
|
||||
# Add GC roots for flake inputs, too
|
||||
# https://github.com/NixOS/nix/issues/4250#issuecomment-1146878407
|
||||
mkdir --parents "$NIX_USER_PROFILE_DIR"
|
||||
gc_root_prefix="$NIX_USER_PROFILE_DIR"/infra-flake-
|
||||
echo "Adding gcroots flake inputs with prefix $gc_root_prefix ..."
|
||||
nix flake archive --json 2>/dev/null | jq --raw-output '.inputs | to_entries[] | "ln --force --symbolic --no-target-directory "+.value.path+" \"'"$gc_root_prefix"'"+.key+"\""' | while read -r line; do
|
||||
eval "$line"
|
||||
done
|
||||
nix --print-build-logs --verbose --accept-flake-config flake check
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
# Apply treewide formatting with nixpkgs-fmt
|
||||
815033c764660e1468b1564a02570bad0f84f77a
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,4 +3,3 @@
|
|||
.direnv
|
||||
.terraform
|
||||
*.plan
|
||||
result
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# The pub.solar infrastructure
|
||||
|
||||
This repository contains almost all of the configuration for the whole pub.solar infrastructure. Our goal is to have everything, from host configurations to Terraform DNS in this repository.
|
||||
This repository contains all almost all of the configuration for the whole pub.solar infrastructure. Our goal is to have everything, from host configurations to Terraform DNS in this repository.
|
||||
|
||||
The architecture we are working towards is a vast simplification of what it was before: one dedicated Hetzner server running [NixOS](https://nixos.org/) with all services. Offsite backups go to several different locations with [restic](https://github.com/restic/restic).
|
||||
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
# Adminstrative access
|
||||
|
||||
People with admin access to the infrastructure are added to [`logins/admins.nix`](../logins/admins.nix). This is a attrset with the following structure:
|
||||
|
||||
```
|
||||
{
|
||||
<username> = {
|
||||
sshPubKeys = {
|
||||
<name> = <pubkey-string>;
|
||||
};
|
||||
|
||||
wireguardDevices = [
|
||||
{
|
||||
publicKey = <pubkey-string>;
|
||||
allowedIPs = [ "10.7.6.<ip-address>/32" "fd00:fae:fae:fae:fae:<ip-address>::/96" ];
|
||||
}
|
||||
}];
|
||||
|
||||
secretEncryptionKeys = {
|
||||
<name> = <encryption-key-string>;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
# SSH Access
|
||||
|
||||
SSH is not reachable from the open internet. Instead, SSH Port 22 is protected by a wireguard VPN network. Thus, to get root access on the servers, at least two pieces of information have to be added to the admins config:
|
||||
|
||||
1. **SSH Public key**: self-explanatory. Add your public key to your user attrset under `sshPubKeys`.
|
||||
2. **Wireguard device**: each wireguard device has two parts: the public key and the IP addresses it should have in the wireguard network. The pub.solar wireguard network is spaced under `10.7.6.0/24` and `fd00:fae:fae:fae:fae::/80`. To add your device, it's best to choose a free number between 200 and 255 and use that in both the ipv4 and ipv6 ranges: `10.7.6.<ip-address>/32` `fd00:fae:fae:fae:fae:<ip-address>::/96`. For more information on how to generate keypairs, see [the NixOS Wireguard docs](https://nixos.wiki/wiki/WireGuard#Generate_keypair).
|
||||
|
||||
# Secret encryption
|
||||
|
||||
Deployment secrets are added to the repository in encrypted files. To be able to work with these encrypted files, your public key(s) will have to be added to your user attrset under `secretEncryptionKeys`.
|
||||
|
||||
See also the docs on [working with secrets](./secrets.md).
|
|
@ -1,61 +0,0 @@
|
|||
# Process for handling a deletion request
|
||||
|
||||
### Keycloak
|
||||
Required:
|
||||
- auth.pub.solar ops user credentials
|
||||
- SSH access to host nachtigall
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
|
||||
sudo --user keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm pub.solar --user ops
|
||||
|
||||
# Take note of user id in response from following command
|
||||
sudo --user keycloak kcadm.sh get --config /tmp/kcadm.config users --realm pub.solar --query email=<email-address>
|
||||
|
||||
# To avoid impersonification, we deactivate the account by resetting the password and email address
|
||||
# Use user id from previous command, for example
|
||||
sudo --user keycloak kcadm.sh update --config /tmp/kcadm.config users/2ec6f173-3c10-4b82-9808-e2f2d393ff11/reset-password --realm pub.solar --set type=password --set value=<random-password> --no-merge
|
||||
sudo --user keycloak kcadm.sh update --config /tmp/kcadm.config users/2ec6f173-3c10-4b82-9808-e2f2d393ff11 --realm pub.solar --set email=<username>@deactivated.pub.solar
|
||||
```
|
||||
|
||||
Docs: https://www.keycloak.org/docs/latest/server_admin/index.html#updating-a-user
|
||||
|
||||
|
||||
### Nextcloud
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
nextcloud-occ user:delete <username>
|
||||
```
|
||||
|
||||
Docs: https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#user-commands-label
|
||||
|
||||
|
||||
### Mastodon
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
sudo -u mastodon mastodon-tootctl accounts delete --email <mail-address>
|
||||
```
|
||||
|
||||
Docs: https://docs.joinmastodon.org/admin/tootctl/#accounts-delete
|
||||
|
||||
|
||||
### Forgejo
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
sudo -u gitea gitea admin user delete --config /var/lib/forgejo/custom/conf/app.ini --purge --email <mail-address>
|
||||
```
|
||||
|
||||
Docs: https://forgejo.org/docs/latest/admin/command-line/#delete
|
||||
|
||||
|
||||
### Matrix
|
||||
```
|
||||
ssh bartender@matrix.pub.solar -p 2020
|
||||
curl --header "Authorization: Bearer <admin-access-token>" --request POST http://172.18.0.3:8008/_synapse/admin/v1/deactivate/@<username>:pub.solar --data '{"erase": true}'
|
||||
```
|
||||
|
||||
Docs: https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account
|
||||
|
||||
|
||||
### OpenBikeSensor
|
||||
Not implemented, see: https://github.com/openbikesensor/portal/issues/95
|
|
@ -1,32 +1,20 @@
|
|||
# Deploying new versions
|
||||
|
||||
We use [deploy-rs](https://github.com/serokell/deploy-rs) to deploy changes.
|
||||
Currently this process is not automated, so configuration changes will have to
|
||||
be manually deployed.
|
||||
We use [deploy-rs](https://github.com/serokell/deploy-rs) to deploy changes. Currently this process is not automated, so configuration changes will have to be manually deployed.
|
||||
|
||||
To deploy, make sure you have a [working development shell](./development-shell.md).
|
||||
Then, run `deploy-rs` with the hostname of the server you want to deploy:
|
||||
To deploy, make sure you have a [working development shell](./development-shell.md). Then, run `deploy-rs` with the hostname of the server you want to deploy:
|
||||
|
||||
For nachtigall.pub.solar:
|
||||
```
|
||||
deploy --targets '.#nachtigall' --magic-rollback false --auto-rollback false
|
||||
deploy '.#nachtigall'
|
||||
```
|
||||
|
||||
For flora-6.pub.solar:
|
||||
```
|
||||
deploy --targets '.#flora-6' --magic-rollback false --auto-rollback false
|
||||
deploy '.#flora-6'
|
||||
```
|
||||
|
||||
Usually we skip all rollback functionality, but if you want to deploy a change
|
||||
that might lock you out, e.g. to SSH, it might make sense to set these to `true`.
|
||||
You'll need to have SSH Access to the boxes to be able to do this.
|
||||
|
||||
To skip flake checks, e.g. because you already ran them manually before
|
||||
deployment, add the flag `--skip-checks` at the end of the command.
|
||||
|
||||
`--dry-activate` can be used to only put all files in place without switching,
|
||||
to enable switching to the new config quickly at a later moment.
|
||||
|
||||
You'll need to have SSH Access to the boxes to be able to run `deploy`.
|
||||
|
||||
### Getting SSH access
|
||||
See [administrative-access.md](./administrative-access.md).
|
||||
### SSH access
|
||||
Ensure your SSH public key is in place [here](./public-keys/admins.nix) and was deployed by someone with access.
|
||||
|
|
|
@ -3,16 +3,9 @@
|
|||
Clone this repository:
|
||||
|
||||
```
|
||||
git clone https://git.pub.solar/pub-solar/infra.git
|
||||
cd infra
|
||||
git clone https://git.pub.solar/pub-solar/infra-new.git
|
||||
```
|
||||
|
||||
then, install [the package manager nix](https://nixos.org/download).
|
||||
|
||||
Finally, run:
|
||||
|
||||
```
|
||||
nix develop
|
||||
```
|
||||
|
||||
This will install a development shell (devshell) with all required tools.
|
||||
Finally, run `nix develop` in this repo. This will install a development shell that has all required tooling available.
|
||||
|
|
41
docs/dns.md
41
docs/dns.md
|
@ -1,44 +1,17 @@
|
|||
# Changing DNS entries
|
||||
|
||||
Our current DNS provider is [namecheap](https://www.namecheap.com/).
|
||||
We use [Terraform](https://www.terraform.io) to declaratively manage our pub.solar DNS records.
|
||||
|
||||
### Initial setup
|
||||
|
||||
Skip this step if you already have a `triton` profile setup.
|
||||
|
||||
```
|
||||
triton profile create
|
||||
```
|
||||
|
||||
Please follow https://docs.greenbaum.cloud/en/devops/triton-cli.html for the details.
|
||||
|
||||
You will need to setup the following [namecheap API credentials](https://www.namecheap.com/support/api/intro),
|
||||
look for "namecheap API key" in the pub.solar Keepass database.
|
||||
```
|
||||
NAMECHEAP_API_KEY
|
||||
NAMECHEAP_API_USER
|
||||
NAMECHEAP_USER_NAME
|
||||
```
|
||||
You will probably also need to add your external IP to the [API allow list](https://ap.www.namecheap.com/settings/tools/apiaccess/whitelisted-ips).
|
||||
```
|
||||
dig -4 ip @dns.toys
|
||||
```
|
||||
|
||||
Now, change into the terraform directory and initialize the terraform providers.
|
||||
Change into the terraform directory and initialize the terraform providers.
|
||||
|
||||
```
|
||||
cd terraform
|
||||
export TRITON_KEY_ID=$(cat ~/.config/triton/profiles.d/lev-1-pub_solar.json | jq --raw-output .keyId)
|
||||
cat ~/.config/triton/profiles.d/lev-1-pub_solar.json | grep keyId
|
||||
export TRITON_KEY_ID=
|
||||
|
||||
terraform init
|
||||
```
|
||||
|
||||
Make your changes, e.g. in `dns.tf`.
|
||||
```
|
||||
$EDITOR dns.tf
|
||||
```
|
||||
|
||||
Plan your changes using:
|
||||
```
|
||||
terraform plan -out pub-solar-infra.plan
|
||||
|
@ -48,11 +21,3 @@ After verification, apply your changes with:
|
|||
```
|
||||
terraform apply "pub-solar-infra.plan"
|
||||
```
|
||||
|
||||
### Useful links
|
||||
|
||||
We use the Manta remote backend to save the terraform state for collaboration.
|
||||
- https://www.terraform.io/language/v1.2.x/settings/backends/manta
|
||||
|
||||
Namecheap Terraform provider docs:
|
||||
- https://registry.terraform.io/providers/namecheap/namecheap/latest/docs
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
# Drone CI
|
||||
|
||||
We currently use two CI systems, [drone CI](https://drone.io), reachable via
|
||||
https://ci.pub.solar and [Forgejo Actions](https://forgejo.org/docs/latest/user/actions/),
|
||||
which UI is integrated into https://git.pub.solar, for example
|
||||
https://git.pub.solar/pub-solar/infra/actions.
|
||||
|
||||
### Signing the `.drone.yml` file
|
||||
|
||||
Login to https://ci.pub.solar by clicking on the user icon in the bottom left.
|
||||
After logging in, you can view your personal API token by clicking on the same
|
||||
icon. If you're using the nix [development-shell](./development-shell.md), the
|
||||
`drone` command will already be installed.
|
||||
|
||||
```
|
||||
export DRONE_TOKEN=<your-drone-api-token>
|
||||
|
||||
drone --token $DRONE_TOKEN sign --save pub-solar/os
|
||||
```
|
|
@ -1,7 +0,0 @@
|
|||
# Forgejo Actions
|
||||
|
||||
Admin docs
|
||||
https://forgejo.org/docs/latest/admin/actions/
|
||||
|
||||
User guide
|
||||
https://forgejo.org/docs/latest/user/actions/
|
|
@ -1,22 +0,0 @@
|
|||
# Process for getting a list of email addresses of all keycloak users
|
||||
|
||||
### Keycloak
|
||||
Required:
|
||||
- auth.pub.solar ops user credentials
|
||||
- SSH access to host nachtigall
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
|
||||
sudo --user keycloak kcadm.sh get users \
|
||||
-r pub.solar \
|
||||
--offset 0 \
|
||||
--limit 1000 \
|
||||
--no-config \
|
||||
--server http://localhost:8080 \
|
||||
--realm master \
|
||||
--user admin \
|
||||
--password <admin password> \
|
||||
> keycloak-user-list.json
|
||||
|
||||
jq -r '.[].email' < keycloak-user-list.json
|
||||
```
|
|
@ -1,33 +0,0 @@
|
|||
# Process for resetting keycloak user passwords
|
||||
|
||||
### Keycloak
|
||||
Required:
|
||||
- auth.pub.solar ops user credentials
|
||||
- SSH access to host nachtigall
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
|
||||
mkdir /tmp/keycloak-credential-reset
|
||||
|
||||
sudo --user keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm pub.solar --user ops
|
||||
|
||||
sudo --user keycloak kcadm.sh get --config /tmp/kcadm.config users --realm pub.solar | jq --raw-output '.[] | .id' > /tmp/keycloak-credential-reset/all-uuids
|
||||
|
||||
for UUID in $(cat /tmp/keycloak-credential-reset/all-uuids); do
|
||||
sudo --user keycloak kcadm.sh get --config /tmp/kcadm.config users/$UUID/credentials --realm pub.solar > /tmp/keycloak-credential-reset/$UUID
|
||||
done
|
||||
|
||||
mkdir /tmp/keycloak-credential-reset/accounts-with-creds
|
||||
|
||||
find /tmp/keycloak-credential-reset -type f -size +3c -exec mv '{}' /tmp/keycloak-credential-reset/accounts-with-creds/ \;
|
||||
|
||||
rm -r /tmp/keycloak-credential-reset/accounts-with-creds/
|
||||
|
||||
find /tmp/keycloak-credential-reset/ -type f -exec basename '{}' \; > /tmp/keycloak-credential-reset/accounts-without-credentials
|
||||
|
||||
vim /tmp/keycloak-credential-reset/accounts-without-credentials
|
||||
|
||||
for UUID in $(cat /tmp/keycloak-credential-reset/accounts-without-credentials); do
|
||||
sudo --user keycloak kcadm.sh update --config /tmp/kcadm.config users/$UUID/reset-password --target-realm pub.solar --set type=password --set value=$(< /dev/urandom tr -dc A-Z-a-z-0-9 | head -c${1:-32};echo;) --set temporary=true --no-merge
|
||||
done
|
||||
```
|
|
@ -1,19 +0,0 @@
|
|||
# Process for updating a keycloak realm via CLI
|
||||
|
||||
### Keycloak
|
||||
Required:
|
||||
- auth.pub.solar ops user credentials
|
||||
- SSH access to host nachtigall
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
|
||||
sudo -u keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm master --user admin
|
||||
|
||||
sudo -u keycloak kcadm.sh get --config /tmp/kcadm.config realms/pub.solar
|
||||
|
||||
sudo -u keycloak kcadm.sh update --config /tmp/kcadm.config realms/pub.solar -s browserFlow='Webauthn Browser'
|
||||
|
||||
sudo -u keycloak kcadm.sh get --config /tmp/kcadm.config realms/pub.solar
|
||||
```
|
||||
|
||||
Source: https://keycloak.ch/keycloak-tutorials/tutorial-webauthn/
|
|
@ -1,31 +0,0 @@
|
|||
# Updating mediawiki docker container
|
||||
|
||||
See the [mediawiki-oidc-docker repository](https://git.pub.solar/pub-solar/mediawiki-oidc-docker#updating-the-docker-image)
|
||||
for instructions on updating our customized mediawiki docker image.
|
||||
|
||||
To deploy a new docker image to `nachtigall`, first bump the mediawiki version
|
||||
of the docker image tag in `hosts/nachtigall/apps/mediawiki.nix` (search for
|
||||
`image`).
|
||||
|
||||
Next, push your changes to https://git.pub.solar and get them reviewed and
|
||||
approved.
|
||||
|
||||
After approval, create a fresh backup of the database and deploy the changes to
|
||||
`nachtigall`:
|
||||
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
sudo -u postgres pg_dump --create -Fc mediawiki > mediawiki-db-$(date +%F).dump
|
||||
exit
|
||||
```
|
||||
|
||||
```
|
||||
deploy --targets '.#nachtigall'
|
||||
```
|
||||
|
||||
Then, finalize the update by running the database migration script:
|
||||
```
|
||||
ssh barkeeper@nachtigall.pub.solar
|
||||
docker exec -it mediawiki bash
|
||||
php maintenance/run.php update.php
|
||||
```
|
|
@ -1,43 +0,0 @@
|
|||
Use these commands to show the diff between versions for planning updates:
|
||||
|
||||
```
|
||||
OLD_CLOSURE=$(nix build --print-out-paths .#nixosConfigurations.nachtigall.config.system.build.toplevel)
|
||||
/nix/store/c6wqp1vzvyr3bq2igd8p460613ddwrmj-nixos-system-nachtigall-23.11.20231201.5de0b32
|
||||
```
|
||||
|
||||
```
|
||||
nix flake update
|
||||
...
|
||||
```
|
||||
|
||||
```
|
||||
NEW_CLOSURE=$(nix build --print-out-paths .#nixosConfigurations.nachtigall.config.system.build.toplevel)
|
||||
/nix/store/xynyf943d2nw1wgawhzxh13xkkf1whb0-nixos-system-nachtigall-23.11.20231210.781e2a9
|
||||
```
|
||||
|
||||
```
|
||||
nix store diff-closures $OLD_CLOSURE $NEW_CLOSURE
|
||||
cpupower: 6.1.64 → 6.1.66
|
||||
element-web: 1.11.47 → 1.11.51, +5325.9 KiB
|
||||
element-web-wrapped: 1.11.47 → 1.11.51
|
||||
initrd-linux: 6.1.64 → 6.1.66
|
||||
keycloak: 22.0.5 → 23.0.0, +15201.4 KiB
|
||||
linux: 6.1.64, 6.1.64-modules → 6.1.66, 6.1.66-modules, +8.3 KiB
|
||||
mastodon: 4.2.1 → 4.2.3, +16.3 KiB
|
||||
mastodon-gems: 4.2.1 → 4.2.3, +14.4 KiB
|
||||
mastodon-modules: 4.2.1 → 4.2.3
|
||||
nix: +18.8 KiB
|
||||
nixos-manual: +73.6 KiB
|
||||
nixos-system-nachtigall: 23.11.20231201.5de0b32 → 23.11.20231210.781e2a9
|
||||
opensearch: 2.11.0 → 2.11.1, +560.5 KiB
|
||||
owncast: 0.1.1 → 0.1.2, +798.9 KiB
|
||||
ruby3.2.2-bcp47_spec: ∅ → 0.2.1, +13.6 KiB
|
||||
ruby3.2.2-json-canonicalization: 0.3.2 → 1.0.0
|
||||
ruby3.2.2-json-ld: 3.2.5 → 3.3.1
|
||||
ruby3.2.2-rdf: 3.2.11 → 3.3.1
|
||||
samba: +12.5 KiB
|
||||
source: +3888.1 KiB
|
||||
wrapped-ruby-mastodon-gems: 4.2.1 → 4.2.3
|
||||
zfs-kernel: 2.2.1-6.1.64 → 2.2.2-6.1.66
|
||||
zfs-user: 2.2.1 → 2.2.2
|
||||
```
|
|
@ -1,11 +0,0 @@
|
|||
# Privacy hardening
|
||||
|
||||
Some default options in the services we run are not as privacy friendly as they can be. Oftentimes, services assume they are running for an organization in which everyone knows (or wants to know) everyone else. However, when running a public service accounts should be hidden from other users.
|
||||
|
||||
## Nextcloud account leaking
|
||||
|
||||
By default, accounts are visible globally across the instance. To prevent this, go into the administration settings -> Sharing. Check the option saying "Restrict users to only share with users in their group".
|
||||
|
||||
## Forgejo email leaking
|
||||
|
||||
By default, emails are visible on the explore page for other logged in users. We have disabled this in the config by setting `service.DEFAULT_KEEP_EMAIL_PRIVATE` to `true`.
|
|
@ -1,5 +1 @@
|
|||
# Working with secrets
|
||||
|
||||
Secrets are handled with [agenix](https://github.com/ryantm/agenix). To be able to view secrets, your public key will have to be added to the admins config. See [Administrative Access](./administrative-access.md) on how to do this.
|
||||
|
||||
For a comprehensive tutorial, see [the agenix repository](https://github.com/ryantm/agenix?tab=readme-ov-file#tutorial).
|
||||
|
|
3
docs/ssh.md
Normal file
3
docs/ssh.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# SSH Access
|
||||
|
||||
SSH Access is granted by adding a public key to [`public-keys/admins.nix`](../public-keys/admins.nix). This change will then have to be deployed to all hosts by an existing key. The keys will also grant access to the initrd SSH Server to enable remote unlock.
|
189
flake.lock
generated
189
flake.lock
generated
|
@ -10,15 +10,14 @@
|
|||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1712079060,
|
||||
"narHash": "sha256-/JdiT9t+zzjChc5qQiF+jhrVhRt8figYH29rZO7pFe4=",
|
||||
"lastModified": 1696775529,
|
||||
"narHash": "sha256-TYlE4B0ktPtlJJF9IFxTWrEeq+XKG8Ny0gc2FGEAdj0=",
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"rev": "1381a759b205dff7a6818733118d02253340fd5e",
|
||||
"rev": "daf42cb35b2dc614d1551e37f96406e4c4a2d3e4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -36,11 +35,11 @@
|
|||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1711973905,
|
||||
"narHash": "sha256-UFKME/N1pbUtn+2Aqnk+agUt8CekbpuqwzljivfIme8=",
|
||||
"lastModified": 1698921442,
|
||||
"narHash": "sha256-7KmvhQ7FuXlT/wG4zjTssap6maVqeAMBdtel+VjClSM=",
|
||||
"owner": "serokell",
|
||||
"repo": "deploy-rs",
|
||||
"rev": "88b3059b020da69cbe16526b8d639bd5e0b51c8b",
|
||||
"rev": "660180bbbeae7d60dad5a92b30858306945fd427",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -51,18 +50,18 @@
|
|||
},
|
||||
"devshell": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"keycloak-theme-pub-solar",
|
||||
"nixpkgs"
|
||||
]
|
||||
],
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705332421,
|
||||
"narHash": "sha256-USpGLPme1IuqG78JNqSaRabilwkCyHmVWY0M9vYyqEA=",
|
||||
"lastModified": 1688380630,
|
||||
"narHash": "sha256-8ilApWVb1mAi4439zS3iFeIT0ODlbrifm/fegWwgHjA=",
|
||||
"owner": "numtide",
|
||||
"repo": "devshell",
|
||||
"rev": "83cb93d6d063ad290beee669f4badf9914cc16ec",
|
||||
"rev": "f9238ec3d75cefbb2b42a44948c4e8fb1ae9a205",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -71,31 +70,14 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"element-themes": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1707755689,
|
||||
"narHash": "sha256-pMwrpZwLp7tw0nBbz/ENVJ2LoN9jIxEfjcq7OXoiKEw=",
|
||||
"owner": "aaronraimist",
|
||||
"repo": "element-themes",
|
||||
"rev": "2368b58c16d2c4aabb82a245f036d228cbb6e5f5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "aaronraimist",
|
||||
"ref": "master",
|
||||
"repo": "element-themes",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"lastModified": 1668681692,
|
||||
"narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"rev": "009399224d5e398d03b22badca40a37ac85412a1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -109,11 +91,11 @@
|
|||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1712014858,
|
||||
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||
"lastModified": 1698882062,
|
||||
"narHash": "sha256-HkhafUayIqxXyHH1X8d9RDl1M2CkFgZLjKD3MzabiEo=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||
"rev": "8c9fa2545007b49a5db5f650ae91f227672c3877",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -124,14 +106,14 @@
|
|||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems_3"
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1689068808,
|
||||
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -141,24 +123,6 @@
|
|||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_3": {
|
||||
"locked": {
|
||||
"lastModified": 1653893745,
|
||||
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
|
||||
|
@ -180,16 +144,16 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1714043624,
|
||||
"narHash": "sha256-Xn2r0Jv95TswvPlvamCC46wwNo8ALjRCMBJbGykdhcM=",
|
||||
"lastModified": 1699748081,
|
||||
"narHash": "sha256-MOmMapBydd7MTjhX4eeQZzKlCABWw8W6iSHSG4OeFKE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "86853e31dc1b62c6eeed11c667e8cdd0285d4411",
|
||||
"rev": "04bac349d585c9df38d78e0285b780a140dc74a4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"ref": "release-23.11",
|
||||
"ref": "release-23.05",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
|
@ -197,17 +161,17 @@
|
|||
"keycloak-theme-pub-solar": {
|
||||
"inputs": {
|
||||
"devshell": "devshell",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1707424749,
|
||||
"narHash": "sha256-eTvts5E3zmD4/DoAI9KedQjRwica0cg36wwIVp1NWbM=",
|
||||
"lastModified": 1689875310,
|
||||
"narHash": "sha256-gJxh8fVX24nZXBxstZcrzZhMRFG9jyOnQEfkgoRr39I=",
|
||||
"ref": "main",
|
||||
"rev": "1202a23c205b3c07a5feb5caf6813f21b3c69307",
|
||||
"revCount": 30,
|
||||
"rev": "c2c86bbf9855f16a231a596b75b443232a7b9395",
|
||||
"revCount": 24,
|
||||
"type": "git",
|
||||
"url": "https://git.pub.solar/pub-solar/keycloak-theme"
|
||||
},
|
||||
|
@ -217,6 +181,22 @@
|
|||
"url": "https://git.pub.solar/pub-solar/keycloak-theme"
|
||||
}
|
||||
},
|
||||
"mastodon-fork": {
|
||||
"locked": {
|
||||
"lastModified": 1698490885,
|
||||
"narHash": "sha256-Ic2YgJ7vlAoiihho4pJgHewIubIZQpv1L8ePRB1wfG4=",
|
||||
"owner": "teutat3s",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "534d90c65614f05e543fd11b3f4acd748704a625",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "teutat3s",
|
||||
"ref": "mastodon-4.2.1",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-darwin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
|
@ -224,11 +204,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1713946171,
|
||||
"narHash": "sha256-lc75rgRQLdp4Dzogv5cfqOg6qYc5Rp83oedF2t0kDp8=",
|
||||
"lastModified": 1699867978,
|
||||
"narHash": "sha256-+arl45HUOcBdKiRGrKXZYXDyBQ6MQGkYPZa/28f6Yzo=",
|
||||
"owner": "lnl7",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "230a197063de9287128e2c68a7a4b0cd7d0b50a7",
|
||||
"rev": "e67f2bf515343da378c3f82f098df8ca01bccc5f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -240,11 +220,11 @@
|
|||
},
|
||||
"nixos-flake": {
|
||||
"locked": {
|
||||
"lastModified": 1711376798,
|
||||
"narHash": "sha256-37wawZGSX/dD1rn7TwFJhUdpozC2VPEQXetpfpK/D+w=",
|
||||
"lastModified": 1699802281,
|
||||
"narHash": "sha256-kfR7z4so9s9vsYHT3Q9kU/GvYYCVeBsQH1h7EpSvkHg=",
|
||||
"owner": "srid",
|
||||
"repo": "nixos-flake",
|
||||
"rev": "7b19503e7f8c7cc0884fc2fbd669c0cc2e05aef5",
|
||||
"rev": "40010feda1ac1afdcc2571ef550ef3de44926b0e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -255,16 +235,16 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1713995372,
|
||||
"narHash": "sha256-fFE3M0vCoiSwCX02z8VF58jXFRj9enYUSTqjyHAjrds=",
|
||||
"lastModified": 1699994397,
|
||||
"narHash": "sha256-xxNeIcMNMXH2EA9IAX6Cny+50mvY22LhIBiGZV363gc=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "dd37924974b9202f8226ed5d74a252a9785aedf8",
|
||||
"rev": "d4b5a67bbe9ef750bd2fdffd4cad400dd5553af8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-23.11",
|
||||
"ref": "nixos-23.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
@ -288,11 +268,11 @@
|
|||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"lastModified": 1711703276,
|
||||
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
|
||||
"lastModified": 1698611440,
|
||||
"narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
|
||||
"rev": "0cbe9f69c234a7700596e943bfae7ef27a31b735",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -307,10 +287,10 @@
|
|||
"inputs": {
|
||||
"agenix": "agenix",
|
||||
"deploy-rs": "deploy-rs",
|
||||
"element-themes": "element-themes",
|
||||
"flake-parts": "flake-parts",
|
||||
"home-manager": "home-manager",
|
||||
"keycloak-theme-pub-solar": "keycloak-theme-pub-solar",
|
||||
"mastodon-fork": "mastodon-fork",
|
||||
"nix-darwin": "nix-darwin",
|
||||
"nixos-flake": "nixos-flake",
|
||||
"nixpkgs": "nixpkgs",
|
||||
|
@ -349,39 +329,9 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_3": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_4": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"triton-vmtools": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_3",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
|
@ -405,11 +355,11 @@
|
|||
},
|
||||
"unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1713895582,
|
||||
"narHash": "sha256-cfh1hi+6muQMbi9acOlju3V1gl8BEaZBXBR9jQfQi4U=",
|
||||
"lastModified": 1699781429,
|
||||
"narHash": "sha256-UYefjidASiLORAjIvVsUHG6WBtRhM67kTjEY4XfZOFs=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "572af610f6151fd41c212f897c71f7056e3fb518",
|
||||
"rev": "e44462d6021bfe23dfb24b775cc7c390844f773d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -420,15 +370,12 @@
|
|||
}
|
||||
},
|
||||
"utils": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1667395993,
|
||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
22
flake.nix
22
flake.nix
|
@ -1,15 +1,16 @@
|
|||
{
|
||||
inputs = {
|
||||
# Track channels with commits tested and built by hydra
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
|
||||
unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
mastodon-fork.url = "github:teutat3s/nixpkgs/mastodon-4.2.1";
|
||||
|
||||
nixpkgs-2205.url = "github:nixos/nixpkgs/nixos-22.05";
|
||||
|
||||
nix-darwin.url = "github:lnl7/nix-darwin/master";
|
||||
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
home-manager.url = "github:nix-community/home-manager/release-23.11";
|
||||
home-manager.url = "github:nix-community/home-manager/release-23.05";
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
|
@ -28,9 +29,6 @@
|
|||
|
||||
triton-vmtools.url = "git+https://git.pub.solar/pub-solar/infra-vintage?ref=main&dir=vmtools";
|
||||
triton-vmtools.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
element-themes.url = "github:aaronraimist/element-themes/master";
|
||||
element-themes.flake = false;
|
||||
};
|
||||
|
||||
outputs = inputs@{ self, ... }:
|
||||
|
@ -39,7 +37,7 @@
|
|||
|
||||
imports = [
|
||||
inputs.nixos-flake.flakeModule
|
||||
./logins
|
||||
./public-keys
|
||||
./lib
|
||||
./overlays
|
||||
./modules
|
||||
|
@ -63,9 +61,9 @@
|
|||
deploy-rs
|
||||
nixpkgs-fmt
|
||||
agenix
|
||||
age-plugin-yubikey
|
||||
cachix
|
||||
editorconfig-checker
|
||||
nix
|
||||
nodePackages.prettier
|
||||
nvfetcher
|
||||
shellcheck
|
||||
|
@ -73,7 +71,6 @@
|
|||
treefmt
|
||||
nixos-generators
|
||||
inputs.nixpkgs-2205.legacyPackages.${system}.terraform
|
||||
jq
|
||||
];
|
||||
};
|
||||
};
|
||||
|
@ -81,20 +78,21 @@
|
|||
flake =
|
||||
let
|
||||
username = "barkeeper";
|
||||
in
|
||||
{
|
||||
in {
|
||||
inherit username;
|
||||
|
||||
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) inputs.deploy-rs.lib;
|
||||
|
||||
deploy.nodes = self.lib.deploy.mkDeployNodes self.nixosConfigurations {
|
||||
nachtigall = {
|
||||
hostname = "10.7.6.1";
|
||||
# hostname is set in hosts/nachtigall/networking.nix
|
||||
sshUser = username;
|
||||
};
|
||||
flora-6 = {
|
||||
hostname = "10.7.6.2";
|
||||
hostname = "flora-6.pub.solar";
|
||||
sshUser = username;
|
||||
# Example
|
||||
#sshOpts = [ "-p" "19999" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
{ self, ... }:
|
||||
{
|
||||
flake = {
|
||||
nixosConfigurations = {
|
||||
nachtigall = self.nixos-flake.lib.mkLinuxSystem {
|
||||
imports = [
|
||||
self.inputs.agenix.nixosModules.default
|
||||
self.nixosModules.home-manager
|
||||
./nachtigall
|
||||
self.nixosModules.overlays
|
||||
self.nixosModules.unlock-zfs-on-boot
|
||||
self.nixosModules.core
|
||||
self.nixosModules.docker
|
||||
];
|
||||
};
|
||||
{ self, ... }:
|
||||
{
|
||||
flake = {
|
||||
nixosConfigurations = {
|
||||
nachtigall = self.nixos-flake.lib.mkLinuxSystem {
|
||||
imports = [
|
||||
self.inputs.agenix.nixosModules.default
|
||||
self.nixosModules.home-manager
|
||||
./nachtigall
|
||||
self.nixosModules.overlays
|
||||
self.nixosModules.unlock-zfs-on-boot
|
||||
self.nixosModules.core
|
||||
self.nixosModules.docker
|
||||
];
|
||||
};
|
||||
|
||||
flora-6 = self.nixos-flake.lib.mkLinuxSystem {
|
||||
imports = [
|
||||
self.inputs.agenix.nixosModules.default
|
||||
self.nixosModules.home-manager
|
||||
./flora-6
|
||||
self.nixosModules.overlays
|
||||
self.nixosModules.core
|
||||
];
|
||||
flora-6 = self.nixos-flake.lib.mkLinuxSystem {
|
||||
imports = [
|
||||
self.inputs.agenix.nixosModules.default
|
||||
self.nixosModules.home-manager
|
||||
./flora-6
|
||||
self.nixosModules.overlays
|
||||
self.nixosModules.core
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,260 +0,0 @@
|
|||
{ lib }:
|
||||
|
||||
let
|
||||
# docker's filesystems disappear quickly, leading to false positives
|
||||
deviceFilter = ''path!~"^(/var/lib/docker|/nix/store).*"'';
|
||||
in
|
||||
lib.mapAttrsToList
|
||||
(name: opts: {
|
||||
alert = name;
|
||||
expr = opts.condition;
|
||||
for = opts.time or "2m";
|
||||
labels = { };
|
||||
annotations.description = opts.description;
|
||||
})
|
||||
({
|
||||
|
||||
# prometheus_too_many_restarts = {
|
||||
# condition = ''changes(process_start_time_seconds{job=~"prometheus|alertmanager"}[15m]) > 2'';
|
||||
# description = "Prometheus has restarted more than twice in the last 15 minutes. It might be crashlooping.";
|
||||
# };
|
||||
|
||||
# alert_manager_config_not_synced = {
|
||||
# condition = ''count(count_values("config_hash", alertmanager_config_hash)) > 1'';
|
||||
# description = "Configurations of AlertManager cluster instances are out of sync.";
|
||||
# };
|
||||
|
||||
#alert_manager_e2e_dead_man_switch = {
|
||||
# condition = "vector(1)";
|
||||
# description = "Prometheus DeadManSwitch is an always-firing alert. It's used as an end-to-end test of Prometheus through the Alertmanager.";
|
||||
#};
|
||||
|
||||
# prometheus_not_connected_to_alertmanager = {
|
||||
# condition = "prometheus_notifications_alertmanagers_discovered < 1";
|
||||
# description = "Prometheus cannot connect the alertmanager\n VALUE = {{ $value }}\n LABELS = {{ $labels }}";
|
||||
# };
|
||||
|
||||
# prometheus_rule_evaluation_failures = {
|
||||
# condition = "increase(prometheus_rule_evaluation_failures_total[3m]) > 0";
|
||||
# description = "Prometheus encountered {{ $value }} rule evaluation failures, leading to potentially ignored alerts.\n VALUE = {{ $value }}\n LABELS = {{ $labels }}";
|
||||
# };
|
||||
|
||||
# prometheus_template_expansion_failures = {
|
||||
# condition = "increase(prometheus_template_text_expansion_failures_total[3m]) > 0";
|
||||
# time = "0m";
|
||||
# description = "Prometheus encountered {{ $value }} template text expansion failures\n VALUE = {{ $value }}\n LABELS = {{ $labels }}";
|
||||
# };
|
||||
|
||||
# promtail_file_lagging = {
|
||||
# condition = ''abs(promtail_file_bytes_total - promtail_read_bytes_total) > 1e6'';
|
||||
# time = "15m";
|
||||
# description = ''{{ $labels.instance }} {{ $labels.job }} {{ $labels.path }} has been lagging by more than 1MB for more than 15m.'';
|
||||
# };
|
||||
|
||||
filesystem_full_80percent = {
|
||||
condition = ''
|
||||
100 - ((node_filesystem_avail_bytes{fstype!="rootfs",mountpoint="/"} * 100) / node_filesystem_size_bytes{fstype!="rootfs",mountpoint="/"}) > 80'';
|
||||
time = "10m";
|
||||
description =
|
||||
"{{$labels.instance}} device {{$labels.device}} on {{$labels.mountpoint}} got less than 20% space left on its filesystem.";
|
||||
};
|
||||
|
||||
# filesystem_inodes_full = {
|
||||
# condition = ''disk_inodes_free / disk_inodes_total < 0.10'';
|
||||
# time = "10m";
|
||||
# description = "{{$labels.instance}} device {{$labels.device}} on {{$labels.mountpoint}} got less than 10% inodes left on its filesystem.";
|
||||
# };
|
||||
|
||||
# daily_task_not_run = {
|
||||
# # give 6 hours grace period
|
||||
# condition = ''time() - task_last_run{state="ok",frequency="daily"} > (24 + 6) * 60 * 60'';
|
||||
# description = "{{$labels.instance}}: {{$labels.name}} was not run in the last 24h";
|
||||
# };
|
||||
|
||||
# daily_task_failed = {
|
||||
# condition = ''task_last_run{state="fail"}'';
|
||||
# description = "{{$labels.instance}}: {{$labels.name}} failed to run";
|
||||
# };
|
||||
# } // (lib.genAttrs [
|
||||
# "borgbackup-turingmachine"
|
||||
# "borgbackup-eve"
|
||||
# "borgbackup-datastore"
|
||||
# ]
|
||||
# (name: {
|
||||
# condition = ''absent_over_time(task_last_run{name="${name}"}[1d])'';
|
||||
# description = "status of ${name} is unknown: no data for a day";
|
||||
# }))
|
||||
# // {
|
||||
|
||||
# borgbackup_matchbox_not_run = {
|
||||
# # give 6 hours grace period
|
||||
# condition = ''time() - task_last_run{state="ok",frequency="daily",name="borgbackup-matchbox"} > 7 * 24 * 60 * 60'';
|
||||
# description = "{{$labels.instance}}: {{$labels.name}} was not run in the last week";
|
||||
# };
|
||||
|
||||
# borgbackup_matchbox = {
|
||||
# condition = ''absent_over_time(task_last_run{name="borgbackup-matchbox"}[7d])'';
|
||||
# description = "status of borgbackup-matchbox is unknown: no data for a week";
|
||||
# };
|
||||
|
||||
# homeassistant = {
|
||||
# condition = ''
|
||||
# homeassistant_entity_available{domain="persistent_notification", entity!="persistent_notification.http_login"} >= 0'';
|
||||
# description =
|
||||
# "homeassistant notification {{$labels.entity}} ({{$labels.friendly_name}}): {{$value}}";
|
||||
# };
|
||||
|
||||
swap_using_20percent = {
|
||||
condition =
|
||||
"node_memory_SwapTotal_bytes - (node_memory_SwapCached_bytes + node_memory_SwapFree_bytes) > node_memory_SwapTotal_bytes * 0.2";
|
||||
time = "30m";
|
||||
description =
|
||||
"{{$labels.instance}} is using 20% of its swap space for at least 30 minutes.";
|
||||
};
|
||||
|
||||
systemd_service_failed = {
|
||||
condition = ''node_systemd_unit_state{state="failed"} == 1'';
|
||||
description =
|
||||
"{{$labels.instance}} failed to (re)start service {{$labels.name}}.";
|
||||
};
|
||||
|
||||
restic_backup_too_old = {
|
||||
condition = ''(time() - restic_snapshots_latest_time)/(60*60) > 24'';
|
||||
description = "{{$labels.instance}} not backed up for more than 24 hours. ({{$value}})";
|
||||
};
|
||||
|
||||
host_down = {
|
||||
condition = ''up{job="node-stats", instance!~"ahorn.wireguard:9100|kartoffel.wireguard:9100|mega.wireguard:9100"} == 0'';
|
||||
description = "{{$labels.instance}} is down!";
|
||||
};
|
||||
|
||||
# service_not_running = {
|
||||
# condition = ''systemd_units_active_code{name=~"teamspeak3-server.service|tt-rss.service", sub!="running"}'';
|
||||
# description = "{{$labels.instance}} should have a running {{$labels.name}}.";
|
||||
# };
|
||||
|
||||
ram_using_90percent = {
|
||||
condition =
|
||||
"node_memory_Buffers_bytes + node_memory_MemFree_bytes + node_memory_Cached_bytes < node_memory_MemTotal_bytes * 0.1";
|
||||
time = "1h";
|
||||
description =
|
||||
"{{$labels.instance}} is using at least 90% of its RAM for at least 1 hour.";
|
||||
};
|
||||
|
||||
cpu_using_90percent = {
|
||||
condition = ''
|
||||
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) >= 90'';
|
||||
time = "10m";
|
||||
description =
|
||||
"{{$labels.instance}} is running with cpu usage > 90% for at least 10 minutes: {{$value}}";
|
||||
};
|
||||
|
||||
reboot = {
|
||||
condition = "node_boot_time_seconds < 300";
|
||||
description = "{{$labels.instance}} just rebooted.";
|
||||
};
|
||||
|
||||
uptime = {
|
||||
condition = "(time() - node_boot_time_seconds ) / (60*60*24) > 30";
|
||||
description =
|
||||
"Uptime monster: {{$labels.instance}} has been up for more than 30 days.";
|
||||
};
|
||||
|
||||
flake_nixpkgs_outdated = {
|
||||
condition = ''
|
||||
(time() - flake_input_last_modified{input="nixpkgs"}) / (60*60*24) > 30'';
|
||||
description =
|
||||
"Nixpkgs outdated: Nixpkgs on {{$labels.instance}} has not been updated in 30 days";
|
||||
};
|
||||
|
||||
/* ping = {
|
||||
condition = "ping_result_code{type!='mobile'} != 0";
|
||||
description = "{{$labels.url}}: ping from {{$labels.instance}} has failed!";
|
||||
};
|
||||
|
||||
ping_high_latency = {
|
||||
condition = "ping_average_response_ms{type!='mobile'} > 5000";
|
||||
description = "{{$labels.instance}}: ping probe from {{$labels.source}} is encountering high latency!";
|
||||
};
|
||||
*/
|
||||
http_status = {
|
||||
condition = ''
|
||||
probe_http_status_code{instance!~"https://megaclan3000.de"} != 200'';
|
||||
description =
|
||||
"http request failed from {{$labels.instance}}: {{$labels.result}}!";
|
||||
};
|
||||
/* http_match_failed = {
|
||||
condition = "http_response_response_string_match == 0";
|
||||
description = "{{$labels.server}} : http body not as expected; status code: {{$labels.status_code}}!";
|
||||
};
|
||||
dns_query = {
|
||||
condition = "dns_query_result_code != 0";
|
||||
description = "{{$labels.domain}} : could retrieve A record {{$labels.instance}} from server {{$labels.server}}: {{$labels.result}}!";
|
||||
};
|
||||
secure_dns_query = {
|
||||
condition = "secure_dns_state != 0";
|
||||
description = "{{$labels.domain}} : could retrieve A record {{$labels.instance}} from server {{$labels.server}}: {{$labels.result}} for protocol {{$labels.protocol}}!";
|
||||
};
|
||||
connection_failed = {
|
||||
condition = "net_response_result_code != 0";
|
||||
description = "{{$labels.server}}: connection to {{$labels.port}}({{$labels.protocol}}) failed from {{$labels.instance}}";
|
||||
};
|
||||
healthchecks = {
|
||||
condition = "hc_check_up == 0";
|
||||
description = "{{$labels.instance}}: healtcheck {{$labels.job}} fails!";
|
||||
};
|
||||
*/
|
||||
cert_expiry = {
|
||||
condition = "(probe_ssl_earliest_cert_expiry - time())/(3600*24) < 30";
|
||||
description =
|
||||
"{{$labels.instance}}: The TLS certificate will expire in less than 30 days: {{$value}}s";
|
||||
};
|
||||
|
||||
# ignore devices that disabled S.M.A.R.T (example if attached via USB)
|
||||
|
||||
# smart_errors = {
|
||||
# condition = ''smart_device_health_ok{enabled!="Disabled"} != 1'';
|
||||
# description =
|
||||
# "{{$labels.instance}}: S.M.A.R.T reports: {{$labels.device}} ({{$labels.model}}) has errors.";
|
||||
# };
|
||||
|
||||
oom_kills = {
|
||||
condition = "increase(node_vmstat_oom_kill[5m]) > 0";
|
||||
description = "{{$labels.instance}}: OOM kill detected";
|
||||
};
|
||||
|
||||
/* unusual_disk_read_latency = {
|
||||
condition =
|
||||
"rate(diskio_read_time[1m]) / rate(diskio_reads[1m]) > 0.1 and rate(diskio_reads[1m]) > 0";
|
||||
description = ''
|
||||
{{$labels.instance}}: Disk latency is growing (read operations > 100ms)
|
||||
'';
|
||||
};
|
||||
|
||||
unusual_disk_write_latency = {
|
||||
condition =
|
||||
"rate(diskio_write_time[1m]) / rate(diskio_write[1m]) > 0.1 and rate(diskio_write[1m]) > 0";
|
||||
description = ''
|
||||
{{$labels.instance}}: Disk latency is growing (write operations > 100ms)
|
||||
'';
|
||||
};
|
||||
*/
|
||||
|
||||
host_memory_under_memory_pressure = {
|
||||
condition = "rate(node_vmstat_pgmajfault[1m]) > 1000";
|
||||
description =
|
||||
"{{$labels.instance}}: The node is under heavy memory pressure. High rate of major page faults: {{$value}}";
|
||||
};
|
||||
|
||||
# ext4_errors = {
|
||||
# condition = "ext4_errors_value > 0";
|
||||
# description =
|
||||
# "{{$labels.instance}}: ext4 has reported {{$value}} I/O errors: check /sys/fs/ext4/*/errors_count";
|
||||
# };
|
||||
|
||||
# alerts_silences_changed = {
|
||||
# condition = ''abs(delta(alertmanager_silences{state="active"}[1h])) >= 1'';
|
||||
# description =
|
||||
# "alertmanager: number of active silences has changed: {{$value}}";
|
||||
# };
|
||||
})
|
|
@ -1,8 +1,9 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
flake,
|
||||
...
|
||||
}:
|
||||
{
|
||||
systemd.tmpfiles.rules = [
|
||||
|
@ -26,33 +27,6 @@
|
|||
reverse_proxy :4000
|
||||
'';
|
||||
};
|
||||
"flora-6.pub.solar" = {
|
||||
logFormat = lib.mkForce ''
|
||||
output discard
|
||||
'';
|
||||
extraConfig = ''
|
||||
basicauth * {
|
||||
hakkonaut $2a$14$mmIAy/Ezm6YGohUtXa2mWeW6Bcw1MQXPhrRbz14jAD2iUu3oob/t.
|
||||
}
|
||||
reverse_proxy :${toString config.services.loki.configuration.server.http_listen_port}
|
||||
'';
|
||||
};
|
||||
"alerts.pub.solar" = {
|
||||
logFormat = lib.mkForce ''
|
||||
output discard
|
||||
'';
|
||||
extraConfig = ''
|
||||
reverse_proxy 10.7.6.2:${toString config.services.prometheus.alertmanager.port}
|
||||
'';
|
||||
};
|
||||
"grafana.pub.solar" = {
|
||||
logFormat = lib.mkForce ''
|
||||
output discard
|
||||
'';
|
||||
extraConfig = ''
|
||||
reverse_proxy :${toString config.services.grafana.settings.server.http_port}
|
||||
'';
|
||||
};
|
||||
"obs-portal.pub.solar" = {
|
||||
logFormat = lib.mkForce ''
|
||||
output discard
|
||||
|
@ -63,5 +37,5 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
flake,
|
||||
...
|
||||
}: {
|
||||
age.secrets.drone-secrets = {
|
||||
file = "${flake.self}/secrets/drone-secrets.age";
|
||||
|
@ -24,24 +25,22 @@
|
|||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.drone = { };
|
||||
users.groups.drone = {};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '/var/lib/drone-db' 0750 drone drone - -"
|
||||
];
|
||||
|
||||
systemd.services."docker-network-drone" =
|
||||
let
|
||||
docker = config.virtualisation.oci-containers.backend;
|
||||
dockerBin = "${pkgs.${docker}}/bin/${docker}";
|
||||
in
|
||||
{
|
||||
serviceConfig.Type = "oneshot";
|
||||
before = [ "docker-drone-server.service" ];
|
||||
script = ''
|
||||
${dockerBin} network inspect drone-net >/dev/null 2>&1 || ${dockerBin} network create drone-net --subnet 172.20.0.0/24
|
||||
'';
|
||||
};
|
||||
systemd.services."docker-network-drone" = let
|
||||
docker = config.virtualisation.oci-containers.backend;
|
||||
dockerBin = "${pkgs.${docker}}/bin/${docker}";
|
||||
in {
|
||||
serviceConfig.Type = "oneshot";
|
||||
before = ["docker-drone-server.service"];
|
||||
script = ''
|
||||
${dockerBin} network inspect drone-net >/dev/null 2>&1 || ${dockerBin} network create drone-net --subnet 172.20.0.0/24
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation = {
|
||||
docker = {
|
||||
|
@ -72,13 +71,12 @@
|
|||
autoStart = true;
|
||||
user = "994";
|
||||
ports = [
|
||||
"127.0.0.1:4000:80"
|
||||
"4000:80"
|
||||
];
|
||||
dependsOn = [ "drone-db" ];
|
||||
dependsOn = ["drone-db"];
|
||||
extraOptions = [
|
||||
"--network=drone-net"
|
||||
"--pull=always"
|
||||
"--add-host=nachtigall.pub.solar:10.7.6.1"
|
||||
];
|
||||
environment = {
|
||||
DRONE_GITEA_SERVER = "https://git.pub.solar";
|
||||
|
@ -98,11 +96,10 @@
|
|||
volumes = [
|
||||
"/var/run/docker.sock:/var/run/docker.sock"
|
||||
];
|
||||
dependsOn = [ "drone-db" ];
|
||||
dependsOn = ["drone-db"];
|
||||
extraOptions = [
|
||||
"--network=drone-net"
|
||||
"--pull=always"
|
||||
"--add-host=nachtigall.pub.solar:10.7.6.1"
|
||||
];
|
||||
environment = {
|
||||
DRONE_RPC_HOST = "ci.pub.solar";
|
||||
|
|
|
@ -1,60 +1,30 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
flake,
|
||||
...
|
||||
}: {
|
||||
age.secrets.forgejo-actions-runner-token = {
|
||||
file = "${flake.self}/secrets/forgejo-actions-runner-token.age";
|
||||
mode = "644";
|
||||
};
|
||||
|
||||
# Trust docker bridge interface traffic
|
||||
# Needed for the docker runner to communicate with the act_runner cache
|
||||
networking.firewall.trustedInterfaces = [ "br-+" ];
|
||||
|
||||
users.users.gitea-runner = {
|
||||
home = "/var/lib/gitea-runner/flora-6";
|
||||
useDefaultShell = true;
|
||||
group = "gitea-runner";
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.gitea-runner = {};
|
||||
|
||||
systemd.services."gitea-runner-flora\\x2d6".serviceConfig = {
|
||||
DynamicUser = lib.mkForce false;
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '/data/gitea-actions-runner' 0750 gitea-runner gitea-runner - -"
|
||||
"d '/var/lib/gitea-runner' 0750 gitea-runner gitea-runner - -"
|
||||
];
|
||||
|
||||
# forgejo actions runner
|
||||
# https://forgejo.org/docs/latest/admin/actions/
|
||||
# https://docs.gitea.com/usage/actions/quickstart
|
||||
services.gitea-actions-runner = {
|
||||
package = pkgs.forgejo-runner;
|
||||
package = pkgs.forgejo-actions-runner;
|
||||
instances."flora-6" = {
|
||||
enable = true;
|
||||
name = config.networking.hostName;
|
||||
url = "https://git.pub.solar";
|
||||
tokenFile = config.age.secrets.forgejo-actions-runner-token.path;
|
||||
settings = {
|
||||
cache = {
|
||||
enabled = true;
|
||||
dir = "/data/gitea-actions-runner/actcache";
|
||||
host = "";
|
||||
port = 0;
|
||||
external_server = "";
|
||||
};
|
||||
};
|
||||
labels = [
|
||||
# provide a debian 12 bookworm base with Node.js for actions
|
||||
"debian-latest:docker://git.pub.solar/pub-solar/actions-base-image:20-bookworm"
|
||||
"debian-latest:docker://node:20-bookworm"
|
||||
# fake the ubuntu name, commonly used in actions examples
|
||||
"ubuntu-latest:docker://git.pub.solar/pub-solar/actions-base-image:20-bookworm"
|
||||
"ubuntu-latest:docker://node:20-bookworm"
|
||||
# alpine with Node.js
|
||||
"alpine-latest:docker://node:20-alpine"
|
||||
# nix flakes enabled image with Node.js
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,112 +0,0 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
}: {
|
||||
age.secrets.grafana-admin-password = {
|
||||
file = "${flake.self}/secrets/grafana-admin-password.age";
|
||||
mode = "644";
|
||||
owner = "grafana";
|
||||
};
|
||||
age.secrets.grafana-smtp-password = {
|
||||
file = "${flake.self}/secrets/grafana-smtp-password.age";
|
||||
mode = "644";
|
||||
owner = "grafana";
|
||||
};
|
||||
age.secrets.grafana-keycloak-client-secret = {
|
||||
file = "${flake.self}/secrets/grafana-keycloak-client-secret.age";
|
||||
mode = "644";
|
||||
owner = "grafana";
|
||||
};
|
||||
|
||||
environment.etc = {
|
||||
"grafana-dashboards/node-exporter-full_rev33.json" = {
|
||||
source = ./grafana-dashboards/node-exporter-full_rev33.json;
|
||||
group = "grafana";
|
||||
user = "grafana";
|
||||
};
|
||||
"grafana-dashboards/synapse.json" = {
|
||||
source = ./grafana-dashboards/synapse.json;
|
||||
group = "grafana";
|
||||
user = "grafana";
|
||||
};
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
# Listening Address
|
||||
http_addr = "127.0.0.1";
|
||||
# and Port
|
||||
http_port = 3000;
|
||||
# Grafana needs to know on which domain and URL it's running
|
||||
domain = "grafana.pub.solar";
|
||||
root_url = "https://grafana.pub.solar";
|
||||
enable_gzip = true;
|
||||
};
|
||||
smtp = {
|
||||
enabled = true;
|
||||
host = "mail.greenbaum.zone:465";
|
||||
user = "admins@pub.solar";
|
||||
password = "\$__file{${config.age.secrets.grafana-smtp-password.path}}";
|
||||
from_address = "no-reply@pub.solar";
|
||||
from_name = "grafana.pub.solar";
|
||||
ehlo_identity = "flora-6.pub.solar";
|
||||
};
|
||||
security = {
|
||||
admin_email = "crew@pub.solar";
|
||||
admin_password = "\$__file{${config.age.secrets.grafana-admin-password.path}}";
|
||||
};
|
||||
"auth.generic_oauth" = {
|
||||
enabled = true;
|
||||
name = "pub.solar ID";
|
||||
allow_sign_up = true;
|
||||
client_id = "grafana";
|
||||
client_secret = "\$__file{${config.age.secrets.grafana-keycloak-client-secret.path}}";
|
||||
scopes = "openid email profile offline_access roles";
|
||||
email_attribute_path = "email";
|
||||
login_attribute_path = "preferred_username";
|
||||
name_attribute_path = "full_name";
|
||||
auth_url = "https://auth.pub.solar/realms/pub.solar/protocol/openid-connect/auth";
|
||||
token_url = "https://auth.pub.solar/realms/pub.solar/protocol/openid-connect/token";
|
||||
api_url = "https://auth.pub.solar/realms/pub.solar/protocol/openid-connect/userinfo";
|
||||
role_attribute_path = "contains(roles[*], 'admin') && 'GrafanaAdmin' || 'Viewer'";
|
||||
allow_assign_grafana_admin = true;
|
||||
};
|
||||
};
|
||||
provision = {
|
||||
enable = true;
|
||||
datasources = {
|
||||
settings = {
|
||||
datasources = [
|
||||
{
|
||||
name = "Prometheus";
|
||||
type = "prometheus";
|
||||
access = "proxy";
|
||||
url = "http://127.0.0.1:${toString config.services.prometheus.port}";
|
||||
isDefault = true;
|
||||
}
|
||||
{
|
||||
name = "Loki";
|
||||
type = "loki";
|
||||
access = "proxy";
|
||||
url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
dashboards = {
|
||||
settings = {
|
||||
providers = [
|
||||
{
|
||||
name = "pub.solar Dashboards";
|
||||
options.path = "/etc/grafana-dashboards";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
}: {
|
||||
# source: https://gist.github.com/rickhull/895b0cb38fdd537c1078a858cf15d63e
|
||||
# https://grafana.com/docs/loki/latest/configure/examples/#1-local-configuration-exampleyaml
|
||||
services.loki = {
|
||||
enable = true;
|
||||
configuration = {
|
||||
server.http_listen_port = 3100;
|
||||
auth_enabled = false;
|
||||
common = {
|
||||
ring = {
|
||||
instance_addr = "127.0.0.1";
|
||||
kvstore = {
|
||||
store = "inmemory";
|
||||
};
|
||||
};
|
||||
replication_factor = 1;
|
||||
path_prefix = "/var/lib/loki";
|
||||
storage = {
|
||||
filesystem = {
|
||||
chunks_directory = "chunks/";
|
||||
rules_directory = "rules/";
|
||||
};
|
||||
};
|
||||
};
|
||||
# Keep logs for 4 weeks
|
||||
# https://grafana.com/docs/loki/latest/operations/storage/retention/
|
||||
limits_config.retention_period = "4w";
|
||||
compactor = {
|
||||
shared_store = "filesystem";
|
||||
compaction_interval = "10m";
|
||||
retention_enabled = true;
|
||||
retention_delete_delay = "2h";
|
||||
retention_delete_worker_count = 150;
|
||||
};
|
||||
schema_config = {
|
||||
configs = [{
|
||||
from = "2020-05-15";
|
||||
store = "boltdb-shipper";
|
||||
object_store = "filesystem";
|
||||
schema = "v11";
|
||||
index = {
|
||||
prefix = "index_";
|
||||
period = "24h";
|
||||
};
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.promtail = {
|
||||
enable = true;
|
||||
configuration = {
|
||||
server = {
|
||||
http_listen_port = 9080;
|
||||
grpc_listen_port = 0;
|
||||
};
|
||||
positions = {
|
||||
filename = "/tmp/positions.yaml";
|
||||
};
|
||||
clients = [{
|
||||
url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
|
||||
}];
|
||||
scrape_configs = [{
|
||||
job_name = "journal";
|
||||
journal = {
|
||||
max_age = "24h";
|
||||
labels = {
|
||||
job = "systemd-journal";
|
||||
host = "flora-6";
|
||||
};
|
||||
};
|
||||
relabel_configs = [{
|
||||
source_labels = [ "__journal__systemd_unit" ];
|
||||
target_label = "unit";
|
||||
}];
|
||||
}];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
}: {
|
||||
age.secrets.nachtigall-metrics-prometheus-basic-auth-password = {
|
||||
file = "${flake.self}/secrets/nachtigall-metrics-prometheus-basic-auth-password.age";
|
||||
mode = "600";
|
||||
owner = "prometheus";
|
||||
};
|
||||
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
port = 9001;
|
||||
exporters = {
|
||||
node = {
|
||||
enable = true;
|
||||
enabledCollectors = [ "systemd" ];
|
||||
port = 9002;
|
||||
};
|
||||
};
|
||||
globalConfig = {
|
||||
scrape_interval = "10s";
|
||||
scrape_timeout = "9s";
|
||||
};
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "node-exporter-http";
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
|
||||
labels = {
|
||||
instance = "flora-6";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
job_name = "node-exporter-https";
|
||||
scheme = "https";
|
||||
metrics_path = "/metrics";
|
||||
basic_auth = {
|
||||
username = "hakkonaut";
|
||||
password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}";
|
||||
};
|
||||
static_configs = [{
|
||||
targets = [ "nachtigall.pub.solar" ];
|
||||
labels = {
|
||||
instance = "nachtigall";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
job_name = "matrix-synapse";
|
||||
scheme = "https";
|
||||
metrics_path = "/_synapse/metrics";
|
||||
basic_auth = {
|
||||
username = "hakkonaut";
|
||||
password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}";
|
||||
};
|
||||
static_configs = [{
|
||||
targets = [ "nachtigall.pub.solar" ];
|
||||
labels = {
|
||||
instance = "nachtigall";
|
||||
};
|
||||
}];
|
||||
}
|
||||
];
|
||||
|
||||
ruleFiles = [
|
||||
(pkgs.writeText "prometheus-rules.yml" (builtins.toJSON {
|
||||
groups = [{
|
||||
name = "alerting-rules";
|
||||
rules = import ./alert-rules.nix { inherit lib; };
|
||||
}];
|
||||
}))
|
||||
];
|
||||
|
||||
alertmanagers = [{ static_configs = [{ targets = [ "localhost:9093" ]; }]; }];
|
||||
|
||||
alertmanager = {
|
||||
enable = true;
|
||||
# port = 9093; # Default
|
||||
webExternalUrl = "https://alerts.pub.solar"; # TODO use a proper url?
|
||||
# environmentFile = "${config.age.secrets.nachtigall-alertmanager-envfile.path}";
|
||||
configuration = {
|
||||
|
||||
route = {
|
||||
receiver = "all";
|
||||
group_by = [ "instance" ];
|
||||
group_wait = "30s";
|
||||
group_interval = "2m";
|
||||
repeat_interval = "24h";
|
||||
};
|
||||
|
||||
receivers = [{
|
||||
name = "all";
|
||||
# Email config documentation: https://prometheus.io/docs/alerting/latest/configuration/#email_config
|
||||
email_configs = [{
|
||||
send_resolved = true;
|
||||
to = "TODO";
|
||||
from = "alerts@pub.solar";
|
||||
smarthost = "TODO";
|
||||
auth_username = "TODO";
|
||||
auth_password_file = "${config.age.secrets.nachtigall-alertmanager-smtp-password.path}";
|
||||
require_tls = true;
|
||||
}];
|
||||
# TODO:
|
||||
# For matrix notifications, look into: https://github.com/pinpox/matrix-hook and add a webhook
|
||||
# webhook_configs = [ { url = "http://127.0.0.1:11000/alert"; } ];
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,13 +1,21 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
psCfg = config.pub-solar;
|
||||
in
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
flake,
|
||||
...
|
||||
}: let
|
||||
psCfg = config.pub-solar;
|
||||
in {
|
||||
imports = [
|
||||
"${flake.inputs.unstable}/nixos/modules/services/continuous-integration/gitea-actions-runner.nix"
|
||||
"${flake.inputs.unstable}/nixos/modules/services/web-servers/caddy/default.nix"
|
||||
];
|
||||
disabledModules = [
|
||||
"services/continuous-integration/gitea-actions-runner.nix"
|
||||
"services/web-servers/caddy/default.nix"
|
||||
];
|
||||
|
||||
config = {
|
||||
# Override nix.conf for more agressive garbage collection
|
||||
nix.extraOptions = lib.mkForce ''
|
||||
|
@ -30,14 +38,6 @@ in
|
|||
# Force getting the hostname from cloud-init
|
||||
networking.hostName = lib.mkDefault "";
|
||||
|
||||
# We use cloud-init to configure networking, this option should fix
|
||||
# systemd-networkd-wait-online timeouts
|
||||
#systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
systemd.network.wait-online.ignoredInterfaces = [
|
||||
"docker0"
|
||||
"wg-ssh"
|
||||
];
|
||||
|
||||
# List services that you want to enable:
|
||||
services.cloud-init.enable = true;
|
||||
services.cloud-init.ext4.enable = true;
|
||||
|
|
|
@ -2,19 +2,14 @@
|
|||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
# Include the results of the hardware scan.
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
./configuration.nix
|
||||
./triton-vmtools.nix
|
||||
./wireguard.nix
|
||||
|
||||
./apps/caddy.nix
|
||||
|
||||
./apps/drone.nix
|
||||
./apps/forgejo-actions-runner.nix
|
||||
./apps/grafana.nix
|
||||
./apps/prometheus.nix
|
||||
./apps/loki.nix
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, modulesPath
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [ ];
|
||||
imports = [];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ahci" "virtio_pci" "xhci_pci" "sr_mod" "virtio_blk" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot.initrd.availableKernelModules = ["ahci" "virtio_pci" "xhci_pci" "sr_mod" "virtio_blk"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = [];
|
||||
boot.extraModulePackages = [];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-label/nixos";
|
||||
|
@ -34,7 +35,7 @@
|
|||
];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
swapDevices = [];
|
||||
|
||||
networking.useDHCP = lib.mkDefault false;
|
||||
networking.networkmanager.enable = lib.mkForce false;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{ pkgs
|
||||
, flake
|
||||
, ...
|
||||
{
|
||||
pkgs,
|
||||
flake,
|
||||
...
|
||||
}: {
|
||||
environment.systemPackages = with pkgs; [
|
||||
flake.inputs.triton-vmtools.packages.${pkgs.system}.default
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
flake,
|
||||
... }:
|
||||
{
|
||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
||||
|
||||
age.secrets.wg-private-key.file = "${flake.self}/secrets/flora6-wg-private-key.age";
|
||||
|
||||
networking.wireguard.interfaces = {
|
||||
wg-ssh = {
|
||||
listenPort = 51820;
|
||||
mtu = 1300;
|
||||
ips = [
|
||||
"10.7.6.2/32"
|
||||
"fd00:fae:fae:fae:fae:2::/96"
|
||||
];
|
||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
||||
peers = flake.self.logins.admins.wireguardDevices ++ [
|
||||
{ # nachtigall.pub.solar
|
||||
endpoint = "138.201.80.102:51820";
|
||||
publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk=";
|
||||
allowedIPs = [ "10.7.6.1/32" "fd00:fae:fae:fae:fae:1::/96" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.openssh.listenAddresses = [
|
||||
{
|
||||
addr = "10.7.6.2";
|
||||
port = 22;
|
||||
}
|
||||
{
|
||||
addr = "[fd00:fae:fae:fae:fae:2::]";
|
||||
port = 22;
|
||||
}
|
||||
];
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, self
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
self,
|
||||
...
|
||||
}: {
|
||||
services.nginx.virtualHosts."collabora.pub.solar" = {
|
||||
enableACME = true;
|
||||
|
@ -14,7 +15,7 @@
|
|||
proxy_pass http://127.0.0.1:9980;
|
||||
proxy_set_header Host $host;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation = {
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
{ flake, config, lib, ... }:
|
||||
{
|
||||
age.secrets."coturn-static-auth-secret" = {
|
||||
file = "${flake.self}/secrets/coturn-static-auth-secret.age";
|
||||
mode = "400";
|
||||
owner = "turnserver";
|
||||
};
|
||||
|
||||
services.coturn = rec {
|
||||
enable = true;
|
||||
no-cli = true;
|
||||
no-tcp-relay = true;
|
||||
min-port = 49000;
|
||||
max-port = 50000;
|
||||
use-auth-secret = true;
|
||||
static-auth-secret-file = "/run/agenix/coturn-static-auth-secret";
|
||||
realm = "turn.pub.solar";
|
||||
cert = "${config.security.acme.certs.${realm}.directory}/full.pem";
|
||||
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
|
||||
extraConfig =
|
||||
let
|
||||
externalIPv4s = lib.strings.concatMapStringsSep "\n" ({ address, ... }: "external-ip=${address}") config.networking.interfaces.enp35s0.ipv4.addresses;
|
||||
externalIPv6s = lib.strings.concatMapStringsSep "\n" ({ address, ... }: "external-ip=${address}") config.networking.interfaces.enp35s0.ipv6.addresses;
|
||||
in
|
||||
''
|
||||
${externalIPv4s}
|
||||
${externalIPv6s}
|
||||
|
||||
no-tlsv1
|
||||
no-tlsv1_1
|
||||
|
||||
no-rfc5780
|
||||
response-origin-only-with-rfc5780
|
||||
|
||||
prod
|
||||
|
||||
no-stun-backward-compatibility
|
||||
|
||||
# ban private IP ranges
|
||||
no-multicast-peers
|
||||
denied-peer-ip=0.0.0.0-0.255.255.255
|
||||
denied-peer-ip=10.0.0.0-10.255.255.255
|
||||
denied-peer-ip=100.64.0.0-100.127.255.255
|
||||
denied-peer-ip=127.0.0.0-127.255.255.255
|
||||
denied-peer-ip=169.254.0.0-169.254.255.255
|
||||
denied-peer-ip=172.16.0.0-172.31.255.255
|
||||
denied-peer-ip=192.0.0.0-192.0.0.255
|
||||
denied-peer-ip=192.0.2.0-192.0.2.255
|
||||
denied-peer-ip=192.88.99.0-192.88.99.255
|
||||
denied-peer-ip=192.168.0.0-192.168.255.255
|
||||
denied-peer-ip=198.18.0.0-198.19.255.255
|
||||
denied-peer-ip=198.51.100.0-198.51.100.255
|
||||
denied-peer-ip=203.0.113.0-203.0.113.255
|
||||
denied-peer-ip=240.0.0.0-255.255.255.255
|
||||
denied-peer-ip=::1
|
||||
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
|
||||
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
|
||||
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
|
||||
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
interfaces.enp35s0 =
|
||||
let
|
||||
range = with config.services.coturn; [{
|
||||
from = min-port;
|
||||
to = max-port;
|
||||
}];
|
||||
in
|
||||
{
|
||||
allowedUDPPortRanges = range;
|
||||
allowedUDPPorts = [ 3478 5349 ];
|
||||
allowedTCPPortRanges = [ ];
|
||||
allowedTCPPorts = [ 3478 5349 ];
|
||||
};
|
||||
};
|
||||
|
||||
# get a certificate
|
||||
security.acme.certs.${config.services.coturn.realm} = {
|
||||
/* insert here the right configuration to obtain a certificate */
|
||||
postRun = "systemctl restart coturn.service";
|
||||
group = "turnserver";
|
||||
};
|
||||
services.nginx.virtualHosts.${config.services.coturn.realm} = {
|
||||
enableACME = true;
|
||||
addSSL = true;
|
||||
globalRedirect = "pub.solar";
|
||||
};
|
||||
|
||||
users.users.nginx.extraGroups = [ "turnserver" ];
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
flake,
|
||||
...
|
||||
}: {
|
||||
age.secrets.forgejo-database-password = {
|
||||
file = "${flake.self}/secrets/forgejo-database-password.age";
|
||||
|
@ -16,25 +17,12 @@
|
|||
owner = "gitea";
|
||||
};
|
||||
|
||||
age.secrets.forgejo-ssh-private-key = {
|
||||
file = "${flake.self}/secrets/forgejo-ssh-private-key.age";
|
||||
mode = "600";
|
||||
owner = "gitea";
|
||||
path = "/etc/forgejo/ssh/id_forgejo";
|
||||
};
|
||||
|
||||
environment.etc."forgejo/ssh/id_forgejo.pub" = {
|
||||
text = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCkPjvF2tZ2lZtkXed6lBvaPUpsNrI5kHlCNEf4LyFtgFXHoUL8UD3Bz9Fn1S+SDkdBMw/SumjvUf7TEGqQqzmFbG7+nWdWg2L00VdN8Kp8W+kKPBByJrzjDUIGhIMt7obaZnlSAVO5Cdqc1Q6bA9POLjSHIBxSD3QUs2pjUCkciNcEtL93easuXnlMwoYa217n5sA8n+BZmOJAcmA/UxYvKsqYlpJxa44m8JgMTy+5L08i/zkx9/FwniOcKcLedxmjZfV8raitDy34LslT2nBNG4I+em7qhKhSScn/cfyPvARiK71pk/rTx9mxBEjcGAkp3+hiA3Nyms0h/qTUh8yGyhbOn8hiro34HEKswXDN1HRfseyyZ4TqOoIC07F53x4OliYA0B+QbvwOemTX2XAWHfU4xEYrIhR46o3Eu5ooOM9HZLLYzIzKjsj/rpuKalFZ+9IeT/PJ/DrbgOEBlJGTu4XucEYXSiIvWB7G9WXij7TXKYbsRAFho9jw+9UZWklFAh9dcUKlX9YxafxOrw9DhJK620hblHLY9wPPFCbZVXDGfqdtn+ncRReMAw6N3VYqxMgnxd+OC52SMsSUi9VaL26i2UvEBwNYuim8GDnVabu/ciQLHMgifBONuF9sKD58ee5nnKgtYLDy9zU86aHBU78Ijew+WhYitO7qejMHMQ==";
|
||||
mode = "600";
|
||||
user = "gitea";
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."git.pub.solar" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/user/login".extraConfig = ''
|
||||
return 302 /user/oauth2/keycloak;
|
||||
return 302 /user/oauth2/keycloak;
|
||||
'';
|
||||
|
||||
locations."/" = {
|
||||
|
@ -45,69 +33,41 @@
|
|||
};
|
||||
};
|
||||
|
||||
users.users.gitea = {
|
||||
home = "/var/lib/forgejo";
|
||||
useDefaultShell = true;
|
||||
group = "gitea";
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.gitea = {};
|
||||
|
||||
# Expose SSH port only for forgejo SSH
|
||||
networking.firewall.interfaces.enp35s0.allowedTCPPorts = [ 2223 ];
|
||||
networking.firewall.extraCommands = ''
|
||||
iptables -t nat -i enp35s0 -I PREROUTING -p tcp --dport 22 -j REDIRECT --to-ports 2223
|
||||
ip6tables -t nat -i enp35s0 -I PREROUTING -p tcp --dport 22 -j REDIRECT --to-ports 2223
|
||||
'';
|
||||
|
||||
services.forgejo = {
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
user = "gitea";
|
||||
group = "gitea";
|
||||
package = pkgs.forgejo;
|
||||
appName = "pub.solar git server";
|
||||
database = {
|
||||
type = "postgres";
|
||||
passwordFile = config.age.secrets.forgejo-database-password.path;
|
||||
name = "gitea";
|
||||
user = "gitea";
|
||||
};
|
||||
stateDir = "/var/lib/forgejo";
|
||||
lfs.enable = true;
|
||||
mailerPasswordFile = config.age.secrets.forgejo-mailer-password.path;
|
||||
settings = {
|
||||
DEFAULT.APP_NAME = "pub.solar git server";
|
||||
|
||||
server = {
|
||||
ROOT_URL = "https://git.pub.solar";
|
||||
DOMAIN = "git.pub.solar";
|
||||
HTTP_ADDR = "127.0.0.1";
|
||||
HTTP_PORT = 3000;
|
||||
START_SSH_SERVER = true;
|
||||
SSH_LISTEN_PORT = 2223;
|
||||
SSH_SERVER_HOST_KEYS = "${config.age.secrets."forgejo-ssh-private-key".path}";
|
||||
};
|
||||
|
||||
log.LEVEL = "Warn";
|
||||
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
PROTOCOL = "smtps";
|
||||
SMTP_ADDR = "mail.greenbaum.zone";
|
||||
SMTP_ADDR = "mx2.greenbaum.cloud";
|
||||
SMTP_PORT = 465;
|
||||
FROM = ''"pub.solar git server" <forgejo@pub.solar>'';
|
||||
USER = "admins@pub.solar";
|
||||
};
|
||||
|
||||
"repository.signing" = {
|
||||
SIGNING_KEY = "default";
|
||||
MERGES = "always";
|
||||
};
|
||||
|
||||
openid = {
|
||||
ENABLE_OPENID_SIGNIN = true;
|
||||
ENABLE_OPENID_SIGNUP = true;
|
||||
};
|
||||
|
||||
service = {
|
||||
# uncomment after initial deployment, first user is admin user
|
||||
# required to setup SSO (oauth openid-connect, keycloak auth provider)
|
||||
|
@ -115,37 +75,15 @@
|
|||
ENABLE_NOTIFY_MAIL = true;
|
||||
DEFAULT_KEEP_EMAIL_PRIVATE = true;
|
||||
};
|
||||
|
||||
session = {
|
||||
PROVIDER = "db";
|
||||
COOKIE_SECURE = lib.mkForce true;
|
||||
};
|
||||
|
||||
# https://forgejo.org/docs/latest/admin/config-cheat-sheet/#webhook-webhook
|
||||
webhook = {
|
||||
ALLOWED_HOST_LIST = "loopback,external,*.pub.solar";
|
||||
};
|
||||
|
||||
# See https://forgejo.org/docs/latest/admin/actions/
|
||||
actions = {
|
||||
ENABLED = true;
|
||||
# In an actions workflow, when uses: does not specify an absolute URL,
|
||||
# the value of DEFAULT_ACTIONS_URL is prepended to it.
|
||||
DEFAULT_ACTIONS_URL = "https://code.forgejo.org";
|
||||
};
|
||||
|
||||
# https://forgejo.org/docs/next/admin/recommendations/#securitylogin_remember_days
|
||||
security = {
|
||||
LOGIN_REMEMBER_DAYS = 365;
|
||||
};
|
||||
|
||||
# https://forgejo.org/docs/next/admin/config-cheat-sheet/#indexer-indexer
|
||||
indexer = {
|
||||
REPO_INDEXER_ENABLED = true;
|
||||
REPO_INDEXER_PATH = "indexers/repos.bleve";
|
||||
MAX_FILE_SIZE = 1048576;
|
||||
REPO_INDEXER_EXCLUDE = "resources/bin/**";
|
||||
};
|
||||
actions.ENABLED = true;
|
||||
# In an actions workflow, when uses: does not specify an absolute URL,
|
||||
# the value of DEFAULT_ACTIONS_URL is prepended to it.
|
||||
actions.DEFAULT_ACTIONS_URL = "https://code.forgejo.org";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -171,7 +109,7 @@
|
|||
GPG_TTY = "$(tty)";
|
||||
};
|
||||
|
||||
services.restic.backups.forgejo-droppie = {
|
||||
services.restic.backups.forgejo = {
|
||||
paths = [
|
||||
"/var/lib/forgejo"
|
||||
"/tmp/forgejo-backup.sql"
|
||||
|
@ -190,34 +128,5 @@
|
|||
backupCleanupCommand = ''
|
||||
rm /tmp/forgejo-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
|
||||
services.restic.backups.forgejo-storagebox = {
|
||||
paths = [
|
||||
"/var/lib/forgejo"
|
||||
"/tmp/forgejo-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 04:20:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-repo-storagebox".path;
|
||||
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d gitea > /tmp/forgejo-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/forgejo-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{ flake
|
||||
, config
|
||||
, lib
|
||||
, pkgs
|
||||
, ...
|
||||
{
|
||||
flake,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
age.secrets.keycloak-database-password = {
|
||||
file = "${flake.self}/secrets/keycloak-database-password.age";
|
||||
|
@ -46,7 +47,7 @@
|
|||
};
|
||||
};
|
||||
|
||||
services.restic.backups.keycloak-droppie = {
|
||||
services.restic.backups.keycloak = {
|
||||
paths = [
|
||||
"/tmp/keycloak-backup.sql"
|
||||
];
|
||||
|
@ -64,33 +65,5 @@
|
|||
backupCleanupCommand = ''
|
||||
rm /tmp/keycloak-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
|
||||
services.restic.backups.keycloak-storagebox = {
|
||||
paths = [
|
||||
"/tmp/keycloak-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 04:10:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-repo-storagebox".path;
|
||||
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d keycloak > /tmp/keycloak-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/keycloak-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
{ flake
|
||||
, config
|
||||
, lib
|
||||
, pkgs
|
||||
, ...
|
||||
{
|
||||
flake,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
networking.firewall.allowedTCPPorts = [ 25 ];
|
||||
networking.firewall.allowedTCPPorts = [25];
|
||||
|
||||
users.users.nginx.extraGroups = [ "mailman" ];
|
||||
|
||||
|
@ -22,13 +23,13 @@
|
|||
|
||||
services.postfix = {
|
||||
enable = true;
|
||||
relayDomains = [ "hash:/var/lib/mailman/data/postfix_domains" ];
|
||||
relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
|
||||
# get TLS certs for list.pub.solar from acme
|
||||
sslCert = "/var/lib/acme/list.pub.solar/fullchain.pem";
|
||||
sslKey = "/var/lib/acme/list.pub.solar/key.pem";
|
||||
config = {
|
||||
transport_maps = [ "hash:/var/lib/mailman/data/postfix_lmtp" ];
|
||||
local_recipient_maps = [ "hash:/var/lib/mailman/data/postfix_lmtp" ];
|
||||
transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
|
||||
local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
|
||||
};
|
||||
rootAlias = "admins@pub.solar";
|
||||
postmasterAlias = "admins@pub.solar";
|
||||
|
@ -37,34 +38,34 @@
|
|||
|
||||
systemd.paths.watcher-acme-ssl-file = {
|
||||
description = "Watches for changes in acme's TLS cert file (after renewals) to reload postfix";
|
||||
documentation = [ "systemd.path(5)" ];
|
||||
partOf = [ "postfix-reload.service" ];
|
||||
documentation = ["systemd.path(5)"];
|
||||
partOf = ["postfix-reload.service"];
|
||||
pathConfig = {
|
||||
PathChanged = "/var/lib/acme/list.pub.solar/fullchain.pem";
|
||||
Unit = "postfix-reload.service";
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wantedBy = ["multi-user.target"];
|
||||
};
|
||||
|
||||
systemd.services."postfix-reload" = {
|
||||
description = "Reloads postfix config, e.g. after TLS certs change, notified by watcher-acme-ssl-file.path";
|
||||
documentation = [ "systemd.path(5)" ];
|
||||
requires = [ "postfix.service" ];
|
||||
after = [ "postfix.service" ];
|
||||
documentation = ["systemd.path(5)"];
|
||||
requires = ["postfix.service"];
|
||||
after = ["postfix.service"];
|
||||
startLimitIntervalSec = 10;
|
||||
startLimitBurst = 5;
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
${pkgs.systemd}/bin/systemctl reload postfix
|
||||
'';
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wantedBy = ["multi-user.target"];
|
||||
};
|
||||
|
||||
services.mailman = {
|
||||
enable = true;
|
||||
serve.enable = true;
|
||||
hyperkitty.enable = true;
|
||||
webHosts = [ "list.pub.solar" ];
|
||||
webHosts = ["list.pub.solar"];
|
||||
siteOwner = "admins@pub.solar";
|
||||
};
|
||||
|
||||
|
@ -79,7 +80,7 @@
|
|||
# ])
|
||||
#'';
|
||||
|
||||
services.restic.backups.mailman-droppie = {
|
||||
services.restic.backups.mailman = {
|
||||
paths = [
|
||||
"/var/lib/mailman"
|
||||
"/var/lib/mailman-web/mailman-web.db"
|
||||
|
@ -94,30 +95,5 @@
|
|||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-repo-droppie".path;
|
||||
repository = "sftp:yule@droppie.b12f.io:/media/internal/pub.solar";
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
|
||||
services.restic.backups.mailman-storagebox = {
|
||||
paths = [
|
||||
"/var/lib/mailman"
|
||||
"/var/lib/mailman-web/mailman-web.db"
|
||||
"/var/lib/mailman-web/settings_local.json"
|
||||
"/var/lib/postfix/conf/aliases.db"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 04:15:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-repo-storagebox".path;
|
||||
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -40,9 +40,10 @@
|
|||
# Different from WEB_DOMAIN in our case
|
||||
localDomain = "pub.solar";
|
||||
enableUnixSocket = true;
|
||||
# Number of processes used by the mastodon-streaming service
|
||||
# Recommended is the amount of your CPU cores minus one
|
||||
# On our current 8-Core system, let's start with 5 for now
|
||||
# Processes used by the mastodon-streaming service. Defaults to the number
|
||||
# of CPU cores minus one
|
||||
# This is without affect until this comment is addressed
|
||||
# https://github.com/NixOS/nixpkgs/pull/251950#issuecomment-1732568492
|
||||
streamingProcesses = 5;
|
||||
# Processes used by the mastodon-web service
|
||||
webProcesses = 2;
|
||||
|
@ -54,16 +55,13 @@
|
|||
vapidPublicKeyFile = "/run/agenix/mastodon-vapid-public-key";
|
||||
smtp = {
|
||||
createLocally = false;
|
||||
host = "mail.greenbaum.zone";
|
||||
host = "mx2.greenbaum.cloud";
|
||||
port = 587;
|
||||
authenticate = true;
|
||||
user = "admins@pub.solar";
|
||||
passwordFile = "/run/agenix/mastodon-smtp-password";
|
||||
fromAddress = "mastodon-notifications@pub.solar";
|
||||
};
|
||||
mediaAutoRemove = {
|
||||
olderThanDays = 7;
|
||||
};
|
||||
extraEnvFiles = [
|
||||
"/run/agenix/mastodon-extra-env-secrets"
|
||||
];
|
||||
|
@ -96,7 +94,7 @@
|
|||
};
|
||||
};
|
||||
|
||||
services.restic.backups.mastodon-droppie = {
|
||||
services.restic.backups.mastodon = {
|
||||
paths = [
|
||||
"/tmp/mastodon-backup.sql"
|
||||
];
|
||||
|
@ -114,33 +112,5 @@
|
|||
backupCleanupCommand = ''
|
||||
rm /tmp/mastodon-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
|
||||
services.restic.backups.mastodon-storagebox = {
|
||||
paths = [
|
||||
"/tmp/mastodon-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 04:05:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-repo-storagebox".path;
|
||||
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d mastodon > /tmp/mastodon-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/mastodon-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,45 +1,46 @@
|
|||
{ pkgs, lib, ... }: {
|
||||
default_server_config = {
|
||||
"m.homeserver" = {
|
||||
base_url = "https://matrix.pub.solar";
|
||||
server_name = "pub.solar";
|
||||
};
|
||||
"m.identity_server" = {
|
||||
base_url = "";
|
||||
};
|
||||
};
|
||||
setting_defaults = {
|
||||
custom_themes = (lib.modules.importJSON "${pkgs.element-themes}").config;
|
||||
};
|
||||
default_theme = "light";
|
||||
default_country_code = "DE";
|
||||
permalink_prefix = "https://matrix.to";
|
||||
disable_custom_urls = true;
|
||||
disable_guests = true;
|
||||
brand = "Element Solar";
|
||||
{
|
||||
default_server_config = {
|
||||
"m.homeserver" = {
|
||||
base_url = "https://matrix.test.pub.solar";
|
||||
server_name = "test.pub.solar";
|
||||
};
|
||||
"m.identity_server" = {
|
||||
base_url = "";
|
||||
};
|
||||
};
|
||||
# TODO: Add themes
|
||||
# setting_defaults = {
|
||||
# custom_themes = {{ matrix_client_element_setting_defaults_custom_themes | to_json }}
|
||||
# };
|
||||
# default_theme = {{ matrix_client_element_default_theme | string | to_json }};
|
||||
# default_country_code = {{ matrix_client_element_default_country_code | string | to_json }};
|
||||
permalink_prefix = "https://matrix.to";
|
||||
disable_custom_urls = true;
|
||||
disable_guests = true;
|
||||
brand = "Element Solar";
|
||||
|
||||
# TODO: Configure these
|
||||
integrations_ui_url = "";
|
||||
integrations_rest_url = "";
|
||||
integrations_widgets_urls = "";
|
||||
integrations_jitsi_widget_url = "";
|
||||
integrations_ui_url = "";
|
||||
integrations_rest_url = "";
|
||||
integrations_widgets_urls = "";
|
||||
integrations_jitsi_widget_url = "";
|
||||
|
||||
bug_report_endpoint_url = "https://element.io/bugreports/submit";
|
||||
show_labs_settings = true;
|
||||
room_directory = {
|
||||
servers = [ "matrix.org" ];
|
||||
};
|
||||
bug_report_endpoint_url = "https://element.io/bugreports/submit";
|
||||
show_labs_settings = true;
|
||||
room_directory = {
|
||||
servers = ["matrix.org"];
|
||||
};
|
||||
# TODO: This looks wrong
|
||||
enable_presence_by_hs_url = "\n";
|
||||
embedded_pages = {
|
||||
homeUrl = "";
|
||||
};
|
||||
branding = {
|
||||
auth_footer_links = [{
|
||||
enable_presence_by_hs_url = "\n";
|
||||
embedded_pages = {
|
||||
homeUrl = "";
|
||||
};
|
||||
branding = {
|
||||
auth_footer_links = [{
|
||||
text = "Privacy";
|
||||
url = "https://pub.solar/privacy";
|
||||
}];
|
||||
# FUTUREWORK: Replace with pub.solar logo
|
||||
auth_header_logo_url = "themes/element/img/logos/element-logo.svg";
|
||||
};
|
||||
auth_header_logo_url = "themes/element/img/logos/element-logo.svg";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
# Find element in list config.services.matrix-synapse.settings.listeners.*.resources
|
||||
# that sets names = "client"
|
||||
nameHasClient = name: name == "client";
|
||||
resourceHasClient = resource: builtins.any nameHasClient resource.names;
|
||||
listenerWithClient = lib.findFirst
|
||||
(listener:
|
||||
builtins.any resourceHasClient listener.resources)
|
||||
(throw "Found no matrix-synapse.settings.listeners.*.resources.*.names containing string client")
|
||||
config.services.matrix-synapse.settings.listeners
|
||||
;
|
||||
synapseClientPort = "${toString listenerWithClient.port}";
|
||||
in
|
||||
{
|
||||
services.matrix-appservice-irc = {
|
||||
enable = true;
|
||||
localpart = "irc_bot";
|
||||
port = 8010;
|
||||
registrationUrl = "http://localhost:8010";
|
||||
settings = {
|
||||
homeserver = {
|
||||
domain = "pub.solar";
|
||||
url = "http://127.0.0.1:${synapseClientPort}";
|
||||
media_url = "https://matrix.pub.solar";
|
||||
enablePresence = false;
|
||||
};
|
||||
ircService = {
|
||||
ident = {
|
||||
address = "::";
|
||||
enabled = false;
|
||||
port = 1113;
|
||||
};
|
||||
logging = {
|
||||
level = "debug";
|
||||
maxFiles = 5;
|
||||
toCosole = true;
|
||||
};
|
||||
matrixHandler = {
|
||||
eventCacheSize = 4096;
|
||||
};
|
||||
metrics = {
|
||||
enabled = true;
|
||||
remoteUserAgeBuckets = [ "1h" "1d" "1w" ];
|
||||
};
|
||||
provisioning = {
|
||||
enabled = false;
|
||||
requestTimeoutSeconds = 300;
|
||||
};
|
||||
servers =
|
||||
let
|
||||
commonConfig = {
|
||||
allowExpiredCerts = false;
|
||||
botConfig = {
|
||||
enabled = false;
|
||||
joinChannelsIfNoUsers = false;
|
||||
nick = "MatrixBot";
|
||||
};
|
||||
dynamicChannels = {
|
||||
createAlias = true;
|
||||
enabled = true;
|
||||
federate = true;
|
||||
joinRule = "public";
|
||||
published = true;
|
||||
};
|
||||
ircClients = {
|
||||
allowNickChanges = true;
|
||||
concurrentReconnectLimit = 50;
|
||||
idleTimeout = 10800;
|
||||
lineLimit = 3;
|
||||
maxClients = 30;
|
||||
nickTemplate = "$DISPLAY[m]";
|
||||
reconnectIntervalMs = 5000;
|
||||
};
|
||||
matrixClients = {
|
||||
joinAttempts = -1;
|
||||
};
|
||||
membershipLists = {
|
||||
enabled = true;
|
||||
floodDelayMs = 10000;
|
||||
global = {
|
||||
ircToMatrix = {
|
||||
incremental = true;
|
||||
initial = true;
|
||||
};
|
||||
matrixToIrc = {
|
||||
incremental = true;
|
||||
initial = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
port = 6697;
|
||||
privateMessages = {
|
||||
enabled = true;
|
||||
federate = true;
|
||||
};
|
||||
sasl = false;
|
||||
sendConnectionMessages = true;
|
||||
ssl = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
"irc.libera.chat" = lib.attrsets.recursiveUpdate commonConfig {
|
||||
name = "libera";
|
||||
dynamicChannels.groupId = "+libera.chat:localhost";
|
||||
dynamicChannels.aliasTemplate = "#_libera_$CHANNEL";
|
||||
matrixClients.displayName = "$NICK (LIBERA-IRC)";
|
||||
};
|
||||
"irc.scratch-network.net" = lib.attrsets.recursiveUpdate commonConfig {
|
||||
name = "scratch";
|
||||
matrixClients.displayName = "$NICK (SCRATCH-IRC)";
|
||||
dynamicChannels.aliasTemplate = "#_scratch_$CHANNEL";
|
||||
dynamicChannels.groupId = "+scratch-network.net:localhost";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
112
hosts/nachtigall/apps/matrix/matrix-hookshot.nix
Normal file
112
hosts/nachtigall/apps/matrix/matrix-hookshot.nix
Normal file
|
@ -0,0 +1,112 @@
|
|||
{ flake, pkgs, ...}:{
|
||||
|
||||
age.secrets."matrix-hookshot-registration.yaml" = {
|
||||
file = "${flake.self}/secrets/matrix-hookshot-registration.yaml.age";
|
||||
mode = "400";
|
||||
owner = "matrix-synapse";
|
||||
};
|
||||
|
||||
configFile = ''
|
||||
bot:
|
||||
avatar: mxc://half-shot.uk/2876e89ccade4cb615e210c458e2a7a6883fe17d
|
||||
displayname: Hookshot Bot
|
||||
bridge:
|
||||
bindAddress: 0.0.0.0
|
||||
domain: test.pub.solar
|
||||
mediaUrl: http://matrix-nginx-proxy:12080
|
||||
port: 9993
|
||||
url: http://matrix-nginx-proxy:12080
|
||||
feeds:
|
||||
enabled: true
|
||||
pollIntervalSeconds: 600
|
||||
pollTimeoutSeconds: 30
|
||||
generic:
|
||||
allowJsTransformationFunctions: true
|
||||
enableHttpGet: false
|
||||
enabled: true
|
||||
urlPrefix: https://matrix.test.pub.solar/hookshot/webhooks
|
||||
userIdPrefix: _webhooks_
|
||||
waitForComplete: false
|
||||
gitlab:
|
||||
instances:
|
||||
gitlab.com:
|
||||
url: https://gitlab.com
|
||||
webhook:
|
||||
secret: ""
|
||||
listeners:
|
||||
- bindAddress: 0.0.0.0
|
||||
port: 9000
|
||||
resources:
|
||||
- webhooks
|
||||
- bindAddress: 0.0.0.0
|
||||
port: 9002
|
||||
resources:
|
||||
- provisioning
|
||||
- bindAddress: 0.0.0.0
|
||||
port: 9003
|
||||
resources:
|
||||
- widgets
|
||||
logging:
|
||||
level: warn
|
||||
metrics:
|
||||
enabled: false
|
||||
passFile: /data/passkey.pem
|
||||
permissions:
|
||||
- actor: pub.solar
|
||||
services:
|
||||
- level: commands
|
||||
service: '*'
|
||||
- actor: '@axeman:pub.solar'
|
||||
services:
|
||||
- level: admin
|
||||
service: '*'
|
||||
- actor: '@b12f:pub.solar'
|
||||
services:
|
||||
- level: admin
|
||||
service: '*'
|
||||
- actor: '@hensoko:pub.solar'
|
||||
services:
|
||||
- level: admin
|
||||
service: '*'
|
||||
- actor: '@teutat3s:pub.solar'
|
||||
services:
|
||||
- level: admin
|
||||
service: '*'
|
||||
provisioning:
|
||||
secret: 1acb44197a5a6d52c6cff38ea07433bfbfe9a83313a6bade
|
||||
widgets:
|
||||
addToAdminRooms: false
|
||||
branding:
|
||||
widgetTitle: Hookshot Configuration
|
||||
publicUrl: https://matrix.pub.solar/hookshot/widgetapi/v1/static
|
||||
roomSetupWidget:
|
||||
addOnInvite: false
|
||||
'';
|
||||
|
||||
systemd.services.matrix-hookshot = {
|
||||
description = "Matrix-Hookshot, a bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA. ";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
|
||||
DynamicUser = true;
|
||||
PrivateTmp = true;
|
||||
UMask = "0027";
|
||||
|
||||
ExecStart = ''
|
||||
${pkgs.matrix-hookshot}/bin/matrix-hookshot
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
homeserver = {
|
||||
# TODO: Use the port from synapse config
|
||||
address = "http://127.0.0.1:8008";
|
||||
domain = "pub.solar";
|
||||
domain = "test.pub.solar";
|
||||
verify_ssl = true;
|
||||
};
|
||||
appservice = {
|
||||
|
@ -27,14 +27,14 @@
|
|||
id = "telegram";
|
||||
max_body_size = 1;
|
||||
port = 8009;
|
||||
provisioning = {
|
||||
provisioning = {
|
||||
enabled = false;
|
||||
prefix = "/_matrix/provision/v1";
|
||||
shared_secret = "generate";
|
||||
};
|
||||
public = {
|
||||
enabled = true;
|
||||
external = "https://matrix.pub.solar/c3c3f34b-29fb-5feb-86e5-98c75ec8214b";
|
||||
external = "https://matrix.test.pub.solar/c3c3f34b-29fb-5feb-86e5-98c75ec8214b";
|
||||
prefix = "/c3c3f34b-29fb-5feb-86e5-98c75ec8214b";
|
||||
};
|
||||
};
|
||||
|
@ -59,7 +59,7 @@
|
|||
bot_messages_as_notices = true;
|
||||
bridge_notices = {
|
||||
default = false;
|
||||
exceptions = [ ];
|
||||
exceptions = [];
|
||||
};
|
||||
command_prefix = "!tg";
|
||||
delivery_error_reports = true;
|
||||
|
@ -84,13 +84,13 @@
|
|||
};
|
||||
federate_rooms = true;
|
||||
filter = {
|
||||
list = [ ];
|
||||
list = [];
|
||||
mode = "blacklist";
|
||||
};
|
||||
image_as_file_size = 10;
|
||||
initial_power_level_overrides = {
|
||||
group = { };
|
||||
user = { };
|
||||
group = {};
|
||||
user = {};
|
||||
};
|
||||
inline_images = false;
|
||||
max_document_size = 100;
|
||||
|
@ -112,15 +112,15 @@
|
|||
public_portals = true;
|
||||
relaybot = {
|
||||
authless_portals = true;
|
||||
group_chat_invite = [ ];
|
||||
group_chat_invite = [];
|
||||
ignore_own_incoming_events = true;
|
||||
ignore_unbridged_group_chat = true;
|
||||
private_chat = {
|
||||
invite = [ ];
|
||||
invite = [];
|
||||
message = "This is a Matrix bridge relaybot and does not support direct chats";
|
||||
state_changes = true;
|
||||
};
|
||||
whitelist = [ ];
|
||||
whitelist = [];
|
||||
whitelist_group_admins = true;
|
||||
};
|
||||
resend_bridge_info = false;
|
||||
|
@ -140,12 +140,12 @@
|
|||
username_template = "telegram_{userid}";
|
||||
|
||||
permissions = {
|
||||
"pub.solar" = "full";
|
||||
"test.pub.solar" = "full";
|
||||
};
|
||||
};
|
||||
|
||||
logging = {
|
||||
formatters = {
|
||||
formatters= {
|
||||
precise = {
|
||||
format = "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s";
|
||||
};
|
||||
|
@ -156,14 +156,14 @@
|
|||
formatter = "precise";
|
||||
};
|
||||
};
|
||||
loggers = {
|
||||
loggers={
|
||||
aiohttp.level = "WARNING";
|
||||
mau.level = "WARNING";
|
||||
telethon.level = "WARNING";
|
||||
};
|
||||
root = {
|
||||
handlers = [ "console" ];
|
||||
level = "WARNING";
|
||||
level = "WARNING";
|
||||
};
|
||||
version = 1;
|
||||
};
|
||||
|
@ -202,8 +202,8 @@
|
|||
};
|
||||
|
||||
systemd.services.mautrix-telegram.path = with pkgs; [
|
||||
lottieconverter # for animated stickers conversion, unfree package
|
||||
ffmpeg # if converting animated stickers to webm (very slow!)
|
||||
lottieconverter # for animated stickers conversion, unfree package
|
||||
ffmpeg # if converting animated stickers to webm (very slow!)
|
||||
];
|
||||
systemd.services.mautrix-telegram.serviceConfig = {
|
||||
User = "matrix-synapse";
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
{ flake, config, pkgs, ... }:
|
||||
let
|
||||
publicDomain = "matrix.pub.solar";
|
||||
serverDomain = "pub.solar";
|
||||
in
|
||||
{
|
||||
publicDomain = "matrix.test.pub.solar";
|
||||
serverDomain = "test.pub.solar";
|
||||
in {
|
||||
age.secrets."matrix-synapse-signing-key" = {
|
||||
file = "${flake.self}/secrets/matrix-synapse-signing-key.age";
|
||||
mode = "400";
|
||||
|
@ -16,17 +15,11 @@ in
|
|||
owner = "matrix-synapse";
|
||||
};
|
||||
|
||||
age.secrets."matrix-synapse-sliding-sync-secret" = {
|
||||
file = "${flake.self}/secrets/matrix-synapse-sliding-sync-secret.age";
|
||||
mode = "400";
|
||||
owner = "matrix-synapse";
|
||||
};
|
||||
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server_name = serverDomain;
|
||||
public_baseurl = "https://${publicDomain}/";
|
||||
public_baseurl = "https://matrix.test.pub.solar/";
|
||||
database = {
|
||||
name = "psycopg2";
|
||||
args = {
|
||||
|
@ -38,56 +31,16 @@ in
|
|||
allow_unsafe_locale = false;
|
||||
txn_limit = 0;
|
||||
};
|
||||
listeners = [
|
||||
{
|
||||
bind_addresses = [
|
||||
"127.0.0.1"
|
||||
];
|
||||
port = 8008;
|
||||
resources = [
|
||||
{
|
||||
compress = true;
|
||||
names = [
|
||||
"client"
|
||||
];
|
||||
}
|
||||
{
|
||||
compress = false;
|
||||
names = [
|
||||
"federation"
|
||||
];
|
||||
}
|
||||
];
|
||||
tls = false;
|
||||
type = "http";
|
||||
x_forwarded = true;
|
||||
}
|
||||
{
|
||||
bind_addresses = [
|
||||
"127.0.0.1"
|
||||
];
|
||||
port = 8012;
|
||||
resources = [
|
||||
{
|
||||
names = [
|
||||
"metrics"
|
||||
];
|
||||
}
|
||||
];
|
||||
tls = false;
|
||||
type = "metrics";
|
||||
}
|
||||
];
|
||||
|
||||
account_threepid_delegates.msisdn = "";
|
||||
alias_creation_rules = [{
|
||||
action = "allow";
|
||||
alias = "*";
|
||||
room_id = "*";
|
||||
alias= "*";
|
||||
room_id = "*" ;
|
||||
user_id = "*";
|
||||
}];
|
||||
allow_guest_access = false;
|
||||
allow_public_rooms_over_federation = true;
|
||||
allow_public_rooms_over_federation = false;
|
||||
allow_public_rooms_without_auth = false;
|
||||
auto_join_rooms = [
|
||||
"#community:${serverDomain}"
|
||||
|
@ -99,9 +52,22 @@ in
|
|||
|
||||
default_room_version = "10";
|
||||
disable_msisdn_registration = true;
|
||||
email = {
|
||||
app_name = "Matrix";
|
||||
client_base_url = "https://chat.pub.solar";
|
||||
enable_notifs = true;
|
||||
enable_tls = true;
|
||||
# FUTUREWORK: Maybe we should change this
|
||||
invite_client_location = "https://app.element.io";
|
||||
notif_for_new_users = true;
|
||||
notif_from = "Matrix <no-reply@pub.solar>";
|
||||
require_transport_security = false;
|
||||
smtp_host = "matrix-mailer";
|
||||
smtp_port = 8025;
|
||||
};
|
||||
|
||||
enable_media_repo = true;
|
||||
enable_metrics = true;
|
||||
mau_stats_only = true;
|
||||
enable_registration = false;
|
||||
enable_registration_captcha = false;
|
||||
enable_registration_without_verification = false;
|
||||
|
@ -109,17 +75,16 @@ in
|
|||
encryption_enabled_by_default_for_room_type = "off";
|
||||
event_cache_size = "100K";
|
||||
federation_rr_transactions_per_room_per_second = 50;
|
||||
federation_client_minimum_tls_version = "1.2";
|
||||
forget_rooms_on_leave = true;
|
||||
include_profile_data_on_invite = true;
|
||||
instance_map = { };
|
||||
instance_map = {};
|
||||
limit_profile_requests_to_users_who_share_rooms = false;
|
||||
|
||||
log_config = ./matrix-log-config.yaml;
|
||||
|
||||
max_spider_size = "10M";
|
||||
max_upload_size = "50M";
|
||||
media_storage_providers = [ ];
|
||||
media_storage_providers = [];
|
||||
|
||||
password_config = {
|
||||
enabled = false;
|
||||
|
@ -127,71 +92,70 @@ in
|
|||
pepper = "";
|
||||
};
|
||||
|
||||
presence.enabled = true;
|
||||
presencee.enabled = true;
|
||||
push.include_content = false;
|
||||
|
||||
rc_admin_redaction = {
|
||||
rc_admin_redaction= {
|
||||
burst_count = 50;
|
||||
per_second = 1;
|
||||
};
|
||||
rc_federation = {
|
||||
rc_federation= {
|
||||
concurrent = 3;
|
||||
reject_limit = 50;
|
||||
sleep_delay = 500;
|
||||
sleep_limit = 10;
|
||||
window_size = 1000;
|
||||
};
|
||||
rc_invites = {
|
||||
per_issuer = {
|
||||
rc_invites= {
|
||||
per_issuer= {
|
||||
burst_count = 10;
|
||||
per_second = 0.3;
|
||||
};
|
||||
per_room = {
|
||||
per_room= {
|
||||
burst_count = 10;
|
||||
per_second = 0.3;
|
||||
};
|
||||
per_user = {
|
||||
per_user= {
|
||||
burst_count = 5;
|
||||
per_second = 0.003;
|
||||
};
|
||||
};
|
||||
rc_joins = {
|
||||
local = {
|
||||
rc_joins= {
|
||||
local= {
|
||||
burst_count = 10;
|
||||
per_second = 0.1;
|
||||
};
|
||||
remote = {
|
||||
remote= {
|
||||
burst_count = 10;
|
||||
per_second = 0.01;
|
||||
};
|
||||
};
|
||||
rc_login = {
|
||||
account = {
|
||||
rc_login= {
|
||||
account= {
|
||||
burst_count = 3;
|
||||
per_second = 0.17;
|
||||
};
|
||||
address = {
|
||||
address= {
|
||||
burst_count = 3;
|
||||
per_second = 0.17;
|
||||
};
|
||||
failed_attempts = {
|
||||
failed_attempts= {
|
||||
burst_count = 3;
|
||||
per_second = 0.17;
|
||||
};
|
||||
};
|
||||
rc_message = {
|
||||
rc_message= {
|
||||
burst_count = 10;
|
||||
per_second = 0.2;
|
||||
};
|
||||
rc_registration = {
|
||||
rc_registration= {
|
||||
burst_count = 3;
|
||||
per_second = 0.17;
|
||||
};
|
||||
redaction_retention_period = "7d";
|
||||
forgotten_room_retention_period = "7d";
|
||||
redis.enabled = false;
|
||||
registration_requires_token = false;
|
||||
registrations_require_3pid = [ "email" ];
|
||||
registrations_require_3pid = ["email"];
|
||||
report_stats = false;
|
||||
require_auth_for_profile_requests = false;
|
||||
room_list_publication_rules = [{
|
||||
|
@ -203,17 +167,13 @@ in
|
|||
|
||||
signing_key_path = "/run/agenix/matrix-synapse-signing-key";
|
||||
|
||||
stream_writers = { };
|
||||
trusted_key_servers = [{ server_name = "matrix.org"; }];
|
||||
suppress_key_server_warning = true;
|
||||
|
||||
stream_writers = {};
|
||||
trusted_key_servers = [{ server_name = "matrix.org";}];
|
||||
turn_allow_guests = false;
|
||||
turn_uris = [
|
||||
"turn:${config.services.coturn.realm}:3478?transport=udp"
|
||||
"turn:${config.services.coturn.realm}:3478?transport=tcp"
|
||||
"turn:matrix.pub.solar?transport=udp"
|
||||
"turn:matrix.pub.solar?transport=tcp"
|
||||
];
|
||||
turn_user_lifetime = "1h";
|
||||
|
||||
url_preview_accept_language = [
|
||||
"en-US"
|
||||
"en"
|
||||
|
@ -249,7 +209,7 @@ in
|
|||
|
||||
app_service_config_files = [
|
||||
"/var/lib/matrix-synapse/telegram-registration.yaml"
|
||||
"/var/lib/matrix-appservice-irc/registration.yml"
|
||||
# "/matrix-appservice-irc-registration.yaml"
|
||||
# "/matrix-appservice-slack-registration.yaml"
|
||||
# "/hookshot-registration.yml"
|
||||
# "/matrix-mautrix-signal-registration.yaml"
|
||||
|
@ -257,8 +217,6 @@ in
|
|||
];
|
||||
};
|
||||
|
||||
withJemalloc = true;
|
||||
|
||||
extraConfigFiles = [
|
||||
"/run/agenix/matrix-synapse-secret-config.yaml"
|
||||
|
||||
|
@ -271,51 +229,8 @@ in
|
|||
"/var/lib/matrix-synapse/telegram-registration.yaml"
|
||||
];
|
||||
|
||||
extras = [
|
||||
"oidc"
|
||||
"redis"
|
||||
];
|
||||
|
||||
plugins = [
|
||||
config.services.matrix-synapse.package.plugins.matrix-synapse-shared-secret-auth
|
||||
];
|
||||
|
||||
sliding-sync = {
|
||||
enable = true;
|
||||
settings = {
|
||||
SYNCV3_SERVER = "https://${publicDomain}";
|
||||
SYNCV3_BINDADDR = "127.0.0.1:8011";
|
||||
# The bind addr for Prometheus metrics, which will be accessible at
|
||||
# /metrics at this address
|
||||
SYNCV3_PROM = "127.0.0.1:9100";
|
||||
};
|
||||
environmentFile = config.age.secrets."matrix-synapse-sliding-sync-secret".path;
|
||||
};
|
||||
};
|
||||
|
||||
services.restic.backups.matrix-synapse-storagebox = {
|
||||
paths = [
|
||||
"/var/lib/matrix-synapse"
|
||||
"/var/lib/matrix-appservice-irc"
|
||||
"/var/lib/mautrix-telegram"
|
||||
"/tmp/matrix-synapse-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 05:00:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-repo-storagebox".path;
|
||||
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d matrix > /tmp/matrix-synapse-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/matrix-synapse-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,161 +1,159 @@
|
|||
{ flake
|
||||
, config
|
||||
, lib
|
||||
, pkgs
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
{
|
||||
flake,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
localSettingsPHP = pkgs.writeScript "LocalSettings.php" ''
|
||||
<?php
|
||||
# Protect against web entry
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
<?php
|
||||
# Protect against web entry
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
# error_reporting( -1 );
|
||||
# ini_set( 'display_errors', 1 );
|
||||
# $wgShowExceptionDetails = true;
|
||||
# $wgDBerrorLog = '/dev/stderr';
|
||||
# $wgDebugLogFile = "/dev/stderr";
|
||||
# error_reporting( -1 );
|
||||
# ini_set( 'display_errors', 1 );
|
||||
# $wgShowExceptionDetails = true;
|
||||
$wgDBerrorLog = '/dev/stderr';
|
||||
$wgDebugLogFile = "/dev/stderr";
|
||||
|
||||
$wgSitename = "pub.solar wiki";
|
||||
$wgMetaNamespace = false;
|
||||
$wgSitename = "pub.solar wiki";
|
||||
$wgMetaNamespace = false;
|
||||
|
||||
## The URL base path to the directory containing the wiki;
|
||||
## defaults for all runtime URL paths are based off of this.
|
||||
## For more information on customizing the URLs
|
||||
## (like /w/index.php/Page_title to /wiki/Page_title) please see:
|
||||
## https://www.mediawiki.org/wiki/Manual:Short_URL
|
||||
$wgScriptPath = "https://wiki.pub.solar";
|
||||
## The URL base path to the directory containing the wiki;
|
||||
## defaults for all runtime URL paths are based off of this.
|
||||
## For more information on customizing the URLs
|
||||
## (like /w/index.php/Page_title to /wiki/Page_title) please see:
|
||||
## https://www.mediawiki.org/wiki/Manual:Short_URL
|
||||
$wgScriptPath = "https://wiki.pub.solar";
|
||||
|
||||
## https://www.mediawiki.org/wiki/Manual:Short_URL
|
||||
## https://www.mediawiki.org/wiki/Extension:OpenID_Connect#Known_issues
|
||||
$wgArticlePath = "/index.php/$1";
|
||||
## https://www.mediawiki.org/wiki/Manual:Short_URL
|
||||
## https://www.mediawiki.org/wiki/Extension:OpenID_Connect#Known_issues
|
||||
$wgArticlePath = "/index.php/$1";
|
||||
|
||||
## The protocol and server name to use in fully-qualified URLs
|
||||
$wgServer = "https://wiki.pub.solar";
|
||||
## The protocol and server name to use in fully-qualified URLs
|
||||
$wgServer = "https://wiki.pub.solar";
|
||||
|
||||
## The URL path to static resources (images, scripts, etc.)
|
||||
$wgResourceBasePath = $wgScriptPath;
|
||||
## The URL path to static resources (images, scripts, etc.)
|
||||
$wgResourceBasePath = $wgScriptPath;
|
||||
|
||||
## The URL path to the logo. Make sure you change this from the default,
|
||||
## or else you'll overwrite your logo when you upgrade!
|
||||
$wgLogo = "https://pub.solar/assets/pubsolar.svg";
|
||||
## The URL path to the logo. Make sure you change this from the default,
|
||||
## or else you'll overwrite your logo when you upgrade!
|
||||
$wgLogo = "$wgResourceBasePath/resources/assets/wiki.png";
|
||||
|
||||
## UPO means: this is also a user preference option
|
||||
## UPO means: this is also a user preference option
|
||||
|
||||
$wgEnableEmail = true;
|
||||
$wgEnableUserEmail = true; # UPO
|
||||
$wgEnableEmail = true;
|
||||
$wgEnableUserEmail = true; # UPO
|
||||
|
||||
$wgPasswordSender = "admins@pub.solar";
|
||||
$wgPasswordSender = "admins@pub.solar";
|
||||
|
||||
$wgEnotifUserTalk = false; # UPO
|
||||
$wgEnotifWatchlist = false; # UPO
|
||||
$wgEmailAuthentication = true;
|
||||
$wgEnotifUserTalk = false; # UPO
|
||||
$wgEnotifWatchlist = false; # UPO
|
||||
$wgEmailAuthentication = true;
|
||||
|
||||
## Database settings
|
||||
$wgDBtype = "postgres";
|
||||
$wgDBserver = "host.docker.internal";
|
||||
$wgDBport = "5432";
|
||||
$wgDBname = "mediawiki";
|
||||
$wgDBuser = "mediawiki";
|
||||
$wgDBpassword = trim(file_get_contents("/run/mediawiki/database-password"));
|
||||
## Database settings
|
||||
$wgDBtype = "postgres";
|
||||
$wgDBserver = "host.docker.internal";
|
||||
$wgDBport = "5432";
|
||||
$wgDBname = "mediawiki";
|
||||
$wgDBuser = "mediawiki";
|
||||
$wgDBpassword = trim(file_get_contents("/run/mediawiki/database-password"));
|
||||
|
||||
## Shared memory settings
|
||||
$wgMainCacheType = CACHE_NONE;
|
||||
$wgMemCachedServers = [];
|
||||
## Shared memory settings
|
||||
$wgMainCacheType = CACHE_NONE;
|
||||
$wgMemCachedServers = [];
|
||||
|
||||
$wgEnableUploads = true;
|
||||
$wgUploadDirectory = "/var/www/html/uploads";
|
||||
$wgUploadPath = $wgScriptPath . "/uploads";
|
||||
$wgEnableUploads = true;
|
||||
$wgUploadDirectory = "/var/www/html/uploads";
|
||||
|
||||
$wgUseImageMagick = true;
|
||||
$wgImageMagickConvertCommand = "/usr/bin/convert";
|
||||
$wgUseImageMagick = true;
|
||||
$wgImageMagickConvertCommand = "/usr/bin/convert";
|
||||
|
||||
# InstantCommons allows wiki to use images from https://commons.wikimedia.org
|
||||
$wgUseInstantCommons = true;
|
||||
# InstantCommons allows wiki to use images from https://commons.wikimedia.org
|
||||
$wgUseInstantCommons = false;
|
||||
|
||||
# Periodically send a pingback to https://www.mediawiki.org/ with basic data
|
||||
# about this MediaWiki instance. The Wikimedia Foundation shares this data
|
||||
# with MediaWiki developers to help guide future development efforts.
|
||||
$wgPingback = true;
|
||||
# Periodically send a pingback to https://www.mediawiki.org/ with basic data
|
||||
# about this MediaWiki instance. The Wikimedia Foundation shares this data
|
||||
# with MediaWiki developers to help guide future development efforts.
|
||||
$wgPingback = true;
|
||||
|
||||
## If you use ImageMagick (or any other shell command) on a
|
||||
## Linux server, this will need to be set to the name of an
|
||||
## available UTF-8 locale
|
||||
$wgShellLocale = "C.UTF-8";
|
||||
## If you use ImageMagick (or any other shell command) on a
|
||||
## Linux server, this will need to be set to the name of an
|
||||
## available UTF-8 locale
|
||||
$wgShellLocale = "C.UTF-8";
|
||||
|
||||
# Site language code, should be one of the list in ./languages/data/Names.php
|
||||
$wgLanguageCode = "en";
|
||||
# Site language code, should be one of the list in ./languages/data/Names.php
|
||||
$wgLanguageCode = "en";
|
||||
|
||||
$wgSecretKey = trim(file_get_contents("/run/mediawiki/secret-key"));
|
||||
$wgSecretKey = trim(file_get_contents("/run/mediawiki/secret-key"));
|
||||
|
||||
# Changing this will log out all existing sessions.
|
||||
$wgAuthenticationTokenVersion = "";
|
||||
# Changing this will log out all existing sessions.
|
||||
$wgAuthenticationTokenVersion = "";
|
||||
|
||||
## For attaching licensing metadata to pages, and displaying an
|
||||
## appropriate copyright notice / icon. GNU Free Documentation
|
||||
## License and Creative Commons licenses are supported so far.
|
||||
$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
|
||||
$wgRightsUrl = "";
|
||||
$wgRightsText = "";
|
||||
$wgRightsIcon = "";
|
||||
## For attaching licensing metadata to pages, and displaying an
|
||||
## appropriate copyright notice / icon. GNU Free Documentation
|
||||
## License and Creative Commons licenses are supported so far.
|
||||
$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
|
||||
$wgRightsUrl = "";
|
||||
$wgRightsText = "";
|
||||
$wgRightsIcon = "";
|
||||
|
||||
# Path to the GNU diff3 utility. Used for conflict resolution.
|
||||
$wgDiff = "/usr/bin/diff";
|
||||
$wgDiff3 = "/usr/bin/diff3";
|
||||
# Path to the GNU diff3 utility. Used for conflict resolution.
|
||||
$wgDiff = "/usr/bin/diff";
|
||||
$wgDiff3 = "/usr/bin/diff3";
|
||||
|
||||
# Enabled skins.
|
||||
wfLoadSkin('MonoBook');
|
||||
wfLoadSkin('Timeless');
|
||||
wfLoadSkin('Vector');
|
||||
# Enabled skins.
|
||||
wfLoadSkin('MonoBook');
|
||||
wfLoadSkin('Timeless');
|
||||
wfLoadSkin('Vector');
|
||||
|
||||
# Enabled extensions.
|
||||
wfLoadExtension('OpenIDConnect');
|
||||
wfLoadExtension('PluggableAuth');
|
||||
wfLoadExtension('VisualEditor');
|
||||
wfLoadExtension('TemplateStyles');
|
||||
# Enabled extensions.
|
||||
wfLoadExtension('OpenIDConnect');
|
||||
wfLoadExtension('PluggableAuth');
|
||||
wfLoadExtension('VisualEditor');
|
||||
|
||||
# End of automatically generated settings.
|
||||
# Add more configuration options below.
|
||||
# End of automatically generated settings.
|
||||
# Add more configuration options below.
|
||||
|
||||
$wgLogos = [
|
||||
'svg' => "https://pub.solar/assets/pubsolar.svg",
|
||||
'icon' => "https://pub.solar/assets/pubsolar.svg",
|
||||
'wordmark' => [
|
||||
'src'=> "https://pub.solar/assets/pubsolar.svg",
|
||||
'width'=> 0,
|
||||
'height'=> 0,
|
||||
],
|
||||
];
|
||||
$wgFavicon = 'https://pub.solar/assets/pubsolar.svg';
|
||||
$wgLogo = "https://pub.solar/assets/pubsolar.svg";
|
||||
$wgLogos = [
|
||||
'svg' => "https://pub.solar/assets/pubsolar.svg",
|
||||
'icon' => "https://pub.solar/assets/pubsolar.svg",
|
||||
'wordmark' => [
|
||||
'src'=> "https://pub.solar/assets/pubsolar.svg",
|
||||
'width'=> 0,
|
||||
'height'=> 0,
|
||||
],
|
||||
];
|
||||
$wgFavicon = 'https://pub.solar/assets/pubsolar.svg';
|
||||
|
||||
$wgDefaultSkin = 'vector-2022';
|
||||
$wgDefaultSkin = 'vector-2022';
|
||||
|
||||
// https://www.mediawiki.org/wiki/Extension:PluggableAuth#Installation
|
||||
$wgGroupPermissions['*']['autocreateaccount'] = true;
|
||||
// https://www.mediawiki.org/wiki/Extension:PluggableAuth#Installation
|
||||
$wgGroupPermissions['*']['autocreateaccount'] = true;
|
||||
|
||||
// https://www.mediawiki.org/wiki/Extension:PluggableAuth#Configuration
|
||||
$wgPluggableAuth_EnableAutoLogin = false;
|
||||
$wgPluggableAuth_ButtonLabel = 'Login with pub.solar ID';
|
||||
// https://www.mediawiki.org/wiki/Extension:PluggableAuth#Configuration
|
||||
$wgPluggableAuth_EnableAutoLogin = false;
|
||||
$wgPluggableAuth_ButtonLabel = 'Login with pub.solar ID';
|
||||
|
||||
// https://www.mediawiki.org/wiki/Extension:OpenID_Connect#Keycloak
|
||||
$wgPluggableAuth_Config[] = [
|
||||
'plugin' => 'OpenIDConnect',
|
||||
'data' => [
|
||||
'providerURL' => 'https://auth.pub.solar/realms/pub.solar',
|
||||
'clientID' => 'mediawiki',
|
||||
'clientsecret' => trim(file_get_contents('/run/mediawiki/oidc-client-secret'))
|
||||
]
|
||||
];
|
||||
$wgOpenIDConnect_SingleLogout = true;
|
||||
$wgOpenIDConnect_MigrateUsersByEmail = true;
|
||||
// https://www.mediawiki.org/wiki/Extension:OpenID_Connect#Keycloak
|
||||
$wgPluggableAuth_Config[] = [
|
||||
'plugin' => 'OpenIDConnect',
|
||||
'data' => [
|
||||
'providerURL' => 'https://auth.pub.solar/realms/pub.solar',
|
||||
'clientID' => 'mediawiki',
|
||||
'clientsecret' => trim(file_get_contents('/run/mediawiki/oidc-client-secret'))
|
||||
]
|
||||
];
|
||||
$wgOpenIDConnect_SingleLogout = true;
|
||||
$wgOpenIDConnect_MigrateUsersByEmail = true;
|
||||
'';
|
||||
|
||||
uid = 986;
|
||||
gid = 984;
|
||||
in
|
||||
{
|
||||
in {
|
||||
age.secrets.mediawiki-database-password = {
|
||||
file = "${flake.self}/secrets/mediawiki-database-password.age";
|
||||
path = "/run/mediawiki/database-password";
|
||||
|
@ -208,7 +206,7 @@ in
|
|||
backend = "docker";
|
||||
|
||||
containers."mediawiki" = {
|
||||
image = "git.pub.solar/pub-solar/mediawiki-oidc-docker:1.41.1";
|
||||
image = "git.pub.solar/pub-solar/mediawiki-oidc-docker:latest";
|
||||
user = "1000:${builtins.toString gid}";
|
||||
autoStart = true;
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Before ![]() (image error) Size: 29 KiB |
|
@ -1,119 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
id="Layer_3"
|
||||
data-name="Layer 3"
|
||||
viewBox="0 0 275.3 276.37"
|
||||
version="1.1"
|
||||
sodipodi:docname="pubsolar.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview226"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4.3962803"
|
||||
inkscape:cx="95.762774"
|
||||
inkscape:cy="149.33079"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1380"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_3" />
|
||||
<defs
|
||||
id="defs197">
|
||||
<style
|
||||
id="style195">.cls-1,.cls-2{fill:#ed1c24;}.cls-1{stroke:#ed1c24;stroke-width:6.89px;}.cls-1,.cls-2,.cls-4{stroke-miterlimit:10;}.cls-2{stroke:#fff;stroke-width:4.72px;}.cls-3{fill:#fff;}.cls-4{stroke:#000;stroke-width:4.58px;}</style>
|
||||
</defs>
|
||||
<title
|
||||
id="title199">PubSolar logo</title>
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M362.85,272.68v11.78l-4.39,1.84a18.38,18.38,0,0,0-11.24,15.8l-.59,9.43-7.92.61a18.38,18.38,0,0,0-15.53,11.22l-2.47,5.9H309.07a18.38,18.38,0,0,0-14.13,6.63l-6.8,8.17-10.58-3.17a18.38,18.38,0,0,0-14.89,1.95l-9.84,6-8.65-5.75a18.38,18.38,0,0,0-15.75-2.2l-10,3.17-5.88-7a18.38,18.38,0,0,0-15.43-6.51l-10.24.76-4.62-8.75a18.38,18.38,0,0,0-14.22-9.69l-9.7-1.08-1.89-10.65a18.38,18.38,0,0,0-11.06-13.77L134.7,283l.93-11.32a18.38,18.38,0,0,0-7-16l-6.52-5.06,3.55-8.77a18.38,18.38,0,0,0-1.77-17.13l-5.74-8.57,6.06-8a18.38,18.38,0,0,0,2.54-17.63l-3.93-10.34,5.12-2.87a18.38,18.38,0,0,0,9.31-17.78l-1.12-11.75,8.18-2.64a18.38,18.38,0,0,0,12.67-16l.75-9.5h6.44a18.38,18.38,0,0,0,17.59-13L184,99.13l12.19,1.25a18.38,18.38,0,0,0,17.27-8.25l4.11-6.3,8.21,3.79a18.38,18.38,0,0,0,20.12-3.14l5.85-5.36L261,88.21a18.38,18.38,0,0,0,18.23,2.32L287.76,87l6,7.67a18.38,18.38,0,0,0,15.32,7l11.25-.51,3.21,7.56a18.38,18.38,0,0,0,15.29,11.12l9.33.83.48,7.39A18.38,18.38,0,0,0,358.1,143l9.37,5.18-.71,11.41a18.38,18.38,0,0,0,7.43,15.93l7.14,5.26-3.79,10.66a18.38,18.38,0,0,0,2,16.27l5.57,8.45-6.46,10.31a18.38,18.38,0,0,0-2.11,14.77l2.66,9.38-9.63,7.93A18.38,18.38,0,0,0,362.85,272.68Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path201" />
|
||||
<circle
|
||||
class="cls-2"
|
||||
cx="137.72"
|
||||
cy="138.48"
|
||||
r="117.79"
|
||||
id="circle203" />
|
||||
<path
|
||||
class="cls-3"
|
||||
d="M326.34,141.78A105.72,105.72,0,0,0,181.56,295.61,105.7,105.7,0,1,1,326.34,141.78Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path205" />
|
||||
<path
|
||||
class="cls-3"
|
||||
d="m 180.73,231.12 c 0.57,1.71 6.47,20.7 10,30 3.53,9.3 7.59,16.9 12.87,17.74 5.28,0.84 10.64,-7.56 16.9,-7.78 8.76,-0.31 13.68,-1 18.13,-8.12 3.56,-5.67 9.9,1.76 25.87,-7.49 8.71,-5 26.56,-4.08 43.4,-11.91 20.26,-9.42 6.82,-12 6.83,-24 0,-3.84 3.66,-4.88 9.42,-7.17 3.82,-1.52 9.75,-4.8 8.63,-8.92 -1.24,-4.55 -0.79,-6.28 -5.2,-7.93 -8.95912,-3.35701 -15.41112,0.51436 -20.81894,2.56685 -7.90305,3.13369 -9.25397,-5.78637 -14.68734,-7.38637 -3.84252,-1.13153 -10.81538,-2.53029 -12.21968,-9.01195 C 278.1258,173.18465 270.1,170.58 261.8,170.42 c -4.33,-0.08 -8,1.37 -11,-5.82 -3.38,-8.07 -10.07,-19.35 -16.92,-12 -6.85,7.35 2,17.55 3.13,27 0.19,1.55 -0.08,3 -1.63,3.23 -3.79619,0.48553 -7.30604,2.27403 -9.93,5.06 -4.27,4.41 -8.18,-2.59 -15.09,3.8 -6.32,5.85 -13.27,-0.73 -25.52,-0.41 -20.65,0.56 -4.11,39.84 -4.11,39.84 z"
|
||||
transform="translate(-113.88,-76.62)"
|
||||
id="path207"
|
||||
sodipodi:nodetypes="csscccccccccscccscccccc" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M200.74,254.41a27,27,0,0,0,1.31,3c2.16,4.33,1.11,2.86,3.11,6.36,1.22,2.13,4.06,6.21,2.11,6.86-1.68.56-4.06-1-4.75-3.08-.34-1-.59-2.08-.93-3.1-2.72-8.19-6.6-15.8-9.33-24-3-9-5.76-18.25-7.12-27.94-.46-3.57-3.28-10.18-.86-11,1.49-.49,2.14.53,2.48,1.55.74,2.23.09,2.45.5,3.66a1.31,1.31,0,0,0,1.7.78c1.68-.56,1.9-3.63,3.95-4.31,7.36-2.45,15.23,5.38,17.4,11.9,1.48,6-1.4,10.39-6.34,15.14a7.39,7.39,0,0,1-2.86,1.67c-2,.68-4.81.46-6.12.89s-1.61,1.36-1.15,2.76,1.21,2.7,1.67,4.1c.68,2,1.15,4.07,1.83,6.11a13.67,13.67,0,0,0,.71,1.83C198.94,249.94,200,252.18,200.74,254.41Zm-6.45-48.32c-6.52,2.17-4.88,13.31-3,19.08,1.3,3.91,4.19,5.44,8.09,4.14,5.59-1.86,9.23-8.65,7.37-14.24C205.11,211,199.22,204.45,194.29,206.09Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path209" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M216.34,197.41a.88.88,0,0,1,1.35.45c2.1,3.85,3.09,9.07,5.33,13.18,2.1,3.85,7.1,7,9.45,5.68,2.67-1.46,4.77-8.79,2.56-12.83-.64-1.17-1.64-2.24-2.5-3.8-1.32-2.41-2.15-6.11.13-7.35,1.37-.75,1.92-.2,2.31.52.07.13.08.29.15.43.25.46.59.78.84,1.23,1.1,2,1.14,4.88,1.54,6.86a21.85,21.85,0,0,0,2,6.08,14.16,14.16,0,0,0,4.19,4.74c.38.38,1,.73,1.24,1.18a1.24,1.24,0,0,1-.71,1.66c-.85.46-3.88-1.52-4.84-3.28-.21-.39-.3-.85-.55-1.31a.78.78,0,0,0-1.14-.23c-.65.36-.62,2.12-.83,2.82-.76,2-1.51,4.21-3.33,5.21-4,2.21-9.11-1.63-10.89-4.89-.43-.78-.79-1.6-1.25-2.45C219.43,207.58,215.43,197.91,216.34,197.41Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path211" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M251.1,184.25c.22.55.06,1.41,1.17,1,.62-.24.83-1.12,1.06-1.77a7.57,7.57,0,0,1,4.54-4.5c6.36-2.5,13.65,1.82,15.88,7.49,2.12,5.39,1,13.9-5.72,16.54a10.23,10.23,0,0,1-5.58.43,4,4,0,0,0-2-.18c-.9.35,0,2.33-1.08,2.74-1.94.76-3.25-.83-4.09-2.74-1.37-3.29-3.11-8.25-4.44-11.64s-2.43-7.19-3.84-10.79c-1.33-3.39-3-6.71-4.39-10.17-.6-1.52-1.13-3.07-1.7-4.52a17.75,17.75,0,0,0-2.25-4.31,1,1,0,0,1-.23-.39,1.46,1.46,0,0,1,1.06-1.77,1.54,1.54,0,0,1,2.14,1l.14.35a75.7,75.7,0,0,0,3.53,10.19c.35.9.8,1.84,1.15,2.74l-.07,0C247.73,177.34,249.77,180.86,251.1,184.25Zm8-3.06c-5.33,2.09-6.44,8.2-4.32,13.59a9.89,9.89,0,0,0,13,5.9c4.36-1.71,5.62-9.07,3.88-13.5C268.24,181.58,263.7,179.37,259.07,181.19Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path213" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M216.42,242.8c-.49-2.48,2.88-6.17,6.16-6.81,1.83-.36,4.94.47,5.28,2.22a1.91,1.91,0,0,1-1.12,2c-1.38.27-2.88-1.93-4.33-1.65s-3.39,2.41-3.13,3.72c.59,3,7.19,5.79,10.06,8.48a7,7,0,0,1,2.07,3.61,7.5,7.5,0,0,1-5.63,8.37c-5.76,1.13-9.07-3-11.63-6.81a2,2,0,0,1-.39-.83,1.4,1.4,0,0,1,1-1.71c.87-.17,1.43.7,1.86,1.38,1.5,3,4,6.41,8.28,5.57,2.7-.53,4.44-3.22,3.79-6.57C227.21,249.93,217.23,247,216.42,242.8Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path215" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M244.38,250.12c-6.18-5.9-6.33-14.67-2.63-18.54,2.46-2.58,9.1-4.36,13.13-.51,3.39,3.23,6.36,13.57,1.38,18.78a6.15,6.15,0,0,1-5.21,1.91,7.1,7.1,0,0,0-3.3.34c-.83.33-1,.34-1.85-.43-.27-.26-.59-.67-1.08-1.13Zm8.85-17.44a6.87,6.87,0,0,0-9.3.16c-2.62,2.74-1.09,12.22,1.38,14.58s7.16,2.94,9.68.3C258,244.55,257.58,236.83,253.23,232.67Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path217" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M269.24,237.75a63.21,63.21,0,0,0-2.83-6.39s-1-2.71-1.6-4.88c-.76-1.94-1.59-3.84-2.35-5.78-2.09-5.33-10.17-21.45-6.49-20.18,1.83.63,2.79.82,3.06,1.52a28.65,28.65,0,0,1,1,4.84c1.23,4.66,4.57,13.94,6.83,19.68.9,2.28,1.89,4.61,2.93,6.83,2,4.46,4.33,9.33,4.18,10.25C273.94,243.64,272.62,248.25,269.24,237.75Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path219" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M288.05,226.57c1-.37,1.51-1,1.29-2.58-.3-2.13-2.48-6.48-4.62-6.18-1.84.26-3.45,3.78-4.85,4-.59.08-1.23-.73-1.29-1.17-.26-1.84,4.38-4.66,5.92-4.88,5.22-.73,7.52,9.3,9.65,15.91.44,1.52,1,2.41,2.74,2.39.68.06,1.72,0,1.83.72A2.08,2.08,0,0,1,297,237c-1.25.17-2.61-1.51-3.64-1.37-2.06.29-3.5,3.94-6.3,4.33a4.31,4.31,0,0,1-4.94-3.66c0-.22,0-.45,0-.67C281.56,230.56,283.06,228.39,288.05,226.57ZM284.42,235c.21,1.47.62,2.84,2.54,2.57s5.26-4.26,5-6.32c-.33-2.36-2.1-2.71-3.91-2.76C285.44,228.81,284,231.64,284.42,235Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path221" />
|
||||
<path
|
||||
class="cls-4"
|
||||
d="M306.07,208c2.38-.87,14.61-5.28,16.95-6.05.86-.23,1.94-.52,2.28.78.92,3.45-22.71,6-20.38,14.81,1.28,4.81,2.85,9.55,4,14.3.25.93.1,1.82-1,2.11-2.08.56-4.25-10.17-4.27-10.24C301.92,216.9,299.43,210.42,306.07,208Z"
|
||||
transform="translate(-113.88 -76.62)"
|
||||
id="path223" />
|
||||
<ellipse
|
||||
style="fill:#000000;fill-rule:evenodd;stroke-width:0.83809"
|
||||
id="path429"
|
||||
cx="172.17104"
|
||||
cy="122.1034"
|
||||
rx="4.5852861"
|
||||
ry="4.9624691" />
|
||||
<metadata
|
||||
id="metadata3053">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title>PubSolar logo</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
Before (image error) Size: 8.7 KiB |
|
@ -1,7 +0,0 @@
|
|||
# Welcome to your pub.solar cloud!
|
||||
|
||||
By default, the cloud is limited to 10MB of storage. If you want more, just send a short request to [crew@pub.solar](mailto:crew@pub.solar).
|
||||
|
||||
To download a desktop client, go to https://nextcloud.com/download.
|
||||
|
||||
You can edit this file by clicking here, and put any contents you want as notes for this directory :)
|
|
@ -1,7 +1,8 @@
|
|||
{ config
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
flake,
|
||||
...
|
||||
}:
|
||||
{
|
||||
age.secrets."nextcloud-secrets" = {
|
||||
|
@ -26,17 +27,15 @@
|
|||
home = "/var/lib/nextcloud";
|
||||
|
||||
enable = true;
|
||||
package = pkgs.nextcloud28;
|
||||
package = pkgs.nextcloud27;
|
||||
https = true;
|
||||
secretFile = config.age.secrets."nextcloud-secrets".path; # secret
|
||||
maxUploadSize = "1G";
|
||||
skeletonDirectory = "./nextcloud-skeleton";
|
||||
|
||||
configureRedis = true;
|
||||
|
||||
notify_push = {
|
||||
enable = true;
|
||||
bendDomainToLocalhost = true;
|
||||
};
|
||||
|
||||
config = {
|
||||
|
@ -47,6 +46,11 @@
|
|||
dbname = "nextcloud";
|
||||
dbtableprefix = "oc_";
|
||||
overwriteProtocol = "https";
|
||||
|
||||
trustedProxies = [
|
||||
"127.0.0.1"
|
||||
"::1"
|
||||
];
|
||||
};
|
||||
|
||||
extraOptions = {
|
||||
|
@ -62,7 +66,7 @@
|
|||
mail_smtpname = "admins@pub.solar";
|
||||
mail_smtpsecure = "tls";
|
||||
mail_smtpauth = 1;
|
||||
mail_smtphost = "mail.greenbaum.zone";
|
||||
mail_smtphost = "mx2.greenbaum.cloud";
|
||||
mail_smtpport = "587";
|
||||
|
||||
# This is to allow connections to collabora and keycloak, among other services
|
||||
|
@ -97,7 +101,6 @@
|
|||
integrity.check.disabled = false;
|
||||
updater.release.channel = "stable";
|
||||
loglevel = 0;
|
||||
maintenance_window_start = "1";
|
||||
# maintenance = false;
|
||||
app_install_overwrite = [
|
||||
"pdfdraw"
|
||||
|
@ -109,10 +112,7 @@
|
|||
};
|
||||
|
||||
phpOptions = {
|
||||
"opcache.interned_strings_buffer" = "32";
|
||||
# https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#:~:text=opcache.jit%20%3D%201255%20opcache.jit_buffer_size%20%3D%20128m
|
||||
"opcache.jit" = "1255";
|
||||
"opcache.jit_buffer_size" = "128M";
|
||||
"opcache.interned_strings_buffer" = "16";
|
||||
};
|
||||
|
||||
# Calculated with 4GiB RAM, 80MiB process size available on
|
||||
|
@ -131,7 +131,7 @@
|
|||
database.createLocally = true;
|
||||
};
|
||||
|
||||
services.restic.backups.nextcloud-droppie = {
|
||||
services.restic.backups.nextcloud = {
|
||||
paths = [
|
||||
"/var/lib/nextcloud/data"
|
||||
"/tmp/nextcloud-backup.sql"
|
||||
|
@ -150,34 +150,5 @@
|
|||
backupCleanupCommand = ''
|
||||
rm /tmp/nextcloud-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
|
||||
services.restic.backups.nextcloud-storagebox = {
|
||||
paths = [
|
||||
"/var/lib/nextcloud/data"
|
||||
"/tmp/nextcloud-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 04:00:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
passwordFile = config.age.secrets."restic-repo-storagebox".path;
|
||||
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d nextcloud > /tmp/nextcloud-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/nextcloud-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,55 +3,40 @@ let
|
|||
cfg = config.services.mastodon;
|
||||
in
|
||||
{
|
||||
services.nginx = {
|
||||
virtualHosts = {
|
||||
"mastodon.pub.solar" = {
|
||||
root = "${cfg.package}/public/";
|
||||
# mastodon only supports https, but you can override this if you offload tls elsewhere.
|
||||
forceSSL = lib.mkDefault true;
|
||||
enableACME = lib.mkDefault true;
|
||||
services.nginx.virtualHosts = {
|
||||
"mastodon.pub.solar" = {
|
||||
root = "${cfg.package}/public/";
|
||||
# mastodon only supports https, but you can override this if you offload tls elsewhere.
|
||||
forceSSL = lib.mkDefault true;
|
||||
enableACME = lib.mkDefault true;
|
||||
|
||||
locations."/auth/sign_up".extraConfig = ''
|
||||
return 302 /auth/sign_in;
|
||||
'';
|
||||
locations."/system/".alias = "/var/lib/mastodon/public-system/";
|
||||
|
||||
locations."/auth/confirmation/new".extraConfig = ''
|
||||
return 302 https://auth.pub.solar/realms/pub.solar/login-actions/reset-credentials?client_id=mastodon;
|
||||
'';
|
||||
|
||||
locations."/auth/password/new".extraConfig = ''
|
||||
return 302 https://auth.pub.solar/realms/pub.solar/login-actions/reset-credentials?client_id=mastodon;
|
||||
'';
|
||||
|
||||
locations."/system/".alias = "/var/lib/mastodon/public-system/";
|
||||
|
||||
locations."/" = {
|
||||
tryFiles = "$uri @proxy";
|
||||
};
|
||||
|
||||
locations."@proxy" = {
|
||||
proxyPass = (if cfg.enableUnixSocket then "http://unix:/run/mastodon-web/web.socket" else "http://127.0.0.1:${toString(cfg.webPort)}");
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
|
||||
locations."/api/v1/streaming/" = {
|
||||
proxyPass = "http://mastodon-streaming";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
locations."/" = {
|
||||
tryFiles = "$uri @proxy";
|
||||
};
|
||||
};
|
||||
|
||||
upstreams.mastodon-streaming = {
|
||||
extraConfig = ''
|
||||
least_conn;
|
||||
locations."/auth/sign_up".extraConfig = ''
|
||||
return 302 /auth/sign_in;
|
||||
'';
|
||||
servers = builtins.listToAttrs
|
||||
(map
|
||||
(i: {
|
||||
name = "unix:/run/mastodon-streaming/streaming-${toString i}.socket";
|
||||
value = { };
|
||||
})
|
||||
(lib.range 1 cfg.streamingProcesses));
|
||||
|
||||
locations."/auth/confirmation/new".extraConfig = ''
|
||||
return 302 https://auth.pub.solar/realms/pub.solar/login-actions/reset-credentials?client_id=mastodon;
|
||||
'';
|
||||
|
||||
locations."/auth/password/new".extraConfig = ''
|
||||
return 302 https://auth.pub.solar/realms/pub.solar/login-actions/reset-credentials?client_id=mastodon;
|
||||
'';
|
||||
|
||||
locations."@proxy" = {
|
||||
proxyPass = (if cfg.enableUnixSocket then "http://unix:/run/mastodon-web/web.socket" else "http://127.0.0.1:${toString(cfg.webPort)}");
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
|
||||
locations."/api/v1/streaming/" = {
|
||||
proxyPass = (if cfg.enableUnixSocket then "http://unix:/run/mastodon-streaming/streaming.socket" else "http://127.0.0.1:${toString(cfg.streamingPort)}/");
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,16 +5,16 @@ let
|
|||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
'';
|
||||
clientConfig = import ./matrix/element-client-config.nix { inherit lib pkgs; };
|
||||
clientConfig = import ./matrix/element-client-config.nix;
|
||||
wellKnownClient = domain: {
|
||||
"m.homeserver".base_url = "https://matrix.${domain}";
|
||||
"m.identity_server".base_url = "https://matrix.${domain}";
|
||||
"org.matrix.msc3575.proxy".url = "https://matrix.${domain}";
|
||||
"org.matrix.msc3575.proxy".url = "https://matrix.${domain}/sliding-sync";
|
||||
"im.vector.riot.e2ee".default = true;
|
||||
"io.element.e2ee" = {
|
||||
default = true;
|
||||
secure_backup_required = false;
|
||||
secure_backup_setup_methods = [ ];
|
||||
secure_backup_setup_methods = [];
|
||||
};
|
||||
"m.integrations" = {
|
||||
managers = [
|
||||
|
@ -25,27 +25,7 @@ let
|
|||
];
|
||||
};
|
||||
};
|
||||
wellKnownServer = domain: { "m.server" = "matrix.${domain}:8448"; };
|
||||
wellKnownSupport = {
|
||||
contacts = [
|
||||
{
|
||||
email_address = "crew@pub.solar";
|
||||
matrix_id = "@b12f:pub.solar";
|
||||
role = "m.role.admin";
|
||||
}
|
||||
{
|
||||
email_address = "crew@pub.solar";
|
||||
matrix_id = "@hensoko:pub.solar";
|
||||
role = "m.role.admin";
|
||||
}
|
||||
{
|
||||
email_address = "crew@pub.solar";
|
||||
matrix_id = "@teutat3s:pub.solar";
|
||||
role = "m.role.admin";
|
||||
}
|
||||
];
|
||||
support_page = "https://pub.solar/about";
|
||||
};
|
||||
wellKnownServer = domain: { "m.server" = "${domain}:8448"; };
|
||||
mkWellKnown = data: ''
|
||||
add_header Content-Type application/json;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
|
@ -54,7 +34,6 @@ let
|
|||
wellKnownLocations = domain: {
|
||||
"= /.well-known/matrix/server".extraConfig = mkWellKnown (wellKnownServer domain);
|
||||
"= /.well-known/matrix/client".extraConfig = mkWellKnown (wellKnownClient domain);
|
||||
"= /.well-known/matrix/support".extraConfig = mkWellKnown wellKnownSupport;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
@ -68,7 +47,11 @@ in
|
|||
locations = wellKnownLocations "pub.solar";
|
||||
};
|
||||
|
||||
"chat.pub.solar" = {
|
||||
#######################################
|
||||
# Stuff below is still in betatesting #
|
||||
#######################################
|
||||
|
||||
"chat.test.pub.solar" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
root = pkgs.element-web.override {
|
||||
|
@ -76,7 +59,7 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
"matrix.pub.solar" = {
|
||||
"matrix.test.pub.solar" = {
|
||||
root = "/dev/null";
|
||||
|
||||
forceSSL = lib.mkDefault true;
|
||||
|
@ -87,19 +70,16 @@ in
|
|||
gzip on;
|
||||
gzip_types text/plain application/json;
|
||||
'';
|
||||
locations = {
|
||||
# For telegram
|
||||
locations = (wellKnownLocations "test.pub.solar") // {
|
||||
# TODO: Configure metrics
|
||||
# "/metrics" = {
|
||||
# };
|
||||
|
||||
"/c3c3f34b-29fb-5feb-86e5-98c75ec8214b" = {
|
||||
proxyPass = "http://127.0.0.1:8009";
|
||||
extraConfig = commonHeaders;
|
||||
};
|
||||
|
||||
# sliding-sync
|
||||
"~ ^/(client/|_matrix/client/unstable/org.matrix.msc3575/sync)" = {
|
||||
proxyPass = "http://127.0.0.1:8011";
|
||||
extraConfig = commonHeaders;
|
||||
};
|
||||
|
||||
"~* ^(/_matrix|/_synapse/client|/_synapse/oidc)" = {
|
||||
proxyPass = "http://127.0.0.1:8008";
|
||||
|
||||
|
@ -117,19 +97,18 @@ in
|
|||
};
|
||||
};
|
||||
"matrix.pub.solar-federation" = {
|
||||
serverName = "matrix.pub.solar";
|
||||
serverName = "matrix.test.pub.solar";
|
||||
forceSSL = lib.mkDefault true;
|
||||
enableACME = lib.mkDefault true;
|
||||
listen = [{
|
||||
port = 8448;
|
||||
addr = "0.0.0.0";
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
port = 8448;
|
||||
addr = "[::]";
|
||||
ssl = true;
|
||||
}];
|
||||
} {
|
||||
port = 8448;
|
||||
addr = "[::]";
|
||||
ssl = true;
|
||||
}];
|
||||
root = "/dev/null";
|
||||
extraConfig = ''
|
||||
server_tokens off;
|
||||
|
@ -151,6 +130,6 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 8448 ];
|
||||
networking.firewall.allowedTCPPorts = [8448];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
{ config, flake, lib, ... }:
|
||||
let
|
||||
# Find element in list config.services.matrix-synapse.settings.listeners
|
||||
# that sets type = "metrics"
|
||||
listenerWithMetrics = lib.findFirst
|
||||
(listener:
|
||||
listener.type == "metrics")
|
||||
(throw "Found no matrix-synapse.settings.listeners.*.type containing string metrics")
|
||||
config.services.matrix-synapse.settings.listeners
|
||||
;
|
||||
synapseMetricsPort = "${toString listenerWithMetrics.port}";
|
||||
in
|
||||
{
|
||||
age.secrets.nachtigall-metrics-nginx-basic-auth = {
|
||||
file = "${flake.self}/secrets/nachtigall-metrics-nginx-basic-auth.age";
|
||||
mode = "600";
|
||||
owner = "nginx";
|
||||
};
|
||||
services.nginx.virtualHosts = {
|
||||
"nachtigall.pub.solar" = {
|
||||
enableACME = true;
|
||||
addSSL = true;
|
||||
basicAuthFile = "${config.age.secrets.nachtigall-metrics-nginx-basic-auth.path}";
|
||||
locations."/metrics" = {
|
||||
proxyPass = "http://127.0.0.1:${toString(config.services.prometheus.exporters.node.port)}";
|
||||
};
|
||||
locations."/_synapse/metrics" = {
|
||||
proxyPass = "http://127.0.0.1:${synapseMetricsPort}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
{ ... }:
|
||||
|
||||
{
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '/srv/www/miom.space' 0750 hakkonaut hakkonaut - -"
|
||||
];
|
||||
|
||||
services.nginx.virtualHosts = {
|
||||
"www.miom.space" = {
|
||||
enableACME = true;
|
||||
addSSL = true;
|
||||
|
||||
extraConfig = ''
|
||||
error_log /dev/null;
|
||||
access_log /dev/null;
|
||||
'';
|
||||
|
||||
locations."/" = {
|
||||
extraConfig = ''
|
||||
return 301 https://miom.space$request_uri;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
"miom.space" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
extraConfig = ''
|
||||
error_log /dev/null;
|
||||
access_log /dev/null;
|
||||
'';
|
||||
|
||||
locations = {
|
||||
"/" = {
|
||||
root = "/srv/www/miom.space";
|
||||
index = "index.html";
|
||||
tryFiles = "$uri $uri/ =404";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
{ lib, ... }: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '/srv/www/pub.solar' 0750 hakkonaut hakkonaut - -"
|
||||
];
|
||||
|
@ -7,12 +9,6 @@
|
|||
"www.pub.solar" = {
|
||||
enableACME = true;
|
||||
addSSL = true;
|
||||
|
||||
extraConfig = ''
|
||||
error_log /dev/null;
|
||||
access_log /dev/null;
|
||||
'';
|
||||
|
||||
locations."/" = {
|
||||
extraConfig = ''
|
||||
return 301 https://pub.solar$request_uri;
|
||||
|
@ -25,23 +21,18 @@
|
|||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
extraConfig = ''
|
||||
error_log /dev/null;
|
||||
access_log /dev/null;
|
||||
'';
|
||||
|
||||
locations = {
|
||||
# serve base domain pub.solar for mastodon.pub.solar
|
||||
# https://masto.host/mastodon-usernames-different-from-the-domain-used-for-installation/
|
||||
# serve base domain pub.solar for mastodon.pub.solar
|
||||
# https://masto.host/mastodon-usernames-different-from-the-domain-used-for-installation/
|
||||
"/.well-known/host-meta" = {
|
||||
extraConfig = ''
|
||||
return 301 https://mastodon.pub.solar$request_uri;
|
||||
'';
|
||||
};
|
||||
|
||||
# Tailscale OIDC webfinger requirement plus Mastodon webfinger redirect
|
||||
# Tailscale OIDC webfinger requirement plus Mastodon webfinger redirect
|
||||
"/.well-known/webfinger" = {
|
||||
# Redirect requests that match /.well-known/webfinger?resource=* to Mastodon
|
||||
# Redirect requests that match /.well-known/webfinger?resource=* to Mastodon
|
||||
extraConfig = ''
|
||||
if ($arg_resource) {
|
||||
return 301 https://mastodon.pub.solar$request_uri;
|
||||
|
@ -52,22 +43,6 @@
|
|||
'';
|
||||
};
|
||||
|
||||
# Responsible disclosure information https://securitytxt.org/
|
||||
"/.well-known/security.txt" = let
|
||||
securityTXT = lib.lists.foldr (a: b: a + "\n" + b) "" [
|
||||
"Contact: mailto:admins@pub.solar"
|
||||
"Expires: 2025-01-04T23:00:00.000Z"
|
||||
"Encryption: https://keys.openpgp.org/vks/v1/by-fingerprint/8A8987ADE3736C8CA2EB315A9B809EBBDD62BAE3"
|
||||
"Preferred-Languages: en,de"
|
||||
"Canonical: https://pub.solar/.well-known/security.txt"
|
||||
];
|
||||
in {
|
||||
extraConfig = ''
|
||||
add_header Content-Type text/plain;
|
||||
return 200 '${securityTXT}';
|
||||
'';
|
||||
};
|
||||
|
||||
"/satzung" = {
|
||||
extraConfig = ''
|
||||
return 302 https://cloud.pub.solar/s/iaKqiW25QJpHPYs;
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, self
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
self,
|
||||
...
|
||||
}: let
|
||||
acmeEmailAddress = "admins@pub.solar";
|
||||
webserverGroup = "hakkonaut";
|
||||
in
|
||||
{
|
||||
in {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
group = webserverGroup;
|
||||
|
@ -21,22 +20,15 @@ in
|
|||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
appendHttpConfig = ''
|
||||
# https://my.f5.com/manage/s/article/K51798430
|
||||
proxy_headers_hash_bucket_size 128;
|
||||
'';
|
||||
appendConfig = ''
|
||||
# Number of CPU cores
|
||||
worker_processes 8;
|
||||
'';
|
||||
eventsConfig = ''
|
||||
worker_connections 1024;
|
||||
# https://nginx.org/en/docs/hash.html
|
||||
proxy_headers_hash_max_size 1024;
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = acmeEmailAddress;
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{ flake
|
||||
, config
|
||||
, lib
|
||||
, pkgs
|
||||
, ...
|
||||
{
|
||||
flake,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
services.nginx.virtualHosts."stream.pub.solar" = {
|
||||
enableACME = true;
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
{ config
|
||||
, ...
|
||||
}: {
|
||||
services.prometheus = {
|
||||
exporters = {
|
||||
node = {
|
||||
enable = true;
|
||||
enabledCollectors = [ "systemd" ];
|
||||
port = 9002;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
{ config
|
||||
, lib
|
||||
, pkgs
|
||||
, flake
|
||||
, ...
|
||||
}: {
|
||||
age.secrets.nachtigall-metrics-prometheus-basic-auth-password = {
|
||||
file = "${flake.self}/secrets/nachtigall-metrics-prometheus-basic-auth-password.age";
|
||||
mode = "600";
|
||||
owner = "promtail";
|
||||
};
|
||||
|
||||
services.promtail = {
|
||||
enable = true;
|
||||
configuration = {
|
||||
server = {
|
||||
http_listen_port = 9080;
|
||||
grpc_listen_port = 0;
|
||||
};
|
||||
positions = {
|
||||
filename = "/tmp/positions.yaml";
|
||||
};
|
||||
clients = [{
|
||||
url = "https://flora-6.pub.solar/loki/api/v1/push";
|
||||
basic_auth = {
|
||||
username = "hakkonaut";
|
||||
password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}";
|
||||
};
|
||||
}];
|
||||
scrape_configs = [{
|
||||
job_name = "journal";
|
||||
journal = {
|
||||
max_age = "24h";
|
||||
labels = {
|
||||
job = "systemd-journal";
|
||||
host = "nachtigall";
|
||||
};
|
||||
};
|
||||
relabel_configs = [{
|
||||
source_labels = [ "__journal__systemd_unit" ];
|
||||
target_label = "unit";
|
||||
}];
|
||||
}];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
{ flake
|
||||
, config
|
||||
, lib
|
||||
, pkgs
|
||||
, ...
|
||||
{
|
||||
flake,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
age.secrets.searx-environment = {
|
||||
|
@ -32,7 +33,7 @@
|
|||
chmod-socket = "660";
|
||||
};
|
||||
|
||||
environmentFile = config.age.secrets.searx-environment.path;
|
||||
environmentFile = config.age.secrets.searx-environment.path;
|
||||
|
||||
settings = {
|
||||
use_default_settings = true;
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
{ ... }:
|
||||
{
|
||||
services.tmate-ssh-server = {
|
||||
enable = true;
|
||||
port = 2222;
|
||||
openFirewall = true;
|
||||
host = "tmate.pub.solar";
|
||||
};
|
||||
}
|
|
@ -4,9 +4,4 @@
|
|||
mode = "400";
|
||||
owner = "root";
|
||||
};
|
||||
age.secrets."restic-repo-storagebox" = {
|
||||
file = "${flake.self}/secrets/restic-repo-storagebox.age";
|
||||
mode = "400";
|
||||
owner = "root";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{ flake
|
||||
, config
|
||||
, pkgs
|
||||
, ...
|
||||
{
|
||||
flake,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
# Use GRUB2 as the boot loader.
|
||||
# We don't use systemd-boot because Hetzner uses BIOS legacy boot.
|
||||
|
|
|
@ -1,39 +1,31 @@
|
|||
{ flake, ... }:
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
# Include the results of the hardware scan.
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
./configuration.nix
|
||||
|
||||
./networking.nix
|
||||
./wireguard.nix
|
||||
./backups.nix
|
||||
./apps/nginx.nix
|
||||
|
||||
./apps/collabora.nix
|
||||
./apps/coturn.nix
|
||||
./apps/forgejo.nix
|
||||
./apps/keycloak.nix
|
||||
./apps/mailman.nix
|
||||
./apps/mastodon.nix
|
||||
./apps/mediawiki.nix
|
||||
./apps/nextcloud.nix
|
||||
./apps/owncast.nix
|
||||
./apps/nginx-mastodon.nix
|
||||
./apps/nginx-mastodon-files.nix
|
||||
./apps/nginx-prometheus-exporters.nix
|
||||
./apps/nginx-website.nix
|
||||
./apps/nginx-website-miom.nix
|
||||
./apps/opensearch.nix
|
||||
./apps/owncast.nix
|
||||
./apps/postgresql.nix
|
||||
./apps/prometheus-exporters.nix
|
||||
./apps/promtail.nix
|
||||
./apps/searx.nix
|
||||
./apps/tmate.nix
|
||||
|
||||
./apps/matrix/irc.nix
|
||||
./apps/matrix/matrix-hookshot.nix
|
||||
./apps/matrix/mautrix-telegram.nix
|
||||
./apps/matrix/synapse.nix
|
||||
./apps/nginx-matrix.nix
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ahci" "nvme" ];
|
||||
|
@ -15,38 +14,32 @@
|
|||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{
|
||||
device = "root_pool/root";
|
||||
{ device = "root_pool/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/var/lib" =
|
||||
{
|
||||
device = "root_pool/data";
|
||||
{ device = "root_pool/data";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/var/lib/postgresql" =
|
||||
{
|
||||
device = "root_pool/data/postgresql";
|
||||
{ device = "root_pool/data/postgresql";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/var/lib/docker" =
|
||||
{
|
||||
device = "root_pool/data/docker";
|
||||
{ device = "root_pool/data/docker";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot1" =
|
||||
{
|
||||
device = "/dev/disk/by-uuid/5493-EFF5";
|
||||
{ device = "/dev/disk/by-uuid/5493-EFF5";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
fileSystems."/boot2" =
|
||||
{
|
||||
device = "/dev/disk/by-uuid/5494-BA1E";
|
||||
{ device = "/dev/disk/by-uuid/5494-BA1E";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
flake,
|
||||
... }:
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
|
||||
networking.hostName = "nachtigall";
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
flake,
|
||||
... }:
|
||||
{
|
||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
||||
|
||||
age.secrets.wg-private-key.file = "${flake.self}/secrets/nachtigall-wg-private-key.age";
|
||||
|
||||
networking.wireguard.interfaces = {
|
||||
wg-ssh = {
|
||||
listenPort = 51820;
|
||||
mtu = 1300;
|
||||
ips = [
|
||||
"10.7.6.1/32"
|
||||
"fd00:fae:fae:fae:fae:1::/96"
|
||||
];
|
||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
||||
peers = flake.self.logins.admins.wireguardDevices ++ [
|
||||
{ # flora-6.pub.solar
|
||||
endpoint = "80.71.153.210:51820";
|
||||
publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU=";
|
||||
allowedIPs = [ "10.7.6.2/32" "fd00:fae:fae:fae:fae:2::/96" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.openssh.listenAddresses = [
|
||||
{
|
||||
addr = "10.7.6.1";
|
||||
port = 22;
|
||||
}
|
||||
{
|
||||
addr = "[fd00:fae:fae:fae:fae:1::]";
|
||||
port = 22;
|
||||
}
|
||||
];
|
||||
}
|
|
@ -5,17 +5,17 @@ let
|
|||
});
|
||||
flake =
|
||||
import
|
||||
(
|
||||
fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||
}
|
||||
)
|
||||
{
|
||||
src = builtins.path {
|
||||
path = ../../.;
|
||||
name = "projectRoot";
|
||||
};
|
||||
(
|
||||
fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||
}
|
||||
)
|
||||
{
|
||||
src = builtins.path {
|
||||
path = ../../.;
|
||||
name = "projectRoot";
|
||||
};
|
||||
};
|
||||
in
|
||||
flake
|
||||
flake
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{ ... }:
|
||||
let
|
||||
{...}: let
|
||||
inherit (default.inputs.nixos) lib;
|
||||
|
||||
host = configs.${hostname} or configs.PubSolarOS;
|
||||
|
@ -7,4 +6,4 @@ let
|
|||
default = (import ../.).defaultNix;
|
||||
hostname = lib.fileContents /etc/hostname;
|
||||
in
|
||||
host
|
||||
host
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
{ self, lib, inputs, ... }: {
|
||||
# Configuration common to all Linux systems
|
||||
flake = {
|
||||
lib =
|
||||
let
|
||||
callLibs = file: import file { inherit lib; };
|
||||
in
|
||||
rec {
|
||||
## Define your own library functions here!
|
||||
#id = x: x;
|
||||
## Or in files, containing functions that take {lib}
|
||||
#foo = callLibs ./foo.nix;
|
||||
## In configs, they can be used under "lib.our"
|
||||
lib = let
|
||||
callLibs = file: import file {inherit lib;};
|
||||
in rec {
|
||||
## Define your own library functions here!
|
||||
#id = x: x;
|
||||
## Or in files, containing functions that take {lib}
|
||||
#foo = callLibs ./foo.nix;
|
||||
## In configs, they can be used under "lib.our"
|
||||
|
||||
deploy = import ./deploy.nix { inherit inputs lib; };
|
||||
};
|
||||
deploy = import ./deploy.nix { inherit inputs lib; };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* Licensed under the MIT license
|
||||
*/
|
||||
|
||||
{ lib, inputs }:
|
||||
let
|
||||
{ lib, inputs }: let
|
||||
# https://github.com/serokell/deploy-rs#overall-usage
|
||||
system = "x86_64-linux";
|
||||
pkgs = import inputs.nixpkgs { inherit system; };
|
||||
|
@ -17,59 +16,57 @@ let
|
|||
(self: super: { deploy-rs = { inherit (pkgs) deploy-rs; lib = super.deploy-rs.lib; }; })
|
||||
];
|
||||
};
|
||||
getFqdn = c:
|
||||
let
|
||||
net = c.config.networking;
|
||||
fqdn =
|
||||
if (net ? domain) && (net.domain != null)
|
||||
then "${net.hostName}.${net.domain}"
|
||||
else net.hostName;
|
||||
in
|
||||
getFqdn = c: let
|
||||
net = c.config.networking;
|
||||
fqdn =
|
||||
if (net ? domain) && (net.domain != null)
|
||||
then "${net.hostName}.${net.domain}"
|
||||
else net.hostName;
|
||||
in
|
||||
fqdn;
|
||||
in
|
||||
{
|
||||
in {
|
||||
mkDeployNodes = systemConfigurations: extraConfig:
|
||||
/*
|
||||
*
|
||||
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
|
||||
/*
|
||||
*
|
||||
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
|
||||
|
||||
Generate the `nodes` attribute expected by deploy-rs
|
||||
where _systemConfigurations_ are `nodes`.
|
||||
Generate the `nodes` attribute expected by deploy-rs
|
||||
where _systemConfigurations_ are `nodes`.
|
||||
|
||||
_systemConfigurations_ should take the form of a flake's
|
||||
_nixosConfigurations_. Note that deploy-rs does not currently support
|
||||
deploying to darwin hosts.
|
||||
_systemConfigurations_ should take the form of a flake's
|
||||
_nixosConfigurations_. Note that deploy-rs does not currently support
|
||||
deploying to darwin hosts.
|
||||
|
||||
_extraConfig_, if specified, will be merged into each of the
|
||||
nodes' configurations.
|
||||
_extraConfig_, if specified, will be merged into each of the
|
||||
nodes' configurations.
|
||||
|
||||
Example _systemConfigurations_ input:
|
||||
Example _systemConfigurations_ input:
|
||||
|
||||
```
|
||||
{
|
||||
hostname-1 = {
|
||||
fastConnection = true;
|
||||
sshOpts = [ "-p" "25" ];
|
||||
};
|
||||
hostname-2 = {
|
||||
sshOpts = [ "-p" "19999" ];
|
||||
sshUser = "root";
|
||||
};
|
||||
}
|
||||
```
|
||||
*
|
||||
*/
|
||||
```
|
||||
{
|
||||
hostname-1 = {
|
||||
fastConnection = true;
|
||||
sshOpts = [ "-p" "25" ];
|
||||
};
|
||||
hostname-2 = {
|
||||
sshOpts = [ "-p" "19999" ];
|
||||
sshUser = "root";
|
||||
};
|
||||
}
|
||||
```
|
||||
*
|
||||
*/
|
||||
lib.recursiveUpdate
|
||||
(lib.mapAttrs
|
||||
(
|
||||
_: c: {
|
||||
hostname = getFqdn c;
|
||||
profiles.system = {
|
||||
user = "root";
|
||||
path = deployPkgs.deploy-rs.lib.activate.nixos c;
|
||||
};
|
||||
}
|
||||
)
|
||||
systemConfigurations)
|
||||
extraConfig;
|
||||
(lib.mapAttrs
|
||||
(
|
||||
_: c: {
|
||||
hostname = getFqdn c;
|
||||
profiles.system = {
|
||||
user = "root";
|
||||
path = deployPkgs.deploy-rs.lib.activate.nixos c;
|
||||
};
|
||||
}
|
||||
)
|
||||
systemConfigurations)
|
||||
extraConfig;
|
||||
}
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
axeman = rec {
|
||||
sshPubKeys = {
|
||||
axeman-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMNeQYLFauAbzDyIbKC86NUh9yZfiyBm/BtIdkcpZnSU axeman@tuxnix";
|
||||
};
|
||||
|
||||
secretEncryptionKeys = sshPubKeys;
|
||||
|
||||
wireguardDevices = [
|
||||
{
|
||||
# tuxnix
|
||||
publicKey = "fTvULvdsc92binFaBV+uWwFi33bi8InShcaPnoxUZEA=";
|
||||
allowedIPs = [ "10.7.6.203/32" "fd00:fae:fae:fae:fae:203::/96" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
b12f = rec {
|
||||
sshPubKeys = {
|
||||
b12f-gpg = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDVbUEOgciblRPOCaCkkwfYoKLjmJ6JKxnfg6MY7sN3W1/N4AsC27bvYPkYI66d4M3Ygi6nztaUrIIKBOPZrQtS0vx1jqosmcDwBMttNI7u4LdSDjGMEGB4zJdfR60HFuzpSNaBI/nKMWcAxr8v1KODy/mKTQ7fnMDN15OhvE7sAZe26B6IptUbG1DLuouezd4AW0OwQ3c6hVIuv5eF96OKrwFZ9XpNyYAashy8WTYqJWJRb71DV8oiqT9b3sN0Dy+7nUAPcLvJdwUDGjHQvnklgFUupKtrPhpRWqgJ41l4ebb1DCxmoL2zpdVohUK4eVC9ELdplvXtK+EJIJ1lKcDAYduYcxk//3+EdUDH0IkfXvz0Tomryu2BeyxURdMPzQh+ctHUWNI49tByx/mWrEqSu+XdgvtcumVg+jNUZKL9eA++xxuOan7H/OyshptLugZHd2e9JNM34NEOUEptq7LtHD5pEdXRV1ZT1IOsuSoDtdX14GeP2GSl21eKLnvSu9g8nGULIsx9hI3CrrlvvL9JU+Aymb4iEvqLhDeUNE643uYQad6P2SuK0kLQ/9Ny0z3y6bgglGn2uDUiAOPd8c+gFRRkMWvAWjWQi3iIR9TYBS4Z+CeYmUv8X2UCRcQPBn1wt69rvE9RcfHqRLZTUE5SpstQ0rXLinXmRA/WQV5Bdw== yubi-gpg";
|
||||
};
|
||||
|
||||
secretEncryptionKeys = {
|
||||
bbcom = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCmXpOU6vzQiVSSYCoxHYv7wDxC63Qg3dxlAMR6AOzwIABCU5PFFNcO0NWYms/YR7MOViorl+19LCLRABar9JgHU1n+uqxKV6eGph3OPeMp5sN8LAh7C9N+TZj8iJzBxQ3ch+Z/LdmLRwYNJ7KSUI+gwGK6xRS3+z1022Y4P0G0sx7IeCBl4lealQEIIF10ZOfjUdBcLQar7XTc5AxyGKnHCerXHRtccCoadLQujk0AvPXbv3Ma4JwX9X++AnCWRWakqS5UInu2tGuZ/6Hrjd2a9AKWjTaBVDcbYqCvY4XVuMj2/A2bCceFBaoi41apybSk26FSFTU4qiEUNQ6lxeOwG4+1NCXyHe2bGI4VyoxinDYa8vLLzXIRfTRA0qoGfCweXNeWPf0jMqASkUKaSOH5Ot7O5ps34r0j9pWzavDid8QeKJPyhxKuF1a5G4iBEZ0O9vuti60dPSjJPci9oTxbune2/jb7Sa0yO06DtLFJ2ncr5f70s/BDxKk4XIwQLy+KsvzlQEGdY8yA6xv28bOGxL3sQ0HE2pDTsvIbAisVOKzdJeolStL9MM5W8Hg0r/KkGj2bg0TfoRp1xHV9hjKkvJrsQ6okaPvNFeZq0HXzPhWMOVQ+/46z80uaQ1ByRLr3FTwuWJ7F/73ndfxiq6bDE4z2Ji0vOjeWJm6HCxTdGw== hello@benjaminbaedorf.com";
|
||||
yubi485 = "age1yubikey1qgxuu2x3uzw7k5pg5sp2dv43edhwdz3xuhj7kjqrnw0p8t0l67c5yz9nm6q";
|
||||
yubi464 = "age1yubikey1qd7szmr9ux2znl4x4hzykkwaru60nr4ufu6kdd88sm7657gjz4x5w0jy4y7";
|
||||
} // sshPubKeys;
|
||||
|
||||
wireguardDevices = [
|
||||
{ # stroopwafel
|
||||
publicKey = "NNb7T8Jmn+V2dTZ8T6Fcq7hGomHGDckKoV3kK2oAhSE=";
|
||||
allowedIPs = [ "10.7.6.200/32" "fd00:fae:fae:fae:fae:200::/96" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
hensoko = rec {
|
||||
sshPubKeys = {
|
||||
hensoko-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEbaQdxp7Flz6ttELe63rn+Nt9g43qJOLih6VCMP4gPb";
|
||||
hensoko-2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAqkqMYgncrnczcW/0PY+Z+FmNXXpgw6D9JWTTwiainy";
|
||||
};
|
||||
|
||||
secretEncryptionKeys = sshPubKeys;
|
||||
wireguardDevices = [
|
||||
{ # judy
|
||||
publicKey = "I+gN7v1VXkAGoSir6L8aebtLbguvy5nAx1QVDTzdckk=";
|
||||
allowedIPs = [ "10.7.6.202/32" "fd00:fae:fae:fae:fae:202::/96" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
teutat3s = {
|
||||
sshPubKeys = {
|
||||
teutat3s-1 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFro/k4Mgqyh8yV/7Zwjc0dv60ZM7bROBU9JNd99P/4co6fxPt1pJiU/pEz2Dax/HODxgcO+jFZfvPEuLMCeAl0= YubiKey #10593996 PIV Slot 9a";
|
||||
};
|
||||
|
||||
secretEncryptionKeys = {
|
||||
teutat3s-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHcU6KPy4b1MQXd6EJhcYwbJu7E+0IrBZF/IP6T7gbMf teutat3s@dumpyourvms";
|
||||
};
|
||||
|
||||
wireguardDevices = [
|
||||
{ # dumpyourvms
|
||||
publicKey = "3UrVLQrwXnPAVXPiTAd7eM3fZYxnFSYgKAGpNMUwnUk=";
|
||||
allowedIPs = [ "10.7.6.201/32" "fd00:fae:fae:fae:fae:201::/96" ];
|
||||
}
|
||||
{ # ryzensun
|
||||
publicKey = "oVF2/s7eIxyVjtG0MhKPx5SZ1JllZg+ZFVF2eVYtPGo=";
|
||||
allowedIPs = [ "10.7.6.204/32" "fd00:fae:fae:fae:fae:204::/96" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{ lib, ... }: let
|
||||
admins = import ./admins.nix;
|
||||
robots = import ./robots.nix;
|
||||
in {
|
||||
flake = {
|
||||
logins = {
|
||||
admins = lib.lists.foldl (logins: adminConfig: {
|
||||
sshPubKeys = logins.sshPubKeys ++ (lib.attrsets.attrValues adminConfig.sshPubKeys);
|
||||
wireguardDevices = logins.wireguardDevices ++ (if adminConfig ? "wireguardDevices" then adminConfig.wireguardDevices else []);
|
||||
}) { sshPubKeys = []; wireguardDevices = []; } (lib.attrsets.attrValues admins);
|
||||
robots.sshPubKeys = lib.attrsets.attrValues robots;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,15 +1,6 @@
|
|||
{ pkgs, lib, ... }: {
|
||||
# Don't expose SSH via public interfaces
|
||||
networking.firewall.interfaces.wg-ssh.allowedTCPPorts = [ 22 ];
|
||||
|
||||
networking.hosts = {
|
||||
"10.7.6.1" = ["nachtigall.pub.solar"];
|
||||
"10.7.6.2" = ["flora-6.pub.solar"];
|
||||
};
|
||||
|
||||
{ pkgs, ... }: {
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
openFirewall = lib.mkDefault false;
|
||||
settings = {
|
||||
PermitRootLogin = "prohibit-password";
|
||||
PasswordAuthentication = false;
|
||||
|
@ -36,11 +27,14 @@
|
|||
|
||||
services.resolved = {
|
||||
enable = true;
|
||||
# DNSSEC=false because of random SERVFAIL responses with Greenbaum DNS
|
||||
# when using allow-downgrade, see https://github.com/systemd/systemd/issues/10579
|
||||
extraConfig = ''
|
||||
DNS=193.110.81.0#dns0.eu 185.253.5.0#dns0.eu 2a0f:fc80::#dns0.eu 2a0f:fc81::#dns0.eu 9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
|
||||
FallbackDNS=5.1.66.255#dot.ffmuc.net 185.150.99.255#dot.ffmuc.net 2001:678:e68:f000::#dot.ffmuc.net 2001:678:ed0:f000::#dot.ffmuc.net
|
||||
Domains=~.
|
||||
DNSOverTLS=yes
|
||||
DNSSEC=false
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{ config
|
||||
, pkgs
|
||||
, lib
|
||||
, flake
|
||||
, ...
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
flake,
|
||||
...
|
||||
}: {
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||
];
|
||||
|
@ -13,21 +14,15 @@
|
|||
gc.automatic = true;
|
||||
optimise.automatic = true;
|
||||
|
||||
registry = {
|
||||
nixpkgs.flake = flake.inputs.nixpkgs;
|
||||
unstable.flake = flake.inputs.unstable;
|
||||
system.flake = flake.self;
|
||||
};
|
||||
|
||||
settings = {
|
||||
# Improve nix store disk usage
|
||||
auto-optimise-store = true;
|
||||
# Prevents impurities in builds
|
||||
sandbox = true;
|
||||
# Give root and @wheel special privileges with nix
|
||||
trusted-users = [ "root" "@wheel" ];
|
||||
trusted-users = ["root" "@wheel"];
|
||||
# Allow only group wheel to connect to the nix daemon
|
||||
allowed-users = [ "@wheel" ];
|
||||
allowed-users = ["@wheel"];
|
||||
};
|
||||
|
||||
# Generally useful nix option defaults
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
# Please create this manually the first time.
|
||||
hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
|
||||
authorizedKeys = flake.self.logins.admins.sshPubKeys;
|
||||
authorizedKeys = flake.self.publicKeys.admins;
|
||||
};
|
||||
# this will automatically load the zfs password prompt on login
|
||||
# and kill the other prompt so boot can continue
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
users.users.${flake.self.username} = {
|
||||
name = flake.self.username;
|
||||
group = flake.self.username;
|
||||
extraGroups = [ "wheel" "docker" ];
|
||||
extraGroups = ["wheel" "docker"];
|
||||
isNormalUser = true;
|
||||
openssh.authorizedKeys.keys = flake.self.logins.admins.sshPubKeys;
|
||||
openssh.authorizedKeys.keys = flake.self.publicKeys.admins;
|
||||
};
|
||||
users.groups.${flake.self.username} = { };
|
||||
users.groups.${flake.self.username} = {};
|
||||
|
||||
# TODO: Remove when we stop locking ourselves out.
|
||||
users.users.root.openssh.authorizedKeys.keys = flake.self.logins.admins.sshPubKeys;
|
||||
users.users.root.openssh.authorizedKeys.keys = flake.self.publicKeys.admins;
|
||||
|
||||
users.users.hakkonaut = {
|
||||
description = "CI and automation user";
|
||||
|
@ -19,10 +19,10 @@
|
|||
uid = 998;
|
||||
group = "hakkonaut";
|
||||
isSystemUser = true;
|
||||
openssh.authorizedKeys.keys = flake.self.logins.robots.sshPubKeys;
|
||||
openssh.authorizedKeys.keys = flake.self.publicKeys.robots;
|
||||
};
|
||||
|
||||
users.groups.hakkonaut = { };
|
||||
users.groups.hakkonaut = {};
|
||||
|
||||
users.users.root.initialHashedPassword = "$y$j9T$bIN6GjQkmPMllOcQsq52K0$q0Z5B5.KW/uxXK9fItB8H6HO79RYAcI/ZZdB0Djke32";
|
||||
|
||||
|
|
|
@ -1,21 +1,18 @@
|
|||
{ self
|
||||
, inputs
|
||||
, ...
|
||||
{
|
||||
self,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
flake = {
|
||||
nixosModules = rec {
|
||||
overlays = ({ ... }: {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev:
|
||||
let
|
||||
unstable = import inputs.unstable {
|
||||
system = prev.system;
|
||||
};
|
||||
in
|
||||
{
|
||||
forgejo-runner = unstable.forgejo-runner;
|
||||
element-themes = prev.callPackage ./pkgs/element-themes { inherit (inputs) element-themes; };
|
||||
})
|
||||
(final: prev: {
|
||||
mastodon = inputs.mastodon-fork.legacyPackages.${prev.system}.mastodon;
|
||||
forgejo-actions-runner = inputs.unstable.legacyPackages.${prev.system}.forgejo-actions-runner;
|
||||
|
||||
mediawiki = inputs.unstable.legacyPackages.${prev.system}.mediawiki;
|
||||
})
|
||||
];
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
{ stdenvNoCC, jq, element-themes }:
|
||||
stdenvNoCC.mkDerivation {
|
||||
src = element-themes;
|
||||
name = "element-themes";
|
||||
nativeBuildInputs = [ jq ];
|
||||
buildPhase = ''
|
||||
find "$src" -name '*.json' -print0 | xargs -0 jq -s '.' > $out
|
||||
'';
|
||||
}
|
9
public-keys/admins.nix
Normal file
9
public-keys/admins.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
axeman-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMNeQYLFauAbzDyIbKC86NUh9yZfiyBm/BtIdkcpZnSU axeman@tuxnix";
|
||||
b12f-1 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHx4A8rLYmFgTOp1fDGbbONN8SOT0l5wWrUSYFUcVzMPTyfdT23ZVIdVD5yZCySgi/7PSh5mVmyLIZVIXlNrZJg= @b12f Yubi Main";
|
||||
b12f-2 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEST9eyAY3nzGYNnqDYfWHu+89LZsOjyKHMqCFvtP7vrgB7F7JbbECjdjAXEOfPDSCVwtMMpq8JJXeRMjpsD0rw= @b12f Yubi Backup";
|
||||
hensoko-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEbaQdxp7Flz6ttELe63rn+Nt9g43qJOLih6VCMP4gPb";
|
||||
hensoko-2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAqkqMYgncrnczcW/0PY+Z+FmNXXpgw6D9JWTTwiainy";
|
||||
teutat3s-1 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFro/k4Mgqyh8yV/7Zwjc0dv60ZM7bROBU9JNd99P/4co6fxPt1pJiU/pEz2Dax/HODxgcO+jFZfvPEuLMCeAl0= YubiKey #10593996 PIV Slot 9a";
|
||||
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
{ lib, ... }:
|
||||
{lib, ...}:
|
||||
{
|
||||
flake = {
|
||||
publicKeys = {
|
||||
admins = lib.attrsets.attrValues (import ./admins.nix);
|
||||
admins = lib.attrsets.attrValues (import ./admins.nix);
|
||||
robots = lib.attrsets.attrValues (import ./robots.nix);
|
||||
};
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
AGE-PLUGIN-YUBIKEY-1HZCCGQVZH5WV7DCL6V837
|
|
@ -1 +0,0 @@
|
|||
AGE-PLUGIN-YUBIKEY-1EKCCGQVZE64TLZCKYUCW7
|
|
@ -1,28 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 iDKjwg FkQYu4K7yxWuKQChw28kOJrZqXDelVmzExig/cEmxjI
|
||||
apgJOiOv/gLcSRTcAkhzDZyLdiKbnsipnNt6okrZ6os
|
||||
-> ssh-ed25519 uYcDNw wfyuSGgrFXRAcNSZoBTCz8kJOMeocD1BFwQ1hhO6dD0
|
||||
J5hhkK/S+RXjDp/kFGOXP1dDxTyKQx5MqhohgKTP8PQ
|
||||
-> ssh-rsa kFDS0A
|
||||
arAz7wP/PQBggo5IOFTZrMp/a1eCxCzx5t0QTs07Mfp1mk1h5Xy39VwRB4PIN1Kw
|
||||
ASRLnBsUmPznZTWJJ+coAjZiISYx0kW0J5BpKmC6g5orxQJHwEieI/c9JZ1KTjUJ
|
||||
G+Rl0BWfJiOk23SiQaCEs5D9OPQiKpQvE2W6ZUTaRVzRelGlmzSHkx5hAz3yX936
|
||||
MXdijUFS15sNKDTaoGrql67YRckYHn8ErrvUaSUEdelNOc9ILhCTT+NSM5SG+oh5
|
||||
B1GVdHf2hrgmTqhKqxwB/DgXmwsOzX5ffa7kV+KqgYypdjVHlLlkWy6RLVQLEYBM
|
||||
ldLIHY4SjpuShqcsuoakZ8jAx/J5aU/SnnRBxIgWcdwwMPbn2dB89wkiK9kVgpVH
|
||||
Izj4oO5EJiZr6Fx+iCFnnsuzBrzswRR2zZOJsYo1XY2uP7JEq8F5iClAgN3C7C9V
|
||||
3gU4Cf61sr4GftKCBnRUGrtohfL5KeXBX7sTpvF9+cmjQWTBB+fF5Q2I6UmOH08Z
|
||||
8OVAkPQsK+zfNaOD5+J8/JoCIXNqZKBq+ShgQoMEPlUFwe3mgy5ji38s8CY09ehY
|
||||
DrsWhQw1M9ka8z0hlfP95jQjNlztUn4K/TB7OXUXAKj9/n74b7lmLJ8OMCn4miZ2
|
||||
EOV9jVyXrCPQF6RujaYOh52OFz3zIRKEINwWwPNfNJY
|
||||
-> ssh-ed25519 YFSOsg 5H/taWUdjZcoYSFndLcYZPX8JUtK6BJs2ou1oJnT6k0
|
||||
dTOUWXMuaERYbfHo6AaiM4NfPWKxTk95YFpRkxq06jQ
|
||||
-> ssh-ed25519 iHV63A KFTTfUVH8bb+ebLc3WefjyFt2YGdfD8cQiK+VURRplI
|
||||
d75sa9BchGJl1NdVHCZ5s4f/RqV5TE7jBtC02OnOt2E
|
||||
-> ssh-ed25519 BVsyTA 8BbKlmlVJvPSoZuVazuOyR2YXncwTHAP80hDYpshjz4
|
||||
I+u3zwtSecaLeOOR1WJ5+fwWTgn31PvW38kkPgGQ4sM
|
||||
-> X}64s-grease V7
|
||||
U9Gkb6Sn+PV3lgb6Kzl0ATgibtLzSm//Z60gct7j8F2wVosjicXaWpv+LVfdBo86
|
||||
JlXZuA
|
||||
--- zjT2F/dHJX8rxVXgbjZMsToMSPUXPLwbeAhGiNawKlc
|
||||
†ÝˆÉ©õÖ‘èËŽ{´–ýÍHª™©kÂ0Z•Yê*¯ÿð“òb;—ÕX#æˆ-•Ÿæé£Í®¸´£Ýé&n<>/mxl
9ò<39>|œc K$åÐú&‹þâ*Š$zÿ‹1÷zÐ
|
Binary file not shown.
|
@ -1,42 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Y0ZZaw FvsdIE/inJoLVSosWXATnFbAAVjVuf7jlEC3nSUF6Ug
|
||||
gX84OKgWdfkGBN+NFy11BxIb4WX1z9UkPA4u2Q1uV+g
|
||||
-> ssh-ed25519 uYcDNw z5Veza0uVwqCqGCGYzGmXPcyaV9HztEN39cWFbSG7yg
|
||||
UWZQcDP1vMsYoWwMQlr4YmzWYw2EKm/s5zJVHNf2M0U
|
||||
-> ssh-rsa f5THog
|
||||
v1kqiU+cx65mvTNeuAhK65eBEk1vmkABRYgcmFIrdr4eY3pru+FaQTfMhTI9HjcO
|
||||
OTU0YPxxSadbUCaN6Z3QnTv5qowwOQlEsWK+RMsOZgnyRQHa2SIrhfHz7v+n8BTF
|
||||
8BYB4UBJpD3aLqM7VED6dYls178HUbiq34ohrG2vY5PHE72xTU60amv9NcJhSJPR
|
||||
twZPiSp3I14MlJU4bboS1YBaEmgxvbXru0DwuoQLw3OUrH7xOggVoSJxm8lVyjR2
|
||||
oFYS5wdnrhAIEsJ0lTsO5fvq9Dmie7qoL60rbBbue9lPk1nD1NlUe3akd4IIo36R
|
||||
kDbthUYluVSJON3o/wenSvJDOw3N3t8bu2+/XfWAd2NL9SPBijMQJtqjK8EAtmz9
|
||||
OjBMjJGQzVdBxRP9U3CWYIwaqYQfWhXXY4AXTwIMsfmeV8ZHZsId3Y156p0NaKg6
|
||||
NGb7eX/AWmcdNTp8ZCqlb4QexICrVd7XDkNbPHkYPUOdUhaMyS+T7YU8Qs3YWroP
|
||||
Bw63QMWbvo1l4HO/3HeIKlzIXTjLEi6PjTiWb7vM4GuoCwjdDg5djMEj4nsvDyea
|
||||
B9EBTEcoP2oj47wgsX0nfV5bKAQ4y8AN4ZNWb00vjN9ybBbLK3q//1DrEWmddieF
|
||||
t6FyZXvZH0Gf6y5OO56yRp/vmxvKFcvxqUA3P8bPAnw
|
||||
-> ssh-rsa kFDS0A
|
||||
c+0wRUbjzdJiBhdKAVlE8yxt1O3t4oQ438F5HjMPohEXSFLiNFi4Y0JQsw6qn3GP
|
||||
hySsyIoj9G+cI9FDPjTFPmE7O1SHrd2LqBZGukyswDXX8CpwmZ7vfqfK2lCgKfos
|
||||
SSPiGaYk+HlQF2QfX/xdgQ2PbFXHnDy8LZ9AfZP04PrnK9wqdiEXwmkWZ/Lu1P+V
|
||||
Wb/28BYxcfkseAprFr/KSJLoNuD9UphRhQwRklmjADnf0lep3vHccxz1Oo5flu5M
|
||||
AD47r+0bLGM+w3epCF1GyR4L2lEBaD8pkVOt3/zIdjn8nFZVNJwjshToazvnVEd3
|
||||
Vd9Uas58AyxcT7Dk/QaVO7c5KJDdfSuxnT1zElkM2ZQM4lEueTJYDBJGyfubb30y
|
||||
Z7re/MsLOh0jNJbb0r1KOkzwpcdm9iyvi26eaGsX7Q1Gb2pzOYFxD1vSUUC6A6Hp
|
||||
W5X6fKsiBPreYLf5MV6p9r2YJPdX4SJiq4XztQi1PL+ndq1h8wskxk3Pyvk9fhle
|
||||
iC5owZ8/FikfC/1oEa2KayeLyYB001BUuktevzfH2GmbqLkR9wBGw5vUJzOO4vOW
|
||||
o8SVCSUxSrG8S+HQksOSXFWywkdBDhqc8eyRUtb+6iqqMA2Q4GDqktSCB1KeBYD6
|
||||
OalH6bo4H1ddV8LPMOKcFtjmTPuum43C7bNge2rxhgg
|
||||
-> piv-p256 vRzPNw A/utfOjPG1zs1Lf2FOWDHhJIJW1PIHmKFqFvBZZycHPn
|
||||
EfGFh9R0PDgskQg00z6thQ1YozT5ZiBhzNN9iTXWDe4
|
||||
-> piv-p256 zqq/iw A0RjdOkfYmTlYCwM3aFLdXfBimXMGzVh21A5QxZ217xW
|
||||
7J9cRYpr1uhQPE0VjvLAwyS7jNSK0+qjA9xUMeRwYos
|
||||
-> ssh-ed25519 YFSOsg w8ljrS1oRdB9RT8Odi5UOPjEtFL3WBlQUAH9Y7gp3WM
|
||||
xcrbEm66K6mNrJ9+877YEgWUdxW85YyS1z8CGMyYxeE
|
||||
-> ssh-ed25519 iHV63A O0bMGpauAYAuiAtbITj+lQOS0LuFl/BDVxIUTly8tQM
|
||||
0Kiu4sNN0joX5D4eB42oQ/iRSntsJI5JNKOmkQeyLGE
|
||||
-> ssh-ed25519 BVsyTA k/0Rtr9qbFH7V6DyCRtyqdAHU1b7D7DNGV8pPPJmrnk
|
||||
dJ29gcfSxaVQ46XbW021PxPotZ8ZG2zjostJme9GUZQ
|
||||
--- 1V0sJP5JIa9GZ0F0hf1GAFX3LNkPSNsxNhqM9cH7Rgc
|
||||
|¿‘#ø©mÌæR„Ö5wäÎQòÅÐf1Ü
ÑÁZ·MUüèOÃfãÜ:GÓ^<5E>ì•!<21>
|
||||
gÐG29wíƒÙ_B‘ìdêÿ
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,28 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Y0ZZaw M6ha3gQ4Oq4PdymYZ5ZG0qGwFlpCYfJdhOBwH9n1gxg
|
||||
zCtB0PJanufNdV0ShynDT0Z/2jxMFDRby8xsfv6YPaA
|
||||
-> ssh-ed25519 uYcDNw V89Ll4HJ3ZkQegiCI6gswz736domVgDGSDCA8bZBwHs
|
||||
W7IrEL+1xUXuVdy6A61z6P+pS/ajTGPL+qv+9Jh8UxI
|
||||
-> ssh-rsa kFDS0A
|
||||
SV6QVIW8MCQVB8ABiOGxLTXEMO6rfeG82CktBFtf76WeIYzlkho/IaGgWXoqoIQ0
|
||||
KC/ev7vNGnB01AOWe/xkuMZDRvK+qGaOLB7wpZG1cJhqSon9oZtztoDjd/Crp5K0
|
||||
nfeHjY9E/jgFr0KYeaLedw5OJuaOw4YiuKyTThVbpRZwbof30nvHXqrYKPZJi1gq
|
||||
s5spoWYH2ijZi9mrJojP2ZqK5DJjCteXqP1YHdz3LjxomoDyl5cv/tLNsvrptfxD
|
||||
FvZMcPrvrC/IWqJ8qGW+f8ENUGyjXxx6jFQ2WN9IMIdJYk5bz458ip3GKqnAlwi3
|
||||
SZbaxRuEYEoy6ikKGRuXMAwpJd3YXcRcaRdetw0a4grdD6hF21bTl2+LnTb1ydnb
|
||||
frzeoXaqbBdhEyLpZFAmGLydteIyA/Kl/D/PEJ0MHc0G0EGofMm6YsNJJrP3mQgi
|
||||
mXC2Kto6WV/JLVEnURayf12rPR1T/VPIyYZ/Xi9HfPh0p3Y21nadPAcEq/PltWgR
|
||||
AqELfBbVpNtcxTP2pjEJqGskJCYKAmMeM+yQ0moKVmuMWicahMqjQRJO1jnvTwwd
|
||||
GhJlUO32EuI6Fn6sApthv2FfLrle+x0H4/v9xvHDJIVSmLYtzK+9ueUPn/A1x8X1
|
||||
lGeJh+ecEV2r630insGAp8WQzyXhraHrn3lgyacwRmA
|
||||
-> ssh-ed25519 YFSOsg KKhXh/XW7iF7wMA7JD9fbgmty5yVPaSS1vGdHz0Xh0M
|
||||
eLJc+F/yIR1ckZX/npLI+l3I2iB+OrKBkJAQTkbWVF4
|
||||
-> ssh-ed25519 iHV63A xoJ7Tr8mKgYVPPeJYBnOHLBY5E0i34vEQR3pMVKxbAc
|
||||
TKqc9Y/RpnfTP3CNvCearB4FuvNmW0mcGVLh7Ebjzeo
|
||||
-> ssh-ed25519 BVsyTA LaMK6X/MJyQTQ24p9uHXh75leMcp/akCA2YZACEG03M
|
||||
psw6sVlNGT8WsG3L9kbXdrhqxp8hIdSF7s4o60jTYgY
|
||||
-> vcxmk`-grease 8^p$~+LB -G)+N&$^ P)7#7[wX
|
||||
8TyK2RrSHFuMyFy9YY7ZI6RSduF5hw6xZKhiysVkif4Husb1flN8QVmWtoW8laWz
|
||||
n8772TmNTcfq5ebUp+UA+S6MVgf75D1GnDumEDH/LbM4LNjRZzyw3nBGu/Q
|
||||
--- Ouu56e69gTpAY1ouLPlzI/n6geKz1CMmTl8wAVyIDPM
|
||||
Ÿ·¢5¿ä7W>J@°óðj’Á–€l_ƒ¥«Ï/œö÷ú=ßÕ»‰4(²<18>²K» µÅÑ¥„zSÌsæ
|
Binary file not shown.
BIN
secrets/matrix-hookshot-registration.yaml.age
Normal file
BIN
secrets/matrix-hookshot-registration.yaml.age
Normal file
Binary file not shown.
Binary file not shown.
|
@ -1,27 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 iDKjwg O7ax7BWOp2BEKA9i4WAmI0hsGoRjSzfAbMb4eRLdoRM
|
||||
LlddBgKAoFe7qKvq7ixIphiWiO1JzKSyLJ6PSmUd2xA
|
||||
-> ssh-ed25519 uYcDNw 5gN/+TZa94jPsMsrwXlrb1U8alMnCJq5/EIegIus0SI
|
||||
NUTWQw6WCZTpKK4EFBL1lxSSnI9WEAb1MB7iFiezDFg
|
||||
-> ssh-rsa kFDS0A
|
||||
mXTGOqDXWJSVo58aok+GC2v7Xm/lL/QUrA9H4Ywfz1ksK2O1vZFmmrj9YOGMwtz3
|
||||
KodmEn8339Oyz0Tw2lSDMJb22OZPxs2q1tYQ33tvj1OXVQygzW1q/RfTPXFtTCVo
|
||||
alKl2Dbr8esFN+Cfpdh4zHJFab73m6FUDGF2k4O5Gos8eOUiUx1O8WPMDtKgwTqM
|
||||
Wtbnk0iBiTdgjwdFjkdMnx1bxGxa4pEtqtBdw9UiLwPKoPWJzHg7F9uIWH8L0FkQ
|
||||
ml7K+pjZMzwWdJwuaLpIB3yCTDiSF4j9Wr74sXjUGQ/atGesIImIGnXEyZ0v6RI2
|
||||
uRP4gx4zA9eoYcIWpuitgx9VKDwwJjcAyhffbZvTYF2ogtnWtCBIlY5jAtIV5l9I
|
||||
x0k/FMfq0hGvXOJb976zsW83ZaXVPFpUEV75mweVAUbsnRmML1kyYKAFWF58hSoa
|
||||
aEmij9hDvPIoQn2f6OTCtWXSJBtJjhxr4uvbKfrvhQojol91cU0w+fDe5rsZzhMk
|
||||
CksD3JM+OmCpguvl+4jANxPVY58avIjZArOn/UVyM0LLuKFLfRzqpBup6ifv3Wpk
|
||||
gplElrdz4iGHoEnceCGVJXcxXVbMfB4cr8I5BMK65TgN0pkl+VG6vY/TvgUl5a1C
|
||||
VjLQxIVg3hEy8mRvIGjjo0R2E8qTkcMn5Bz5mjFJeXI
|
||||
-> ssh-ed25519 YFSOsg nvVCR2LV8DHU+hIQa19uX9pEhA+NQxMkmBUMDktKOGU
|
||||
Q9qhrcOeEA3myMqZbptbsWCS9hbm67pF5qO3jARN/bs
|
||||
-> ssh-ed25519 iHV63A +Pca506lCnqn/+2e3lKVzlLcsa63EgngYry54yiAxA0
|
||||
hyZZUoRuYjJvhznZBAkRRjq2x6jZvJX0sfj+jigX39c
|
||||
-> ssh-ed25519 BVsyTA hza+5wLH7L3VyXIwBK/sq5UNR6SC3EnKxQ3ucrVPwXc
|
||||
BAXKAf2gdMT29ZXEAeq0B54ojrGa9LwfhBK91v68yis
|
||||
-> !By"-grease
|
||||
7r6wODXXipdv7nXJ+K653PLYdKOLF1pEvCWeKk8/q49s5ScMqZpGVA
|
||||
--- zNjNg84OVHL/CbJyutcBz6eWD+71peLb7weZ/EjQaic
|
||||
r!ï?RUàÕoäE‹¤~Wü>_íðtÜî=‰*7ëÎt<C38E>=QÔ¹ü[`@ï‹“£BÛ<42>§jedܰ͢q¤Ño^Ÿ³™P÷±áNÜÏ{H…^€ª¾j¬°ÚBûh¼:PPµÞ&â™—mܯt
|
|
@ -1,31 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Y0ZZaw FWuk2kYGB+GfoY3rWfeCosoBOLvUHrH7SR8Fv18o+XI
|
||||
YyOTULtyOJ3vfAOnYSMzeCCyipJ4Fqrr3PJgRtbElJg
|
||||
-> ssh-ed25519 iDKjwg Bq6lNuS5MOhsU/7ypHw/E70BktIA+SmN6e3pvrIqRBQ
|
||||
Xo0OOUXfOkPQfArhqSJyiAkH5lxcJIAO7M5krkCZNfc
|
||||
-> ssh-ed25519 uYcDNw EfB1B4CSNk8Oe5B7T+KSl9O5OsCrulaLOjR3PBtxpSk
|
||||
xJxkmBSENc5JosdRiEAC3a41WI6TmTlTxm+lclup+g4
|
||||
-> ssh-rsa kFDS0A
|
||||
dYH3A43wClFnDQp8m3ZnhTK5d8LeG6ZkqDQ5dS1yB//4G5TaUnMqOp5Q2G1gbgXY
|
||||
Zu9qYOHdUydn5HIRSwBXj/KbBm5xJ1zFImOszn7S5mk4iReHFyTnSzAi4utatQcY
|
||||
DEjGnvKKRoc7ih08+F44kq6DYnhUBFqF8eigQZIsyeWpiW6C1FzasL0KnXoedPG2
|
||||
AYJForNB8zKp7a2Evxi0MY7a+ldHAekktz1Fta2u9MvrWUtqP/yLqJhCwCNvos7J
|
||||
kG+XO4j0kiOQCIO9TOeLAu59+VCVM64mY+dp+xc8tX0fWuu7ItSAh6jRHzfgSKjC
|
||||
qDJc/1YpUG1EnYSH39mfVox3ndeMuVrG6Q1h509jZuxsw/zoDsbY3bbhTaUQ3X8Y
|
||||
5ShCponnEGBLqeSm1gALCAnlgu8IS4gL6ePKuAhN0qMYj6iiXP/Ugp3lTcv1TvFD
|
||||
KINnV/tas1CO3PApQm6JgijHEPT9zyUbqR/xN06+OCWbg4hHuEix+0OhM1T5w2xC
|
||||
KvKF30iUK0tU2hZvKdku2MpbP4N0cQLqBEWiyrUKHRMCdXi3kyO5D84UdWXvETAt
|
||||
BfEvZ8ZG5fiSXzbPLxVqObXFZUirLuWomWtstqkDuadL9xJkTcsbr8ZCCNpPhxdL
|
||||
oOfao+tox3RBilAS3AfQVhrPvD2rVUptm+0nPtnO3rY
|
||||
-> ssh-ed25519 YFSOsg T2OdtA0kY4DqDIxE1QxMV5aCygvKlI5LgXQ+QYYuOko
|
||||
l0Kzo02jGISCT1zrGf5soXYj7FMVrN/9REF3Zscbmik
|
||||
-> ssh-ed25519 iHV63A 75daRGD2TQ/mXRsckaH9sGGkHMkLxgHFhn0eDdkDsU8
|
||||
TXeoLqfU0ywQucPayYoG43Gr56uZoYIWaK9F2YJJ0FM
|
||||
-> ssh-ed25519 BVsyTA J/xNtG1CAzfoiKPsnWwDp4pId7d3MywXpfhKAmpze3I
|
||||
8uMO07Se/6krP79flt+XZfjIsw12kWsoD6LqZyLG70M
|
||||
-> B-grease y3$t@ ; Bs *w
|
||||
dUrvWB09znCDyvO7RnduMguc9pWTn19q1fc0MHFUXk7WQWns+4kpJIX1qljB5hz/
|
||||
NPAbNzwMDQKj6awHAth1iFLaEw
|
||||
--- rI4jrrXCiUpV/EzGsla+lxONmL5/Eel/LODoIM80jcM
|
||||
˜_°0àÆ7Jˆq•[÷ç<>è'/ù‘õŽi„Ü<E2809E>Òl°mÙ
|
||||
ÌÂ!JPþ¼>œ…wk¡ž·³¤+ é™)ÚÈPhUÜóç²O=>k=?ÂTÐ
|
|
@ -1,30 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 Y0ZZaw CxhF1nK1+6OmJb/68UQ4mBIqxGgr8ngkNsL9dfaPN2s
|
||||
jZ/JBaTCjFcL0SAGVx5ECDanVn4TGt0g2yn2OQOP9iY
|
||||
-> ssh-ed25519 iDKjwg D/xqqA53Lw2UQJesg27wmK/UNCV+s914mvMlbKN1rhg
|
||||
AOg0SkPvSotuSHk33zVfRxB0wn67a29YWc/itDUZ/LQ
|
||||
-> ssh-ed25519 uYcDNw /QdfQUJmBMQZ+KRCst1gA0LqFGvM1K91ZL/RIRP+qBc
|
||||
Ttksa44OdwLuRmgYPC2rIn+wy/SooRPUq8gQTR+pF0k
|
||||
-> ssh-rsa kFDS0A
|
||||
L9MGJFRceqbge3EF/rqXdT13jt9faxP1NmfRB3i2mrTasvCaovc/62bA0UmlsB/9
|
||||
Y3hIzo28d6pZRcMm91l6PhWV0M33YNwPQf87vd7klv++1aMIdZ6/jHsQiohIBkRd
|
||||
4pBe6rrx/lUqEqfQVYUFPfRE50ufkw+hRw/NJCvcBgHgNhhDoeb8keWRPZhhuv0Z
|
||||
f0eP9ORKjeKxjv3tsIPjiE7aqxE1zTdrnSr7FuqklJhMYRdwVv+2ofNEh05hU6pR
|
||||
VL4AS7d6Di/0dWTWc/Je2ytsrdio2v0rPAUXN1fyTh4AtrAmGQzUXNWnr4sB5xH9
|
||||
QlL0Ea3IwndJSDNkqc4qI3JL0vx6QMUbsuNcMmVWSMkODP+gNQYXQNbnwNfeMAnE
|
||||
V++WBfyrA8+V+ES+usqeWoOXjApzShn+gnrV0DHHXDAzNR+M647rQcsLePSyNjf/
|
||||
NKd7Z8VfEq7m65AxmSHPezSGdICMf63WLG/Bffj9rWiQxaoiayGF8jbALpXlu93X
|
||||
txOw8pK7zA8xFEBujmkrDPH3sJFPLOgOMYa0uuCMbrCGxeJ34nuQMhSUTamESSXb
|
||||
AD3AgUrRvte1iXwy2PoZGolRLZfdq9zcAfFyq9KvIhvz/8b2F+KbqHQlAiKVPw8p
|
||||
XQo4sXcDAmF251WSCJGN1C6Doxj/6XLuWILbkobQqoI
|
||||
-> ssh-ed25519 YFSOsg FtIvWeEXI9blJIFAWMacXgPym5ePGXsuiOR+Gh3b3R8
|
||||
0rp/NIu4kCCt05Is2+eRdUmgNX8QPMsDPhZWIejnBDA
|
||||
-> ssh-ed25519 iHV63A 85G1w54UHS/gFcLvsXyYLPXvLHkJl3YQCi8ehb+ZrU8
|
||||
lXDaMXlPw5ohaaYpiEkCNAmE2tJ2824ydmp9EakPtD8
|
||||
-> ssh-ed25519 BVsyTA XimcaonVCGGyyCfn3BSX/a7zjJkWeaVY/xAcdNDrl1U
|
||||
RaqpXzUd54qrkYYRbRTUclTpZdZx2us42lkP6wBxjBM
|
||||
-> CWM8^B-grease
|
||||
HvBgzYx54YVP0M6pk1bp9qegLscQ4tHIV9DZhr7jnrW41adgY0D39wnE2IgIRc6g
|
||||
keRHAr7QVqdPy/kr+u0GwQ1MGFKI8Jss8vRxKwv/UgQfmg
|
||||
--- dJWXhQRYjxWchTW1u3TrF7KvQIOdrOvkEC7oUtFcGeE
|
||||
l>qTðFÞ®/®â@tË\Å&Zò êÄ:„Þ@ òÚKÏx©ªr¾áHKûĦEûb0ÊÖ—5Ëm¸/
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue