commit 30ce0dafc2cb2f4de5313636afe43a06d4b5806a Author: Rustam Efimov Date: Wed Apr 1 08:50:01 2026 +0300 initial commit diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..6e1e748 --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,42 @@ +name: Nix CI + +on: + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Install Nix + uses: cachix/install-nix-action@v31 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: Enable flakes + run: | + mkdir -p ~/.config/nix + echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf + + - name: Setup SOPS key + if: env.SOPS_AGE_KEY != '' + run: | + echo "$SOPS_AGE_KEY" > /tmp/key.txt + export SOPS_AGE_KEY_FILE=/tmp/key.txt + env: + SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }} + + - name: Flake check + run: nix flake check + + - name: Build all hosts + run: | + nix flake show --json | jq -r ' + .nixosConfigurations | keys[]' | while read host; do + echo "Building $host" + nix build .#nixosConfigurations.$host.config.system.build.toplevel + done diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c49cf96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.envrc +.direnv \ No newline at end of file diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..3773c4e --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,13 @@ +creation_rules: + - path_regex: \.sops\.yaml$ + encrypted_regex: ^(data|stringData|\$ANSIBLE_VAULT) + - path_regex: ^secrets/.*\.ya?ml$ + key_groups: + - age: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPRVeP7aRYdbIku7Qr6dLFLQrcq8LUUTTpYZZ3E8ZoQK rus07tam + - age1qchtmcrsuq7ehf8c60yezurt2cgt64unlhzx2ldntgtnaqds4elslthql3 + - age10hsw859vkkjk6lss3npzmhu9urjtuhn0x8l63v4h3lfk8wrdxd7s8pfu5g + + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFg3eK2k8JC+iUMsYJFjb8ux19Nl23pi9qQ81ns563Db root@velarion + - age13uupj0vkwn6dlgeqvu06le5d2ms0meu0j694tpnvvn6mnct9xs8ssyjtc2 + - age1723x4jfn3urne8knvxqawmslq8ysr66uml8c3svj6zy0j3hdh4hs94yfqf diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ce1bf23 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "nixEnvSelector.nixFile": "${workspaceFolder}/flake.nix" +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3c577b0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e494fc9 --- /dev/null +++ b/README.md @@ -0,0 +1,166 @@ +# nixos-infra + +Declarative NixOS infrastructure: host configurations, system modules, services, and user environments. Built on **Nix flakes**, **NixOS modules**, and **Home Manager**. + +**Design principles:** + +- Single source of truth for all systems +- Fully reproducible builds +- Minimal duplication; shared logic in modules and lib +- Modular services with a unified `machine..*` interface + +**Contents:** + +- [Machines](#machines) +- [Architecture](#architecture) +- [Repository structure](#repository-structure) +- [Security](#security) +- [System update (nixos-update)](#system-update-nixos-update) +- [Deployment](#deployment) +- [TODO](#todo) +- [License](#license) + +--- + +## Machines + +| Host | Role | +| ------------ | ------------------------------------------- | +| **elaris** | Personal desktop | +| **velarion** | RuJect infrastructure (Forgejo, mail, etc.) | + +--- + +## Architecture + +- **hosts/** — per-machine configuration (hardware, disk, common baseline) +- **modules/** — reusable NixOS modules (SSH, security, fonts, nixos-update, etc.) +- **services/** — service definitions with `options.nix` and `service.nix`; enabled via `machine..enable`, `machine..domain`, etc. +- **users/** — user accounts and Home Manager configs (`system.nix`, `default.nix`, `hosts/.nix`) +- **lib/** — `mkNixos`, `mkUsers`, `mkHome` for assembling systems and home configs + +--- + +## Repository structure + +```plaintext +. +├── flake.nix +├── hosts/ +│ ├── common/ # shared baseline (modules, packages, locale) +│ ├── elaris/ +│ └── velarion/ +├── modules/ # NixOS modules (ssh, security, nixos-update, …) +├── services/ # machine..* service definitions +├── users/ +├── lib/ +└── secrets/ +``` + +### Hosts + +Per-host config lives under `hosts//` (e.g. `disk.nix`, `machine.nix`, `default.nix`). The `common/` import provides a shared baseline for all hosts (see `hosts/common/default.nix`). + +### Lib + +- **mkNixos** — builds a `nixosSystem`: flake inputs, host config, Home Manager, users. Entrypoint: `mkNixos { hostname = "velarion"; users = [ "rus07tam" ]; }`. +- **mkUsers** — turns `users//system.nix` and `users//default.nix` into system modules and Home Manager config. +- **mkHome** — builds Home Manager config for a user on a given host; supports `users//hosts/.nix` overrides. + +### Services + +Each service is a module with a unified NixOS option namespace `machine..*`. + +**Typical layout** (see `services/forgejo/`): + +| File | Purpose | +|------|---------| +| `default.nix` | Entry point; imports `options.nix`, `service.nix`, and optional submodules | +| `options.nix` | Declares `machine..*` options (enable, domain, port, database, etc.) | +| `service.nix` | Core service config: enables the service, configures settings, system packages, SSH `AllowUsers` if needed | + +**Optional components:** + +| File | Purpose | +|---------------------------- |------------------------------------------------------------------------------------------- | +| `network.nix` / `nginx.nix` | Firewall (`allowedTCPPorts`), nginx virtualHost with reverse proxy, SSL/ACME | +| `mail.nix` | SMTP/mailer config for the service; mailserver login accounts (when `machine.mail.enable`) | +| `tmpfiles.nix` | `systemd.tmpfiles.rules` for directories and static assets (e.g. custom themes) | +| `secrets.nix` | Sops secrets referenced by the service | +| `database.nix` | Database setup (PostgreSQL `ensureDatabases`, `ensureUsers`) when the service needs a DB | + +### Users + +Per-user directory: `users//`. + +- **system.nix** — system-level: `users.users.` (groups, `hashedPasswordFile`, `openssh.authorizedKeys`), `services.openssh.settings.AllowUsers`, shared programs (e.g. `programs.fish.enable`). Passwords and sensitive data come from **sops** secrets. +- **default.nix** — Home Manager base: `imports` (variables, modules), `home.packages`, `targets.genericLinux.enable`. +- **hosts/\.nix** — host-specific Home Manager overrides. +- **modules/**, **variables/**, **assets/** — user-local modules and shared variables. + +Example layout: `users/rus07tam/{system.nix, default.nix, secrets.nix, variables/, modules/, hosts/}`. + +### Secrets + +Managed with **sops**. Layout: `secrets/common.yaml`, `secrets/rus07tam.yaml`, etc. Secrets are decrypted at evaluation time and referenced in config (e.g. `config.sops.secrets."rus07tam/hashedPassword".path`). + +--- + +## Security + +### Sudo + +Configures **sudo** for group `wheel`: NOPASSWD for a fixed set of commands only: + +- `nixos-rebuild` +- `nix` +- `systemctl` +- `reboot` +- `poweroff` + +All other operations require a password. This keeps privilege escalation explicit and limited. + +### OpenSSH + +- **services.openssh**: enabled, `openFirewall = true`. +- **Global settings**: Access is key-only; root login is disabled. +- **Per-user access**: each user and each service account that needs SSH (e.g. `forgejo` for git) is added explicitly via `services.openssh.settings.AllowUsers` in the corresponding module (e.g. in `users/rus07tam/system.nix` or `services/forgejo/service.nix`). + +--- + +## System update (nixos-update) + +The module **`modules/nixos-update.nix`** (included in the common host baseline) provides a script `nixos-update`, installed as a system package. + +It: + +1. Clones or updates the flake from `ssh://forgejo@git.ruject.fun/RuJect/nixos-infra.git` into a fixed directory (e.g. `/tmp/nixos-infra-flake`). +2. Prompts for confirmation. +3. Runs `nh os switch` for the current host. + +Interactive shell startup reminds the user to use `nixos-update` for system updates. Adjust the flake URL and paths in the module if your setup differs. + +--- + +## Deployment + +On a host, apply the configuration for that host: + +```bash +sudo nixos-rebuild switch --flake .# +``` + +Alternatively, use the **nixos-update** script (see [System update (nixos-update)](#system-update-nixos-update)) to pull the latest flake from the remote and run `nh os switch`. + +--- + +## TODO + +- Decouple service dependencies so that services can run independently (many currently depend on nginx). +- Configure **Synapse** and **Prosody**. + +--- + +## License + +See [LICENSE](LICENSE). diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..e44e71f --- /dev/null +++ b/flake.lock @@ -0,0 +1,986 @@ +{ + "nodes": { + "apple-fonts": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "ny": "ny", + "sf-arabic": "sf-arabic", + "sf-armenian": "sf-armenian", + "sf-compact": "sf-compact", + "sf-georgian": "sf-georgian", + "sf-hebrew": "sf-hebrew", + "sf-mono": "sf-mono", + "sf-pro": "sf-pro" + }, + "locked": { + "lastModified": 1772251183, + "narHash": "sha256-Zfr9trB8LaesfpupugDgXPqC4F25MO18kyMyb9b2PkM=", + "owner": "Lyndeno", + "repo": "apple-fonts.nix", + "rev": "f8dad87c2cb956695d18c1f36360322d8a0b7d63", + "type": "github" + }, + "original": { + "owner": "Lyndeno", + "repo": "apple-fonts.nix", + "type": "github" + } + }, + "base16": { + "inputs": { + "fromYaml": "fromYaml" + }, + "locked": { + "lastModified": 1755819240, + "narHash": "sha256-qcMhnL7aGAuFuutH4rq9fvAhCpJWVHLcHVZLtPctPlo=", + "owner": "SenchoPens", + "repo": "base16.nix", + "rev": "75ed5e5e3fce37df22e49125181fa37899c3ccd6", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "base16.nix", + "type": "github" + } + }, + "base16-fish": { + "flake": false, + "locked": { + "lastModified": 1765809053, + "narHash": "sha256-XCUQLoLfBJ8saWms2HCIj4NEN+xNsWBlU1NrEPcQG4s=", + "owner": "tomyun", + "repo": "base16-fish", + "rev": "86cbea4dca62e08fb7fd83a70e96472f92574782", + "type": "github" + }, + "original": { + "owner": "tomyun", + "repo": "base16-fish", + "rev": "86cbea4dca62e08fb7fd83a70e96472f92574782", + "type": "github" + } + }, + "base16-helix": { + "flake": false, + "locked": { + "lastModified": 1760703920, + "narHash": "sha256-m82fGUYns4uHd+ZTdoLX2vlHikzwzdu2s2rYM2bNwzw=", + "owner": "tinted-theming", + "repo": "base16-helix", + "rev": "d646af9b7d14bff08824538164af99d0c521b185", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-helix", + "type": "github" + } + }, + "base16-vim": { + "flake": false, + "locked": { + "lastModified": 1732806396, + "narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=", + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "577fe8125d74ff456cf942c733a85d769afe58b7", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "577fe8125d74ff456cf942c733a85d769afe58b7", + "type": "github" + } + }, + "disko": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1773889306, + "narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=", + "owner": "nix-community", + "repo": "disko", + "rev": "5ad85c82cc52264f4beddc934ba57f3789f28347", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "dns": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1768143854, + "narHash": "sha256-E5/kyPz4zAZn/lZdvqlF83jMgCWNxmqYjjWuadngCbk=", + "owner": "nix-community", + "repo": "dns.nix", + "rev": "a97cf4156e9f044fe4bed5be531061000dfabb07", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "dns.nix", + "type": "github" + } + }, + "firefox-gnome-theme": { + "flake": false, + "locked": { + "lastModified": 1764873433, + "narHash": "sha256-1XPewtGMi+9wN9Ispoluxunw/RwozuTRVuuQOmxzt+A=", + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "rev": "f7ffd917ac0d253dbd6a3bf3da06888f57c69f92", + "type": "github" + }, + "original": { + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1751685974, + "narHash": "sha256-NKw96t+BgHIYzHUjkTK95FqYRVKB8DHpVhefWSz/kTw=", + "ref": "refs/heads/main", + "rev": "549f2762aebeff29a2e5ece7a7dc0f955281a1d1", + "revCount": 92, + "type": "git", + "url": "https://git.lix.systems/lix-project/flake-compat.git" + }, + "original": { + "type": "git", + "url": "https://git.lix.systems/lix-project/flake-compat.git" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1761588595, + "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nvf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "stylix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1767609335, + "narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "250481aafeb741edfe23d29195671c19b36b6dca", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1614513358, + "narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5466c5bbece17adaab2d82fae80b46e807611bf3", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "fromYaml": { + "flake": false, + "locked": { + "lastModified": 1731966426, + "narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=", + "owner": "SenchoPens", + "repo": "fromYaml", + "rev": "106af9e2f715e2d828df706c386a685698f3223b", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "fromYaml", + "type": "github" + } + }, + "gnome-shell": { + "flake": false, + "locked": { + "host": "gitlab.gnome.org", + "lastModified": 1767737596, + "narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=", + "owner": "GNOME", + "repo": "gnome-shell", + "rev": "ef02db02bf0ff342734d525b5767814770d85b49", + "type": "gitlab" + }, + "original": { + "host": "gitlab.gnome.org", + "owner": "GNOME", + "ref": "gnome-49", + "repo": "gnome-shell", + "type": "gitlab" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1774738535, + "narHash": "sha256-2jfBEZUC67IlnxO5KItFCAd7Oc+1TvyV/jQlR+2ykGQ=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "769e07ef8f4cf7b1ec3b96ef015abec9bc6b1e2a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "hyprpanel", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1750798083, + "narHash": "sha256-DTCCcp6WCFaYXWKFRA6fiI2zlvOLCf5Vwx8+/0R8Wc4=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "ff31a4677c1a8ae506aa7e003a3dba08cb203f82", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_3": { + "inputs": { + "nixpkgs": [ + "nix-openclaw", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1767909183, + "narHash": "sha256-u/bcU0xePi5bgNoRsiqSIwaGBwDilKKFTz3g0hqOBAo=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "cd6e96d56ed4b2a779ac73a1227e0bb1519b3509", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "hyprpanel": { + "inputs": { + "flake-utils": "flake-utils_3", + "home-manager": "home-manager_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1774257081, + "narHash": "sha256-92ZbaBfsEXEE7VaWJjv9aRSk3l9nyoYYyMe2AwTqSZI=", + "owner": "Jas-SinghFSU", + "repo": "HyprPanel", + "rev": "e919b4a8a8ab5f2a0752f68576ab3eed6993cefd", + "type": "github" + }, + "original": { + "owner": "Jas-SinghFSU", + "repo": "HyprPanel", + "type": "github" + } + }, + "libnbtplusplus": { + "flake": false, + "locked": { + "lastModified": 1650031308, + "narHash": "sha256-TvVOjkUobYJD9itQYueELJX3wmecvEdCbJ0FinW2mL4=", + "owner": "PolyMC", + "repo": "libnbtplusplus", + "rev": "2203af7eeb48c45398139b583615134efd8d407f", + "type": "github" + }, + "original": { + "owner": "PolyMC", + "repo": "libnbtplusplus", + "type": "github" + } + }, + "mnw": { + "locked": { + "lastModified": 1770419553, + "narHash": "sha256-b1XqsH7AtVf2dXmq2iyRr2NC1yG7skY7Z6N2MpWHlK4=", + "owner": "Gerg-L", + "repo": "mnw", + "rev": "2aaffa8030d0b262176146adbb6b0e6374ce2957", + "type": "github" + }, + "original": { + "owner": "Gerg-L", + "repo": "mnw", + "type": "github" + } + }, + "ndg": { + "inputs": { + "nixpkgs": [ + "nvf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1768214250, + "narHash": "sha256-hnBZDQWUxJV3KbtvyGW5BKLO/fAwydrxm5WHCWMQTbw=", + "owner": "feel-co", + "repo": "ndg", + "rev": "a6bd3c1ce2668d096e4fdaaa03ad7f03ba1fbca8", + "type": "github" + }, + "original": { + "owner": "feel-co", + "ref": "refs/tags/v2.6.0", + "repo": "ndg", + "type": "github" + } + }, + "nix-openclaw": { + "inputs": { + "flake-utils": "flake-utils_4", + "home-manager": "home-manager_3", + "nix-steipete-tools": "nix-steipete-tools", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1773851886, + "narHash": "sha256-+3ygZuf5K8mtSGMMEZ/h+vxGvXCu1CmiB+531KMagH8=", + "owner": "openclaw", + "repo": "nix-openclaw", + "rev": "64d410666821866c565e048a4d07d6cf5d8e494e", + "type": "github" + }, + "original": { + "owner": "openclaw", + "repo": "nix-openclaw", + "type": "github" + } + }, + "nix-steipete-tools": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1773561580, + "narHash": "sha256-wT0bKTp45YnMkc4yXQvk943Zz/rksYiIjEXGdWzxnic=", + "owner": "openclaw", + "repo": "nix-steipete-tools", + "rev": "cd4c429ff3b3aaef9f92e59812cf2baf5704b86f", + "type": "github" + }, + "original": { + "owner": "openclaw", + "repo": "nix-steipete-tools", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1773628058, + "narHash": "sha256-hpXH0z3K9xv0fHaje136KY872VT2T5uwxtezlAskQgY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f8573b9c935cfaa162dd62cc9e75ae2db86f85df", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1767364772, + "narHash": "sha256-fFUnEYMla8b7UKjijLnMe+oVFOz6HjijGGNS1l7dYaQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "16c7794d0a28b5a37904d55bcca36003b9109aaa", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1774386573, + "narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1761880412, + "narHash": "sha256-QoJjGd4NstnyOG4mm4KXF+weBzA2AH/7gn1Pmpfcb0A=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "a7fc11be66bdfb5cdde611ee5ce381c183da8386", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nur": { + "inputs": { + "flake-parts": [ + "stylix", + "flake-parts" + ], + "nixpkgs": [ + "stylix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1767810917, + "narHash": "sha256-ZKqhk772+v/bujjhla9VABwcvz+hB2IaRyeLT6CFnT0=", + "owner": "nix-community", + "repo": "NUR", + "rev": "dead29c804adc928d3a69dfe7f9f12d0eec1f1a4", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NUR", + "type": "github" + } + }, + "nvf": { + "inputs": { + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "mnw": "mnw", + "ndg": "ndg", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems_4" + }, + "locked": { + "lastModified": 1774736237, + "narHash": "sha256-uQ+Was7QP9Bupr0XZyZXOAD32Ox8z2mJnevT2FmDwS8=", + "owner": "notashelf", + "repo": "nvf", + "rev": "a0636d5c977743851c91d3c2e74bfac90be48835", + "type": "github" + }, + "original": { + "owner": "notashelf", + "repo": "nvf", + "type": "github" + } + }, + "ny": { + "flake": false, + "locked": { + "narHash": "sha256-3257NAH4qlan2YHVLpNRy7x8IJqR2pal3OzFo/ykqXs=", + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/NY.dmg" + }, + "original": { + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/NY.dmg" + } + }, + "polymc": { + "inputs": { + "flake-compat": "flake-compat_2", + "libnbtplusplus": "libnbtplusplus", + "nixpkgs": "nixpkgs_4", + "tomlplusplus": "tomlplusplus" + }, + "locked": { + "lastModified": 1772648049, + "narHash": "sha256-iPOTfk1seKcKdus3+ksnZUUr3NFxwsz9d93vtxSmg5c=", + "owner": "PolyMC", + "repo": "PolyMC", + "rev": "5603242bf3b70d83a8dbd171b52be5f4fcedfc1c", + "type": "github" + }, + "original": { + "owner": "PolyMC", + "repo": "PolyMC", + "type": "github" + } + }, + "root": { + "inputs": { + "apple-fonts": "apple-fonts", + "disko": "disko", + "dns": "dns", + "flake-utils": "flake-utils_2", + "home-manager": "home-manager", + "hyprpanel": "hyprpanel", + "nix-openclaw": "nix-openclaw", + "nixpkgs": "nixpkgs_3", + "nvf": "nvf", + "polymc": "polymc", + "sops-nix": "sops-nix", + "stylix": "stylix" + } + }, + "sf-arabic": { + "flake": false, + "locked": { + "narHash": "sha256-/0gjRimqvZyE60xYxxPdlU+7Q2LJnnvtbmwOP0YmS9U=", + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Arabic.dmg" + }, + "original": { + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Arabic.dmg" + } + }, + "sf-armenian": { + "flake": false, + "locked": { + "narHash": "sha256-rRoDkbNMYkzOHZmQm96Zv80TZvRlAeoxkv4pMHP5nUg=", + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Armenian.dmg" + }, + "original": { + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Armenian.dmg" + } + }, + "sf-compact": { + "flake": false, + "locked": { + "narHash": "sha256-oLhkN4HYkU1Xjxk+xdmyxJmROSzo1qd/tafdxw7icxs=", + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Compact.dmg" + }, + "original": { + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Compact.dmg" + } + }, + "sf-georgian": { + "flake": false, + "locked": { + "narHash": "sha256-IevVNOC28IiR45YfI3PsZzXLMRxuB5u7UiE53Zn6tRU=", + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Georgian.dmg" + }, + "original": { + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Georgian.dmg" + } + }, + "sf-hebrew": { + "flake": false, + "locked": { + "narHash": "sha256-Dw84kYwMpCtKKKqm8cZcQ9TZ7GayU5MO7W0LJw0Rcwk=", + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Hebrew.dmg" + }, + "original": { + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Hebrew.dmg" + } + }, + "sf-mono": { + "flake": false, + "locked": { + "narHash": "sha256-ICdHRFdNL7PM/fXJUzS7LgZxZiqcyIuCMHLze4En4vg=", + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Mono.dmg" + }, + "original": { + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Mono.dmg" + } + }, + "sf-pro": { + "flake": false, + "locked": { + "narHash": "sha256-s42hsaUe0Vkaw5yw8G7G3W3AYJb2TPqSlMqPyY0e5WU=", + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg" + }, + "original": { + "type": "file", + "url": "https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1774760784, + "narHash": "sha256-D+tgywBHldTc0klWCIC49+6Zlp57Y4GGwxP1CqfxZrY=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "8adb84861fe70e131d44e1e33c426a51e2e0bfa5", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "stylix": { + "inputs": { + "base16": "base16", + "base16-fish": "base16-fish", + "base16-helix": "base16-helix", + "base16-vim": "base16-vim", + "firefox-gnome-theme": "firefox-gnome-theme", + "flake-parts": "flake-parts_2", + "gnome-shell": "gnome-shell", + "nixpkgs": [ + "nixpkgs" + ], + "nur": "nur", + "systems": "systems_5", + "tinted-foot": "tinted-foot", + "tinted-kitty": "tinted-kitty", + "tinted-schemes": "tinted-schemes", + "tinted-tmux": "tinted-tmux", + "tinted-zed": "tinted-zed" + }, + "locked": { + "lastModified": 1774124764, + "narHash": "sha256-Poz9WTjiRlqZIf197CrMMJfTifZhrZpbHFv0eU1Nhtg=", + "owner": "danth", + "repo": "stylix", + "rev": "e31c79f571c5595a155f84b9d77ce53a84745494", + "type": "github" + }, + "original": { + "owner": "danth", + "repo": "stylix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "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" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "tinted-foot": { + "flake": false, + "locked": { + "lastModified": 1726913040, + "narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=", + "owner": "tinted-theming", + "repo": "tinted-foot", + "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-foot", + "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4", + "type": "github" + } + }, + "tinted-kitty": { + "flake": false, + "locked": { + "lastModified": 1735730497, + "narHash": "sha256-4KtB+FiUzIeK/4aHCKce3V9HwRvYaxX+F1edUrfgzb8=", + "owner": "tinted-theming", + "repo": "tinted-kitty", + "rev": "de6f888497f2c6b2279361bfc790f164bfd0f3fa", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-kitty", + "type": "github" + } + }, + "tinted-schemes": { + "flake": false, + "locked": { + "lastModified": 1767710407, + "narHash": "sha256-+W1EB79Jl0/gm4JqmO0Nuc5C7hRdp4vfsV/VdzI+des=", + "owner": "tinted-theming", + "repo": "schemes", + "rev": "2800e2b8ac90f678d7e4acebe4fa253f602e05b2", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "schemes", + "type": "github" + } + }, + "tinted-tmux": { + "flake": false, + "locked": { + "lastModified": 1767489635, + "narHash": "sha256-e6nnFnWXKBCJjCv4QG4bbcouJ6y3yeT70V9MofL32lU=", + "owner": "tinted-theming", + "repo": "tinted-tmux", + "rev": "3c32729ccae99be44fe8a125d20be06f8d7d8184", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-tmux", + "type": "github" + } + }, + "tinted-zed": { + "flake": false, + "locked": { + "lastModified": 1767488740, + "narHash": "sha256-wVOj0qyil8m+ouSsVZcNjl5ZR+1GdOOAooAatQXHbuU=", + "owner": "tinted-theming", + "repo": "base16-zed", + "rev": "11abb0b282ad3786a2aae088d3a01c60916f2e40", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-zed", + "type": "github" + } + }, + "tomlplusplus": { + "flake": false, + "locked": { + "lastModified": 1756542235, + "narHash": "sha256-qcc8yXND9htFqjQADU60+xoJZ0acoQwcs7tIK1LgAOg=", + "owner": "marzer", + "repo": "tomlplusplus", + "rev": "e7aaccca3fa3dbde9818ab8313250f3da4976e37", + "type": "github" + }, + "original": { + "owner": "marzer", + "repo": "tomlplusplus", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..962c07a --- /dev/null +++ b/flake.nix @@ -0,0 +1,103 @@ +{ + description = "RuJect Nix meta repository"; + + inputs = { + # nixpkgs + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + # home-manager + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # games + polymc.url = "github:PolyMC/PolyMC"; + + # other + flake-utils.url = "github:numtide/flake-utils"; + disko.url = "github:nix-community/disko"; + nvf = { + url = "github:notashelf/nvf"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + stylix = { + url = "github:danth/stylix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + apple-fonts = { + url = "github:Lyndeno/apple-fonts.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + hyprpanel = { + url = "github:Jas-SinghFSU/HyprPanel"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + dns = { + url = "github:nix-community/dns.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nix-openclaw = { + url = "github:openclaw/nix-openclaw"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + { + nixpkgs, + flake-utils, + ... + }@inputs: + let + mkNixos = import ./lib/mkNixos.nix; + infra = { + users = [ + "rus07tam" + ]; + modules = [ + inputs.disko.nixosModules.disko + ]; + overlays = [ + inputs.polymc.overlay + inputs.nix-openclaw.overlays.default + ]; + inherit inputs; + }; + in + flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + { + packages = { }; + + formatter = pkgs.nixfmt-tree; + } + ) + // { + nixosConfigurations = { + elaris = mkNixos ( + infra + // { + hostname = "elaris"; + } + ); + velarion = mkNixos ( + infra + // { + hostname = "velarion"; + users = [ + "rus07tam" + "macan" + ]; + } + ); + }; + }; +} diff --git a/hosts/common/default.nix b/hosts/common/default.nix new file mode 100644 index 0000000..fd766e9 --- /dev/null +++ b/hosts/common/default.nix @@ -0,0 +1,75 @@ +{ + pkgs, + modulesPath, + hostname, + lib, + config, + ... +}: +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ../../modules/direnv.nix + ../../modules/fonts.nix + ../../modules/motd.nix + ../../modules/nh.nix + ../../modules/nix.nix + ../../modules/nixos-update.nix + ../../modules/sops.nix + ../../modules/ssh.nix + ../../modules/remote-build.nix + ../../modules/security.nix + ../../modules/tmux.nix + ../../services + ]; + + boot.kernelPackages = pkgs.linuxPackages_latest; + + system.stateVersion = "25.11"; + environment.systemPackages = with pkgs; [ + atool + curl + cmake + dig + eza + fastfetch + git + ripgrep + bat + rmtrash + ]; + + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; + }; + + console = { + font = "cyr-sun16"; + keyMap = "ruwin_alt_sh-UTF-8"; + }; + + programs.nix-ld = { + enable = true; + libraries = [ ]; + }; + + services.xserver.xkb = { + layout = "us"; + variant = ""; + }; + + time.timeZone = lib.mkDefault "Europe/Moscow"; + + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/elaris/default.nix b/hosts/elaris/default.nix new file mode 100644 index 0000000..359d9e3 --- /dev/null +++ b/hosts/elaris/default.nix @@ -0,0 +1,23 @@ +{ pkgs, ... }: +{ + imports = [ + ./hardware-configuration.nix + ./secrets.nix + ./machine.nix + ../../modules/audio.nix + ../../modules/throne.nix + ../../modules/opentablet.nix + ]; + + boot.loader.grub = { + enable = true; + device = "/dev/sdc"; + useOSProber = true; + }; + + programs.dconf.enable = true; + + environment.systemPackages = with pkgs; [ + android-tools + ]; +} diff --git a/hosts/elaris/hardware-configuration.nix b/hosts/elaris/hardware-configuration.nix new file mode 100644 index 0000000..8fe5d5e --- /dev/null +++ b/hosts/elaris/hardware-configuration.nix @@ -0,0 +1,30 @@ +{ + boot = { + initrd = { + availableKernelModules = [ + "xhci_pci" + "ahci" + "usbhid" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ ]; + }; + kernelModules = [ "kvm-amd" ]; + extraModulePackages = [ ]; + }; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/5a3b4297-3879-4adc-a8eb-6b7c13bfcb81"; + fsType = "ext4"; + }; + + swapDevices = [ + { device = "/dev/disk/by-uuid/ba42c990-1896-4a4d-8a08-d5ada45c4b72"; } + ]; + + hardware = { + graphics.enable = true; + nvidia.modesetting.enable = true; + }; +} diff --git a/hosts/elaris/machine.nix b/hosts/elaris/machine.nix new file mode 100644 index 0000000..7e17951 --- /dev/null +++ b/hosts/elaris/machine.nix @@ -0,0 +1,7 @@ +{ + machine.xray-3x-ui = { + enable = true; + domain = "3x-ui.ruject.fun"; + subscriptions.domain = "sub.3x-ui.ruject.fun"; + }; +} \ No newline at end of file diff --git a/hosts/elaris/secrets.nix b/hosts/elaris/secrets.nix new file mode 100644 index 0000000..a359b1c --- /dev/null +++ b/hosts/elaris/secrets.nix @@ -0,0 +1,16 @@ +{ + sops.secrets = { + "elaris/publicKey" = { + sopsFile = ./../../secrets/elaris.yaml; + mode = "0644"; + owner = "root"; + group = "root"; + }; + "elaris/privateKey" = { + sopsFile = ./../../secrets/elaris.yaml; + mode = "0600"; + owner = "root"; + group = "root"; + }; + }; +} diff --git a/hosts/velarion/default.nix b/hosts/velarion/default.nix new file mode 100644 index 0000000..bf61a20 --- /dev/null +++ b/hosts/velarion/default.nix @@ -0,0 +1,25 @@ +{ modulesPath, ... }: +{ + imports = [ + ./disk.nix + ./machine.nix + ./secrets.nix + ../../modules/podman.nix + (modulesPath + "/installer/scan/not-detected.nix") + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.loader.grub = { + enable = true; + efiSupport = true; + efiInstallAsRemovable = true; + useOSProber = true; + }; + + programs.dconf.enable = true; + + # Setup DKIM key directory + systemd.tmpfiles.rules = [ + "d /var/dkim 0755 root root - -" + ]; +} diff --git a/hosts/velarion/disk.nix b/hosts/velarion/disk.nix new file mode 100644 index 0000000..d6209c0 --- /dev/null +++ b/hosts/velarion/disk.nix @@ -0,0 +1,37 @@ +{ + disko.devices = { + disk.disk1 = { + device = "/dev/vda"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + boot = { + name = "boot"; + size = "1M"; + type = "EF02"; + }; + esp = { + name = "ESP"; + size = "500M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + name = "root"; + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; +} diff --git a/hosts/velarion/machine.nix b/hosts/velarion/machine.nix new file mode 100644 index 0000000..1eef872 --- /dev/null +++ b/hosts/velarion/machine.nix @@ -0,0 +1,161 @@ +{dns, ...}: let + domain = "ruject.fun"; + database = { + host = "127.0.0.1"; + port = 5432; + }; + ipv4 = "94.156.112.0"; +in { + services.nginx.enable = true; + machine = { + gateway = "10.0.0.1"; + inherit ipv4; + bind = { + enable = true; + inherit domain; + zones = with dns.lib.combinators; { + ${domain} = { + SOA = { + nameServer = "ns1"; + adminEmail = "hostmaster"; + serial = 2019030800; + refresh = 3 * 60 * 60; # 3 hours + retry = 1 * 60 * 60; # 1 hour + expire = 7 * 24 * 60 * 60; # 7 days + }; + useOrigin = false; + NS = [ + "ns1" + "ns2" + ]; + + A = [ipv4]; + + subdomains = rec { + ns1 = host ipv4 null; + ns2 = ns1; + "3x-ui" = ns1; + "sub.3x-ui" = ns1; + git = ns1; + music = ns1; + bitwarden = ns1; + roundcube = ns1; + status = ns1; + irc = ns1; + "upload.irc" = ns1; + nextcloud = ns1; + code = ns1; + mail = ns1; + matrix = ns1; + chat = ns1; + turn = ns1; + }; + + TXT = [ + (with spf; strict ["a:mail.ruject.fun"]) + ]; + + MX = with mx; [(mx 10 "mail.ruject.fun.")]; + + DMARC = [ + { + p = "quarantine"; + adkim = "strict"; + aspf = "strict"; + } + ]; + DKIM = [ + { + selector = "mail"; + k = "rsa"; + p = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0L14rM/ObA5WwVlPpCMiy3ESOhqo9Ye0edtc52sjt+YxJxpDgT1oo1yCdoXWbF38/f2RfqgmBCKg0+N9YQFsAL8FbBcAlkERXbt52T/5A5gBkfUnwB1I646WQdT43JsCWiSYgDc4IcVM/tG8Quj/oKois+b8W6dco6NWLET7bBcnBCEfJYL7TLnG+O83poB+gHef3g0WqwMMqXqbgvJutGb4uevJ327Ywa77fcUp7oYrMvgz6ESmetgmsizTwJadwuXC2k4E50ZmlM3tdjpisQgaUImJBqEa311SXfkhD9AbKjfp5tmOjinPMZwqVM09GFkIn89X7U6LDykh85zBNwIDAQAB"; + } + ]; + }; + }; + }; + code-server = { + enable = true; + port = 4444; + domain = "code.${domain}"; + user = "rus07tam"; + hashedPassword = "$argon2i$v=19$m=4096,t=3,p=1$Z29zNjNOalFobUwyak1YY3pwYlYwL0IrN053PQ$hmRE46O8UM9zTgINjt5/xn35xypU+MMxNNq1r7xPXqo"; + }; + coturn = { + enable = true; + startPort = 49000; + endPort = 50000; + realm = "turn.${domain}"; + }; + forgejo = { + enable = true; + enableRunner = true; + domain = "git.${domain}"; + port = 3000; + inherit database; + }; + mail = { + enable = true; + inherit domain; + fqdn = "mail.${domain}"; + }; + minecraft-server = { + enable = false; + port = 25565; + }; + mysql = { + enable = true; + port = 3306; + }; + navidrome = { + enable = true; + domain = "music.${domain}"; + port = 4533; + folder = "/mnt/music"; + }; + postgresql = { + enable = true; + port = 5432; + }; + prosody = { + enable = true; + port = 5347; + domain = "irc.${domain}"; + }; + nextcloud = { + enable = true; + host = "nextcloud.${domain}"; + }; + redis = { + enable = true; + port = 6379; + }; + roundcube = { + enable = true; + domain = "roundcube.${domain}"; + }; + synapse = { + enable = true; + element = { + enable = true; + domain = "chat.${domain}"; + }; + domain = "matrix.${domain}"; + port = 8008; + metrics = { + enable = true; + port = 9000; + }; + }; + uptime-kuma = { + enable = true; + domain = "status.${domain}"; + port = 4000; + }; + vaultwarden = { + enable = true; + domain = "bitwarden.${domain}"; + port = 4534; + }; + }; +} diff --git a/hosts/velarion/secrets.nix b/hosts/velarion/secrets.nix new file mode 100644 index 0000000..764421b --- /dev/null +++ b/hosts/velarion/secrets.nix @@ -0,0 +1,25 @@ +{ + lib, + ... +}: +let + cfg = config.machine.bind; +in +with lib; mkIf cfg.enable { + sops.secrets = { + "velarion/publicKey" = { + sopsFile = ./../../secrets/velarion.yaml; + path = "/etc/ssh/ssh_host_ed25519_key.pub"; + mode = "0644"; + owner = "root"; + group = "root"; + }; + "velarion/privateKey" = { + sopsFile = ./../../secrets/velarion.yaml; + path = "/etc/ssh/ssh_host_ed25519_key"; + mode = "0600"; + owner = "root"; + group = "root"; + }; + }; +} diff --git a/lib/baseHome.nix b/lib/baseHome.nix new file mode 100644 index 0000000..544df64 --- /dev/null +++ b/lib/baseHome.nix @@ -0,0 +1,16 @@ +{ + osConfig, + config, + username, + ... +}: +{ + _module.args = { + me = { + inherit username; + } + // osConfig.users.users.${username}; + osSec = osConfig.sops.secrets; + sec = config.sops.secrets; + }; +} diff --git a/lib/mkColmena.nix b/lib/mkColmena.nix new file mode 100644 index 0000000..7433405 --- /dev/null +++ b/lib/mkColmena.nix @@ -0,0 +1,49 @@ +{ + hostname, + inputs, + users ? [ ], + modules ? [ ], + overlays ? [ ], +}: +let + mkHome = import ./mkHome.nix; + usersHomes = builtins.listToAttrs ( + map (username: { + name = username; + value = mkHome { + inherit username hostname; + }; + }) users + ); + usersSystemsConfigs = map (username: ../users/${username}/system.nix) users; +in +{ + deployment = { + allowLocalDeployment = true; + tags = [ hostname ]; + }; + imports = [ + { + _module.args = { + inherit inputs; + inherit hostname; + }; + nixpkgs.overlays = overlays; + } + ../hosts/${hostname} + ../hosts/common + inputs.home-manager.nixosModules.home-manager + { + home-manager = { + useGlobalPkgs = true; + extraSpecialArgs = { + inherit inputs; + inherit hostname; + }; + users = usersHomes; + }; + } + ] + ++ modules + ++ usersSystemsConfigs; +} diff --git a/lib/mkHome.nix b/lib/mkHome.nix new file mode 100644 index 0000000..488e36d --- /dev/null +++ b/lib/mkHome.nix @@ -0,0 +1,19 @@ +{ + username, + hostname, +}: +{ + imports = [ + ./baseHome.nix + ../users/${username}/home.nix + ../users/${username}/hosts/${hostname}.nix + ]; + home = { + inherit username; + stateVersion = "25.05"; + }; + _module.args = { + inherit username; + inherit hostname; + }; +} diff --git a/lib/mkNixos.nix b/lib/mkNixos.nix new file mode 100644 index 0000000..260642b --- /dev/null +++ b/lib/mkNixos.nix @@ -0,0 +1,45 @@ +{ + hostname, + inputs, + system ? "x86_64-linux", + users ? [ ], + modules ? [ ], + homeModules ? [ ], + overlays ? [ ], +}: +let + mkUsers = import ./mkUsers.nix; +in +inputs.nixpkgs.lib.nixosSystem { + inherit system; + modules = [ + { + _module.args = { + inherit inputs; + inherit hostname; + inherit system; + } + // inputs; + nixpkgs.overlays = overlays; + } + inputs.sops-nix.nixosModules.sops + inputs.home-manager.nixosModules.home-manager + { + home-manager = { + useGlobalPkgs = true; + sharedModules = [ inputs.sops-nix.homeManagerModules.sops ] ++ homeModules; + extraSpecialArgs = { + inherit inputs; + inherit hostname; + }; + }; + } + ../hosts/${hostname} + ../hosts/common + (mkUsers { + inherit hostname; + inherit users; + }) + ] + ++ modules; +} diff --git a/lib/mkUsers.nix b/lib/mkUsers.nix new file mode 100644 index 0000000..560f91a --- /dev/null +++ b/lib/mkUsers.nix @@ -0,0 +1,20 @@ +{ + hostname, + users ? [ ], +}: +let + mkHome = import ./mkHome.nix; + usersHomes = builtins.listToAttrs ( + map (username: { + name = username; + value = mkHome { + inherit username hostname; + }; + }) users + ); + usersSystemsConfigs = map (username: ../users/${username}/system.nix) users; +in +{ + home-manager.users = usersHomes; + imports = usersSystemsConfigs; +} diff --git a/modules/audio.nix b/modules/audio.nix new file mode 100644 index 0000000..cf433fd --- /dev/null +++ b/modules/audio.nix @@ -0,0 +1,21 @@ +{ + security.rtkit.enable = true; + services.pulseaudio.enable = false; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + wireplumber = { + enable = true; + extraConfig = { + "10-disable-camera" = { + "wireplumber.profiles" = { + main."monitor.libcamera" = "disabled"; + }; + }; + }; + }; + }; +} diff --git a/modules/direnv.nix b/modules/direnv.nix new file mode 100644 index 0000000..67ff211 --- /dev/null +++ b/modules/direnv.nix @@ -0,0 +1,8 @@ +{ + programs.direnv = { + enable = true; + nix-direnv = { + enable = true; + }; + }; +} diff --git a/modules/fonts.nix b/modules/fonts.nix new file mode 100644 index 0000000..412174c --- /dev/null +++ b/modules/fonts.nix @@ -0,0 +1,25 @@ +{ pkgs, ... }: +{ + fonts = { + packages = with pkgs; [ + roboto + work-sans + comic-neue + source-sans + comfortaa + inter + lato + lexend + jost + dejavu_fonts + noto-fonts + noto-fonts-cjk-sans + noto-fonts-color-emoji + nerd-fonts.fira-code + nerd-fonts.meslo-lg + openmoji-color + twemoji-color-font + ]; + enableDefaultPackages = false; + }; +} diff --git a/modules/home-manager.nix b/modules/home-manager.nix new file mode 100644 index 0000000..fded2c0 --- /dev/null +++ b/modules/home-manager.nix @@ -0,0 +1,6 @@ +{ + home-manager = { + useUserPackages = true; + backupFileExtension = "backup"; + }; +} diff --git a/modules/motd.nix b/modules/motd.nix new file mode 100644 index 0000000..7080c05 --- /dev/null +++ b/modules/motd.nix @@ -0,0 +1,13 @@ +{ + hostname, + system, + ... +}: +{ + users.motd = '' + This is a NixOS machine. + Machine: ${hostname} (${system}) + Configuration: https://git.ruject.fun/RuJect/nixos-infra + If you administer this machine, you can run 'nixos-update' to update the configuration + ''; +} diff --git a/modules/nh.nix b/modules/nh.nix new file mode 100644 index 0000000..29cd7c9 --- /dev/null +++ b/modules/nh.nix @@ -0,0 +1,8 @@ +{ + programs.nh = { + enable = true; + clean.enable = true; + clean.extraArgs = "--keep-since 4d --keep 3"; + flake = "/home/rus07tam/nixos-infra"; + }; +} diff --git a/modules/nix.nix b/modules/nix.nix new file mode 100644 index 0000000..4f33283 --- /dev/null +++ b/modules/nix.nix @@ -0,0 +1,39 @@ +{ lib, ... }: +{ + nixpkgs = { + hostPlatform = lib.mkDefault "x86_64-linux"; + config.allowUnfree = true; + }; + + nix = { + channel.enable = false; + extraOptions = '' + warn-dirty = false + ''; + settings = { + download-buffer-size = 262144000; # 250 MB + auto-optimise-store = true; + experimental-features = [ + "nix-command" + "flakes" + ]; + substituters = [ + "https://cache.nixos.org?priority=10" + "https://hyprland.cachix.org" + "https://nix-community.cachix.org" + "https://numtide.cachix.org" + "https://walker-git.cachix.org" + ]; + trusted-users = [ + "root" + "@wheel" + ]; + trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE=" + "walker-git.cachix.org-1:vmC0ocfPWh0S/vRAQGtChuiZBTAe4wiKDeyyXM0/7pM=" + ]; + }; + }; +} diff --git a/modules/nixos-update.nix b/modules/nixos-update.nix new file mode 100644 index 0000000..10bca86 --- /dev/null +++ b/modules/nixos-update.nix @@ -0,0 +1,55 @@ +{ + config, + pkgs, + ... +}: +let + hostname = config.networking.hostName; + flakeDir = "/tmp/nixos-infra-flake"; + updateScript = pkgs.writeShellScriptBin "nixos-update" '' + #!/usr/bin/env bash + set -euo pipefail + + FLAKE_URL="ssh://forgejo@git.ruject.fun/RuJect/nixos-infra.git" + FLAKE_DIR="${flakeDir}" + REBUILD_CMD="nh os switch $FLAKE_DIR -H ${hostname}" + + echo "→ Updating flake from git.ruject.fun..." + + if [[ ! -d "$FLAKE_DIR/.git" ]]; then + echo "→ Cloning $FLAKE_DIR ..." + git clone --depth=1 "$FLAKE_URL" "$FLAKE_DIR" + else + echo "→ Repository $FLAKE_DIR already exists, updating..." + git -C "$FLAKE_DIR" fetch --depth=1 + git -C "$FLAKE_DIR" reset --hard FETCH_HEAD + fi + + echo "→ Will run:" + echo " $REBUILD_CMD" + + read -r -p "→ Continue? [Y/n] " answer + case "$answer" in + [Yy]*|"") + echo "→ Running..." + $REBUILD_CMD + ;; + *) + echo "→ Cancelled by user." + exit 0 + ;; + esac + + echo + echo "→ Done." + ''; +in +{ + environment.systemPackages = [ + updateScript + ]; + + environment.interactiveShellInit = '' + echo "For update system use command: nixos-update" + ''; +} diff --git a/modules/opentablet.nix b/modules/opentablet.nix new file mode 100644 index 0000000..3397874 --- /dev/null +++ b/modules/opentablet.nix @@ -0,0 +1,3 @@ +{ + hardware.opentabletdriver.enable = true; +} diff --git a/modules/podman.nix b/modules/podman.nix new file mode 100644 index 0000000..d9284b0 --- /dev/null +++ b/modules/podman.nix @@ -0,0 +1,19 @@ +{ pkgs, ... }: +{ + virtualisation = { + containers.enable = true; + oci-containers.backend = "podman"; + }; + + virtualisation.podman = { + enable = true; + dockerSocket.enable = true; + dockerCompat = true; + defaultNetwork.settings.dns_enabled = false; + }; + + environment.systemPackages = with pkgs; [ + podman + podman-compose + ]; +} diff --git a/modules/remote-build.nix b/modules/remote-build.nix new file mode 100644 index 0000000..6baabe7 --- /dev/null +++ b/modules/remote-build.nix @@ -0,0 +1,61 @@ +{ pkgs, ... }: +{ + sops.secrets = { + "remote-build/publicKey" = { + sopsFile = ./../secrets/common.yaml; + path = "/root/.ssh/remote-build.pub"; + mode = "0644"; + owner = "root"; + group = "root"; + }; + "remote-build/privateKey" = { + sopsFile = ./../secrets/common.yaml; + path = "/root/.ssh/remote-build"; + mode = "0600"; + owner = "root"; + group = "root"; + }; + }; + + services.openssh.settings.AllowUsers = [ "remotebuild" ]; + users = { + users.remotebuild = { + isSystemUser = true; + group = "remotebuild"; + shell = pkgs.bashInteractive; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDGsHMycO4DL/HlkyWbzSQ6fzeWwRje/pb44NNwrwB11 remotebuild@ruject" + ]; + }; + groups.remotebuild = { }; + }; + + nix = { + distributedBuilds = true; + settings = { + builders-use-substitutes = true; + trusted-users = [ "remotebuild" ]; + }; + + buildMachines = [ + { + hostName = "ruject.fun"; + sshUser = "remotebuild"; + sshKey = "/root/.ssh/remote-build"; + protocol = "ssh"; + system = "x86_64-linux"; + systems = [ + "x86_64-linux" + ]; + maxJobs = 4; + speedFactor = 2; + supportedFeatures = [ + "nixos-test" + "benchmark" + "big-parallel" + "kvm" + ]; + } + ]; + }; +} diff --git a/modules/security.nix b/modules/security.nix new file mode 100644 index 0000000..3f0816e --- /dev/null +++ b/modules/security.nix @@ -0,0 +1,32 @@ +{ + security.sudo = { + enable = true; + extraRules = [ + { + groups = [ "wheel" ]; + commands = [ + { + command = "/run/current-system/sw/bin/nixos-rebuild"; + options = [ "NOPASSWD" ]; + } + { + command = "/run/current-system/sw/bin/nix"; + options = [ "NOPASSWD" ]; + } + { + command = "/run/current-system/sw/bin/systemctl"; + options = [ "NOPASSWD" ]; + } + { + command = "/run/current-system/sw/bin/reboot"; + options = [ "NOPASSWD" ]; + } + { + command = "/run/current-system/sw/bin/poweroff"; + options = [ "NOPASSWD" ]; + } + ]; + } + ]; + }; +} diff --git a/modules/sops.nix b/modules/sops.nix new file mode 100644 index 0000000..ea409cb --- /dev/null +++ b/modules/sops.nix @@ -0,0 +1,19 @@ +{ + pkgs, + config, + ... +}: +{ + _module.args = { + sec = config.sops.secrets; + }; + + environment.systemPackages = with pkgs; [ + sops + ]; + + sops = { + defaultSopsFile = ./../secrets/common.yaml; + age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + }; +} diff --git a/modules/ssh.nix b/modules/ssh.nix new file mode 100644 index 0000000..4bf1904 --- /dev/null +++ b/modules/ssh.nix @@ -0,0 +1,11 @@ +{ + services.openssh = { + enable = true; + openFirewall = true; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + PermitRootLogin = "no"; + }; + }; +} diff --git a/modules/throne.nix b/modules/throne.nix new file mode 100644 index 0000000..ba683ef --- /dev/null +++ b/modules/throne.nix @@ -0,0 +1,9 @@ +{ + programs.throne = { + enable = true; + tunMode = { + enable = true; + setuid = true; + }; + }; +} diff --git a/modules/tmux.nix b/modules/tmux.nix new file mode 100644 index 0000000..d9022c5 --- /dev/null +++ b/modules/tmux.nix @@ -0,0 +1,6 @@ +{ + programs.tmux = { + enable = true; + clock24 = true; + }; +} diff --git a/secrets/common.yaml b/secrets/common.yaml new file mode 100644 index 0000000..4677c88 --- /dev/null +++ b/secrets/common.yaml @@ -0,0 +1,86 @@ +pgsql: + stub_password: ENC[AES256_GCM,data:sv1LiXVMp0M1K0V3p3uNUw9Z+Csxzn92R1dmPw==,iv:7QVwH0VKEWekmdL3AGIZ4StCQenk2Fkgg/j1cx+EQ6s=,tag:9phQFL5zoRg2Ozc3y+oUhw==,type:str] + ruject_password: ENC[AES256_GCM,data:1aK1JyxhlFO8l1O4BmI/Rg==,iv:QUB3gVt7sfK7h9zmIuafl3aVpI6Bfl6W5YS3Y6CUXZs=,tag:uu19ZMFu8SpB6BotYwSxtA==,type:str] +redis: + password: ENC[AES256_GCM,data:JlPBdw8kYha0njCEIg1lWjDGl9bOM3Nf0YsmRWhXAENvmJCfJxRym3/KKvu2yzaq1u+gUtur,iv:5W8gzdPP28GOtcRGfY7Cm9EwI8RxOX43g1nPY1WUido=,tag:xZhLXIfchwy/PTpqYe38bw==,type:str] +forgejo: + runnerToken: ENC[AES256_GCM,data:35QFaIHQTh2vkqH2r7yJIeMqmJoeUm6cAnwNGIwhMVlZDwx0CqwXcrKJ9B5qQg==,iv:VLMWH5RUZQua2CWfI7fm6b6NgXgxcY/ofj8c1ue9F4c=,tag:U/Q0EeQeyL/ptz/5phPqHA==,type:str] +mail: + adminPassword: ENC[AES256_GCM,data:AHE/5iezL1MEPQ==,iv:+xEuFvWcjvW9mNEuOkcRZpGynJ1m4BBEyFR0OOgCBjg=,tag:qPlKRvnXByeQ+rCk2x8XZQ==,type:str] + servicePassword: ENC[AES256_GCM,data:3MIyNYsTYoYfjixtkSrafXGfJSwFCR9XPTVP73dnkWmsRhtKJJiE63AyzkSNHrmq9TYDrRhB8rrAlYegVnkgEpV3HJYmjrYVCvpcd+/qyckx0XXoyRF4VMFjpKwR/Zs54VvWgY45AO9c5vgzyo+v6VKZcdEJZHKd05p0oTY5KDk=,iv:EswLlL0BEljkLM7eN9qcd5TCeRhXAJsKHuZkC08GkPg=,tag:343y2ccMtiW6XhSm9yCdXw==,type:str] + serviceHashedPassword: ENC[AES256_GCM,data:Hgkyrxdkrp0V0ufP1/83yjgn1InyvwSW1qbHPDknLKdmD8tSAP8Du8KCHnAvApFc9zZznxs74/0X9c/MrqPiWly4Rire0UklmQ==,iv:DuL4bzlTO2BCf1cFEn6vHvitWifch3KTCPO1y2yhp8o=,tag:Nz4F+7vTpRwDP3jBPX7ncg==,type:str] + NikitaHapanulStaff228HashedPassword: ENC[AES256_GCM,data:zU2J7VgjKcfLKWINzpMXyn7t56c29elaQOs5QwTUh3/jtZmW6NMmK7ixfe0q0RpbPUvlZ3+aoZx53iK5,iv:YBh5BulGBqPFMlgeGCmAUOsbwEpWTVikdnYdEZAiL6E=,tag:ME+rXqlN599i7HfOCxAWlQ==,type:str] + nikitapocox6prohype: ENC[AES256_GCM,data:YWoNud+wj+vNuoDwggJ2u/wRsrBCHVJZzmrjuawEcFir0AgKKDmSE6TgA23ME8nbgf5eZDe/W9OrqScC,iv:CCa6xHt7tlZmqR/efUVbptc+dgAUFYKtYFgY/RuTsmU=,tag:Wt1+XvnmgizoD/bq9F8PXg==,type:str] +nextcloud: + adminPassword: ENC[AES256_GCM,data:DAcDVpXzB4YGW4WjhfdbRmD4KqzCNzSGkeLUkLWqBjDD5oUzHJGQPWmCPGA0FPjnD7m+Amp7PGL2EiVUb25fnZLpjdvCMBlV3LX+7FhrbhgRLC08tuzNnbTC5wZnFMnNVyafVo6KbHizNZ010CLS7nPmNLEQ66u8D1itfjzAhiM=,iv:oFSMCPuGrvxo1FmdZzItCKo8MBXdPwypxJTNIHZtaYE=,tag:VihrlVnC8f2C3bBNl1EiLQ==,type:str] +matrix: + registrationSharedSecret: ENC[AES256_GCM,data:D7QXctCxuAklGaJ97Hs1FVklGir+Bm0FywEobBy/g10OZep59k5ZZvMIryD9mliRcTBZ6yDCLEUSrCR/mivODMwCIeHa7j/bQ+aRePdfldGxKwVTDPj9bPrqHlIjD/udnCfLxMUoiDlW28qRvREViFV2UCUsfv30Vs781Cb+w+jxMYd+jlvGlMQ8yR1KcHiz/OFmXqa4Mf9VGWBk3lo46hXp3hfUPNmRkEe1TJydkqsk/tT983W5T1D3yPEhYyFKffOW5DoxZCVqB/rqgI3sxKImNnbKSXaHOcNS7pd3X6eT6bASwA57Drn2Eq9GGCbFuHKiwcFK5IfGGQ1iGnSQ9Q==,iv:XKToUDOV72dgTEwYR4AsDGPyr+4ifR8HKXYQV9yMAMY=,tag:iubeVLZlE8lQos35BUFxaA==,type:str] + signingKey: ENC[AES256_GCM,data:DdTsNPxrma6o/1BgsZlk/E6hDewNnU8AbukKR65U1b4WvS+YF3ffCRqYU7i1AMpbgUgf43H5bhlUTw==,iv:uTdZ5Rqf1/XCusoICInGp25CFDIanUzbl23K22ASDmI=,tag:vO7KGumD5slZrDCx134oCQ==,type:str] +turn: + authSecret: ENC[AES256_GCM,data:MjeCwd8CTugY5SccIOPMhGPwSurPiWnqlxmAVlMxSAWDMtngFwmyCl97ixW8BRMYTZy2iaml2AGlWrDyV42JgsFhvohYx/H3bsWFgKC2pO+PxHtC0syYKiuRWj2V8+mIb8wcsr//2L7O9gCTKBnyrwYbv8hG8J3SLfHqFDCBhX5dyzKCht6wjnhJOU3ZXN+foZHCyapOEqoY75K4oeVJxsWRCI9T/VPhuiH3QyosjTiyNBXYhz8UWYG+tpuh4AY7IPmHYeof04BqiuojjjTjaSuy+2v2QHVR2RSDJ6kCb4QkqwwsoGaDujm3el4xnduzRwLh60yZeNPFscKIylHi6A==,iv:Hq6yM3iurnj2TVjyvQb6iaUD+MRjas3bTFkht/mZ2Iw=,tag:YeR2fdglcdRKNgMZizGgOg==,type:str] +remote-build: + publicKey: ENC[AES256_GCM,data:NxHuASqi56IftFCJKLjw1mbTedT87T05frAdM8HEEHPDcxC5pkcf+KTiNFTZHlfaI4/ZHI86LowK1PsHaS9CDOflwY4R8x6nT+Ysz0ff0udXzfrWR9qknHBWbvUEowunCU+/,iv:3j5TrIi0Rej6VYb7lRsPTxL+jHCqvvPMKptQ9r+vm2Q=,tag:84n/Sc5KOiZ49EZW8Ya9nA==,type:str] + privateKey: ENC[AES256_GCM,data:bLE+T+s0b/+TqNUpDZ2kTYQwDlflCGeFhqsuq6Mc/og7TFn4JRfFxCR0B0glvbuMJs4GM/v+IERIRUNolVmg3u1Sqc6mmWXM5pKlba3NXsZW/MxzOeLgsiUQFnhEyo1rEmAqNr0CQH1fTbiOiBYLxEpnAvz2Swggd7wXUDhM5NrlQeVUSnsyET12Nc/WH7K5YRyIEa/KjIvjo3DWPzUuWcqwQ39f7j17uutjwdfirAsojakmW/jfd/SI7/9oqC5MI5Uwnk4DqmNGviO1SHRHQQ9cGlA5WYVw3kIzW8faEaygbKxbzJYTpoO3jljZKEn/Xakj6rpmCeKKGbKB7JoZbMI2ye3GSj/W77kYLj6QaMuDBy7BqLo6CytFKTUl+QxmXkOWngzLDA8VhKzZVIRIjIQTB5d+82f77ztXLvPkq7AOEOhd9ySRZHC23yPPjLpzl+BcmxLSDzNrTah2LcfaNAUptN3VvgHcl3uNjKRdTj9aJ4ERXeExVjDqsIKRczg0mklYwGbjQNtqCfu68Z61oX3C57LiIwa2ByTp,iv:HuCYE3EwVJbc6a6VB9liWMAKZvk6Wbs6S2hrNj2SseQ=,tag:KPP3KWtF6jZ7D18Bx3PXrA==,type:str] +dkim_default_private: ENC[AES256_GCM,data:/+rjVdc3CRahnHdpDM0ZMJaskE3qdcwwd69v9+teLF9H7gqL4I9Y7Lvs0zxmraDv2+C9uNmjvN/XP50bV42wKqVR1yhKRn9zfw9fyM/MHQuynxnlxwN8yMWUaiJ0B1llpbrg7nBxUkiIP4bjRIrIVDcW7I5waju9OceDFE09nLaJuFl4zzRbKf+tBRqynRPNH3rBug+SL8RbpLwipULMaWQTieOktDFy5NdW75lV458F/BWzfWHdPu9YRgW/w8r7QEZc2BZSH/GaVFA5OORUG9GaHMw3FWeOxejrrx1BThPn7+ILqPUXjakIk//W0mPFcbxD498kfbNgmIsP0jjLb+lsEY5AKQF+57ldePKLQx6kX4tMi+Ofg1qWVk7n0dywTVYB8yBKkp9N08JawAMuMQnXpdIj/XYGUJzsYw9s8ysps+J+suEd9o1AuK0iI6f/TZJfBhn3ptYwUyCtKSk13cKSzZFaQRSBHHnv6XmOMDhzucnJKjefAOF7zJIc7ZR2Cy73gXFACx1eqdwky68F0iM1NxVJ9DwX1552KjKmQ3gXVlm6R24juTsGwOsj0/iVS3GOqGNeBFTYNF+mXvAjLUuhONFxImsZGIMON/Ufbsa/yBhtSGIlkRKDF480n5fEKEnaIALPaEV8E4nnQHvYJuDp3lp7teGRFOSDdXL1d5/jSJ/ASvFJY+BarE8W1CocSvCObKS++LpqVcak8Re6FvYmuacA966spmX/ftXXsszdlGHbgGlCNgEDIySAcdGMGFJSjgFQpX4IOIAxxTwdLebTiJlHTn9seKmopb6PdqgPTnRj8i8RQHYx29PX+ZTWs60HHpBvMaSk9R4PDNi3DC0pffa40jHmH9s5K0qf2Dkv0f6s+KyrRurEXo8MOgqT9ErDiZdR+MJkSHls67tk/nYP8eFYdGrYle9+DA2IFdaJpcaCCI0ZBsN33ZXRx27d8LIxmhrBv5FeomHxAleiumSTnsaO1jkM47YHe6ZIqoWloiKmvkS8zc9CrK2VVhpJlx1M01RoUMntBKbiqN3pJoZ86ZRSPZnurqGgTe7IWlfmlvgIvJkvmst2JaWoOfNYZqRFbJERvUsuPku1ggvHTWiOt/ICgGb0HFxuYutySkBZuddiO2an3r+0zkMSiHE77T8QHh+sV+RrcCWINBfg/0MPLy0IMjKanx9qBKDRVbniLqSaMjSfdAVhI9lzre96mWu8dAHEsslMGLoKu2vOzQjwL+RUHSEunIkEs5xiL4SjHpPnTd5QjcA+q0BEls8HkQkdoFzJHycFM2OP4gVEjIXW/fhRx4j4JejUCqO7XjLX1qcBVV5JD50VVuPgZbPP00P94z2Rw3VnZQhpwHXxsPczhv3FYgM8fs+xC5Wwnjq61KQBYxQ5o6j6XEfFlmLPrwAMJs5peC2wHf1JcihvSsw8zAiZ8fvrOv/TiaUgQ+8YHCRtg29/1ykLQdq7gqU4o5ZMeGBYxwTvN5yHqlxkhl4HSsusQYF4lyCjpNe+QdJzHie2g9IuarY8pYVIPyGOvQypLCYdJiYXMr2Zz6eDkv5oUv5LYaNPL5mgl8KvtEYZhscdAkuuNxSMVZ5OBReJ7+YQ6ujuWk80anyXoYQLDeYEdBiteGUbYDYwLPPJDC+3vs6mh3mLqCaW3mSbfjj7igs7oIFpGMW1n+iVizroSNPbtljHaan0NSnYNAIsxNagTRVPG9wax0oMPPhbD9S6Km7HRPL52MRDIRFAgp5Ja4cxO/sbYQ/6u6a2hv1550iVe5G0ITkZJQO9/wYEfp2sSLqGxCmidI1eSkWkXxaMuRaFEVejm0t1ns4qk/vyjsdbPc/LHizBYNY/wogATYFyUUbkvH793b6vylVm2kP1vvcd+U6n1GqfiqPPbAAWSHXrEc9MpMK90xlyrVjhT8Cm07CEqPpphDuD8u8zPAE0Pckd5/js/Mu6GDabrwNI/wcYuIUw9sE1U4Wzh3xtToIix3p3xWC04KTGR6HjoggHzuuG1cytpdmaZ9MqjhuT92iCPMPSm3zvWY4AjSEGsPnng4LQZZ5aRlRcXdd7MDvXEN5Oq+1clW008/zKpjPKvtIes3JJosPDgHw3iyMx+dayAGxb/zwKY7L2xexDnX9GZnVyNfzfi90dTm7RTofOr4cXrxhRKXlR4MLTgg77FMMVDc2ogffX4WQMzl03fyQjwTphURq7aMlRn4McB+UxbqLxZi0pYJWGYPKY7MRl7nDFrkkkDvecXjID7jN71gzfg03U8yBQo7CB,iv:CaV9+khwZ1OVxGxePjSAnw4Nd3rzqlk1pNQBRXjwpgo=,tag:trfnSC1cnSJsp8tafKY76w==,type:str] +sops: + age: + - recipient: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPRVeP7aRYdbIku7Qr6dLFLQrcq8LUUTTpYZZ3E8ZoQK rus07tam + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFhvTldnZyBsclJN + cjNSSmVjUnlqZ1pNcHlOUTJXMWRJbDRla09uV0s5QXlpTWwzTlVJClpTOXZpdjdL + Y09ocEMyTDFmNWpnQlZ5cVg3aUNra3cwVUgyRnBSUnFCa1EKLS0tIGRjdEJiMXl2 + NVMwaFFlLzF2bWF3cVZwMXp0Vnc0OHBxbUc1YlJDS3pKWFEKsZIAtDpHFPyWKGcW + /Ost3aPXNZTzioM867BiGpZytJPD2fLp+7cJS5Ym4QaAYlJ3AvwL9iRjbFoacLqP + /Vo39A== + -----END AGE ENCRYPTED FILE----- + - recipient: age1qchtmcrsuq7ehf8c60yezurt2cgt64unlhzx2ldntgtnaqds4elslthql3 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHUkErUVIwaTI0U2hpT1Ry + OEdRNlFDMzlaVnpnbW5yaWQ0cWFIdXJma2lZCnhJc2V5ZGhoS252eEJUNGhEVDRS + UGVyY0VBMnRleEIyYTZzc1VGcGE1eFUKLS0tIGRORVYwcEFuZDVzY3dweEtYc3lN + ek9qcVA5WVExVHA0MmFLV3hOWjdVTGMKKQNfuEDdJYOtKZOtzmMUZ2i/Q09lLRIS + bHW+pKIIiFg+udq0HQm6M6xpY+pBnpkAGx3G+jNIB8jByiDu3ZK6cg== + -----END AGE ENCRYPTED FILE----- + - recipient: age10hsw859vkkjk6lss3npzmhu9urjtuhn0x8l63v4h3lfk8wrdxd7s8pfu5g + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQeVg0Z1VYY0R5Q1lMN2tF + by9VSlJWS0JYNXdJMlFMRnBUVUNGUFlaOVNBCndTT05uWG5Cc3M0Wi9kUHVDZExI + RCtTTkxFUW9uWEpTZTRoM2pvTlpXa28KLS0tIFZaWU9hTVFxODJFSjk0VGpFcVVq + TGh0Sk5wbTJVWmhDdE1Yd3crMmppV2cKS7Ob18TDJlA/DJ5eqQ5ikqCY/367LQAX + /G4YUOnvYENHjcxT0o9RsH8JVHu0gGdjDrsYKHYgAtMn/6iOhLWddQ== + -----END AGE ENCRYPTED FILE----- + - recipient: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFg3eK2k8JC+iUMsYJFjb8ux19Nl23pi9qQ81ns563Db root@velarion + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IDUxMmYxdyBDYUZa + SjJHb1EweUZaaHpVMXFHMnVPUXBNVVB1RnNJYkZhRUxUcVpadjJrCkVNTi9sUzl1 + aFU1UTh6OTFONEFySi9oeEY3bFVuT1FKczk1RzZYOTdZWkEKLS0tIFIxemNuS21D + V2lwRjUycXlHVi9PR3ZvZ2tVanFabWVpUlQxcXpjWEg4K2sKZr4ayMfAAQZloZ2J + ieD9150XkqhWLYjiSjSOR01Fp8liXxpkU39knmajzGd0UySQyVjhmzc4V9TW7VWI + nP2OnA== + -----END AGE ENCRYPTED FILE----- + - recipient: age13uupj0vkwn6dlgeqvu06le5d2ms0meu0j694tpnvvn6mnct9xs8ssyjtc2 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmaEkwa2Q3T2J4eFcwb05G + N3hOUmZCeU5UMFJLNUMyWTVOQ1MzN3QyaDNFClR4bW04M0ZnN0hOb0RuWDhROTFy + YXpNOWlDQUtnQWFVelF2SU1RbWd6cjAKLS0tIFV1S0psUy9HZUZkTzRLS1RvRG9X + MzVJejJmYTlqK3NYMVNMOTIyeVdtQ0EKQ897Cuaey+kUW7V+/beZcYyuV3vWDnVz + i1NXoMh9+Feek4rFsczIP69TFMQes78KMP6L55+2dEq3+OE3pUQZqg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1723x4jfn3urne8knvxqawmslq8ysr66uml8c3svj6zy0j3hdh4hs94yfqf + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByNXpmOWRiSFhzYy9XcHNi + NFJnN1hIOHgyYXpSazdCZGVreU91S1A3eXhRCk5nVWo5b1VnYi91WnBjVE1xMEhz + K3dHTWk0MTJkTTdjQ09sYnM0VG5PcEkKLS0tIHZESFFLNlcrQjBjaFV1enJkTUVq + eXNxVEZzUW5lR0dqaUhMTWJmcWJNUHMKXZuzo97FE43+c+KcxibO9bcFA+4omTjB + LQUFFMxenelJ1MWawmUhCeJ13rKjk3EEeTbEav14EF1WzYd4bZgbZQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-31T07:56:54Z" + mac: ENC[AES256_GCM,data:RbblTICMaiSX47NKgKbCoi/2dTDmT/dCXOnM+dXtAYMQI/VNDlbF7EbyXuslmtk9c1rAiW4Bw8iG2JOfbYb/x7Fx6aFm22Caq4cswicuJkYFPKQAEzJo+RkYZXHsdQzXPDTgUZDJJHGka64fOJbss3qDMCTy+JYXlSGMza15OFI=,iv:woR1tD86pX/cNn15JaUfOkFof4WwIu/30DZ/DHlpysk=,tag:KbXiPJPHRd4gNKxQ/T8vwA==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.2 diff --git a/secrets/elaris.yaml b/secrets/elaris.yaml new file mode 100644 index 0000000..090ade3 --- /dev/null +++ b/secrets/elaris.yaml @@ -0,0 +1,65 @@ +elaris: + publicKey: ENC[AES256_GCM,data:WzoDspLsEQ/klU8mgg2C6tVwCl5LPHlJZWw64HyQytfrO4DueJXybs6o5U1tdPODFnsz7BNvmB0XhUu+WVYE2D2PeRr55cAvzZaD+aHSMKedyrcivKGxyZC7fvI=,iv:HQxiEU7PI9uiiDOS15hZzVnpcpWoEY+P868NNCFjbHg=,tag:wqM71r1loamG8yeltgx0qg==,type:str] + privateKey: ENC[AES256_GCM,data:DEYszBbarR/8bysDscQRvsrmzdhkhVABylNtKblG+RkXPnTbdXSwN4K9JZQES8bu0iyas82Ml6Q603Umt29Gv+U0eoGlBeUVAMliZYz7r6/4T0zAauY3oCiZej0SxpQX7ixIQ6HDlqde3lnd9rAA2XltrKGI+WgyknlssOqY6eXI3WN0kfn5b7C25LkaAf9y4I2neT98BfB0hN112EK63faNGa25AEBAnQ/DB1wR3feuWWEkF6N6vwtfdECWZ+onvHzWEMGDIeY8E94n/er3vMZKCKZjbFYJyeANMdDLkIR0K6RJEv0gpsNHhnrDudVUeOod3vbqai/ReAaZVsQBKvvrOSc7NdHTdkaGtxyWTSSVTlJkFwhkTcWYA0yPdIaMaFqGftAXDnjsb020UJZapX2KYcku8R7Q/NPk3TinuM12RFolKm2a9OkIkS3YOo7oDa+sPr0vyCPsIO4LXojGGboeHnu0ui11D93FChq62LQeg7GZJbSKWgH9JSJwE9oVAmUFT91qctj8IVfMo3ET,iv:ms9GGnUm1aTR/uYdt/veidoGChjB8uzYEYyOR4dTEXQ=,tag:WEEmJVAF5B1NKqwyb6OPvA==,type:str] +sops: + age: + - recipient: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPRVeP7aRYdbIku7Qr6dLFLQrcq8LUUTTpYZZ3E8ZoQK rus07tam + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFhvTldnZyBTU1Vu + UDloYmlGL1BBTlg4dzBtRFpUTk5Kb280VEljTld3MTkvK3JqL2dBCndVWDg3d3Na + eUVFSkRxRnR1WFp3WW5JYUtjaWM2aVZUQ2g1TTNLMHZYb0EKLS0tIDU0SGdCUGpF + UjFsVlY0NkVmcC9YMExMYzN5VWorYUNyU3dlR3lMeDNhaDgKrbAzaLaeZtOkeD2u + dO8ct2PPfvt5wNmVdujuX3LvW6w+YjHow78ddz+Ob1KZVqVZV2cmXXmMMdpGmaDn + 2rEEnA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1qchtmcrsuq7ehf8c60yezurt2cgt64unlhzx2ldntgtnaqds4elslthql3 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQYkJYbjRXMzJMQ0NWL0g2 + eGVzMWJHSTFIYUxMWEl4T1NrZUJYT3huVG5jCnI2RFZqODFwaHlENTRCQzhkS1hQ + dFppWFhCeHhZZTdGZTFwWGx4MFdFWlEKLS0tICswcm1mZ2ExUEJEbHNrejBrYXVu + YnhUbCsrY0kvcUdWVmt5U2dLRkZhYzgKY9tY80Rz53Fz9/4//c3ILj0mlHOATBgK + isuAvj9hONSBmdVH1Jz9DQGZaJ5GgFatQtdkmVgpA7Q5/2Vf3aSFKQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age10hsw859vkkjk6lss3npzmhu9urjtuhn0x8l63v4h3lfk8wrdxd7s8pfu5g + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLNEdiaWEyeGhvWk9oRGxT + Z1o3dEZRdXIwZXI3NGhIZ0IweG9wNGU4YUFRCm5rSDg1NjgyVGNabXZDaXduQzdS + MUp3emc4aUhYVzF3WVZvbWVWTGd0bzgKLS0tIDYxR2h2VS9nWDBYTzRtcnkzaEFw + OCtFTlhkVWEyRHYwNDdFZVFoRUFOYTAKwCuCAX+lPrnZ/LvquuRsFNHLF969qkBU + Zx8W8FwJvy6vzzt4g087yKZmTXnjPDz7iKIJxuOAS/pWptpfxNTi8Q== + -----END AGE ENCRYPTED FILE----- + - recipient: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFg3eK2k8JC+iUMsYJFjb8ux19Nl23pi9qQ81ns563Db root@velarion + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IDUxMmYxdyBYcGxa + cW1EMmpTOXJLa1o2UThpdmlHbnRvNXpvekhwbXgzZlltVytmbFhFCmZ5cENyaDI1 + cXRnOEFqTG9aUFF0c1ZWVm01V3pYZHVnV2Eyd1JFYTVFbnMKLS0tIFYrVFVPZkNp + YkhYZTcvSUxlSmM1ZXcyUEdDWXVHYzN0dmxXbktmZVVVdUUKVKARFFdSFHqJEDqb + oS4w2CRVpXwp9mqXs34VPa5xmLON2UXXMpYgNd8FBywhayTO1R8ASec/GVLR0SdZ + oqY/cQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age13uupj0vkwn6dlgeqvu06le5d2ms0meu0j694tpnvvn6mnct9xs8ssyjtc2 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPdkV0MzhOck9tbXJ3ajNR + aE0zVVpTS1IxbDlMMk1IL3ZHalQ2TjdKNGpVCldTVDF5M1NaMkYxMHJmdjlOcWxn + NkFnbHJ5dlNnbjZkNHQ3ZW1FV1ozc0EKLS0tIGNHejhLWVRvWUwyamE2QXJhZzMx + YW1HTkl6aFdQazlwaE93WnoxV3FSM3MK1v0ONp3YyM3Xqb5t/ND7xw/pO9gXfrqt + Yf+HTSO1MvHZ8Rb+Q4H/XWxVcMSCbsBGVd51lWfonNEwX8MoJakdYw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1723x4jfn3urne8knvxqawmslq8ysr66uml8c3svj6zy0j3hdh4hs94yfqf + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrbnFyY1c5amFveThyQ0pJ + MFN4RFdyUVYwQmN2emUwZmh1VU9xNFEyOWx3CjhTdmtjRzIxS3FzMVpZaGhDdnZt + allGcXpmbzRjeHBST2Q0MCtlR2tFQlEKLS0tIFc1SVpkOVRXWCs2QWtJd3kyRUlW + M0pDVzFaZi9HQUd1NkttaTFza2FUMG8K30FbhmejxcVyL0d2eD9aXkpHlkJmr4wB + VXkWaX8ywy7HJ2UCZAGDO1N6IXF2HP8lOaOvJmCTN8JueSTXkkYWMA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-14T12:52:49Z" + mac: ENC[AES256_GCM,data:bTMRGIAX5QWpLmUNu+K2nKABdVoPAmB7wizrFlPVOJcvzyJqnQNHH6Ruj1TJLG+xwH3AYyzq+zlfhJPtYXNzc8DoU23LotKfGRiWH+Kn4Eip0wm1m3IiA2a3NssRusiVfrxnm1HDDuRNRDNUv38j/u/aRMtTGz0iICyDiTRIrh4=,iv:7BNXbCL/BU6zfCWFAdAR98kLzqti6FvJ37KfTij5TS0=,tag:5C7sBUNNTd91ZAIz4y3hiA==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.1 diff --git a/secrets/rus07tam.yaml b/secrets/rus07tam.yaml new file mode 100644 index 0000000..f4f7996 --- /dev/null +++ b/secrets/rus07tam.yaml @@ -0,0 +1,75 @@ +rus07tam: + password: ENC[AES256_GCM,data:xgbrEeExmAE3fg==,iv:PhVdo10JII7stLx5E4PX6H3IIYoNuw//fSkd/HQfE/w=,tag:eAGcduhXN5kLF02LsNybHg==,type:str] + hashedPassword: ENC[AES256_GCM,data:Qu0yg569duyqnUQLJyG0niLyGk7pcrh543bvdrMacVlzfp9L1i2tdphb1ErTWgTxXulqosN5UUAEyfRr1xmRjdup23Xxw7xpwQ==,iv:y3rqLeccE1KLly8rXzWtLHywWAuLMw43fAOA1AGaZjE=,tag:F4zPV3N1fMdiTrRxagSHzw==,type:str] + tokens: + forgejo.ruject.fun: ENC[AES256_GCM,data:HL49uipEgJfSHSMh9rD7sL3uDCaBNSlgm/545+PtWaCwoTI+ljNWxw==,iv:bC26lj2vDT5k/dHrIPkFoSTLubEtCSnYh0BlrmnjEFc=,tag:Nink73kyVskdOq1tOtWgMw==,type:str] + nextcloud.ruject.fun: ENC[AES256_GCM,data:Mxu7ixvMmhYD7dQxml6g9RaKMRZhWOmtdZWnr4I=,iv:LXljC2dMoIqGx6WNudPGTOBFCB958BsKBApDYcxXGpg=,tag:Bk2OlTKRgaiRO+IoGM2BTA==,type:str] + openclaw: + gatewayToken: ENC[AES256_GCM,data:c0pWl4Dh4OKERL026UzNrAgfeE+N67Tk6lJc3FUwBuQcILoV9Oqscz6TngkObrM=,iv:yIZ6h0YpZ9e3HQ+FX1txeISrsiXatbbwNSmMgL8/C3A=,tag:mksrURr/EGpOzsYbpdNpBw==,type:str] + telegramToken: ENC[AES256_GCM,data:imMIGjU3s4wks1IOutAlwUF9XSu1d4487sZX7YyBSlbicgpL/OsRyX2m8lXTgw==,iv:UN4vudmyBOkM8bK+KGVBFKlzUXmPM3hFskaPc4J5Wzo=,tag:tojoRu2dDkv/Jsj6+qoHtg==,type:str] + keys: + ssh: + public: ENC[AES256_GCM,data:HTMK1R3JNCAXUzqAtpC9ree4goOx+B+Z/DRZsr5oZ18J/HFsaDDCi+LggHZD9LrFo+J8uJbliWIh7/yVztqLTPAaUUgACN/uNw0w5o4W6q5dFybJZIQHRM6MxLnRCblW,iv:XZ2CjdyDzr/Vjerlp2/oPU66atbzXCXLfYFwUji5hCs=,tag:sLW1oNGqS4ZeNSOgCm64EQ==,type:str] + private: ENC[AES256_GCM,data:nNFimf3QXUB7Zcy/nTI0EMWY65m++pY2I7EkgmXEiATeh0S5br0ETean66uWWXeSzEBeW55mt59hxhAdbWlLIVknf4XsKzhcVTiU2SArCQQWnKRJzq8UMINNfxh4XCjYBxQxeV+B2p2hSo8aypfpOksblLE5db8pi+gg6lc8RspHFUCzid41weu3E8IW+cVMs9cUF7x6/Db5wAwhpGlsEPDtisamFlCXaVEhVivPAP3Qq5YkCXvvzlH3uTm+FNcp0LWMF+yUqzwAcsPOm2sCtOa4j7ZtkGYSYNtXpywM6HusScvp7JcKgEBvyrF4AtWJ5SUGnw4mjz8CDqE8CfMeiiyY7ZlFRKTxKMHT1CJUR2WPfjEFtcFzM9WjaouoNFn97bEUHIb/znqWXOIkPF2qBml6AEKdRauNRI9sRCwJfGsSwpZJMDl/XSoNDyhYg7tUYF7eHP/Ckmv9UUtD/zgEkYpvnssednjVK8SX01Wf+hzWbCYFidKWmoNGTYaK3FnGHcNu,iv:wcvEiLSKM0/rh9vYaOWWrVFGsdvG4aVpG8K+l7u3JD8=,tag:E+o+jErQS+GMmOTiMlfIEw==,type:str] +sops: + age: + - recipient: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPRVeP7aRYdbIku7Qr6dLFLQrcq8LUUTTpYZZ3E8ZoQK rus07tam + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFhvTldnZyBRcmJs + d2IxS0lwVFJuRGpwdGdCaWovVnNlcExoV05hVmhrd3Mwd2RTSlFnCkRvSE1lRGdq + Tk5xdFVnVTI1dE1ETjVvTkFCUEYxSmgrU2FBQ0Z2OE8yQU0KLS0tIGJGN3BtVUVa + emxTMTF6QXVxa2c5MDZaSGE0cDRtVTQxZ283aFVsd3BqcGcKtuN9MND0deqD2Ajw + mX+4cn19Qx+mBdnddwztdaPn1yo0Uug2TX2ioaNSm0jIbeLeLJKNN1iSGyc1V8Ht + JAJFQA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1qchtmcrsuq7ehf8c60yezurt2cgt64unlhzx2ldntgtnaqds4elslthql3 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVaVROWTNBU2R5VzZEZ3do + cmQ5bE9mMUdkcFlGOG1Jc0paS1lET0kzOGpNClViMGRuWWpoUXE0bU5zNUV5VFQx + d0MvZ3U4U3dXamlNcWRkT3JmSXNXbmsKLS0tIHp6cTN3RG84VkdIeWJTdWtBUis5 + WStmOWVWUnVGYUxISGJZUXdYQ01mZHcK/daRFSEv8Ojqubkh1M0gNCqiM51LC3oc + AbLckEXLIIRHRt/IZqCBw6UuGZuS9PYbffTMn1lr2fXht+jw3hGmpw== + -----END AGE ENCRYPTED FILE----- + - recipient: age10hsw859vkkjk6lss3npzmhu9urjtuhn0x8l63v4h3lfk8wrdxd7s8pfu5g + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnbGVKOGY0VndENHhxcXA1 + bFdic3JkcktSQitTUkYxMG5OUlpDYWcvZENvCmNPZC9ETXJmekVqS2NTZHE4MS8r + Z0FlT1NXcVRCclorcWkwdm5wYlYvaHMKLS0tIEFJTVdpUE9xcUYrR1VzWmcvYWdZ + MGFxcG8rMXROL2pFY2xKM0J1aVppV2MKIysYDx5ygqzISV51/1ik1g8QVzk8Kkf8 + Vtr592p/cjgNDDpu4W5kXgCPqR3vh46Doj638tkBqXemMIw0ouIyFw== + -----END AGE ENCRYPTED FILE----- + - recipient: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFg3eK2k8JC+iUMsYJFjb8ux19Nl23pi9qQ81ns563Db root@velarion + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IDUxMmYxdyBwNVVi + dWE1RE9YeS9iaU1sb0o0bFByN2Mwbk9yTHQvWmMxWEthKzZjVUFFCnZBRTVwY1Bj + eWRML3ZBS2hKOU0rZUpNWE5RdzBXMnlqWk1xTVFQN0t2ZnMKLS0tIGZnQXdWS3Qz + cnpwNWZtbGdKd2FNcWNRZS9WL0lHUVE3Y2dlZ21ybVd6ajQKTu5fy/YznOtlE8gg + zzvWwm6Q8dZIMPmfsZQayob4exJ7nKapGYk/NvvBdOnnlHPQpe8wBB/sVdij3RlZ + AAAQ5w== + -----END AGE ENCRYPTED FILE----- + - recipient: age13uupj0vkwn6dlgeqvu06le5d2ms0meu0j694tpnvvn6mnct9xs8ssyjtc2 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4QkhzSHpZbVM2dytvL1Jl + NklkTkpRalc2M3U1Mkt0b0pDUWpyeXFLaVYwCmlIY0ttT0R1NlVvZGtPUk9TK2Ns + OEEzRmNFTFp6dk85TTBKdXVlaFhLVHcKLS0tIDdaY1hhZjZKbk93STVKNlBjbDRx + WFNnOGlBQ284cmJ1SmNuRTNYcGpFU0kK7NVOsmQE3kMsmGaYzcmUigWGRCARccQl + D31cj6R0O8c0T/oQQ1SarP4CV8uM0e5bJUTzAGDQdWWstaof9qHWuA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1723x4jfn3urne8knvxqawmslq8ysr66uml8c3svj6zy0j3hdh4hs94yfqf + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4NTVUclVpN016cCtQWGVo + c2hCREpUMW1CSDIvdkRxbVZhMmNWWlMwZ253CjhUaEpCZE5CWjkwUjZzSVdaMGcy + aktOWElxQUZ3VTFaZHJkNlBKamVTejAKLS0tIEVlU2lkdmxiZW1EQkU0azV1TEcy + Ky8wb0Z5TDRnWjJ4Y0haU0Fzb0xWSjQKEoPTlWh+ldPBzqkycMwEDR/+eEgpXXqt + 0t4p6looSG7GR8EEGlJAXl286Ee1/jBbUETsvcpZ4mTtqiy8a4gA7Q== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-31T08:00:11Z" + mac: ENC[AES256_GCM,data:oVEVe5UsQ/Xsc2tKi8P+1ysejjFui7iuvOnkjntUNm8NX74uvvbY2IajzbWXYRC0Bsh1IlYLQR3EqqO+gLzxilr+WPOBa2uQJsKWhORzKTlCHJpRA0ubxtWgh871oh8IBEooqFiTP8lgaKooy8hWvCS97I9xr90xmSvGlaSnu0s=,iv:VOUXq2Uc1eLOxxOSMzAcbifjoiMmkc0HrZUWxNbq8zk=,tag:fleyFUkWqpnUVh6UAeK9LQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.2 diff --git a/secrets/velarion.yaml b/secrets/velarion.yaml new file mode 100644 index 0000000..1df6275 --- /dev/null +++ b/secrets/velarion.yaml @@ -0,0 +1,65 @@ +velarion: + publicKey: ENC[AES256_GCM,data:x7N0hicf4OIn552Y6oiSvTXDAhAO9A1HXOyXLaPkbBCMdUodN1BsTdXeOVVjDF8o2FepWd6V+JsQ79FB95jCYm2HAXYv8RVQk1CRJe0LhKbroXNPmZF5pnyifXUQ7w==,iv:QQBIC/KjH3410QlAPvxBo9ISJ3MtMkpK2+zlIlWJYn8=,tag:8luzXFyG+EVaNsuSyujH0g==,type:str] + privateKey: ENC[AES256_GCM,data:gPgVoLIN4Yx7+H7EftQfoQbJlEbj1OZ5z2E9Ph7fFs3HJhghHnpgEdx7pYs3fMY2ItkJbaFmwjgaUBgqg/Hf5+gIdkNZkpGSVzGo5uQ9HzpmxT0xvOAOdM1p9RauNTGZ+C5vCF+E+L1by0OD4AQkJWC+3Z+KXyTuA/YrsDA40tIjQRBLACXdNWUjYrt7HwtLugI7/mIA5XnsUJfM8BTPR1FDmkvvvVnmd5LKZEMCnIPdP/WNTbzQZjKAwZDODrv+XBsRywgrUwPyKsyFltSYAkGaOTO0oynutwO/E1GdZJKoqL0FoIv/GXDgrCKsoGwjXjRg5IkfC8/mpq5iMjM33D5ojXE0d0aV5IPnG/+0tIoi7wJQwMJWzLHTFbnq4XnyZEDHmcvLpiADQMC8vHedWiUbgWFjRICeQy6fILUvoRp5hCYmX9UrLUlZ6hltbsleLiQviBirJv+XHsebenrlDuVAD40YShH+hMkMXXPdpr7EI9jaSOmT6MG80UisMVB5AdhZthUX9TToJf4Lcuhv,iv:crGxpSc9SdGOVMYvaF4XSMt7UVpxFHj/oUPEjsQDZDk=,tag:5mQL52tFQH/QmzHAUs/wDg==,type:str] +sops: + age: + - recipient: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPRVeP7aRYdbIku7Qr6dLFLQrcq8LUUTTpYZZ3E8ZoQK rus07tam + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFhvTldnZyAvRG9z + Q2MzZDd3QWN1TU1lQjUyWCt4T2Y1Ullza0RMeHAyRUZDYmw2eWtvClBtZk1yd1Bj + UHFiODZEaHlheXlVSVJCdmRNSVk2ZzFvRmJJRWNILzUydncKLS0tIFRUVU41MjBt + OEZVK2FLSFRxOEhGakNXUW04YWV5bTRmYVlPRVh1N29RdzQKo/t5hxuJRbO0jrHG + Iqk7LsYG3LEeXiDdq1T6AX7xl5UI8KWQfGqZ0IyYB5kIeDvTqJ5JPX/L7QXpH3eN + QOPJew== + -----END AGE ENCRYPTED FILE----- + - recipient: age1qchtmcrsuq7ehf8c60yezurt2cgt64unlhzx2ldntgtnaqds4elslthql3 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKdmY4MlgwdHBNRVVtWFhO + SjExM0U3RkR3RU9wRW5QSEhFcWlZYXdtVkJzCjBYTVEwUjhxYmZYRUdydWhmUHY2 + eUxSTVJlYXZtT3FLZXc5QkRTeWRLejQKLS0tIGpRaWVxZ1E0NEJjM1hGWndYdjhu + dkRkaDdmZGYzbjBkNFF6K1gzVllvSzQKn3/x/Mdht+Gqnxt452pteXYutqcN14Lu + FWyeXleKdDRDbKUWhOr9dqrvvD3xedLw0OMSD2vPjFqbDcJ4T52Vbw== + -----END AGE ENCRYPTED FILE----- + - recipient: age10hsw859vkkjk6lss3npzmhu9urjtuhn0x8l63v4h3lfk8wrdxd7s8pfu5g + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvbXJXMm5ESFlLNk5PSm9H + cmhyNDEvdkVZMFlwNXZnSlNyRml5SzJzb1YwCmxLYjIvQ1hjMlBtbDZQWlRvR3VL + cmZsam1xSUFaYStQaGR1SEJiUTlabncKLS0tIEROZkFjdEdzbGxmVnZ3Qkg2eUV2 + a0F5eTNzSDdWQmkwRXJicnFqVGptMkkKZo1h0NrllsdSxeuK/b5hEpnQx1cEb4MY + rl8PEuqDET6EPF6YumTwO8a4rBk0aFr70j5d1Nwt9NP/7/sabJT44A== + -----END AGE ENCRYPTED FILE----- + - recipient: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFg3eK2k8JC+iUMsYJFjb8ux19Nl23pi9qQ81ns563Db root@velarion + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IDUxMmYxdyBkN0Fy + WnNuM2VUNzlnbEhOL3JaZjRMdG9nN2NwdlVvNUJFQ000cGxzUFFzCjJlcm9weFVt + YWU4TVNIaVRtM0tISUJ1UXN5c2psVEF4OWxRQm5JM1owOFEKLS0tIHBjSFBONEhl + Z2U2ZnRMZkNPTWFtWUZtYWFEN2VjRlBXTStyZjNlL2Zqb0UKgSbnykvrEounRQYX + qadBQe1L7mLF2kLZ7rCBtrvoeig++n3vkxiTUAWXzrrIn0GrW/0aec73HbxWUcw3 + vnDgYQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age13uupj0vkwn6dlgeqvu06le5d2ms0meu0j694tpnvvn6mnct9xs8ssyjtc2 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMZXpqRVdwWWZVbGsvNkgv + d0tMSlF0RU1QNHhneUgvM3pKeXJoTWhPT3lJCnR3VHFJOFpCbEtmeW1aTXpWV1dL + emJEY3BQRjZ3QmcrbVZ5VTNkTGcvV2MKLS0tIDdDNkNlS2ZNWTc0UUY3M0RhTVQ0 + NTBQR2pZWWVGbCs0VHdGRDN4OG9QS00K8IVI+E1HYJPwI0t+QbiTPjc11CV2/SuD + yM1AYGMPR607X8hONxMSDUXSfbr9p/gasV9/SAFyY8vDswthm7KkIQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1723x4jfn3urne8knvxqawmslq8ysr66uml8c3svj6zy0j3hdh4hs94yfqf + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlekErdGgrOHdjOFRlTG9R + UDhXa2o1eHY2NjhFb0t4QjNrUGRZMXlKSVRFCnMyczd5MUs3Q0gzM1pqcCtTeCsy + dEYwUU1pTkptRWVzdDV5OVd2NWlNelEKLS0tIGVTQUQwZmlVVDJPRXhUd1lzNDU5 + YkhmakNxQm1QQk9FUklnK21Uak9ZSzQKakWIF83WIkFewGf5JujB4B0olIEFKPs/ + dW6TAVEPU8HCVuxW5Lw/1ku2BgC+BfHpSVWADop8TkhGTIQNO5Nppg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-14T12:52:16Z" + mac: ENC[AES256_GCM,data:6scaFNi1tCyacOBgpZdQ14VVD/GQ8wvUyl3pgOdPPjxbtbbe5k9dcj9cpGiAjyyk0iPW23W0x5EZBB4jqZxUgaNebyyXhKB/VlJZ0dcWRy4ogBMgUoLMteNdU4i+6FVcEm4SWyrZ2se8ud5FEDbDOuZtHiN4TFRwtNmboWIigRA=,iv:4cJfCgHKxisyqNzhzLnoZAI3GYHn2Y2meQ55hWsqy+Y=,tag:afRV4ED0L5E4gF81q9BChQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.1 diff --git a/services/bind/default.nix b/services/bind/default.nix new file mode 100644 index 0000000..be5ae0a --- /dev/null +++ b/services/bind/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./firewall.nix + ./options.nix + ./service.nix + ]; +} diff --git a/services/bind/firewall.nix b/services/bind/firewall.nix new file mode 100644 index 0000000..1196ffd --- /dev/null +++ b/services/bind/firewall.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + ... +}: +let + cfg = config.machine.bind; +in +with lib; mkIf cfg.enable { + networking.firewall = { + allowedTCPPorts = [ cfg.port ]; + allowedUDPPorts = [ cfg.port ]; + }; +} diff --git a/services/bind/options.nix b/services/bind/options.nix new file mode 100644 index 0000000..f122b00 --- /dev/null +++ b/services/bind/options.nix @@ -0,0 +1,25 @@ +{ + dns, + lib, + ... +}: +with lib; +{ + options.machine.bind = { + enable = mkEnableOption "Bind Server"; + domain = mkOption { + type = types.str; + description = "Domain name"; + }; + port = mkOption { + type = types.port; + default = 53; + description = "Port to listen on."; + }; + zones = mkOption { + type = types.attrsOf dns.lib.types.zone; + default = { }; + description = "DNS zones"; + }; + }; +} diff --git a/services/bind/service.nix b/services/bind/service.nix new file mode 100644 index 0000000..de504c1 --- /dev/null +++ b/services/bind/service.nix @@ -0,0 +1,21 @@ +{ + config, + pkgs, + lib, + ... +}: +let + cfg = config.machine.bind; +in +with lib; mkIf cfg.enable { + services.bind = { + enable = cfg.enable; + listenOnPort = cfg.port; + zones = { + ${cfg.domain} = { + master = true; + file = pkgs.writeText "zone-${cfg.domain}" (builtins.toString cfg.zones.${cfg.domain}); + }; + }; + }; +} diff --git a/services/code-server/default.nix b/services/code-server/default.nix new file mode 100644 index 0000000..05067d6 --- /dev/null +++ b/services/code-server/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./options.nix + ./service.nix + ./nginx.nix + ]; +} diff --git a/services/code-server/nginx.nix b/services/code-server/nginx.nix new file mode 100644 index 0000000..296d0ed --- /dev/null +++ b/services/code-server/nginx.nix @@ -0,0 +1,27 @@ +{ + lib, + config, + ... +}: +let + cfg = config.machine.code-server; +in +with lib; mkIf cfg.enable { + services.nginx.virtualHosts = mkIf (cfg.domain != null) { + ${cfg.domain} = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString cfg.port}"; + proxyWebsockets = true; + extraConfig = '' + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 86400; + proxy_send_timeout 86400; + ''; + }; + }; + }; +} diff --git a/services/code-server/options.nix b/services/code-server/options.nix new file mode 100644 index 0000000..66dfcbe --- /dev/null +++ b/services/code-server/options.nix @@ -0,0 +1,33 @@ +{ + lib, + config, + ... +}: +let + cfg = config.machine.code-server; +in +with lib; { + options.machine.code-server = { + enable = mkEnableOption "code-server"; + port = mkOption { + type = types.port; + default = 4444; + description = "Port to listen on."; + }; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "domain for the code-server instance."; + }; + hashedPassword = mkOption { + type = types.nullOr types.str; + default = null; + description = "Hashed password for code-server"; + }; + user = mkOption { + type = types.str; + default = config.services.code-server.user; + description = "The user to run code-server as"; + }; + }; +} diff --git a/services/code-server/service.nix b/services/code-server/service.nix new file mode 100644 index 0000000..5671050 --- /dev/null +++ b/services/code-server/service.nix @@ -0,0 +1,49 @@ +{ + pkgs, + config, + lib, + ... +}: +let + cfg = config.machine.code-server; +in +with lib; mkIf cfg.enable { + services.code-server = { + enable = cfg.enable; + port = cfg.port; + hashedPassword = cfg.hashedPassword; + user = cfg.user; + host = "127.0.0.1"; + disableTelemetry = true; + disableUpdateCheck = true; + disableWorkspaceTrust = true; + package = pkgs.vscode-with-extensions.override { + vscode = pkgs.code-server; + vscodeExtensions = + (with pkgs.vscode-extensions; [ + rust-lang.rust-analyzer + fill-labs.dependi + ms-python.black-formatter + ms-python.python + ms-python.isort + ms-python.mypy-type-checker + intellsmi.comment-translate + editorconfig.editorconfig + dbaeumer.vscode-eslint + davidanson.vscode-markdownlint + yzhang.markdown-all-in-one + jnoortheen.nix-ide + ziglang.vscode-zig + bbenoist.nix + ]) + ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [ + { + name = "purpleVoid"; + publisher = "Rej"; + version = "1.0.3"; + sha256 = "oCZ2N8j2U0xGvechD7DlW64KiL0eSDKYwniYft0kVu4="; + } + ]; + }; + }; +} diff --git a/services/coturn/default.nix b/services/coturn/default.nix new file mode 100644 index 0000000..be5ae0a --- /dev/null +++ b/services/coturn/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./firewall.nix + ./options.nix + ./service.nix + ]; +} diff --git a/services/coturn/firewall.nix b/services/coturn/firewall.nix new file mode 100644 index 0000000..e9c410c --- /dev/null +++ b/services/coturn/firewall.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + ... +}: +let + cfg = config.machine.coturn; +in +with lib; mkIf cfg.enable { + networking.firewall = { + interfaces.enp2s0 = + let + range = with config.services.coturn; [ + { + from = min-port; + to = max-port; + } + ]; + in + { + allowedUDPPortRanges = range; + allowedUDPPorts = [ + 3478 + 5349 + ]; + allowedTCPPortRanges = [ ]; + allowedTCPPorts = [ + 3478 + 5349 + ]; + }; + }; +} diff --git a/services/coturn/options.nix b/services/coturn/options.nix new file mode 100644 index 0000000..338cfb1 --- /dev/null +++ b/services/coturn/options.nix @@ -0,0 +1,22 @@ +{ lib, ... }: +with lib; +{ + options.machine.coturn = { + enable = mkEnableOption "Coturn"; + startPort = mkOption { + type = types.port; + default = 49000; + description = "Start port for Coturn."; + }; + endPort = mkOption { + type = types.port; + default = 50000; + description = "End port for Coturn."; + }; + realm = mkOption { + type = types.str; + default = "turn.example.com"; + description = "Realm for Coturn."; + }; + }; +} diff --git a/services/coturn/service.nix b/services/coturn/service.nix new file mode 100644 index 0000000..712bd88 --- /dev/null +++ b/services/coturn/service.nix @@ -0,0 +1,60 @@ +{ + config, + lib, + sec, + ... +}: +let + inherit (config.machine.coturn) + enable + startPort + endPort + realm + ; +in +with lib; mkIf enable { + services.coturn = rec { + inherit realm enable; + no-cli = true; + no-tcp-relay = true; + min-port = startPort; + max-port = endPort; + use-auth-secret = true; + static-auth-secret-file = sec."turn/authSecret".path; + cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; + pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; + extraConfig = '' + # for debugging + verbose + # 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 + ''; + }; + + security.acme.certs.${config.services.coturn.realm} = { + postRun = "systemctl restart coturn.service"; + group = "turnserver"; + }; +} diff --git a/services/default.nix b/services/default.nix new file mode 100644 index 0000000..8760ef3 --- /dev/null +++ b/services/default.nix @@ -0,0 +1,23 @@ +{ + imports = [ + ./bind + ./code-server + ./coturn + ./forgejo + ./mail + ./minecraft-server + ./mysql + ./navidrome + ./networking + ./nextcloud + ./nginx + ./postgresql + ./prosody + ./redis + ./roundcube + ./synapse + ./uptime-kuma + ./vaultwarden + ./xray-3x-ui + ]; +} diff --git a/services/forgejo/default.nix b/services/forgejo/default.nix new file mode 100644 index 0000000..ff54295 --- /dev/null +++ b/services/forgejo/default.nix @@ -0,0 +1,10 @@ +{ + imports = [ + ./mail.nix + ./network.nix + ./options.nix + ./runners.nix + ./service.nix + ./tmpfiles.nix + ]; +} diff --git a/services/forgejo/mail.nix b/services/forgejo/mail.nix new file mode 100644 index 0000000..9e0f5e6 --- /dev/null +++ b/services/forgejo/mail.nix @@ -0,0 +1,37 @@ +{ + config, + pkgs, + lib, + sec, + ... +}: +let + inherit (config.machine.forgejo) domain; + address = "noreply@${domain}"; +in +with lib; mkIf config.machine.mail.enable { + services.forgejo = { + secrets = { + mailer.PASSWD = sec."mail/servicePassword".path; + }; + settings.mailer = { + ENABLED = true; + FROM = address; + USER = address; + SMTP_ADDR = config.machine.mail.fqdn; + SMTP_PORT = 465; + PROTOCOL = "smtps"; + SENDMAIL_PATH = "${pkgs.system-sendmail}/bin/sendmail"; + SEND_AS_PLAIN_TEXT = true; + }; + }; + + mailserver = { + domains = [ domain ]; + accounts.${address} = { + hashedPasswordFile = sec."mail/serviceHashedPassword".path; + aliases = [ ]; + sendOnly = true; + }; + }; +} diff --git a/services/forgejo/network.nix b/services/forgejo/network.nix new file mode 100644 index 0000000..546e966 --- /dev/null +++ b/services/forgejo/network.nix @@ -0,0 +1,28 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.forgejo) + enable + domain + port + ; +in +with lib; mkIf enable { + networking.firewall = { + allowedTCPPorts = [ port ]; + }; + + services.nginx.virtualHosts = with lib; mkIf (domain != null) { + "${domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://[::1]:${toString port}"; + proxyWebsockets = true; + }; + }; + }; +} diff --git a/services/forgejo/options.nix b/services/forgejo/options.nix new file mode 100644 index 0000000..22d9b9d --- /dev/null +++ b/services/forgejo/options.nix @@ -0,0 +1,40 @@ +{ + lib, + config, + ... +}: +let + inherit (lib) + mkEnableOption + mkOption + types + ; +in +{ + options.machine.forgejo = { + enable = mkEnableOption "Forgejo"; + enableRunner = mkEnableOption "Actions runner"; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain name. If not set, will be disabled, and use the localhost."; + }; + port = mkOption { + type = types.port; + default = 3000; + description = "Listen port."; + }; + database = { + host = mkOption { + type = types.str; + default = "127.0.0.1"; + description = "PostgreSQL database host address."; + }; + port = mkOption { + type = types.port; + default = config.services.postgresql.port; + description = "PostgreSQL database host port."; + }; + }; + }; +} diff --git a/services/forgejo/runners.nix b/services/forgejo/runners.nix new file mode 100644 index 0000000..21e8acb --- /dev/null +++ b/services/forgejo/runners.nix @@ -0,0 +1,41 @@ +{ + config, + pkgs, + lib, + sec, + ... +}: +let + url = config.services.forgejo.settings.server.ROOT_URL; + cfg = config.machine.forgejo; +in +with lib; mkIf cfg.enableRunner { + sops.secrets = { + "forgejo/runnerToken" = { + sopsFile = ./../../secrets/common.yaml; + }; + }; + + services.gitea-actions-runner = { + package = pkgs.forgejo-runner; + instances.default = { + name = "forgejo-runner"; + enable = cfg.enableRunner; + tokenFile = sec."forgejo/runnerToken".path; + inherit url; + labels = [ + "ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest" + "ubuntu-26.04:docker://ghcr.io/catthehacker/ubuntu:act-26.04" + "ubuntu-24.04:docker://ghcr.io/catthehacker/ubuntu:act-24.04" + "ubuntu-22.04:docker://ghcr.io/catthehacker/ubuntu:act-22.04" + "nixos:docker://nixos/nix:latest" + "nixos-2.34.4:docker://nixos/nix:2.34.4" + ]; + settings = { + container = { + network = "host"; + }; + }; + }; + }; +} diff --git a/services/forgejo/service.nix b/services/forgejo/service.nix new file mode 100644 index 0000000..efb691f --- /dev/null +++ b/services/forgejo/service.nix @@ -0,0 +1,64 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.forgejo) + enable + database + domain + port + ; +in +{ + environment.systemPackages = lib.optionals enable [ + config.services.forgejo.package + ]; + + services.openssh.settings.AllowUsers = [ + "forgejo" + ]; + + services.forgejo = { + inherit enable; + database = { + type = "postgres"; + inherit (database) host; + inherit (database) port; + }; + lfs.enable = true; + settings = { + DEFAULT = { + APP_NAME = "RuJect Forgejo"; + }; + server = { + DOMAIN = if (domain != null) then domain else "[::1]"; + ROOT_URL = if (domain != null) then "https://${domain}/" else "http://[::1]/"; + HTTP_PORT = port; + }; + service = { + SHOW_REGISTRATION_BUTTON = true; + REGISTER_EMAIL_CONFIRM = true; + ENABLE_NOTIFY_MAIL = true; + }; + "repository.signing" = { + DEFAULT_TRUST_MODEL = "committer"; + }; + actions = { + ENABLED = true; + DEFAULT_ACTIONS_URL = "github"; + }; + picture = { + AVATAR_MAX_FILE_SIZE = 10485760; + AVATAR_MAX_WIDTH = 8192; + AVATAR_MAX_HEIGHT = 8192; + AVATAR_MAX_ORIGIN_SIZE = 5242880; + }; + ui = { + DEFAULT_THEME = "catppuccin-mocha"; + THEMES = "forgejo-auto,forgejo-light,forgejo-dark,catppuccin-mocha"; + }; + }; + }; +} diff --git a/services/forgejo/themes/theme-catppuccin-mocha-lavender.css b/services/forgejo/themes/theme-catppuccin-mocha-lavender.css new file mode 100644 index 0000000..95be21a --- /dev/null +++ b/services/forgejo/themes/theme-catppuccin-mocha-lavender.css @@ -0,0 +1,873 @@ +:root { + color-scheme: dark; + --is-dark-theme: true; + accent-color: #b4befe; + --color-primary: #b4befe; + --color-primary-contrast: #11111b; + --color-primary-hover: rgb(154.8355263158, 168.1907894737, 253.6644736842); + --color-primary-dark-1: rgb(164.9013157895, 176.9144736842, 253.7986842105); + --color-primary-dark-2: rgb(149.8026315789, 163.8289473684, 253.5973684211); + --color-primary-dark-3: rgb(134.7039473684, 150.7434210526, 253.3960526316); + --color-primary-dark-4: rgb(119.6052631579, 137.6578947368, 253.1947368421); + --color-primary-dark-5: rgb(104.5065789474, 124.5723684211, 252.9934210526); + --color-primary-dark-6: rgb(89.4078947368, 111.4868421053, 252.7921052632); + --color-primary-dark-7: rgb(74.3092105263, 98.4013157895, 252.5907894737); + --color-primary-light-1: rgb(195.0986842105, 203.0855263158, 254.2013157895); + --color-primary-light-2: rgb(210.1973684211, 216.1710526316, 254.4026315789); + --color-primary-light-3: rgb(225.2960526316, 229.2565789474, 254.6039473684); + --color-primary-light-4: rgb(240.3947368421, 242.3421052632, 254.8052631579); + --color-primary-light-5: hsl(231.8918918919, 97.3684210526%, 100.0980392157%); + --color-primary-light-6: hsl(231.8918918919, 97.3684210526%, 103.0980392157%); + --color-primary-light-7: hsl(231.8918918919, 97.3684210526%, 106.0980392157%); + --color-primary-alpha-10: rgba(180, 190, 254, 0.1); + --color-primary-alpha-20: rgba(180, 190, 254, 0.2); + --color-primary-alpha-30: rgba(180, 190, 254, 0.3); + --color-primary-alpha-40: rgba(180, 190, 254, 0.4); + --color-primary-alpha-50: rgba(180, 190, 254, 0.5); + --color-primary-alpha-60: rgba(180, 190, 254, 0.6); + --color-primary-alpha-70: rgba(180, 190, 254, 0.7); + --color-primary-alpha-80: rgba(180, 190, 254, 0.8); + --color-primary-alpha-90: rgba(180, 190, 254, 0.9); + --color-secondary: #45475a; + --color-secondary-dark-1: rgb(55.4076923077, 56.5384615385, 76.8923076923); + --color-secondary-dark-2: rgb(61.8153846154, 63.0769230769, 85.7846153846); + --color-secondary-dark-3: rgb(68.2230769231, 69.6153846154, 94.6769230769); + --color-secondary-dark-4: rgb(74.6307692308, 76.1538461538, 103.5692307692); + --color-secondary-dark-5: rgb(81.0384615385, 82.6923076923, 112.4615384615); + --color-secondary-dark-6: rgb(87.4461538462, 89.2307692308, 121.3538461538); + --color-secondary-dark-7: rgb(93.8538461538, 95.7692307692, 130.2461538462); + --color-secondary-dark-8: rgb(100.2615384615, 102.3076923077, 139.1384615385); + --color-secondary-dark-9: rgb(106.6692307692, 108.8461538462, 148.0307692308); + --color-secondary-dark-10: rgb(115.5128205128, 117.5641025641, 154.4871794872); + --color-secondary-dark-11: rgb(124.4051282051, 126.3256410256, 160.8948717949); + --color-secondary-dark-12: rgb(133.2974358974, 135.0871794872, 167.3025641026); + --color-secondary-dark-13: rgb(142.1897435897, 143.8487179487, 173.7102564103); + --color-secondary-light-1: rgb(42.5923076923, 43.4615384615, 59.1076923077); + --color-secondary-light-2: rgb(36.1846153846, 36.9230769231, 50.2153846154); + --color-secondary-light-3: rgb(29.7769230769, 30.3846153846, 41.3230769231); + --color-secondary-light-4: rgb(23.3692307692, 23.8461538462, 32.4307692308); + --color-secondary-alpha-10: rgba(49, 50, 68, 0.1); + --color-secondary-alpha-20: rgba(49, 50, 68, 0.2); + --color-secondary-alpha-30: rgba(49, 50, 68, 0.3); + --color-secondary-alpha-40: rgba(49, 50, 68, 0.4); + --color-secondary-alpha-50: rgba(49, 50, 68, 0.5); + --color-secondary-alpha-60: rgba(49, 50, 68, 0.6); + --color-secondary-alpha-70: rgba(49, 50, 68, 0.7); + --color-secondary-alpha-80: rgba(49, 50, 68, 0.8); + --color-secondary-alpha-90: rgba(49, 50, 68, 0.9); + /* colors */ + --color-red: #f38ba8; + --color-orange: #fab387; + --color-yellow: #f9e2af; + --color-olive: #a6e3a1; + --color-green: #a6e3a1; + --color-teal: #94e2d5; + --color-blue: #89b4fa; + --color-violet: #b4befe; + --color-purple: #cba6f7; + --color-pink: #f5c2e7; + --color-brown: #f2cdcd; + --color-grey: #9399b2; + --color-black: #181825; + /* light variants - produced via Sass scale-color(color, $lightness: -10%) */ + --color-red-light: rgb(238.21875, 92.78125, 133.3359375); + --color-orange-light: rgb(247.96, 147.992, 86.04); + --color-yellow-light: rgb(245.4418604651, 208.8023255814, 127.5581395349); + --color-olive-light: rgb(128.7950819672, 215.2950819672, 121.7049180328); + --color-green-light: rgb(128.7950819672, 215.2950819672, 121.7049180328); + --color-teal-light: rgb(107.875, 215.125, 197.25); + --color-blue-light: rgb(88.0731707317, 148.9024390244, 247.9268292683); + --color-violet-light: rgb(129.6710526316, 146.3815789474, 253.3289473684); + --color-purple-light: rgb(175.6597938144, 119.206185567, 242.793814433); + --color-pink-light: rgb(237.8169014085, 150.1830985915, 213.7605633803); + --color-brown-light: rgb(231.4761904762, 164.5238095238, 164.5238095238); + --color-grey-light: rgb(117.227027027, 124.8810810811, 156.772972973); + --color-black-light: rgb(3.9344262295, 3.9344262295, 6.0655737705); + /* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */ + --color-red-dark-1: rgb(238.21875, 92.78125, 133.3359375); + --color-orange-dark-1: rgb(247.96, 147.992, 86.04); + --color-yellow-dark-1: rgb(245.4418604651, 208.8023255814, 127.5581395349); + --color-olive-dark-1: rgb(128.7950819672, 215.2950819672, 121.7049180328); + --color-green-dark-1: rgb(128.7950819672, 215.2950819672, 121.7049180328); + --color-teal-dark-1: rgb(107.875, 215.125, 197.25); + --color-blue-dark-1: rgb(88.0731707317, 148.9024390244, 247.9268292683); + --color-violet-dark-1: rgb(129.6710526316, 146.3815789474, 253.3289473684); + --color-purple-dark-1: rgb(175.6597938144, 119.206185567, 242.793814433); + --color-pink-dark-1: rgb(237.8169014085, 150.1830985915, 213.7605633803); + --color-brown-dark-1: rgb(231.4761904762, 164.5238095238, 164.5238095238); + --color-black-dark-1: rgb(3.9344262295, 3.9344262295, 6.0655737705); + /* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */ + --color-red-dark-2: rgb(233.4375, 46.5625, 98.671875); + --color-orange-dark-2: rgb(245.92, 116.984, 37.08); + --color-yellow-dark-2: rgb(241.8837209302, 191.6046511628, 80.1162790698); + --color-olive-dark-2: rgb(91.5901639344, 203.5901639344, 82.4098360656); + --color-green-dark-2: rgb(91.5901639344, 203.5901639344, 82.4098360656); + --color-teal-dark-2: rgb(67.75, 204.25, 181.5); + --color-blue-dark-2: rgb(39.1463414634, 117.8048780488, 245.8536585366); + --color-violet-dark-2: rgb(79.3421052632, 102.7631578947, 252.6578947368); + --color-purple-dark-2: rgb(148.3195876289, 72.412371134, 238.587628866); + --color-pink-dark-2: rgb(230.6338028169, 106.3661971831, 196.5211267606); + --color-brown-dark-2: rgb(220.9523809524, 124.0476190476, 124.0476190476); + --color-black-dark-2: hsl(240, 21.3114754098%, -8.0392156863%); + /* other colors */ + --color-gold: #f5e0dc; + --color-white: #cdd6f4; + --color-diff-removed-word-bg: rgba(243, 139, 168, 0.15); + --color-diff-added-word-bg: rgba(166, 227, 161, 0.15); + --color-diff-removed-row-bg: rgba(243, 139, 168, 0.07); + --color-diff-moved-row-bg: rgba(249, 226, 175, 0.07); + --color-diff-added-row-bg: rgba(166, 227, 161, 0.07); + --color-diff-removed-row-border: rgba(243, 139, 168, 0.07); + --color-diff-moved-row-border: rgba(249, 226, 175, 0.07); + --color-diff-added-row-border: rgba(166, 227, 161, 0.07); + --color-diff-inactive: #9399b2; + --color-error-border: #f38ba8; + --color-error-bg: #f38ba8; + --color-error-bg-active: rgb(240.609375, 115.890625, 150.66796875); + --color-error-bg-hover: rgb(238.21875, 92.78125, 133.3359375); + --color-error-text: #11111b; + --color-success-border: rgb(128.7950819672, 215.2950819672, 121.7049180328); + --color-success-bg: #a6e3a1; + --color-success-text: #11111b; + --color-warning-border: rgb(245.4418604651, 208.8023255814, 127.5581395349); + --color-warning-bg: #f9e2af; + --color-warning-text: #11111b; + --color-info-border: rgb(88.0731707317, 148.9024390244, 247.9268292683); + --color-info-bg: #11111b; + --color-info-text: #cdd6f4; + --color-red-badge: rgb(238.21875, 92.78125, 133.3359375); + --color-red-badge-bg: #11111b; + --color-red-badge-hover-bg: rgb(240.609375, 115.890625, 150.66796875); + --color-green-badge: #a6e3a1; + --color-green-badge-bg: #a6e3a1; + --color-green-badge-hover-bg: rgb(147.3975409836, 221.1475409836, 141.3524590164); + --color-yellow-badge: #f9e2af; + --color-yellow-badge-bg: #11111b; + --color-yellow-badge-hover-bg: rgb(247.2209302326, 217.4011627907, 151.2790697674); + --color-orange-badge: #fab387; + --color-orange-badge-bg: #11111b; + --color-orange-badge-hover-bg: rgb(248.98, 163.496, 110.52); + --color-git: #fab387; + --color-highlight-bg: rgba(249, 226, 175, 0.15); + /* target-based colors */ + --color-body: #11111b; + --color-box-header: #181825; + --color-box-body: #181825; + --color-box-body-highlight: #313244; + --color-text-dark: #a6adc8; + --color-text: #cdd6f4; + --color-text-light: #bac2de; + --color-text-light-1: #bac2de; + --color-text-light-2: #bac2de; + --color-text-light-3: #bac2de; + --color-footer: #181825; + --color-timeline: #313244; + --color-input-text: #cdd6f4; + --color-input-background: #313244; + --color-input-toggle-background: #313244; + --color-input-border: #45475a; + --color-input-border-hover: #585b70; + --color-nav-bg: #181825; + --color-nav-hover-bg: var(--color-hover); + --color-navbar: #181825; + --color-navbar-transparent: rgba(17, 17, 27, 0); + --color-light: rgba(88, 91, 112, 0.3); + --color-light-mimic-enabled: rgba( + 0, + 0, + 0, + calc(40 / 255 * 222 / 255 / var(--opacity-disabled)) + ); + --color-light-border: #585b70; + --color-hover: rgba(108, 112, 134, 0.2); + --color-active: rgba(205, 214, 244, 0.1); + --color-menu: #313244; + --color-card: #313244; + --color-markup-table-row: rgba(205, 214, 244, 0.02); + --color-markup-code-block: rgba(205, 214, 244, 0.05); + --color-markup-code-inline: #313244; + --color-button: #313244; + --color-code-bg: #1e1e2e; + --color-code-sidebar-bg: #313244; + --color-shadow: rgba(17, 17, 27, 0.1); + --color-tooltip-bg: #313244; + --color-tooltip-text: var(--color-text); + --color-secondary-bg: #313244; + --color-text-focus: #cdd6f4; + --color-expand-button: #585b70; + --color-placeholder-text: #a6adc8; + --color-editor-line-highlight: var(--color-primary-light-5); + --color-project-board-bg: var(--color-secondary-light-2); + /* gitea source code: */ + /* should ideally be --color-text-dark, see go-gitea/gitea#15651 */ + --color-caret: var(--color-text); + --color-reaction-bg: rgba(205, 214, 244, 0.07); + --color-reaction-active-bg: var(--color-primary-alpha-40); + --color-header-wrapper: #181825; + --color-header-wrapper-transparent: rgba(24, 24, 37, 0); + --color-label-text: #11111b; + --color-label-bg: #b4befe; + --color-label-hover-bg: rgb(149.8026315789, 163.8289473684, 253.5973684211); + --color-label-active-bg: rgb(164.9013157895, 176.9144736842, 253.7986842105); + --color-accent: var(--color-primary-light-1); + --color-small-accent: var(--color-primary-light-5); + --color-active-line: #45475a; +} + +/* invert emojis that are hard to read otherwise */ +.emoji[aria-label="check mark"], +.emoji[aria-label="currency exchange"], +.emoji[aria-label="TOP arrow"], +.emoji[aria-label="END arrow"], +.emoji[aria-label="ON! arrow"], +.emoji[aria-label="SOON arrow"], +.emoji[aria-label="heavy dollar sign"], +.emoji[aria-label=copyright], +.emoji[aria-label=registered], +.emoji[aria-label="trade mark"], +.emoji[aria-label=multiply], +.emoji[aria-label=plus], +.emoji[aria-label=minus], +.emoji[aria-label=divide], +.emoji[aria-label="curly loop"], +.emoji[aria-label="double curly loop"], +.emoji[aria-label="wavy dash"], +.emoji[aria-label="paw prints"], +.emoji[aria-label="musical note"], +.emoji[aria-label="musical notes"] { + filter: invert(100%) hue-rotate(180deg); +} + +.ui.ui.ui.button:not(.inverted, .basic).primary, .ui.ui.ui.button:not(.inverted, .basic).green, .ui.ui.ui.button:not(.inverted, .basic).red, .ui.ui.ui.button:not(.inverted, .basic).teal, +.ui.ui.ui.label:not(.inverted, .basic).primary, +.ui.ui.ui.label:not(.inverted, .basic).green, +.ui.ui.ui.label:not(.inverted, .basic).red, +.ui.ui.ui.label:not(.inverted, .basic).teal { + color: #11111b; +} +.ui.ui.ui.button:not(.inverted, .basic).primary:hover, .ui.ui.ui.button:not(.inverted, .basic).green:hover, .ui.ui.ui.button:not(.inverted, .basic).red:hover, .ui.ui.ui.button:not(.inverted, .basic).teal:hover, +.ui.ui.ui.label:not(.inverted, .basic).primary:hover, +.ui.ui.ui.label:not(.inverted, .basic).green:hover, +.ui.ui.ui.label:not(.inverted, .basic).red:hover, +.ui.ui.ui.label:not(.inverted, .basic).teal:hover { + color: #1e1e2e; +} + +.ui.basic.modal { + background-color: #1e1e2e; +} + +.ui.commit-header-row .svg.gitea-lock ~ a { + color: #11111b; +} + +.ui.negative.message .header { + color: var(--color-error-text); +} + +.ui.sha.isSigned.isVerified .shortsha { + color: #11111b; +} +.ui.sha.isSigned.isVerified svg.gitea-lock { + fill: #11111b; +} + +.ui.basic.modal, +.ui.basic.modal > .header, +.ui.inverted.button { + color: #cdd6f4 !important; +} + +#repo-topics, +#topic_edit > .ui.selection.dropdown { + color: var(--color-label-text) !important; +} + +blockquote.attention-tip { + border-left-color: var(--color-success-bg); +} +blockquote.attention-warning { + border-left-color: var(--color-warning-bg); +} + +svg.attention-tip, +strong.attention-tip { + color: var(--color-success-bg); +} +svg.attention-warning, +strong.attention-warning { + color: var(--color-warning-bg); +} + +.inline-code-block { + color: #11111b; +} + +::selection { + background: rgba(180, 190, 254, 0.3) !important; +} + +/* NameBuiltinPseudo */ +.chroma .bp { + color: #fab387; +} + +/* Comment */ +.chroma .c { + color: #6c7086; +} + +/* CommentSingle */ +.chroma .c1 { + color: #6c7086; +} + +/* CommentHashbang */ +.chroma .ch { + color: #6c7086; +} + +/* CommentMultiline */ +.chroma .cm { + color: #6c7086; +} + +/* CommentPreproc */ +.chroma .cp { + color: #89b4fa; +} + +/* CommentPreprocFile */ +.chroma .cpf { + color: #89b4fa; +} + +/* CommentSpecial */ +.chroma .cs { + color: #6c7086; +} + +/* LiteralStringDelimiter */ +.chroma .dl { + color: #89b4fa; +} + +/* NameFunctionMagic */ +/* Generic */ +/* GenericDeleted */ +.chroma .gd { + color: #cdd6f4; + background-color: rgba(243, 139, 168, 0.15); +} + +/* GenericEmph */ +.chroma .ge { + font-style: italic; +} + +/* GenericHeading */ +.chroma .gh { + color: #89dceb; +} + +/* GenericInserted */ +.chroma .gi { + color: #cdd6f4; + background-color: rgba(166, 227, 161, 0.15); +} + +/* GenericUnderline */ +/* GenericOutput */ +.chroma .go { + color: #fab387; +} + +/* GenericPrompt */ +.chroma .gp { + color: #6c7086; + font-weight: bold; +} + +/* GenericError */ +.chroma .gr { + color: #eba0ac; +} + +/* GenericStrong */ +.chroma .gs { + font-weight: bold; +} + +/* GenericTraceback */ +.chroma .gt { + color: #eba0ac; +} + +/* GenericSubheading */ +.chroma .gu { + color: #89dceb; +} + +/* LiteralNumberIntegerLong */ +.chroma .il { + color: #fab387; +} + +/* Keyword */ +.chroma .k { + color: #cba6f7; +} + +/* KeywordConstant */ +.chroma .kc { + color: #f9e2af; +} + +/* KeywordDeclaration */ +.chroma .kd { + color: #cba6f7; +} + +/* KeywordNamespace */ +.chroma .kn { + color: #f9e2af; +} + +/* KeywordPseudo */ +.chroma .kp { + color: #cba6f7; + font-weight: bold; +} + +/* KeywordReserved */ +.chroma .kr { + color: #cba6f7; +} + +/* KeywordType */ +.chroma .kt { + color: #f9e2af; +} + +/* Literal */ +/* LiteralDate */ +/* LiteralNumber */ +.chroma .m { + color: #fab387; +} + +/* LiteralNumberBin */ +.chroma .mb { + color: #fab387; +} + +/* LiteralNumberFloat */ +.chroma .mf { + color: #fab387; +} + +/* LiteralNumberHex */ +.chroma .mh { + color: #fab387; +} + +/* LiteralNumberInteger */ +.chroma .mi { + color: #fab387; +} + +/* LiteralNumberOct */ +.chroma .mo { + color: #fab387; +} + +/* Name */ +.chroma .n { + color: #b4befe; +} + +/* NameAttribute */ +.chroma .na { + color: #f9e2af; +} + +/* NameBuiltin */ +.chroma .nb { + color: #fab387; +} + +/* NameClass */ +.chroma .nc { + color: #f9e2af; +} + +/* NameDecorator */ +.chroma .nd { + color: #f5c2e7; +} + +/* NameException */ +.chroma .ne { + color: #eba0ac; +} + +/* NameFunction */ +.chroma .nf { + color: #89b4fa; +} + +/* NameEntity */ +.chroma .ni { + color: #f5c2e7; +} + +/* NameLabel */ +.chroma .nl { + color: #f9e2af; +} + +/* NameNamespace */ +.chroma .nn { + color: #f9e2af; +} + +/* NameConstant */ +.chroma .no { + color: #f9e2af; +} + +/* NameTag */ +.chroma .nt { + color: #cba6f7; +} + +/* NameVariable */ +.chroma .nv { + color: #fab387; +} + +/* NameOther */ +.chroma .nx { + color: #fab387; +} + +/* Operator */ +.chroma .o { + color: #89dceb; +} + +/* OperatorWord */ +.chroma .ow { + color: #89dceb; + font-weight: bold; +} + +/* Punctuation */ +.chroma .p { + color: #9399b2; +} + +/* NameProperty */ +/* LiteralString */ +.chroma .s { + color: #a6e3a1; +} + +/* LiteralStringSingle */ +.chroma .s1 { + color: #a6e3a1; +} + +/* LiteralStringDouble */ +.chroma .s2 { + color: #a6e3a1; +} + +/* LiteralStringAffix */ +.chroma .sa { + color: #a6e3a1; +} + +/* LiteralStringBacktick */ +.chroma .sb { + color: #a6e3a1; +} + +/* LiteralStringChar */ +.chroma .sc { + color: #a6e3a1; +} + +/* LiteralStringDoc */ +.chroma .sd { + color: #a6e3a1; +} + +/* LiteralStringEscape */ +.chroma .se { + color: #89b4fa; +} + +/* LiteralStringHeredoc */ +.chroma .sh { + color: #a6e3a1; +} + +/* LiteralStringInterpol */ +.chroma .si { + color: #a6e3a1; +} + +/* LiteralStringRegex */ +.chroma .sr { + color: #89b4fa; +} + +/* LiteralStringSymbol */ +.chroma .ss { + color: #a6e3a1; +} + +/* LiteralStringOther */ +.chroma .sx { + color: #a6e3a1; +} + +/* NameVariableClass */ +.chroma .vc { + color: #f9e2af; +} + +/* NameVariableGlobal */ +.chroma .vg { + color: #fab387; +} + +/* NameVariableInstance */ +.chroma .vi { + color: #f9e2af; +} + +/* NameVariableMagic */ +/* TextWhitespace */ +.chroma .w { + color: #313244; +} + +.CodeMirror .cm-property, +.CodeMirror.cm-s-default .cm-property, +.CodeMirror.cm-s-paper .cm-property { + color: #cdd6f4; +} +.CodeMirror .cm-header, +.CodeMirror.cm-s-default .cm-header, +.CodeMirror.cm-s-paper .cm-header { + color: #cdd6f4; +} +.CodeMirror .cm-quote, +.CodeMirror.cm-s-default .cm-quote, +.CodeMirror.cm-s-paper .cm-quote { + color: #a6e3a1; +} +.CodeMirror .cm-keyword, +.CodeMirror.cm-s-default .cm-keyword, +.CodeMirror.cm-s-paper .cm-keyword { + color: #cba6f7; +} +.CodeMirror .cm-atom, +.CodeMirror.cm-s-default .cm-atom, +.CodeMirror.cm-s-paper .cm-atom { + color: #f38ba8; +} +.CodeMirror .cm-number, +.CodeMirror.cm-s-default .cm-number, +.CodeMirror.cm-s-paper .cm-number { + color: #fab387; +} +.CodeMirror .cm-def, +.CodeMirror.cm-s-default .cm-def, +.CodeMirror.cm-s-paper .cm-def { + color: #cdd6f4; +} +.CodeMirror .cm-variable-2, +.CodeMirror.cm-s-default .cm-variable-2, +.CodeMirror.cm-s-paper .cm-variable-2 { + color: #89dceb; +} +.CodeMirror .cm-variable-3, +.CodeMirror.cm-s-default .cm-variable-3, +.CodeMirror.cm-s-paper .cm-variable-3 { + color: #94e2d5; +} +.CodeMirror .cm-comment, +.CodeMirror.cm-s-default .cm-comment, +.CodeMirror.cm-s-paper .cm-comment { + color: #585b70; +} +.CodeMirror .cm-string, +.CodeMirror.cm-s-default .cm-string, +.CodeMirror.cm-s-paper .cm-string { + color: #a6e3a1; +} +.CodeMirror .cm-string-2, +.CodeMirror.cm-s-default .cm-string-2, +.CodeMirror.cm-s-paper .cm-string-2 { + color: #a6e3a1; +} +.CodeMirror .cm-meta, +.CodeMirror.cm-s-default .cm-meta, +.CodeMirror.cm-s-paper .cm-meta { + color: #fab387; +} +.CodeMirror .cm-qualifier, +.CodeMirror.cm-s-default .cm-qualifier, +.CodeMirror.cm-s-paper .cm-qualifier { + color: #fab387; +} +.CodeMirror .cm-builtin, +.CodeMirror.cm-s-default .cm-builtin, +.CodeMirror.cm-s-paper .cm-builtin { + color: #fab387; +} +.CodeMirror .cm-bracket, +.CodeMirror.cm-s-default .cm-bracket, +.CodeMirror.cm-s-paper .cm-bracket { + color: #cdd6f4; +} +.CodeMirror .cm-tag, +.CodeMirror.cm-s-default .cm-tag, +.CodeMirror.cm-s-paper .cm-tag { + color: #f9e2af; +} +.CodeMirror .cm-attribute, +.CodeMirror.cm-s-default .cm-attribute, +.CodeMirror.cm-s-paper .cm-attribute { + color: #f9e2af; +} +.CodeMirror .cm-hr, +.CodeMirror.cm-s-default .cm-hr, +.CodeMirror.cm-s-paper .cm-hr { + color: #9399b2; +} +.CodeMirror .cm-url, +.CodeMirror.cm-s-default .cm-url, +.CodeMirror.cm-s-paper .cm-url { + color: #89b4fa; +} +.CodeMirror .cm-link, +.CodeMirror.cm-s-default .cm-link, +.CodeMirror.cm-s-paper .cm-link { + color: #89b4fa; +} +.CodeMirror .cm-error, +.CodeMirror.cm-s-default .cm-error, +.CodeMirror.cm-s-paper .cm-error { + color: #f38ba8; +} + +.monaco-editor .selected-text { + background-color: #313244 !important; +} +.monaco-editor .margin-view-overlays .line-numbers { + color: #a6adc8 !important; +} +.monaco-editor .line-numbers.active-line-number { + color: #b4befe !important; +} +.monaco-editor .view-overlays .current-line, +.monaco-editor .margin-view-overlays .current-line-margin { + background-color: rgb(42.16, 42.8, 60.08) !important; +} +.monaco-editor .mtk1 { + color: #cdd6f4 !important; +} +.monaco-editor .mtk2 { + color: #ff69b4 !important; +} +.monaco-editor .mtk3 { + color: #fab387 !important; +} +.monaco-editor .mtk4 { + color: #94e2d5 !important; +} +.monaco-editor .mtk5 { + color: #cdd6f4 !important; +} +.monaco-editor .mtk6 { + color: #cba6f7 !important; +} +.monaco-editor .mtk7 { + color: #fab387 !important; +} +.monaco-editor .mtk8 { + color: #9399b2 !important; +} +.monaco-editor .mtk9 { + color: #cba6f7 !important; +} +.monaco-editor .mtk10 { + color: #a6adc8 !important; +} +.monaco-editor .mtk11 { + color: #94e2d5 !important; +} +.monaco-editor .mtk12 { + color: #94e2d5 !important; +} +.monaco-editor .mtk13 { + color: #ff69b4 !important; +} +.monaco-editor .mtk14 { + color: #ff69b4 !important; +} +.monaco-editor .mtk15 { + color: #cba6f7 !important; +} +.monaco-editor .mtk16 { + color: #9399b2 !important; +} +.monaco-editor .mtk17 { + color: #ff69b4 !important; +} +.monaco-editor .mtk18 { + color: #ff69b4 !important; +} +.monaco-editor .mtk19 { + color: #94e2d5 !important; +} +.monaco-editor .mtk20 { + color: #ff69b4 !important; +} +.monaco-editor .mtk21 { + color: #a6e3a1 !important; +} +.monaco-editor .mtk22 { + color: #ff69b4 !important; +} +.monaco-editor .mtk23 { + color: #89b4fa !important; +} +.monaco-editor .mtk24 { + color: #fab387 !important; +} +.monaco-editor .mtk25 { + color: #f5c2e7 !important; +} +.monaco-editor .bracket-highlighting-0 { + color: rgb(227.8, 169, 198.4) !important; +} +.monaco-editor .bracket-highlighting-1 { + color: rgb(232, 193, 178.6) !important; +} +.monaco-editor .bracket-highlighting-2 { + color: rgb(231.4, 221.2, 202.6) !important; +} +.monaco-editor .bracket-highlighting-3 { + color: rgb(181.6, 221.8, 194.2) !important; +} +.monaco-editor .bracket-highlighting-4 { + color: rgb(164.2, 193.6, 247.6) !important; +} +.monaco-editor .bracket-highlighting-5 { + color: rgb(203.8, 185.2, 245.8) !important; +} \ No newline at end of file diff --git a/services/forgejo/tmpfiles.nix b/services/forgejo/tmpfiles.nix new file mode 100644 index 0000000..dab1371 --- /dev/null +++ b/services/forgejo/tmpfiles.nix @@ -0,0 +1,18 @@ +{ + config, + lib, + ... +}: +let + cfg = config.machine.forgejo; + customDir = config.services.forgejo.customDir; +in +with lib; mkIf cfg.enable { + systemd.tmpfiles.rules = [ + "d '${customDir}/templates' - forgejo forgejo - -" + "d '${customDir}/public' - forgejo forgejo - -" + "d '${customDir}/public/assets' - forgejo forgejo - -" + "d '${customDir}/public/assets/css' - forgejo forgejo - -" + "C+ '${customDir}/public/assets/css/theme-catppuccin-mocha.css' - forgejo forgejo - ${./themes/theme-catppuccin-mocha-lavender.css}" + ]; +} diff --git a/services/mail/default.nix b/services/mail/default.nix new file mode 100644 index 0000000..b09449a --- /dev/null +++ b/services/mail/default.nix @@ -0,0 +1,9 @@ +{ + imports = [ + ./options.nix + ./rspamd.nix + ./secrets.nix + ./service.nix + ./tmpfiles.nix + ]; +} diff --git a/services/mail/options.nix b/services/mail/options.nix new file mode 100644 index 0000000..51ba8ea --- /dev/null +++ b/services/mail/options.nix @@ -0,0 +1,23 @@ +{ lib, ... }: +let + inherit (lib) + mkEnableOption + mkOption + types + ; +in +{ + options.machine.mail = { + enable = mkEnableOption "Mail"; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain name"; + }; + fqdn = mkOption { + type = types.nullOr types.str; + default = null; + description = "fqdn"; + }; + }; +} diff --git a/services/mail/rspamd.nix b/services/mail/rspamd.nix new file mode 100644 index 0000000..210f2d6 --- /dev/null +++ b/services/mail/rspamd.nix @@ -0,0 +1,20 @@ +{ + lib, + config, + ... +}: +let + inherit (config.machine.mail) enable; +in +with lib; mkIf enable { + services.rspamd = { + enable = true; + overrides = { + "local.d/greylist.conf" = { + text = '' + enabled = false; + ''; + }; + }; + }; +} diff --git a/services/mail/secrets.nix b/services/mail/secrets.nix new file mode 100644 index 0000000..743ed69 --- /dev/null +++ b/services/mail/secrets.nix @@ -0,0 +1,25 @@ +{ + sops.secrets = { + dkim_default_private = { + key = "dkim_default_private"; + owner = "root"; + group = "root"; + mode = "0600"; + }; + "rus07tam/hashedPassword" = { + sopsFile = ./../../secrets/rus07tam.yaml; + }; + "mail/serviceHashedPassword" = { + sopsFile = ./../../secrets/common.yaml; + }; + "mail/servicePassword" = { + sopsFile = ./../../secrets/common.yaml; + }; + "mail/NikitaHapanulStaff228HashedPassword" = { + sopsFile = ./../../secrets/common.yaml; + }; + "mail/nikitapocox6prohype" = { + sopsFile = ./../../secrets/common.yaml; + }; + }; +} diff --git a/services/mail/service.nix b/services/mail/service.nix new file mode 100644 index 0000000..2bc49a4 --- /dev/null +++ b/services/mail/service.nix @@ -0,0 +1,66 @@ +{ config, lib, ... }: +let + sec = config.sops.secrets; + inherit (config.machine.mail) + enable + domain + fqdn + ; +in +{ + imports = [ + (builtins.fetchTarball { + url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/master/nixos-mailserver-master.tar.gz"; + sha256 = "0vnczps1ns4d7b3l5m4qwp2fp567pr6b38w40h1x48qfw70x8mf0"; + }) + ]; + + mailserver = { + inherit enable; + inherit fqdn; + stateVersion = 5; + domains = [ domain ]; + messageSizeLimit = 52428800; # 50MB + enableManageSieve = true; + + localDnsResolver = false; + + accounts = { + "admin@${domain}" = { + hashedPasswordFile = sec."mail/serviceHashedPassword".path; + aliases = [ + "postmaster@${domain}" + "system@${domain}" + "contact@${domain}" + "sales@${domain}" + ]; + }; + "rus07tam@${domain}" = { + hashedPasswordFile = sec."rus07tam/hashedPassword".path; + aliases = [ ]; + }; + "nikitahapanulstaff228@${domain}" = { + hashedPasswordFile = sec."mail/NikitaHapanulStaff228HashedPassword".path; + aliases = [ + "mamutraxal@${domain}" + "sava.uwu@${domain}" + ]; + }; + "nikitapocox6prohype@${domain}" = { + hashedPasswordFile = sec."mail/nikitapocox6prohype".path; + aliases = [ + "pomoemuhype@${domain}" + "nikita.uwu@${domain}" + ]; + }; + }; + + x509.useACMEHost = config.mailserver.fqdn; + + dkim = { + enable = true; + keyDirectory = "/var/dkim"; + defaults.selector = "default"; + }; + }; +} diff --git a/services/mail/tmpfiles.nix b/services/mail/tmpfiles.nix new file mode 100644 index 0000000..b376e21 --- /dev/null +++ b/services/mail/tmpfiles.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + sec, + ... +}: +let + inherit (config.machine.mail) enable; +in +with lib; mkIf enable { + systemd.tmpfiles.rules = [ + "C /var/dkim/default.private 0600 root root - - ${sec.dkim_default_private.path}" + ]; +} diff --git a/services/minecraft-server/default.nix b/services/minecraft-server/default.nix new file mode 100644 index 0000000..47d563e --- /dev/null +++ b/services/minecraft-server/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./options.nix + ./firewall.nix + ./service.nix + ]; +} diff --git a/services/minecraft-server/firewall.nix b/services/minecraft-server/firewall.nix new file mode 100644 index 0000000..8bb68f4 --- /dev/null +++ b/services/minecraft-server/firewall.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.minecraft-server) + enable + port + ; +in +with lib; mkIf enable { + networking.firewall.allowedTCPPorts = [ + port + ]; +} diff --git a/services/minecraft-server/options.nix b/services/minecraft-server/options.nix new file mode 100644 index 0000000..8a7a7a4 --- /dev/null +++ b/services/minecraft-server/options.nix @@ -0,0 +1,12 @@ +{ lib, ... }: +with lib; +{ + options.machine.minecraft-server = { + enable = mkEnableOption "Minecraft Server"; + port = mkOption { + type = types.port; + default = 25565; + description = "Listen port."; + }; + }; +} diff --git a/services/minecraft-server/service.nix b/services/minecraft-server/service.nix new file mode 100644 index 0000000..ffce921 --- /dev/null +++ b/services/minecraft-server/service.nix @@ -0,0 +1,46 @@ +{ + config, + lib, + pkgs, + ... +}: +let + inherit (config.machine.minecraft-server) + enable + port + ; +in +with lib; mkIf enable { + services.minecraft-server = { + inherit enable; + dataDir = "/var/lib/minecraft"; + declarative = true; + eula = true; + jvmOpts = "-Xms2046M -Xmx2046M -XX:+UseZGC"; + package = pkgs.papermcServers.papermc-1_21; + serverProperties = { + server-port = port; + query-port = port; + allow-flight = false; + broadcast-console-to-ops = false; + broadcast-rcon-to-ops = false; + difficulty = "hard"; + enable-query = true; + enable-rcon = false; + enable-status = true; + enforce-whitelist = false; + force-gamemode = true; + gamemode = "survival"; + log-ips = false; + max-players = 20; + max-tick-time = -1; + motd = "RuJect's Minecraft Server"; + online-mode = false; + op-permission-level = 4; + simulation-distance = 16; + view-distance = 16; + spawn-protection = 0; + white-list = false; + }; + }; +} diff --git a/services/mysql/default.nix b/services/mysql/default.nix new file mode 100644 index 0000000..be5ae0a --- /dev/null +++ b/services/mysql/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./firewall.nix + ./options.nix + ./service.nix + ]; +} diff --git a/services/mysql/firewall.nix b/services/mysql/firewall.nix new file mode 100644 index 0000000..2ef7ae1 --- /dev/null +++ b/services/mysql/firewall.nix @@ -0,0 +1,13 @@ +{ + config, + lib, + ... +}: +let + cfg = config.machine.mysql; +in +with lib; mkIf cfg.enable { + networking.firewall = { + allowedTCPPorts = [ cfg.port ]; + }; +} diff --git a/services/mysql/options.nix b/services/mysql/options.nix new file mode 100644 index 0000000..5268eb2 --- /dev/null +++ b/services/mysql/options.nix @@ -0,0 +1,12 @@ +{ lib, ... }: +with lib; +{ + options.machine.mysql = { + enable = mkEnableOption "Postgresql"; + port = mkOption { + type = types.port; + default = 3306; + description = "The port on which listens."; + }; + }; +} diff --git a/services/mysql/service.nix b/services/mysql/service.nix new file mode 100644 index 0000000..1a01be1 --- /dev/null +++ b/services/mysql/service.nix @@ -0,0 +1,22 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (config.machine.mysql) + port + enable + ; +in +with lib; mkIf enable { + services.mysql = { + inherit enable; + package = pkgs.mysql84; + ensureDatabases = [ ]; + settings.mysqld = { + inherit port; + }; + }; +} diff --git a/services/navidrome/default.nix b/services/navidrome/default.nix new file mode 100644 index 0000000..e860eca --- /dev/null +++ b/services/navidrome/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} diff --git a/services/navidrome/options.nix b/services/navidrome/options.nix new file mode 100644 index 0000000..d5b54f6 --- /dev/null +++ b/services/navidrome/options.nix @@ -0,0 +1,22 @@ +{ lib, ... }: +with lib; +{ + options.machine.navidrome = { + enable = mkEnableOption "Navidrome"; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain name. If not set, will be disabled, and use the localhost."; + }; + port = mkOption { + type = types.port; + default = 4533; + description = "Listen port."; + }; + folder = mkOption { + type = types.str; + default = "/mnt/music"; + description = "Navidrome music folder."; + }; + }; +} diff --git a/services/navidrome/service.nix b/services/navidrome/service.nix new file mode 100644 index 0000000..be70885 --- /dev/null +++ b/services/navidrome/service.nix @@ -0,0 +1,36 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.navidrome) + enable + domain + port + folder + ; +in +with lib; mkIf enable { + services.nginx.virtualHosts = with lib; mkIf (domain != null) { + "${domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://[::1]:${toString port}"; + proxyWebsockets = true; + }; + }; + }; + + services.navidrome = { + inherit enable; + settings = { + Address = "0.0.0.0"; + Port = port; + MusicFolder = folder; + DefaultTheme = "AMusic"; + EnableSharing = true; + }; + }; +} diff --git a/services/networking/default.nix b/services/networking/default.nix new file mode 100644 index 0000000..9fc890e --- /dev/null +++ b/services/networking/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} \ No newline at end of file diff --git a/services/networking/options.nix b/services/networking/options.nix new file mode 100644 index 0000000..1b8d9e1 --- /dev/null +++ b/services/networking/options.nix @@ -0,0 +1,17 @@ +{ lib, ... }: +with lib; +{ + options.machine = { + gateway = mkOption { + type = types.nullOr types.str; + default = null; + description = "Default network gateway"; + }; + + ipv4 = mkOption { + type = types.nullOr types.str; + default = null; + description = "Main IPv4 address"; + }; + }; +} diff --git a/services/networking/service.nix b/services/networking/service.nix new file mode 100644 index 0000000..cec7c64 --- /dev/null +++ b/services/networking/service.nix @@ -0,0 +1,32 @@ +{ config, lib, hostname, ... }: +let + inherit (config.machine) ipv4 gateway; +in +with lib; { + networking = { + hostName = hostname; + networkmanager.enable = mkDefault true; + firewall = { + enable = true; + allowPing = true; + }; + nameservers = [ + "1.1.1.1" + "1.0.0.1" + "9.9.9.9" + "8.8.8.8" + ]; + interfaces.ens3 = mkIf (ipv4 != null) { + ipv4.addresses = [ + { + address = ipv4; + prefixLength = 32; + } + ]; + }; + defaultGateway = mkIf (gateway != null) { + address = gateway; + interface = "ens3"; + }; + }; +} diff --git a/services/nextcloud/database.nix b/services/nextcloud/database.nix new file mode 100644 index 0000000..86d9b71 --- /dev/null +++ b/services/nextcloud/database.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + ... +}: +let + pgsqlEnable = config.machine.postgresql.enable; + cfg = config.machine.nextcloud; +in +with lib; mkIf cfg.enable { + services.nextcloud.config = + if pgsqlEnable then + { + dbtype = "pgsql"; + dbhost = "localhost:${toString config.machine.postgresql.port}"; + } + else + { + dbtype = "sqlite"; + dbhost = "localhost"; + }; + + services.postgresql = with lib; mkIf pgsqlEnable { + ensureDatabases = [ "nextcloud" ]; + ensureUsers = [ + { + name = "nextcloud"; + ensureDBOwnership = true; + } + ]; + }; +} diff --git a/services/nextcloud/default.nix b/services/nextcloud/default.nix new file mode 100644 index 0000000..69df504 --- /dev/null +++ b/services/nextcloud/default.nix @@ -0,0 +1,8 @@ +{ + imports = [ + ./database.nix + ./mail.nix + ./options.nix + ./service.nix + ]; +} diff --git a/services/nextcloud/mail.nix b/services/nextcloud/mail.nix new file mode 100644 index 0000000..2c741f3 --- /dev/null +++ b/services/nextcloud/mail.nix @@ -0,0 +1,40 @@ +{ + config, + lib, + sec, + ... +}: +let + inherit (config.machine.nextcloud) + enable + host + ; + address = "noreply@${host}"; +in +with lib; mkIf enable { + services.nextcloud = { + settings = { + mail_smtpmode = "smtp"; + mail_sendmailmode = "smtp"; + mail_smtpsecure = "ssl"; + mail_domain = host; + mail_from_address = "noreply"; + mail_smtpname = address; + mail_smtphost = config.machine.mail.fqdn; + mail_smtpport = 465; + mail_smtpauth = true; + }; + secrets = { + mail_smtppassword = sec."mail/servicePassword".path; + }; + }; + + mailserver = { + domains = [ host ]; + accounts.${address} = { + hashedPasswordFile = sec."mail/serviceHashedPassword".path; + aliases = [ ]; + sendOnly = true; + }; + }; +} diff --git a/services/nextcloud/options.nix b/services/nextcloud/options.nix new file mode 100644 index 0000000..c7769fb --- /dev/null +++ b/services/nextcloud/options.nix @@ -0,0 +1,12 @@ +{ lib, ... }: +with lib; +{ + options.machine.nextcloud = { + enable = mkEnableOption "Nextcloud"; + host = mkOption { + type = types.str; + default = "localhost"; + description = "FQDN for the nextcloud instance."; + }; + }; +} diff --git a/services/nextcloud/service.nix b/services/nextcloud/service.nix new file mode 100644 index 0000000..47106a1 --- /dev/null +++ b/services/nextcloud/service.nix @@ -0,0 +1,44 @@ +{ + pkgs, + config, + lib, + sec, + ... +}: +let + cfg = config.machine.nextcloud; +in +with lib; mkIf cfg.enable { + services.nextcloud = { + inherit enable; + appstoreEnable = false; + autoUpdateApps.enable = false; + config.adminpassFile = sec."nextcloud/adminPassword".path; + hostName = cfg.host; + package = pkgs.nextcloud33; + https = if cfg.host == "localhost" then false else true; + settings = { + default_phone_region = "RU"; + log_type = "file"; + loglevel = 1; + }; + extraAppsEnable = true; + extraApps = with pkgs.nextcloud33Packages.apps; { + inherit + mail + contacts + collectives + impersonate + ; + }; + }; + + services.nginx.virtualHosts.${config.services.nextcloud.hostName} = { + forceSSL = true; + enableACME = true; + }; + + sops.secrets = { + "nextcloud/adminPassword" = { }; + }; +} diff --git a/services/nginx/acme.nix b/services/nginx/acme.nix new file mode 100644 index 0000000..7d1d58b --- /dev/null +++ b/services/nginx/acme.nix @@ -0,0 +1,10 @@ +{ lib, config, ... }: +with lib; mkIf (config.nginx.enable) { + security.acme = { + acceptTerms = true; + defaults = { + email = "admin@ruject.fun"; + webroot = "/var/lib/acme/acme-challenge/"; + }; + }; +} diff --git a/services/nginx/default.nix b/services/nginx/default.nix new file mode 100644 index 0000000..87c0eb9 --- /dev/null +++ b/services/nginx/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./acme.nix + ./firewall.nix + ./service.nix + ]; +} diff --git a/services/nginx/firewall.nix b/services/nginx/firewall.nix new file mode 100644 index 0000000..a8969c8 --- /dev/null +++ b/services/nginx/firewall.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + ... +}: +let + inherit (config.services.nginx) enable; +in +with lib; mkIf enable { + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; +} diff --git a/services/nginx/service.nix b/services/nginx/service.nix new file mode 100644 index 0000000..a29231c --- /dev/null +++ b/services/nginx/service.nix @@ -0,0 +1,12 @@ +{ + users.groups.acme.members = [ + "nginx" + ]; + + services.nginx = { + recommendedProxySettings = true; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + }; +} diff --git a/services/postgresql/default.nix b/services/postgresql/default.nix new file mode 100644 index 0000000..e860eca --- /dev/null +++ b/services/postgresql/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} diff --git a/services/postgresql/options.nix b/services/postgresql/options.nix new file mode 100644 index 0000000..d7473a0 --- /dev/null +++ b/services/postgresql/options.nix @@ -0,0 +1,14 @@ +{ lib, ... }: +with lib; +{ + options.machine.postgresql = { + enable = mkEnableOption "Postgresql"; + port = mkOption { + type = types.port; + default = 5432; + description = '' + The port on which PostgreSQL listens. + ''; + }; + }; +} diff --git a/services/postgresql/service.nix b/services/postgresql/service.nix new file mode 100644 index 0000000..72704ce --- /dev/null +++ b/services/postgresql/service.nix @@ -0,0 +1,29 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (config.machine.postgresql) + port + enable + ; +in +with lib; mkIf enable { + services.postgresql = { + inherit enable; + settings = { + inherit port; + }; + ensureDatabases = [ ]; + enableTCPIP = true; + authentication = mkOverride 10 '' + #type database DBuser origin-address auth-method + local all all trust + host all all 127.0.0.1/32 trust + host all all ::1/128 trust + host all all 0.0.0.0/0 md5 + ''; + }; +} diff --git a/services/prometheus/default.nix b/services/prometheus/default.nix new file mode 100644 index 0000000..e860eca --- /dev/null +++ b/services/prometheus/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} diff --git a/services/prometheus/options.nix b/services/prometheus/options.nix new file mode 100644 index 0000000..cdbab66 --- /dev/null +++ b/services/prometheus/options.nix @@ -0,0 +1,15 @@ +{ + options.machine.prometheus = { + enable = mkEnableOption "Prometheus"; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain name. If not set, will be disabled, and use the localhost."; + }; + port = mkOption { + type = types.port; + default = cfg.port; + description = "Listen port."; + }; + }; +} diff --git a/services/prometheus/service.nix b/services/prometheus/service.nix new file mode 100644 index 0000000..7810105 --- /dev/null +++ b/services/prometheus/service.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.prometheus) + enable + port + ; +in +with lib; mkIf enable { + services.prometheus = { + inherit enable port; + }; +} diff --git a/services/prosody/default.nix b/services/prosody/default.nix new file mode 100644 index 0000000..9a28810 --- /dev/null +++ b/services/prosody/default.nix @@ -0,0 +1,8 @@ +{ + imports = [ + ./firewall.nix + ./nginx.nix + ./options.nix + ./service.nix + ]; +} diff --git a/services/prosody/firewall.nix b/services/prosody/firewall.nix new file mode 100644 index 0000000..ebd8cf2 --- /dev/null +++ b/services/prosody/firewall.nix @@ -0,0 +1,38 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.prosody) + enable + ; +in +with lib; mkIf enable { + networking.firewall = { + allowedTCPPorts = [ + # HTTP filer + 80 + 443 + + # C2S + 5222 + 5223 + + # S2S + 5269 + 5270 + + # WebSockets / BOSH + 5280 + 5281 + ] + ++ concatLists ( + with config.services.prosody; + [ + httpPorts + httpsPorts + ] + ); + }; +} diff --git a/services/prosody/nginx.nix b/services/prosody/nginx.nix new file mode 100644 index 0000000..8445478 --- /dev/null +++ b/services/prosody/nginx.nix @@ -0,0 +1,54 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.prosody) + enable + domain + ; + + localhost = "http://localhost:5280"; +in +with lib; mkIf enable { + security.acme.certs."${domain}".extraDomainNames = [ + "conference.${domain}" + "upload.${domain}" + ]; + users.groups.acme.members = [ + "prosody" + ]; + services.nginx.virtualHosts = with lib; mkIf (domain != null) { + "${domain}".locations = { + "= /xmpp-websocket" = { + proxyPass = localhost; + proxyWebsockets = true; + }; + "= /http-bind".proxyPass = localhost; + "/push".proxyPass = localhost; + "= /.well-known/host-meta".proxyPass = localhost; + "= /.well-known/host-meta.json".proxyPass = localhost; + }; + "conference.${domain}" = { + http3 = true; + quic = true; + forceSSL = true; + kTLS = true; + useACMEHost = domain; + sslCertificate = "${config.security.acme.certs.${domain}.directory}/fullchain.pem"; + sslCertificateKey = "${config.security.acme.certs.${domain}.directory}/key.pem"; + locations."/".proxyPass = localhost; + }; + "upload.${domain}" = { + http3 = true; + quic = true; + forceSSL = true; + kTLS = true; + useACMEHost = domain; + sslCertificate = "${config.security.acme.certs.${domain}.directory}/fullchain.pem"; + sslCertificateKey = "${config.security.acme.certs.${domain}.directory}/key.pem"; + locations."/".proxyPass = localhost; + }; + }; +} diff --git a/services/prosody/options.nix b/services/prosody/options.nix new file mode 100644 index 0000000..6ef42e3 --- /dev/null +++ b/services/prosody/options.nix @@ -0,0 +1,17 @@ +{ lib, ... }: +with lib; +{ + options.machine.prosody = { + enable = mkEnableOption "Prosody"; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain name. If not set, will be disabled, and use the localhost."; + }; + port = mkOption { + type = types.port; + default = 4000; + description = "Listen port."; + }; + }; +} diff --git a/services/prosody/service.nix b/services/prosody/service.nix new file mode 100644 index 0000000..f9b30c2 --- /dev/null +++ b/services/prosody/service.nix @@ -0,0 +1,104 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (config.machine.prosody) + enable + domain + ; + + sslCertDir = config.security.acme.certs."${domain}".directory; +in +with lib; mkIf enable { + services.prosody = { + inherit enable; + + package = pkgs.prosody.override { + withCommunityModules = [ + "sasl2" + "sasl2_bind2" + "sasl_ssdp" + "sasl2_fast" + "sasl_ssdp" + "csi_battery_saver" + "muc_notifications" + ]; + }; + + admins = [ + "admin@${domain}" + ]; + allowRegistration = true; + s2sSecureAuth = true; + c2sRequireEncryption = true; + modules = { + http_files = true; + limits = true; + server_contact_info = true; + bosh = true; + motd = true; + announce = true; + welcome = true; + admin_adhoc = true; + websocket = true; + watchregistrations = true; + }; + extraModules = [ + "turn_external" + ]; + xmppComplianceSuite = true; + checkConfig = false; + ssl = { + cert = "${sslCertDir}/fullchain.pem"; + key = "${sslCertDir}/key.pem"; + }; + virtualHosts.${domain} = { + inherit domain; + enabled = enable; + ssl = { + cert = "${sslCertDir}/fullchain.pem"; + key = "${sslCertDir}/key.pem"; + }; + }; + muc = [ + { + domain = "conference.${domain}"; + restrictRoomCreation = "local"; + } + ]; + httpFileShare = { + domain = "upload.${domain}"; + http_host = domain; + expires_after = "never"; + size_limit = 32 * 1024 * 1024; + }; + extraConfig = '' + storage = "sql" + sql = { + driver = "SQLite3"; + database = "prosody.sqlite"; + } + + -- Keep messages + archive_expires_after = "never" + muc_log_presences = true + muc_log_expires_after = "never" + + -- Recommended by Monal dev + smacks_max_queue_size = 4000 + + c2s_direct_tls_ports = { 5223 }; + s2s_direct_tls_ports = { 5270 }; + + trusted_proxies = { "127.0.0.1", "::1" }; + http_external_url = "https://${domain}/" + consider_bosh_secure = true; + consider_websocket_secure = true; + statistics = "internal"; + statistics_interval = "manual"; + ''; + }; +} diff --git a/services/redis/default.nix b/services/redis/default.nix new file mode 100644 index 0000000..e860eca --- /dev/null +++ b/services/redis/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} diff --git a/services/redis/options.nix b/services/redis/options.nix new file mode 100644 index 0000000..1fd6ea1 --- /dev/null +++ b/services/redis/options.nix @@ -0,0 +1,12 @@ +{ lib, ... }: +with lib; +{ + options.machine.redis = { + enable = mkEnableOption "Redis"; + port = mkOption { + type = types.port; + default = 6379; + description = "Port to listen on."; + }; + }; +} diff --git a/services/redis/service.nix b/services/redis/service.nix new file mode 100644 index 0000000..5dc40f7 --- /dev/null +++ b/services/redis/service.nix @@ -0,0 +1,28 @@ +{ + config, + lib, + sec, + ... +}: +let + inherit (config.machine.redis) + port + enable + ; +in +with lib; mkIf enable { + sops.secrets = { + "redis/password" = { }; + }; + + networking.firewall = { + allowedTCPPorts = [ port ]; + }; + + services.redis.servers."default" = { + inherit enable; + inherit port; + bind = null; + requirePassFile = sec."redis/password".path; + }; +} diff --git a/services/roundcube/default.nix b/services/roundcube/default.nix new file mode 100644 index 0000000..e860eca --- /dev/null +++ b/services/roundcube/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} diff --git a/services/roundcube/options.nix b/services/roundcube/options.nix new file mode 100644 index 0000000..52e6fa2 --- /dev/null +++ b/services/roundcube/options.nix @@ -0,0 +1,12 @@ +{ lib, ... }: +with lib; +{ + options.machine.roundcube = { + enable = mkEnableOption "Roundcube"; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain name. If not set, will be disabled, and use the localhost."; + }; + }; +} diff --git a/services/roundcube/service.nix b/services/roundcube/service.nix new file mode 100644 index 0000000..a302fcc --- /dev/null +++ b/services/roundcube/service.nix @@ -0,0 +1,45 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (config.machine.roundcube) + enable + domain + ; +in +with lib; mkIf enable { + services.roundcube = { + inherit enable; + dicts = with pkgs.aspellDicts; [ + ru + en + fr + ]; + hostName = domain; + configureNginx = true; + extraConfig = '' + // IMAP + $config['imap_host'] = 'ssl://${config.mailserver.fqdn}'; + $config['imap_conn_options'] = array( + 'ssl' => array( + 'verify_peer' => false, + 'verify_peer_name' => false, + ), + ); + + // SMTP + $config['smtp_host'] = 'ssl://${config.mailserver.fqdn}:465'; + $config['smtp_conn_options'] = array( + 'ssl' => array( + 'verify_peer' => false, + 'verify_peer_name' => false, + ), + ); + $config['smtp_user'] = '%u'; + $config['smtp_pass'] = '%p'; + ''; + }; +} diff --git a/services/synapse/database.nix b/services/synapse/database.nix new file mode 100644 index 0000000..f353491 --- /dev/null +++ b/services/synapse/database.nix @@ -0,0 +1,26 @@ +{ + config, + lib, + ... +}: +let + pgsqlEnable = config.machine.postgresql.enable; + inherit (config.machine.synapse) enable; +in +with lib; mkIf enable { + services.postgresql = with lib; mkIf pgsqlEnable { + ensureUsers = [ + { + name = "matrix-synapse"; + ensureDBOwnership = true; + } + ]; + ensureDatabases = [ "matrix-synapse" ]; + }; + services.matrix-synapse.settings.database = { + name = if pgsqlEnable then "psycopg2" else "sqlite3"; + args = with lib; mkIf pgsqlEnable { + host = "/run/postgresql"; + }; + }; +} diff --git a/services/synapse/default.nix b/services/synapse/default.nix new file mode 100644 index 0000000..34f756c --- /dev/null +++ b/services/synapse/default.nix @@ -0,0 +1,13 @@ +{ + imports = [ + ./database.nix + ./element.nix + ./mail.nix + ./nginx.nix + ./options.nix + ./redis.nix + ./secrets.nix + ./synapse.nix + ./turn.nix + ]; +} diff --git a/services/synapse/element.nix b/services/synapse/element.nix new file mode 100644 index 0000000..f0999fa --- /dev/null +++ b/services/synapse/element.nix @@ -0,0 +1,64 @@ +{ + lib, + config, + pkgs, + ... +}: +let + inherit (config.machine.synapse.element) domain enable; + elementConfig = { + default_server_config = { + "m.homeserver" = with config.services.matrix-synapse.settings; { + base_url = public_baseurl; + inherit server_name; + }; + "m.identity_server" = { + base_url = ""; + }; + }; + disable_custom_urls = false; + disable_guests = true; + disable_login_language_selector = false; + disable_3pid_login = false; + brand = "Element"; + default_country_code = "US"; + show_labs_settings = true; + features = { + feature_video_rooms = true; + feature_group_calls = true; + feature_element_call_video_rooms = true; + feature_new_device_manager = true; + feature_wysiwyg_composer = true; + }; + default_federate = true; + room_directory = with config.services.matrix-synapse.settings; { + servers = [ + server_name + "matrix.org" + ]; + }; + setting_defaults = { + breadcrumbs = true; + "MessageComposerInput.autoReplaceEmoji" = true; + sendTypingNotifications = true; + showTypingNotifications = true; + showReadReceipts = true; + showJoinLeaves = false; + urlPreviewsEnabled = true; + }; + sso_redirect_options = { + immediate = false; + on_welcome_page = true; + }; + }; +in +with lib; mkIf enable { + services.nginx.virtualHosts.${domain} = { + enableACME = true; + forceSSL = true; + + root = pkgs.element-web.override (_old: { + conf = elementConfig; + }); + }; +} diff --git a/services/synapse/mail.nix b/services/synapse/mail.nix new file mode 100644 index 0000000..8c7111b --- /dev/null +++ b/services/synapse/mail.nix @@ -0,0 +1,39 @@ +{ + config, + lib, + sec, + ... +}: +let + inherit (config.machine.synapse) + enable + domain + ; + address = "noreply@${domain}"; +in +with lib; mkIf (enable && config.machine.mail.enable) { + services.matrix-synapse = { + settings = { + admin_contact = address; + registrations_require_3pid = [ "email" ]; + email = { + smtp_host = config.machine.mail.fqdn; + smtp_port = 465; + smtp_user = address; + require_transport_security = true; + enable_tls = true; + notif_from = "RuJect Matrix <${address}>"; + app_name = "RuJect Matrix"; + }; + }; + }; + + mailserver = { + domains = [ domain ]; + accounts.${address} = { + hashedPasswordFile = sec."mail/serviceHashedPassword".path; + aliases = [ ]; + sendOnly = true; + }; + }; +} diff --git a/services/synapse/nginx.nix b/services/synapse/nginx.nix new file mode 100644 index 0000000..ffc30a7 --- /dev/null +++ b/services/synapse/nginx.nix @@ -0,0 +1,98 @@ +{ config, ... }: +let + inherit (config.machine.synapse) domain port; + maxUploadSize = config.services.matrix-synapse.settings.max_upload_size; +in +{ + systemd.services.nginx.serviceConfig.SupplementaryGroups = [ "matrix-synapse" ]; + + services.nginx = { + appendHttpConfig = '' + limit_req_zone $binary_remote_addr zone=matrix_login:10m rate=1r/s; + limit_req_zone $binary_remote_addr zone=matrix_register:10m rate=1r/m; + limit_req_zone $binary_remote_addr zone=matrix_api:10m rate=20r/s; + limit_req_zone $binary_remote_addr zone=matrix_media:10m rate=10r/s; + limit_req_zone $binary_remote_addr zone=matrix_federation:10m rate=50r/s; + limit_conn_zone $binary_remote_addr zone=conn_limit:10m; + ''; + upstreams."matrix-synapse".servers = { + "unix:/run/matrix-synapse/matrix-synapse.sock" = { }; + }; + virtualHosts.${domain} = { + forceSSL = true; + enableACME = true; + + locations = { + # Synapse client API + "/_matrix/client" = { + proxyPass = "http://127.0.0.1:${toString port}"; + extraConfig = '' + limit_req zone=matrix_api burst=50 nodelay; + client_max_body_size ${maxUploadSize}; + ''; + }; + + # Login endpoint with stricter rate limiting + "~ ^/_matrix/client/(r0|v3)/login$" = { + proxyPass = "http://127.0.0.1:${toString port}"; + extraConfig = '' + limit_req zone=matrix_login burst=3 nodelay; + ''; + }; + + # Registration with very strict rate limiting + "~ ^/_matrix/client/(r0|v3)/register" = { + proxyPass = "http://127.0.0.1:${toString port}"; + extraConfig = '' + limit_req zone=matrix_register burst=2 nodelay; + ''; + }; + + # Sync endpoint with longer timeout + "~ ^/_matrix/client/(r0|v3|unstable)/sync" = { + proxyPass = "http://127.0.0.1:${toString port}"; + extraConfig = '' + limit_req zone=matrix_api burst=50 nodelay; + proxy_read_timeout 600s; + ''; + }; + + # Media + "/_matrix/media" = { + proxyPass = "http://127.0.0.1:${toString port}"; + extraConfig = '' + limit_req zone=matrix_media burst=100 nodelay; + client_max_body_size ${maxUploadSize}; + ''; + }; + + # Federation + "/_matrix/federation" = { + proxyPass = "http://127.0.0.1:${toString port}"; + extraConfig = '' + limit_req zone=matrix_federation burst=100 nodelay; + client_max_body_size 50M; + ''; + }; + + "/_matrix/key" = { + proxyPass = "http://127.0.0.1:${toString port}"; + extraConfig = '' + limit_req zone=matrix_federation burst=50 nodelay; + ''; + }; + + # Health check + "= /health" = { + proxyPass = "http://127.0.0.1:${toString port}"; + extraConfig = '' + access_log off; + ''; + }; + + # Block admin API from public + "/_synapse/admin".return = "404"; + }; + }; + }; +} diff --git a/services/synapse/options.nix b/services/synapse/options.nix new file mode 100644 index 0000000..b77a831 --- /dev/null +++ b/services/synapse/options.nix @@ -0,0 +1,37 @@ +{ + lib, + config, + ... +}: +with lib; +{ + options.machine.synapse = { + enable = mkEnableOption "Synapse"; + element = { + enable = mkEnableOption "Elemenet web"; + domain = mkOption { + type = types.nullOr types.str; + default = "chat.${config.machine.synapse.domain}"; + description = "Domain name."; + }; + }; + domain = mkOption { + type = types.str; + default = "example.com"; + description = "Domain name."; + }; + port = mkOption { + type = types.port; + default = 8008; + description = "Listen port."; + }; + metrics = { + enable = mkEnableOption "Synapse metrics"; + port = mkOption { + type = types.port; + default = 9000; + description = "Listen port."; + }; + }; + }; +} diff --git a/services/synapse/redis.nix b/services/synapse/redis.nix new file mode 100644 index 0000000..4845b76 --- /dev/null +++ b/services/synapse/redis.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + ... +}: +let + redisEnable = config.machine.redis.enable; + inherit (config.machine.synapse) enable; +in +with lib; mkIf (redisEnable && enable) { + services.redis.servers.matrix-synapse = { + enable = true; + }; + systemd.services.matrix-synapse.serviceConfig.SupplementaryGroups = [ "redis-matrix-synapse" ]; + services.matrix-synapse.settings.redis = { + enabled = true; + path = config.services.redis.servers.matrix-synapse.unixSocket; + }; +} diff --git a/services/synapse/secrets.nix b/services/synapse/secrets.nix new file mode 100644 index 0000000..73eb31a --- /dev/null +++ b/services/synapse/secrets.nix @@ -0,0 +1,46 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.synapse) + enable + ; +in +with lib; mkIf enable { + sops.secrets = { + "matrix/registrationSharedSecret" = { + sopsFile = ./../../secrets/common.yaml; + owner = config.users.users.matrix-synapse.name; + inherit (config.users.users.matrix-synapse) group; + restartUnits = [ "matrix-synapse.service" ]; + }; + "matrix/signingKey" = { + sopsFile = ./../../secrets/common.yaml; + owner = config.users.users.matrix-synapse.name; + inherit (config.users.users.matrix-synapse) group; + restartUnits = [ "matrix-synapse.service" ]; + }; + "turn/authSecret" = { + sopsFile = ./../../secrets/common.yaml; + owner = config.users.users.turnserver.name; + inherit (config.users.users.turnserver) group; + restartUnits = [ "coturn.service" ]; + }; + }; + sops.templates.matrix-synapse-config = { + owner = config.users.users.matrix-synapse.name; + inherit (config.users.users.matrix-synapse) group; + restartUnits = [ "matrix-synapse.service" ]; + content = '' + registration_shared_secret: ${config.sops.placeholder."matrix/registrationSharedSecret"} + turn_shared_secret: ${config.sops.placeholder."turn/authSecret"} + mail: + smtp_pass: ${config.sops.placeholder."mail/servicePassword"} + ''; + }; + services.matrix-synapse.extraConfigFiles = with lib; mkIf config.machine.synapse.enable [ + config.sops.templates.matrix-synapse-config.path + ]; +} diff --git a/services/synapse/synapse.nix b/services/synapse/synapse.nix new file mode 100644 index 0000000..022ac61 --- /dev/null +++ b/services/synapse/synapse.nix @@ -0,0 +1,94 @@ +{ + config, + lib, + sec, + ... +}: +let + inherit (config.machine.synapse) + domain + enable + port + metrics + ; +in +with lib; mkIf enable { + services.matrix-synapse = { + inherit enable; + enableRegistrationScript = true; + settings = { + server_name = domain; + public_baseurl = "https://${domain}"; + signing_key_path = sec."matrix/signingKey".path; + listeners = [ + { + inherit port; + bind_addresses = [ "127.0.0.1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + compress = true; + names = [ + "client" + "federation" + ]; + } + ]; + } + ] + ++ (optionals metrics.enable [ + { + inherit (metrics) port; + bind_addresses = [ "127.0.0.1" ]; + type = "metrics"; + tls = false; + resources = [ + { + names = [ "metrics" ]; + } + ]; + } + ]); + + enable_metrics = metrics.enable; + + enable_registration = true; + enable_registration_without_verification = false; + + allow_public_rooms_over_federation = true; + federation_domain_whitelist = [ ]; + + allow_public_rooms_without_auth = true; + + url_preview_enabled = true; + url_preview_ip_range_blacklist = [ + "127.0.0.0/8" + "10.0.0.0/8" + "172.16.0.0/12" + "192.168.0.0/16" + "100.64.0.0/10" + "169.254.0.0/16" + "::1/128" + "fe80::/10" + "fc00::/7" + ]; + + dynamic_thumbnails = true; + max_upload_size = "50M"; + media_retention = { + local_media_lifetime = "90d"; + remote_media_lifetime = "14d"; + }; + + retention = { + enabled = true; + default_policy.max_lifetime = "180d"; + purge_jobs = [ + { interval = "1d"; } + ]; + }; + }; + }; +} diff --git a/services/synapse/turn.nix b/services/synapse/turn.nix new file mode 100644 index 0000000..556c996 --- /dev/null +++ b/services/synapse/turn.nix @@ -0,0 +1,18 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.coturn) enable; +in +with lib; mkIf (enable && config.machine.coturn.enable) { + services.matrix-synapse.settings = with config.services.coturn; { + turn_uris = [ + "turn:${realm}:3478?transport=udp" + "turn:${realm}:3478?transport=tcp" + ]; + turn_user_lifetime = "1h"; + turn_allow_guests = false; + }; +} diff --git a/services/uptime-kuma/default.nix b/services/uptime-kuma/default.nix new file mode 100644 index 0000000..e860eca --- /dev/null +++ b/services/uptime-kuma/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} diff --git a/services/uptime-kuma/options.nix b/services/uptime-kuma/options.nix new file mode 100644 index 0000000..ab04b1a --- /dev/null +++ b/services/uptime-kuma/options.nix @@ -0,0 +1,17 @@ +{ lib, ... }: +with lib; +{ + options.machine.uptime-kuma = { + enable = mkEnableOption "Uptime Kuma"; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain name. If not set, will be disabled, and use the localhost."; + }; + port = mkOption { + type = types.port; + default = 4000; + description = "Listen port."; + }; + }; +} diff --git a/services/uptime-kuma/service.nix b/services/uptime-kuma/service.nix new file mode 100644 index 0000000..3be7bde --- /dev/null +++ b/services/uptime-kuma/service.nix @@ -0,0 +1,35 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.uptime-kuma) + domain + enable + port + ; +in +with lib; mkIf enable { + services.uptime-kuma = { + inherit enable; + settings = { + PORT = toString port; + }; + }; + + services.nginx.virtualHosts = with lib; mkIf (domain != null) { + "${domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString port}"; + proxyWebsockets = true; + }; + }; + }; + + networking.firewall = { + allowedTCPPorts = [ port ]; + }; +} diff --git a/services/vaultwarden/default.nix b/services/vaultwarden/default.nix new file mode 100644 index 0000000..e860eca --- /dev/null +++ b/services/vaultwarden/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./options.nix + ./service.nix + ]; +} diff --git a/services/vaultwarden/options.nix b/services/vaultwarden/options.nix new file mode 100644 index 0000000..34fac8c --- /dev/null +++ b/services/vaultwarden/options.nix @@ -0,0 +1,17 @@ +{ lib, ... }: +with lib; +{ + options.machine.vaultwarden = { + enable = mkEnableOption "Vaultwarden"; + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "Domain name. If not set, will be disabled, and use the localhost."; + }; + port = mkOption { + type = types.port; + default = 4534; + description = "Listen port."; + }; + }; +} diff --git a/services/vaultwarden/service.nix b/services/vaultwarden/service.nix new file mode 100644 index 0000000..e35d78e --- /dev/null +++ b/services/vaultwarden/service.nix @@ -0,0 +1,55 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.vaultwarden) + enable + domain + port + ; +in +with lib; mkIf enable { + networking.firewall = { + allowedTCPPorts = [ port ]; + }; + + services.nginx.virtualHosts = with lib; mkIf (domain != null) { + "${domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString port}"; + proxyWebsockets = true; + extraConfig = '' + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + ''; + }; + + extraConfig = '' + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header Referrer-Policy same-origin; + add_header X-XSS-Protection "1; mode=block"; + ''; + }; + }; + + services.vaultwarden = { + inherit enable; + backupDir = "/var/local/vaultwarden/backup"; + environmentFile = "/var/lib/vaultwarden/vaultwarden.env"; + config = { + DOMAIN = "https://${domain}"; + SIGNUPS_ALLOWED = true; + + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = port; + ROCKET_LOG = "critical"; + }; + }; +} diff --git a/services/xray-3x-ui/default.nix b/services/xray-3x-ui/default.nix new file mode 100644 index 0000000..b94857e --- /dev/null +++ b/services/xray-3x-ui/default.nix @@ -0,0 +1,8 @@ +{ + imports = [ + ./options.nix + ./firewall.nix + ./nginx.nix + ./service.nix + ]; +} diff --git a/services/xray-3x-ui/firewall.nix b/services/xray-3x-ui/firewall.nix new file mode 100644 index 0000000..aef0dcc --- /dev/null +++ b/services/xray-3x-ui/firewall.nix @@ -0,0 +1,24 @@ +{ + config, + lib, + ... +}: +let + inherit (config.machine.xray-3x-ui) + enable + port + ; +in +with lib; mkIf enable { + networking.firewall.allowedTCPPorts = [ + # Web panel + port + + # SSL & HTTP + 80 + 443 + + # Inbounds + 1082 + ]; +} diff --git a/services/xray-3x-ui/nginx.nix b/services/xray-3x-ui/nginx.nix new file mode 100644 index 0000000..19c0c86 --- /dev/null +++ b/services/xray-3x-ui/nginx.nix @@ -0,0 +1,44 @@ +{ + lib, + config, + ... +}: let + inherit + (config.machine.xray-3x-ui) + enable + port + domain + subscriptions + ; +in { + services.nginx.virtualHosts = with lib; mkIf enable { + ${domain} = with lib; mkIf (domain != null) { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString port}"; + proxyWebsockets = true; + extraConfig = '' + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + ''; + }; + }; + ${subscriptions.domain} = with lib; mkIf (subscriptions.domain != null) { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:2096"; + proxyWebsockets = true; + extraConfig = '' + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + ''; + }; + }; + }; +} diff --git a/services/xray-3x-ui/options.nix b/services/xray-3x-ui/options.nix new file mode 100644 index 0000000..e6aab90 --- /dev/null +++ b/services/xray-3x-ui/options.nix @@ -0,0 +1,33 @@ +{ lib, config, ... }: +with lib; +{ + options.machine.xray-3x-ui = { + enable = mkEnableOption "3x-ui Xray panel"; + + port = mkOption { + type = types.port; + default = 2053; + description = "Port for the web interface."; + }; + + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "domain for the web interface."; + }; + + subscriptions = { + domain = mkOption { + type = types.nullOr types.str; + default = null; + description = "domain for the web interface."; + }; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/3x-ui"; + description = "Directory to store 3x-ui data."; + }; + }; +} \ No newline at end of file diff --git a/services/xray-3x-ui/service.nix b/services/xray-3x-ui/service.nix new file mode 100644 index 0000000..175915a --- /dev/null +++ b/services/xray-3x-ui/service.nix @@ -0,0 +1,96 @@ +# See https://github.com/sunmeplz/xray-3x-ui + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.machine.xray-3x-ui; + + # Minimum Go version required for building + minGoVersion = "1.26.0"; + + xray-3x-ui = + assert assertMsg + (versionAtLeast pkgs.go.version minGoVersion) + "3x-ui requires Go >= ${minGoVersion}, but ${pkgs.go.version} is available"; + + pkgs.buildGoModule rec { + pname = "3x-ui"; + version = "2.8.11"; + + src = pkgs.fetchFromGitHub { + owner = "MHSanaei"; + repo = "3x-ui"; + rev = "v${version}"; + hash = "sha256-2I6t3caf2t7nKSFwxI/dVIobpBzuptrgauuXfFw8ltg="; + }; + + vendorHash = "sha256-M8YQTMfF/xZut4hxUcAfF2xGK625vwJNp4JS/zoXUCQ="; + + ldflags = [ "-s" "-w" ]; + + meta = with lib; { + description = "Xray panel supporting multi-protocol multi-user"; + homepage = "https://github.com/MHSanaei/3x-ui"; + license = licenses.gpl3Only; + platforms = platforms.linux; + maintainers = [ ]; + }; + }; + +in { + # Service implementation + config = mkIf cfg.enable { + # User and group configuration + users.users.xray-3x-ui = { + isSystemUser = true; + group = "xray-3x-ui"; + description = "3x-ui service user"; + }; + + users.groups.xray-3x-ui = { }; + + # Directory structure + systemd.tmpfiles.rules = [ + "d ${cfg.dataDir} 0755 xray-3x-ui xray-3x-ui -" + "d ${cfg.dataDir}/bin 0755 xray-3x-ui xray-3x-ui -" + "d ${cfg.dataDir}/logs 0755 xray-3x-ui xray-3x-ui -" + ]; + + # Systemd service + systemd.services.xray-3x-ui = { + description = "3x-ui Xray Panel"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = { + XUI_DB_FOLDER = cfg.dataDir; + XUI_BIN_FOLDER = "${cfg.dataDir}/bin"; + XUI_LOG_FOLDER = "${cfg.dataDir}/logs"; + }; + + preStart = '' + # Symlink xray-core binary to expected location + ln -sf ${pkgs.xray}/bin/xray ${cfg.dataDir}/bin/xray-linux-amd64 + ''; + + serviceConfig = { + Type = "simple"; + ExecStart = "${xray-3x-ui}/bin/3x-ui"; + WorkingDirectory = cfg.dataDir; + Restart = "on-failure"; + RestartSec = "10s"; + User = "xray-3x-ui"; + Group = "xray-3x-ui"; + StateDirectory = "3x-ui 3x-ui/bin 3x-ui/logs"; + StateDirectoryMode = "0755"; + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" "CAP_NET_ADMIN" ]; + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" "CAP_NET_ADMIN" ]; + }; + }; + + # Add to system packages for CLI access + environment.systemPackages = [ xray-3x-ui ]; + }; +} diff --git a/users/macan/home.nix b/users/macan/home.nix new file mode 100644 index 0000000..ae4a51a --- /dev/null +++ b/users/macan/home.nix @@ -0,0 +1,10 @@ +{ + imports = [ + ./variables + ./modules/fish + ./modules/nvf + ./modules/stylix + ]; + + targets.genericLinux.enable = true; +} diff --git a/users/macan/hosts/velarion.nix b/users/macan/hosts/velarion.nix new file mode 100644 index 0000000..d741104 --- /dev/null +++ b/users/macan/hosts/velarion.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + python314 + sqlite + ]; +} diff --git a/users/macan/modules/fish/default.nix b/users/macan/modules/fish/default.nix new file mode 100644 index 0000000..34a03f5 --- /dev/null +++ b/users/macan/modules/fish/default.nix @@ -0,0 +1,7 @@ +{ config, ... }: +{ + programs.fish = { + enable = true; + inherit (config) shellAliases; + }; +} diff --git a/users/macan/modules/nvf/assistant.nix b/users/macan/modules/nvf/assistant.nix new file mode 100644 index 0000000..54c2dad --- /dev/null +++ b/users/macan/modules/nvf/assistant.nix @@ -0,0 +1,12 @@ +{ + programs.nvf.settings.vim.assistant.neocodeium = { + enable = true; + setupOpts = { + enabled = true; + log_level = "debug"; + }; + keymaps = { + accept = ""; + }; + }; +} diff --git a/users/macan/modules/nvf/default.nix b/users/macan/modules/nvf/default.nix new file mode 100644 index 0000000..3f8f511 --- /dev/null +++ b/users/macan/modules/nvf/default.nix @@ -0,0 +1,31 @@ +{ + inputs, + pkgs, + ... +}: +{ + imports = [ + inputs.nvf.homeManagerModules.default + ./assistant.nix + ./options.nix + ./languages.nix + ./picker.nix + ./snacks.nix + ./keymaps.nix + ./utils.nix + ./mini.nix + ]; + + home.packages = with pkgs; [ + neovim + ]; + + programs.nvf = { + enable = true; + settings.vim = { + startPlugins = [ + pkgs.vimPlugins.vim-kitty-navigator + ]; + }; + }; +} diff --git a/users/macan/modules/nvf/keymaps.nix b/users/macan/modules/nvf/keymaps.nix new file mode 100644 index 0000000..32b6462 --- /dev/null +++ b/users/macan/modules/nvf/keymaps.nix @@ -0,0 +1,269 @@ +{ + programs.nvf.settings.vim = { + globals.mapleader = " "; + binds = { + whichKey = { + enable = true; + register = { }; + }; + }; + keymaps = [ + # "hjkl" -> "jkl;" + { + mode = "n"; # Normal mode + key = "j"; + action = ""; + desc = "Move Left"; + } + { + mode = "n"; + key = "k"; + action = ""; + desc = "Move Down"; + } + { + mode = "n"; + key = "l"; + action = ""; + desc = "Move Up"; + } + { + mode = "n"; + key = ";"; + action = ""; + desc = "Move Right"; + } + { + mode = "v"; # Visual mode + key = "j"; + action = ""; + desc = "Move Left"; + } + { + mode = "v"; + key = "k"; + action = ""; + desc = "Move Down"; + } + { + mode = "v"; + key = "l"; + action = ""; + desc = "Move Up"; + } + { + mode = "v"; + key = ";"; + action = ""; + desc = "Move Right"; + } + + # General Mappings + { + key = "s"; + mode = "n"; + silent = true; + action = "lua require('flash').jump()"; + desc = "Flash"; + } + { + key = "K"; + mode = "n"; + silent = true; + action = "lua vim.lsp.buf.hover()"; + desc = "LSP Hover"; + } + { + key = ""; + mode = "n"; + silent = true; + action = "bnext"; + desc = "Next Buffer"; + } + { + key = "rn"; + mode = "n"; + silent = true; + action = "lua vim.lsp.buf.rename()"; + desc = "Rename symbol"; + } + + # Escape from Insert Mode + { + key = "jj"; + mode = "i"; + action = ""; + desc = "Exit insert mode"; + } # UI + { + key = "uw"; + mode = "n"; + silent = true; + action = "set wrap!"; + desc = "Toggle word wrapping"; + } + { + key = "ul"; + mode = "n"; + silent = true; + action = "set linebreak!"; + desc = "Toggle linebreak"; + } + { + key = "us"; + mode = "n"; + silent = true; + action = "set spell!"; + desc = "Toggle spellLazyGitcheck"; + } + { + key = "uc"; + mode = "n"; + silent = true; + action = "set cursorline!"; + desc = "Toggle cursorline"; + } + { + key = "un"; + mode = "n"; + silent = true; + action = "set number!"; + desc = "Toggle line numbers"; + } + { + key = "ur"; + mode = "n"; + silent = true; + action = "set relativenumber!"; + desc = "Toggle relative line numbers"; + } + { + key = "ut"; + mode = "n"; + silent = true; + action = "set showtabline=2"; + desc = "Show tabline"; + } + { + key = "uT"; + mode = "n"; + silent = true; + action = "set showtabline=0"; + desc = "Hide tabline"; + } + + # Windows + { + key = "ws"; + mode = "n"; + silent = true; + action = "split"; + desc = "Split"; + } + { + key = "wv"; + mode = "n"; + silent = true; + action = "vsplit"; + desc = "VSplit"; + } + { + key = "wd"; + mode = "n"; + silent = true; + action = "close"; + desc = "Close"; + } + + # Disable Arrow Keys in Normal Mode + { + key = ""; + mode = "n"; + silent = true; + action = ""; + desc = "Disable Up Arrow"; + } + { + key = ""; + mode = "n"; + silent = true; + action = ""; + desc = "Disable Down Arrow"; + } + { + key = ""; + mode = "n"; + silent = true; + action = ""; + desc = "Disable Left Arrow"; + } + { + key = ""; + mode = "n"; + silent = true; + action = ""; + desc = "Disable Right Arrow"; + } + + # Disable Arrow Keys in Visual Mode + { + key = ""; + mode = "v"; + silent = true; + action = ""; + desc = "Disable Up Arrow"; + } + { + key = ""; + mode = "v"; + silent = true; + action = ""; + desc = "Disable Down Arrow"; + } + { + key = ""; + mode = "v"; + silent = true; + action = ""; + desc = "Disable Left Arrow"; + } + { + key = ""; + mode = "v"; + silent = true; + action = ""; + desc = "Disable Right Arrow"; + } + + # Disable Arrow Keys in Insert Mode + { + key = ""; + mode = "i"; + silent = true; + action = ""; + desc = "Disable Up Arrow"; + } + { + key = ""; + mode = "i"; + silent = true; + action = ""; + desc = "Disable Down Arrow"; + } + { + key = ""; + mode = "i"; + silent = true; + action = ""; + desc = "Disable Left Arrow"; + } + { + key = ""; + mode = "i"; + silent = true; + action = ""; + desc = "Disable Right Arrow"; + } + ]; + }; +} diff --git a/users/macan/modules/nvf/languages.nix b/users/macan/modules/nvf/languages.nix new file mode 100644 index 0000000..9d04fe2 --- /dev/null +++ b/users/macan/modules/nvf/languages.nix @@ -0,0 +1,122 @@ +{ lib, ... }: +{ + programs.nvf.settings.vim = { + diagnostics = { + enable = true; + config = { + signs = { + text = { + "vim.diagnostic.severity.Error" = " "; + "vim.diagnostic.severity.Warn" = " "; + "vim.diagnostic.severity.Hint" = " "; + "vim.diagnostic.severity.Info" = " "; + }; + }; + underline = true; + update_in_insert = true; + virtual_text = { + format = + lib.generators.mkLuaInline + # lua + '' + function(diagnostic) + return string.format("%s", diagnostic.message) + --return string.format("%s (%s)", diagnostic.message, diagnostic.source) + end + ''; + }; + }; + nvim-lint = { + enable = true; + }; + }; + syntaxHighlighting = true; + treesitter = { + enable = true; + autotagHtml = true; + context.enable = true; + highlight.enable = true; + }; + lsp = { + enable = true; + trouble.enable = true; + lspSignature.enable = true; + lspconfig.enable = true; + formatOnSave = true; + inlayHints.enable = true; + null-ls.enable = true; + otter-nvim = { + enable = true; + setupOpts = { + buffers.set_filetype = true; + lsp = { + diagnostic_update_event = [ + "BufWritePost" + "InsertLeave" + ]; + }; + }; + }; + lspkind.enable = true; + lspsaga = { + enable = true; + setupOpts = { + ui = { + code_action = ""; + }; + lightbulb = { + sign = false; + virtual_text = true; + }; + breadcrumbs.enable = false; + }; + }; + }; + languages = { + enableDAP = true; + enableExtraDiagnostics = true; + enableFormat = true; + enableTreesitter = true; + + bash.enable = true; + clang.enable = true; + css.enable = true; + elixir.enable = true; + go.enable = true; + html.enable = true; + json.enable = true; + lua.enable = true; + markdown = { + enable = true; + extensions = { + render-markdown-nvim = { + enable = true; + }; + }; + extraDiagnostics.enable = true; + }; + nim.enable = true; + nix.enable = true; + python = { + enable = true; + format.type = [ + "black" + "isort" + ]; + }; + rust.enable = true; + tailwind.enable = true; + ts = { + enable = true; + extensions.ts-error-translator.enable = true; + }; + yaml.enable = true; + zig.enable = true; + }; + formatter = { + conform-nvim = { + enable = true; + }; + }; + }; +} diff --git a/users/macan/modules/nvf/mini.nix b/users/macan/modules/nvf/mini.nix new file mode 100644 index 0000000..2c0568b --- /dev/null +++ b/users/macan/modules/nvf/mini.nix @@ -0,0 +1,13 @@ +{ + programs.nvf.settings.vim.mini = { + starter.enable = true; + comment.enable = true; + # cursorword.enable = true; + icons.enable = true; + indentscope.enable = true; + notify.enable = true; + pairs.enable = true; + diff.enable = true; + git.enable = true; + }; +} diff --git a/users/macan/modules/nvf/options.nix b/users/macan/modules/nvf/options.nix new file mode 100644 index 0000000..76b17a6 --- /dev/null +++ b/users/macan/modules/nvf/options.nix @@ -0,0 +1,41 @@ +{ lib, ... }: +{ + programs.nvf.settings.vim = { + viAlias = false; + vimAlias = true; + withNodeJs = true; + # syntaxHighlighting = true; + options = { + autoindent = true; + smartindent = true; + shiftwidth = 2; + foldlevel = 99; + foldcolumn = "auto:1"; + mousescroll = "ver:1,hor:1"; + mousemoveevent = true; + fillchars = "eob:‿,fold: ,foldopen:▼,foldsep:⸽,foldclose:⏵"; + signcolumn = "yes"; + tabstop = 2; + softtabstop = 2; + wrap = false; + }; + globals = { + navic_silence = true; # navic tries to attach multiple LSPs and fails + suda_smart_edit = 1; # use super user write automatically + neovide_scale_factor = 0.7; + neovide_cursor_animation_length = 0.1; + neovide_cursor_short_animation_length = 0; + }; + clipboard = { + enable = true; + registers = "unnamedplus"; + providers.wl-copy.enable = true; + }; + theme = { + enable = true; + name = lib.mkForce "catppuccin"; + style = lib.mkForce "mocha"; + transparent = lib.mkForce true; + }; + }; +} diff --git a/users/macan/modules/nvf/picker.nix b/users/macan/modules/nvf/picker.nix new file mode 100644 index 0000000..5b1a629 --- /dev/null +++ b/users/macan/modules/nvf/picker.nix @@ -0,0 +1,256 @@ +{ + programs.nvf.settings.vim = { + utility = { + oil-nvim.enable = true; + snacks-nvim = { + setupOpts = { + picker.enabled = true; + explorer.enabled = true; + }; + }; + }; + keymaps = [ + # Top Pickers & Explorer + { + key = " "; + mode = "n"; + silent = true; + action = "lua Snacks.picker.smart()"; + desc = "Smart Find Files"; + } + { + key = ","; + mode = "n"; + silent = true; + action = "lua Snacks.picker.buffers()"; + desc = "Buffers"; + } + { + key = "/"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.grep()"; + desc = "Grep"; + } + { + key = ":"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.command_history()"; + desc = "Command History"; + } + { + key = "e"; + mode = "n"; + silent = true; + action = "lua Snacks.explorer()"; + desc = "File Explorer"; + } + { + key = "-"; + mode = "n"; + silent = true; + action = "Oil"; + desc = "Oil"; + } + + # Find + { + key = "fb"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.buffers()"; + desc = "Buffers"; + } + { + key = "fc"; + mode = "n"; + silent = true; + action = ''lua Snacks.picker.files({ cwd = vim.fn.stdpath("config") })''; + desc = "Find Config File"; + } + { + key = "ff"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.files()"; + desc = "Find Files"; + } + { + key = "fg"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_files()"; + desc = "Find Git Files"; + } + { + key = "fp"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.projects()"; + desc = "Projects"; + } + { + key = "fr"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.recent()"; + desc = "Recent"; + } + { + key = "fn"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.notifications()"; + desc = "Notification History"; + } + { + key = "fe"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.icons()"; + desc = "Emoji"; + } + + # Git + { + key = "gb"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_branches()"; + desc = "Git Branches"; + } + { + key = "gL"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_log()"; + desc = "Git Log Line"; + } + { + key = "gs"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_status()"; + desc = "Git Status"; + } + { + key = "gS"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_stash()"; + desc = "Git Stash"; + } + { + key = "gd"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_diff()"; + desc = "Git Diff (Hunks)"; + } + { + key = "gf"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_log_file()"; + desc = "Git Log File"; + } + + # Grep + { + key = "sb"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lines()"; + desc = "Buffer Lines"; + } + { + key = "st"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.todo_comments()"; + desc = "Todos"; + } + { + key = "sB"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.grep_buffers()"; + desc = "Grep Open Buffers"; + } + { + key = "sg"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.grep()"; + desc = "Grep"; + } + { + key = "sw"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.grep_word()"; + desc = "Visual selection or word"; + } + { + key = "sr"; + mode = "n"; + silent = true; + action = "nohlsearch"; + desc = "Reset search"; + } + + # LSP + { + key = "gd"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_definitions()"; + desc = "Goto Definition"; + } + { + key = "gD"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_declarations()"; + desc = "Goto Declaration"; + } + { + key = "gr"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_references()"; + desc = "References"; + nowait = true; + } + { + key = "gI"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_implementations()"; + desc = "Goto Implementation"; + } + { + key = "gy"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_type_definitions()"; + desc = "Goto Type Definition"; + } + { + key = "ss"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_symbols()"; + desc = "LSP Symbols"; + } + { + key = "sS"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_workspace_symbols()"; + desc = "LSP Workspace Symbols"; + } + ]; + }; +} diff --git a/users/macan/modules/nvf/snacks.nix b/users/macan/modules/nvf/snacks.nix new file mode 100644 index 0000000..f0faf03 --- /dev/null +++ b/users/macan/modules/nvf/snacks.nix @@ -0,0 +1,16 @@ +{ + programs.nvf.settings.vim.utility.snacks-nvim = { + enable = true; + setupOpts = { + image = { + enabled = true; + setupOpts.doc.inline = false; + }; + quickfile.enabled = true; + statuscolumn.enabled = true; + zen.enabled = true; + bufdelete.enabled = true; + gitsigns.enabled = true; + }; + }; +} diff --git a/users/macan/modules/nvf/utils.nix b/users/macan/modules/nvf/utils.nix new file mode 100644 index 0000000..c7b44bf --- /dev/null +++ b/users/macan/modules/nvf/utils.nix @@ -0,0 +1,50 @@ +{ pkgs, ... }: +{ + programs.nvf.settings.vim = { + undoFile.enable = true; + utility = { + motion.flash-nvim.enable = true; + outline.aerial-nvim.enable = true; + }; + tabline.nvimBufferline.enable = true; + notes.todo-comments.enable = true; + statusline.lualine.enable = true; + + autocomplete = { + nvim-cmp = { + enable = true; + sources = { + buffer = "[Buffer]"; + nvim-cmp = null; + path = "[Path]"; + }; + sourcePlugins = [ + pkgs.vimPlugins.cmp-cmdline + ]; + }; + }; + + snippets.luasnip.enable = true; + ui = { + noice.enable = true; + colorizer.enable = true; + }; + git = { + enable = true; + gitsigns.enable = true; + }; + terminal.toggleterm = { + enable = true; + lazygit = { + enable = true; + mappings.open = "gl"; + }; + }; + visuals = { + rainbow-delimiters.enable = true; + nvim-scrollbar = { + enable = false; + }; + }; + }; +} diff --git a/users/macan/modules/stylix/default.nix b/users/macan/modules/stylix/default.nix new file mode 100644 index 0000000..95a7509 --- /dev/null +++ b/users/macan/modules/stylix/default.nix @@ -0,0 +1,45 @@ +{ + pkgs, + config, + inputs, + ... +}: +{ + imports = [ + inputs.stylix.homeModules.stylix + ]; + + stylix = { + enable = true; + + base16Scheme = config.theme.colors; + + cursor = { + name = "phinger-cursors-light"; + package = pkgs.phinger-cursors; + size = 20; + }; + + fonts = { + monospace = { + package = pkgs.nerd-fonts.jetbrains-mono; + name = "JetBrains Mono Nerd Font"; + }; + sansSerif = { + package = pkgs.source-sans-pro; + name = "Source Sans Pro"; + }; + serif = { + package = pkgs.source-sans-pro; + name = "Source Sans Pro"; + }; + emoji = { + package = pkgs.noto-fonts-color-emoji; + name = "Noto Color Emoji"; + }; + inherit (config.theme.fonts) sizes; + }; + + polarity = "dark"; + }; +} diff --git a/users/macan/system.nix b/users/macan/system.nix new file mode 100644 index 0000000..54e8053 --- /dev/null +++ b/users/macan/system.nix @@ -0,0 +1,19 @@ +{ pkgs, ... }: +{ + services.openssh.settings.AllowUsers = [ "macan" ]; + + programs.fish.enable = true; + + users.users.macan = { + isNormalUser = true; + description = "macan"; + uid = 1002; + extraGroups = [ ]; + openssh.authorizedKeys = { + keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID+VwmEaHwGHqoSlyWgOZDEc0eSMIcr0vNAHNeqWUone macan" + ]; + }; + shell = pkgs.fish; + }; +} diff --git a/users/macan/variables/default.nix b/users/macan/variables/default.nix new file mode 100644 index 0000000..ef01586 --- /dev/null +++ b/users/macan/variables/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./theme.nix + ./shell_aliases.nix + ]; +} diff --git a/users/macan/variables/shell_aliases.nix b/users/macan/variables/shell_aliases.nix new file mode 100644 index 0000000..bbe4e30 --- /dev/null +++ b/users/macan/variables/shell_aliases.nix @@ -0,0 +1,33 @@ +{ lib, ... }: +{ + options.shellAliases = lib.mkOption { + type = lib.types.attrs; + default = { + e = "exit"; + ls = "eza --icons=always --no-quotes"; + tree = "eza --icons=always --tree --no-quotes"; + cat = "bat --theme=base16 --color=always --paging=never --tabs=2 --wrap=never --plain"; + mkdir = "mkdir -p"; + poweroff = "sudo poweroff"; + shutdown = "sudo poweroff"; + reboot = "sudo reboot"; + + nix-shell = "nix-shell --command fish"; + + # git + ga = "git add"; + gc = "git commit"; + gp = "git push"; + gpl = "git pull"; + gs = "git status"; + gd = "git diff"; + gco = "git checkout"; + gcb = "git checkout -b"; + gbr = "git branch"; + grs = "git reset HEAD~1"; + grh = "git reset --hard HEAD~1"; + gaa = "git add ."; + gcm = "git commit -m"; + }; + }; +} diff --git a/users/macan/variables/theme.nix b/users/macan/variables/theme.nix new file mode 100644 index 0000000..569efdb --- /dev/null +++ b/users/macan/variables/theme.nix @@ -0,0 +1,51 @@ +{ lib, ... }: +{ + options.theme = lib.mkOption { + type = lib.types.attrs; + default = { + rounding = 20; + gaps-in = 7; + gaps-out = 7 * 2; + active-opacity = 0.95; + inactive-opacity = 0.92; + blur = true; + border-size = 2; + animation-speed = "fast"; # "fast" | "medium" | "slow" + + bar = { + position = "top"; # "top" | "bottom" + transparent = true; + transparentButtons = false; + floating = true; + }; + + colors = { + base00 = "000000"; # 000000 ---- + base01 = "231a40"; # 231a40 --- + base02 = "432d59"; # 432d59 -- + base03 = "593380"; # 593380 - + base04 = "00ff00"; # 7b43bf + + base05 = "b08ae6"; # b08ae6 ++ + base06 = "9045e6"; # 9045e6 +++ + base07 = "a366ff"; # a366ff ++++ + base08 = "a82ee6"; # a82ee6 red + base09 = "bb66cc"; # bb66cc orange + base0A = "f29df2"; # f29df2 yellow + base0B = "4595e6"; # 41d9bF green + base0C = "40dfff"; # 40dfff aqua/cyan + base0D = "4136d9"; # 326ee6 blue + base0E = "7e5ce6"; # 7e5ce6 purple + base0F = "a886bf"; # a886bf brown + }; + + fonts = { + sizes = { + applications = 12; + desktop = 12; + popups = 12; + terminal = 10; + }; + }; + }; + }; +} diff --git a/users/rus07tam/assets/wallpaper.png b/users/rus07tam/assets/wallpaper.png new file mode 100644 index 0000000..d97590e Binary files /dev/null and b/users/rus07tam/assets/wallpaper.png differ diff --git a/users/rus07tam/home.nix b/users/rus07tam/home.nix new file mode 100644 index 0000000..86d2b0a --- /dev/null +++ b/users/rus07tam/home.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: +{ + imports = [ + ./variables + ./secrets/home.nix + ./modules/fish + ./modules/git + ./modules/nvf + ./modules/rclone + ./modules/stylix + ./modules/zellij + ]; + + targets.genericLinux.enable = true; + + home.packages = with pkgs; [ + any-nix-shell + bitwarden-cli + ]; +} diff --git a/users/rus07tam/hosts/elaris.nix b/users/rus07tam/hosts/elaris.nix new file mode 100644 index 0000000..a761352 --- /dev/null +++ b/users/rus07tam/hosts/elaris.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: +{ + imports = [ + ./../modules/alacritty + ./../modules/clipboard + ./../modules/firefox + ./../modules/hyprland + ./../modules/obsidian + ./../modules/wofi + ./../modules/zed + ./../modules/apps.nix + ./../modules/games.nix + ]; + + xdg.enable = true; + + home.packages = with pkgs; [ + dragon-drop + ]; +} diff --git a/users/rus07tam/hosts/velarion.nix b/users/rus07tam/hosts/velarion.nix new file mode 100644 index 0000000..f7e9be4 --- /dev/null +++ b/users/rus07tam/hosts/velarion.nix @@ -0,0 +1,4 @@ +{ + imports = [ + ]; +} diff --git a/users/rus07tam/modules/alacritty/default.nix b/users/rus07tam/modules/alacritty/default.nix new file mode 100644 index 0000000..9000bf3 --- /dev/null +++ b/users/rus07tam/modules/alacritty/default.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: +{ + programs.alacritty = { + enable = true; + settings = { + terminal.shell = "${pkgs.fish}/bin/fish"; + window = { + padding = { + x = 5; + y = 5; + }; + }; + }; + }; +} diff --git a/users/rus07tam/modules/apps.nix b/users/rus07tam/modules/apps.nix new file mode 100644 index 0000000..dccb7de --- /dev/null +++ b/users/rus07tam/modules/apps.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + vscode-fhs + libreoffice-qt + hunspell + hunspellDicts.ru_RU + telegram-desktop + krita + ]; +} diff --git a/users/rus07tam/modules/clipboard/default.nix b/users/rus07tam/modules/clipboard/default.nix new file mode 100644 index 0000000..f135d6f --- /dev/null +++ b/users/rus07tam/modules/clipboard/default.nix @@ -0,0 +1,22 @@ +{ pkgs, ... }: +let + clipboard = pkgs.writeShellScriptBin "clipboard" '' + #!/usr/bin/env bash + + if [ -t 0 ]; then + ${pkgs.wl-clipboard}/bin/wl-paste + else + cat - | ${pkgs.wl-clipboard}/bin/wl-copy -n + fi + ''; + + clipboard-clear = pkgs.writeShellScriptBin "clipboard-clear" '' + ${pkgs.wl-clipboard}/bin/wl-copy --all + ''; +in +{ + home.packages = [ + clipboard + clipboard-clear + ]; +} diff --git a/users/rus07tam/modules/firefox/default.nix b/users/rus07tam/modules/firefox/default.nix new file mode 100644 index 0000000..509212c --- /dev/null +++ b/users/rus07tam/modules/firefox/default.nix @@ -0,0 +1,57 @@ +{ pkgs, ... }: +{ + programs.firefox = { + enable = true; + languagePacks = [ + "en" + "ru" + ]; + profiles = { + rus07tam = { + isDefault = true; + search = { + force = true; + default = "ddg"; + engines = { + "Nix Packages" = { + urls = [ + { + template = "https://search.nixos.org/packages"; + params = [ + { + name = "channel"; + value = "unstable"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + } + ]; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@np" ]; + }; + "MyNixOS" = { + urls = [ + { + template = "https://mynixos.com/search"; + params = [ + { + name = "q"; + value = "{searchTerms}"; + } + ]; + } + ]; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake-white.svg"; + definedAliases = [ "@mn" ]; + }; + }; + }; + }; + }; + }; + + stylix.targets.firefox.profileNames = [ "rus07tam" ]; +} diff --git a/users/rus07tam/modules/fish/default.nix b/users/rus07tam/modules/fish/default.nix new file mode 100644 index 0000000..34a03f5 --- /dev/null +++ b/users/rus07tam/modules/fish/default.nix @@ -0,0 +1,7 @@ +{ config, ... }: +{ + programs.fish = { + enable = true; + inherit (config) shellAliases; + }; +} diff --git a/users/rus07tam/modules/games.nix b/users/rus07tam/modules/games.nix new file mode 100644 index 0000000..4ebdabb --- /dev/null +++ b/users/rus07tam/modules/games.nix @@ -0,0 +1,6 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + osu-lazer-bin + ]; +} diff --git a/users/rus07tam/modules/git/default.nix b/users/rus07tam/modules/git/default.nix new file mode 100644 index 0000000..07c31fe --- /dev/null +++ b/users/rus07tam/modules/git/default.nix @@ -0,0 +1,17 @@ +{ + programs.git = { + enable = true; + settings = { + init.defaultBranch = "main"; + user = { + name = "Rustam Efimov"; + email = "rus07tam+contact@ruject.fun"; + }; + }; + signing = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPRVeP7aRYdbIku7Qr6dLFLQrcq8LUUTTpYZZ3E8ZoQK"; + format = "ssh"; + signByDefault = true; + }; + }; +} diff --git a/users/rus07tam/modules/hyprland/animations.nix b/users/rus07tam/modules/hyprland/animations.nix new file mode 100644 index 0000000..e1adb5e --- /dev/null +++ b/users/rus07tam/modules/hyprland/animations.nix @@ -0,0 +1,57 @@ +{ config, ... }: +let + animationSpeed = config.theme.animation-speed; + + animationDuration = + if animationSpeed == "slow" then + "4" + else if animationSpeed == "medium" then + "2.5" + else + "1.5"; + + borderDuration = + if animationSpeed == "slow" then + "10" + else if animationSpeed == "medium" then + "6" + else + "3"; +in +{ + wayland.windowManager.hyprland.settings = { + animations = { + enabled = true; + bezier = [ + "linear, 0, 0, 1, 1" + "md3_standard, 0.2, 0, 0, 1" + "md3_decel, 0.05, 0.7, 0.1, 1" + "md3_accel, 0.3, 0, 0.8, 0.15" + "overshot, 0.05, 0.9, 0.1, 1.1" + "crazyshot, 0.1, 1.5, 0.76, 0.92" + "hyprnostretch, 0.05, 0.9, 0.1, 1.0" + "menu_decel, 0.1, 1, 0, 1" + "menu_accel, 0.38, 0.04, 1, 0.07" + "easeInOutCirc, 0.85, 0, 0.15, 1" + "easeOutCirc, 0, 0.55, 0.45, 1" + "easeOutExpo, 0.16, 1, 0.3, 1" + "softAcDecel, 0.26, 0.26, 0.15, 1" + "md2, 0.4, 0, 0.2, 1" + ]; + + animation = [ + "windows, 1, ${animationDuration}, md3_decel, popin 60%" + "windowsIn, 1, ${animationDuration}, md3_decel, popin 60%" + "windowsOut, 1, ${animationDuration}, md3_accel, popin 60%" + "border, 1, ${borderDuration}, default" + "fade, 1, ${animationDuration}, md3_decel" + "layersIn, 1, ${animationDuration}, menu_decel, slide" + "layersOut, 1, ${animationDuration}, menu_accel" + "fadeLayersIn, 1, ${animationDuration}, menu_decel" + "fadeLayersOut, 1, ${animationDuration}, menu_accel" + "workspaces, 1, ${animationDuration}, menu_decel, slide" + "specialWorkspace, 1, ${animationDuration}, md3_decel, slidevert" + ]; + }; + }; +} diff --git a/users/rus07tam/modules/hyprland/autorun.nix b/users/rus07tam/modules/hyprland/autorun.nix new file mode 100644 index 0000000..0a35a35 --- /dev/null +++ b/users/rus07tam/modules/hyprland/autorun.nix @@ -0,0 +1,10 @@ +{ pkgs, ... }: +{ + wayland.windowManager.hyprland.settings = { + exec-once = [ + "hyprpaper" + "${pkgs.firefox}/bin/firefox" + "${pkgs.throne}/bin/Throne" + ]; + }; +} diff --git a/users/rus07tam/modules/hyprland/bindings.nix b/users/rus07tam/modules/hyprland/bindings.nix new file mode 100644 index 0000000..65e27d4 --- /dev/null +++ b/users/rus07tam/modules/hyprland/bindings.nix @@ -0,0 +1,79 @@ +{ pkgs, ... }: +{ + wayland.windowManager.hyprland.settings = { + "$mainMod" = "SUPER"; + "$shiftMod" = "SUPER_SHIFT"; + + bind = [ + # Control + "$mainMod, C, killactive," + "$mainMod, ESCAPE, exit," + "$mainMod, V, togglefloating," + "$mainMod, S, togglesplit," + + # Programs + "$mainMod, T, exec, alacritty" + "$mainMod, M, exec, ${pkgs.wofi}/bin/wofi --show drun" + + # Move focus with "jkl;" + "$mainMod, j, movefocus, l" + "$mainMod, semicolon, movefocus, r" + "$mainMod, l, movefocus, u" + "$mainMod, k, movefocus, d" + + # Move focus with arrows + "$mainMod, left, movefocus, l" + "$mainMod, right, movefocus, r" + "$mainMod, up, movefocus, u" + "$mainMod, down, movefocus, d" + + # Screenshots + ",PRINT, exec, ${pkgs.hyprshot}/bin/hyprshot -m region -o ~/Pictures/Screenshots" + "ALT,PRINT, exec, ${pkgs.hyprshot}/bin/hyprshot -m window -active -o ~/Pictures/Screenshots" # Screenshot active window + "$mainMod,PRINT, exec, ${pkgs.hyprshot}/bin/hyprshot -m output -o ~/Pictures/Screenshots" # Screenshot monitor + "$shiftMod,PRINT, exec, ${pkgs.hyprshot}/bin/hyprshot -m window -o ~/Pictures/Screenshots" # Screenshot window + + # Switch workspaces + "$mainMod, 1, workspace, 1" + "$mainMod, 2, workspace, 2" + "$mainMod, 3, workspace, 3" + "$mainMod, 4, workspace, 4" + "$mainMod, 5, workspace, 5" + "$mainMod, 6, workspace, 6" + "$mainMod, 7, workspace, 7" + "$mainMod, 8, workspace, 8" + "$mainMod, 9, workspace, 9" + "$mainMod, 0, workspace, 10" + + # Move window to workspace + "$mainMod SHIFT, 1, movetoworkspace, 1" + "$mainMod SHIFT, 2, movetoworkspace, 2" + "$mainMod SHIFT, 3, movetoworkspace, 3" + "$mainMod SHIFT, 4, movetoworkspace, 4" + "$mainMod SHIFT, 5, movetoworkspace, 5" + "$mainMod SHIFT, 6, movetoworkspace, 6" + "$mainMod SHIFT, 7, movetoworkspace, 7" + "$mainMod SHIFT, 8, movetoworkspace, 8" + "$mainMod SHIFT, 9, movetoworkspace, 9" + "$mainMod SHIFT, 0, movetoworkspace, 10" + + # Scroll through existing workspaces with mainMod + scroll + "$mainMod, mouse_down, workspace, e+1" + "$mainMod, mouse_up, workspace, e-1" + ]; + bindm = [ + # Move/resize windows with mainMod + LMB/RMB and dragging + "$mainMod, mouse:272, movewindow" + "$mainMod, mouse:273, resizewindow" + ]; + bindel = [ + # Multimedia keys for volume and LCD brightness + ",XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+" + ",XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" + ",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + ",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" + ",XF86MonBrightnessUp, exec, brightnessctl -e4 -n2 set 5%+" + ",XF86MonBrightnessDown, exec, brightnessctl -e4 -n2 set 5%-" + ]; + }; +} diff --git a/users/rus07tam/modules/hyprland/decoration.nix b/users/rus07tam/modules/hyprland/decoration.nix new file mode 100644 index 0000000..18ed534 --- /dev/null +++ b/users/rus07tam/modules/hyprland/decoration.nix @@ -0,0 +1,44 @@ +{ + config, + lib, + ... +}: +let + border-size = toString config.theme.border-size; + gaps-in = toString config.theme.gaps-in; + gaps-out = toString config.theme.gaps-out; + active-opacity = toString config.theme.active-opacity; + inactive-opacity = toString config.theme.inactive-opacity; + rounding = toString config.theme.rounding; + inherit (config.theme) blur; + inactive-border = "rgb(" + config.theme.colors.base00 + ")"; + active-border = "rgb(" + config.theme.colors.base05 + ")"; +in +{ + wayland.windowManager.hyprland.settings = { + general = { + resize_on_border = true; + gaps_in = gaps-in; + gaps_out = gaps-out; + border_size = border-size; + layout = "dwindle"; + "col.active_border" = lib.mkForce active-border; + "col.inactive_border" = lib.mkForce inactive-border; + }; + + decoration = { + inherit rounding; + active_opacity = active-opacity; + inactive_opacity = inactive-opacity; + shadow = { + enabled = true; + range = 20; + render_power = 3; + }; + blur = { + enabled = if blur then "true" else "false"; + size = 18; + }; + }; + }; +} diff --git a/users/rus07tam/modules/hyprland/default.nix b/users/rus07tam/modules/hyprland/default.nix new file mode 100644 index 0000000..6aff09c --- /dev/null +++ b/users/rus07tam/modules/hyprland/default.nix @@ -0,0 +1,70 @@ +{ + imports = [ + ./animations.nix + ./autorun.nix + ./bindings.nix + ./decoration.nix + ./hyprlauncher.nix + ./hyprpanel.nix + ./hyprpaper.nix + ./hyprtoolkit.nix + ./input.nix + ./rules.nix + ]; + + wayland.windowManager.hyprland = { + enable = true; + }; + + wayland.windowManager.hyprland.settings = { + env = [ + "XDG_CURRENT_DESKTOP,Hyprland" + "MOZ_ENABLE_WAYLAND,1" + "ANKI_WAYLAND,1" + "DISABLE_QT5_COMPAT,0" + "NIXOS_OZONE_WL,1" + "XDG_SESSION_TYPE,wayland" + "XDG_SESSION_DESKTOP,Hyprland" + "QT_AUTO_SCREEN_SCALE_FACTOR,1" + "QT_QPA_PLATFORM=wayland,xcb" + "QT_WAYLAND_DISABLE_WINDOWDECORATION,1" + "ELECTRON_OZONE_PLATFORM_HINT,auto" + "__GL_GSYNC_ALLOWED,0" + "__GL_VRR_ALLOWED,0" + "DISABLE_QT5_COMPAT,0" + "DIRENV_LOG_FORMAT," + "WLR_DRM_NO_ATOMIC,1" + "WLR_BACKEND,vulkan" + "WLR_RENDERER,vulkan" + "WLR_NO_HARDWARE_CURSORS,1" + "SDL_VIDEODRIVER,wayland" + "CLUTTER_BACKEND,wayland" + ]; + + monitor = [ + ",preffered,auto,1" + ]; + + dwindle = { + pseudotile = true; + preserve_split = true; + }; + + master = { + new_status = true; + allow_small_split = true; + mfact = 0.5; + }; + + misc = { + vfr = true; + disable_hyprland_logo = true; + disable_splash_rendering = true; + disable_autoreload = true; + focus_on_activate = true; + on_focus_under_fullscreen = 2; + }; + + "debug:disable_scale_checks" = true; + }; +} diff --git a/users/rus07tam/modules/hyprland/hyprlauncher.nix b/users/rus07tam/modules/hyprland/hyprlauncher.nix new file mode 100644 index 0000000..14ed19e --- /dev/null +++ b/users/rus07tam/modules/hyprland/hyprlauncher.nix @@ -0,0 +1,26 @@ +{ + services.hyprlauncher = { + enable = true; + + settings = { + cache = { + enabled = false; + }; + finders = { + default_finder = "desktop"; + desktop_prefix = ""; + unicode_prefix = "."; + math_prefix = "="; + font_prefix = "'"; + desktop_launch_prefix = ""; + desktop_icons = true; + }; + general = { + grab_focus = true; + }; + ui = { + window_size = "400 260"; + }; + }; + }; +} diff --git a/users/rus07tam/modules/hyprland/hyprpanel.nix b/users/rus07tam/modules/hyprland/hyprpanel.nix new file mode 100644 index 0000000..264f8ef --- /dev/null +++ b/users/rus07tam/modules/hyprland/hyprpanel.nix @@ -0,0 +1,224 @@ +{ + config, + lib, + ... +}: +let + inherit (config.theme.bar) transparentButtons; + + accent = "#${config.lib.stylix.colors.base0D}"; + accent-alt = "#${config.lib.stylix.colors.base03}"; + background = "#${config.lib.stylix.colors.base00}"; + background-alt = "#${config.lib.stylix.colors.base01}"; + foreground = "#${config.lib.stylix.colors.base05}"; + foregroundOnWallpaper = "#${config.theme.textColorOnWallpaper}"; + font = "${config.stylix.fonts.serif.name}"; + fontSizeForHyprpanel = "${toString config.stylix.fonts.sizes.desktop}px"; + + inherit (config.theme) rounding; + inherit (config.theme) border-size; + + inherit (config.theme) gaps-out; + inherit (config.theme) gaps-in; + + inherit (config.theme.bar) floating; + inherit (config.theme.bar) transparent; + inherit (config.theme.bar) position; + + notificationOpacity = 90; +in +{ + programs.hyprpanel = { + enable = true; + + settings = lib.mkForce { + bar = { + layouts = { + "*" = { + left = [ + "dashboard" + "workspaces" + "windowtitle" + ]; + middle = [ + "media" + "cava" + ]; + right = [ + "systray" + "volume" + "clock" + "notifications" + "kbinput" + ]; + }; + }; + launcher.icon = ""; + workspaces = { + show_numbered = false; + workspaces = 7; + numbered_active_indicator = "color"; + monitorSpecific = false; + applicationIconEmptyWorkspace = ""; + showApplicationIcons = true; + showWsIcons = true; + }; + windowtitle.label = true; + volume.label = false; + network.truncation_size = 12; + bluetooth.label = false; + clock.format = "%a %b %d %I:%M %p"; + notifications.show_total = true; + media.show_active_only = true; + customModules = { + updates.pollingInterval = 1440000; + cava = { + showIcon = false; + stereo = true; + showActiveOnly = true; + }; + }; + }; + + notifications = { + position = "top right"; + showActionsOnHover = true; + }; + + menus = { + dashboard = { + shortcuts.enabled = false; + powermenu = { + confirmation = false; + avatar.image = "~/.face.icon"; + }; + directories = { }; + }; + power.lowBatteryNotification = true; + }; + + wallpaper.enable = false; + + theme = { + font = { + name = font; + size = fontSizeForHyprpanel; + }; + osd = { + enable = true; + orientation = "vertical"; + location = "left"; + radius = toString rounding + "px"; + margins = "0px 0px 0px 10px"; + muted_zero = true; + bar_color = accent; + bar_overflow_color = accent-alt; + icon = background; + icon_container = accent; + label = accent; + bar_container = background-alt; + }; + notification = { + opacity = notificationOpacity; + enableShadow = true; + border_radius = toString rounding + "px"; + background = background-alt; + actions = { + background = accent; + text = foreground; + }; + label = accent; + border = background-alt; + text = foreground; + labelicon = accent; + close_button = { + background = background-alt; + label = "#f38ba8"; + }; + }; + bar = { + outer_spacing = if floating && transparent then "0px" else "8px"; + margin_top = (if position == "top" then toString (gaps-in * 2) else "0") + "px"; + margin_bottom = (if position == "top" then "0" else toString (gaps-in * 2)) + "px"; + margin_sides = toString gaps-out + "px"; + border_radius = toString rounding + "px"; + inherit transparent; + location = position; + dropdownGap = "4.5em"; + inherit floating; + menus = { + inherit background; + cards = background-alt; + label = foreground; + text = foreground; + border.color = accent; + popover = { + text = foreground; + background = background-alt; + }; + listitems.active = accent; + icons.active = accent; + switch.enabled = accent; + check_radio_button.active = accent; + buttons = { + default = accent; + active = accent; + }; + iconbuttons.active = accent; + progressbar.foreground = accent; + slider.primary = accent; + tooltip = { + background = background-alt; + text = foreground; + }; + dropdownmenu = { + background = background-alt; + text = foreground; + }; + shadow = if transparent then "0 0 0 0" else "0px 0px 3px 1px #16161e"; + monochrome = true; + card_radius = toString rounding + "px"; + border = { + size = toString border-size + "px"; + radius = toString rounding + "px"; + }; + menu.media = { + background.color = background-alt; + card = { + color = background-alt; + tint = 90; + }; + }; + }; + background = background + (if transparentButtons && transparent then "00" else ""); + buttons = { + workspaces = { + hover = accent-alt; + active = accent; + available = accent-alt; + occupied = accent-alt; + }; + y_margins = if floating && transparent then "0px" else "8px"; + spacing = "0.3em"; + radius = (if transparent then toString rounding else toString (rounding - 8)) + "px"; + padding_x = "0.8rem"; + padding_y = "0.4rem"; + style = "default"; + monochrome = true; + text = if transparent && transparentButtons then foregroundOnWallpaper else foreground; + background = + (if transparent then background else background-alt) + (if transparentButtons then "00" else ""); + icon = accent; + hover = lib.mkForce background; + notifications = { + hover = background; + total = accent; + icon = accent; + background = lib.mkForce background-alt; + }; + }; + }; + }; + }; + }; +} diff --git a/users/rus07tam/modules/hyprland/hyprpaper.nix b/users/rus07tam/modules/hyprland/hyprpaper.nix new file mode 100644 index 0000000..f8fdf23 --- /dev/null +++ b/users/rus07tam/modules/hyprland/hyprpaper.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ hyprpaper ]; + services.hyprpaper = { + enable = true; + settings = { + splash = false; + splash_offset = 2; + }; + }; +} diff --git a/users/rus07tam/modules/hyprland/hyprtoolkit.nix b/users/rus07tam/modules/hyprland/hyprtoolkit.nix new file mode 100644 index 0000000..eebdb47 --- /dev/null +++ b/users/rus07tam/modules/hyprland/hyprtoolkit.nix @@ -0,0 +1,25 @@ +{ + config, + pkgs, + ... +}: +let + inherit (config.theme) colors; + font = config.stylix.fonts.serif.name; + font-size = config.stylix.fonts.sizes.popups; +in +{ + home.packages = with pkgs; [ wofi-emoji ]; + + xdg.configFile."hypr/hyprtoolkit.conf".text = '' + background = 0x${colors.base00} + base = 0x${colors.base01} + alternate_base = 0x${colors.base02} + text = 0x${colors.base05} + bright_text = 0x${colors.base06} + accent = 0x${colors.base0D} + accent_secondary = 0x${colors.base0E} + font_family = ${font} + font_size = ${toString font-size} + ''; +} diff --git a/users/rus07tam/modules/hyprland/input.nix b/users/rus07tam/modules/hyprland/input.nix new file mode 100644 index 0000000..4f1a0e8 --- /dev/null +++ b/users/rus07tam/modules/hyprland/input.nix @@ -0,0 +1,24 @@ +{ + wayland.windowManager.hyprland.settings = { + cursor = { + no_hardware_cursors = true; + hide_on_touch = true; + inactive_timeout = 0; + }; + input = { + kb_layout = "us,ru"; + + kb_options = "altwin:swap_alt_win,grp:caps_toggle"; + follow_mouse = 1; + sensitivity = 0.5; + repeat_delay = 300; + repeat_rate = 50; + numlock_by_default = true; + + touchpad = { + natural_scroll = true; + clickfinger_behavior = true; + }; + }; + }; +} diff --git a/users/rus07tam/modules/hyprland/rules.nix b/users/rus07tam/modules/hyprland/rules.nix new file mode 100644 index 0000000..b488762 --- /dev/null +++ b/users/rus07tam/modules/hyprland/rules.nix @@ -0,0 +1,7 @@ +{ + wayland.windowManager.hyprland.settings = { + windowrule = [ + "match:class .*, suppress_event maximize" + ]; + }; +} diff --git a/users/rus07tam/modules/nvf/assistant.nix b/users/rus07tam/modules/nvf/assistant.nix new file mode 100644 index 0000000..54c2dad --- /dev/null +++ b/users/rus07tam/modules/nvf/assistant.nix @@ -0,0 +1,12 @@ +{ + programs.nvf.settings.vim.assistant.neocodeium = { + enable = true; + setupOpts = { + enabled = true; + log_level = "debug"; + }; + keymaps = { + accept = ""; + }; + }; +} diff --git a/users/rus07tam/modules/nvf/default.nix b/users/rus07tam/modules/nvf/default.nix new file mode 100644 index 0000000..3f8f511 --- /dev/null +++ b/users/rus07tam/modules/nvf/default.nix @@ -0,0 +1,31 @@ +{ + inputs, + pkgs, + ... +}: +{ + imports = [ + inputs.nvf.homeManagerModules.default + ./assistant.nix + ./options.nix + ./languages.nix + ./picker.nix + ./snacks.nix + ./keymaps.nix + ./utils.nix + ./mini.nix + ]; + + home.packages = with pkgs; [ + neovim + ]; + + programs.nvf = { + enable = true; + settings.vim = { + startPlugins = [ + pkgs.vimPlugins.vim-kitty-navigator + ]; + }; + }; +} diff --git a/users/rus07tam/modules/nvf/keymaps.nix b/users/rus07tam/modules/nvf/keymaps.nix new file mode 100644 index 0000000..32b6462 --- /dev/null +++ b/users/rus07tam/modules/nvf/keymaps.nix @@ -0,0 +1,269 @@ +{ + programs.nvf.settings.vim = { + globals.mapleader = " "; + binds = { + whichKey = { + enable = true; + register = { }; + }; + }; + keymaps = [ + # "hjkl" -> "jkl;" + { + mode = "n"; # Normal mode + key = "j"; + action = ""; + desc = "Move Left"; + } + { + mode = "n"; + key = "k"; + action = ""; + desc = "Move Down"; + } + { + mode = "n"; + key = "l"; + action = ""; + desc = "Move Up"; + } + { + mode = "n"; + key = ";"; + action = ""; + desc = "Move Right"; + } + { + mode = "v"; # Visual mode + key = "j"; + action = ""; + desc = "Move Left"; + } + { + mode = "v"; + key = "k"; + action = ""; + desc = "Move Down"; + } + { + mode = "v"; + key = "l"; + action = ""; + desc = "Move Up"; + } + { + mode = "v"; + key = ";"; + action = ""; + desc = "Move Right"; + } + + # General Mappings + { + key = "s"; + mode = "n"; + silent = true; + action = "lua require('flash').jump()"; + desc = "Flash"; + } + { + key = "K"; + mode = "n"; + silent = true; + action = "lua vim.lsp.buf.hover()"; + desc = "LSP Hover"; + } + { + key = ""; + mode = "n"; + silent = true; + action = "bnext"; + desc = "Next Buffer"; + } + { + key = "rn"; + mode = "n"; + silent = true; + action = "lua vim.lsp.buf.rename()"; + desc = "Rename symbol"; + } + + # Escape from Insert Mode + { + key = "jj"; + mode = "i"; + action = ""; + desc = "Exit insert mode"; + } # UI + { + key = "uw"; + mode = "n"; + silent = true; + action = "set wrap!"; + desc = "Toggle word wrapping"; + } + { + key = "ul"; + mode = "n"; + silent = true; + action = "set linebreak!"; + desc = "Toggle linebreak"; + } + { + key = "us"; + mode = "n"; + silent = true; + action = "set spell!"; + desc = "Toggle spellLazyGitcheck"; + } + { + key = "uc"; + mode = "n"; + silent = true; + action = "set cursorline!"; + desc = "Toggle cursorline"; + } + { + key = "un"; + mode = "n"; + silent = true; + action = "set number!"; + desc = "Toggle line numbers"; + } + { + key = "ur"; + mode = "n"; + silent = true; + action = "set relativenumber!"; + desc = "Toggle relative line numbers"; + } + { + key = "ut"; + mode = "n"; + silent = true; + action = "set showtabline=2"; + desc = "Show tabline"; + } + { + key = "uT"; + mode = "n"; + silent = true; + action = "set showtabline=0"; + desc = "Hide tabline"; + } + + # Windows + { + key = "ws"; + mode = "n"; + silent = true; + action = "split"; + desc = "Split"; + } + { + key = "wv"; + mode = "n"; + silent = true; + action = "vsplit"; + desc = "VSplit"; + } + { + key = "wd"; + mode = "n"; + silent = true; + action = "close"; + desc = "Close"; + } + + # Disable Arrow Keys in Normal Mode + { + key = ""; + mode = "n"; + silent = true; + action = ""; + desc = "Disable Up Arrow"; + } + { + key = ""; + mode = "n"; + silent = true; + action = ""; + desc = "Disable Down Arrow"; + } + { + key = ""; + mode = "n"; + silent = true; + action = ""; + desc = "Disable Left Arrow"; + } + { + key = ""; + mode = "n"; + silent = true; + action = ""; + desc = "Disable Right Arrow"; + } + + # Disable Arrow Keys in Visual Mode + { + key = ""; + mode = "v"; + silent = true; + action = ""; + desc = "Disable Up Arrow"; + } + { + key = ""; + mode = "v"; + silent = true; + action = ""; + desc = "Disable Down Arrow"; + } + { + key = ""; + mode = "v"; + silent = true; + action = ""; + desc = "Disable Left Arrow"; + } + { + key = ""; + mode = "v"; + silent = true; + action = ""; + desc = "Disable Right Arrow"; + } + + # Disable Arrow Keys in Insert Mode + { + key = ""; + mode = "i"; + silent = true; + action = ""; + desc = "Disable Up Arrow"; + } + { + key = ""; + mode = "i"; + silent = true; + action = ""; + desc = "Disable Down Arrow"; + } + { + key = ""; + mode = "i"; + silent = true; + action = ""; + desc = "Disable Left Arrow"; + } + { + key = ""; + mode = "i"; + silent = true; + action = ""; + desc = "Disable Right Arrow"; + } + ]; + }; +} diff --git a/users/rus07tam/modules/nvf/languages.nix b/users/rus07tam/modules/nvf/languages.nix new file mode 100644 index 0000000..9d04fe2 --- /dev/null +++ b/users/rus07tam/modules/nvf/languages.nix @@ -0,0 +1,122 @@ +{ lib, ... }: +{ + programs.nvf.settings.vim = { + diagnostics = { + enable = true; + config = { + signs = { + text = { + "vim.diagnostic.severity.Error" = " "; + "vim.diagnostic.severity.Warn" = " "; + "vim.diagnostic.severity.Hint" = " "; + "vim.diagnostic.severity.Info" = " "; + }; + }; + underline = true; + update_in_insert = true; + virtual_text = { + format = + lib.generators.mkLuaInline + # lua + '' + function(diagnostic) + return string.format("%s", diagnostic.message) + --return string.format("%s (%s)", diagnostic.message, diagnostic.source) + end + ''; + }; + }; + nvim-lint = { + enable = true; + }; + }; + syntaxHighlighting = true; + treesitter = { + enable = true; + autotagHtml = true; + context.enable = true; + highlight.enable = true; + }; + lsp = { + enable = true; + trouble.enable = true; + lspSignature.enable = true; + lspconfig.enable = true; + formatOnSave = true; + inlayHints.enable = true; + null-ls.enable = true; + otter-nvim = { + enable = true; + setupOpts = { + buffers.set_filetype = true; + lsp = { + diagnostic_update_event = [ + "BufWritePost" + "InsertLeave" + ]; + }; + }; + }; + lspkind.enable = true; + lspsaga = { + enable = true; + setupOpts = { + ui = { + code_action = ""; + }; + lightbulb = { + sign = false; + virtual_text = true; + }; + breadcrumbs.enable = false; + }; + }; + }; + languages = { + enableDAP = true; + enableExtraDiagnostics = true; + enableFormat = true; + enableTreesitter = true; + + bash.enable = true; + clang.enable = true; + css.enable = true; + elixir.enable = true; + go.enable = true; + html.enable = true; + json.enable = true; + lua.enable = true; + markdown = { + enable = true; + extensions = { + render-markdown-nvim = { + enable = true; + }; + }; + extraDiagnostics.enable = true; + }; + nim.enable = true; + nix.enable = true; + python = { + enable = true; + format.type = [ + "black" + "isort" + ]; + }; + rust.enable = true; + tailwind.enable = true; + ts = { + enable = true; + extensions.ts-error-translator.enable = true; + }; + yaml.enable = true; + zig.enable = true; + }; + formatter = { + conform-nvim = { + enable = true; + }; + }; + }; +} diff --git a/users/rus07tam/modules/nvf/mini.nix b/users/rus07tam/modules/nvf/mini.nix new file mode 100644 index 0000000..2c0568b --- /dev/null +++ b/users/rus07tam/modules/nvf/mini.nix @@ -0,0 +1,13 @@ +{ + programs.nvf.settings.vim.mini = { + starter.enable = true; + comment.enable = true; + # cursorword.enable = true; + icons.enable = true; + indentscope.enable = true; + notify.enable = true; + pairs.enable = true; + diff.enable = true; + git.enable = true; + }; +} diff --git a/users/rus07tam/modules/nvf/options.nix b/users/rus07tam/modules/nvf/options.nix new file mode 100644 index 0000000..76b17a6 --- /dev/null +++ b/users/rus07tam/modules/nvf/options.nix @@ -0,0 +1,41 @@ +{ lib, ... }: +{ + programs.nvf.settings.vim = { + viAlias = false; + vimAlias = true; + withNodeJs = true; + # syntaxHighlighting = true; + options = { + autoindent = true; + smartindent = true; + shiftwidth = 2; + foldlevel = 99; + foldcolumn = "auto:1"; + mousescroll = "ver:1,hor:1"; + mousemoveevent = true; + fillchars = "eob:‿,fold: ,foldopen:▼,foldsep:⸽,foldclose:⏵"; + signcolumn = "yes"; + tabstop = 2; + softtabstop = 2; + wrap = false; + }; + globals = { + navic_silence = true; # navic tries to attach multiple LSPs and fails + suda_smart_edit = 1; # use super user write automatically + neovide_scale_factor = 0.7; + neovide_cursor_animation_length = 0.1; + neovide_cursor_short_animation_length = 0; + }; + clipboard = { + enable = true; + registers = "unnamedplus"; + providers.wl-copy.enable = true; + }; + theme = { + enable = true; + name = lib.mkForce "catppuccin"; + style = lib.mkForce "mocha"; + transparent = lib.mkForce true; + }; + }; +} diff --git a/users/rus07tam/modules/nvf/picker.nix b/users/rus07tam/modules/nvf/picker.nix new file mode 100644 index 0000000..5b1a629 --- /dev/null +++ b/users/rus07tam/modules/nvf/picker.nix @@ -0,0 +1,256 @@ +{ + programs.nvf.settings.vim = { + utility = { + oil-nvim.enable = true; + snacks-nvim = { + setupOpts = { + picker.enabled = true; + explorer.enabled = true; + }; + }; + }; + keymaps = [ + # Top Pickers & Explorer + { + key = " "; + mode = "n"; + silent = true; + action = "lua Snacks.picker.smart()"; + desc = "Smart Find Files"; + } + { + key = ","; + mode = "n"; + silent = true; + action = "lua Snacks.picker.buffers()"; + desc = "Buffers"; + } + { + key = "/"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.grep()"; + desc = "Grep"; + } + { + key = ":"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.command_history()"; + desc = "Command History"; + } + { + key = "e"; + mode = "n"; + silent = true; + action = "lua Snacks.explorer()"; + desc = "File Explorer"; + } + { + key = "-"; + mode = "n"; + silent = true; + action = "Oil"; + desc = "Oil"; + } + + # Find + { + key = "fb"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.buffers()"; + desc = "Buffers"; + } + { + key = "fc"; + mode = "n"; + silent = true; + action = ''lua Snacks.picker.files({ cwd = vim.fn.stdpath("config") })''; + desc = "Find Config File"; + } + { + key = "ff"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.files()"; + desc = "Find Files"; + } + { + key = "fg"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_files()"; + desc = "Find Git Files"; + } + { + key = "fp"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.projects()"; + desc = "Projects"; + } + { + key = "fr"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.recent()"; + desc = "Recent"; + } + { + key = "fn"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.notifications()"; + desc = "Notification History"; + } + { + key = "fe"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.icons()"; + desc = "Emoji"; + } + + # Git + { + key = "gb"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_branches()"; + desc = "Git Branches"; + } + { + key = "gL"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_log()"; + desc = "Git Log Line"; + } + { + key = "gs"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_status()"; + desc = "Git Status"; + } + { + key = "gS"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_stash()"; + desc = "Git Stash"; + } + { + key = "gd"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_diff()"; + desc = "Git Diff (Hunks)"; + } + { + key = "gf"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.git_log_file()"; + desc = "Git Log File"; + } + + # Grep + { + key = "sb"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lines()"; + desc = "Buffer Lines"; + } + { + key = "st"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.todo_comments()"; + desc = "Todos"; + } + { + key = "sB"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.grep_buffers()"; + desc = "Grep Open Buffers"; + } + { + key = "sg"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.grep()"; + desc = "Grep"; + } + { + key = "sw"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.grep_word()"; + desc = "Visual selection or word"; + } + { + key = "sr"; + mode = "n"; + silent = true; + action = "nohlsearch"; + desc = "Reset search"; + } + + # LSP + { + key = "gd"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_definitions()"; + desc = "Goto Definition"; + } + { + key = "gD"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_declarations()"; + desc = "Goto Declaration"; + } + { + key = "gr"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_references()"; + desc = "References"; + nowait = true; + } + { + key = "gI"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_implementations()"; + desc = "Goto Implementation"; + } + { + key = "gy"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_type_definitions()"; + desc = "Goto Type Definition"; + } + { + key = "ss"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_symbols()"; + desc = "LSP Symbols"; + } + { + key = "sS"; + mode = "n"; + silent = true; + action = "lua Snacks.picker.lsp_workspace_symbols()"; + desc = "LSP Workspace Symbols"; + } + ]; + }; +} diff --git a/users/rus07tam/modules/nvf/snacks.nix b/users/rus07tam/modules/nvf/snacks.nix new file mode 100644 index 0000000..f0faf03 --- /dev/null +++ b/users/rus07tam/modules/nvf/snacks.nix @@ -0,0 +1,16 @@ +{ + programs.nvf.settings.vim.utility.snacks-nvim = { + enable = true; + setupOpts = { + image = { + enabled = true; + setupOpts.doc.inline = false; + }; + quickfile.enabled = true; + statuscolumn.enabled = true; + zen.enabled = true; + bufdelete.enabled = true; + gitsigns.enabled = true; + }; + }; +} diff --git a/users/rus07tam/modules/nvf/utils.nix b/users/rus07tam/modules/nvf/utils.nix new file mode 100644 index 0000000..c7b44bf --- /dev/null +++ b/users/rus07tam/modules/nvf/utils.nix @@ -0,0 +1,50 @@ +{ pkgs, ... }: +{ + programs.nvf.settings.vim = { + undoFile.enable = true; + utility = { + motion.flash-nvim.enable = true; + outline.aerial-nvim.enable = true; + }; + tabline.nvimBufferline.enable = true; + notes.todo-comments.enable = true; + statusline.lualine.enable = true; + + autocomplete = { + nvim-cmp = { + enable = true; + sources = { + buffer = "[Buffer]"; + nvim-cmp = null; + path = "[Path]"; + }; + sourcePlugins = [ + pkgs.vimPlugins.cmp-cmdline + ]; + }; + }; + + snippets.luasnip.enable = true; + ui = { + noice.enable = true; + colorizer.enable = true; + }; + git = { + enable = true; + gitsigns.enable = true; + }; + terminal.toggleterm = { + enable = true; + lazygit = { + enable = true; + mappings.open = "gl"; + }; + }; + visuals = { + rainbow-delimiters.enable = true; + nvim-scrollbar = { + enable = false; + }; + }; + }; +} diff --git a/users/rus07tam/modules/obsidian/default.nix b/users/rus07tam/modules/obsidian/default.nix new file mode 100644 index 0000000..c762f1f --- /dev/null +++ b/users/rus07tam/modules/obsidian/default.nix @@ -0,0 +1,28 @@ +{ + programs.obsidian = { + enable = true; + defaultSettings = { + corePlugins = [ + "backlink" + "bases" + "bookmarks" + "canvas" + "command-palette" + "daily-notes" + "editor-status" + "file-explorer" + "file-recovery" + "global-search" + "graph" + "note-composer" + "outgoing-link" + "outline" + "page-preview" + "switcher" + "tag-pane" + "templates" + "word-count" + ]; + }; + }; +} diff --git a/users/rus07tam/modules/openclaw/default.nix b/users/rus07tam/modules/openclaw/default.nix new file mode 100644 index 0000000..643132e --- /dev/null +++ b/users/rus07tam/modules/openclaw/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./secrets.nix + ./service.nix + ]; +} diff --git a/users/rus07tam/modules/openclaw/secrets.nix b/users/rus07tam/modules/openclaw/secrets.nix new file mode 100644 index 0000000..16ffaf1 --- /dev/null +++ b/users/rus07tam/modules/openclaw/secrets.nix @@ -0,0 +1,6 @@ +{ + sops.secrets = { + "rus07tam/openclaw/gatewayToken" = { }; + "rus07tam/openclaw/telegramToken" = { }; + }; +} diff --git a/users/rus07tam/modules/openclaw/service.nix b/users/rus07tam/modules/openclaw/service.nix new file mode 100644 index 0000000..26ce819 --- /dev/null +++ b/users/rus07tam/modules/openclaw/service.nix @@ -0,0 +1,37 @@ +{ sec, inputs, ... }: +{ + imports = [ + inputs.nix-openclaw.homeManagerModules.openclaw + ]; + + programs.openclaw = { + enable = true; + installApp = false; + + bundledPlugins = { + summarize.enable = true; + }; + + instances.default = { + enable = true; + systemd.enable = true; + + config = { + gateway = { + mode = "local"; + auth.token = sec."rus07tam/openclaw/gatewayToken".value; + }; + + channels.telegram = { + tokenFile = sec."rus07tam/openclaw/telegramToken".path; + allowFrom = [ 6146757977 ]; + groups = { + "*" = { + requireMention = true; + }; + }; + }; + }; + }; + }; +} diff --git a/users/rus07tam/modules/rclone/default.nix b/users/rus07tam/modules/rclone/default.nix new file mode 100644 index 0000000..e2f0386 --- /dev/null +++ b/users/rus07tam/modules/rclone/default.nix @@ -0,0 +1,9 @@ +{ + imports = [ + ./nextcloud.nix + ]; + + programs.rclone = { + enable = true; + }; +} diff --git a/users/rus07tam/modules/rclone/nextcloud.nix b/users/rus07tam/modules/rclone/nextcloud.nix new file mode 100644 index 0000000..2d3e5f5 --- /dev/null +++ b/users/rus07tam/modules/rclone/nextcloud.nix @@ -0,0 +1,22 @@ +{ + config, + sec, + ... +}: +{ + sops.secrets."rus07tam/tokens/nextcloud.ruject.fun" = { }; + + programs.rclone.remotes.nextcloud = { + config = { + type = "webdav"; + vendor = "nextcloud"; + url = "https://nextcloud.ruject.fun/remote.php/dav/files/rus07tam"; + user = "rus07tam"; + }; + secrets.pass = sec."rus07tam/tokens/nextcloud.ruject.fun".path; + mounts."" = { + enable = true; + mountPoint = "${config.home.homeDirectory}/Nextcloud"; + }; + }; +} diff --git a/users/rus07tam/modules/stylix/default.nix b/users/rus07tam/modules/stylix/default.nix new file mode 100644 index 0000000..e484f2a --- /dev/null +++ b/users/rus07tam/modules/stylix/default.nix @@ -0,0 +1,47 @@ +{ + pkgs, + config, + inputs, + ... +}: +{ + imports = [ + inputs.stylix.homeModules.stylix + ]; + + stylix = { + enable = true; + + base16Scheme = config.theme.colors; + + cursor = { + name = "phinger-cursors-light"; + package = pkgs.phinger-cursors; + size = 20; + }; + + fonts = { + monospace = { + package = pkgs.nerd-fonts.jetbrains-mono; + name = "JetBrains Mono Nerd Font"; + }; + sansSerif = { + package = pkgs.source-sans-pro; + name = "Source Sans Pro"; + }; + serif = { + package = pkgs.source-sans-pro; + name = "Source Sans Pro"; + }; + emoji = { + package = pkgs.noto-fonts-color-emoji; + name = "Noto Color Emoji"; + }; + inherit (config.theme.fonts) sizes; + }; + + polarity = "dark"; + + image = config.assets.wallpaper; + }; +} diff --git a/users/rus07tam/modules/wofi/default.nix b/users/rus07tam/modules/wofi/default.nix new file mode 100644 index 0000000..f96cbfe --- /dev/null +++ b/users/rus07tam/modules/wofi/default.nix @@ -0,0 +1,113 @@ +{ + config, + pkgs, + lib, + ... +}: +let + accent = "#${config.theme.colors.base0D}"; + background = "#${config.theme.colors.base00}"; + background-alt = "#${config.theme.colors.base01}"; + foreground = "#${config.theme.colors.base05}"; + font = config.stylix.fonts.serif.name; + inherit (config.theme) rounding; + font-size = config.stylix.fonts.sizes.popups; +in +{ + home.packages = with pkgs; [ wofi-emoji ]; + + programs.wofi = { + enable = true; + + settings = { + allow_markup = true; + width = 650; + show = "drun"; + prompt = "Apps"; + normal_window = true; + layer = "top"; + height = "325px"; + orientation = "vertical"; + halign = "fill"; + line_wrap = "off"; + dynamic_lines = false; + allow_images = true; + image_size = 24; + exec_search = false; + hide_search = false; + parse_search = false; + insensitive = true; + hide_scroll = true; + no_actions = true; + sort_order = "default"; + gtk_dark = true; + filter_rate = 100; + key_expand = "Tab"; + key_exit = "Escape"; + }; + + style = + lib.mkForce + # css + '' + * { + font-family: "${font}"; + font-weight: 600; + font-size: ${toString font-size}px; + } + + #window { + background-color: ${background}; + color: ${foreground}; + border-radius: ${toString rounding}px; + } + + #outer-box { + padding: 20px; + } + + #input { + background-color: ${background-alt}; + border: 0px solid ${accent}; + color: ${foreground}; + padding: 8px 12px; + } + + #scroll { + margin-top: 20px; + } + + #inner-box {} + + #img { + padding-right: 8px; + } + + #text { + color: ${foreground}; + } + + #text:selected { + color: ${foreground}; + } + + #entry { + padding: 6px; + } + + #entry:selected { + background-color: ${accent}; + color: ${foreground}; + } + + #unselected {} + + #selected {} + + #input, + #entry:selected { + border-radius: ${toString rounding}px; + } + ''; + }; +} diff --git a/users/rus07tam/modules/zed/default.nix b/users/rus07tam/modules/zed/default.nix new file mode 100644 index 0000000..b6acd8b --- /dev/null +++ b/users/rus07tam/modules/zed/default.nix @@ -0,0 +1,143 @@ +{ + pkgs, + lib, + ... +}: +{ + programs.zed-editor = { + enable = true; + extensions = [ + "nix" + "git-firefly" + "toml" + "ruff" + "pylsp" + "shades-of-purple-theme" + "material-icon-theme" + ]; + extraPackages = with pkgs; [ + nixd + ruff + ]; + mutableUserDebug = false; + mutableUserKeymaps = false; + mutableUserSettings = false; + mutableUserTasks = false; + userSettings = { + auto_update = false; + base_keymap = "VSCode"; + edit_predictions = { + disabled_globs = [ + "**/.env*" + "**/*.pem" + "**/*.key" + "**/*.cert" + "**/*.crt" + "**/secrets.yml" + ]; + }; + features = { + copilot = false; + }; + file_scan_exclusions = [ + "_build" + ".vscode" + ".lexical" + ".elixir_ls" + ".coverage" + ".venv" + ".pytest_cache/" + ".mypy_cache/" + ".ruff_cache" + ".git/" + ".idea" + "**/__pycache__" + "node_modules" + "test_db.sql" + ".ropeproject" + ".expert" + ]; + format_on_save = "on"; + icon_theme = { + mode = "system"; + light = "Material Icon Theme"; + dark = "Material Icon Theme"; + }; + load_direnv = "direct"; + languages = { + Markdown = { }; + Nix = { + language_servers = [ + "nixd" + "!nil" + ]; + formatter.external = { + command = "${lib.getExe pkgs.nixfmt}"; + arguments = [ + "--quiet" + "--" + ]; + }; + show_edit_predictions = true; + }; + Python = { + language_servers = [ + "ty" + "ruff" + ]; + format_on_save = "on"; + formatter = [ + { + code_action = "source.fixAll.ruff"; + } + { + code_action = "source.organizeImports.ruff"; + } + { + language_server = { + name = "ruff"; + }; + } + ]; + show_edit_predictions = true; + }; + }; + lsp = { + nixd = { + binary.path = lib.getExe pkgs.nixd; + }; + ruff = { + binary = { + path = lib.getExe pkgs.ruff; + arguments = [ "server" ]; + }; + }; + }; + preview_tabs = { + enabled = true; + enable_preview_from_file_finder = true; + enable_preview_from_code_navigation = true; + }; + show_edit_predictions = true; + tabs = { + file_icons = true; + git_status = true; + }; + tab_size = 2; + telemetry = { + diagnostics = false; + metrics = false; + }; + minimap.show = "never"; + use_smartcase_search = true; + vim_mode = true; + relative_line_numbers = true; + remove_trailing_whitespace_on_save = true; + theme = lib.mkForce { + mode = "system"; + light = "Shades Of Purple"; + dark = "Shades Of Purple (Super Dark)"; + }; + }; + }; +} diff --git a/users/rus07tam/modules/zellij/default.nix b/users/rus07tam/modules/zellij/default.nix new file mode 100644 index 0000000..6ed1b6b --- /dev/null +++ b/users/rus07tam/modules/zellij/default.nix @@ -0,0 +1,5 @@ +{ + programs.zellij = { + enable = true; + }; +} diff --git a/users/rus07tam/secrets/home.nix b/users/rus07tam/secrets/home.nix new file mode 100644 index 0000000..431169c --- /dev/null +++ b/users/rus07tam/secrets/home.nix @@ -0,0 +1,17 @@ +{ + sops = { + defaultSopsFile = ./../../../secrets/rus07tam.yaml; + age.sshKeyPaths = [ + "/home/rus07tam/.ssh/id_ed25519" + ]; + + secrets = { + "rus07tam/keys/ssh/public" = { + mode = "0644"; + }; + "rus07tam/keys/ssh/private" = { + mode = "0600"; + }; + }; + }; +} diff --git a/users/rus07tam/secrets/system.nix b/users/rus07tam/secrets/system.nix new file mode 100644 index 0000000..16fd7d8 --- /dev/null +++ b/users/rus07tam/secrets/system.nix @@ -0,0 +1,21 @@ +{ + sops = { + secrets = { + "rus07tam/hashedPassword" = { + sopsFile = ./../../../secrets/rus07tam.yaml; + }; + "rus07tam/keys/ssh/public" = { + sopsFile = ./../../../secrets/rus07tam.yaml; + mode = "0644"; + owner = "rus07tam"; + group = "users"; + }; + "rus07tam/keys/ssh/private" = { + sopsFile = ./../../../secrets/rus07tam.yaml; + mode = "0600"; + owner = "rus07tam"; + group = "users"; + }; + }; + }; +} diff --git a/users/rus07tam/system.nix b/users/rus07tam/system.nix new file mode 100644 index 0000000..f38c4e1 --- /dev/null +++ b/users/rus07tam/system.nix @@ -0,0 +1,29 @@ +{ + pkgs, + sec, + ... +}: +{ + imports = [ ./secrets/system.nix ]; + + services.openssh.settings.AllowUsers = [ "rus07tam" ]; + + programs.fish.enable = true; + + users.users.rus07tam = { + isNormalUser = true; + description = "rus07tam"; + uid = 1000; + extraGroups = [ + "networkmanager" + "wheel" + ]; + hashedPasswordFile = sec."rus07tam/hashedPassword".path; + openssh.authorizedKeys = { + keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPRVeP7aRYdbIku7Qr6dLFLQrcq8LUUTTpYZZ3E8ZoQK ruject@rus07tam" + ]; + }; + shell = pkgs.fish; + }; +} diff --git a/users/rus07tam/variables/assets.nix b/users/rus07tam/variables/assets.nix new file mode 100644 index 0000000..906d5f0 --- /dev/null +++ b/users/rus07tam/variables/assets.nix @@ -0,0 +1,9 @@ +{ lib, ... }: +{ + options.assets = lib.mkOption { + type = lib.types.attrs; + default = { + wallpaper = ../assets/wallpaper.png; + }; + }; +} diff --git a/users/rus07tam/variables/default.nix b/users/rus07tam/variables/default.nix new file mode 100644 index 0000000..a4d6270 --- /dev/null +++ b/users/rus07tam/variables/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./assets.nix + ./theme.nix + ./shell_aliases.nix + ]; +} diff --git a/users/rus07tam/variables/shell_aliases.nix b/users/rus07tam/variables/shell_aliases.nix new file mode 100644 index 0000000..757ef45 --- /dev/null +++ b/users/rus07tam/variables/shell_aliases.nix @@ -0,0 +1,45 @@ +{ + lib, + pkgs, + ... +}: +{ + options.shellAliases = lib.mkOption { + type = lib.types.attrs; + default = { + e = "exit"; + ls = "eza --icons=always --no-quotes"; + tree = "eza --icons=always --tree --no-quotes"; + cat = "bat --theme=base16 --color=always --paging=never --tabs=2 --wrap=never --plain"; + mkdir = "mkdir -p"; + rm = "${pkgs.rmtrash}/bin/rmtrash"; + rmdir = "${pkgs.rmtrash}/bin/rmdirtrash"; + frm = "${pkgs.coreutils}/bin/rm"; + frmdir = "${pkgs.coreutils}/bin/rmdir"; + poweroff = "sudo poweroff"; + shutdown = "sudo poweroff"; + reboot = "sudo reboot"; + + nix-shell = "nix-shell --command fish"; + + # git + ga = "git add"; + gc = "git commit"; + gp = "git push"; + gpl = "git pull"; + gs = "git status"; + gl = "git log"; + gd = "git diff"; + gf = "git fetch"; + gm = "git merge"; + gsw = "git switch"; + gco = "git checkout"; + gcb = "git checkout -b"; + gbr = "git branch"; + grs = "git reset HEAD~1"; + grh = "git reset --hard HEAD~1"; + gaa = "git add ."; + gcm = "git commit -m"; + }; + }; +} diff --git a/users/rus07tam/variables/theme.nix b/users/rus07tam/variables/theme.nix new file mode 100644 index 0000000..569efdb --- /dev/null +++ b/users/rus07tam/variables/theme.nix @@ -0,0 +1,51 @@ +{ lib, ... }: +{ + options.theme = lib.mkOption { + type = lib.types.attrs; + default = { + rounding = 20; + gaps-in = 7; + gaps-out = 7 * 2; + active-opacity = 0.95; + inactive-opacity = 0.92; + blur = true; + border-size = 2; + animation-speed = "fast"; # "fast" | "medium" | "slow" + + bar = { + position = "top"; # "top" | "bottom" + transparent = true; + transparentButtons = false; + floating = true; + }; + + colors = { + base00 = "000000"; # 000000 ---- + base01 = "231a40"; # 231a40 --- + base02 = "432d59"; # 432d59 -- + base03 = "593380"; # 593380 - + base04 = "00ff00"; # 7b43bf + + base05 = "b08ae6"; # b08ae6 ++ + base06 = "9045e6"; # 9045e6 +++ + base07 = "a366ff"; # a366ff ++++ + base08 = "a82ee6"; # a82ee6 red + base09 = "bb66cc"; # bb66cc orange + base0A = "f29df2"; # f29df2 yellow + base0B = "4595e6"; # 41d9bF green + base0C = "40dfff"; # 40dfff aqua/cyan + base0D = "4136d9"; # 326ee6 blue + base0E = "7e5ce6"; # 7e5ce6 purple + base0F = "a886bf"; # a886bf brown + }; + + fonts = { + sizes = { + applications = 12; + desktop = 12; + popups = 12; + terminal = 10; + }; + }; + }; + }; +}