- Download the [NixOS ISO installer](https://nixos.org/download/#nixos-iso).
- Refer to the [NixOS Manual](https://nixos.org/manual/nixos/stable/) for further instructions.
## Security
Below are described the general security principles followed throughout this project:
- Never lean on security through obscurity.
- Minimize friction induced by security. Friction induces laziness, which inevitably circumvents the original security system.
- Understand that security practices cannot *eliminate* vulnerability of the system, only make it *too expensive* to attack.
- Tie less important secrets to more important secrets, but not vice-versa.
Further, we have some tool-specific guidelines.
### Securing SSH
When configuring the SSH server for a local host or VPS, or when provisioning a new SSH keypair.
- Generate one private key for each user-machine pair.
- Do not automate dissemination of pubkeys. Always install pubkeys manually.
- Disable password-based authentication.
- Disable root login.
### Docker Compose
To write secrets into `docker-compose.yml` files securely, we use the following [`env_file`](https://docs.docker.com/reference/compose-file/services/#env_file) snippet:
```yaml
env_file:
- path: ./<service>.secrets
required: true
```
And we then write the required secrets in [dotenv format](https://www.dotenv.org/docs/security/env.html) in a file located at `./<service>.secrets`. For example:
```dotenv
API_KEY=zj1vtmUNGIfHJBfYsDINr8AVN5on1Hy0
# ROOT_PASSWORD=changeme
ROOT_PASSWORD=0gavJVrsv89bmdDeJXAcI1eCvQ4Um8Hy
```
When these files are staged in git, our [.gitattributes](/.gitattributes) runs the `sops` filter against any file matching one of its described patterns.
### Web Services
**If a service supports OAuth2**, we configure [Keycloak SSO]() for that service.
When feasible, we shift responsibility for authentication and authorization to Keycloak. This is dependent on each service implementing OAuth2/OpenIDConnect.
**If a service does not support OAuth2**, but it does support authentication via the `X-Forwarded-User` header, we use [mesosphere/traefik-forward-auth](https://github.com/mesosphere/traefik-forward-auth) as a Traefik middleware. This middleare restricts access to the service regardless of whether the service understands the `X-Forwarded-User` header, which makes it useful for compatible multi-user applications *and* single-user applications.
**If a service should not be internet-accessible**, we use Traefik's [`ipWhiteList`](https://doc.traefik.io/traefik/middlewares/http/ipwhitelist/) middleware to restrict access to LAN IPs only.
**Else**, some services *absolutely require* separate authentication (e.g. Plex, N8n). In such cases, we create user credentials as we would for any internet service; using our password manager.