Compare commits
1 Commits
6a6a371256
...
docs-frame
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be4cd657c9 |
@@ -34,7 +34,6 @@ from typing import Any
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.services.modules import (
|
||||
CategoryInfo,
|
||||
ModuleManifest,
|
||||
)
|
||||
|
||||
# Get environment variables
|
||||
@@ -103,7 +102,7 @@ def render_option(
|
||||
read_only = option.get("readOnly")
|
||||
|
||||
res = f"""
|
||||
{"#" * level} {sanitize(name) if short_head is None else sanitize(short_head)} {"{: #" + sanitize_anchor(name) + "}" if level > 1 else ""}
|
||||
{"#" * level} {sanitize(name) if short_head is None else sanitize(short_head)}
|
||||
|
||||
"""
|
||||
|
||||
@@ -130,14 +129,12 @@ def render_option(
|
||||
"""
|
||||
example = option.get("example", {}).get("text")
|
||||
if example:
|
||||
example_indented = join_lines_with_indentation(example.split("\n"))
|
||||
res += f"""
|
||||
|
||||
???+ example
|
||||
```nix title="example"
|
||||
{example}
|
||||
```
|
||||
|
||||
```nix
|
||||
{example_indented}
|
||||
```
|
||||
"""
|
||||
if option.get("relatedPackages"):
|
||||
res += f"""
|
||||
@@ -154,7 +151,7 @@ def render_option(
|
||||
source_path = source_path.split(",")[0]
|
||||
|
||||
res += f"""
|
||||
:simple-git: Declared in: [{name}]({source_path})
|
||||
📃 Declared in: [{name}]({source_path})
|
||||
"""
|
||||
res += "\n\n"
|
||||
|
||||
@@ -224,7 +221,7 @@ def produce_clan_core_docs() -> None:
|
||||
indexfile = f"{module_name}/index.md"
|
||||
core_outputs[indexfile] = module_header(module_name) + clan_core_descr
|
||||
|
||||
core_outputs[indexfile] += """!!! info "Submodules"\n"""
|
||||
core_outputs[indexfile] += """:::note[Submodules]"\n"""
|
||||
|
||||
for submodule_name, split_options in split.items():
|
||||
root = options_to_tree(split_options)
|
||||
@@ -320,10 +317,11 @@ Each `clanService`:
|
||||
* Can define **roles** (e.g., `client`, `server`)
|
||||
* Uses **`inventory.instances`** to configure where and how it is deployed
|
||||
|
||||
!!! Note
|
||||
`clanServices` are part of Clan's next-generation service model and are intended to replace `clanModules`.
|
||||
:::note
|
||||
`clanServices` are part of Clan's next-generation service model and are intended to replace `clanModules`.
|
||||
|
||||
See [Migration Guide](../../guides/migrations/migrate-inventory-services.md) for help on migrating.
|
||||
See [Migration Guide](../../guides/migrations/migrate-inventory-services.md) for help on migrating.
|
||||
:::
|
||||
|
||||
Learn how to use `clanServices` in practice in the [Using clanServices guide](../../guides/inventory/clanServices.md).
|
||||
"""
|
||||
@@ -339,15 +337,20 @@ Learn how to use `clanServices` in practice in the [Using clanServices guide](..
|
||||
if module_name in ["internet", "tor"]:
|
||||
continue
|
||||
|
||||
output = f"# {module_name}\n\n"
|
||||
output = f"""---
|
||||
title: {module_name}
|
||||
description: {module_info["manifest"]["description"]}
|
||||
---
|
||||
|
||||
"""
|
||||
# output += f"`clan.modules.{module_name}`\n"
|
||||
output += f"*{module_info['manifest']['description']}*\n"
|
||||
|
||||
# output += "## Categories\n\n"
|
||||
output += render_categories(
|
||||
module_info["manifest"]["categories"],
|
||||
ModuleManifest.categories_info(),
|
||||
)
|
||||
# output += render_categories(
|
||||
# module_info["manifest"]["categories"],
|
||||
# ModuleManifest.categories_info(),
|
||||
# )
|
||||
|
||||
output += f"{module_info['manifest']['readme']}\n"
|
||||
|
||||
@@ -417,10 +420,11 @@ This document describes the structure and configurable attributes of a `clan.ser
|
||||
|
||||
Typically needed by module authors to define roles, behavior and metadata for distributed services.
|
||||
|
||||
!!! Note
|
||||
This is not a user-facing documentation, but rather meant as a reference for *module authors*
|
||||
:::note
|
||||
This is not a user-facing documentation, but rather meant as a reference for *module authors*
|
||||
|
||||
See: [clanService Authoring Guide](../../guides/services/community.md)
|
||||
See: [clanService Authoring Guide](../../guides/services/community.md)
|
||||
:::
|
||||
"""
|
||||
# Inventory options are already included under the clan attribute
|
||||
# We just omitted them in the clan docs, because we want a separate output for the inventory model
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
Services provided by the community
|
||||
---
|
||||
title: Services provided by the community
|
||||
---
|
||||
|
||||
!!! tip "Add your own!"
|
||||
|
||||
Have you built a service or a tool for? Open a PR adding a link to this page!
|
||||
:::tip[Add your own!]
|
||||
Have you built a service or a tool for? Open a PR adding a link to this page!
|
||||
:::
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ Just like with Nix you could specify a remote url or path to the flake containin
|
||||
|
||||
`clan flakes create --template=github:owner/repo#foo`
|
||||
|
||||
!!! Note "Implementation Note"
|
||||
Not all features of Nix's attribute selection are currently matched.
|
||||
There are minor differences in case of unexpected behavior please create an [issue](https://git.clan.lol/clan/clan-core/issues/new)
|
||||
:::note
|
||||
Not all features of Nix's attribute selection are currently matched.
|
||||
There are minor differences in case of unexpected behavior please create an [issue](https://git.clan.lol/clan/clan-core/issues/new)
|
||||
:::
|
||||
@@ -6,8 +6,9 @@ This section contains the architecture decisions that have been reviewed and gen
|
||||
|
||||
> An architecture decision record (ADR) is a document that captures an important architecture decision made along with its context and consequences.
|
||||
|
||||
!!! Note
|
||||
For further reading about adr's we recommend [architecture-decision-record](https://github.com/joelparkerhenderson/architecture-decision-record)
|
||||
:::note
|
||||
For further reading about adr's we recommend [architecture-decision-record](https://github.com/joelparkerhenderson/architecture-decision-record)
|
||||
:::
|
||||
|
||||
## Crafting a new ADR
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Here are some methods for debugging and testing the clan-cli
|
||||
|
||||
To streamline your development process, I suggest not installing `clan-cli`. Instead, clone the `clan-core` repository and add `clan-core/pkgs/clan-cli/bin` to your PATH to use the checked-out version directly.
|
||||
|
||||
!!! Note
|
||||
:::Note
|
||||
After cloning, navigate to `clan-core/pkgs/clan-cli` and execute `direnv allow` to activate the devshell. This will set up a symlink to nixpkgs at a specific location; without it, `clan-cli` won't function correctly.
|
||||
|
||||
With this setup, you can easily use [breakpoint()](https://docs.python.org/3/library/pdb.html) to inspect the application's internal state as needed.
|
||||
@@ -26,7 +26,7 @@ pkgs.mkShell {
|
||||
|
||||
## Debugging nixos-anywhere
|
||||
|
||||
If you encounter a bug in a complex shell script such as `nixos-anywhere`, start by replacing the `nixos-anywhere` command with a local checkout of the project, look in the [contribution](./CONTRIBUTING.md) section for an example.
|
||||
If you encounter a bug in a complex shell script such as `nixos-anywhere`, start by replacing the `nixos-anywhere` command with a local checkout of the project, look in the [contribution](./CONTRIBUTING.md) section for an example.
|
||||
|
||||
## The Debug Flag
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
This guide provides an example setup for a single-disk ZFS system with native encryption, accessible for decryption remotely.
|
||||
|
||||
!!! Warning
|
||||
:::warning
|
||||
This configuration only applies to `systemd-boot` enabled systems and **requires** UEFI booting.
|
||||
|
||||
!!! Info "Secure Boot"
|
||||
:::Info "Secure Boot"
|
||||
This guide is compatible with systems that have [secure boot disabled](./secure-boot.md). If you encounter boot issues, check if secure boot needs to be disabled in your UEFI settings.
|
||||
|
||||
Replace the highlighted lines with your own disk-id.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
!!! Danger ":fontawesome-solid-road-barrier: Under Construction :fontawesome-solid-road-barrier:"
|
||||
:::Danger ":fontawesome-solid-road-barrier: Under Construction :fontawesome-solid-road-barrier:"
|
||||
Currently under construction use with caution
|
||||
|
||||
:fontawesome-solid-road-barrier: :fontawesome-solid-road-barrier: :fontawesome-solid-road-barrier:
|
||||
|
||||
@@ -41,7 +41,7 @@ See the complete [list](../inventory/autoincludes.md) of auto-loaded files.
|
||||
|
||||
### Configuring a machine
|
||||
|
||||
!!! Note
|
||||
:::Note
|
||||
The option: `inventory.machines.<name>` is used to define metadata about the machine
|
||||
That includes for example `deploy.targethost` `machineClass` or `tags`
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ In Clan Services are multi-Host & role-based:
|
||||
|
||||
To learn more: [Guide about clanService](../inventory/clanServices.md)
|
||||
|
||||
!!! Important
|
||||
:::Important
|
||||
It is recommended to add at least one networking service such as `zerotier` that allows to reach all your clan machines from your setup computer across the globe.
|
||||
|
||||
## Configure a Zerotier Network (recommended)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# How to add users
|
||||
|
||||
!!! Note "Under construction"
|
||||
:::Note "Under construction"
|
||||
|
||||
The users concept of clan is not done yet. This guide outlines some solutions from our community.
|
||||
Defining users can be done in many different ways. We want to highlight two approaches:
|
||||
@@ -109,7 +109,7 @@ We can use this property of clan services to bind a nixosModule to the user, whi
|
||||
|
||||
1. Type `path` or `string`: Must point to a separate file. Inlining a module is not possible
|
||||
|
||||
!!! Note "This is inspiration"
|
||||
:::Note "This is inspiration"
|
||||
Our community might come up with better solutions soon.
|
||||
We are seeking contributions to improve this pattern if you have a nicer solution in mind.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ Available 'machine' templates
|
||||
|
||||
For this guide we will select the `single-disk` template, that uses `A simple ext4 disk with a single partition`.
|
||||
|
||||
!!! tip
|
||||
:::tip
|
||||
For advanced partitioning, see [Disko templates](https://github.com/nix-community/disko-templates) or [Disko examples](https://github.com/nix-community/disko/tree/master/example).
|
||||
You can also [contribute a disk template to clan core](https://docs.clan.lol/guides/disko-templates/community/)
|
||||
|
||||
@@ -58,15 +58,15 @@ Applied disk template 'single-disk' to machine 'jon'
|
||||
A disko.nix file should be created in `machines/jon`
|
||||
You can have a look and customize it if needed.
|
||||
|
||||
!!! Danger
|
||||
:::Danger
|
||||
Don't change the `disko.nix` after the machine is installed for the first time, unless you really know what you are doing.
|
||||
Changing disko configuration requires wiping and reinstalling the machine.
|
||||
|
||||
## Deploy the machine
|
||||
|
||||
**Finally deployment time!**
|
||||
**Finally deployment time!**
|
||||
|
||||
This command is destructive and will format your disk and install NixOS on it! It is equivalent to appending `--phases kexec,disko,install,reboot`.
|
||||
This command is destructive and will format your disk and install NixOS on it! It is equivalent to appending `--phases kexec,disko,install,reboot`.
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This guide will help you convert your existing NixOS configurations into a Clan.
|
||||
|
||||
!!! Warning
|
||||
:::Warning
|
||||
Migrating instead of starting new can be trickier and might lead to bugs or
|
||||
unexpected issues. We recommend reading the [Getting Started](./index.md) guide first.
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
To install Clan on physical machines, you need to use our custom installer image. This is necessary for proper installation and operation.
|
||||
|
||||
!!! note "Deploying to a Virtual Machine?"
|
||||
:::note "Deploying to a Virtual Machine?"
|
||||
If you're deploying to a virtual machine (VM), you can skip this section and go directly to the [Deploy Virtual Machine](./hardware-report-virtual.md) step. In this scenario, we automatically use [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) to replace the kernel during runtime.
|
||||
|
||||
??? info "Why nixos-anywhere Doesn't Work on Physical Hardware?"
|
||||
:::info "Why nixos-anywhere Doesn't Work on Physical Hardware?"
|
||||
nixos-anywhere relies on [kexec](https://wiki.archlinux.org/title/Kexec) to replace the running kernel with our custom one. This method often has compatibility issues with real hardware, especially systems with dedicated graphics cards like laptops and servers, leading to crashes and black screens.
|
||||
|
||||
??? info "Reasons for a Custom Install Image"
|
||||
:::info "Reasons for a Custom Install Image"
|
||||
Our custom install images are built to include essential tools like [nixos-facter](https://github.com/nix-community/nixos-facter) and support for [ZFS](https://wiki.archlinux.org/title/ZFS). They're also optimized to run on systems with as little as 1 GB of RAM, ensuring efficient performance even on lower-end hardware.
|
||||
|
||||
## Prerequisites
|
||||
@@ -36,7 +36,7 @@ To install Clan on physical machines, you need to use our custom installer image
|
||||
└─luks-f7600028-9d83-4967-84bc-dd2f498bc486 254:0 0 1,8T 0 crypt /nix/store
|
||||
```
|
||||
|
||||
!!! Info "In this case the USB device is `sdb`"
|
||||
:::Info "In this case the USB device is `sdb`"
|
||||
|
||||
3. Ensure all partitions on the drive are unmounted. Replace `sdb1` in the command below with your device identifier (like `sdc1`, etc.):
|
||||
|
||||
@@ -62,11 +62,11 @@ sudo umount /dev/sdb1
|
||||
--disk main /dev/sd<X> \
|
||||
flash-installer
|
||||
```
|
||||
!!! Note
|
||||
:::Note
|
||||
Replace `$HOME/.ssh/id_ed25519.pub` with a path to your SSH public key.
|
||||
Replace `/dev/sd<X>` with the drive path you want to flash
|
||||
|
||||
!!! Danger "Specifying the wrong device can lead to unrecoverable data loss."
|
||||
:::Danger "Specifying the wrong device can lead to unrecoverable data loss."
|
||||
|
||||
The `clan flash` utility will erase the disk. Make sure to specify the correct device
|
||||
|
||||
@@ -114,12 +114,12 @@ sudo umount /dev/sdb1
|
||||
wget https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-installer-aarch64-linux.iso
|
||||
```
|
||||
|
||||
!!! Note
|
||||
:::Note
|
||||
If you don't have `wget` installed, you can use `curl --progress-bar -OL <url>` instead.
|
||||
|
||||
## Flash the Installer to the USB Drive
|
||||
|
||||
!!! Danger "Specifying the wrong device can lead to unrecoverable data loss."
|
||||
:::Danger "Specifying the wrong device can lead to unrecoverable data loss."
|
||||
|
||||
The `dd` utility will erase the disk. Make sure to specify the correct device (`of=...`)
|
||||
|
||||
@@ -197,7 +197,7 @@ IPv4 address 192.168.188.50 (Your new local ip)
|
||||
|
||||
Press ++ctrl+d++ to exit `IWD`.
|
||||
|
||||
!!! Important
|
||||
:::Important
|
||||
Press ++ctrl+d++ **again** to update the displayed QR code and connection information.
|
||||
|
||||
You're all set up
|
||||
|
||||
@@ -22,7 +22,7 @@ nix flake check
|
||||
|
||||
This command helps ensure that your system configuration is correct and free from errors.
|
||||
|
||||
!!! Tip
|
||||
:::Tip
|
||||
|
||||
You can integrate this step into your [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) workflow to ensure that only valid Nix configurations are merged into your codebase.
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ This is an example of the booted installer.
|
||||
This password is autogenerated and meant to be easily typeable.
|
||||
3. See how to connect the installer medium to wlan [here](./create-installer.md).
|
||||
|
||||
!!!tip
|
||||
:::tip
|
||||
For easy sharing of deployment information via QR code, we highly recommend using [KDE Connect](https://apps.kde.org/de/kdeconnect/).
|
||||
|
||||
There are two ways to deploy your machine:
|
||||
|
||||
@@ -12,7 +12,7 @@ Now that you have created a machine, added some services, and set up secrets, th
|
||||
Clan supports any cloud machine if it is reachable via SSH and supports `kexec`.
|
||||
|
||||
|
||||
??? tip "NixOS can cause strange issues when booting in certain cloud environments."
|
||||
:::tip "NixOS can cause strange issues when booting in certain cloud environments."
|
||||
If on Linode: Make sure that the system uses "Direct Disk boot kernel" (found in the configuration panel)
|
||||
|
||||
|
||||
@@ -26,5 +26,5 @@ clan machines install [MACHINE] \
|
||||
--target-host myuser@<IP>
|
||||
```
|
||||
|
||||
!!! Warning
|
||||
:::Warning
|
||||
After running the above command, be aware that the SSH login user changes from `myuser` to `root`. For subsequent SSH connections to the target machine, use `root` as the login user. This change occurs because the system switches to the NixOS kernel using `kexec`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# :material-clock-fast: Getting Started
|
||||
|
||||
Ready to manage your fleet of machines?
|
||||
Ready to manage your fleet of machines?
|
||||
|
||||
We will create a declarative infrastructure using **clan**, **git**, and **nix flakes**.
|
||||
|
||||
@@ -13,7 +13,7 @@ Make sure you have the following:
|
||||
* 💻 **Administration Machine**: Run the setup commands from this machine.
|
||||
* 🛠️ **Nix**: The Nix package manager, installed on your administration machine.
|
||||
|
||||
??? info "**How to install Nix (Linux / MacOS / NixOS)**"
|
||||
:::info "**How to install Nix (Linux / MacOS / NixOS)**"
|
||||
|
||||
**On Linux or macOS:**
|
||||
|
||||
@@ -43,7 +43,7 @@ Make sure you have the following:
|
||||
## Create a New Clan
|
||||
|
||||
1. Navigate to your desired directory:
|
||||
|
||||
|
||||
```shellSession
|
||||
cd <your-directory>
|
||||
```
|
||||
@@ -75,8 +75,8 @@ my-clan/
|
||||
└── sops/
|
||||
```
|
||||
|
||||
!!! note "Templates"
|
||||
This is the structure for the `default` template.
|
||||
:::note "Templates"
|
||||
This is the structure for the `default` template.
|
||||
|
||||
Use `clan templates list` and `clan templates --help` for available templates & more. Keep in mind that the exact files may change as templates evolve.
|
||||
|
||||
@@ -121,7 +121,7 @@ Name: __CHANGE_ME__
|
||||
Description: None
|
||||
```
|
||||
|
||||
This confirms your setup is working correctly.
|
||||
This confirms your setup is working correctly.
|
||||
|
||||
You can now change the default name by editing the `meta.name` field in your `clan.nix` file.
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ If the machine does not have enough resources to run the NixOS **evaluation** or
|
||||
it is also possible to specify a `buildHost` instead.
|
||||
During an update, clan will ssh into the `buildHost` and run `nixos-rebuild` from there.
|
||||
|
||||
!!! Note
|
||||
:::Note
|
||||
The `buildHost` option should be set directly within your machine’s Nix configuration, **not** under `inventory.machines`.
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ clan machines update jon --build-host root@192.168.1.10
|
||||
clan machines update jon --build-host local
|
||||
```
|
||||
|
||||
!!! Note
|
||||
:::Note
|
||||
Make sure the CPU architecture of the `buildHost` matches that of the `targetHost`
|
||||
|
||||
For example, if deploying to a macOS machine with an ARM64-Darwin architecture, you need a second macOS machine with the same architecture to build it.
|
||||
|
||||
@@ -6,7 +6,7 @@ Clan automatically imports specific files from each machine directory and regist
|
||||
|
||||
Every folder under `machines/{machineName}` is automatically registered as a Clan machine.
|
||||
|
||||
!!! info "Files loaded automatically for each machine"
|
||||
:::info "Files loaded automatically for each machine"
|
||||
|
||||
The following files are detected and imported for every Clan machine:
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ The inventory logic will automatically derive the modules and configurations to
|
||||
|
||||
The following tutorial will walk through setting up a Backup service where the terms `Service` and `Role` will become more clear.
|
||||
|
||||
!!! example "Experimental status"
|
||||
:::example "Experimental status"
|
||||
The inventory implementation is not considered stable yet.
|
||||
We are actively soliciting feedback from users.
|
||||
|
||||
@@ -36,7 +36,7 @@ Each service can still be customized and configured according to the modules opt
|
||||
|
||||
### Setting up the Backup Service
|
||||
|
||||
!!! Example "Borgbackup Example"
|
||||
:::Example "Borgbackup Example"
|
||||
|
||||
To configure a service it needs to be added to the machine.
|
||||
It is required to assign the service (`borgbackup`) an arbitrary instance name. (`instance_1`)
|
||||
@@ -64,7 +64,7 @@ The inventory allows machines to set Tags
|
||||
|
||||
It is possible to add services to multiple machines via tags as shown
|
||||
|
||||
!!! Example "Tags Example"
|
||||
:::Example "Tags Example"
|
||||
|
||||
```{.nix hl_lines="5 8 18"}
|
||||
{
|
||||
@@ -93,11 +93,11 @@ It is possible to add services to multiple machines via tags as shown
|
||||
|
||||
### Multiple Service Instances
|
||||
|
||||
!!! danger "Important"
|
||||
:::danger "Important"
|
||||
Not all modules implement support for multiple instances yet.
|
||||
Multiple instance usage could create complexity, refer to each modules documentation, for intended usage.
|
||||
|
||||
!!! Example
|
||||
:::Example
|
||||
|
||||
In this example `backup_server` has role `client` and `server` in different instances.
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ The following table shows the migration status of each deprecated clanModule:
|
||||
|
||||
---
|
||||
|
||||
!!! Warning
|
||||
:::Warning
|
||||
* Old `clanModules` (`class = "nixos"`) are deprecated and will be removed in the near future.
|
||||
* `inventory.services` is no longer recommended; use `inventory.instances` instead.
|
||||
* Module authors should begin exporting service modules under the `clan.modules` attribute of their flake.
|
||||
|
||||
@@ -98,7 +98,7 @@ clan network overview
|
||||
|
||||
## Option 2: Manual targetHost (Bypasses Fallback!)
|
||||
|
||||
!!! warning
|
||||
:::warning
|
||||
Setting `targetHost` directly **disables all automatic networking and fallback**. Only use this if you need complete control and don't want Clan's intelligent connection management.
|
||||
|
||||
### Using Inventory (For Static Addresses)
|
||||
@@ -155,7 +155,7 @@ Use machine-level `targetHost` when you need to **interpolate values from the Ni
|
||||
- Building from multiple config values: `"${config.users.users.deploy.name}@${config.networking.hostName}"`
|
||||
- Any address that depends on evaluated NixOS configuration
|
||||
|
||||
!!! info "Key Difference"
|
||||
:::info "Key Difference"
|
||||
**Inventory-level** (`deploy.targetHost`) is evaluated immediately and works with static strings.
|
||||
**Machine-level** (`clan.core.networking.targetHost`) is evaluated after NixOS configuration and can access `config.*` values.
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ However, there are important considerations when using `nixos-rebuild` directly
|
||||
|
||||
## Important Considerations
|
||||
|
||||
!!! warning "Vars Must Be Uploaded First"
|
||||
:::warning "Vars Must Be Uploaded First"
|
||||
If your configuration uses clan vars, failing to run `clan vars upload` before `nixos-rebuild` will result in missing secrets and potentially broken services.
|
||||
|
||||
!!! info "Build Host Configuration"
|
||||
:::info "Build Host Configuration"
|
||||
Clan automatically handles build host configuration based on your machine settings.
|
||||
When using `nixos-rebuild` manually, you need to specify `--build-host` and `--target-host` options yourself.
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ Clan can also be configured to be used with other secret store [backends](../ref
|
||||
|
||||
To get started, you'll need to create **your admin keypair**.
|
||||
|
||||
!!! info
|
||||
:::info
|
||||
Don't worry — if you've already made one before, this step won't change or overwrite it.
|
||||
|
||||
```bash
|
||||
@@ -33,7 +33,7 @@ Generated age private key at '/home/joerg/.config/sops/age/keys.txt' for your us
|
||||
Also add your age public key to the repository with 'clan secrets users add YOUR_USER age1wkth7uhpkl555g40t8hjsysr20drq286netu8zptw50lmqz7j95sw2t3l7' (replace YOUR_USER with your actual username)
|
||||
```
|
||||
|
||||
!!! warning
|
||||
:::warning
|
||||
Make sure to keep a safe backup of the private key you've just created.
|
||||
If it's lost, you won't be able to get to your secrets anymore because they all need the admin key to be unlocked.
|
||||
|
||||
@@ -47,7 +47,7 @@ Alternatively, you can provide your [age] secret key as an environment variable
|
||||
using `SOPS_AGE_KEY_FILE`.
|
||||
For more information see the [SOPS] guide on [encrypting with age].
|
||||
|
||||
!!! note
|
||||
:::note
|
||||
It's safe to add any secrets created by the clan CLI and placed in your repository to version control systems like `git`.
|
||||
|
||||
## Add Your Public Key(s)
|
||||
@@ -68,7 +68,7 @@ sops/
|
||||
```
|
||||
If you followed the quickstart tutorial all necessary secrets are initialized at this point.
|
||||
|
||||
!!! note
|
||||
:::note
|
||||
You can add multiple age keys for a user by providing multiple `--age-key <your_public_key>` flags:
|
||||
|
||||
```console
|
||||
@@ -260,7 +260,7 @@ The secrets system conceptually knows two different entities:
|
||||
|
||||
**A machine** Can decrypt secrets that where encrypted specifically for that machine.
|
||||
|
||||
!!! Danger
|
||||
:::Danger
|
||||
**Always make sure at least one _User_ has access to a secret**. Otherwise you could lock yourself out from accessing the secret.
|
||||
|
||||
### Inherited implications
|
||||
@@ -275,8 +275,9 @@ By default clan uses [sops](https://github.com/getsops/sops) through [sops-nix](
|
||||
- **Machine key-pairs are auto-generated**: When a machine is created **no user-interaction is required** to setup public/private key-pairs.
|
||||
- **secrets are re-encrypted**: In case machines, users or groups are modified secrets get re-encrypted on demand.
|
||||
|
||||
!!! Important
|
||||
After revoking access to a secret you should also change the underlying secret. i.e. change the API key, or the password.
|
||||
:::caution
|
||||
After revoking access to a secret you should also change the underlying secret. i.e. change the API key, or the password.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ At the moment, NixOS/Clan does not support [Secure Boot](https://wiki.gentoo.org
|
||||
|
||||
- Restart your computer.
|
||||
- As your computer restarts, press the appropriate key to enter the UEFI/BIOS settings.
|
||||
??? tip "The key depends on your laptop or motherboard manufacturer. Click to see a reference list:"
|
||||
:::tip "The key depends on your laptop or motherboard manufacturer. Click to see a reference list:"
|
||||
|
||||
| Manufacturer | UEFI/BIOS Key(s) |
|
||||
|--------------------|---------------------------|
|
||||
@@ -31,8 +31,9 @@ At the moment, NixOS/Clan does not support [Secure Boot](https://wiki.gentoo.org
|
||||
| EVGA | `Del` |
|
||||
| Origin PC | `F2`, `Delete` |
|
||||
|
||||
!!! Note
|
||||
Pressing the key quickly and repeatedly is sometimes necessary to access the UEFI/BIOS menu, as the window to enter this mode is brief.
|
||||
:::note
|
||||
Pressing the key quickly and repeatedly is sometimes necessary to access the UEFI/BIOS menu, as the window to enter this mode is brief.
|
||||
:::
|
||||
|
||||
## Access Advanced Mode (Optional)
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ Next we need to define the settings and the behavior of these distinct roles.
|
||||
|
||||
## Using values from a NixOS machine inside the module
|
||||
|
||||
!!! Example "Experimental Status"
|
||||
:::Example "Experimental Status"
|
||||
This feature is experimental and should be used with care.
|
||||
|
||||
Sometimes a settings value depends on something within a machines `config`.
|
||||
@@ -174,7 +174,7 @@ The following example shows how to create a local instance of machine specific s
|
||||
}
|
||||
```
|
||||
|
||||
!!! Danger
|
||||
:::Danger
|
||||
`localSettings` are a local attribute. Other machines cannot access it.
|
||||
If calling extendSettings is done that doesn't change the original `settings` this means if a different machine tries to access i.e `roles.client.settings` it would *NOT* contain your changes.
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ Below is a [list of popular `age` plugins](https://github.com/FiloSottile/awesom
|
||||
|
||||
If you want to use `fido2 tokens` to encrypt your secret instead of the normal age secret key then you need to prefix your age secret key with the corresponding plugin name. In our case we want to use the `age-plugin-fido2-hmac` plugin so we replace `AGE-SECRET-KEY` with `AGE-PLUGIN-FIDO2-HMAC`.
|
||||
|
||||
??? tip
|
||||
:::tip
|
||||
- On Linux the age secret key is located at `~/.config/sops/age/keys.txt`
|
||||
- On macOS it is located at `/Users/admin/Library/Application Support/sops/age/keys.txt`
|
||||
|
||||
|
||||
21
tested-trappist/.gitignore
vendored
Normal file
21
tested-trappist/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# build output
|
||||
dist/
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
4
tested-trappist/.vscode/extensions.json
vendored
Normal file
4
tested-trappist/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
11
tested-trappist/.vscode/launch.json
vendored
Normal file
11
tested-trappist/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "./node_modules/.bin/astro dev",
|
||||
"name": "Development server",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
49
tested-trappist/README.md
Normal file
49
tested-trappist/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Starlight Starter Kit: Basics
|
||||
|
||||
[](https://starlight.astro.build)
|
||||
|
||||
```
|
||||
npm create astro@latest -- --template starlight
|
||||
```
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro + Starlight project, you'll see the following folders and files:
|
||||
|
||||
```
|
||||
.
|
||||
├── public/
|
||||
├── src/
|
||||
│ ├── assets/
|
||||
│ ├── content/
|
||||
│ │ └── docs/
|
||||
│ └── content.config.ts
|
||||
├── astro.config.mjs
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
|
||||
|
||||
Images can be added to `src/assets/` and embedded in Markdown with a relative link.
|
||||
|
||||
Static assets, like favicons, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
|
||||
58
tested-trappist/astro.config.mjs
Normal file
58
tested-trappist/astro.config.mjs
Normal file
@@ -0,0 +1,58 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from "astro/config";
|
||||
import starlightOpenAPI, { openAPISidebarGroups } from "starlight-openapi";
|
||||
import starlight from "@astrojs/starlight";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
starlight({
|
||||
title: "Clan",
|
||||
favicon: "/public/favicon.svg",
|
||||
// logo: { src: "/public/logo.svg", alt: "Clan Logo" },
|
||||
social: [
|
||||
{
|
||||
icon: "seti:git",
|
||||
label: "Git",
|
||||
href: "https://git.clan.lol/clan/clan-core",
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
// Generate the OpenAPI documentation pages.
|
||||
starlightOpenAPI([
|
||||
{
|
||||
base: "api",
|
||||
schema: "openapi.json",
|
||||
sidebar: {
|
||||
collapsed: true,
|
||||
label: "Internal API",
|
||||
},
|
||||
},
|
||||
]),
|
||||
],
|
||||
sidebar: [
|
||||
{
|
||||
label: "Getting Started",
|
||||
autogenerate: { directory: "getting-started" },
|
||||
collapsed: false,
|
||||
},
|
||||
{
|
||||
label: "Guides",
|
||||
autogenerate: { directory: "guides" },
|
||||
collapsed: false,
|
||||
},
|
||||
{
|
||||
label: "Reference",
|
||||
items: [
|
||||
{
|
||||
label: "Clan Services",
|
||||
autogenerate: { directory: "reference/clanServices" },
|
||||
collapsed: false,
|
||||
},
|
||||
...openAPISidebarGroups,
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
6754
tested-trappist/openapi.json
Normal file
6754
tested-trappist/openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
6571
tested-trappist/package-lock.json
generated
Normal file
6571
tested-trappist/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
tested-trappist/package.json
Normal file
18
tested-trappist/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "tested-trappist",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/starlight": "^0.35.3",
|
||||
"astro": "^5.6.1",
|
||||
"sharp": "^0.34.2",
|
||||
"starlight-openapi": "^0.20.0"
|
||||
}
|
||||
}
|
||||
1
tested-trappist/public/favicon.svg
Normal file
1
tested-trappist/public/favicon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="89" fill="currentColor"><g clip-path="url(#a)"><path d="M57.709 20.105H68.62c1.157 0 2.099-.94 2.099-2.095V9.632a2.1 2.1 0 0 0-2.099-2.095h-3.439c-1.111 0-2.014-.9-2.014-2.01V2.095A2.1 2.1 0 0 0 61.07 0H30.02a2.1 2.1 0 0 0-2.098 2.095v3.432c0 1.11-.903 2.01-2.014 2.01H22.47c-1.157 0-2.098.94-2.098 2.095v3.432c0 1.11-.903 2.01-2.014 2.01h-3.439c-1.157 0-2.099.94-2.099 2.094 0 0-.503-1.272-.503 22.493 0 21.247.503 19.38.503 19.38 0 1.156.942 2.096 2.1 2.096h3.438c1.111 0 2.014.9 2.014 2.01v3.517c0 1.109.902 2.01 2.013 2.01h3.524c1.111 0 2.014.9 2.014 2.01v3.432a2.1 2.1 0 0 0 2.098 2.094h30.211c1.157 0 2.099-.94 2.099-2.094v-3.433c0-1.11.902-2.01 2.013-2.01h5.557c1.158 0 2.099-.94 2.099-2.094v-9.984a2.1 2.1 0 0 0-2.099-2.095h-13.03c-1.157 0-2.098.94-2.098 2.095v5.044c0 1.11-.902 2.01-2.014 2.01H37.488c-1.111 0-2.013-.9-2.013-2.01v-5.11a2.1 2.1 0 0 0-2.099-2.094h-5.119c-1.111 0-1.739.163-2.014-2.01-.085-.698-.13-1.553-.196-2.695-.163-2.878-.307-1.723-.307-10.369 0-12.085.314-15.563.503-17.24.19-1.677.903-2.01 2.014-2.01h5.12c1.156 0 2.098-.94 2.098-2.094v-3.433c0-1.109.902-2.01 2.013-2.01h16.116c1.111 0 2.014.901 2.014 2.01v3.433c0 1.155.94 2.094 2.098 2.094zM18.626 73.757h-2.478a.87.87 0 0 1-.87-.868v-2.473c0-.96-.777-1.743-1.745-1.743H6.838c-.96 0-1.745.777-1.745 1.743v2.473a.87.87 0 0 1-.87.868H1.746c-.961 0-1.746.776-1.746 1.742v6.682c0 .96.778 1.742 1.746 1.742h2.477c.484 0 .87.392.87.868v2.473c0 .96.778 1.743 1.745 1.743h6.695c.961 0 1.746-.777 1.746-1.743v-2.473c0-.483.392-.868.87-.868h2.477c.961 0 1.746-.776 1.746-1.742v-6.682c0-.96-.778-1.742-1.746-1.742"/></g><defs><clipPath id="a"><path d="M0 0h72v89H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
1
tested-trappist/public/logo.svg
Normal file
1
tested-trappist/public/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="223" height="89" fill="currentColor"><g clip-path="url(#a)"><path d="M55.503 18.696h10.104a1.946 1.946 0 0 0 1.943-1.948v-7.79c0-1.075-.87-1.947-1.943-1.947h-3.186a1.863 1.863 0 0 1-1.866-1.87V1.947C60.555.872 59.685 0 58.612 0h-27.98a1.946 1.946 0 0 0-1.944 1.947v3.194c0 1.036-.832 1.87-1.865 1.87h-3.187a1.946 1.946 0 0 0-1.943 1.947v3.194c0 1.036-.832 1.87-1.866 1.87h-3.186a1.946 1.946 0 0 0-1.943 1.947s-.467 1.153-.467 23.253c0 19.763.467 21.913.467 21.913 0 1.075.87 1.948 1.943 1.948h3.186c1.034 0 1.866.833 1.866 1.87v3.271c0 1.036.831 1.87 1.865 1.87h3.265c1.033 0 1.865.833 1.865 1.87v3.193c0 1.075.87 1.948 1.943 1.948h27.981a1.946 1.946 0 0 0 1.943-1.948v-3.194c0-1.036.832-1.87 1.866-1.87h5.145a1.946 1.946 0 0 0 1.943-1.947v-9.285c0-1.075-.87-1.948-1.943-1.948H55.503a1.946 1.946 0 0 0-1.943 1.948v4.69c0 1.035-.832 1.869-1.866 1.869H37.55a1.863 1.863 0 0 1-1.866-1.87v-4.752c0-1.075-.87-1.947-1.943-1.947H29c-1.034 0-1.609.148-1.865-1.87-.078-.646-.125-1.44-.18-2.508-.147-2.68-.287-5.5-.287-13.539 0-11.24.288-16.81.466-18.369.18-1.558.832-1.87 1.866-1.87h4.741a1.946 1.946 0 0 0 1.943-1.947v-3.193c0-1.037.832-1.87 1.866-1.87h14.145c1.034 0 1.866.833 1.866 1.87v3.193c0 1.075.87 1.948 1.943 1.948M20.247 74.822h-2.293a.814.814 0 0 1-.808-.81v-2.298c0-.896-.723-1.62-1.617-1.62H9.327c-.894 0-1.617.724-1.617 1.62v2.298c0 .444-.365.81-.808.81H4.609c-.894 0-1.617.725-1.617 1.62v6.217c0 .896.723 1.62 1.617 1.62h2.293c.443 0 .808.366.808.81v2.299c0 .895.723 1.62 1.617 1.62h6.202c.894 0 1.617-.725 1.617-1.62v-2.299c0-.444.365-.81.808-.81h2.293c.894 0 1.617-.724 1.617-1.62v-6.216c0-.896-.723-1.62-1.617-1.62M221.135 35.04h-1.71a1.863 1.863 0 0 1-1.866-1.87v-3.272c0-1.036-.831-1.87-1.865-1.87h-3.265a1.863 1.863 0 0 1-1.865-1.87v-3.271c0-1.036-.832-1.87-1.865-1.87h-20.971a1.863 1.863 0 0 0-1.865 1.87v3.965c0 .514-.42.935-.933.935h-3.559c-.513 0-.84-.32-.933-.935l-.622-3.918c-.148-1.099-.676-1.777-1.788-1.777l-3.653-.14h-2.052a3.736 3.736 0 0 0-3.73 3.74V61.68a3.736 3.736 0 0 1-3.731 3.739h-8.394a1.863 1.863 0 0 1-1.866-1.87V36.714c0-11.825-7.461-18.813-22.556-18.813-13.718 0-20.325 5.04-21.203 14.443-.109 1.153.552 1.815 1.702 1.815l7.757.569c1.143.1 1.594-.554 1.811-1.652.77-3.74 4.174-5.827 9.933-5.827 7.081 0 10.042 3.358 10.042 9.076v3.014c0 1.036-.831 1.87-1.865 1.87l-.342-.024h-9.715c-15.421 0-22.984 5.983-22.984 17.956 0 3.802.778 7.058 2.254 9.738h-.59c-1.765-1.27-2.457-2.236-3.055-2.93-.256-.295-.653-.537-1.345-.537h-1.717l-5.993.008h-3.264a3.736 3.736 0 0 1-3.731-3.74V1.769C89.74.654 89.072 0 87.969 0H79.55c-1.034 0-1.865.732-1.865 1.768l-.024 54.304v13.554c0 4.13 3.343 7.479 7.462 7.479h50.84c8.448-.429 8.604-3.42 9.436-4.542.645 3.56 1.865 4.347 4.71 4.518 8.137.117 18.343.032 18.49.024h4.975c4.119 0 6.684-3.35 6.684-7.479l.777-27.264c0-1.036.832-1.87 1.866-1.87h2.021a1.56 1.56 0 0 0 1.554-1.558v-3.583c0-1.036.832-1.87 1.866-1.87h11.868a3.37 3.37 0 0 1 3.366 3.373v3.249c0 1.075.87 1.947 1.943 1.947h4.119c.513 0 .933.42.933.935v32.25c0 1.036.831 1.87 1.865 1.87h6.84a3.736 3.736 0 0 0 3.731-3.74V36.91c0-1.036-.832-1.87-1.866-1.87zM142.64 54.225c0 8.927-6.132 14.715-15.335 14.715-6.606 0-9.793-2.953-9.793-8.748 0-6.442 3.832-9.636 11.62-9.636h13.508v3.669"/></g><defs><clipPath id="a"><path d="M0 0h223v89H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
BIN
tested-trappist/src/assets/houston.webp
Normal file
BIN
tested-trappist/src/assets/houston.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
7
tested-trappist/src/content.config.ts
Normal file
7
tested-trappist/src/content.config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { defineCollection } from 'astro:content';
|
||||
import { docsLoader } from '@astrojs/starlight/loaders';
|
||||
import { docsSchema } from '@astrojs/starlight/schema';
|
||||
|
||||
export const collections = {
|
||||
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
|
||||
};
|
||||
128
tested-trappist/src/content/docs/getting-started/add-machines.md
Normal file
128
tested-trappist/src/content/docs/getting-started/add-machines.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: How to add machines
|
||||
---
|
||||
|
||||
Machines can be added using the following methods
|
||||
|
||||
- Create a file `machines/{machine_name}/configuration.nix` (See: [File Autoincludes](../inventory/autoincludes.md))
|
||||
- Imperative via cli command: `clan machines create`
|
||||
- Editing nix expressions in flake.nix See [`clan-core.lib.clan`](/options/?scope=Flake Options (clan.nix file))
|
||||
|
||||
See the complete [list](../inventory/autoincludes.md) of auto-loaded files.
|
||||
|
||||
## Create a machine
|
||||
|
||||
=== "clan.nix (declarative)"
|
||||
|
||||
```{.nix hl_lines="3-4"}
|
||||
{
|
||||
inventory.machines = {
|
||||
# Define a machine
|
||||
jon = { };
|
||||
};
|
||||
|
||||
# Additional NixOS configuration can be added here.
|
||||
# machines/jon/configuration.nix will be automatically imported.
|
||||
# See: https://docs.clan.lol/guides/more-machines/#automatic-registration
|
||||
machines = {
|
||||
# jon = { config, ... }: {
|
||||
# environment.systemPackages = [ pkgs.asciinema ];
|
||||
# };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
=== "CLI (imperative)"
|
||||
|
||||
```sh
|
||||
clan machines create jon
|
||||
```
|
||||
|
||||
The imperative command might create a machine folder in `machines/jon`
|
||||
And might persist information in `inventory.json`
|
||||
|
||||
### Configuring a machine
|
||||
|
||||
:::note
|
||||
The option: `inventory.machines.<name>` is used to define metadata about the machine
|
||||
That includes for example `deploy.targethost` `machineClass` or `tags`
|
||||
|
||||
The option: `machines.<name>` is used to add extra *nixosConfiguration* to a machine
|
||||
:::
|
||||
|
||||
Add the following to your `clan.nix` file for each machine.
|
||||
This example demonstrates what is needed based on a machine called `jon`:
|
||||
|
||||
```nix title="clan.nix" {3-6, 15-19}
|
||||
{
|
||||
inventory.machines = {
|
||||
jon = {
|
||||
# Define tags here (optional)
|
||||
tags = [ ]; # (1)
|
||||
};
|
||||
sara = {
|
||||
deploy.targetHost = "root@sara";
|
||||
tags = [ ];
|
||||
};
|
||||
};
|
||||
# Define additional nixosConfiguration here
|
||||
# Or in /machines/jon/configuration.nix (autoloaded)
|
||||
machines = {
|
||||
jon = { config, pkgs, ... }: {
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC..." # elided (2)
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
1. Tags can be used to automatically add this machine to services later on. - You dont need to set this now.
|
||||
2. Add your *ssh key* here - That will ensure you can always login to your machine via *ssh* in case something goes wrong.
|
||||
|
||||
### (Optional) Create a `configuration.nix`
|
||||
|
||||
```nix title="./machines/jon/configuration.nix"
|
||||
{
|
||||
imports = [
|
||||
# enables GNOME desktop (optional)
|
||||
../../modules/gnome.nix
|
||||
];
|
||||
|
||||
# Set nixosOptions here
|
||||
# Or import your own modules via 'imports'
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
### (Optional) Renaming a Machine
|
||||
|
||||
Older templates included static machine folders like `jon` and `sara`.
|
||||
If your setup still uses such static machines, you can rename a machine folder to match your own machine name:
|
||||
|
||||
```bash
|
||||
git mv ./machines/jon ./machines/<your-machine-name>
|
||||
```
|
||||
|
||||
Since your Clan configuration lives inside a Git repository, remember:
|
||||
|
||||
* Only files tracked by Git (`git add`) are recognized.
|
||||
* Whenever you add, rename, or remove files, run:
|
||||
|
||||
```bash
|
||||
git add ./machines/<your-machine-name>
|
||||
```
|
||||
|
||||
to stage the changes.
|
||||
|
||||
---
|
||||
|
||||
### (Optional) Removing a Machine
|
||||
|
||||
If you want to work with a single machine for now, you can remove other machine entries both from your `flake.nix` and from the `machines` directory. For example, to remove the machine `sara`:
|
||||
|
||||
```bash
|
||||
git rm -rf ./machines/sara
|
||||
```
|
||||
|
||||
Make sure to also remove or update any references to that machine in your `nix files` or `inventory.json` if you have any of that
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: How to add services
|
||||
---
|
||||
|
||||
A service in clan is a self-contained, reusable unit of system configuration that provides a specific piece of functionality across one or more machines.
|
||||
|
||||
Think of it as a recipe for running a tool — like automatic backups, VPN networking, monitoring, etc.
|
||||
|
||||
In Clan Services are multi-Host & role-based:
|
||||
|
||||
- Roles map machines to logical service responsibilities, enabling structured, clean deployments.
|
||||
|
||||
- You can use tags instead of explicit machine names.
|
||||
|
||||
To learn more: [Guide about clanService](../inventory/clanServices.md)
|
||||
|
||||
:::caution
|
||||
It is recommended to add at least one networking service such as `zerotier` that allows to reach all your clan machines from your setup computer across the globe.
|
||||
:::
|
||||
|
||||
## Configure a Zerotier Network (recommended)
|
||||
|
||||
```{.nix title="clan.nix" hl_lines="8-16"}
|
||||
{
|
||||
inventory.machines = {
|
||||
jon = { };
|
||||
sara = { };
|
||||
};
|
||||
|
||||
inventory.instances = {
|
||||
zerotier = { # (1)
|
||||
# Replace with the name (string) of your machine that you will use as zerotier-controller
|
||||
# See: https://docs.zerotier.com/controller/
|
||||
# Deploy this machine first to create the network secrets
|
||||
roles.controller.machines."jon" = { }; # (2)
|
||||
# Peers of the network
|
||||
# this line means 'all' clan machines will be 'peers'
|
||||
roles.peer.tags.all = { }; # (3)
|
||||
};
|
||||
};
|
||||
# ...
|
||||
# elided
|
||||
}
|
||||
```
|
||||
|
||||
1. See [reference/clanServices](../../reference/clanServices/index.md) for all available services and how to configure them.
|
||||
Or read [authoring/clanServices](../services/community.md) if you want to bring your own
|
||||
|
||||
2. Replace `__YOUR_CONTROLLER_` with the *name* of your machine.
|
||||
|
||||
3. This line will add all machines of your clan as `peer` to zerotier
|
||||
|
||||
## Adding more recommended defaults
|
||||
|
||||
Adding the following services is recommended for most users:
|
||||
|
||||
```{.nix title="clan.nix" hl_lines="7-14"}
|
||||
{
|
||||
inventory.machines = {
|
||||
jon = { };
|
||||
sara = { };
|
||||
};
|
||||
inventory.instances = {
|
||||
admin = { # (1)
|
||||
roles.default.tags.all = { };
|
||||
roles.default.settings = {
|
||||
allowedKeys = {
|
||||
"my-user" = "ssh-ed25519 AAAAC3N..."; # (2)
|
||||
};
|
||||
};
|
||||
};
|
||||
# ...
|
||||
# elided
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
1. The `admin` service will generate a **root-password** and **add your ssh-key** that allows for convienient administration.
|
||||
2. Equivalent to directly setting `authorizedKeys` like in [configuring a machine](./add-machines.md#configuring-a-machine)
|
||||
3. Adds `user = jon` as a user on all machines. Will create a `home` directory, and prompt for a password before deployment.
|
||||
131
tested-trappist/src/content/docs/getting-started/add-user.md
Normal file
131
tested-trappist/src/content/docs/getting-started/add-user.md
Normal file
@@ -0,0 +1,131 @@
|
||||
---
|
||||
title: How to add users
|
||||
---
|
||||
|
||||
:::note[Under construction]
|
||||
|
||||
The users concept of clan is not done yet. This guide outlines some solutions from our community.
|
||||
Defining users can be done in many different ways. We want to highlight two approaches:
|
||||
|
||||
- Using clan's [users](../../reference/clanServices/users.md) service.
|
||||
- Using a custom approach.
|
||||
:::
|
||||
|
||||
## Adding Users using the [users](../../reference/clanServices/users.md) service
|
||||
|
||||
To add a first *user* this guide will be leveraging two things:
|
||||
|
||||
- [clanServices](../../reference/clanServices/index.md): Allows to bind arbitrary logic to something we call an `ìnstance`.
|
||||
- [clanServices/users](../../reference/clanServices/users.md): Implements logic for adding a single user perInstance.
|
||||
|
||||
The example shows how to add a user called `jon`:
|
||||
|
||||
```{.nix title="clan.nix" hl_lines="7-21"}
|
||||
{
|
||||
inventory.machines = {
|
||||
jon = { };
|
||||
sara = { };
|
||||
};
|
||||
inventory.instances = {
|
||||
jon-user = { # (1)
|
||||
module.name = "users";
|
||||
|
||||
roles.default.tags.all = { }; # (2)
|
||||
|
||||
roles.default.settings = {
|
||||
user = "jon"; # (3)
|
||||
groups = [
|
||||
"wheel" # Allow using 'sudo'
|
||||
"networkmanager" # Allows to manage network connections.
|
||||
"video" # Allows to access video devices.
|
||||
"input" # Allows to access input devices.
|
||||
];
|
||||
};
|
||||
};
|
||||
# ...
|
||||
# elided
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
1. Add `user = jon` as a user on all machines. Will create a `home` directory, and prompt for a password before deployment.
|
||||
2. Add this user to `all` machines
|
||||
3. Define the `name` of the user to be `jon`
|
||||
|
||||
The `users` service creates a `/home/jon` directory, allows `jon` to sign in and will take care of the user's password.
|
||||
|
||||
For more information see [clanService/users](../../reference/clanServices/users.md)
|
||||
|
||||
## Using a custom approach
|
||||
|
||||
Some people like to define a `users` folder in their repository root.
|
||||
That allows to bind all user specific logic to a single place (`default.nix`)
|
||||
Which can be imported into individual machines to make the user available on that machine.
|
||||
|
||||
```bash
|
||||
.
|
||||
├── machines
|
||||
│ ├── jon
|
||||
# ......
|
||||
├── users
|
||||
│ ├── jon
|
||||
│ │ └── default.nix # <- a NixOS module; sets some options
|
||||
# ... ... ...
|
||||
```
|
||||
|
||||
## using [home-manager](https://github.com/nix-community/home-manager)
|
||||
|
||||
When using clan's `users` service it is possible to define extraModules.
|
||||
In fact this is always possible when using clan's services.
|
||||
|
||||
We can use this property of clan services to bind a nixosModule to the user, which configures home-manager.
|
||||
|
||||
```{.nix title="clan.nix" hl_lines="22"}
|
||||
{
|
||||
inventory.machines = {
|
||||
jon = { };
|
||||
sara = { };
|
||||
};
|
||||
inventory.instances = {
|
||||
jon-user = {
|
||||
module.name = "users";
|
||||
|
||||
roles.default.tags.all = { };
|
||||
|
||||
roles.default.settings = {
|
||||
user = "jon",
|
||||
groups = [
|
||||
"wheel"
|
||||
"networkmanager"
|
||||
"video"
|
||||
"input"
|
||||
];
|
||||
};
|
||||
|
||||
roles.default.extraModules = [ ./users/jon/home.nix ]; # (1)
|
||||
};
|
||||
# ...
|
||||
# elided
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
1. Type `path` or `string`: Must point to a separate file. Inlining a module is not possible
|
||||
|
||||
:::Note[This is inspiration]
|
||||
Our community might come up with better solutions soon.
|
||||
We are seeking contributions to improve this pattern if you have a nicer solution in mind.
|
||||
:::
|
||||
|
||||
```nix title="users/jon/home.nix"
|
||||
# NixOS module to import home-manager and the home-manager configuration of 'jon'
|
||||
{ self, ...}:
|
||||
{
|
||||
imports = [ self.inputs.home-manager.nixosModules.default ];
|
||||
home-manager.users.jon = {
|
||||
imports = [
|
||||
./home-configuration.nix
|
||||
];
|
||||
};
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: Configure Disk Config
|
||||
---
|
||||
|
||||
By default clan uses [disko](https://github.com/nix-community/disko) which allows for declarative disk partitioning.
|
||||
|
||||
To see what disk templates are available run:
|
||||
```{.shellSession hl_lines="10" .no-copy}
|
||||
$ clan templates list
|
||||
|
||||
Available 'clan' template
|
||||
├── <builtin>
|
||||
│ ├── default: Initialize a new clan flake
|
||||
│ ├── flake-parts: Flake-parts
|
||||
│ └── minimal: for clans managed via (G)UI
|
||||
Available 'disko' templates
|
||||
├── <builtin>
|
||||
│ └── single-disk: A simple ext4 disk with a single partition
|
||||
Available 'machine' templates
|
||||
├── <builtin>
|
||||
│ ├── demo-template: Demo machine for the CLAN project
|
||||
│ ├── flash-installer: Initialize a new flash-installer machine
|
||||
│ ├── new-machine: Initialize a new machine
|
||||
│ └── test-morph-template: Morph a machine
|
||||
```
|
||||
|
||||
|
||||
For this guide we will select the `single-disk` template, that uses `A simple ext4 disk with a single partition`.
|
||||
|
||||
:::tip
|
||||
For advanced partitioning, see [Disko templates](https://github.com/nix-community/disko-templates) or [Disko examples](https://github.com/nix-community/disko/tree/master/example).
|
||||
You can also [contribute a disk template to clan core](https://docs.clan.lol/guides/disko-templates/community/)
|
||||
:::
|
||||
|
||||
To setup a disk schema for a machine run
|
||||
|
||||
```bash
|
||||
clan templates apply disk single-disk jon --set mainDisk ""
|
||||
```
|
||||
|
||||
Which should fail and give the valid options for the specific hardware:
|
||||
|
||||
```shellSession
|
||||
Invalid value for placeholder mainDisk - Valid options:
|
||||
/dev/disk/by-id/nvme-WD_PC_SN740_SDDQNQD-512G-1201_232557804368
|
||||
```
|
||||
|
||||
Re-run the command with the correct disk:
|
||||
|
||||
```bash
|
||||
clan templates apply disk single-disk jon --set mainDisk "/dev/disk/by-id/nvme-WD_PC_SN740_SDDQNQD-512G-1201_232557804368"
|
||||
```
|
||||
|
||||
Should now be successful
|
||||
|
||||
```shellSession
|
||||
Applied disk template 'single-disk' to machine 'jon'
|
||||
```
|
||||
|
||||
A disko.nix file should be created in `machines/jon`
|
||||
You can have a look and customize it if needed.
|
||||
|
||||
:::danger
|
||||
Don't change the `disko.nix` after the machine is installed for the first time, unless you really know what you are doing.
|
||||
Changing disko configuration requires wiping and reinstalling the machine.
|
||||
:::
|
||||
|
||||
## Deploy the machine
|
||||
|
||||
**Finally deployment time!**
|
||||
|
||||
This command is destructive and will format your disk and install NixOS on it! It is equivalent to appending `--phases kexec,disko,install,reboot`.
|
||||
|
||||
|
||||
```bash
|
||||
clan machines install [MACHINE] --target-host root@<IP>
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
---
|
||||
title: Convert existing NixOS configurations
|
||||
---
|
||||
|
||||
This guide will help you convert your existing NixOS configurations into a Clan.
|
||||
|
||||
:::caution
|
||||
Migrating instead of starting new can be trickier and might lead to bugs or
|
||||
unexpected issues. We recommend reading the [Getting Started](./index.md) guide first.
|
||||
|
||||
Once you have a working setup and understand the concepts transfering your NixOS configurations over is easy.
|
||||
:::
|
||||
|
||||
## Back up your existing configuration
|
||||
|
||||
Before you start, it is strongly recommended to back up your existing
|
||||
configuration in any form you see fit. If you use version control to manage
|
||||
your configuration changes, it is also a good idea to follow the migration
|
||||
guide in a separte branch until everything works as expected.
|
||||
|
||||
## Starting Point
|
||||
|
||||
We assume you are already using NixOS flakes to manage your configuration. If
|
||||
not, migrate to a flake-based setup following the official [NixOS
|
||||
documentation](https://nix.dev/manual/nix/2.25/command-ref/new-cli/nix3-flake.html).
|
||||
The snippet below shows a common Nix flake. For this example we will assume you
|
||||
have have two hosts: **berlin** and **cologne**.
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
|
||||
outputs = { self, nixpkgs, ... }: {
|
||||
|
||||
nixosConfigurations = {
|
||||
|
||||
berlin = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [ ./machines/berlin/configuration.nix ];
|
||||
};
|
||||
|
||||
cologne = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [ ./machines/cologne/configuration.nix ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## 1. Add `clan-core` to `inputs`
|
||||
|
||||
Add `clan-core` to your flake as input.
|
||||
|
||||
```nix
|
||||
inputs.clan-core = {
|
||||
url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
|
||||
# Don't do this if your machines are on nixpkgs stable.
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Update Outputs
|
||||
|
||||
To be able to access our newly added dependency, it has to be added to the
|
||||
output parameters.
|
||||
|
||||
```diff
|
||||
- outputs = { self, nixpkgs, ... }:
|
||||
+ outputs = { self, nixpkgs, clan-core }:
|
||||
```
|
||||
|
||||
The existing `nixosConfigurations` output of your flake will be created by
|
||||
clan. In addition, a new `clanInternals` output will be added. Since both of
|
||||
these are provided by the output of `clan-core.lib.clan`, a common syntax is to use a
|
||||
`let...in` statement to create your clan and access it's parameters in the flake
|
||||
outputs.
|
||||
|
||||
For the provide flake example, your flake should now look like this:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
|
||||
inputs.clan-core = {
|
||||
url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, clan-core, ... }:
|
||||
let
|
||||
clan = clan-core.lib.clan {
|
||||
self = self; # this needs to point at the repository root
|
||||
specialArgs = {};
|
||||
meta.name = throw "Change me to something unique";
|
||||
|
||||
machines = {
|
||||
berlin = {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
imports = [ ./machines/berlin/configuration.nix ];
|
||||
};
|
||||
cologne = {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
imports = [ ./machines/cologne/configuration.nix ];
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit (clan.config) nixosConfigurations nixosModules clanInternals;
|
||||
clan = clan.config;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
✅ Et voilà! Your existing hosts are now part of a clan.
|
||||
|
||||
Existing Nix tooling
|
||||
should still work as normal. To check that you didn't make any errors, run `nix
|
||||
flake show` and verify both hosts are still recognized as if nothing had
|
||||
changed. You should also see the new `clan` output.
|
||||
|
||||
```
|
||||
❯ nix flake show
|
||||
git+file:///my-nixos-config
|
||||
├───clan: unknown
|
||||
└───nixosConfigurations
|
||||
├───berlin: NixOS configuration
|
||||
└───cologne: NixOS configuration
|
||||
```
|
||||
|
||||
Of course you can also rebuild your configuration using `nixos-rebuild` and
|
||||
veryify everything still works.
|
||||
|
||||
## 3. Add `clan-cli` to your `devShells`
|
||||
|
||||
At this point Clan is set up, but you can't use the CLI yet. To do so, it is
|
||||
recommended to expose it via a `devShell` in your flake. It is also possible to
|
||||
install it any other way you would install a package in Nix, but using a
|
||||
developtment shell ensures the CLI's version will always be in sync with your
|
||||
configuration.
|
||||
|
||||
A minimal example is provided below, add it to your flake outputs.
|
||||
|
||||
```nix
|
||||
devShells."x86_64-linux".default = nixpkgs.legacyPackages."x86_64-linux".mkShell {
|
||||
packages = [ clan-core.packages."x86_64-linux".clan-cli ];
|
||||
}
|
||||
```
|
||||
|
||||
To use the CLI, execute `nix develop` in the directory of your flake. The
|
||||
resulting shell, provides you with the `clan` CLI tool. Since you will be using
|
||||
it every time you interact with Clan, it is recommended to set up
|
||||
[direnv](https://direnv.net/).
|
||||
|
||||
Verify everything works as expected by running `clan machines list`.
|
||||
|
||||
```
|
||||
❯ nix develop
|
||||
[user@host:~/my-nixos-config]$ clan machines list
|
||||
berlin
|
||||
cologne
|
||||
```
|
||||
|
||||
## Specify Targets
|
||||
|
||||
Clan needs to know where it can reach your hosts. For testing purpose set
|
||||
`clan.core.networking.targetHost` to the machines adress or hostname.
|
||||
|
||||
```nix
|
||||
# machines/berlin/configuration.nix
|
||||
{
|
||||
clan.core.networking.targetHost = "123.4.56.78";
|
||||
}
|
||||
```
|
||||
|
||||
See our guide on for properly [configuring machines networking](../networking/networking.md)
|
||||
|
||||
## Next Steps
|
||||
|
||||
You are now fully set up. Use the CLI to manage your hosts or proceed to
|
||||
configure further services. At this point you should be able to run commands
|
||||
like `clan machines update berlin` to deploy a host.
|
||||
@@ -0,0 +1,217 @@
|
||||
---
|
||||
title: USB Installer Image for Physical Machines
|
||||
---
|
||||
|
||||
To install Clan on physical machines, you need to use our custom installer image. This is necessary for proper installation and operation.
|
||||
|
||||
:::note[Deploying to a Virtual Machine?]
|
||||
If you're deploying to a virtual machine (VM), you can skip this section and go directly to the [Deploy Virtual Machine](./hardware-report-virtual.md) step. In this scenario, we automatically use [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) to replace the kernel during runtime.
|
||||
:::
|
||||
|
||||
:::tip[Why nixos-anywhere Doesn't Work on Physical Hardware?]
|
||||
nixos-anywhere relies on [kexec](https://wiki.archlinux.org/title/Kexec) to replace the running kernel with our custom one. This method often has compatibility issues with real hardware, especially systems with dedicated graphics cards like laptops and servers, leading to crashes and black screens.
|
||||
:::
|
||||
|
||||
:::tip[Reasons for a Custom Install Image]
|
||||
Our custom install images are built to include essential tools like [nixos-facter](https://github.com/nix-community/nixos-facter) and support for [ZFS](https://wiki.archlinux.org/title/ZFS). They're also optimized to run on systems with as little as 1 GB of RAM, ensuring efficient performance even on lower-end hardware.
|
||||
:::
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [x] A free USB Drive with at least 1.5GB (All data on it will be lost)
|
||||
- [x] Linux/NixOS Machine with Internet
|
||||
|
||||
## Identify the USB Flash Drive
|
||||
|
||||
1. Insert your USB flash drive into your computer.
|
||||
|
||||
2. Identify your flash drive with `lsblk`:
|
||||
|
||||
```shellSession
|
||||
lsblk
|
||||
```
|
||||
|
||||
```{.shellSession hl_lines="2" .no-copy}
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
sdb 8:0 1 117,2G 0 disk
|
||||
└─sdb1 8:1 1 117,2G 0 part /run/media/qubasa/INTENSO
|
||||
nvme0n1 259:0 0 1,8T 0 disk
|
||||
├─nvme0n1p1 259:1 0 512M 0 part /boot
|
||||
└─nvme0n1p2 259:2 0 1,8T 0 part
|
||||
└─luks-f7600028-9d83-4967-84bc-dd2f498bc486 254:0 0 1,8T 0 crypt /nix/store
|
||||
```
|
||||
|
||||
:::tip
|
||||
In this case the USB device is `sdb`
|
||||
:::
|
||||
|
||||
3. Ensure all partitions on the drive are unmounted. Replace `sdb1` in the command below with your device identifier (like `sdc1`, etc.):
|
||||
|
||||
```shellSession
|
||||
sudo umount /dev/sdb1
|
||||
```
|
||||
|
||||
## Installer
|
||||
|
||||
=== "**Linux OS**"
|
||||
**Create a Custom Installer**
|
||||
|
||||
We recommend to build your own installer because of the following reasons:
|
||||
|
||||
- Include your ssh public keys into the image that allows passwordless ssh connection later on.
|
||||
- Set your preferred language and keymap
|
||||
|
||||
```bash
|
||||
clan flash write --flake https://git.clan.lol/clan/clan-core/archive/main.tar.gz \
|
||||
--ssh-pubkey $HOME/.ssh/id_ed25519.pub \
|
||||
--keymap us \
|
||||
--language en_US.UTF-8 \
|
||||
--disk main /dev/sd<X> \
|
||||
flash-installer
|
||||
```
|
||||
:::note
|
||||
Replace `$HOME/.ssh/id_ed25519.pub` with a path to your SSH public key.
|
||||
Replace `/dev/sd<X>` with the drive path you want to flash
|
||||
:::
|
||||
|
||||
:::danger
|
||||
Specifying the wrong device can lead to unrecoverable data loss.
|
||||
|
||||
The `clan flash` utility will erase the disk. Make sure to specify the correct device
|
||||
:::
|
||||
|
||||
- **SSH-Pubkey Option**
|
||||
|
||||
To add an ssh public key into the installer image append the option:
|
||||
```
|
||||
--ssh-pubkey <pubkey_path>
|
||||
```
|
||||
If you do not have an ssh key yet, you can generate one with `ssh-keygen -t ed25519` command.
|
||||
This ssh key will be installed into the root user.
|
||||
|
||||
- **Connect to the installer**
|
||||
|
||||
On boot, the installer will display on-screen the IP address it received from the network.
|
||||
If you need to configure Wi-Fi first, refer to the next section.
|
||||
If Multicast-DNS (Avahi) is enabled on your own machine, you can also access the installer using the `flash-installer.local` address.
|
||||
|
||||
- **List Keymaps**
|
||||
|
||||
You can get a list of all keymaps with the following command:
|
||||
```
|
||||
clan flash list keymaps
|
||||
```
|
||||
|
||||
- **List Languages**
|
||||
|
||||
You can get a list of all languages with the following command:
|
||||
```
|
||||
clan flash list languages
|
||||
```
|
||||
|
||||
=== "**Other OS**"
|
||||
**Download Generic Installer**
|
||||
|
||||
For x86_64:
|
||||
|
||||
```shellSession
|
||||
wget https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-installer-x86_64-linux.iso
|
||||
```
|
||||
|
||||
For generic arm64 / aarch64 (probably does not work on raspberry pi...)
|
||||
|
||||
```shellSession
|
||||
wget https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-installer-aarch64-linux.iso
|
||||
```
|
||||
|
||||
:::note
|
||||
If you don't have `wget` installed, you can use `curl --progress-bar -OL <url>` instead.
|
||||
:::
|
||||
|
||||
## Flash the Installer to the USB Drive
|
||||
|
||||
:::danger
|
||||
Specifying the wrong device can lead to unrecoverable data loss.
|
||||
|
||||
The `dd` utility will erase the disk. Make sure to specify the correct device (`of=...`)
|
||||
|
||||
For example if the USB device is `sdb` use `of=/dev/sdb` (on macOS it will look more like /dev/disk1)
|
||||
:::
|
||||
|
||||
On Linux, you can use the `lsblk` utility to identify the correct disko
|
||||
|
||||
```
|
||||
lsblk --output NAME,ID-LINK,FSTYPE,SIZE,MOUNTPOINT
|
||||
```
|
||||
|
||||
On macos use `diskutil`:
|
||||
|
||||
```
|
||||
diskutil list
|
||||
```
|
||||
|
||||
Use the `dd` utility to write the NixOS installer image to your USB drive.
|
||||
Replace `/dev/sd<X>` with your external drive from above.
|
||||
|
||||
```shellSession
|
||||
sudo dd bs=4M conv=fsync status=progress if=./nixos-installer-x86_64-linux.iso of=/dev/sd<X>
|
||||
```
|
||||
|
||||
- **Connect to the installer
|
||||
|
||||
On boot, the installer will display on-screen the IP address it received from the network.
|
||||
If you need to configure Wi-Fi first, refer to the next section.
|
||||
If Multicast-DNS (Avahi) is enabled on your own machine, you can also access the installer using the `nixos-installer.local` address.
|
||||
|
||||
## Boot From USB Stick
|
||||
|
||||
- To use, boot from the Clan USB drive with **secure boot turned off**. For step by step instructions go to [Disabling Secure Boot](../secure-boot.md)
|
||||
|
||||
## (Optional) Connect to Wifi Manually
|
||||
|
||||
If you don't have access via LAN the Installer offers support for connecting via Wifi.
|
||||
|
||||
```shellSession
|
||||
iwctl
|
||||
```
|
||||
|
||||
This will enter `iwd`
|
||||
|
||||
```{.console, .no-copy}
|
||||
[iwd]#
|
||||
```
|
||||
|
||||
Now run the following command to connect to your Wifi:
|
||||
|
||||
```{.shellSession .no-copy}
|
||||
# Identify your network device.
|
||||
device list
|
||||
|
||||
# Replace 'wlan0' with your wireless device name
|
||||
# Find your Wifi SSID.
|
||||
station wlan0 scan
|
||||
station wlan0 get-networks
|
||||
|
||||
# Replace your_ssid with the Wifi SSID
|
||||
# Connect to your network.
|
||||
station wlan0 connect your_ssid
|
||||
|
||||
# Verify you are connected
|
||||
station wlan0 show
|
||||
```
|
||||
|
||||
If the connection was successful you should see something like this:
|
||||
|
||||
```{.console, .no-copy}
|
||||
State connected
|
||||
Connected network FRITZ!Box (Your router device)
|
||||
IPv4 address 192.168.188.50 (Your new local ip)
|
||||
```
|
||||
|
||||
Press ++ctrl+d++ to exit `IWD`.
|
||||
|
||||
:::caution
|
||||
Press ++ctrl+d++ **again** to update the displayed QR code and connection information.
|
||||
:::
|
||||
|
||||
You're all set up
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: Generate Facts and Vars
|
||||
---
|
||||
|
||||
Typically, this step is handled automatically when a machine is deployed. However, to enable the use of `nix flake check` with your configuration, it must be completed manually beforehand.
|
||||
|
||||
Currently, generating all the necessary facts requires two separate commands. This is due to the coexistence of two parallel secret management solutions:
|
||||
the newer, recommended version (`clan vars`) and the older version (`clan facts`) that we are slowly phasing out.
|
||||
|
||||
To generate both facts and vars, execute the following commands:
|
||||
|
||||
```sh
|
||||
clan facts generate && clan vars generate
|
||||
```
|
||||
|
||||
|
||||
### Check Configuration
|
||||
|
||||
Validate your configuration by running:
|
||||
|
||||
```bash
|
||||
nix flake check
|
||||
```
|
||||
|
||||
This command helps ensure that your system configuration is correct and free from errors.
|
||||
|
||||
:::tip
|
||||
|
||||
You can integrate this step into your [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) workflow to ensure that only valid Nix configurations are merged into your codebase.
|
||||
:::
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: Installing a Physical Machine
|
||||
next: { link: "/getting-started/choose-disk", label: Configure Disk }
|
||||
---
|
||||
|
||||
Now that you have created a machine, added some services, and set up secrets, this guide will walk you through how to deploy it.
|
||||
|
||||
|
||||
### Prerequisites
|
||||
- [x] RAM > 2GB
|
||||
- [x] **Two Computers**: You need one computer that you're getting ready (we'll call this the Target Computer) and another one to set it up from (we'll call this the Setup Computer). Make sure both can talk to each other over the network using SSH.
|
||||
- [x] **Machine configuration**: See our basic [adding and configuring machine guide](./add-machines.md)
|
||||
- [x] **Initialized secrets**: See [secrets](../secrets.md) for how to initialize your secrets.
|
||||
- [x] **USB Flash Drive**: See [Clan Installer](./create-installer.md)
|
||||
|
||||
|
||||
### Image Installer
|
||||
This method makes use of the [image installers](./create-installer.md).
|
||||
|
||||
The installer will randomly generate a password and local addresses on boot, then run a SSH server with these preconfigured.
|
||||
The installer shows its deployment relevant information in two formats, a text form, as well as a QR code.
|
||||
|
||||
|
||||
This is an example of the booted installer.
|
||||
|
||||
```{ .bash .annotate .no-copy .nohighlight}
|
||||
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ┌───────────────────────────┐ │
|
||||
│ │███████████████████████████│ # This is the QR Code (1) │
|
||||
│ │██ ▄▄▄▄▄ █▀▄█▀█▀▄█ ▄▄▄▄▄ ██│ │
|
||||
│ │██ █ █ █▀▄▄▄█ ▀█ █ █ ██│ │
|
||||
│ │██ █▄▄▄█ █▀▄ ▀▄▄▄█ █▄▄▄█ ██│ │
|
||||
│ │██▄▄▄▄▄▄▄█▄▀ ▀▄▀▄█▄▄▄▄▄▄▄██│ │
|
||||
│ │███▀▀▀ █▄▄█ ▀▄ ▄▀▄█ ███│ │
|
||||
│ │██▄██▄▄█▄▄▀▀██▄▀ ▄▄▄ ▄▀█▀██│ │
|
||||
│ │██ ▄▄▄▄▄ █▄▄▄▄ █ █▄█ █▀ ███│ │
|
||||
│ │██ █ █ █ █ █ ▄▄▄ ▄▀▀ ██│ │
|
||||
│ │██ █▄▄▄█ █ ▄ ▄ ▄ ▀█ ▄███│ │
|
||||
│ │██▄▄▄▄▄▄▄█▄▄▄▄▄▄█▄▄▄▄▄█▄███│ │
|
||||
│ │███████████████████████████│ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │Root password: cheesy-capital-unwell # password (2) │ │
|
||||
│ │Local network addresses: │ │
|
||||
│ │enp1s0 UP 192.168.178.169/24 metric 1024 fe80::21e:6ff:fe45:3c92/64 │ │
|
||||
│ │enp2s0 DOWN │ │
|
||||
│ │wlan0 DOWN # connect to wlan (3) │ │
|
||||
│ │Onion address: 6evxy5yhzytwpnhc2vpscrbti3iktxdhpnf6yim6bbs25p4v6beemzyd.onion │ │
|
||||
│ │Multicast DNS: nixos-installer.local │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ Press 'Ctrl-C' for console access │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
1. This is not an actual QR code, because it is displayed rather poorly on text sites.
|
||||
This would be the actual content of this specific QR code prettified:
|
||||
```json
|
||||
{
|
||||
"pass": "cheesy-capital-unwell",
|
||||
"tor": "6evxy5yhzytwpnhc2vpscrbti3iktxdhpnf6yim6bbs25p4v6beemzyd.onion",
|
||||
"addrs": [
|
||||
"2001:9e8:347:ca00:21e:6ff:fe45:3c92"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
To generate the actual QR code, that would be displayed use:
|
||||
```shellSession
|
||||
echo '{"pass":"cheesy-capital-unwell","tor":"6evxy5yhzytwpnhc2vpscrbti3iktxdhpnf6yim6bbs25p4v6beemzyd.onion","addrs":["2001:9e8:347:ca00:21e:6ff:fe45:3c92"]}' | nix run nixpkgs#qrencode -- -s 2 -m 2 -t utf8
|
||||
```
|
||||
2. The root password for the installer medium.
|
||||
This password is autogenerated and meant to be easily typeable.
|
||||
3. See how to connect the installer medium to wlan [here](./create-installer.md).
|
||||
|
||||
:::tip
|
||||
For easy sharing of deployment information via QR code, we highly recommend using [KDE Connect](https://apps.kde.org/de/kdeconnect/).
|
||||
:::
|
||||
|
||||
There are two ways to deploy your machine:
|
||||
|
||||
### Generating a Hardware Report
|
||||
|
||||
The following command will generate a hardware report with [nixos-facter](https://github.com/nix-community/nixos-facter) and writes it back into your machine folder. The `--phases kexec` flag makes sure we are not yet formatting anything, instead if the target system is not a NixOS machine it will use [kexec](https://wiki.archlinux.org/title/Kexec) to switch to a NixOS kernel.
|
||||
|
||||
=== "Password"
|
||||
**Password**
|
||||
|
||||
```terminal
|
||||
clan machines install [MACHINE] \
|
||||
--update-hardware-config nixos-facter \
|
||||
--phases kexec \
|
||||
--target-host root@192.168.178.169
|
||||
```
|
||||
|
||||
=== "QR Code"
|
||||
**QR Code**
|
||||
|
||||
**Using a JSON String or File Path**:
|
||||
|
||||
Copy the JSON string contained in the QR Code and provide its path or paste it directly:
|
||||
```terminal
|
||||
clan machines install [MACHINE] --json [JSON] \
|
||||
--update-hardware-config nixos-facter \
|
||||
--phases kexec
|
||||
```
|
||||
|
||||
**Using an Image Containing the QR Code**:
|
||||
|
||||
Provide the path to an image file containing the QR code displayed by the installer:
|
||||
```terminal
|
||||
clan machines install [MACHINE] --png [PATH] \
|
||||
--update-hardware-config nixos-facter \
|
||||
--phases kexec
|
||||
```
|
||||
|
||||
|
||||
If you are using our template `[MACHINE]` would be `jon`
|
||||
|
||||
[Next Step (Choose Disk Format)](./choose-disk.md){ .md-button .md-button--primary }
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Generate a VM Hardware Report
|
||||
---
|
||||
|
||||
Now that you have created a machine, added some services, and set up secrets, this guide will walk you through how to deploy it.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
- [x] RAM > 2GB
|
||||
- [x] **Two Computers**: You need one computer that you're getting ready (we'll call this the Target Computer) and another one to set it up from (we'll call this the Setup Computer). Make sure both can talk to each other over the network using SSH.
|
||||
- [x] **Machine configuration**: See our basic [adding and configuring machine guide](./add-machines.md)
|
||||
|
||||
|
||||
Clan supports any cloud machine if it is reachable via SSH and supports `kexec`.
|
||||
|
||||
|
||||
:::tip
|
||||
NixOS can cause strange issues when booting in certain cloud environments.
|
||||
|
||||
If on Linode: Make sure that the system uses "Direct Disk boot kernel" (found in the configuration panel)
|
||||
:::
|
||||
|
||||
|
||||
The following command will generate a hardware report with [nixos-facter](https://github.com/nix-community/nixos-facter) and writes it back into your machine folder. The `--phases kexec` flag makes sure we are not yet formatting anything, instead if the target system is not a NixOS machine it will use [kexec](https://wiki.archlinux.org/title/Kexec) to switch to a NixOS kernel.
|
||||
|
||||
|
||||
```terminal
|
||||
clan machines install [MACHINE] \
|
||||
--update-hardware-config nixos-facter \
|
||||
--phases kexec \
|
||||
--target-host myuser@<IP>
|
||||
```
|
||||
|
||||
:::caution
|
||||
After running the above command, be aware that the SSH login user changes from `myuser` to `root`. For subsequent SSH connections to the target machine, use `root` as the login user. This change occurs because the system switches to the NixOS kernel using `kexec`.
|
||||
:::
|
||||
133
tested-trappist/src/content/docs/getting-started/update.md
Normal file
133
tested-trappist/src/content/docs/getting-started/update.md
Normal file
@@ -0,0 +1,133 @@
|
||||
---
|
||||
title: Update Machines
|
||||
---
|
||||
|
||||
The Clan command line interface enables you to update machines remotely over SSH.
|
||||
In this guide we will teach you how to set a `targetHost` in Nix,
|
||||
and how to define a remote builder for your machine closures.
|
||||
|
||||
|
||||
## Setting `targetHost`
|
||||
|
||||
Set the machine’s `targetHost` to the reachable IP address of the new machine.
|
||||
This eliminates the need to specify `--target-host` in CLI commands.
|
||||
|
||||
```{.nix title="clan.nix" hl_lines="9"}
|
||||
{
|
||||
# Ensure this is unique among all clans you want to use.
|
||||
meta.name = "my-clan";
|
||||
|
||||
inventory.machines = {
|
||||
# Define machines here.
|
||||
# The machine name will be used as the hostname.
|
||||
jon = {
|
||||
deploy.targetHost = "root@192.168.192.4"; # (1)
|
||||
};
|
||||
};
|
||||
# [...]
|
||||
}
|
||||
```
|
||||
|
||||
The use of `root@` in the target address implies SSH access as the `root` user.
|
||||
Ensure that the root login is secured and only used when necessary.
|
||||
|
||||
## Multiple Target Hosts
|
||||
|
||||
You can now experiment with a new interface that allows you to define multiple `targetHost` addresses for different VPNs. Learn more and try it out in our [networking guide](../networking/networking.md).
|
||||
|
||||
## Updating Machine Configurations
|
||||
|
||||
Execute the following command to update the specified machine:
|
||||
|
||||
```bash
|
||||
clan machines update jon
|
||||
```
|
||||
|
||||
All machines can be updated simultaneously by omitting the machine name:
|
||||
|
||||
```bash
|
||||
clan machines update
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
The following options are only needed for special cases, such as limited resources, mixed environments, or private flakes.
|
||||
|
||||
### Setting `buildHost`
|
||||
|
||||
If the machine does not have enough resources to run the NixOS **evaluation** or **build** itself,
|
||||
it is also possible to specify a `buildHost` instead.
|
||||
During an update, clan will ssh into the `buildHost` and run `nixos-rebuild` from there.
|
||||
|
||||
:::note
|
||||
The `buildHost` option should be set directly within your machine’s Nix configuration, **not** under `inventory.machines`.
|
||||
:::
|
||||
|
||||
|
||||
```{.nix hl_lines="5" .no-copy}
|
||||
clan {
|
||||
# ...
|
||||
machines = {
|
||||
"jon" = {
|
||||
clan.core.networking.buildHost = "root@<host_or_ip>";
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### Overriding configuration with CLI flags
|
||||
|
||||
`buildHost` / `targetHost`, and other network settings can be temporarily overridden for a single command:
|
||||
|
||||
For the full list of flags refer to the [Clan CLI](../../reference/cli/index.md)
|
||||
|
||||
```bash
|
||||
# Build on a remote host
|
||||
clan machines update jon --build-host root@192.168.1.10
|
||||
|
||||
# Build locally (useful for testing or when the target has limited resources)
|
||||
clan machines update jon --build-host local
|
||||
```
|
||||
|
||||
:::note
|
||||
Make sure the CPU architecture of the `buildHost` matches that of the `targetHost`
|
||||
|
||||
For example, if deploying to a macOS machine with an ARM64-Darwin architecture, you need a second macOS machine with the same architecture to build it.
|
||||
:::
|
||||
|
||||
|
||||
### Excluding a machine from `clan machine update`
|
||||
|
||||
To exclude machines from being updated when running `clan machines update` without any machines specified,
|
||||
one can set the `clan.deployment.requireExplicitUpdate` option to true:
|
||||
|
||||
```{.nix hl_lines="5" .no-copy}
|
||||
clan {
|
||||
# ...
|
||||
machines = {
|
||||
"jon" = {
|
||||
clan.deployment.requireExplicitUpdate = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
This is useful for machines that are not always online or are not part of the regular update cycle.
|
||||
|
||||
### Uploading Flake Inputs
|
||||
|
||||
When updating remote machines, flake inputs are usually fetched by the build host.
|
||||
However, if flake inputs require authentication (e.g., private repositories),
|
||||
|
||||
Use the `--upload-inputs` flag to upload all inputs from your local machine:
|
||||
|
||||
```bash
|
||||
clan machines update jon --upload-inputs
|
||||
```
|
||||
|
||||
This is particularly useful when:
|
||||
- The flake references private Git repositories
|
||||
- Authentication credentials are only available on local machine
|
||||
- The build host doesn't have access to certain network resources
|
||||
89
tested-trappist/src/content/docs/guides/vars/age-plugins.md
Normal file
89
tested-trappist/src/content/docs/guides/vars/age-plugins.md
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: Using Age Plugins with Clan Vars
|
||||
sidebar:
|
||||
order: 99
|
||||
---
|
||||
|
||||
This guide explains how to set up YubiKey and other plugins for `clan vars` secrets.
|
||||
|
||||
By default the `clan vars` subcommand uses the `age` encryption tool, which supports various plugins.
|
||||
|
||||
---
|
||||
|
||||
## Supported Age Plugins
|
||||
|
||||
Below is a [list of popular `age` plugins](https://github.com/FiloSottile/awesome-age?tab=readme-ov-file#plugins) you can use with Clan. (Last updated: **September 12, 2025**)
|
||||
|
||||
- ⭐️ [**age-plugin-yubikey**](https://github.com/str4d/age-plugin-yubikey): YubiKey (and other PIV tokens) plugin.
|
||||
- [**age-plugin-se**](https://github.com/remko/age-plugin-se): Apple Secure Enclave plugin.
|
||||
- 🧪 [**age-plugin-tpm**](https://github.com/Foxboron/age-plugin-tpm): TPM 2.0 plugin.
|
||||
- 🧪 [**age-plugin-tkey**](https://github.com/quite/age-plugin-tkey): Tillitis TKey plugin.
|
||||
[**age-plugin-trezor**](https://github.com/romanz/trezor-agent/blob/master/doc/README-age.md): Hardware wallet plugin (TREZOR, Ledger, etc.).
|
||||
- 🧪 [**age-plugin-sntrup761x25519**](https://github.com/keisentraut/age-plugin-sntrup761x25519): Post-quantum hybrid plugin (NTRU Prime + X25519).
|
||||
- 🧪 [**age-plugin-fido**](https://github.com/riastradh/age-plugin-fido): Prototype symmetric encryption plugin for FIDO2 keys.
|
||||
- 🧪 [**age-plugin-fido2-hmac**](https://github.com/olastor/age-plugin-fido2-hmac): FIDO2 plugin with PIN support.
|
||||
- 🧪 [**age-plugin-sss**](https://github.com/olastor/age-plugin-sss): Shamir's Secret Sharing (SSS) plugin.
|
||||
- 🧪 [**age-plugin-amnesia**](https://github.com/cedws/amnesia/blob/master/README.md#age-plugin-experimental): Adds Q&A-based identity wrapping.
|
||||
|
||||
> **Note:** Plugins marked with 🧪 are experimental. Plugins marked with ⭐️ are official.
|
||||
|
||||
---
|
||||
|
||||
## Using Plugin-Generated Keys
|
||||
|
||||
If you want to use `fido2 tokens` to encrypt your secret instead of the normal age secret key then you need to prefix your age secret key with the corresponding plugin name. In our case we want to use the `age-plugin-fido2-hmac` plugin so we replace `AGE-SECRET-KEY` with `AGE-PLUGIN-FIDO2-HMAC`.
|
||||
|
||||
:::tip
|
||||
- On Linux the age secret key is located at `~/.config/sops/age/keys.txt`
|
||||
- On macOS it is located at `/Users/admin/Library/Application Support/sops/age/keys.txt`
|
||||
|
||||
**Before**:
|
||||
```hl_lines="2"
|
||||
# public key: age1zdy49ek6z60q9r34vf5mmzkx6u43pr9haqdh5lqdg7fh5tpwlfwqea356l
|
||||
AGE-SECRET-KEY-1QQPQZRFR7ZZ2WCV...
|
||||
```
|
||||
|
||||
**After**:
|
||||
```hl_lines="2"
|
||||
# public key: age1zdy49ek6z60q9r34vf5mmzkx6u43pr9haqdh5lqdg7fh5tpwlfwqea356l
|
||||
AGE-PLUGIN-FIDO2-HMAC-1QQPQZRFR7ZZ2WCV...
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Configuring Plugins in `flake.nix`
|
||||
|
||||
To use `age` plugins with Clan, you need to configure them in your `flake.nix` file. Here’s an example:
|
||||
|
||||
```nix title="flake.nix"
|
||||
{
|
||||
inputs.clan-core.url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
|
||||
inputs.nixpkgs.follows = "clan-core/nixpkgs";
|
||||
|
||||
outputs = { self, clan-core, ... }:
|
||||
let
|
||||
# Define Clan configuration
|
||||
clan = clan-core.lib.clan {
|
||||
inherit self;
|
||||
|
||||
meta.name = "myclan";
|
||||
|
||||
# Add YubiKey and FIDO2 HMAC plugins
|
||||
# Note: Plugins must be available in nixpkgs.
|
||||
secrets.age.plugins = [
|
||||
"age-plugin-yubikey"
|
||||
"age-plugin-fido2-hmac"
|
||||
];
|
||||
|
||||
machines = {
|
||||
# Machine configurations (elided for brevity)
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit (clan) nixosConfigurations nixosModules clanInternals;
|
||||
|
||||
# Additional configurations (elided for brevity)
|
||||
};
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,292 @@
|
||||
---
|
||||
title: Advanced Vars Examples
|
||||
---
|
||||
|
||||
This guide demonstrates complex, real-world patterns for the vars system.
|
||||
|
||||
|
||||
## Certificate Authority with Intermediate Certificates
|
||||
|
||||
This example shows how to create a complete certificate authority with root and intermediate certificates using dependencies.
|
||||
|
||||
```nix
|
||||
{
|
||||
# Generate root CA (not deployed to machines)
|
||||
clan.core.vars.generators.root-ca = {
|
||||
files."ca.key" = {
|
||||
secret = true;
|
||||
deploy = false; # Keep root key offline
|
||||
};
|
||||
files."ca.crt".secret = false;
|
||||
runtimeInputs = [ pkgs.step-cli ];
|
||||
script = ''
|
||||
step certificate create "My Root CA" \
|
||||
$out/ca.crt $out/ca.key \
|
||||
--profile root-ca \
|
||||
--no-password \
|
||||
--not-after 87600h
|
||||
'';
|
||||
};
|
||||
|
||||
# Generate intermediate key
|
||||
clan.core.vars.generators.intermediate-key = {
|
||||
files."intermediate.key" = {
|
||||
secret = true;
|
||||
deploy = true;
|
||||
};
|
||||
runtimeInputs = [ pkgs.step-cli ];
|
||||
script = ''
|
||||
step crypto keypair \
|
||||
$out/intermediate.pub \
|
||||
$out/intermediate.key \
|
||||
--no-password
|
||||
'';
|
||||
};
|
||||
|
||||
# Generate intermediate certificate signed by root
|
||||
clan.core.vars.generators.intermediate-cert = {
|
||||
files."intermediate.crt".secret = false;
|
||||
dependencies = [
|
||||
"root-ca"
|
||||
"intermediate-key"
|
||||
];
|
||||
runtimeInputs = [ pkgs.step-cli ];
|
||||
script = ''
|
||||
step certificate create "My Intermediate CA" \
|
||||
$out/intermediate.crt \
|
||||
$in/intermediate-key/intermediate.key \
|
||||
--ca $in/root-ca/ca.crt \
|
||||
--ca-key $in/root-ca/ca.key \
|
||||
--profile intermediate-ca \
|
||||
--not-after 8760h \
|
||||
--no-password
|
||||
'';
|
||||
};
|
||||
|
||||
# Use the certificates in services
|
||||
services.nginx.virtualHosts."example.com" = {
|
||||
sslCertificate = config.clan.core.vars.generators.intermediate-cert.files."intermediate.crt".value;
|
||||
sslCertificateKey = config.clan.core.vars.generators.intermediate-key.files."intermediate.key".path;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Multi-Service Secret Sharing
|
||||
|
||||
Generate secrets that multiple services can use:
|
||||
|
||||
```nix
|
||||
{
|
||||
# Generate database credentials
|
||||
clan.core.vars.generators.database = {
|
||||
share = true; # Share across machines
|
||||
files."password" = { };
|
||||
files."connection-string" = { };
|
||||
prompts.dbname = {
|
||||
description = "Database name";
|
||||
type = "line";
|
||||
};
|
||||
script = ''
|
||||
# Generate password
|
||||
tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32 > $out/password
|
||||
|
||||
# Create connection string
|
||||
echo "postgresql://app:$(cat $out/password)@localhost/$prompts/dbname" \
|
||||
> $out/connection-string
|
||||
'';
|
||||
};
|
||||
|
||||
# PostgreSQL uses the password
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
initialScript = pkgs.writeText "init.sql" ''
|
||||
CREATE USER app WITH PASSWORD '${
|
||||
builtins.readFile config.clan.core.vars.generators.database.files."password".path
|
||||
}';
|
||||
'';
|
||||
};
|
||||
|
||||
# Application uses the connection string
|
||||
systemd.services.myapp = {
|
||||
serviceConfig.EnvironmentFile =
|
||||
config.clan.core.vars.generators.database.files."connection-string".path;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## SSH Host Keys with Certificates
|
||||
|
||||
Generate SSH host keys and sign them with a CA:
|
||||
|
||||
```nix
|
||||
{
|
||||
# SSH Certificate Authority (shared)
|
||||
clan.core.vars.generators.ssh-ca = {
|
||||
share = true;
|
||||
files."ca" = { secret = true; deploy = false; };
|
||||
files."ca.pub" = { secret = false; };
|
||||
runtimeInputs = [ pkgs.openssh ];
|
||||
script = ''
|
||||
ssh-keygen -t ed25519 -N "" -f $out/ca
|
||||
mv $out/ca.pub $out/ca.pub
|
||||
'';
|
||||
};
|
||||
|
||||
# Host-specific SSH keys
|
||||
clan.core.vars.generators.ssh-host = {
|
||||
files."ssh_host_ed25519_key" = {
|
||||
secret = true;
|
||||
owner = "root";
|
||||
group = "root";
|
||||
mode = "0600";
|
||||
};
|
||||
files."ssh_host_ed25519_key.pub" = { secret = false; };
|
||||
files."ssh_host_ed25519_key-cert.pub" = { secret = false; };
|
||||
dependencies = [ "ssh-ca" ];
|
||||
runtimeInputs = [ pkgs.openssh ];
|
||||
script = ''
|
||||
# Generate host key
|
||||
ssh-keygen -t ed25519 -N "" -f $out/ssh_host_ed25519_key
|
||||
|
||||
# Sign with CA
|
||||
ssh-keygen -s $in/ssh-ca/ca \
|
||||
-I "host:${config.networking.hostName}" \
|
||||
-h \
|
||||
-V -5m:+365d \
|
||||
$out/ssh_host_ed25519_key.pub
|
||||
'';
|
||||
};
|
||||
|
||||
# Configure SSH to use the generated keys
|
||||
services.openssh = {
|
||||
hostKeys = [{
|
||||
path = config.clan.core.vars.generators.ssh-host.files."ssh_host_ed25519_key".path;
|
||||
type = "ed25519";
|
||||
}];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## WireGuard Mesh Network
|
||||
|
||||
Create a WireGuard configuration with pre-shared keys:
|
||||
|
||||
```nix
|
||||
{
|
||||
# Generate WireGuard keys for this host
|
||||
clan.core.vars.generators.wireguard = {
|
||||
files."privatekey" = {
|
||||
secret = true;
|
||||
owner = "systemd-network";
|
||||
mode = "0400";
|
||||
};
|
||||
files."publickey" = { secret = false; };
|
||||
files."preshared" = { secret = true; };
|
||||
runtimeInputs = [ pkgs.wireguard-tools ];
|
||||
script = ''
|
||||
# Generate key pair
|
||||
wg genkey > $out/privatekey
|
||||
wg pubkey < $out/privatekey > $out/publickey
|
||||
|
||||
# Generate pre-shared key
|
||||
wg genpsk > $out/preshared
|
||||
'';
|
||||
};
|
||||
|
||||
# Configure WireGuard
|
||||
networking.wireguard.interfaces.wg0 = {
|
||||
privateKeyFile = config.clan.core.vars.generators.wireguard.files."privatekey".path;
|
||||
|
||||
peers = [{
|
||||
publicKey = "peer-public-key-here";
|
||||
presharedKeyFile = config.clan.core.vars.generators.wireguard.files."preshared".path;
|
||||
allowedIPs = [ "10.0.0.2/32" ];
|
||||
}];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Conditional Generation Based on Machine Role
|
||||
|
||||
Generate different secrets based on machine configuration:
|
||||
|
||||
```nix
|
||||
{
|
||||
clan.core.vars.generators = lib.mkMerge [
|
||||
# All machines get basic auth
|
||||
{
|
||||
basic-auth = {
|
||||
files."htpasswd" = { };
|
||||
prompts.username = {
|
||||
description = "Username for basic auth";
|
||||
type = "line";
|
||||
};
|
||||
prompts.password = {
|
||||
description = "Password for basic auth";
|
||||
type = "hidden";
|
||||
};
|
||||
runtimeInputs = [ pkgs.apacheHttpd ];
|
||||
script = ''
|
||||
htpasswd -nbB "$prompts/username" "$prompts/password" > $out/htpasswd
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
# Only servers get API tokens
|
||||
(lib.mkIf config.services.myapi.enable {
|
||||
api-tokens = {
|
||||
files."admin-token" = { };
|
||||
files."readonly-token" = { };
|
||||
runtimeInputs = [ pkgs.openssl ];
|
||||
script = ''
|
||||
openssl rand -hex 32 > $out/admin-token
|
||||
openssl rand -hex 16 > $out/readonly-token
|
||||
'';
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Backup Encryption Keys
|
||||
|
||||
Generate and manage backup encryption keys:
|
||||
|
||||
```nix
|
||||
{
|
||||
clan.core.vars.generators.backup = {
|
||||
share = true; # Same key for all backup sources
|
||||
files."encryption.key" = {
|
||||
secret = true;
|
||||
deploy = true;
|
||||
};
|
||||
files."encryption.pub" = { secret = false; };
|
||||
runtimeInputs = [ pkgs.age ];
|
||||
script = ''
|
||||
# Generate age key pair
|
||||
age-keygen -o $out/encryption.key 2>/dev/null
|
||||
|
||||
# Extract public key
|
||||
grep "public key:" $out/encryption.key | cut -d: -f2 | tr -d ' ' \
|
||||
> $out/encryption.pub
|
||||
'';
|
||||
};
|
||||
|
||||
# Use in backup service
|
||||
services.borgbackup.jobs.system = {
|
||||
encryption = {
|
||||
mode = "repokey-blake2";
|
||||
passCommand = "cat ${config.clan.core.vars.generators.backup.files."encryption.key".path}";
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Tips and Best Practices
|
||||
|
||||
1. **Use dependencies** to build complex multi-stage generations
|
||||
2. **Share generators** when the same secret is needed across machines
|
||||
3. **Set appropriate permissions** for service-specific secrets
|
||||
4. **Use prompts** for user-specific values that shouldn't be generated
|
||||
5. **Combine secret and non-secret files** in the same generator when they're related
|
||||
6. **Use conditional generation** with `lib.mkIf` for role-specific secrets
|
||||
142
tested-trappist/src/content/docs/guides/vars/vars-backend.md
Normal file
142
tested-trappist/src/content/docs/guides/vars/vars-backend.md
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: Diving deeper
|
||||
---
|
||||
|
||||
The `clan vars` subcommand is a powerful tool for managing machine-specific variables in a declarative and reproducible way. This guide will walk you through its usage, from setting up a generator to sharing and updating variables across machines.
|
||||
|
||||
For a detailed API reference, see the [vars module documentation](../../reference/clan.core/vars.md).
|
||||
|
||||
In this guide, you will learn how to:
|
||||
|
||||
1. Declare a `generator` in the machine's NixOS configuration.
|
||||
2. Inspect the status of variables using the Clan CLI.
|
||||
3. Generate variables interactively.
|
||||
4. Observe the changes made to your repository.
|
||||
5. Update the machine configuration.
|
||||
6. Share the root password between multiple machines.
|
||||
7. Change the root password when needed.
|
||||
|
||||
By the end of this guide, you will have a clear understanding of how to use `clan vars` to manage sensitive data, such as passwords, in a secure and efficient manner.
|
||||
|
||||
|
||||
## Declare the generator
|
||||
|
||||
In this example, a `vars` `generator` is used to:
|
||||
|
||||
- prompt the user for the password
|
||||
- run the required `mkpasswd` command to generate the hash
|
||||
- store the hash in a file
|
||||
- expose the file path to the nixos configuration
|
||||
|
||||
Create a new nix file `root-password.nix` with the following content and import it into your `configuration.nix`
|
||||
```nix
|
||||
{config, pkgs, ...}: {
|
||||
|
||||
clan.core.vars.generators.root-password = {
|
||||
# prompt the user for a password
|
||||
# (`password-input` being an arbitrary name)
|
||||
prompts.password-input.description = "the root user's password";
|
||||
prompts.password-input.type = "hidden";
|
||||
# don't store the prompted password itself
|
||||
prompts.password-input.persist = false;
|
||||
# define an output file for storing the hash
|
||||
files.password-hash.secret = false;
|
||||
# define the logic for generating the hash
|
||||
script = ''
|
||||
cat $prompts/password-input | mkpasswd -m sha-512 > $out/password-hash
|
||||
'';
|
||||
# the tools required by the script
|
||||
runtimeInputs = [ pkgs.mkpasswd ];
|
||||
};
|
||||
|
||||
# ensure users are immutable (otherwise the following config might be ignored)
|
||||
users.mutableUsers = false;
|
||||
# set the root password to the file containing the hash
|
||||
users.users.root.hashedPasswordFile =
|
||||
# clan will make sure, this path exists
|
||||
config.clan.core.vars.generators.root-password.files.password-hash.path;
|
||||
}
|
||||
```
|
||||
|
||||
## Inspect the status
|
||||
|
||||
Executing `clan vars list`, you should see the following:
|
||||
```shellSession
|
||||
$ clan vars list my_machine
|
||||
root-password/password-hash: <not set>
|
||||
```
|
||||
|
||||
...indicating that the value `password-hash` for the generator `root-password` is not set yet.
|
||||
|
||||
## Generate the values
|
||||
|
||||
This step is not strictly necessary, as deploying the machine via `clan machines update` would trigger the generator as well.
|
||||
|
||||
To run the generator, execute `clan vars generate` for your machine
|
||||
```shellSession
|
||||
$ clan vars generate my_machine
|
||||
Enter the value for root-password/password-input (hidden):
|
||||
```
|
||||
|
||||
After entering the value, the updated status is reported:
|
||||
```shellSession
|
||||
Updated var root-password/password-hash
|
||||
old: <not set>
|
||||
new: $6$RMats/YMeypFtcYX$DUi...
|
||||
```
|
||||
|
||||
## Observe the changes
|
||||
|
||||
With the last step, a new file was created in your repository:
|
||||
`vars/per-machine/my-machine/root-password/password-hash/value`
|
||||
|
||||
If the repository is a git repository, a commit was created automatically:
|
||||
```shellSession
|
||||
$ git log -n1
|
||||
commit ... (HEAD -> master)
|
||||
Author: ...
|
||||
Date: ...
|
||||
|
||||
Update vars via generator root-password for machine grmpf-nix
|
||||
```
|
||||
|
||||
## Update the machine
|
||||
|
||||
```shell
|
||||
clan machines update my_machine
|
||||
```
|
||||
|
||||
## Share root password between machines
|
||||
|
||||
If we just imported the `root-password.nix` from above into more machines, clan would ask for a new password for each additional machine.
|
||||
|
||||
If the root password instead should only be entered once and shared across all machines, the generator defined above needs to be declared as `shared`, by adding `share = true` to it:
|
||||
```nix
|
||||
{config, pkgs, ...}: {
|
||||
clan.core.vars.generators.root-password = {
|
||||
share = true;
|
||||
# ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Importing that shared generator into each machine, will ensure that the password is only asked once the first machine gets updated and then re-used for all subsequent machines.
|
||||
|
||||
## Change the root password
|
||||
|
||||
Changing the password can be done via this command.
|
||||
Replace `my-machine` with your machine.
|
||||
If the password is shared, just pick any machine that has the generator declared.
|
||||
|
||||
```shellSession
|
||||
$ clan vars generate my-machine --generator root-password --regenerate
|
||||
...
|
||||
Enter the value for root-password/password-input (hidden):
|
||||
Input received. Processing...
|
||||
...
|
||||
Updated var root-password/password-hash
|
||||
old: $6$tb27m6EOdff.X9TM$19N...
|
||||
|
||||
new: $6$OyoQtDVzeemgh8EQ$zRK...
|
||||
```
|
||||
|
||||
125
tested-trappist/src/content/docs/guides/vars/vars-concepts.md
Normal file
125
tested-trappist/src/content/docs/guides/vars/vars-concepts.md
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: Understanding Clan Vars
|
||||
---
|
||||
|
||||
This guide explains the architecture and design principles behind the vars system.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The vars system provides a declarative, reproducible way to manage generated files (especially secrets) in NixOS configurations.
|
||||
|
||||
## Data Flow
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Generator Script] --> B[Output Files]
|
||||
C[User Prompts] --> A
|
||||
D[Dependencies] --> A
|
||||
B --> E[Secret Storage<br/>sops/password-store]
|
||||
B --> F[Nix Store<br/>public files]
|
||||
E --> G[Machine Deployment]
|
||||
F --> G
|
||||
```
|
||||
|
||||
## Key Design Principles
|
||||
|
||||
### 1. Declarative Generation
|
||||
|
||||
Unlike imperative secret management, vars are declared in your NixOS configuration and generated deterministically. This ensures reproducibility across deployments.
|
||||
|
||||
### 2. Separation of Concerns
|
||||
|
||||
- **Generation logic**: Defined in generator scripts
|
||||
- **Storage**: Handled by pluggable backends (sops, password-store, etc.)
|
||||
- **Deployment**: Managed by NixOS activation scripts
|
||||
- **Access control**: Enforced through file permissions and ownership
|
||||
|
||||
### 3. Composability Through Dependencies
|
||||
|
||||
Generators can depend on outputs from other generators, enabling complex workflows:
|
||||
|
||||
```nix
|
||||
# Dependencies create a directed acyclic graph (DAG)
|
||||
A → B → C
|
||||
↓
|
||||
D
|
||||
```
|
||||
|
||||
This allows building sophisticated systems like certificate authorities where intermediate certificates depend on root certificates.
|
||||
|
||||
### 4. Type Safety
|
||||
|
||||
The vars system distinguishes between:
|
||||
- **Secret files**: Only accessible via `.path`, deployed to `/run/secrets/`
|
||||
- **Public files**: Accessible via `.value`, stored in nix store
|
||||
|
||||
This prevents accidental exposure of secrets in the nix store.
|
||||
|
||||
## Storage Backend Architecture
|
||||
|
||||
The vars system uses pluggable storage backends:
|
||||
|
||||
- **sops** (default): Integrates with clan's existing sops encryption
|
||||
- **password-store**: For users already using pass
|
||||
|
||||
Each backend handles encryption/decryption transparently, allowing the same generator definitions to work across different security models.
|
||||
|
||||
## Timing and Lifecycle
|
||||
|
||||
### Generation Phases
|
||||
|
||||
1. **Pre-deployment**: `clan vars generate` creates vars before deployment
|
||||
2. **During deployment**: Missing vars are generated automatically
|
||||
3. **Regeneration**: Explicit regeneration with `--regenerate` flag
|
||||
|
||||
### The `neededFor` Option
|
||||
|
||||
Control when vars are available during system activation:
|
||||
|
||||
```nix
|
||||
files."early-secret" = {
|
||||
secret = true;
|
||||
neededFor = [ "users" "groups" ]; # Available early in activation
|
||||
};
|
||||
```
|
||||
|
||||
## Advanced Patterns
|
||||
|
||||
### Multi-Machine Coordination
|
||||
|
||||
The `share` option enables cross-machine secret sharing:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Shared Generator] --> B[Machine 1]
|
||||
A --> C[Machine 2]
|
||||
A --> D[Machine 3]
|
||||
```
|
||||
|
||||
This is useful for:
|
||||
- Shared certificate authorities
|
||||
- Mesh VPN pre-shared keys
|
||||
- Cluster join tokens
|
||||
|
||||
### Generator Composition
|
||||
|
||||
Complex systems can be built by composing simple generators:
|
||||
|
||||
```
|
||||
root-ca → intermediate-ca → service-cert
|
||||
↓
|
||||
ocsp-responder
|
||||
```
|
||||
|
||||
Each generator focuses on one task, making the system modular and testable.
|
||||
|
||||
## Key Advantages
|
||||
|
||||
Compared to manual secret management, vars provides:
|
||||
|
||||
- **Declarative configuration**: Define once, generate consistently
|
||||
- **Dependency management**: Build complex systems with generator dependencies
|
||||
- **Type safety**: Separate handling of secret and public files
|
||||
- **User prompts**: Gather input when needed
|
||||
- **Easy regeneration**: Update secrets with a single command
|
||||
|
||||
147
tested-trappist/src/content/docs/guides/vars/vars-overview.md
Normal file
147
tested-trappist/src/content/docs/guides/vars/vars-overview.md
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
title: Introduction to Vars
|
||||
---
|
||||
|
||||
The vars system is clan's declarative solution for managing generated files, secrets, and dynamic configuration in your NixOS deployments. It eliminates the manual steps of generating credentials, certificates, and other dynamic values by automating these processes within your infrastructure-as-code workflow.
|
||||
|
||||
## What Problems Does Vars Solve?
|
||||
|
||||
### Before Vars: Manual Secret Management
|
||||
|
||||
Traditional NixOS deployments require manual steps for secrets and generated files:
|
||||
|
||||
```bash
|
||||
# Generate password hash manually
|
||||
mkpasswd -m sha-512 > /tmp/root-password-hash
|
||||
# Copy hash into configuration
|
||||
users.users.root.hashedPasswordFile = "/tmp/root-password-hash";
|
||||
```
|
||||
|
||||
This approach has several problems:
|
||||
|
||||
- **Not reproducible**: Manual steps vary between team members
|
||||
|
||||
- **Hard to maintain**: Updating secrets requires remembering manual commands
|
||||
|
||||
- **Deployment friction**: Secrets must be managed outside of your configuration
|
||||
|
||||
- **Team collaboration issues**: Sharing credentials securely is complex
|
||||
|
||||
### After Vars: Declarative Generation
|
||||
|
||||
With vars, the same process becomes declarative and automated:
|
||||
|
||||
```nix
|
||||
clan.core.vars.generators.root-password = {
|
||||
prompts.password.description = "Root password";
|
||||
prompts.password.type = "hidden";
|
||||
files.hash.secret = false;
|
||||
script = "mkpasswd -m sha-512 < $prompts/password > $out/hash";
|
||||
runtimeInputs = [ pkgs.mkpasswd ];
|
||||
};
|
||||
|
||||
users.users.root.hashedPasswordFile =
|
||||
config.clan.core.vars.generators.root-password.files.hash.path;
|
||||
```
|
||||
|
||||
## Core Benefits
|
||||
|
||||
- **🔄 Reproducible**: Same inputs always produce the same outputs
|
||||
- **📝 Declarative**: Defined alongside your NixOS configuration
|
||||
- **🔐 Secure**: Automatic secret storage and encrypted deployment
|
||||
- **👥 Collaborative**: Built-in sharing for team environments
|
||||
- **🚀 Automated**: No manual intervention required for deployments
|
||||
- **🔗 Integrated**: Works seamlessly with clan's deployment workflow
|
||||
|
||||
## How It Works
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A[Generator Declaration] --> B[clan vars generate]
|
||||
B --> C{Prompts User}
|
||||
C --> D[Execute Script]
|
||||
D --> E[Output Files]
|
||||
E --> F{Secret?}
|
||||
F -->|Yes| G[Encrypted Storage]
|
||||
F -->|No| H[Git Repository]
|
||||
G --> I[Deploy to Machine]
|
||||
H --> I
|
||||
I --> J[Available in NixOS]
|
||||
```
|
||||
|
||||
1. **Declare generators** in your NixOS configuration
|
||||
2. **Generate values** using `clan vars generate` (or automatically during deployment)
|
||||
3. **Store securely** in encrypted backends or version control
|
||||
4. **Deploy seamlessly** to your machines where they're accessible as file paths
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
| Use Case | What Gets Generated | Benefits |
|
||||
|----------|-------------------|----------|
|
||||
| **User passwords** | Password hashes | No plaintext in config |
|
||||
| **SSH keys** | Host/user keypairs | Automated key rotation |
|
||||
| **TLS certificates** | Certificates + private keys | Automated PKI |
|
||||
| **Database credentials** | Passwords + connection strings | Secure service communication |
|
||||
| **API tokens** | Random tokens | Service authentication |
|
||||
| **Configuration files** | Complex configs with secrets | Dynamic config generation |
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The vars system has three main components:
|
||||
|
||||
### 1. **Generators**
|
||||
Define how to create files from inputs:
|
||||
|
||||
- **Prompts**: Values requested from users
|
||||
|
||||
- **Scripts**: Generation logic
|
||||
|
||||
- **Dependencies**: Other generators this depends on
|
||||
|
||||
- **Outputs**: Files that get created
|
||||
|
||||
### 2. **Storage Backends**
|
||||
Handle secret storage and deployment:
|
||||
|
||||
- **sops**: Encrypted files in git (recommended)
|
||||
|
||||
- **password-store**: GPG/age-based secret storage
|
||||
|
||||
## Quick Start Example
|
||||
|
||||
Here's a complete example showing password generation and usage:
|
||||
|
||||
```nix
|
||||
# generator.nix
|
||||
{ config, pkgs, ... }: {
|
||||
clan.core.vars.generators.user-password = {
|
||||
prompts.password = {
|
||||
description = "User password";
|
||||
type = "hidden";
|
||||
};
|
||||
files.hash = { secret = false; };
|
||||
script = ''
|
||||
mkpasswd -m sha-512 < $prompts/password > $out/hash
|
||||
'';
|
||||
runtimeInputs = [ pkgs.mkpasswd ];
|
||||
};
|
||||
|
||||
users.users.myuser = {
|
||||
hashedPasswordFile =
|
||||
config.clan.core.vars.generators.user-password.files.hash.path;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Generate the password
|
||||
clan vars generate my-machine
|
||||
|
||||
# Deploy to machine
|
||||
clan machines update my-machine
|
||||
```
|
||||
|
||||
## Migration from Facts
|
||||
|
||||
If you're currently using the legacy facts system, see our [Migration Guide](../migrations/migration-facts-vars.md) for step-by-step instructions on upgrading to vars.
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
---
|
||||
title: Troubleshooting Vars
|
||||
---
|
||||
|
||||
Quick reference for diagnosing and fixing vars issues.
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Generator Script Fails
|
||||
|
||||
**Symptom**: Error during `clan vars generate` or deployment
|
||||
|
||||
**Possible causes and solutions**:
|
||||
|
||||
1. **Missing runtime inputs**
|
||||
```nix
|
||||
# Wrong - missing required tool
|
||||
runtimeInputs = [ ];
|
||||
script = ''
|
||||
openssl rand -hex 32 > $out/secret # openssl not found!
|
||||
'';
|
||||
|
||||
# Correct
|
||||
runtimeInputs = [ pkgs.openssl ];
|
||||
```
|
||||
|
||||
2. **Wrong output path**
|
||||
```nix
|
||||
# Wrong - must use $out
|
||||
script = ''
|
||||
echo "secret" > ./myfile
|
||||
'';
|
||||
|
||||
# Correct
|
||||
script = ''
|
||||
echo "secret" > $out/myfile
|
||||
'';
|
||||
```
|
||||
|
||||
3. **Missing declared files**
|
||||
```nix
|
||||
files."config" = { };
|
||||
files."key" = { };
|
||||
script = ''
|
||||
# Wrong - only generates one file
|
||||
echo "data" > $out/config
|
||||
'';
|
||||
|
||||
# Correct - must generate all declared files
|
||||
script = ''
|
||||
echo "data" > $out/config
|
||||
echo "key" > $out/key
|
||||
'';
|
||||
```
|
||||
|
||||
### Cannot Access Generated Files
|
||||
|
||||
**Symptom**: "attribute 'value' missing" or file not found
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. **Secret files don't have `.value`**
|
||||
```nix
|
||||
# Wrong - secret files can't use .value
|
||||
files."secret" = { secret = true; };
|
||||
# ...
|
||||
environment.etc."app.conf".text =
|
||||
config.clan.core.vars.generators.app.files."secret".value;
|
||||
|
||||
# Correct - use .path for secrets
|
||||
environment.etc."app.conf".source =
|
||||
config.clan.core.vars.generators.app.files."secret".path;
|
||||
```
|
||||
|
||||
2. **Public files should use `.value`**
|
||||
```nix
|
||||
# Better for non-secrets
|
||||
files."cert.pem" = { secret = false; };
|
||||
# ...
|
||||
sslCertificate =
|
||||
config.clan.core.vars.generators.ca.files."cert.pem".value;
|
||||
```
|
||||
|
||||
### Dependencies Not Available
|
||||
|
||||
**Symptom**: "No such file or directory" when accessing `$in/...`
|
||||
|
||||
**Solution**: Declare dependencies correctly
|
||||
```nix
|
||||
clan.core.vars.generators.child = {
|
||||
# Wrong - missing dependency
|
||||
script = ''
|
||||
cat $in/parent/file > $out/newfile
|
||||
'';
|
||||
|
||||
# Correct
|
||||
dependencies = [ "parent" ];
|
||||
script = ''
|
||||
cat $in/parent/file > $out/newfile
|
||||
'';
|
||||
};
|
||||
```
|
||||
|
||||
### Permission Denied
|
||||
|
||||
**Symptom**: Service cannot read generated secret file
|
||||
|
||||
**Solution**: Set correct ownership and permissions
|
||||
```nix
|
||||
files."service.key" = {
|
||||
secret = true;
|
||||
owner = "myservice"; # Match service user
|
||||
group = "myservice";
|
||||
mode = "0400"; # Read-only for owner
|
||||
};
|
||||
```
|
||||
|
||||
### Vars Not Regenerating
|
||||
|
||||
**Symptom**: Changes to generator script don't trigger regeneration
|
||||
|
||||
**Solution**: Use `--regenerate` flag
|
||||
```bash
|
||||
clan vars generate my-machine --generator my-generator --regenerate
|
||||
```
|
||||
|
||||
### Prompts Not Working
|
||||
|
||||
**Symptom**: Script fails with "No such file or directory" for prompts
|
||||
|
||||
**Solution**: Access prompts correctly
|
||||
```nix
|
||||
# Wrong
|
||||
script = ''
|
||||
echo $password > $out/file
|
||||
'';
|
||||
|
||||
# Correct
|
||||
prompts.password.type = "hidden";
|
||||
script = ''
|
||||
cat $prompts/password > $out/file
|
||||
'';
|
||||
```
|
||||
|
||||
## Debugging Techniques
|
||||
|
||||
### 1. Check Generator Status
|
||||
|
||||
See what vars are set:
|
||||
```bash
|
||||
clan vars list my-machine
|
||||
```
|
||||
|
||||
### 2. Inspect Generated Files
|
||||
|
||||
For shared vars:
|
||||
```bash
|
||||
ls -la vars/shared/my-generator/
|
||||
```
|
||||
|
||||
For per-machine vars:
|
||||
```bash
|
||||
ls -la vars/per-machine/my-machine/my-generator/
|
||||
```
|
||||
|
||||
### 3. Test Generators Locally
|
||||
|
||||
Create a test script to debug:
|
||||
```nix
|
||||
# test-generator.nix
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "test-generator";
|
||||
buildInputs = [ pkgs.openssl ]; # Your runtime inputs
|
||||
buildCommand = ''
|
||||
# Your generator script here
|
||||
mkdir -p $out
|
||||
openssl rand -hex 32 > $out/secret
|
||||
ls -la $out/
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
Run with:
|
||||
```bash
|
||||
nix-build test-generator.nix
|
||||
```
|
||||
|
||||
### 4. Enable Debug Logging
|
||||
|
||||
Set debug mode:
|
||||
```bash
|
||||
clan --debug vars generate my-machine
|
||||
```
|
||||
|
||||
### 5. Check File Permissions
|
||||
|
||||
Verify generated secret permissions:
|
||||
```bash
|
||||
# On the target machine
|
||||
ls -la /run/secrets/
|
||||
```
|
||||
|
||||
## Recovery Procedures
|
||||
|
||||
### Regenerate All Vars
|
||||
|
||||
If vars are corrupted or need refresh:
|
||||
```bash
|
||||
# Regenerate all for a machine
|
||||
clan vars generate my-machine --regenerate
|
||||
|
||||
# Regenerate specific generator
|
||||
clan vars generate my-machine --generator my-generator --regenerate
|
||||
```
|
||||
|
||||
### Manual Secret Injection
|
||||
|
||||
For recovery or testing:
|
||||
```bash
|
||||
# Set a var manually (bypass generator)
|
||||
echo "temporary-secret" | clan vars set my-machine my-generator/my-file
|
||||
```
|
||||
|
||||
### Restore from Backup
|
||||
|
||||
Vars are stored in the repository:
|
||||
```bash
|
||||
# Restore previous version
|
||||
git checkout HEAD~1 -- vars/
|
||||
|
||||
# Check and regenerate if needed
|
||||
clan vars list my-machine
|
||||
```
|
||||
|
||||
## Storage Backend Issues
|
||||
|
||||
### SOPS Decryption Fails
|
||||
|
||||
**Symptom**: "Failed to decrypt" or permission errors
|
||||
|
||||
**Solution**: Ensure your user/machine has the correct age keys configured. Clan manages encryption keys automatically based on the configured users and machines in your flake.
|
||||
|
||||
Check that:
|
||||
|
||||
1. Your machine is properly configured in the flake
|
||||
|
||||
2. Your user has access to the machine's secrets
|
||||
|
||||
3. The age key is available in the expected location
|
||||
|
||||
### Password Store Issues
|
||||
|
||||
**Symptom**: "pass: store not initialized"
|
||||
|
||||
**Solution**: Initialize password store:
|
||||
```bash
|
||||
export PASSWORD_STORE_DIR=/path/to/clan/vars
|
||||
pass init your-gpg-key
|
||||
```
|
||||
|
||||
## Getting Help
|
||||
|
||||
If these solutions don't resolve your issue:
|
||||
|
||||
1. Check the [clan-core issue tracker](https://git.clan.lol/clan/clan-core/issues)
|
||||
2. Ask in the Clan community channels
|
||||
3. Provide:
|
||||
|
||||
- The generator configuration
|
||||
|
||||
- The exact error message
|
||||
|
||||
- Output of `clan --debug vars generate`
|
||||
148
tested-trappist/src/content/docs/index.md
Normal file
148
tested-trappist/src/content/docs/index.md
Normal file
@@ -0,0 +1,148 @@
|
||||
---
|
||||
title: Welcome to Clan
|
||||
---
|
||||
|
||||
## What is Clan?
|
||||
|
||||
<style>
|
||||
.clamp-wrap {
|
||||
--lines: 5; /* visible lines when collapsed */
|
||||
--fade-height: 2.5rem;/* fade size */
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Accessible, visually hidden checkbox */
|
||||
.clamp-toggle {
|
||||
position: absolute;
|
||||
width: 1px; height: 1px;
|
||||
margin: -1px; border: 0; padding: 0;
|
||||
clip: rect(0 0 0 0); clip-path: inset(50%);
|
||||
overflow: hidden; white-space: nowrap;
|
||||
}
|
||||
|
||||
.clamp-content {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: var(--lines);
|
||||
overflow: hidden;
|
||||
|
||||
/* Fade via mask (no overlay needed) */
|
||||
-webkit-mask-image: linear-gradient(
|
||||
to bottom,
|
||||
black,
|
||||
black calc(100% - var(--fade-height)),
|
||||
transparent
|
||||
);
|
||||
mask-image: linear-gradient(
|
||||
to bottom,
|
||||
black,
|
||||
black calc(100% - var(--fade-height)),
|
||||
transparent
|
||||
);
|
||||
}
|
||||
|
||||
/* Right-aligned Read more/less */
|
||||
.clamp-more {
|
||||
display: block;
|
||||
width: max-content;
|
||||
/* margin-left: auto; */
|
||||
margin-top: 0.5rem;
|
||||
cursor: pointer;
|
||||
color: #0057d9;
|
||||
text-decoration: underline;
|
||||
user-select: none;
|
||||
}
|
||||
.clamp-more:hover,
|
||||
.clamp-more:focus { text-decoration: none; }
|
||||
|
||||
/* Expanded state */
|
||||
.clamp-toggle:checked ~ .clamp-content {
|
||||
-webkit-line-clamp: initial;
|
||||
display: block;
|
||||
-webkit-mask-image: none;
|
||||
mask-image: none;
|
||||
}
|
||||
|
||||
/* Dynamic label text */
|
||||
.clamp-more::after { content: "Read more"; }
|
||||
.clamp-toggle:checked ~ .clamp-more::after { content: "Read less"; }
|
||||
</style>
|
||||
|
||||
<div class="clamp-wrap" style="--lines: 3;">
|
||||
<input type="checkbox" id="clan-readmore" class="clamp-toggle" />
|
||||
<div class="clamp-content">
|
||||
<p><a href="https://clan.lol/">Clan</a> is a peer-to-peer computer management framework that empowers you to selfhost in a reliable and scalable way</strong>.</p>
|
||||
<p>Built on NixOS, Clan provides a declarative interface for managing machines</strong> with automated <a href="./guides/secrets.md">secret management</a>, easy <a href="./guides/mesh-vpn.md">mesh VPN connectivity</a>, and <a href="./guides/backups.md">automated backups</a>.</p>
|
||||
<p>Whether you're running a homelab or maintaining critical computing infrastructure, Clan will help reduce maintenance burden</strong> by allowing a git repository to define your whole network</strong> of computers.</p>
|
||||
<p>In combination with <a href="https://github.com/Mic92/sops-nix">sops-nix</a>, <a href="https://github.com/nix-community/nixos-anywhere">nixos-anywhere</a> and <a href="https://github.com/nix-community/disko">disko</a>, Clan makes it possible to have collaborative infrastructure</strong>.</p>
|
||||
<p>At the heart of Clan are <a href="./reference/clanServices/index.md">Clan Services</a> - the core concept that enables you to add functionality across multiple machines in your network. While Clan ships with essential core services, you can <a href="./guides/inventory/clanServices.md">create custom services</a> tailored to your specific needs.</p>
|
||||
</div>
|
||||
<label class="clamp-more" for="clan-readmore"></label>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
[Get started](./guides/getting-started/index.md)
|
||||
[View on Gitea](https://git.clan.lol/clan/clan-core)
|
||||
|
||||
## Guides
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [Inventory](./guides/inventory/inventory.md)
|
||||
|
||||
***
|
||||
|
||||
Learn how about inventory
|
||||
|
||||
- [Vars](./guides/vars/vars-overview.md)
|
||||
|
||||
***
|
||||
|
||||
Learn how to use vars
|
||||
|
||||
- [macOS](./guides/macos.md)
|
||||
|
||||
***
|
||||
|
||||
Using Clan to manage your macOS machines
|
||||
|
||||
</div>
|
||||
|
||||
## Reference
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [CLI](./reference/cli/index.md)
|
||||
|
||||
***
|
||||
|
||||
command line interface
|
||||
|
||||
- [Clan Options](/options)
|
||||
|
||||
***
|
||||
|
||||
Search all options
|
||||
|
||||
- [Services](./reference/clanServices/index.md)
|
||||
|
||||
***
|
||||
|
||||
Discover services
|
||||
|
||||
</div>
|
||||
|
||||
## Blog
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [Clan Blog](https://clan.lol/blog/)
|
||||
|
||||
***
|
||||
|
||||
For the latest updates, tutorials, and community stories.
|
||||
|
||||
</div>
|
||||
107
tested-trappist/src/content/docs/reference/clanServices/admin.md
Normal file
107
tested-trappist/src/content/docs/reference/clanServices/admin.md
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
title: admin
|
||||
description: Convenient Administration for the Clan App
|
||||
---
|
||||
|
||||
*Convenient Administration for the Clan App*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The admin module has the following roles:
|
||||
|
||||
- default
|
||||
## Options for the `default` role
|
||||
#### allowedKeys
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The allowed public keys for ssh access to the admin user
|
||||
|
||||
|
||||
**Type**: `attribute set of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
{
|
||||
key_1 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD...";
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/admin/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/admin/default.nix)
|
||||
|
||||
|
||||
|
||||
#### certificateSearchDomains
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List of domains to include in the certificate.
|
||||
This option will prepend the machine name in front of each domain before adding it to the certificate.
|
||||
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"mydomain.com"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/admin/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/admin/default.nix)
|
||||
|
||||
|
||||
|
||||
#### rsaHostKey.enable
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Whether to enable Generate RSA host key.
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
false
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
true
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/admin/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/admin/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
title: borgbackup
|
||||
description: Efficient, deduplicating backup program with optional compression and secure encryption.
|
||||
---
|
||||
|
||||
*Efficient, deduplicating backup program with optional compression and secure encryption.*
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
inventory.instances = {
|
||||
borgbackup = {
|
||||
module = {
|
||||
name = "borgbackup";
|
||||
input = "clan-core";
|
||||
};
|
||||
roles.client.machines."jon".settings = {
|
||||
destinations."storagebox" = {
|
||||
repo = "username@$hostname:/./borgbackup";
|
||||
rsh = ''ssh -oPort=23 -i /run/secrets/vars/borgbackup/borgbackup.ssh'';
|
||||
};
|
||||
};
|
||||
roles.server.machines = { };
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
The input should be named according to your flake input. Jon is configured as a
|
||||
client machine with a destination pointing to a Hetzner Storage Box.
|
||||
|
||||
## Overview
|
||||
|
||||
This guide explains how to set up and manage
|
||||
[BorgBackup](https://borgbackup.readthedocs.io/) for secure, efficient backups
|
||||
in a clan network. BorgBackup provides:
|
||||
|
||||
- Space efficient storage of backups with deduplication
|
||||
- Secure, authenticated encryption
|
||||
- Compression: lz4, zstd, zlib, lzma or none
|
||||
- Mountable backups with FUSE
|
||||
- Easy installation on multiple platforms: Linux, macOS, BSD, …
|
||||
- Free software (BSD license).
|
||||
- Backed by a large and active open-source community.
|
||||
|
||||
## Roles
|
||||
|
||||
### 1. Client
|
||||
|
||||
Clients are machines that create and send backups to various destinations. Each
|
||||
client can have multiple backup destinations configured.
|
||||
|
||||
### 2. Server
|
||||
|
||||
Servers act as backup repositories, receiving and storing backups from client
|
||||
machines. They can be dedicated backup servers within your clan network.
|
||||
|
||||
## Backup destinations
|
||||
|
||||
This service allows you to perform backups to multiple `destinations`.
|
||||
Destinations can be:
|
||||
|
||||
- **Local**: Local disk storage
|
||||
- **Server**: Your own borgbackup server (using the `server` role)
|
||||
- **Third-party services**: Such as Hetzner's Storage Box
|
||||
|
||||
For a more comprehensive guide on backups look into the guide section.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The borgbackup module has the following roles:
|
||||
|
||||
- client
|
||||
- server
|
||||
## Options for the `client` role
|
||||
#### destinations
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
external destinations where the machine should be backuped to
|
||||
|
||||
|
||||
|
||||
**Type**: `attribute set of (submodule)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/borgbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/borgbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### destinations.<name\>.name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
the name of the backup job
|
||||
|
||||
|
||||
**Type**: `string matching the pattern ^[a-zA-Z0-9._-]+$`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"‹name›"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/borgbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/borgbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### destinations.<name\>.repo
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
the borgbackup repository to backup to
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/borgbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/borgbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### destinations.<name\>.rsh
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
the rsh to use for the backup
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"ssh -i \${config.clan.core.vars.generators.borgbackup.files.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/borgbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/borgbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### exclude
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Directories/Files to exclude from the backup.
|
||||
Use * as a wildcard.
|
||||
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"*.pyc"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/borgbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/borgbackup/default.nix)
|
||||
|
||||
|
||||
## Options for the `server` role
|
||||
#### directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The directory where the borgbackup repositories are stored.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"/var/lib/borgbackup"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/borgbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/borgbackup/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
---
|
||||
title: certificates
|
||||
description: Sets up a certificates internal to your Clan
|
||||
---
|
||||
|
||||
*Sets up a certificates internal to your Clan*
|
||||
This service sets up a certificate authority (CA) that can issue certificates to
|
||||
other machines in your clan. For this the `ca` role is used.
|
||||
It additionally provides a `default` role, that can be applied to all machines
|
||||
in your clan and will make sure they trust your CA.
|
||||
|
||||
## Example Usage
|
||||
|
||||
The following configuration would add a CA for the top level domain `.foo`. If
|
||||
the machine `server` now hosts a webservice at `https://something.foo`, it will
|
||||
get a certificate from `ca` which is valid inside your clan. The machine
|
||||
`client` will trust this certificate if it makes a request to
|
||||
`https://something.foo`.
|
||||
|
||||
This clan service can be combined with the `coredns` service for easy to deploy,
|
||||
SSL secured clan-internal service hosting.
|
||||
|
||||
```nix
|
||||
inventory = {
|
||||
machines.ca = { };
|
||||
machines.client = { };
|
||||
machines.server = { };
|
||||
|
||||
instances."certificates" = {
|
||||
module.name = "certificates";
|
||||
module.input = "self";
|
||||
|
||||
roles.ca.machines.ca.settings.tlds = [ "foo" ];
|
||||
roles.default.machines.client = { };
|
||||
roles.default.machines.server = { };
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The certificates module has the following roles:
|
||||
|
||||
- ca
|
||||
- default
|
||||
## Options for the `ca` role
|
||||
#### acmeEmail
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Email address for account creation and correspondence from the CA.
|
||||
It is recommended to use the same email for all certs to avoid account
|
||||
creation limits.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"none@none.tld"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/certificates/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/certificates/default.nix)
|
||||
|
||||
|
||||
|
||||
#### expire
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
When the certificate should expire.
|
||||
|
||||
|
||||
**Type**: `null or string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"8760h"
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"8760h"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/certificates/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/certificates/default.nix)
|
||||
|
||||
|
||||
|
||||
#### tlds
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Top level domain for this CA. Certificates will be issued and trusted for *.<tld>
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/certificates/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/certificates/default.nix)
|
||||
|
||||
|
||||
## Options for the `default` role
|
||||
#### acmeEmail
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Email address for account creation and correspondence from the CA.
|
||||
It is recommended to use the same email for all certs to avoid account
|
||||
creation limits.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"none@none.tld"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/certificates/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/certificates/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
---
|
||||
title: coredns
|
||||
description: Clan-internal DNS and service exposure
|
||||
---
|
||||
|
||||
*Clan-internal DNS and service exposure*
|
||||
This module enables hosting clan-internal services easily, which can be resolved
|
||||
inside your VPN. This allows defining a custom top-level domain (e.g. `.clan`)
|
||||
and exposing endpoints from a machine to others, which will be
|
||||
accessible under `http://<service>.clan` in your browser.
|
||||
|
||||
The service consists of two roles:
|
||||
|
||||
- A `server` role: This is the DNS-server that will be queried when trying to
|
||||
resolve clan-internal services. It defines the top-level domain.
|
||||
- A `default` role: This does two things. First, it sets up the nameservers so
|
||||
that clan-internal queries are resolved via the `server` machine, while
|
||||
external queries are resolved as normal via DHCP. Second, it allows exposing
|
||||
services (see example below).
|
||||
|
||||
## Example Usage
|
||||
|
||||
Here the machine `dnsserver` is designated as internal DNS-server for the TLD
|
||||
`.foo`. `server01` will host an application that shall be reachable at
|
||||
`http://one.foo` and `server02` is going to be reachable at `http://two.foo`.
|
||||
`client` is any other machine that is part of the clan but does not host any
|
||||
services.
|
||||
|
||||
When `client` tries to resolve `http://one.foo`, the DNS query will be
|
||||
routed to `dnsserver`, which will answer with `192.168.1.3`. If it tries to
|
||||
resolve some external domain (e.g. `https://clan.lol`), the query will not be
|
||||
routed to `dnsserver` but resolved as before, via the nameservers advertised by
|
||||
DHCP.
|
||||
|
||||
```nix
|
||||
inventory = {
|
||||
|
||||
machines = {
|
||||
dnsserver = { }; # 192.168.1.2
|
||||
server01 = { }; # 192.168.1.3
|
||||
server02 = { }; # 192.168.1.4
|
||||
client = { }; # 192.168.1.5
|
||||
};
|
||||
|
||||
instances = {
|
||||
coredns = {
|
||||
|
||||
module.name = "@clan/coredns";
|
||||
module.input = "self";
|
||||
|
||||
# Add the default role to all machines, including `client`
|
||||
roles.default.tags.all = { };
|
||||
|
||||
# DNS server
|
||||
roles.server.machines."dnsserver".settings = {
|
||||
ip = "192.168.1.2";
|
||||
tld = "foo";
|
||||
};
|
||||
|
||||
# First service
|
||||
roles.default.machines."server01".settings = {
|
||||
ip = "192.168.1.3";
|
||||
services = [ "one" ];
|
||||
};
|
||||
|
||||
# Second service
|
||||
roles.default.machines."server02".settings = {
|
||||
ip = "192.168.1.4";
|
||||
services = [ "two" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The coredns module has the following roles:
|
||||
|
||||
- default
|
||||
- server
|
||||
## Options for the `default` role
|
||||
#### dnsPort
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Port of the clan-internal DNS server
|
||||
|
||||
|
||||
**Type**: `signed integer`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
1053
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/coredns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/coredns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### ip
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
IP on which the services will listen
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/coredns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/coredns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### services
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Service endpoints this host exposes (without TLD). Each entry will
|
||||
be resolved to <entry>.<tld> using the configured top-level domain.
|
||||
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/coredns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/coredns/default.nix)
|
||||
|
||||
|
||||
## Options for the `server` role
|
||||
#### dnsPort
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Port of the clan-internal DNS server
|
||||
|
||||
|
||||
**Type**: `signed integer`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
1053
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/coredns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/coredns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### ip
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
IP for the DNS to listen on
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/coredns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/coredns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### tld
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Top-level domain for this instance. All services below this will be
|
||||
resolved internally.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"clan"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/coredns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/coredns/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
---
|
||||
title: data-mesher
|
||||
description: Set up data-mesher
|
||||
---
|
||||
|
||||
*Set up data-mesher*
|
||||
This service will set up data-mesher.
|
||||
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
inventory.instances = {
|
||||
data-mesher = {
|
||||
module = {
|
||||
name = "data-mesher";
|
||||
input = "clan-core";
|
||||
};
|
||||
roles.admin.machines.server0 = {
|
||||
settings = {
|
||||
bootstrapNodes = {
|
||||
node1 = "192.168.1.1:7946";
|
||||
node2 = "192.168.1.2:7946";
|
||||
};
|
||||
|
||||
network = {
|
||||
hostTTL = "24h";
|
||||
interface = "tailscale0";
|
||||
};
|
||||
};
|
||||
};
|
||||
roles.peer.machines.server1 = { };
|
||||
roles.signer.machines.server2 = { };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The data-mesher module has the following roles:
|
||||
|
||||
- admin
|
||||
- peer
|
||||
- signer
|
||||
## Options for the `admin` role
|
||||
#### bootstrapNodes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
A list of bootstrap nodes that act as an initial gateway when joining
|
||||
the cluster.
|
||||
|
||||
|
||||
|
||||
**Type**: `null or (list of string)`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"192.168.1.1:7946"
|
||||
"192.168.1.2:7946"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
|
||||
#### network.hostTTL
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The TTL for hosts in the network, in the form of a Go time.Duration
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"672h"
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"24h"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
|
||||
#### network.interface
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The interface over which cluster communication should be performed.
|
||||
All the ip addresses associate with this interface will be part of
|
||||
our host claim, including both ipv4 and ipv6.
|
||||
|
||||
This should be set to an internal/VPN interface.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"tailscale0"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
|
||||
#### network.port
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Port to listen on for cluster communication.
|
||||
|
||||
|
||||
|
||||
**Type**: `16 bit unsigned integer; between 0 and 65535 (both inclusive)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
7946
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
|
||||
#### network.tld
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Top level domain to use for the network
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"clan"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
## Options for the `peer` role
|
||||
#### bootstrapNodes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
A list of bootstrap nodes that act as an initial gateway when joining
|
||||
the cluster.
|
||||
|
||||
|
||||
|
||||
**Type**: `null or (list of string)`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"192.168.1.1:7946"
|
||||
"192.168.1.2:7946"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
|
||||
#### network.interface
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The interface over which cluster communication should be performed.
|
||||
All the ip addresses associate with this interface will be part of
|
||||
our host claim, including both ipv4 and ipv6.
|
||||
|
||||
This should be set to an internal/VPN interface.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"tailscale0"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
|
||||
#### network.port
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Port to listen on for cluster communication.
|
||||
|
||||
|
||||
|
||||
**Type**: `16 bit unsigned integer; between 0 and 65535 (both inclusive)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
7946
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
## Options for the `signer` role
|
||||
#### bootstrapNodes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
A list of bootstrap nodes that act as an initial gateway when joining
|
||||
the cluster.
|
||||
|
||||
|
||||
|
||||
**Type**: `null or (list of string)`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"192.168.1.1:7946"
|
||||
"192.168.1.2:7946"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
|
||||
#### network.interface
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The interface over which cluster communication should be performed.
|
||||
All the ip addresses associate with this interface will be part of
|
||||
our host claim, including both ipv4 and ipv6.
|
||||
|
||||
This should be set to an internal/VPN interface.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"tailscale0"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
|
||||
#### network.port
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Port to listen on for cluster communication.
|
||||
|
||||
|
||||
|
||||
**Type**: `16 bit unsigned integer; between 0 and 65535 (both inclusive)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
7946
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/data-mesher/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/data-mesher/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
---
|
||||
title: dyndns
|
||||
description: A dynamic DNS service to update domain IPs
|
||||
---
|
||||
|
||||
*A dynamic DNS service to update domain IPs*
|
||||
|
||||
A Dynamic-DNS (DDNS) service continuously keeps one or more DNS records in sync with the current public IP address of your machine.
|
||||
In *clan* this service is backed by [qdm12/ddns-updater](https://github.com/qdm12/ddns-updater).
|
||||
|
||||
> Info
|
||||
> ddns-updater itself is **heavily opinionated and version-specific**. Whenever you need the exhaustive list of flags or
|
||||
> provider-specific fields refer to its *versioned* documentation – **not** the GitHub README
|
||||
---
|
||||
|
||||
# 1. Configuration model
|
||||
|
||||
Internally ddns-updater consumes a single file named `config.json`.
|
||||
A minimal configuration for the registrar *Namecheap* looks like:
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "namecheap",
|
||||
"domain": "sub.example.com",
|
||||
"password": "e5322165c1d74692bfa6d807100c0310"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Another example for *Porkbun*:
|
||||
|
||||
```json
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"provider": "porkbun",
|
||||
"domain": "domain.com",
|
||||
"api_key": "sk1_…",
|
||||
"secret_api_key": "pk1_…",
|
||||
"ip_version": "ipv4",
|
||||
"ipv6_suffix": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When you write a `clan.nix` the **common** fields (`provider`, `domain`, `period`, …) are already exposed as typed
|
||||
*Nix options*.
|
||||
Registrar-specific or very new keys can be passed through an open attribute set called **extraSettings**.
|
||||
|
||||
---
|
||||
|
||||
# 2. Full Porkbun example
|
||||
|
||||
Manage three records – `@`, `home` and `test` – of the domain
|
||||
`jon.blog` and refresh them every 15 minutes:
|
||||
|
||||
```nix title="clan.nix" hl_lines="10-11"
|
||||
inventory.instances = {
|
||||
dyndns = {
|
||||
roles.default.machines."jon" = { };
|
||||
roles.default.settings = {
|
||||
period = 15; # minutes
|
||||
settings = {
|
||||
"all-jon-blog" = {
|
||||
provider = "porkbun";
|
||||
domain = "jon.blog";
|
||||
|
||||
# (1) tell the secret-manager which key we are going to store
|
||||
secret_field_name = "secret_api_key";
|
||||
|
||||
# everything below is copied verbatim into config.json
|
||||
extraSettings = {
|
||||
host = "@,home,test"; # (2) comma-separated list of sub-domains
|
||||
ip_version = "ipv4";
|
||||
ipv6_suffix = "";
|
||||
api_key = "pk1_4bb2b231275a02fdc23b7e6f3552s01S213S"; # (3) public – safe to commit
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
1. `secret_field_name` tells the *vars-generator* to store the entered secret under the specified JSON field name in the configuration.
|
||||
2. ddns-updater allows multiple hosts by separating them with a comma.
|
||||
3. The `api_key` above is *public*; the corresponding **private key** is retrieved through `secret_field_name`.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The dyndns module has the following roles:
|
||||
|
||||
- default
|
||||
## Options for the `default` role
|
||||
#### period
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Domain update period in minutes
|
||||
|
||||
|
||||
**Type**: `signed integer`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
5
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### server.acmeEmail
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Email address for account creation and correspondence from the CA.
|
||||
It is recommended to use the same email for all certs to avoid account
|
||||
creation limits.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### server.domain
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Domain to serve the webservice on
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### server.enable
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Whether to enable dyndns webserver.
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
false
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
true
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### server.port
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Port to listen on
|
||||
|
||||
|
||||
**Type**: `signed integer`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
54805
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### settings
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Configuration for which domains to update
|
||||
|
||||
|
||||
**Type**: `attribute set of (submodule)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### settings.<name\>.domain
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The top level domain to update.
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"example.com"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### settings.<name\>.extraSettings
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Extra settings for the provider.
|
||||
Provider specific settings: https://github.com/qdm12/ddns-updater#configuration
|
||||
|
||||
|
||||
|
||||
**Type**: `attribute set of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### settings.<name\>.provider
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The dyndns provider to use
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"namecheap"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
|
||||
#### settings.<name\>.secret_field_name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The field name for the secret
|
||||
|
||||
|
||||
**Type**: `one of "password", "token", "api_key", "secret_api_key"`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"password"
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"api_key"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/dyndns/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/dyndns/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: emergency-access
|
||||
description: Set recovery password for emergency access to machine
|
||||
---
|
||||
|
||||
*Set recovery password for emergency access to machine*
|
||||
This service will automatically set the emergency access password if your system fails to boot.
|
||||
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
inventory.instances = {
|
||||
emergency-access = {
|
||||
module = {
|
||||
name = "emergency-access";
|
||||
input = "clan-core";
|
||||
};
|
||||
|
||||
roles.default.tags.nixos = { };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The emergency-access module has the following roles:
|
||||
|
||||
- default
|
||||
This role has no configuration
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: garage
|
||||
description: S3-compatible object store for small self-hosted geo-distributed deployments
|
||||
---
|
||||
|
||||
*S3-compatible object store for small self-hosted geo-distributed deployments*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The garage module has the following roles:
|
||||
|
||||
- default
|
||||
This role has no configuration
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
title: hello-world
|
||||
description: This is a test
|
||||
---
|
||||
|
||||
*This is a test*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The hello-world module has the following roles:
|
||||
|
||||
- evening
|
||||
- morning
|
||||
## Options for the `evening` role
|
||||
#### greeting
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The greeting to use
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"Good evening"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/hello-world/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/hello-world/default.nix)
|
||||
|
||||
|
||||
## Options for the `morning` role
|
||||
#### greeting
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The greeting to use
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"Good morning"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/hello-world/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/hello-world/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: importer
|
||||
description: Convenient, structured module imports for hosts.
|
||||
---
|
||||
|
||||
*Convenient, structured module imports for hosts.*
|
||||
The importer module allows users to configure importing modules in a flexible and structured way.
|
||||
It exposes the `extraModules` functionality of the inventory, without any added configuration.
|
||||
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
inventory.instances = {
|
||||
|
||||
zone1 = {
|
||||
module.name = "@clan/importer";
|
||||
roles.default.tags.zone1 = {};
|
||||
roles.default.extraModules = [ "modules/zone1.nix" ];
|
||||
};
|
||||
|
||||
base = {
|
||||
module.name = "@clan/importer";
|
||||
roles.default.tags.all = {};
|
||||
roles.default.extraModules = [ "modules/base.nix" ];
|
||||
};
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
This will import the module `modules/base.nix` to all machines that have the `all` tag,
|
||||
which by default is every machine managed by the clan.
|
||||
And also import for all machines tagged with `zone1` the module at `modules/zone1.nix`.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The importer module has the following roles:
|
||||
|
||||
- default
|
||||
This role has no configuration
|
||||
@@ -0,0 +1,290 @@
|
||||
---
|
||||
title: localbackup
|
||||
description: Automatically backups current machine to local directory.
|
||||
---
|
||||
|
||||
*Automatically backups current machine to local directory.*
|
||||
## Features
|
||||
|
||||
- Creates incremental snapshots using rsnapshot
|
||||
- Supports multiple backup targets
|
||||
- Mount/unmount hooks for external storage
|
||||
- Pre/post backup hooks for custom scripts
|
||||
- Configurable snapshot retention
|
||||
- Automatic state folder detection
|
||||
|
||||
## Usage
|
||||
|
||||
Enable the localbackup service and configure backup targets:
|
||||
|
||||
```nix
|
||||
instances = {
|
||||
localbackup = {
|
||||
module.name = "@clan/localbackup";
|
||||
module.input = "self";
|
||||
roles.default.machines."machine".settings = {
|
||||
targets.external= {
|
||||
directory = "/mnt/backup";
|
||||
mountpoint = "/mnt/backup";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
The service provides these commands:
|
||||
|
||||
- `localbackup-create`: Create a new backup
|
||||
- `localbackup-list`: List available backups
|
||||
- `localbackup-restore`: Restore from backup (requires NAME and FOLDERS environment variables)
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The localbackup module has the following roles:
|
||||
|
||||
- default
|
||||
## Options for the `default` role
|
||||
#### snapshots
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Number of snapshots to keep
|
||||
|
||||
|
||||
**Type**: `signed integer`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
20
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List of directories where backups are stored
|
||||
|
||||
|
||||
**Type**: `attribute set of (submodule)`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
the directory to backup
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.mountpoint
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mountpoint of the directory to backup. If set, the directory will be mounted before the backup and unmounted afterwards
|
||||
|
||||
|
||||
**Type**: `null or string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
null
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
the name of the backup job
|
||||
|
||||
|
||||
**Type**: `string matching the pattern ^[a-zA-Z0-9._-]+$`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"‹name›"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.postBackupHook
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Shell commands to run after the backup
|
||||
|
||||
|
||||
**Type**: `null or strings concatenated with "\n"`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
null
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.postMountHook
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Shell commands to run after the directory is mounted
|
||||
|
||||
|
||||
**Type**: `null or strings concatenated with "\n"`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
null
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.postUnmountHook
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Shell commands to run after the directory is unmounted
|
||||
|
||||
|
||||
**Type**: `null or strings concatenated with "\n"`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
null
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.preBackupHook
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Shell commands to run before the backup
|
||||
|
||||
|
||||
**Type**: `null or strings concatenated with "\n"`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
null
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.preMountHook
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Shell commands to run before the directory is mounted
|
||||
|
||||
|
||||
**Type**: `null or strings concatenated with "\n"`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
null
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
|
||||
#### targets.<name\>.preUnmountHook
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Shell commands to run before the directory is unmounted
|
||||
|
||||
|
||||
**Type**: `null or strings concatenated with "\n"`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
null
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/localbackup/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/localbackup/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: matrix-synapse
|
||||
description: A federated messaging server with end-to-end encryption.
|
||||
---
|
||||
|
||||
*A federated messaging server with end-to-end encryption.*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The matrix-synapse module has the following roles:
|
||||
|
||||
- default
|
||||
## Options for the `default` role
|
||||
#### acmeEmail
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Email address for account creation and correspondence from the CA.
|
||||
It is recommended to use the same email for all certs to avoid account
|
||||
creation limits.
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/matrix-synapse/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/matrix-synapse/default.nix)
|
||||
|
||||
|
||||
|
||||
#### app_domain
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The matrix server hostname also serves the element client
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"matrix.example.com"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/matrix-synapse/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/matrix-synapse/default.nix)
|
||||
|
||||
|
||||
|
||||
#### server_tld
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The address that is suffixed after your username i.e @alice:example.com
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"example.com"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/matrix-synapse/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/matrix-synapse/default.nix)
|
||||
|
||||
|
||||
|
||||
#### services.matrix-synapse.package
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Package to use for matrix-synapse
|
||||
|
||||
|
||||
**Type**: `unspecified value`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/matrix-synapse/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/matrix-synapse/default.nix)
|
||||
|
||||
|
||||
|
||||
#### users
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
A list of users. Not that only new users will be created and existing ones are not modified.
|
||||
|
||||
|
||||
**Type**: `attribute set of (submodule)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
{
|
||||
alice = {
|
||||
admin = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/matrix-synapse/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/matrix-synapse/default.nix)
|
||||
|
||||
|
||||
|
||||
#### users.<name\>.admin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Whether the user should be an admin
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
false
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/matrix-synapse/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/matrix-synapse/default.nix)
|
||||
|
||||
|
||||
|
||||
#### users.<name\>.name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The name of the user
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"‹name›"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/matrix-synapse/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/matrix-synapse/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: monitoring
|
||||
description: Monitoring service for the nodes in your clan
|
||||
---
|
||||
|
||||
*Monitoring service for the nodes in your clan*
|
||||
## Usage
|
||||
|
||||
```
|
||||
inventory.instances = {
|
||||
monitoring = {
|
||||
module.name = "monitoring";
|
||||
roles.telegraf.tags.all = {
|
||||
settings.interfaces = [ "wg-clan" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
This service will eventually set up a monitoring stack for your clan. For now,
|
||||
only a telegraf role is implemented, which exposes the currently deployed
|
||||
version of your configuration, so it can be used to check for required updates.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The monitoring module has the following roles:
|
||||
|
||||
- telegraf
|
||||
## Options for the `telegraf` role
|
||||
#### allowAllInterfaces
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
If true, Telegraf will listen on all interfaces. Otherwise, it will only listen on the interfaces specified in `interfaces`
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
false
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/monitoring/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/monitoring/default.nix)
|
||||
|
||||
|
||||
|
||||
#### interfaces
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List of interfaces to expose the metrics to
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[
|
||||
"zt+"
|
||||
]
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/monitoring/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/monitoring/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: mycelium
|
||||
description: End-2-end encrypted IPv6 overlay network
|
||||
---
|
||||
|
||||
*End-2-end encrypted IPv6 overlay network*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The mycelium module has the following roles:
|
||||
|
||||
- peer
|
||||
## Options for the `peer` role
|
||||
#### addHostedPublicNodes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Add hosted Public nodes
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
true
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/mycelium/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/mycelium/default.nix)
|
||||
|
||||
|
||||
|
||||
#### openFirewall
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Open the firewall for mycelium
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
true
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/mycelium/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/mycelium/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: packages
|
||||
description: Define package sets from nixpkgs and install them on one or more machines
|
||||
---
|
||||
|
||||
*Define package sets from nixpkgs and install them on one or more machines*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The packages module has the following roles:
|
||||
|
||||
- default
|
||||
## Options for the `default` role
|
||||
#### packages
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The packages to install on the machine
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"cowsay"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/packages/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/packages/default.nix)
|
||||
|
||||
|
||||
148
tested-trappist/src/content/docs/reference/clanServices/sshd.md
Normal file
148
tested-trappist/src/content/docs/reference/clanServices/sshd.md
Normal file
@@ -0,0 +1,148 @@
|
||||
---
|
||||
title: sshd
|
||||
description: Enables secure remote access to the machine over SSH
|
||||
---
|
||||
|
||||
*Enables secure remote access to the machine over SSH*
|
||||
The `sshd` Clan service manages SSH to make it easy to securely access your machines over the internet. The service uses `vars` to store the SSH host keys for each machine to ensure they remain stable across deployments.
|
||||
|
||||
`sshd` also generates SSH certificates for both servers and clients allowing for certificate-based authentication for SSH.
|
||||
|
||||
The service also disables password-based authentication over SSH, to access your machines you'll need to use public key authentication or certificate-based authentication.
|
||||
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
{
|
||||
inventory.instances = {
|
||||
# By default this service only generates ed25519 host keys
|
||||
sshd-basic = {
|
||||
module = {
|
||||
name = "sshd";
|
||||
input = "clan-core";
|
||||
};
|
||||
roles.server.tags.all = { };
|
||||
roles.client.tags.all = { };
|
||||
};
|
||||
|
||||
# Also generate RSA host keys for all servers
|
||||
sshd-with-rsa = {
|
||||
module = {
|
||||
name = "sshd";
|
||||
input = "clan-core";
|
||||
};
|
||||
roles.server.tags.all = { };
|
||||
roles.server.settings = {
|
||||
hostKeys.rsa.enable = true;
|
||||
};
|
||||
roles.client.tags.all = { };
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The sshd module has the following roles:
|
||||
|
||||
- client
|
||||
- server
|
||||
## Options for the `client` role
|
||||
#### certificate.searchDomains
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List of domains to include in the certificate.
|
||||
This option will prepend the machine name in front of each domain
|
||||
before adding it to the certificate.
|
||||
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"mydomain.com"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/sshd/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/sshd/default.nix)
|
||||
|
||||
|
||||
## Options for the `server` role
|
||||
#### certificate.searchDomains
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List of domains to include in the certificate. This option will
|
||||
prepend the machine name in front of each domain before adding
|
||||
it to the certificate.
|
||||
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"mydomain.com"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/sshd/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/sshd/default.nix)
|
||||
|
||||
|
||||
|
||||
#### hostKeys.rsa.enable
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Whether to enable Generate RSA host key.
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
false
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
true
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/sshd/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/sshd/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
---
|
||||
title: syncthing
|
||||
description: Syncthing is a continuous file synchronization program with automatic peer discovery
|
||||
---
|
||||
|
||||
*Syncthing is a continuous file synchronization program with automatic peer discovery*
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
{
|
||||
instances.syncthing = {
|
||||
roles.peer.tags.all = { };
|
||||
roles.peer.settings.folders = {
|
||||
documents = {
|
||||
path = "~/syncthing/documents";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Now the folder `~/syncthing/documents` will be shared with all your machines.
|
||||
|
||||
|
||||
## Documentation
|
||||
Extensive documentation is available on the [Syncthing](https://docs.syncthing.net/) website.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The syncthing module has the following roles:
|
||||
|
||||
- peer
|
||||
## Options for the `peer` role
|
||||
#### extraDevices
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
External syncthing devices not managed by clan (e.g., mobile phones)
|
||||
|
||||
|
||||
**Type**: `attribute set of (submodule)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
{
|
||||
phone = {
|
||||
id = "P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2";
|
||||
name = "My Phone";
|
||||
addresses = [ "dynamic" ];
|
||||
};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### extraDevices.<name\>.addresses
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List of addresses for the device
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[
|
||||
"dynamic"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"dynamic"
|
||||
"tcp://192.168.1.100:22000"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### extraDevices.<name\>.id
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Device ID of the external syncthing device
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### extraDevices.<name\>.name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Human readable name for the device
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
""
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Folders to synchronize between all peers
|
||||
|
||||
|
||||
**Type**: `attribute set of (submodule)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders.<name\>.devices
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List of device names to share this folder with. Empty list means all peers and extraDevices.
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders.<name\>.ignorePerms
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Ignore permission changes
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
false
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders.<name\>.path
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Path to the folder to sync
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders.<name\>.rescanIntervalS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Rescan interval in seconds
|
||||
|
||||
|
||||
**Type**: `signed integer`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
3600
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders.<name\>.type
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Folder type
|
||||
|
||||
|
||||
**Type**: `one of "sendreceive", "sendonly", "receiveonly"`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"sendreceive"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders.<name\>.versioning
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Versioning configuration
|
||||
|
||||
|
||||
**Type**: `null or (submodule)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
null
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders.<name\>.versioning.params
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Versioning parameters
|
||||
|
||||
|
||||
**Type**: `attribute set of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### folders.<name\>.versioning.type
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Versioning type
|
||||
|
||||
|
||||
**Type**: `one of "external", "simple", "staggered", "trashcan"`
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
|
||||
#### openDefaultPorts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Whether to open the default syncthing ports in the firewall.
|
||||
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
true
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/syncthing/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/syncthing/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: trusted-nix-caches
|
||||
description: This module sets the `clan.lol` and `nix-community` cache up as a trusted cache.
|
||||
---
|
||||
|
||||
*This module sets the `clan.lol` and `nix-community` cache up as a trusted cache.*
|
||||
Sets up nix to trust and use the clan cache
|
||||
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
inventory.instances = {
|
||||
clan-cache = {
|
||||
module = {
|
||||
name = "trusted-nix-caches";
|
||||
input = "clan-core";
|
||||
};
|
||||
roles.default.machines.draper = { };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The trusted-nix-caches module has the following roles:
|
||||
|
||||
- default
|
||||
This role has no configuration
|
||||
242
tested-trappist/src/content/docs/reference/clanServices/users.md
Normal file
242
tested-trappist/src/content/docs/reference/clanServices/users.md
Normal file
@@ -0,0 +1,242 @@
|
||||
---
|
||||
title: users
|
||||
description: An instance of this module will create a user account on the added machines, along with a generated password that is constant across machines and user settings.
|
||||
---
|
||||
|
||||
*An instance of this module will create a user account on the added machines,
|
||||
along with a generated password that is constant across machines and user settings.
|
||||
*
|
||||
## Usage
|
||||
|
||||
```nix
|
||||
{
|
||||
inventory.instances = {
|
||||
# Deploy user alice on all machines. Don't prompt for password (will be
|
||||
# auto-generated).
|
||||
user-alice = {
|
||||
module = {
|
||||
name = "users";
|
||||
input = "clan-core";
|
||||
};
|
||||
roles.default.tags.all = { };
|
||||
roles.default.settings = {
|
||||
user = "alice";
|
||||
prompt = false;
|
||||
};
|
||||
};
|
||||
|
||||
# Deploy user Carol on all machines. Prompt only once and use the
|
||||
# same password on all machines. (`share = true`)
|
||||
user-carol = {
|
||||
module = {
|
||||
name = "users";
|
||||
input = "clan";
|
||||
};
|
||||
roles.default.tags.all = { };
|
||||
roles.default.settings = {
|
||||
user = "carol";
|
||||
share = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Deploy user bob only on his laptop. Prompt for a password.
|
||||
user-bob = {
|
||||
module = {
|
||||
name = "users";
|
||||
input = "clan-core";
|
||||
};
|
||||
roles.default.machines.bobs-laptop = { };
|
||||
roles.default.settings.user = "bob";
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Migration from `root-password` module
|
||||
|
||||
The deprecated `clan.root-password` module has been replaced by the `users` module. Here's how to migrate:
|
||||
|
||||
### 1. Update your flake configuration
|
||||
|
||||
Replace the `root-password` module import with a `users` service instance:
|
||||
|
||||
```nix
|
||||
# OLD - Remove this from your nixosModules:
|
||||
imports = [
|
||||
self.inputs.clan-core.clanModules.root-password
|
||||
];
|
||||
|
||||
# NEW - Add to inventory.instances or machines/flake-module.nix:
|
||||
instances = {
|
||||
users-root = {
|
||||
module.name = "users";
|
||||
module.input = "clan-core";
|
||||
roles.default.tags.nixos = { };
|
||||
roles.default.settings = {
|
||||
user = "root";
|
||||
prompt = false; # Set to true if you want to be prompted
|
||||
groups = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Migrate vars
|
||||
|
||||
The vars structure has changed from `root-password` to `user-password-root`:
|
||||
|
||||
```bash
|
||||
# For each machine, rename the vars directories:
|
||||
cd vars/per-machine/<machine-name>/
|
||||
mv root-password user-password-root
|
||||
mv user-password-root/password-hash user-password-root/user-password-hash
|
||||
mv user-password-root/password user-password-root/user-password
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The users module has the following roles:
|
||||
|
||||
- default
|
||||
## Options for the `default` role
|
||||
#### groups
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Additional groups the user should be added to.
|
||||
You can add any group that exists on your system.
|
||||
Make sure these group exists on all machines where the user is enabled.
|
||||
|
||||
Commonly used groups:
|
||||
|
||||
- "wheel" - Allows the user to run commands as root using `sudo`.
|
||||
- "networkmanager" - Allows the user to manage network connections.
|
||||
- "video" - Allows the user to access video devices.
|
||||
- "input" - Allows the user to access input devices.
|
||||
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
[
|
||||
"wheel"
|
||||
"networkmanager"
|
||||
"video"
|
||||
"input"
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/users/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/users/default.nix)
|
||||
|
||||
|
||||
|
||||
#### prompt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Whether the user should be prompted for a password.
|
||||
|
||||
Effects:
|
||||
|
||||
- *enabled* (`true`) - Prompt for a password during the machine installation or update workflow.
|
||||
- *disabled* (`false`) - Generate a password during the machine installation or update workflow.
|
||||
|
||||
The password can be shown in two steps:
|
||||
|
||||
- `clan vars list <machine-name>`
|
||||
- `clan vars get <machine-name> <name-of-password-variable>`
|
||||
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
true
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
false
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/users/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/users/default.nix)
|
||||
|
||||
|
||||
|
||||
#### share
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Weather the user should have the same password on all machines.
|
||||
|
||||
By default, you will be prompted for a new password for every host.
|
||||
Unless `generate` is set to `true`.
|
||||
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
false
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
true
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/users/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/users/default.nix)
|
||||
|
||||
|
||||
|
||||
#### user
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The user the password should be generated for.
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"alice"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/users/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/users/default.nix)
|
||||
|
||||
|
||||
109
tested-trappist/src/content/docs/reference/clanServices/wifi.md
Normal file
109
tested-trappist/src/content/docs/reference/clanServices/wifi.md
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: wifi
|
||||
description: No description
|
||||
---
|
||||
|
||||
*No description*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The wifi module has the following roles:
|
||||
|
||||
- default
|
||||
## Options for the `default` role
|
||||
#### networks
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Wifi networks to predefine
|
||||
|
||||
|
||||
**Type**: `attribute set of (submodule)`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
{ }
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/wifi/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wifi/default.nix)
|
||||
|
||||
|
||||
|
||||
#### networks.<name\>.autoConnect
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Automatically try to join this wifi network
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
true
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/wifi/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wifi/default.nix)
|
||||
|
||||
|
||||
|
||||
#### networks.<name\>.enable
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Enable this wifi network
|
||||
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
true
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/wifi/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wifi/default.nix)
|
||||
|
||||
|
||||
|
||||
#### networks.<name\>.keyMgmt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Key management used for the connection.
|
||||
One of "none" (WEP or no password protection), "ieee8021x" (Dynamic WEP), "owe" (Opportunistic Wireless Encryption), "wpa-psk" (WPA2 + WPA3 personal),
|
||||
"sae" (WPA3 personal only), "wpa-eap" (WPA2 + WPA3 enterprise) or "wpa-eap-suite-b-192" (WPA3 enterprise only).
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
"wpa-psk"
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/wifi/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wifi/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,390 @@
|
||||
---
|
||||
title: wireguard
|
||||
description: Wireguard-based VPN mesh network with automatic IPv6 address allocation
|
||||
---
|
||||
|
||||
*Wireguard-based VPN mesh network with automatic IPv6 address allocation*
|
||||
# Wireguard VPN Service
|
||||
|
||||
This service provides a Wireguard-based VPN mesh network with automatic IPv6 address allocation and routing between clan machines.
|
||||
|
||||
## Overview
|
||||
|
||||
The wireguard service creates a secure mesh network between clan machines using two roles:
|
||||
- **Controllers**: Machines with public endpoints that act as connection points and routers
|
||||
- **Peers**: Machines that connect through controllers to access the network
|
||||
|
||||
## Requirements
|
||||
|
||||
- Controllers must have a publicly accessible endpoint (domain name or static IP)
|
||||
- Peers must be in networks where UDP traffic is not blocked (uses port 51820 by default, configurable)
|
||||
|
||||
## Features
|
||||
|
||||
- Automatic IPv6 address allocation using ULA (Unique Local Address) prefixes
|
||||
- Full mesh connectivity between all machines
|
||||
- Automatic key generation and distribution
|
||||
- IPv6 forwarding on controllers for inter-peer communication
|
||||
- Support for multiple controllers for redundancy
|
||||
|
||||
## Network Architecture
|
||||
|
||||
### IPv6 Address Allocation
|
||||
- Base network: `/40` ULA prefix (deterministically generated from instance name)
|
||||
- Controllers: Each gets a `/56` subnet from the base `/40`
|
||||
- Peers: Each gets a unique 64-bit host suffix that is used in ALL controller subnets
|
||||
|
||||
### Addressing Design
|
||||
- Each peer generates a unique host suffix (e.g., `:8750:a09b:0:1`)
|
||||
- This suffix is appended to each controller's `/56` prefix to create unique addresses
|
||||
- Example: peer1 with suffix `:8750:a09b:0:1` gets:
|
||||
- `fd51:19c1:3b:f700:8750:a09b:0:1` in controller1's subnet
|
||||
- `fd51:19c1:c1:aa00:8750:a09b:0:1` in controller2's subnet
|
||||
- Controllers allow each peer's `/96` subnet for routing flexibility
|
||||
|
||||
### Connectivity
|
||||
- Peers use a single WireGuard interface with multiple IPs (one per controller subnet)
|
||||
- Controllers connect to ALL other controllers and ALL peers on a single interface
|
||||
- Controllers have IPv6 forwarding enabled to route traffic between peers
|
||||
- All traffic between peers flows through controllers
|
||||
- Symmetric routing is maintained as each peer has consistent IPs across all controllers
|
||||
|
||||
### Example Network Topology
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph Controllers
|
||||
C1[controller1<br/>endpoint: vpn1.example.com<br/>fd51:19c1:3b:f700::/56]
|
||||
C2[controller2<br/>endpoint: vpn2.example.com<br/>fd51:19c1:c1:aa00::/56]
|
||||
end
|
||||
|
||||
subgraph Peers
|
||||
P1[peer1<br/>designated: controller1]
|
||||
P2[peer2<br/>designated: controller2]
|
||||
P3[peer3<br/>designated: controller1]
|
||||
end
|
||||
|
||||
%% Controllers connect to each other
|
||||
C1 <--> C2
|
||||
|
||||
%% All peers connect to all controllers
|
||||
P1 <--> C1
|
||||
P1 <--> C2
|
||||
P2 <--> C1
|
||||
P2 <--> C2
|
||||
P3 <--> C1
|
||||
P3 <--> C2
|
||||
|
||||
%% Peer-to-peer traffic flows through controllers
|
||||
P1 -.->|via controllers| P3
|
||||
P1 -.->|via controllers| P2
|
||||
P2 -.->|via controllers| P3
|
||||
|
||||
classDef controller fill:#f9f,stroke:#333,stroke-width:4px
|
||||
classDef peer fill:#bbf,stroke:#333,stroke-width:2px
|
||||
class C1,C2 controller
|
||||
class P1,P2,P3 peer
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Basic Setup with Single Controller
|
||||
|
||||
```nix
|
||||
# In your flake.nix or inventory
|
||||
{
|
||||
services.wireguard.server1 = {
|
||||
roles.controller = {
|
||||
# Public endpoint where this controller can be reached
|
||||
endpoint = "vpn.example.com";
|
||||
# Optional: Change the UDP port (default: 51820)
|
||||
port = 51820;
|
||||
};
|
||||
};
|
||||
|
||||
services.wireguard.laptop1 = {
|
||||
roles.peer = {
|
||||
# No configuration needed if only one controller exists
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple Controllers Setup
|
||||
|
||||
```nix
|
||||
{
|
||||
services.wireguard.server1 = {
|
||||
roles.controller = {
|
||||
endpoint = "vpn1.example.com";
|
||||
};
|
||||
};
|
||||
|
||||
services.wireguard.server2 = {
|
||||
roles.controller = {
|
||||
endpoint = "vpn2.example.com";
|
||||
};
|
||||
};
|
||||
|
||||
services.wireguard.laptop1 = {
|
||||
roles.peer = {
|
||||
# Must specify which controller subnet is exposed as the default in /etc/hosts, when multiple controllers exist
|
||||
controller = "server1";
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Advanced Options
|
||||
|
||||
|
||||
### Automatic Hostname Resolution
|
||||
|
||||
The wireguard service automatically adds entries to `/etc/hosts` for all machines in the network. Each machine is accessible via its hostname in the format `<machine-name>.<instance-name>`.
|
||||
|
||||
For example, with an instance named `vpn`:
|
||||
- `server1.vpn` - resolves to server1's IPv6 address
|
||||
- `laptop1.vpn` - resolves to laptop1's IPv6 address
|
||||
|
||||
This allows machines to communicate using hostnames instead of IPv6 addresses:
|
||||
|
||||
```bash
|
||||
# Ping another machine by hostname
|
||||
ping6 server1.vpn
|
||||
|
||||
# SSH to another machine
|
||||
ssh user@laptop1.vpn
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Check Wireguard Status
|
||||
```bash
|
||||
sudo wg show
|
||||
```
|
||||
|
||||
### Verify IP Addresses
|
||||
```bash
|
||||
ip addr show dev <instance-name>
|
||||
```
|
||||
|
||||
### Check Routing
|
||||
```bash
|
||||
ip -6 route show dev <instance-name>
|
||||
```
|
||||
|
||||
### Interface Fails to Start: "Address already in use"
|
||||
|
||||
If you see this error in your logs:
|
||||
```
|
||||
wireguard: Could not bring up interface, ignoring: Address already in use
|
||||
```
|
||||
|
||||
This means the configured port (default: 51820) is already in use by another service or wireguard instance. Solutions:
|
||||
|
||||
1. **Check for conflicting wireguard instances:**
|
||||
```bash
|
||||
sudo wg show
|
||||
sudo ss -ulnp | grep 51820
|
||||
```
|
||||
|
||||
2. **Use a different port:**
|
||||
```nix
|
||||
services.wireguard.myinstance = {
|
||||
roles.controller = {
|
||||
endpoint = "vpn.example.com";
|
||||
port = 51821; # Use a different port
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
3. **Ensure unique ports across multiple instances:**
|
||||
If you have multiple wireguard instances on the same machine, each must use a different port.
|
||||
|
||||
### Key Management
|
||||
|
||||
Keys are automatically generated and stored in the clan vars system. To regenerate keys:
|
||||
|
||||
```bash
|
||||
# Regenerate keys for a specific machine and instance
|
||||
clan vars generate --service wireguard-keys-<instance-name> --regenerate --machine <machine-name>
|
||||
|
||||
# Apply the new keys
|
||||
clan machines update <machine-name>
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- All traffic is encrypted using Wireguard's modern cryptography
|
||||
- Private keys never leave the machines they're generated on
|
||||
- Public keys are distributed through the clan vars system
|
||||
- Controllers must have publicly accessible endpoints
|
||||
- Firewall rules are automatically configured for the Wireguard ports
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The wireguard module has the following roles:
|
||||
|
||||
- controller
|
||||
- peer
|
||||
## Options for the `controller` role
|
||||
#### domain
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Domain suffix to use for hostnames in /etc/hosts.
|
||||
Defaults to the instance name.
|
||||
|
||||
|
||||
|
||||
**Type**: `null or string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
instanceName
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/wireguard/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wireguard/default.nix)
|
||||
|
||||
|
||||
|
||||
#### endpoint
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Endpoint where the controller can be reached
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"vpn.clan.lol"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/wireguard/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wireguard/default.nix)
|
||||
|
||||
|
||||
|
||||
#### port
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Port for the wireguard interface
|
||||
|
||||
|
||||
|
||||
**Type**: `signed integer`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
51820
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
51820
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/wireguard/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wireguard/default.nix)
|
||||
|
||||
|
||||
## Options for the `peer` role
|
||||
#### controller
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Machinename of the controller to attach to
|
||||
|
||||
|
||||
|
||||
**Type**: `string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
"controller1"
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/wireguard/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wireguard/default.nix)
|
||||
|
||||
|
||||
|
||||
#### domain
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Domain suffix to use for hostnames in /etc/hosts.
|
||||
Defaults to the instance name.
|
||||
|
||||
|
||||
|
||||
**Type**: `null or string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
instanceName
|
||||
```
|
||||
|
||||
📃 Declared in: [clanServices/wireguard/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wireguard/default.nix)
|
||||
|
||||
|
||||
|
||||
#### port
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Port for the wireguard interface
|
||||
|
||||
|
||||
|
||||
**Type**: `signed integer`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
51820
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
51820
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/wireguard/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/wireguard/default.nix)
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
---
|
||||
title: zerotier
|
||||
description: Configuration of the secure and efficient Zerotier VPN
|
||||
---
|
||||
|
||||
*Configuration of the secure and efficient Zerotier VPN*
|
||||
## Usage
|
||||
|
||||
```
|
||||
inventory.instances = {
|
||||
zerotier = {
|
||||
module = {
|
||||
name = "zerotier";
|
||||
input = "clan-core";
|
||||
};
|
||||
roles.peer.tags.all = { };
|
||||
roles.controller.machines.jon = { };
|
||||
roles.moon.machines.sara.settings.stableEndpoints = [ "77.52.165.46" ];
|
||||
};
|
||||
```
|
||||
|
||||
The input should be named according to your flake input.
|
||||
All machines will be peers and connected to the zerotier network.
|
||||
Jon is the controller machine, which will will accept other machines into the network.
|
||||
Sara is a moon and sets the `stableEndpoint` setting with a publicly reachable IP, the moon is optional.
|
||||
|
||||
## Overview
|
||||
|
||||
This guide explains how to set up and manage a [ZeroTier VPN](https://zerotier.com) for a clan network. Each VPN requires a single controller and can support multiple peers and optional moons for better connectivity.
|
||||
|
||||
## Roles
|
||||
|
||||
### 1. Controller
|
||||
|
||||
The [Controller](https://docs.zerotier.com/controller/) manages network membership and is responsible for admitting new peers.
|
||||
When a new node is added to the clan, the controller must be updated to ensure it has the latest member list.
|
||||
|
||||
- **Key Points:**
|
||||
- Must be online to admit new machines to the VPN.
|
||||
- Existing nodes can continue to communicate even when the controller is offline.
|
||||
|
||||
### 2. Moons
|
||||
|
||||
[Moons](https://docs.zerotier.com/roots) act as relay nodes,
|
||||
providing direct connectivity to peers via their public IP addresses.
|
||||
They enable devices that are not publicly reachable to join the VPN by routing through these nodes.
|
||||
|
||||
- **Configuration Notes:**
|
||||
- Each moon must define its public IP address.
|
||||
- Ensures connectivity for devices behind NAT or restrictive firewalls.
|
||||
|
||||
### 3. Peers
|
||||
|
||||
Peers are standard nodes in the VPN.
|
||||
They connect to other peers, moons, and the controller as needed.
|
||||
|
||||
- **Purpose:**
|
||||
- General role for all machines that are neither controllers nor moons.
|
||||
- Ideal for most clan members devices.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Roles
|
||||
The zerotier module has the following roles:
|
||||
|
||||
- controller
|
||||
- moon
|
||||
- peer
|
||||
## Options for the `controller` role
|
||||
#### allowedIps
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Extra machines by their zerotier ip that the zerotier controller
|
||||
should accept. These could be external machines.
|
||||
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
**Default**:
|
||||
|
||||
```nix
|
||||
[ ]
|
||||
```
|
||||
|
||||
|
||||
```nix title="example"
|
||||
''
|
||||
[ "fd5d:bbe3:cbc5:fe6b:f699:935d:bbe3:cbc5" ]
|
||||
''
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/zerotier/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/zerotier/default.nix)
|
||||
|
||||
|
||||
## Options for the `moon` role
|
||||
#### stableEndpoints
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Make this machine a moon.
|
||||
Other machines can join this moon by adding this moon in their config.
|
||||
It will be reachable under the given stable endpoints.
|
||||
|
||||
|
||||
|
||||
**Type**: `list of string`
|
||||
|
||||
|
||||
|
||||
```nix title="example"
|
||||
''
|
||||
[ "1.2.3.4" "10.0.0.3/9993" "2001:abcd:abcd::3/9993" ]
|
||||
''
|
||||
```
|
||||
|
||||
|
||||
📃 Declared in: [clanServices/zerotier/default.nix](https://git.clan.lol/clan/clan-core/src/branch/main//clanServices/zerotier/default.nix)
|
||||
|
||||
|
||||
This role has no configuration
|
||||
5
tested-trappist/tsconfig.json
Normal file
5
tested-trappist/tsconfig.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
Reference in New Issue
Block a user