Mochi init
This commit is contained in:
commit
cc530d3d5f
90 changed files with 3276 additions and 0 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
use nix
|
50
.forgejo/workflows/build.yml
Normal file
50
.forgejo/workflows/build.yml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
name: "Build"
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
jobs:
|
||||||
|
nix-build:
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- system: varda
|
||||||
|
os: native-aarch64
|
||||||
|
- system: durincore
|
||||||
|
os: native-x86_64
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
PATH: ${{ format('{0}:{1}', '/run/current-system/sw/bin', env.PATH) }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: https://github.com/cachix/cachix-action@v15
|
||||||
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
|
with:
|
||||||
|
name: hsndev
|
||||||
|
# If you chose API tokens for write access OR if you have a private cache
|
||||||
|
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||||
|
# env:
|
||||||
|
# USER: 'root'
|
||||||
|
|
||||||
|
- name: Garbage collect build dependencies
|
||||||
|
run: nix-collect-garbage
|
||||||
|
|
||||||
|
- name: Build new ${{ matrix.system }} system
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
nix build \
|
||||||
|
".#top.${{ matrix.system }}" \
|
||||||
|
--profile ./profile \
|
||||||
|
--fallback \
|
||||||
|
-v \
|
||||||
|
--log-format raw \
|
||||||
|
> >(tee stdout.log) 2> >(tee /tmp/nix-build-err.log >&2)
|
||||||
|
- name: Push to Cachix
|
||||||
|
if: success()
|
||||||
|
env:
|
||||||
|
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
|
||||||
|
run: nix build ".#top.${{ matrix.system }}" --json | jq -r .[].drvPath | cachix push hsndev
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
**/*.tmp.sops.yaml
|
||||||
|
**/*.sops.tmp.yaml
|
||||||
|
age.key
|
||||||
|
result*
|
||||||
|
.direnv
|
||||||
|
.kube
|
38
.pre-commit-config.yaml
Normal file
38
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
fail_fast: false
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/adrienverge/yamllint
|
||||||
|
rev: v1.35.1
|
||||||
|
hooks:
|
||||||
|
- args:
|
||||||
|
- --config-file
|
||||||
|
- .yamllint.yaml
|
||||||
|
id: yamllint
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.6.0
|
||||||
|
hooks:
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: fix-byte-order-marker
|
||||||
|
- id: mixed-line-ending
|
||||||
|
- id: check-added-large-files
|
||||||
|
args: [--maxkb=2048]
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: check-executables-have-shebangs
|
||||||
|
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
||||||
|
rev: v1.5.5
|
||||||
|
hooks:
|
||||||
|
- id: remove-crlf
|
||||||
|
- id: remove-tabs
|
||||||
|
exclude: (Makefile)
|
||||||
|
- repo: https://github.com/zricethezav/gitleaks
|
||||||
|
rev: v8.18.2
|
||||||
|
hooks:
|
||||||
|
- id: gitleaks
|
||||||
|
- repo: https://github.com/yuvipanda/pre-commit-hook-ensure-sops
|
||||||
|
rev: v1.1
|
||||||
|
hooks:
|
||||||
|
- id: sops-encryption
|
||||||
|
# Uncomment to exclude all markdown files from encryption
|
||||||
|
# exclude: *.\.md
|
29
.sops.yaml
Normal file
29
.sops.yaml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
# config files for sops & used for encrypting keys that sops-nix decrypts.
|
||||||
|
# each machine key is derieved from its generated `ssh_hosts_ed` file
|
||||||
|
# via ssh-to-age
|
||||||
|
# sops encrypts the secrets ready to decrypt with the private key of any of the below machines
|
||||||
|
# OR my 'main' key thats kept outside this repo securely.
|
||||||
|
|
||||||
|
# key-per-machine is a little more secure and a little more work than
|
||||||
|
# copying one key to each machine
|
||||||
|
|
||||||
|
keys:
|
||||||
|
- users:
|
||||||
|
- &jahanson age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
|
||||||
|
- hosts:
|
||||||
|
- &durincore age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
|
||||||
|
- &gandalf age1nuj9sk2k8ede06f8gk5twdlc593uuc7lll2dvuy20nxw9zn97u5swrcjpj
|
||||||
|
- &telperion age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
|
||||||
|
- &varda age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
|
||||||
|
|
||||||
|
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: .*\.sops\.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *durincore
|
||||||
|
- *gandalf
|
||||||
|
- *jahanson
|
||||||
|
- *telperion
|
||||||
|
- *varda
|
23
.taskfiles/pre-commit/Taskfile.yaml
Normal file
23
.taskfiles/pre-commit/Taskfile.yaml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
# yaml-language-server: $schema=https://taskfile.dev/schema.json
|
||||||
|
version: "3"
|
||||||
|
|
||||||
|
vars:
|
||||||
|
host: $HOSTNAME
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
init:
|
||||||
|
desc: Initialize pre-commit hooks
|
||||||
|
cmds:
|
||||||
|
- pre-commit install --install-hooks
|
||||||
|
|
||||||
|
update:
|
||||||
|
desc: Update pre-commit dependencies
|
||||||
|
cmds:
|
||||||
|
- pre-commit autoupdate
|
||||||
|
|
||||||
|
run:
|
||||||
|
desc: Run pre-commit
|
||||||
|
cmds:
|
||||||
|
- pre-commit run --all-files
|
18
.taskfiles/sops/Taskfile.yaml
Normal file
18
.taskfiles/sops/Taskfile.yaml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
# yaml-language-server: $schema=https://taskfile.dev/schema.json
|
||||||
|
version: "3"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
re-encrypt:
|
||||||
|
desc: Decrypt and re-encrypt all sops secrets
|
||||||
|
silent: true
|
||||||
|
dir: "{{.USER_WORKING_DIR}}"
|
||||||
|
vars:
|
||||||
|
SECRET_FILES:
|
||||||
|
sh: find . -type f -name '*.sops.yaml' ! -name ".sops.yaml"
|
||||||
|
cmds:
|
||||||
|
- for: { var: SECRET_FILES }
|
||||||
|
cmd: |
|
||||||
|
echo "Re-encrypting {{ .ITEM }}"
|
||||||
|
sops --decrypt --in-place "{{ .ITEM }}"
|
||||||
|
sops --encrypt --in-place "{{ .ITEM }}"
|
11
.vscode/extensions.json
vendored
Normal file
11
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"jnoortheen.nix-ide",
|
||||||
|
"mikestead.dotenv",
|
||||||
|
"redhat.ansible",
|
||||||
|
"redhat.vscode-yaml",
|
||||||
|
"signageos.signageos-vscode-sops",
|
||||||
|
"pkief.material-icon-theme",
|
||||||
|
"ms-vscode-remote.remote-ssh"
|
||||||
|
]
|
||||||
|
}
|
32
.vscode/module.code-snippets
vendored
Normal file
32
.vscode/module.code-snippets
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"nix-module": {
|
||||||
|
"prefix": "nm",
|
||||||
|
"body": [
|
||||||
|
"{ lib",
|
||||||
|
", config",
|
||||||
|
", pkgs",
|
||||||
|
", ...",
|
||||||
|
"}:",
|
||||||
|
"with lib;",
|
||||||
|
"let",
|
||||||
|
" cfg = config.mySystem.${1}.${2};",
|
||||||
|
" app = \"${3}\"",
|
||||||
|
" appFolder = \"apps/${app}\";",
|
||||||
|
" persistentFolder = \"${config.mySystem.persistentFolder}/${appFolder}\";",
|
||||||
|
" user = app;",
|
||||||
|
" group = app;",
|
||||||
|
"in",
|
||||||
|
"{",
|
||||||
|
" options.mySystem.${1}.${2}.enable = mkEnableOption \"${4}\";",
|
||||||
|
"",
|
||||||
|
" config = mkIf cfg.enable {",
|
||||||
|
"",
|
||||||
|
" $5",
|
||||||
|
"",
|
||||||
|
" };",
|
||||||
|
"}",
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"description": "nix-module"
|
||||||
|
}
|
||||||
|
}
|
27
.yamllint.yaml
Normal file
27
.yamllint.yaml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
ignore: |
|
||||||
|
.direnv/
|
||||||
|
.private/
|
||||||
|
.vscode/
|
||||||
|
*.sops.*
|
||||||
|
|
||||||
|
extends: default
|
||||||
|
|
||||||
|
rules:
|
||||||
|
truthy:
|
||||||
|
allowed-values: ["true", "false", "on"]
|
||||||
|
|
||||||
|
comments:
|
||||||
|
min-spaces-from-content: 1
|
||||||
|
|
||||||
|
line-length: disable
|
||||||
|
|
||||||
|
braces:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 1
|
||||||
|
|
||||||
|
brackets:
|
||||||
|
min-spaces-inside: 0
|
||||||
|
max-spaces-inside: 0
|
||||||
|
|
||||||
|
indentation: enable
|
23
README.md
Normal file
23
README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# jahanson's homelab
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
- [ ] Learn nix
|
||||||
|
- [ ] Services I want to separate from my kubernetes cluster I will use Nix.
|
||||||
|
- [ ] Approval-based update automation for flakes.
|
||||||
|
- [ ] Expand usage to other shell environments such as WSL, etc
|
||||||
|
- [ ] keep it simple, use trusted boring tools
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
- [ x ] Forgejo Actions
|
||||||
|
- [ ] Bring over hosts
|
||||||
|
- [ x ] Varda (forgejo)
|
||||||
|
- [ ] Telperion (network services)
|
||||||
|
- [ ] Gandalf (NixNAS)
|
||||||
|
- [ x ] Thinkpad T470
|
||||||
|
|
||||||
|
## Links & References
|
||||||
|
|
||||||
|
- [truxnell/dotfiles](https://github.com//truxnell/nix-config/)
|
||||||
|
- [billimek/dotfiles](https://github.com/billimek/dotfiles/)
|
33
Taskfile.yaml
Normal file
33
Taskfile.yaml
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
# go-task runner file - rest of config in .taskfiles/**.*.yaml
|
||||||
|
version: "3"
|
||||||
|
|
||||||
|
includes:
|
||||||
|
sops:
|
||||||
|
taskfile: ".taskfiles/sops"
|
||||||
|
dir: .taskfiles/sops
|
||||||
|
pre:
|
||||||
|
taskfile: ".taskfiles/pre-commit"
|
||||||
|
dir: "{{.ROOT_DOR}}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
silent: true
|
||||||
|
cmds:
|
||||||
|
- task -l
|
||||||
|
|
||||||
|
lint:
|
||||||
|
desc: Run statix lint
|
||||||
|
cmds:
|
||||||
|
- statix check .
|
||||||
|
|
||||||
|
check:
|
||||||
|
desc: Check project files
|
||||||
|
cmds:
|
||||||
|
- task: lint
|
||||||
|
- task: pc-run
|
||||||
|
|
||||||
|
format:
|
||||||
|
desc: Check project files
|
||||||
|
cmds:
|
||||||
|
- nixpkgs-fmt {{.ROOT_DIR}}
|
0
flake.nix
Normal file
0
flake.nix
Normal file
93
nixos/home/jahanson/global.nix
Normal file
93
nixos/home/jahanson/global.nix
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
with config;
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
../modules
|
||||||
|
];
|
||||||
|
|
||||||
|
config = {
|
||||||
|
myHome.username = "jahanson";
|
||||||
|
myHome.homeDirectory = "/home/jahanson/";
|
||||||
|
|
||||||
|
systemd.user.sessionVariables = {
|
||||||
|
EDITOR = "vim";
|
||||||
|
};
|
||||||
|
|
||||||
|
home = {
|
||||||
|
# Install these packages for my user
|
||||||
|
packages = with pkgs; [
|
||||||
|
# misc
|
||||||
|
file
|
||||||
|
which
|
||||||
|
tree
|
||||||
|
gnused
|
||||||
|
gnutar
|
||||||
|
gawk
|
||||||
|
zstd
|
||||||
|
gnupg
|
||||||
|
|
||||||
|
# archives
|
||||||
|
zip
|
||||||
|
xz
|
||||||
|
unzip
|
||||||
|
p7zip
|
||||||
|
|
||||||
|
# cli
|
||||||
|
_1password
|
||||||
|
bat
|
||||||
|
dbus
|
||||||
|
direnv
|
||||||
|
git
|
||||||
|
nix-index
|
||||||
|
python3
|
||||||
|
fzf
|
||||||
|
ripgrep
|
||||||
|
vim
|
||||||
|
lsd
|
||||||
|
|
||||||
|
# terminal file managers
|
||||||
|
nnn
|
||||||
|
ranger
|
||||||
|
yazi
|
||||||
|
|
||||||
|
# networking tools
|
||||||
|
iperf3
|
||||||
|
dnsutils # `dig` + `nslookup`
|
||||||
|
ldns # replacement of `dig`, it provide the command `drill`
|
||||||
|
aria2 # A lightweight multi-protocol & multi-source command-line download utility
|
||||||
|
socat # replacement of openbsd-netcat
|
||||||
|
nmap # A utility for network discovery and security auditing
|
||||||
|
ipcalc # it is a calculator for the IPv4/v6 addresses
|
||||||
|
|
||||||
|
# system tools
|
||||||
|
sysstat
|
||||||
|
lm_sensors # for `sensors` command
|
||||||
|
ethtool
|
||||||
|
pciutils # lspci
|
||||||
|
usbutils # lsusb
|
||||||
|
|
||||||
|
# system call monitoring
|
||||||
|
strace # system call monitoring
|
||||||
|
ltrace # library call monitoring
|
||||||
|
lsof # list open files
|
||||||
|
|
||||||
|
btop # replacement of htop/nmon
|
||||||
|
iotop # io monitoring
|
||||||
|
iftop # network monitoring
|
||||||
|
|
||||||
|
# dev utils
|
||||||
|
direnv # shell environment management
|
||||||
|
envsubst
|
||||||
|
|
||||||
|
# nix tools
|
||||||
|
nvd
|
||||||
|
];
|
||||||
|
|
||||||
|
sessionVariables = {
|
||||||
|
EDITOR = "vim";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
6
nixos/home/jahanson/server.nix
Normal file
6
nixos/home/jahanson/server.nix
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./global.nix
|
||||||
|
];
|
||||||
|
}
|
42
nixos/home/jahanson/workstation.nix
Normal file
42
nixos/home/jahanson/workstation.nix
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
with config;
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./global.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
myHome.programs.firefox.enable = true;
|
||||||
|
|
||||||
|
myHome.shell = {
|
||||||
|
starship.enable = true;
|
||||||
|
fish.enable = true;
|
||||||
|
|
||||||
|
git = {
|
||||||
|
enable = true;
|
||||||
|
username = "Joseph Hanson";
|
||||||
|
email = "joe@veri.dev";
|
||||||
|
signingKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIDSAmssproxG+KsVn2DfuteBAemHrmmAFzCtldpKl4J";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home = {
|
||||||
|
# Install these packages for my user
|
||||||
|
packages = with pkgs;
|
||||||
|
[
|
||||||
|
#apps
|
||||||
|
_1password-gui
|
||||||
|
discord
|
||||||
|
flameshot
|
||||||
|
vlc
|
||||||
|
|
||||||
|
# cli
|
||||||
|
brightnessctl
|
||||||
|
|
||||||
|
# dev utils
|
||||||
|
pre-commit # Pre-commit tasks for git
|
||||||
|
minio-client # S3 management
|
||||||
|
shellcheck # shell script linting
|
||||||
|
];
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
36
nixos/home/modules/default.nix
Normal file
36
nixos/home/modules/default.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./shell
|
||||||
|
./programs
|
||||||
|
./security
|
||||||
|
];
|
||||||
|
|
||||||
|
options.myHome.username = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "users username";
|
||||||
|
default = "jahanson";
|
||||||
|
};
|
||||||
|
options.myHome.homeDirectory = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "users homedir";
|
||||||
|
default = "jahanson";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Home-manager defaults
|
||||||
|
config = {
|
||||||
|
home.stateVersion = "24.11";
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
home-manager.enable = true;
|
||||||
|
git.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.enable = true;
|
||||||
|
|
||||||
|
nixpkgs.config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
5
nixos/home/modules/programs/browsers/default.nix
Normal file
5
nixos/home/modules/programs/browsers/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{ ... }: {
|
||||||
|
imports = [
|
||||||
|
./firefox
|
||||||
|
];
|
||||||
|
}
|
32
nixos/home/modules/programs/browsers/firefox/default.nix
Normal file
32
nixos/home/modules/programs/browsers/firefox/default.nix
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.myHome.programs.firefox;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.myHome.programs.firefox.enable = mkEnableOption "Firefox";
|
||||||
|
|
||||||
|
config = mkIf cfg.enable
|
||||||
|
{
|
||||||
|
programs.firefox = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.firefox.override
|
||||||
|
{
|
||||||
|
extraPolicies = {
|
||||||
|
DontCheckDefaultBrowser = true;
|
||||||
|
DisablePocket = true;
|
||||||
|
# See nixpkgs' firefox/wrapper.nix to check which options you can use
|
||||||
|
nativeMessagingHosts = [
|
||||||
|
# Gnome shell native connector
|
||||||
|
pkgs.gnome-browser-connector
|
||||||
|
# plasma connector
|
||||||
|
# plasma5Packages.plasma-browser-integration
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
policies = import ./policies.nix;
|
||||||
|
|
||||||
|
profiles.default = import ./profile-default.nix { inherit pkgs; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
20
nixos/home/modules/programs/browsers/firefox/policies.nix
Normal file
20
nixos/home/modules/programs/browsers/firefox/policies.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
DisableTelemetry = true;
|
||||||
|
DisableFirefoxStudies = true;
|
||||||
|
EnableTrackingProtection = {
|
||||||
|
Value = true;
|
||||||
|
Locked = true;
|
||||||
|
Cryptomining = true;
|
||||||
|
Fingerprinting = true;
|
||||||
|
};
|
||||||
|
DisablePocket = true;
|
||||||
|
# DisableFirefoxAccounts = true;
|
||||||
|
# DisableAccounts = true;
|
||||||
|
# DisableFirefoxScreenshots = true;
|
||||||
|
# OverrideFirstRunPage = "";
|
||||||
|
OverridePostUpdatePage = "";
|
||||||
|
DontCheckDefaultBrowser = true;
|
||||||
|
DisplayBookmarksToolbar = "never"; # alternatives: "always" or "newtab"
|
||||||
|
DisplayMenuBar = "default-off"; # alternatives: "always", "never" or "default-on"
|
||||||
|
SearchBar = "unified"; # alternative: "separate"
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
{ pkgs }:
|
||||||
|
{
|
||||||
|
id = 0;
|
||||||
|
name = "default";
|
||||||
|
isDefault = true;
|
||||||
|
settings = {
|
||||||
|
"browser.startup.homepage" = "https://status.hsn.dev";
|
||||||
|
"browser.search.suggest.enabled.private" = false;
|
||||||
|
# 0 => blank page
|
||||||
|
# 1 => your home page(s) {default}
|
||||||
|
# 2 => the last page viewed in Firefox
|
||||||
|
# 3 => previous session windows and tabs
|
||||||
|
"browser.startup.page" = "3";
|
||||||
|
|
||||||
|
"browser.send_pings" = false;
|
||||||
|
# Do not track
|
||||||
|
"privacy.donottrackheader.enabled" = "true";
|
||||||
|
"privacy.donottrackheader.value" = 1;
|
||||||
|
"browser.display.use_system_colors" = "true";
|
||||||
|
|
||||||
|
"browser.display.use_document_colors" = "false";
|
||||||
|
"devtools.theme" = "dark";
|
||||||
|
|
||||||
|
"extensions.pocket.enabled" = false;
|
||||||
|
};
|
||||||
|
extensions = with pkgs.nur.repos.rycee.firefox-addons; [
|
||||||
|
ublock-origin
|
||||||
|
privacy-badger
|
||||||
|
link-cleaner
|
||||||
|
refined-github
|
||||||
|
];
|
||||||
|
}
|
5
nixos/home/modules/programs/de/default.nix
Normal file
5
nixos/home/modules/programs/de/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{ ... }: {
|
||||||
|
imports = [
|
||||||
|
./gnome
|
||||||
|
];
|
||||||
|
}
|
36
nixos/home/modules/programs/de/gnome/default.nix
Normal file
36
nixos/home/modules/programs/de/gnome/default.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Adjusted manually from generated output of dconf2nix
|
||||||
|
# https://github.com/gvolpe/dconf2nix
|
||||||
|
{ lib, pkgs, osConfig, ... }:
|
||||||
|
with lib.hm.gvariant; {
|
||||||
|
config = lib.mkIf osConfig.mySystem.de.gnome.enable {
|
||||||
|
# add user packages
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
dconf2nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# worked out from dconf2nix
|
||||||
|
# dconf dump / | dconf2nix > dconf.nix
|
||||||
|
# can also dconf watch
|
||||||
|
dconf.settings = {
|
||||||
|
"org/gnome/mutter" = {
|
||||||
|
edge-tiling = true;
|
||||||
|
workspaces-only-on-primary = false;
|
||||||
|
};
|
||||||
|
"org/gnome/desktop/wm/preferences" = {
|
||||||
|
workspace-names = [ "sys" "talk" "web" "edit" "run" ];
|
||||||
|
};
|
||||||
|
"org/gnome/shell" = {
|
||||||
|
disabled-extensions = [ "apps-menu@gnome-shell-extensions.gcampax.github.com" "light-style@gnome-shell-extensions.gcampax.github.com" "places-menu@gnome-shell-extensions.gcampax.github.com" "drive-menu@gnome-shell-extensions.gcampax.github.com" "window-list@gnome-shell-extensions.gcampax.github.com" "workspace-indicator@gnome-shell-extensions.gcampax.github.com" ];
|
||||||
|
enabled-extensions = [ "appindicatorsupport@rgcjonas.gmail.com" "caffeine@patapon.info" "dash-to-dock@micxgx.gmail.com" "gsconnect@andyholmes.github.io" "Vitals@CoreCoding.com" "sp-tray@sp-tray.esenliyim.github.com" ];
|
||||||
|
favorite-apps = [ "org.gnome.Nautilus.desktop" "firefox.desktop" "org.wezfurlong.wezterm.desktop" "PrusaGcodeviewer.desktop" "spotify.desktop" "org.gnome.Console.desktop" "codium.desktop" "discord.desktop" ];
|
||||||
|
};
|
||||||
|
"org/gnome/nautilus/preferences" = {
|
||||||
|
default-folder-viewer = "list-view";
|
||||||
|
};
|
||||||
|
"org/gnome/nautilus/icon-view" = {
|
||||||
|
default-zoom-level = "small";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
6
nixos/home/modules/programs/default.nix
Normal file
6
nixos/home/modules/programs/default.nix
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{ ... }: {
|
||||||
|
imports = [
|
||||||
|
./browsers
|
||||||
|
./de
|
||||||
|
];
|
||||||
|
}
|
5
nixos/home/modules/security/default.nix
Normal file
5
nixos/home/modules/security/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{ ... }: {
|
||||||
|
imports = [
|
||||||
|
./ssh
|
||||||
|
];
|
||||||
|
}
|
21
nixos/home/modules/security/ssh/default.nix
Normal file
21
nixos/home/modules/security/ssh/default.nix
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.myHome.security.ssh;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.myHome.security.ssh = {
|
||||||
|
enable = mkEnableOption "ssh";
|
||||||
|
matchBlocks = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
programs.ssh = {
|
||||||
|
inherit (cfg) matchBlocks;
|
||||||
|
enable = true;
|
||||||
|
# addKeysToAgent = "yes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
8
nixos/home/modules/shell/default.nix
Normal file
8
nixos/home/modules/shell/default.nix
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{ ... }: {
|
||||||
|
imports = [
|
||||||
|
./fish
|
||||||
|
./starship
|
||||||
|
./wezterm
|
||||||
|
./git
|
||||||
|
];
|
||||||
|
}
|
75
nixos/home/modules/shell/fish/default.nix
Normal file
75
nixos/home/modules/shell/fish/default.nix
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
with lib; let
|
||||||
|
inherit (config.myHome) username homeDirectory;
|
||||||
|
cfg = config.myHome.shell.fish;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.myHome.shell.fish = {
|
||||||
|
enable = mkEnableOption "fish";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(mkIf cfg.enable {
|
||||||
|
programs.fish = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
shellAliases = {
|
||||||
|
m = "less";
|
||||||
|
ls = "${pkgs.lsd}/bin/lsd";
|
||||||
|
ll = "${pkgs.lsd}/bin/lsd -l";
|
||||||
|
la = "${pkgs.lsd}/bin/lsd -a";
|
||||||
|
lt = "${pkgs.lsd}/bin/lsd --tree";
|
||||||
|
lla = "${pkgs.lsd}/bin/lsd -la";
|
||||||
|
tm = "tmux attach -t (basename $PWD) || tmux new -s (basename $PWD)";
|
||||||
|
x = "exit";
|
||||||
|
};
|
||||||
|
|
||||||
|
shellAbbrs = {
|
||||||
|
nrs = "sudo nixos-rebuild switch --flake .";
|
||||||
|
nvdiff = "nvd diff /run/current-system result";
|
||||||
|
};
|
||||||
|
|
||||||
|
interactiveShellInit = ''
|
||||||
|
# Erase fish_mode_prompt function
|
||||||
|
functions -e fish_mode_prompt
|
||||||
|
|
||||||
|
function remove_path
|
||||||
|
if set -l index (contains -i $argv[1] $PATH)
|
||||||
|
set --erase --universal fish_user_paths[$index]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function update_path
|
||||||
|
if test -d $argv[1]
|
||||||
|
fish_add_path -m $argv[1]
|
||||||
|
else
|
||||||
|
remove_path $argv[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Paths are in reverse priority order
|
||||||
|
update_path /opt/homebrew/opt/postgresql@16/bin
|
||||||
|
update_path /opt/homebrew/bin
|
||||||
|
update_path ${homeDirectory}/.krew/bin
|
||||||
|
update_path /nix/var/nix/profiles/default/bin
|
||||||
|
update_path /run/current-system/sw/bin
|
||||||
|
update_path /etc/profiles/per-user/${username}/bin
|
||||||
|
update_path /run/wrappers/bin
|
||||||
|
update_path ${homeDirectory}/.nix-profile/bin
|
||||||
|
update_path ${homeDirectory}/go/bin
|
||||||
|
update_path ${homeDirectory}/.cargo/bin
|
||||||
|
update_path ${homeDirectory}/.local/bin
|
||||||
|
|
||||||
|
set -gx EDITOR "vim"
|
||||||
|
|
||||||
|
set -gx LSCOLORS "Gxfxcxdxbxegedabagacad"
|
||||||
|
set -gx LS_COLORS 'di=01;34:ln=01;36:pi=33:so=01;35:bd=01;33:cd=33:or=31:ex=01;32:*.7z=01;31:*.bz2=01;31:*.gz=01;31:*.lz=01;31:*.lzma=01;31:*.lzo=01;31:*.rar=01;31:*.tar=01;31:*.tbz=01;31:*.tgz=01;31:*.xz=01;31:*.zip=01;31:*.zst=01;31:*.zstd=01;31:*.bmp=01;35:*.tiff=01;35:*.tif=01;35:*.TIFF=01;35:*.gif=01;35:*.jpeg=01;35:*.jpg=01;35:*.png=01;35:*.webp=01;35:*.pot=01;35:*.pcb=01;35:*.gbr=01;35:*.scm=01;35:*.xcf=01;35:*.spl=01;35:*.stl=01;35:*.dwg=01;35:*.ply=01;35:*.apk=01;31:*.deb=01;31:*.rpm=01;31:*.jad=01;31:*.jar=01;31:*.crx=01;31:*.xpi=01;31:*.avi=01;35:*.divx=01;35:*.m2v=01;35:*.m4v=01;35:*.mkv=01;35:*.MOV=01;35:*.mov=01;35:*.mp4=01;35:*.mpeg=01;35:*.mpg=01;35:*.sample=01;35:*.wmv=01;35:*.3g2=01;35:*.3gp=01;35:*.gp3=01;35:*.webm=01;35:*.flv=01;35:*.ogv=01;35:*.f4v=01;35:*.3ga=01;35:*.aac=01;35:*.m4a=01;35:*.mp3=01;35:*.mp4a=01;35:*.oga=01;35:*.ogg=01;35:*.opus=01;35:*.s3m=01;35:*.sid=01;35:*.wma=01;35:*.flac=01;35:*.alac=01;35:*.mid=01;35:*.midi=01;35:*.pcm=01;35:*.wav=01;35:*.ass=01;33:*.srt=01;33:*.ssa=01;33:*.sub=01;33:*.git=01;33:*.ass=01;33:*README=33:*README.rst=33:*README.md=33:*LICENSE=33:*COPYING=33:*INSTALL=33:*COPYRIGHT=33:*AUTHORS=33:*HISTORY=33:*CONTRIBUTOS=33:*PATENTS=33:*VERSION=33:*NOTICE=33:*CHANGES=33:*CHANGELOG=33:*log=33:*.txt=33:*.md=33:*.markdown=33:*.nfo=33:*.org=33:*.pod=33:*.rst=33:*.tex=33:*.texttile=33:*.bib=35:*.json=35:*.jsonl=35:*.jsonnet=35:*.libsonnet=35:*.rss=35:*.xml=35:*.fxml=35:*.toml=35:*.yaml=35:*.yml=35:*.dtd=35:*.cbr=35:*.cbz=35:*.chm=35:*.pdf=35:*.PDF=35:*.epub=35:*.awk=35:*.bash=35:*.bat=35:*.BAT=35:*.sed=35:*.sh=35:*.zsh=35:*.vim=35:*.py=35:*.ipynb=35:*.rb=35:*.gemspec=35:*.pl=35:*.PL=35:*.t=35:*.msql=35:*.mysql=35:*.pgsql=35:*.sql=35:*.r=35:*.R=35:*.cljw=35:*.scala=35:*.sc=35:*.dart=35:*.asm=35:*.cl=35:*.lisp=35:*.rkt=35:*.el=35:*.elc=35:*.eln=35:*.lua=35:*.c=35:*.C=35:*.h=35:*.H=35:*.tcc=35:*.c++=35:*.h++=35:*.hpp=35:*.hxx=35:*ii.=35:*.m=35:*.M=35:*.cc=35:*.cs=35:*.cp=35:*.cpp=35:*.cxx=35:*.go=35:*.f=35:*.F=35:*.nim=35:*.nimble=35:*.s=35:*.S=35:*.rs=35:*.scpt=35:*.swift=35:*.vala=35:*.vapi=35:*.hs=35:*.lhs=35:*.zig=35:*.v=35:*.pyc=35:*.tf=35:*.tfstate=35:*.tfvars=35:*.css=35:*.less=35:*.sass=35:*.scss=35:*.htm=35:*.html=35:*.jhtm=35:*.mht=35:*.eml=35:*.coffee=35:*.java=35:*.js=35:*.mjs=35:*.jsm=35:*.jsp=35:*.rasi=35:*.php=35:*.twig=35:*.vb=35:*.vba=35:*.vbs=35:*.Dockerfile=35:*.dockerignore=35:*.Makefile=35:*.MANIFEST=35:*.am=35:*.in=35:*.hin=35:*.scan=35:*.m4=35:*.old=35:*.out=35:*.SKIP=35:*.diff=35:*.patch=35:*.tmpl=35:*.j2=35:*PKGBUILD=35:*config=35:*.conf=35:*.service=31:*.@.service=31:*.socket=31:*.swap=31:*.device=31:*.mount=31:*.automount=31:*.target=31:*.path=31:*.timer=31:*.snapshot=31:*.allow=31:*.swp=31:*.swo=31:*.tmp=31:*.pid=31:*.state=31:*.lock=31:*.lockfile=31:*.pacnew=31:*.un=31:*.orig=31:'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
home.sessionVariables.fish_greeting = "";
|
||||||
|
|
||||||
|
programs.nix-index.enable = true;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
69
nixos/home/modules/shell/git/default.nix
Normal file
69
nixos/home/modules/shell/git/default.nix
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{ pkgs, config, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.myHome.shell.git;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.myHome.shell.git = {
|
||||||
|
enable = lib.mkEnableOption "git";
|
||||||
|
username = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
email = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
signingKey = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.enable {
|
||||||
|
programs.gh.enable = true;
|
||||||
|
programs.gpg.enable = true;
|
||||||
|
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
userName = cfg.username;
|
||||||
|
userEmail = cfg.email;
|
||||||
|
|
||||||
|
extraConfig = {
|
||||||
|
core.autocrlf = "input";
|
||||||
|
init.defaultBranch = "main";
|
||||||
|
pull.rebase = true;
|
||||||
|
rebase.autoStash = true;
|
||||||
|
# public key for signing commits
|
||||||
|
user.signingKey = cfg.signingKey;
|
||||||
|
# ssh instead of gpg
|
||||||
|
gpg.format = "ssh";
|
||||||
|
# 1password signing gui git signing
|
||||||
|
gpg.ssh.program = "${pkgs._1password-gui}/bin/op-ssh-sign";
|
||||||
|
# Auto sign commits without -S
|
||||||
|
commit.gpgsign = true;
|
||||||
|
};
|
||||||
|
aliases = {
|
||||||
|
co = "checkout";
|
||||||
|
};
|
||||||
|
ignores = [
|
||||||
|
# Mac OS X hidden files
|
||||||
|
".DS_Store"
|
||||||
|
# Windows files
|
||||||
|
"Thumbs.db"
|
||||||
|
# asdf
|
||||||
|
".tool-versions"
|
||||||
|
# Sops
|
||||||
|
".decrypted~*"
|
||||||
|
"*.decrypted.*"
|
||||||
|
# Python virtualenvs
|
||||||
|
".venv"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
home.packages = [
|
||||||
|
pkgs.git-filter-repo
|
||||||
|
pkgs.tig
|
||||||
|
pkgs.lazygit
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
115
nixos/home/modules/shell/starship/default.nix
Normal file
115
nixos/home/modules/shell/starship/default.nix
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
{ lib
|
||||||
|
, config
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.myHome.shell.starship;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.myHome.shell.starship = { enable = mkEnableOption "starship"; };
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
programs.starship = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
add_newline = false;
|
||||||
|
command_timeout = 1000;
|
||||||
|
format = lib.concatStrings [
|
||||||
|
"$username"
|
||||||
|
"$hostname"
|
||||||
|
"$directory"
|
||||||
|
"$git_branch"
|
||||||
|
"$git_status"
|
||||||
|
"$\{custom.direnv\}"
|
||||||
|
"$fill"
|
||||||
|
"$python"
|
||||||
|
"$status"
|
||||||
|
"$cmd_duration"
|
||||||
|
"$line_break"
|
||||||
|
"$character"
|
||||||
|
];
|
||||||
|
|
||||||
|
username = {
|
||||||
|
style_user = "yellow";
|
||||||
|
style_root = "red";
|
||||||
|
format = "[$user]($style)";
|
||||||
|
show_always = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
hostname = {
|
||||||
|
ssh_only = true;
|
||||||
|
format = "[@$hostname]($style) in ";
|
||||||
|
style = "green";
|
||||||
|
};
|
||||||
|
|
||||||
|
directory = {
|
||||||
|
truncation_length = 3;
|
||||||
|
format = "[$path]($style)[$read_only]($read_only_style) ";
|
||||||
|
style = "blue";
|
||||||
|
read_only = " ";
|
||||||
|
truncation_symbol = "../";
|
||||||
|
truncate_to_repo = true;
|
||||||
|
fish_style_pwd_dir_length = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
git_branch = {
|
||||||
|
format = "on [$symbol$branch]($style) ";
|
||||||
|
style = "purple";
|
||||||
|
symbol = " ";
|
||||||
|
};
|
||||||
|
|
||||||
|
git_status = {
|
||||||
|
format = "([$all_status$ahead_behind]($style) )";
|
||||||
|
style = "purple";
|
||||||
|
conflicted = " ";
|
||||||
|
ahead = " ";
|
||||||
|
behind = " ";
|
||||||
|
diverged = " ";
|
||||||
|
up_to_date = " ";
|
||||||
|
untracked = " ";
|
||||||
|
stashed = " ";
|
||||||
|
modified = " ";
|
||||||
|
staged = " ";
|
||||||
|
renamed = " ";
|
||||||
|
deleted = " ";
|
||||||
|
};
|
||||||
|
|
||||||
|
fill = {
|
||||||
|
symbol = " ";
|
||||||
|
};
|
||||||
|
|
||||||
|
python = {
|
||||||
|
format = "[\${symbol}\${pyenv_prefix}(\${version} )(\($virtualenv\) )]($style)";
|
||||||
|
symbol = "🐍 ";
|
||||||
|
};
|
||||||
|
|
||||||
|
status = {
|
||||||
|
disabled = false;
|
||||||
|
format = "[$symbol]($style) ";
|
||||||
|
symbol = " ";
|
||||||
|
success_symbol = " ";
|
||||||
|
style = "red";
|
||||||
|
};
|
||||||
|
|
||||||
|
cmd_duration = {
|
||||||
|
min_time = 2000;
|
||||||
|
format = "took [$duration]($style) ";
|
||||||
|
style = "yellow";
|
||||||
|
};
|
||||||
|
|
||||||
|
character = {
|
||||||
|
success_symbol = "[](green)";
|
||||||
|
error_symbol = "[](green)";
|
||||||
|
vicmd_symbol = "[](purple)";
|
||||||
|
};
|
||||||
|
|
||||||
|
custom.direnv = {
|
||||||
|
format = "[$symbol]($style)";
|
||||||
|
symbol = " ";
|
||||||
|
style = "blue";
|
||||||
|
when = "env | grep -E '^DIRENV_FILE='";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
43
nixos/home/modules/shell/wezterm/default.nix
Normal file
43
nixos/home/modules/shell/wezterm/default.nix
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{ config
|
||||||
|
, pkgs
|
||||||
|
, lib
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.myHome.shell.wezterm;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.myHome.shell.wezterm = {
|
||||||
|
enable = mkEnableOption "wezterm";
|
||||||
|
configPath = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# xdg.configFile."wezterm/wezterm.lua".source = config.lib.file.mkOutOfStoreSymlink cfg.configPath;
|
||||||
|
programs.wezterm.package = pkgs.unstable.wezterm;
|
||||||
|
programs.wezterm = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
local wez = require('wezterm')
|
||||||
|
return {
|
||||||
|
-- issue relating to nvidia drivers
|
||||||
|
-- https://github.com/wez/wezterm/issues/2011
|
||||||
|
-- had to build out 550.67 manually to 'fix'
|
||||||
|
enable_wayland = true,
|
||||||
|
|
||||||
|
color_scheme = "Dracula (Official)",
|
||||||
|
check_for_updates = false,
|
||||||
|
window_background_opacity = .90,
|
||||||
|
window_padding = {
|
||||||
|
left = '2cell',
|
||||||
|
right = '2cell',
|
||||||
|
top = '1cell',
|
||||||
|
bottom = '0cell',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
33
nixos/hosts/durincore/default.nix
Normal file
33
nixos/hosts/durincore/default.nix
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{ ... }: {
|
||||||
|
config = {
|
||||||
|
|
||||||
|
# hardware-configuration.nix - half of the hardware-configuration.nix file
|
||||||
|
|
||||||
|
networking.hostId = "ad4380db";
|
||||||
|
networking.hostName = "durincore";
|
||||||
|
|
||||||
|
fileSystems."/" =
|
||||||
|
{ device = "rpool/root";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/home" =
|
||||||
|
{ device = "rpool/home";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/F1B9-CA7C";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [ "fmask=0077" "dmask=0077" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# System settings and services.
|
||||||
|
mySystem = {
|
||||||
|
system.motd.networkInterfaces = [ "enp0s31f6" "wlp4s0" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
34
nixos/hosts/varda/default.nix
Normal file
34
nixos/hosts/varda/default.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{ ... }: {
|
||||||
|
imports = [ ];
|
||||||
|
|
||||||
|
networking.hostId = "cdab8473";
|
||||||
|
networking.hostName = "varda"; # Define your hostname.
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "rpool/root";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/home" = {
|
||||||
|
device = "rpool/home";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" =
|
||||||
|
{ device = "/dev/disk/by-uuid/8091-E7F2";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
# System settings and services.
|
||||||
|
mySystem = {
|
||||||
|
system.motd.networkInterfaces = [ "enp1s0" ];
|
||||||
|
security.acme.enable = true;
|
||||||
|
services = {
|
||||||
|
forgejo.enable = true;
|
||||||
|
nginx.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
43
nixos/lib/default.nix
Normal file
43
nixos/lib/default.nix
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
rec {
|
||||||
|
|
||||||
|
firstOrDefault = first: default: if first != null then first else default;
|
||||||
|
existsOrDefault = x: set: default: if builtins.hasAttr x set then builtins.getAttr x set else default;
|
||||||
|
|
||||||
|
# main service builder
|
||||||
|
mkService = options: (
|
||||||
|
let
|
||||||
|
user = existsOrDefault "user" options "568";
|
||||||
|
group = existsOrDefault "group" options "568";
|
||||||
|
|
||||||
|
enableBackups = (lib.attrsets.hasAttrByPath [ "persistence" "folder" ] options)
|
||||||
|
&& (lib.attrsets.attrByPath [ "persistence" "enable" ] true options);
|
||||||
|
|
||||||
|
# Security options for containers
|
||||||
|
containerExtraOptions = lib.optionals (lib.attrsets.attrByPath [ "container" "caps" "privileged" ] false options) [ "--privileged" ]
|
||||||
|
++ lib.optionals (lib.attrsets.attrByPath [ "container" "caps" "readOnly" ] false options) [ "--read-only" ]
|
||||||
|
++ lib.optionals (lib.attrsets.attrByPath [ "container" "caps" "tmpfs" ] false options) [ (map (folders: "--tmpfs=${folders}") tmpfsFolders) ]
|
||||||
|
++ lib.optionals (lib.attrsets.attrByPath [ "container" "caps" "noNewPrivileges" ] false options) [ "--security-opt=no-new-privileges" ]
|
||||||
|
++ lib.optionals (lib.attrsets.attrByPath [ "container" "caps" "dropAll" ] false options) [ "--cap-drop=ALL" ]
|
||||||
|
;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
virtualisation.oci-containers.containers.${options.app} = mkIf options.container.enable {
|
||||||
|
image = "${options.container.image}";
|
||||||
|
user = "${user}:${group}";
|
||||||
|
environment = {
|
||||||
|
TZ = options.timeZone;
|
||||||
|
} // options.container.env;
|
||||||
|
environmentFiles = lib.attrsets.attrByPath [ "container" "envFiles" ] [ ] options;
|
||||||
|
volumes = [ "/etc/localtime:/etc/localtime:ro" ] ++
|
||||||
|
lib.optionals (lib.attrsets.hasAttrByPath [ "container" "persistentFolderMount" ] options) [
|
||||||
|
"${options.persistence.folder}:${options.container.persistentFolderMount}:rw"
|
||||||
|
] ++ lib.attrsets.attrByPath [ "container" "volumes" ] [ ] options;
|
||||||
|
extraOptions = containerExtraOptions;
|
||||||
|
};
|
||||||
|
systemd.tmpfiles.rules = lib.optionals (lib.attrsets.hasAttrByPath [ "persistence" "folder" ] options) [ "d ${options.persistence.folder} 0750 ${user} ${group} -" ];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
0
nixos/modules/.gitkeep
Normal file
0
nixos/modules/.gitkeep
Normal file
9
nixos/modules/README.md
Normal file
9
nixos/modules/README.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
## Modules
|
||||||
|
|
||||||
|
A set of 'custom' modules with the aim to enable easy on/off/settings to build up a system modularly to my 'specs'.
|
||||||
|
|
||||||
|
The main goal is to build up a `mySystem` options key which is easy to read and toggle functionality on and off.
|
||||||
|
|
||||||
|
This option key will largely be manipulated by a profile to build up a host to a base, then toggle specific options from there.
|
||||||
|
|
||||||
|
I will _try_ and only do modules for things I want to be able to configure, and just use nixos config directly for some simple static things.
|
3
nixos/modules/default.nix
Normal file
3
nixos/modules/default.nix
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
mySystem = import ./nixos;
|
||||||
|
}
|
56
nixos/modules/nixos/containers/backrest/default.nix
Normal file
56
nixos/modules/nixos/containers/backrest/default.nix
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
app = "backrest";
|
||||||
|
image = "garethgeorge/backrest:v1.1.0";
|
||||||
|
user = "568"; #string
|
||||||
|
group = "568"; #string
|
||||||
|
port = 9898; #int
|
||||||
|
cfg = config.mySystem.services.${app};
|
||||||
|
appFolder = "/var/lib/${app}";
|
||||||
|
# persistentFolder = "${config.mySystem.persistentFolder}/var/lib/${appFolder}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.services.${app} =
|
||||||
|
{
|
||||||
|
enable = mkEnableOption "${app}";
|
||||||
|
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# ensure folder exist and has correct owner/group
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${appFolder}/config 0750 ${user} ${group} -"
|
||||||
|
"d ${appFolder}/data 0750 ${user} ${group} -"
|
||||||
|
"d ${appFolder}/cache 0750 ${user} ${group} -"
|
||||||
|
];
|
||||||
|
|
||||||
|
virtualisation.oci-containers.containers.${app} = {
|
||||||
|
image = "${image}";
|
||||||
|
user = "${user}:${group}";
|
||||||
|
environment = {
|
||||||
|
BACKREST_PORT = "9898";
|
||||||
|
BACKREST_DATA = "/data";
|
||||||
|
BACKREST_CONFIG = "/config/config.json";
|
||||||
|
XDG_CACHE_HOME = "/cache";
|
||||||
|
};
|
||||||
|
volumes = [
|
||||||
|
"${appFolder}/nixos/config:/config:rw"
|
||||||
|
"${appFolder}/nixos/data:/data:rw"
|
||||||
|
"${appFolder}/nixos/cache:/cache:rw"
|
||||||
|
"${config.mySystem.nasFolder}/backup/nixos/nixos:/repos:rw"
|
||||||
|
"/etc/localtime:/etc/localtime:ro"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."${app}.${config.networking.domain}" = {
|
||||||
|
useACMEHost = config.networking.domain;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."^~ /" = {
|
||||||
|
proxyPass = "http://${app}:${builtins.toString port}";
|
||||||
|
extraConfig = "resolver 10.88.0.1;";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
5
nixos/modules/nixos/containers/default.nix
Normal file
5
nixos/modules/nixos/containers/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./backrest
|
||||||
|
];
|
||||||
|
}
|
5
nixos/modules/nixos/de/default.nix
Normal file
5
nixos/modules/nixos/de/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./gnome.nix
|
||||||
|
];
|
||||||
|
}
|
101
nixos/modules/nixos/de/gnome.nix
Normal file
101
nixos/modules/nixos/de/gnome.nix
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.de.gnome;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.de.gnome.enable = mkEnableOption "GNOME";
|
||||||
|
options.mySystem.de.gnome.systrayicons = mkEnableOption "Enable systray icons" // { default = true; };
|
||||||
|
options.mySystem.de.gnome.gsconnect = mkEnableOption "Enable gsconnect (KDEConnect for GNOME)" // { default = true; };
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
# Ref: https://nixos.wiki/wiki/GNOME
|
||||||
|
|
||||||
|
# GNOME plz
|
||||||
|
services = {
|
||||||
|
displayManager = {
|
||||||
|
defaultSession = "gnome";
|
||||||
|
autoLogin = {
|
||||||
|
enable = false;
|
||||||
|
user = "jahanson"; # TODO move to config overlay
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
xserver = {
|
||||||
|
enable = true;
|
||||||
|
xkb.layout = "us"; # `localctl` will give you
|
||||||
|
|
||||||
|
displayManager = {
|
||||||
|
gdm.enable = true;
|
||||||
|
};
|
||||||
|
desktopManager = {
|
||||||
|
# GNOME
|
||||||
|
gnome.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
udev.packages = optionals cfg.systrayicons [ pkgs.gnome.gnome-settings-daemon ]; # support appindicator
|
||||||
|
};
|
||||||
|
|
||||||
|
# systyray icons
|
||||||
|
# extra pkgs and extensions
|
||||||
|
environment = {
|
||||||
|
systemPackages = with pkgs; [
|
||||||
|
wl-clipboard # ls ~/Downloads | wl-copy or wl-paste > clipboard.txt
|
||||||
|
playerctl # gsconnect play/pause command
|
||||||
|
pamixer # gcsconnect volume control
|
||||||
|
gnome.gnome-tweaks
|
||||||
|
gnome.dconf-editor
|
||||||
|
|
||||||
|
# This installs the extension packages, but
|
||||||
|
# dont forget to enable them per-user in dconf settings -> "org/gnome/shell"
|
||||||
|
gnomeExtensions.vitals
|
||||||
|
gnomeExtensions.caffeine
|
||||||
|
gnomeExtensions.dash-to-dock
|
||||||
|
]
|
||||||
|
++ optionals cfg.systrayicons [ pkgs.gnomeExtensions.appindicator ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# enable gsconnect
|
||||||
|
# this method also opens the firewall ports required when enable = true
|
||||||
|
programs.kdeconnect = mkIf
|
||||||
|
cfg.gsconnect
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.gnomeExtensions.gsconnect;
|
||||||
|
};
|
||||||
|
|
||||||
|
# GNOME connection to browsers - requires flag on browser as well
|
||||||
|
services.gnome.gnome-browser-connector.enable = lib.any
|
||||||
|
(user: user.programs.firefox.enable)
|
||||||
|
(lib.attrValues config.home-manager.users);
|
||||||
|
|
||||||
|
# And dconf
|
||||||
|
programs.dconf.enable = true;
|
||||||
|
|
||||||
|
# Exclude default GNOME packages that dont interest me.
|
||||||
|
environment.gnome.excludePackages =
|
||||||
|
(with pkgs; [
|
||||||
|
gnome-photos
|
||||||
|
gnome-tour
|
||||||
|
gedit # text editor
|
||||||
|
])
|
||||||
|
++ (with pkgs.gnome; [
|
||||||
|
cheese # webcam tool
|
||||||
|
gnome-music
|
||||||
|
gnome-terminal
|
||||||
|
epiphany # web browser
|
||||||
|
geary # email reader
|
||||||
|
evince # document viewer
|
||||||
|
gnome-characters
|
||||||
|
totem # video player
|
||||||
|
tali # poker game
|
||||||
|
iagno # go game
|
||||||
|
hitori # sudoku game
|
||||||
|
atomix # puzzle game
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
62
nixos/modules/nixos/default.nix
Normal file
62
nixos/modules/nixos/default.nix
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./system
|
||||||
|
./programs
|
||||||
|
./services
|
||||||
|
./de
|
||||||
|
./hardware
|
||||||
|
./containers
|
||||||
|
./lib.nix
|
||||||
|
./security
|
||||||
|
];
|
||||||
|
|
||||||
|
options.mySystem.persistentFolder = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "persistent folder for nixos mutable files";
|
||||||
|
default = "/persist";
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mySystem.nasFolder = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "folder where nas mounts reside";
|
||||||
|
default = "/mnt/nas";
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mySystem.nasAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "NAS Address or name for the backup nas";
|
||||||
|
default = "10.1.1.13";
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mySystem.domain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "domain for hosted services";
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mySystem.internalDomain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "domain for local devices";
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mySystem.purpose = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "System purpose";
|
||||||
|
default = "Production";
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mySystem.monitoring.prometheus.scrapeConfigs = mkOption {
|
||||||
|
type = lib.types.listOf lib.types.attrs;
|
||||||
|
description = "Prometheus scrape targets";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${config.mySystem.persistentFolder} 777 - - -" #The - disables automatic cleanup, so the file wont be removed after a period
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
5
nixos/modules/nixos/hardware/default.nix
Normal file
5
nixos/modules/nixos/hardware/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./nvidia
|
||||||
|
];
|
||||||
|
}
|
79
nixos/modules/nixos/hardware/nvidia/default.nix
Normal file
79
nixos/modules/nixos/hardware/nvidia/default.nix
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.hardware.nvidia;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.hardware.nvidia.enable = mkEnableOption "NVIDIA config";
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
# ref: https://nixos.wiki/wiki/Nvidia
|
||||||
|
# Enable OpenGL
|
||||||
|
hardware.opengl = {
|
||||||
|
enable = true;
|
||||||
|
driSupport = true;
|
||||||
|
driSupport32Bit = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.opengl.extraPackages = with pkgs; [
|
||||||
|
vaapiVdpau
|
||||||
|
];
|
||||||
|
|
||||||
|
# This is for the benefit of VSCODE running natively in wayland
|
||||||
|
environment.sessionVariables.NIXOS_OZONE_WL = "1";
|
||||||
|
|
||||||
|
hardware.nvidia = {
|
||||||
|
|
||||||
|
# Modesetting is required.
|
||||||
|
modesetting.enable = true;
|
||||||
|
|
||||||
|
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
|
||||||
|
# Enable this if you have graphical corruption issues or application crashes after waking
|
||||||
|
# up from sleep. This fixes it by saving the entire VRAM memory to /tmp/ instead
|
||||||
|
# of just the bare essentials.
|
||||||
|
powerManagement.enable = false;
|
||||||
|
|
||||||
|
# Fine-grained power management. Turns off GPU when not in use.
|
||||||
|
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
|
||||||
|
powerManagement.finegrained = false;
|
||||||
|
|
||||||
|
# Use the NVidia open source kernel module (not to be confused with the
|
||||||
|
# independent third-party "nouveau" open source driver).
|
||||||
|
# Support is limited to the Turing and later architectures. Full list of
|
||||||
|
# supported GPUs is at:
|
||||||
|
# https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
|
||||||
|
# Only available from driver 515.43.04+
|
||||||
|
# Currently alpha-quality/buggy, so false is currently the recommended setting.
|
||||||
|
open = false;
|
||||||
|
|
||||||
|
# Enable the Nvidia settings menu,
|
||||||
|
# accessible via `nvidia-settings`.
|
||||||
|
nvidiaSettings = true;
|
||||||
|
|
||||||
|
# Optionally, you may need to select the appropriate driver version for your specific GPU.
|
||||||
|
# package = config.boot.kernelPackages.nvidiaPackages.stable;
|
||||||
|
|
||||||
|
# manual build nvidia driver, works around some wezterm issues
|
||||||
|
# https://github.com/wez/wezterm/issues/2011
|
||||||
|
package =
|
||||||
|
# let
|
||||||
|
# rcu_patch = pkgs.fetchpatch {
|
||||||
|
# url = "https://github.com/gentoo/gentoo/raw/c64caf53/x11-drivers/nvidia-drivers/files/nvidia-drivers-470.223.02-gpl-pfn_valid.patch";
|
||||||
|
# hash = "sha256-eZiQQp2S/asE7MfGvfe6dA/kdCvek9SYa/FFGp24dVg=";
|
||||||
|
# };
|
||||||
|
# in
|
||||||
|
config.boot.kernelPackages.nvidiaPackages.mkDriver {
|
||||||
|
version = "550.67";
|
||||||
|
sha256_64bit = "sha256-mSAaCccc/w/QJh6w8Mva0oLrqB+cOSO1YMz1Se/32uI=";
|
||||||
|
sha256_aarch64 = "sha256-+UuK0UniAsndN15VDb/xopjkdlc6ZGk5LIm/GNs5ivA=";
|
||||||
|
openSha256 = "sha256-M/1qAQxTm61bznAtCoNQXICfThh3hLqfd0s1n1BFj2A=";
|
||||||
|
settingsSha256 = "sha256-FUEwXpeUMH1DYH77/t76wF1UslkcW721x9BHasaRUaM=";
|
||||||
|
persistencedSha256 = "sha256-ojHbmSAOYl3lOi2X6HOBlokTXhTCK6VNsH6+xfGQsyo=";
|
||||||
|
# patches = [ rcu_patch ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
};
|
||||||
|
}
|
83
nixos/modules/nixos/lib.nix
Normal file
83
nixos/modules/nixos/lib.nix
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
|
||||||
|
# container builder
|
||||||
|
lib.mySystem.mkContainer = options: (
|
||||||
|
let
|
||||||
|
# nix doesnt have an exhausive list of options for oci
|
||||||
|
# so here i try to get a robust list of security options for containers
|
||||||
|
# because everyone needs more tinfoild hat right? RIGHT?
|
||||||
|
|
||||||
|
containerExtraOptions = lib.optionals (lib.attrsets.attrByPath [ "caps" "privileged" ] false options) [ "--privileged" ]
|
||||||
|
++ lib.optionals (lib.attrsets.attrByPath [ "caps" "readOnly" ] false options) [ "--read-only" ]
|
||||||
|
++ lib.optionals (lib.attrsets.attrByPath [ "caps" "tmpfs" ] false options) [ (map (folders: "--tmpfs=${folders}") tmpfsFolders) ]
|
||||||
|
++ lib.optionals (lib.attrsets.attrByPath [ "caps" "noNewPrivileges" ] false options) [ "--security-opt=no-new-privileges" ]
|
||||||
|
++ lib.optionals (lib.attrsets.attrByPath [ "caps" "dropAll" ] false options) [ "--cap-drop=ALL" ];
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
${options.app} = {
|
||||||
|
image = "${options.image}";
|
||||||
|
user = "${options.user}:${options.group}";
|
||||||
|
environment = {
|
||||||
|
TZ = config.time.timeZone;
|
||||||
|
} // lib.attrsets.attrByPath [ "env" ] { } options;
|
||||||
|
environmentFiles = lib.attrsets.attrByPath [ "envFiles" ] [ ] options;
|
||||||
|
volumes = [ "/etc/localtime:/etc/localtime:ro" ]
|
||||||
|
++ lib.attrsets.attrByPath [ "volumes" ] [ ] options;
|
||||||
|
ports = lib.attrsets.attrByPath [ "ports" ] [ ] options;
|
||||||
|
extraOptions = containerExtraOptions;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# build a restic restore set for both local and remote
|
||||||
|
lib.mySystem.mkRestic = options: (
|
||||||
|
let
|
||||||
|
excludePath = if builtins.hasAttr "excludePath" options then options.excludePath else [ ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "02:05";
|
||||||
|
Persistent = true;
|
||||||
|
RandomizedDelaySec = "3h";
|
||||||
|
};
|
||||||
|
pruneOpts = [
|
||||||
|
"--keep-daily 7"
|
||||||
|
"--keep-weekly 5"
|
||||||
|
"--keep-monthly 12"
|
||||||
|
];
|
||||||
|
initialize = true;
|
||||||
|
backupPrepareCommand = ''
|
||||||
|
# remove stale locks - this avoids some occasional annoyance
|
||||||
|
#
|
||||||
|
${pkgs.restic}/bin/restic unlock --remove-all || true
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# local backup
|
||||||
|
"${options.app}-local" = {
|
||||||
|
inherit pruneOpts timerConfig initialize backupPrepareCommand;
|
||||||
|
# Move the path to the zfs snapshot path
|
||||||
|
paths = map (x: "${config.mySystem.system.resticBackup.mountPath}/${x}") options.paths;
|
||||||
|
passwordFile = config.sops.secrets."services/restic/password".path;
|
||||||
|
exclude = excludePath;
|
||||||
|
repository = "${config.mySystem.system.resticBackup.local.location}/${options.appFolder}";
|
||||||
|
# inherit (options) user;
|
||||||
|
};
|
||||||
|
|
||||||
|
# remote backup
|
||||||
|
"${options.app}-remote" = {
|
||||||
|
inherit pruneOpts timerConfig initialize backupPrepareCommand;
|
||||||
|
# Move the path to the zfs snapshot path
|
||||||
|
paths = map (x: "${config.mySystem.system.resticBackup.mountPath}/${x}") options.paths;
|
||||||
|
environmentFile = config.sops.secrets."services/restic/env".path;
|
||||||
|
passwordFile = config.sops.secrets."services/restic/password".path;
|
||||||
|
repository = "${config.mySystem.system.resticBackup.remote.location}/${options.appFolder}";
|
||||||
|
exclude = excludePath;
|
||||||
|
# inherit (options) user;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
5
nixos/modules/nixos/programs/default.nix
Normal file
5
nixos/modules/nixos/programs/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./shell
|
||||||
|
];
|
||||||
|
}
|
5
nixos/modules/nixos/programs/shell/default.nix
Normal file
5
nixos/modules/nixos/programs/shell/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./fish.nix
|
||||||
|
];
|
||||||
|
}
|
28
nixos/modules/nixos/programs/shell/fish.nix
Normal file
28
nixos/modules/nixos/programs/shell/fish.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.shell.fish;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.shell.fish =
|
||||||
|
{
|
||||||
|
enable = mkEnableOption "Fish";
|
||||||
|
enablePlugins = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "If we want to add fish plugins";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Install fish systemwide
|
||||||
|
config.programs.fish = mkIf cfg.enable {
|
||||||
|
enable = true;
|
||||||
|
vendor = {
|
||||||
|
completions.enable = true;
|
||||||
|
config.enable = true;
|
||||||
|
functions.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
36
nixos/modules/nixos/security/acme/default.nix
Normal file
36
nixos/modules/nixos/security/acme/default.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.security.acme;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.security.acme.enable = mkEnableOption "acme";
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
sops.secrets = {
|
||||||
|
"security/acme/env".sopsFile = ./secrets.sops.yaml;
|
||||||
|
"security/acme/env".restartUnits = [ "lego.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
|
||||||
|
directories = [ "/var/lib/acme" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
security.acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
defaults.email = "admin@${config.networking.domain}";
|
||||||
|
|
||||||
|
certs.${config.networking.domain} = {
|
||||||
|
extraDomainNames = [
|
||||||
|
"${config.networking.domain}"
|
||||||
|
"*.${config.networking.domain}"
|
||||||
|
];
|
||||||
|
dnsProvider = "cloudflare";
|
||||||
|
dnsResolver = "1.1.1.1:53";
|
||||||
|
credentialsFile = config.sops.secrets."security/acme/env".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
50
nixos/modules/nixos/security/acme/secrets.sops.yaml
Normal file
50
nixos/modules/nixos/security/acme/secrets.sops.yaml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
security:
|
||||||
|
acme:
|
||||||
|
env: ENC[AES256_GCM,data:/exabYG1GvSCxe+TBeECudCN6DQLVBrifa9509skrNRYBsbm1UJRK+WxO0xcrAQkcb1Lse4WE95ueQurSFaY81w=,iv:oD2zcXbO12TlOeH0xLYsaHWw4PVjMHtbVm1LAWp89oo=,tag:dwGBevRXV1B4n/5Sveq5cg==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGVEVHekhud2xUclpURFZB
|
||||||
|
bzgrSkh2TWFibndHcTBpb3AySjRnUWliYzJBCmlROE83ZmJNbWpLaTExOUNwTmZw
|
||||||
|
dElIUThUQVo3MjlobjVrdFMrZUJHM1EKLS0tIGVlcU16Vm12eERKN1o1Ym1yRnJB
|
||||||
|
UkR2YUlLSnBWT0QrWTJuS0hRMnhBM2MKBaaD1gtd52RwKKPf7Yi7fhVEot6kIhAg
|
||||||
|
oaS589WtWIiIiEs/Fde8QfOEJ4aydhuyfVFGxsJkb8a5QGkjKP4Faw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiSEwyT21iZHl2cEtKZTRG
|
||||||
|
RGwwclFtTnNkK2c0U2U0U2NTWTkrckllbHhrCkprUTRxcFJnT3hTS3VuUjZXQUti
|
||||||
|
MDNWZGMrSmFDL2svaTJDZlEwcFpEeEUKLS0tIEVBMDlxZmVEU0UreS9KZnNodWcy
|
||||||
|
bUF2WVRySUd6NDJpbFRiYWszVlFYeGMK7Cl76mjrhdMNKy3SXQ4KqpUJl/P9peJc
|
||||||
|
O+EZ0Q1m0tZrShg1soqdMb1p/00ubvy+Rvxx5Tq0jsIF/Lq0Y3Q3CA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5U0cyRlFDaCsvSEZyeE1q
|
||||||
|
WXpUdU5teVpGT1J6dkJ3VHJudG5UaEIvMlYwCm8xcldxOTFEV3JJbUhYbHNjZjgw
|
||||||
|
T2tDZERTNnZtdVEvNWo5STZTdzZYbnMKLS0tIHpXQUREODAzOWIzcGVxZFJ1a2Rh
|
||||||
|
S2U3T2NUdkVKL3VhWGtRTXUrclJ3TnMKE+6waO9P3EWCGeBRmh3OH689ttLU0F0G
|
||||||
|
hEeBbwYSXfrXtHGSEwwNo++5vP1UVA7KUvLTF2G3mM2nhztJwacWtg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsSEREWEtSWTFUN1l3Uktp
|
||||||
|
YlJCNUZEMnBJL0xQc21VenBkVTgrcVBDQlJFCm51QkhVK2J4ODNQN3AyZ2V4dnQw
|
||||||
|
SVI2blo4SzdSYVdpeDluSFJ1YjFscXMKLS0tIEFMQXAyMGc2MHdMYjkxeHZOWHJ3
|
||||||
|
TnJ6dFBkUGpXMTBjRU5MMVJGTWZmd2sKh83VVst9g3e9lbx2v3b46X23HHtQAeS/
|
||||||
|
//oLEkBDuk5yqnNFtbcSGsWI9DBh9mD87bupw0Hz7GXTC/5LkApTkQ==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-05-18T16:39:41Z"
|
||||||
|
mac: ENC[AES256_GCM,data:tiHQmGUiTuM6aH5Vf9abJUIPDlQ73vmXHCNvkoBHanX7k9ScDxpByqgnDaIR2Tue4SusVVgXFpAlSda9fTT/bSgLUA1+0Qxo4YDLRz5I0pp4sCXAGVELHguADKwAbv+AyT7x4idzecLZ532RGqKkLWHljfOzHtAAlA8FBHH3ylk=,iv:iHlFeshdBreirhJGCBYUucUkz0oEbxYLo6dIeab73e0=,tag:ZeUXSWla9hDldeoqFIw+/g==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.8.1
|
6
nixos/modules/nixos/security/default.nix
Normal file
6
nixos/modules/nixos/security/default.nix
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./acme
|
||||||
|
];
|
||||||
|
}
|
22
nixos/modules/nixos/services/cockpit/default.nix
Normal file
22
nixos/modules/nixos/services/cockpit/default.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.services.cockpit;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.services.cockpit.enable = mkEnableOption "Cockpit";
|
||||||
|
|
||||||
|
config.services.cockpit = mkIf cfg.enable {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
package = pkgs.cockpit.overrideAttrs (old: {
|
||||||
|
# remove packagekit and selinux, don't work on NixOS
|
||||||
|
postBuild = ''
|
||||||
|
${old.postBuild}
|
||||||
|
rm -rf \
|
||||||
|
dist/packagekit \
|
||||||
|
dist/selinux
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
12
nixos/modules/nixos/services/default.nix
Normal file
12
nixos/modules/nixos/services/default.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./cockpit
|
||||||
|
./forgejo
|
||||||
|
./nginx
|
||||||
|
./podman
|
||||||
|
./postgresql
|
||||||
|
./radicale
|
||||||
|
./reboot-required-check.nix
|
||||||
|
./restic
|
||||||
|
];
|
||||||
|
}
|
92
nixos/modules/nixos/services/forgejo/default.nix
Normal file
92
nixos/modules/nixos/services/forgejo/default.nix
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.services.forgejo;
|
||||||
|
http_port = 3000;
|
||||||
|
serviceUser = "forgejo";
|
||||||
|
domain = "git.hsn.dev";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.services.forgejo = {
|
||||||
|
enable = mkEnableOption "Forgejo";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.nginx = {
|
||||||
|
virtualHosts.${domain} = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = config.networking.domain;
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 512M;
|
||||||
|
'';
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:${toString http_port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
# enable sql db dumps daily
|
||||||
|
dump.enable = true;
|
||||||
|
database.type = "postgres";
|
||||||
|
# Enable support for Git Large File Storage
|
||||||
|
lfs.enable = true;
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
DOMAIN = domain;
|
||||||
|
# You need to specify this to remove the port from URLs in the web UI.
|
||||||
|
ROOT_URL = "https://${domain}/";
|
||||||
|
HTTP_PORT = http_port;
|
||||||
|
# Default landing page on 'explore'
|
||||||
|
LANDING_PAGE = "explore";
|
||||||
|
};
|
||||||
|
# You can temporarily allow registration to create an admin user.
|
||||||
|
service = {
|
||||||
|
DISABLE_REGISTRATION = true;
|
||||||
|
ENABLE_NOTIFY_MAIL = true;
|
||||||
|
REGISTER_EMAIL_CONFIRM = true;
|
||||||
|
REQUIRE_SIGNIN_VIEW = false;
|
||||||
|
};
|
||||||
|
indexer = {
|
||||||
|
REPO_INDEXER_ENABLED = true;
|
||||||
|
REPO_INDEXER_PATH = "indexers/repos.bleve";
|
||||||
|
MAX_FILE_SIZE = 1048576;
|
||||||
|
REPO_INDEXER_INCLUDE = "";
|
||||||
|
REPO_INDEXER_EXCLUDE = "resources/bin/**";
|
||||||
|
};
|
||||||
|
picture = {
|
||||||
|
AVATAR_UPLOAD_PATH = "/var/lib/forgejo/data/avatars";
|
||||||
|
REPOSITORY_AVATAR_UPLOAD_PATH = "/var/lib/forgejo/data/repo-avatars";
|
||||||
|
};
|
||||||
|
# Add support for actions, based on act: https://github.com/nektos/act
|
||||||
|
actions = {
|
||||||
|
ENABLED = true;
|
||||||
|
};
|
||||||
|
# Sending emails is completely optional
|
||||||
|
# You can send a test email from the web UI at:
|
||||||
|
# Profile Picture > Site Administration > Configuration > Mailer Configuration
|
||||||
|
mailer = {
|
||||||
|
ENABLED = true;
|
||||||
|
SMTP_ADDR = "smtp.mailgun.org";
|
||||||
|
FROM = "git@hsn.dev";
|
||||||
|
USER = "git@mg.hsn.dev";
|
||||||
|
SMTP_PORT = 587;
|
||||||
|
};
|
||||||
|
session = {
|
||||||
|
COOKIE_SECURE = true;
|
||||||
|
COOKIE_NAME = "session";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mailerPasswordFile = config.sops.secrets."services/forgejo/smtp/password".path;
|
||||||
|
};
|
||||||
|
# sops
|
||||||
|
sops.secrets."services/forgejo/smtp/password" = {
|
||||||
|
sopsFile = ./secrets.sops.yaml;
|
||||||
|
owner = serviceUser;
|
||||||
|
mode = "400";
|
||||||
|
restartUnits = [ "forgejo.service" ];
|
||||||
|
};
|
||||||
|
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
|
||||||
|
directories = [ "/var/lib/forgejo" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
51
nixos/modules/nixos/services/forgejo/secrets.sops.yaml
Normal file
51
nixos/modules/nixos/services/forgejo/secrets.sops.yaml
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
services:
|
||||||
|
forgejo:
|
||||||
|
smtp:
|
||||||
|
password: ENC[AES256_GCM,data:p5iDVW+V0aIlj9RTHpMgko/1ahVkiHXafgm2u2g3TTrYFORBqCJqv+lCSSm4mGIabn4=,iv:GIx/dnn1y6Is6uzKEkmo326AUSS+I5RnLsV2duKHPBo=,tag:7R4222rGEsK+egunnB+llg==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVOU9SMEZvQUxhZWU2dzJ0
|
||||||
|
Z1ZUODd0R2Rtb2lmaHhweC9Tb0J2anJuRno4Cis5UGZHc3pobkQ2OUJwSy9tV1RF
|
||||||
|
SmNvUi9Xek9oVFdPdzZQUnlJeWtBSEEKLS0tIFpoWTZOYlFOK2p4bTFaUVhGV1hz
|
||||||
|
dlpWOWhLT2VtYXdDQjJlWnh4T05TT3MKJtewm9QN1EfT8IQkkHdH0GGNDyg1wH6Z
|
||||||
|
Ja6lcZB580FPEHwoMC7cayQe5v82vbQsj6s8mOaUW9yRQLMQMkmOfA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6bUNpMWJ1YklkV1JPMnFi
|
||||||
|
S0tiajlKblV5aTU2djJaQjN0M1IwOU9pdTNRCnFycmQ5WHFadmxhZ1R6a1ZHYjlW
|
||||||
|
TjVCN2dUelc5Qkt5Y0ZtYUtNRHN0WTAKLS0tIDFKSUE2YzFmQzB1TjgrRDFEalJO
|
||||||
|
MDg0bU9NS3VObVVYNDAvY1JIRU5xZEEKSWzp9smLNYypodRIh49XPBxS536XtFWf
|
||||||
|
kJWaLiUfULifcN46F8Tyts9dGHXx/bOgM5rCFAqtqTL7EaJbam13pw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuQ09PSWwyY2tGZzdyOGxq
|
||||||
|
KzZuUW95Z2QzVXY4dk5tRGZ3MXMxNW9INXlRCmkra2t2UUMwWnBhM0VoTnpUaWIx
|
||||||
|
UW13a3VxZWJyL0ZDdk1IVXJNQitpblkKLS0tIGMwZHJqOGt4Y2FCUUUrc2tEQjY0
|
||||||
|
eWp3WmdOMUlTNVlUT3FMM0JCTnViQ28KE6rpeFodW4BAIDVdjpgPpRs26XgUya3b
|
||||||
|
Xbg6IuB90DvzNMKkoGB36Dh5cWUGFBsJ3QYopSDQGFbUepyDQa4Wvw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6VG9uejd2YTZ4c1p3akFZ
|
||||||
|
dUtEbXk3S1UzeEhLeld4VXVLK1dVKytlOEc4ClFwbVVUUG9SbzB2bDZwRHA2cE4y
|
||||||
|
STFLOWR3S0YrQ1FBbjJDV3o1aW1rNjgKLS0tIDlnQkZhRlpXanY5TzViVzdTNGpo
|
||||||
|
NDhZZ24zWmwwNVE4VDM0bllyUkdxVncKdyYx4r4ERRy2lz7b2oK4JvzF1RnIJ/mV
|
||||||
|
neTz0N1LSdmTUAOUtRT7D73tR6HhBZQNxH4LIsYiRllto46mEamx7g==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-05-18T16:39:41Z"
|
||||||
|
mac: ENC[AES256_GCM,data:TQ019mze1TDfHM3unUvhLzQOdPVhZ0lIw+CbcuSGIqpjITr7nGVRYtPMvHtY9taxaAQgpdJghOaP9MS/YR6KT9II54qYtel944rmOHxOIpB8Oy/mRHBJvx1JhQxHzxPx6hLsLxNagSbgIpyiNGwMiR2gedBLPI/BBNcPGESiMTA=,iv:m4UnG4p0eWzRmspSU/RL4HSeq3Fr5t+9FnNMxgCMOJE=,tag:w2aJxYjVoEHlaQAT+VAa7g==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.8.1
|
62
nixos/modules/nixos/services/nginx/default.nix
Normal file
62
nixos/modules/nixos/services/nginx/default.nix
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.services.nginx;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.services.nginx.enable = mkEnableOption "nginx";
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
recommendedBrotliSettings = true;
|
||||||
|
|
||||||
|
proxyResolveWhileRunning = true; # needed to ensure nginx loads even if it cant resolve vhosts
|
||||||
|
|
||||||
|
statusPage = true;
|
||||||
|
enableReload = true;
|
||||||
|
|
||||||
|
# Only allow PFS-enabled ciphers with AES256
|
||||||
|
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
||||||
|
|
||||||
|
appendHttpConfig = ''
|
||||||
|
# Minimize information leaked to other domains
|
||||||
|
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||||
|
|
||||||
|
# Disable embedding as a frame
|
||||||
|
add_header X-Frame-Options DENY;
|
||||||
|
|
||||||
|
# Prevent injection of code in other mime types (XSS Attacks)
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
|
||||||
|
'';
|
||||||
|
commonHttpConfig = ''
|
||||||
|
add_header X-Clacks-Overhead "GNU Terry Pratchett";
|
||||||
|
'';
|
||||||
|
# provide default host with returning error
|
||||||
|
# else nginx returns the first server
|
||||||
|
# in the config file... >:S
|
||||||
|
virtualHosts = {
|
||||||
|
"_" = {
|
||||||
|
default = true;
|
||||||
|
rejectSSL = true;
|
||||||
|
extraConfig = "return 444;";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
allowedTCPPorts = [ 80 443 ];
|
||||||
|
allowedUDPPorts = [ 80 443 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# required for using acme certs
|
||||||
|
users.users.nginx.extraGroups = [ "acme" ];
|
||||||
|
};
|
||||||
|
}
|
51
nixos/modules/nixos/services/podman/default.nix
Normal file
51
nixos/modules/nixos/services/podman/default.nix
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.services.podman;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.services.podman.enable = mkEnableOption "Podman";
|
||||||
|
|
||||||
|
config = mkIf cfg.enable
|
||||||
|
{
|
||||||
|
virtualisation.podman = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
dockerCompat = true;
|
||||||
|
extraPackages = [ pkgs.zfs ];
|
||||||
|
|
||||||
|
# regular cleanup
|
||||||
|
autoPrune.enable = true;
|
||||||
|
autoPrune.dates = "weekly";
|
||||||
|
|
||||||
|
# and add dns
|
||||||
|
defaultNetwork.settings = {
|
||||||
|
dns_enabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
virtualisation.oci-containers = {
|
||||||
|
backend = "podman";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
podman-tui # status of containers in the terminal
|
||||||
|
lazydocker
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.fish.shellAliases = {
|
||||||
|
# lazydocker --> lazypodman
|
||||||
|
lazypodman="sudo DOCKER_HOST=unix:///run/podman/podman.sock lazydocker";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.interfaces.podman0.allowedUDPPorts = [ 53 ];
|
||||||
|
|
||||||
|
# extra user for containers
|
||||||
|
users.users.kah = {
|
||||||
|
uid = 568;
|
||||||
|
group = "kah";
|
||||||
|
};
|
||||||
|
users.groups.kah = { };
|
||||||
|
users.users.jahanson.extraGroups = [ "kah" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
71
nixos/modules/nixos/services/postgresql/default.nix
Normal file
71
nixos/modules/nixos/services/postgresql/default.nix
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.${category}.${app};
|
||||||
|
app = "postgresql";
|
||||||
|
category = "services";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.${category}.${app} =
|
||||||
|
{
|
||||||
|
enable = mkEnableOption "${app}";
|
||||||
|
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
|
||||||
|
prometheus = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "Enable prometheus scraping";
|
||||||
|
default = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
backupLocation = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.string;
|
||||||
|
description = "Location for sql backups to be stored.";
|
||||||
|
default = "/persist/backup/postgresql";
|
||||||
|
};
|
||||||
|
backup = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "Enable backups";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
identMap = ''
|
||||||
|
# ArbitraryMapName systemUser DBUser
|
||||||
|
superuser_map root postgres
|
||||||
|
superuser_map postgres postgres
|
||||||
|
# Let other names login as themselves
|
||||||
|
superuser_map /^(.*)$ \1
|
||||||
|
'';
|
||||||
|
|
||||||
|
authentication = ''
|
||||||
|
#type database DBuser auth-method optional_ident_map
|
||||||
|
local sameuser all peer map=superuser_map
|
||||||
|
'';
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
max_connections = 200;
|
||||||
|
random_page_cost = 1.1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# enable backups
|
||||||
|
services.postgresqlBackup = mkIf cfg.backup {
|
||||||
|
enable = lib.mkForce true;
|
||||||
|
location = cfg.backupLocation;
|
||||||
|
};
|
||||||
|
|
||||||
|
### firewall config
|
||||||
|
|
||||||
|
# networking.firewall = mkIf cfg.openFirewall {
|
||||||
|
# allowedTCPPorts = [ port ];
|
||||||
|
# allowedUDPPorts = [ port ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
110
nixos/modules/nixos/services/radicale/default.nix
Normal file
110
nixos/modules/nixos/services/radicale/default.nix
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.${category}.${app};
|
||||||
|
app = "radicale";
|
||||||
|
category = "services";
|
||||||
|
user = app; #string
|
||||||
|
group = app; #string
|
||||||
|
port = 5232; #int
|
||||||
|
appFolder = "/var/lib/${app}";
|
||||||
|
url = "${app}.jahanson.tech";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.${category}.${app} =
|
||||||
|
{
|
||||||
|
enable = mkEnableOption "${app}";
|
||||||
|
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
|
||||||
|
monitor = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "Enable gatus monitoring";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
prometheus = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "Enable prometheus scraping";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
backups = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "Enable local backups";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
sops.secrets."${category}/${app}/htpasswd" = {
|
||||||
|
sopsFile = ./secrets.sops.yaml;
|
||||||
|
owner = user;
|
||||||
|
inherit group;
|
||||||
|
restartUnits = [ "${app}.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.jahanson.extraGroups = [ group ];
|
||||||
|
|
||||||
|
environment.persistence."${config.mySystem.system.impermanence.persistPath}" = lib.mkIf config.mySystem.system.impermanence.enable {
|
||||||
|
hideMounts = true;
|
||||||
|
directories = [ "/var/lib/radicale/" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
## service
|
||||||
|
services.radicale = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
server.hosts = [ "0.0.0.0:${builtins.toString port}" ];
|
||||||
|
auth = {
|
||||||
|
type = "htpasswd";
|
||||||
|
htpasswd_filename = config.sops.secrets."${category}/${app}/htpasswd".path;
|
||||||
|
htpasswd_encryption = "plain";
|
||||||
|
realm = "Radicale - Password Required";
|
||||||
|
};
|
||||||
|
storage.filesystem_folder = "/var/lib/radicale/collections";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
### gatus integration
|
||||||
|
mySystem.services.gatus.monitors = mkIf cfg.monitor [
|
||||||
|
{
|
||||||
|
name = app;
|
||||||
|
group = "${category}";
|
||||||
|
url = "https://${url}";
|
||||||
|
interval = "1m";
|
||||||
|
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
### Ingress
|
||||||
|
services.nginx.virtualHosts.${host} = {
|
||||||
|
useACMEHost = config.networking.domain;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${builtins.toString port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
### firewall config
|
||||||
|
|
||||||
|
# networking.firewall = mkIf cfg.openFirewall {
|
||||||
|
# allowedTCPPorts = [ port ];
|
||||||
|
# allowedUDPPorts = [ port ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
### backups
|
||||||
|
warnings = [
|
||||||
|
(mkIf (!cfg.backups && config.mySystem.purpose != "Development")
|
||||||
|
"WARNING: Backups for ${app} are disabled!")
|
||||||
|
];
|
||||||
|
|
||||||
|
services.restic.backups = mkIf cfg.backups (config.lib.mySystem.mkRestic
|
||||||
|
{
|
||||||
|
inherit app user;
|
||||||
|
paths = [ appFolder ];
|
||||||
|
inherit appFolder;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
50
nixos/modules/nixos/services/radicale/secrets.sops.yaml
Normal file
50
nixos/modules/nixos/services/radicale/secrets.sops.yaml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
services:
|
||||||
|
radicale:
|
||||||
|
htpasswd: ENC[AES256_GCM,data:4y6QUrivlOpUVNAGDuPb9w==,iv:AS13cN3EKDEfRCc6USejkYG4SEFS4sPoYrfok8jsfYg=,tag:60ZhYvH/+SQhZKR6M9Zlfw==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLc011SkxreTJSZERMemlS
|
||||||
|
clM0NnhPekF3bFZiUXUreDZEN3dkN3NmN0RNCmM3UEdlV3Azbk4yL2dpS3ZRQVpv
|
||||||
|
OWRQZ2E0eGU5cVIxRUU1c3RxMnpucEUKLS0tIHhjVXhtZEdVb3lvRnpoVGdJbkNq
|
||||||
|
WEM1bGRUOFVrOU5jbmhxSmpRK0F4WWsKoV2ABFGgcLb0qMmorOzNaAzPf6AbMfr0
|
||||||
|
PUdIkaXLJrF3Qi3bts96KhlPLUA7llArSMrUBtkXeCit6xS+87Imuw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBka1htN2tsN2ZZMkpDdHph
|
||||||
|
dk5EY1JkM0hONlRiaXFhdGVIT0xuVDA0b2tBCnlTVExGOHg5RFdiRzU0RWd3dEg3
|
||||||
|
aXB2UkhQRUF6QnBRN0FnNjRqMWIwRkUKLS0tIHJxOWNmR09PRVFQK1E3Um1laHJj
|
||||||
|
VmdPdHl0OGtGODBIZHVzelByaVVoRTAKWb7/Th4zdNFo+K+rwi+nHpbftxnnMOlt
|
||||||
|
BV0hsMpFBaQZXw01n9uw71MZiJZAbZOMA9P+toMKL9UwWSx+isa3gA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNVTdVN1VnN1JpWkJFWC95
|
||||||
|
Qmc3dUNQdUtWSjRwWlVSVlJ2aGZ1MXIrMEFJCjNtck5vcGVhNnFQNXk2MjlHSC9P
|
||||||
|
aDU3WHQwbWdtbTBMcWdCUFE4Ulg5RlkKLS0tIGFDYnpGNE1SY2cvaUk4cWtBVmN6
|
||||||
|
VGRIaEpkUk1qN1RsakV2YkdCbGJhUGcK8l4O+ysy9MeOq5uqnzt9GdkkH53BPtFf
|
||||||
|
rmONh4pxPogBB0IsvZBz2NUsKkixnucEK0+SrF2X5x0wveMl/2Nm3Q==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3d2FMMStGS2dSYVcxMHNM
|
||||||
|
QXdPenBQMXJlWFJWcHp0U0h0SkNpWWlNdXgwClBTMk1TQXg4M3ZueVZha1dNN1gv
|
||||||
|
cTNuS3hBblNPQjBCa3o3N2xyNG9EZWMKLS0tIEo5SVc1b04xZndSNXQ4T3BOTmtr
|
||||||
|
M1NVZkphS2E1R2c3dWovcHlaTloxTkUKsDiyHq40XddMdcZ/2UmOUnPSu44SWTRZ
|
||||||
|
ZcDiYbfU4R7Ysgqaxl2iqBun/GOPWf4yeAbcynwXsLMUGG+XnsRWVw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-05-18T16:39:41Z"
|
||||||
|
mac: ENC[AES256_GCM,data:9HLkT8t+LOSeVCWbjMhXMi7XduJ0nw4nZz9/dYCeyMW0w0/NscYn2avSUSks/5j14xAt4/NFmuM+KxW6z2dEdXE7DsCo1nWh+WyaTpL1QUId5xSWc6abQaexaKeRu/3QJ1wLNFgotaCuut96iFFTmvDL+t266ozxst8N3iR7zhk=,iv:NQwgSFv6Ogybrs6BMYl9eLeu0kNIJpmHR0MJCYHbCxA=,tag:X3BkmlHDt3E3GFT1iDYJHg==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.8.1
|
45
nixos/modules/nixos/services/reboot-required-check.nix
Normal file
45
nixos/modules/nixos/services/reboot-required-check.nix
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.services.rebootRequiredCheck;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.services.rebootRequiredCheck.enable = mkEnableOption "Reboot required check";
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# Enable timer
|
||||||
|
systemd.timers."reboot-required-check" = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
# start at boot
|
||||||
|
OnBootSec = "0m";
|
||||||
|
# check every hour
|
||||||
|
OnUnitActiveSec = "1h";
|
||||||
|
Unit = "reboot-required-check.service";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Below script will check if initrd, kernel, kernel-modules that were booted match the current system
|
||||||
|
# i.e. if a nixos-rebuild switch has upgraded anything
|
||||||
|
systemd.services."reboot-required-check" = {
|
||||||
|
script = ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# compare current system with booted sysetm to determine if a reboot is required
|
||||||
|
if [[ "$(readlink /run/booted-system/{initrd,kernel,kernel-modules})" == "$(readlink /run/current-system/{initrd,kernel,kernel-modules})" ]]; then
|
||||||
|
# check if the '/var/run/reboot-required' file exists and if it does, remove it
|
||||||
|
if [[ -f /var/run/reboot-required ]]; then
|
||||||
|
rm /var/run/reboot-required || { echo "Failed to remove /var/run/reboot-required"; exit 1; }
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "reboot required"
|
||||||
|
touch /var/run/reboot-required || { echo "Failed to create /var/run/reboot-required"; exit 1; }
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "root";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
102
nixos/modules/nixos/services/restic/default.nix
Normal file
102
nixos/modules/nixos/services/restic/default.nix
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.system.resticBackup;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.system.resticBackup = {
|
||||||
|
local = {
|
||||||
|
enable = mkEnableOption "Local backups" // { default = true; };
|
||||||
|
location = mkOption
|
||||||
|
{
|
||||||
|
type = types.str;
|
||||||
|
description = "Location for local backups";
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
remote = {
|
||||||
|
enable = mkEnableOption "Remote backups" // { default = true; };
|
||||||
|
location = mkOption
|
||||||
|
{
|
||||||
|
type = types.str;
|
||||||
|
description = "Location for remote backups";
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mountPath = mkOption
|
||||||
|
{
|
||||||
|
type = types.str;
|
||||||
|
description = "Location for snapshot mount";
|
||||||
|
default = "/mnt/nightly_backup";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
|
||||||
|
# Warn if backups are disable and machine isnt a dev box
|
||||||
|
warnings = [
|
||||||
|
(mkIf (!cfg.local.enable && config.mySystem.purpose != "Development") "WARNING: Local backups are disabled!")
|
||||||
|
(mkIf (!cfg.remote.enable && config.mySystem.purpose != "Development") "WARNING: Remote backups are disabled!")
|
||||||
|
];
|
||||||
|
|
||||||
|
sops.secrets = mkIf (cfg.local.enable || cfg.remote.enable) {
|
||||||
|
"services/restic/password" = {
|
||||||
|
sopsFile = ./secrets.sops.yaml;
|
||||||
|
owner = "kah";
|
||||||
|
group = "kah";
|
||||||
|
};
|
||||||
|
|
||||||
|
"services/restic/env" = {
|
||||||
|
sopsFile = ./secrets.sops.yaml;
|
||||||
|
owner = "kah";
|
||||||
|
group = "kah";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.persistence = mkIf (cfg.local.enable || cfg.remote.enable) {
|
||||||
|
"${config.mySystem.system.impermanence.persistPath}" = {
|
||||||
|
directories = [ "/var/lib/containers" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# useful commands:
|
||||||
|
# view snapshots - zfs list -t snapshot
|
||||||
|
|
||||||
|
# below takes a snapshot of the zfs persist volume
|
||||||
|
# ready for restic syncs
|
||||||
|
# essentially its a nightly rotation of atomic state at 2am.
|
||||||
|
|
||||||
|
# this is the safest option, as if you run restic
|
||||||
|
# on live services/databases/etc, you will have
|
||||||
|
# a bad day when you try and restore
|
||||||
|
# (backing up a in-use file can and will cause corruption)
|
||||||
|
|
||||||
|
# ref: https://cyounkins.medium.com/correct-backups-require-filesystem-snapshots-23062e2e7a15
|
||||||
|
systemd = mkIf (cfg.local.enable || cfg.remote.enable) {
|
||||||
|
|
||||||
|
timers.restic_nightly_snapshot = {
|
||||||
|
description = "Nightly ZFS snapshot timer";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
partOf = [ "restic_nightly_snapshot.service" ];
|
||||||
|
timerConfig.OnCalendar = "2:00";
|
||||||
|
timerConfig.Persistent = "true";
|
||||||
|
};
|
||||||
|
|
||||||
|
# recreate snapshot and mount, ready for backup
|
||||||
|
# I used mkdir -p over a nix tmpfile, as mkdir -p exits cleanly
|
||||||
|
# if the folder already exists, and tmpfiles complain
|
||||||
|
# if the folder exists and is already mounted.
|
||||||
|
services.restic_nightly_snapshot = {
|
||||||
|
description = "Nightly ZFS snapshot for Restic";
|
||||||
|
path = with pkgs; [ zfs busybox ];
|
||||||
|
serviceConfig.Type = "simple";
|
||||||
|
script = ''
|
||||||
|
mkdir -p /mnt/nightly_backup/ && \
|
||||||
|
umount ${cfg.mountPath} || true && \
|
||||||
|
zfs destroy rpool/safe/persist@restic_nightly_snap || true && \
|
||||||
|
zfs snapshot rpool/safe/persist@restic_nightly_snap && \
|
||||||
|
mount -t zfs rpool/safe/persist@restic_nightly_snap ${cfg.mountPath}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
52
nixos/modules/nixos/services/restic/secrets.sops.yaml
Normal file
52
nixos/modules/nixos/services/restic/secrets.sops.yaml
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
services:
|
||||||
|
restic:
|
||||||
|
password: ENC[AES256_GCM,data:23E=,iv:qK5OxK70KSC6nxsiovOWLDG1+6Mdlf+DNibc/mm3uGA=,tag:GV3V+T/Y8dO/L7pv+OkHzg==,type:str]
|
||||||
|
repository: ENC[AES256_GCM,data:Sbao4Q==,iv:M9asdh36DY4Ys3RHugTeduECunSkrcL9yjE0j+CaCTk=,tag:Nmy8LNJbwr7cOTQd1p/kqQ==,type:str]
|
||||||
|
env: ENC[AES256_GCM,data:wNFPsVW6DwZF6Qyyztt0Jw==,iv:PrP6gq+IMTUSKWIKt8zV8o1wbR51vZuZ95Yjwt07ypU=,tag:bBO0tYVR4qrSTZxMoQKgZA==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaMzZ0Y0FRaUdzY0tMeEx5
|
||||||
|
VUJxZkFRUlY3clI1ejVCT0xPNnN3NTh1OHhZCnh2YkxkemZ0ekwxT1NQKzIvTGlH
|
||||||
|
ejZISVJqVmM2UE1iM0M1eGpDSTN6VGcKLS0tIHJxSEhobUxoYWNXeE1LbWV6N0t1
|
||||||
|
dGluUjZCbjFMMktnMFhHSVRscUtUNFEKFAEjmLUA0/9iZLQ4EhpPgyYYYkzQCpUL
|
||||||
|
bo83xqeLmxY7jU8HGF2YNyBe+I9LHpZvxDTiXzBDiK0Bry9b57hWgg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLS1diU0xaU0M0amJEajM3
|
||||||
|
YkpDeUh2VlNGa3liTFZMOGZYUDRoRUNGeldzCk5kSTcrOXNsclJTUnRoMEZqT0s5
|
||||||
|
WTVKcFh4WVlSY0JlYUp0QmF4dWhCWlEKLS0tIGhoeERZWmZCcHR5bEtRZW1JczFy
|
||||||
|
bEl2Yy9mb1NnbUx6WFFHUGhjUXNqV2cK4M0cAXzjNzG09g2FHCZUw8NQkw6Qw3o9
|
||||||
|
G3uFAkWw1Dny8PewS4tzOErAZlUQ0iKJDgUVqOrrBrfvctTFtBseAw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3WE9jVFRMRC9iNFVaTnNw
|
||||||
|
OEovY3hwYW5kWnlrSTRIbFU5enFJVXlFVTJjCkdueno5bXZFS0VPU2RWdk5PUTRj
|
||||||
|
Tk53UGJVZXZ3MExER2txVlRsVDIvY1kKLS0tIFI3VlNyYzB1S1RLS2JEbW54MTdW
|
||||||
|
aHpBN3ZqWENXc1cvZE5Xa2FiaHNlU0UKQ5/xk21o60JLZ6xNcB0cFHkoTXMN99LD
|
||||||
|
okhdVhlpml06ODoMIsFq/PR3adjeWJRjB7C4/Bz/wzlEUmze3TQMew==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3L0h2T3crY2JpaGMreS8z
|
||||||
|
YkJLOTMvbTRKUFNlWXgzZkpPUVJ5eDFON3pFCnBEeDg1YnpxNXZvdWtPbndRT1VZ
|
||||||
|
ZUhPRFE3TGFYaGluSDRjbkFHdi81NVEKLS0tIFJYZ3NaSVd6a25qMmxZV1VUNk50
|
||||||
|
Wmo2cHY4cUZFMkFlUmNKcmg2RjcrUncKmbMWBL8r6R777c3SvFmmRpRY2oRQsf+A
|
||||||
|
Yqlv0wmrD6A1B61SDRDwkmFggnk0PquznZD/y0JctqRqmcstAscyNQ==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-05-18T16:39:41Z"
|
||||||
|
mac: ENC[AES256_GCM,data:sMTQ25VnUOrMSN9Ro7GoovFWh9Y/4RmHXm/mRHNuOGpl2utXGGQhAGM0F2lpdQwJfd/cRneiDfEJ1GSV+yaSPfTm2KFVVM+Kzl7AyHQO6W1dEvaMhJgGvxixc0SkF9zuU0WXnNOxW67fKUuuZZ69TwMdcVmwF1u7pV9tsONtgf8=,iv:Heynu00CnyU17zNkv1riz2hpulbXOeoi7ukj7c3Qk1g=,tag:Jqkaqq3XSXvENl/8a1z2QA==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.8.1
|
14
nixos/modules/nixos/system/default.nix
Normal file
14
nixos/modules/nixos/system/default.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./impermanence.nix
|
||||||
|
./motd
|
||||||
|
./nix.nix
|
||||||
|
./nfs
|
||||||
|
./openssh.nix
|
||||||
|
./pushover
|
||||||
|
./security.nix
|
||||||
|
./systempackages.nix
|
||||||
|
./time.nix
|
||||||
|
./zfs.nix
|
||||||
|
];
|
||||||
|
}
|
55
nixos/modules/nixos/system/impermanence.nix
Normal file
55
nixos/modules/nixos/system/impermanence.nix
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.system.impermanence;
|
||||||
|
in
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.mySystem.system.impermanence = {
|
||||||
|
enable = mkEnableOption "system impermanence";
|
||||||
|
rootBlankSnapshotName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "blank";
|
||||||
|
};
|
||||||
|
rootPoolName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "rpool/local/root";
|
||||||
|
};
|
||||||
|
persistPath = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/persist";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# move ssh keys
|
||||||
|
|
||||||
|
# bind a initrd command to rollback to blank root after boot
|
||||||
|
boot.initrd.postDeviceCommands = lib.mkAfter ''
|
||||||
|
zfs rollback -r ${cfg.rootPoolName}@${cfg.rootBlankSnapshotName}
|
||||||
|
'';
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = mkIf config.services.openssh.enable [
|
||||||
|
"d /etc/ 0755 root root -" #The - disables automatic cleanup, so the file wont be removed after a period
|
||||||
|
"d /etc/ssh/ 0755 root root -" #The - disables automatic cleanup, so the file wont be removed after a period
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.persistence."${cfg.persistPath}" = {
|
||||||
|
hideMounts = true;
|
||||||
|
directories =
|
||||||
|
[
|
||||||
|
"/var/log" # persist logs between reboots for debugging
|
||||||
|
"/var/lib/cache" # cache files (restic, nginx, contaienrs)
|
||||||
|
"/var/lib/nixos" # nixos state
|
||||||
|
];
|
||||||
|
files = [
|
||||||
|
"/etc/machine-id"
|
||||||
|
"/etc/adjtime" # hardware clock adjustment
|
||||||
|
# ssh keys
|
||||||
|
"/etc/ssh/ssh_host_ed25519_key"
|
||||||
|
"/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
|
"/etc/ssh/ssh_host_rsa_key"
|
||||||
|
"/etc/ssh/ssh_host_rsa_key.pub"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
98
nixos/modules/nixos/system/motd/default.nix
Normal file
98
nixos/modules/nixos/system/motd/default.nix
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
motd = pkgs.writeShellScriptBin "motd"
|
||||||
|
''
|
||||||
|
#! /usr/bin/env bash
|
||||||
|
source /etc/os-release
|
||||||
|
service_status=$(systemctl list-units | grep podman-)
|
||||||
|
RED="\e[31m"
|
||||||
|
GREEN="\e[32m"
|
||||||
|
BOLD="\e[1m"
|
||||||
|
ENDCOLOR="\e[0m"
|
||||||
|
LOAD1=`cat /proc/loadavg | awk {'print $1'}`
|
||||||
|
LOAD5=`cat /proc/loadavg | awk {'print $2'}`
|
||||||
|
LOAD15=`cat /proc/loadavg | awk {'print $3'}`
|
||||||
|
|
||||||
|
MEMORY=`free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100 / $2 }'`
|
||||||
|
|
||||||
|
# time of day
|
||||||
|
HOUR=$(date +"%H")
|
||||||
|
if [ $HOUR -lt 12 -a $HOUR -ge 0 ]
|
||||||
|
then TIME="morning"
|
||||||
|
elif [ $HOUR -lt 17 -a $HOUR -ge 12 ]
|
||||||
|
then TIME="afternoon"
|
||||||
|
else
|
||||||
|
TIME="evening"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
uptime=`cat /proc/uptime | cut -f1 -d.`
|
||||||
|
upDays=$((uptime/60/60/24))
|
||||||
|
upHours=$((uptime/60/60%24))
|
||||||
|
upMins=$((uptime/60%60))
|
||||||
|
upSecs=$((uptime%60))
|
||||||
|
|
||||||
|
figlet "$(hostname)" | lolcat -f
|
||||||
|
printf "$BOLD %-20s$ENDCOLOR %s\n" "Role:" "${config.mySystem.purpose}"
|
||||||
|
printf "\n"
|
||||||
|
${lib.strings.concatStrings (lib.lists.forEach cfg.networkInterfaces (x: "printf \"$BOLD * %-20s$ENDCOLOR %s\\n\" \"IPv4 ${x}\" \"$(ip -4 addr show ${x} | grep -oP '(?<=inet\\s)\\d+(\\.\\d+){3}')\"\n"))}
|
||||||
|
printf "$BOLD * %-20s$ENDCOLOR %s\n" "Release" "$PRETTY_NAME"
|
||||||
|
printf "$BOLD * %-20s$ENDCOLOR %s\n" "Kernel" "$(uname -rs)"
|
||||||
|
[ -f /var/run/reboot-required ] && printf "$RED * %-20s$ENDCOLOR %s\n" "A reboot is required"
|
||||||
|
printf "\n"
|
||||||
|
printf "$BOLD * %-20s$ENDCOLOR %s\n" "CPU usage" "$LOAD1, $LOAD5, $LOAD15 (1, 5, 15 min)"
|
||||||
|
printf "$BOLD * %-20s$ENDCOLOR %s\n" "Memory" "$MEMORY"
|
||||||
|
printf "$BOLD * %-20s$ENDCOLOR %s\n" "System uptime" "$upDays days $upHours hours $upMins minutes $upSecs seconds"
|
||||||
|
printf "\n"
|
||||||
|
if ! type "$zpool" &> /dev/null; then
|
||||||
|
printf "$BOLD Zpool status: $ENDCOLOR\n"
|
||||||
|
zpool status -x | sed -e 's/^/ /'
|
||||||
|
fi
|
||||||
|
if ! type "$zpool" &> /dev/null; then
|
||||||
|
printf "$BOLD Zpool usage: $ENDCOLOR\n"
|
||||||
|
zpool list -Ho name,cap,size | awk '{ printf("%-10s%+3s used out of %+5s\n", $1, $2, $3); }' | sed -e 's/^/ /'
|
||||||
|
fi
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
if [[ -n "$service_status" ]]; then
|
||||||
|
printf "$BOLDService status$ENDCOLOR\n"
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ $line =~ ".scope" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if echo "$line" | grep -q 'failed'; then
|
||||||
|
service_name=$(echo $line | awk '{print $2;}' | sed 's/podman-//g')
|
||||||
|
printf "$RED• $ENDCOLOR%-50s $RED[failed]$ENDCOLOR\n" "$service_name"
|
||||||
|
elif echo "$line" | grep -q 'running'; then
|
||||||
|
service_name=$(echo $line | awk '{print $1;}' | sed 's/podman-//g')
|
||||||
|
printf "$GREEN• $ENDCOLOR%-50s $GREEN[active]$ENDCOLOR\n" "$service_name"
|
||||||
|
else
|
||||||
|
echo "service status unknown"
|
||||||
|
fi
|
||||||
|
done <<< "$service_status"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
cfg = config.mySystem.system.motd;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.system.motd = {
|
||||||
|
enable = lib.mkEnableOption "MOTD";
|
||||||
|
networkInterfaces = lib.mkOption {
|
||||||
|
description = "Network interfaces to monitor";
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
# default = lib.mapAttrsToList (_: val: val.interface)
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [
|
||||||
|
motd
|
||||||
|
pkgs.lolcat
|
||||||
|
pkgs.figlet
|
||||||
|
];
|
||||||
|
programs.fish.interactiveShellInit = lib.mkIf config.programs.fish.enable ''
|
||||||
|
motd
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
24
nixos/modules/nixos/system/nfs/default.nix
Normal file
24
nixos/modules/nixos/system/nfs/default.nix
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{ lib
|
||||||
|
, config
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.services.nfs;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.services.nfs = {
|
||||||
|
enable = lib.mkEnableOption "nfs";
|
||||||
|
exports = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.nfs.server.enable = true;
|
||||||
|
services.nfs.server.exports = cfg.exports;
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
2049
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
38
nixos/modules/nixos/system/nix.nix
Normal file
38
nixos/modules/nixos/system/nix.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.nix;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.nix = {
|
||||||
|
autoOptimiseStore = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "If we want to auto optimise store";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
gc = {
|
||||||
|
enable = mkEnableOption "automatic garbage collection" // {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
persistent = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "Persistent timer for gc, runs at startup if timer missed";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config.nix = {
|
||||||
|
optimise.automatic = cfg.autoOptimiseStore;
|
||||||
|
# automatically garbage collect nix store
|
||||||
|
gc = mkIf cfg.gc.enable {
|
||||||
|
# garbage collection
|
||||||
|
automatic = cfg.gc.enable;
|
||||||
|
dates = "daily";
|
||||||
|
options = "--delete-older-than 7d";
|
||||||
|
inherit (cfg.gc) persistent;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
38
nixos/modules/nixos/system/openssh.nix
Normal file
38
nixos/modules/nixos/system/openssh.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.services.openssh;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.services.openssh = {
|
||||||
|
enable = mkEnableOption "openssh" // { default = true; };
|
||||||
|
passwordAuthentication = mkOption
|
||||||
|
{
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "If password can be accepted for ssh (commonly disable for security hardening)";
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
permitRootLogin = mkOption
|
||||||
|
{
|
||||||
|
type = types.enum [ "yes" "without-password" "prohibit-password" "forced-commands-only" "no" ];
|
||||||
|
description = "If root can login via ssh (commonly disable for security hardening)";
|
||||||
|
default = "prohibit-password";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
settings = {
|
||||||
|
# Harden
|
||||||
|
PasswordAuthentication = cfg.passwordAuthentication;
|
||||||
|
PermitRootLogin = cfg.permitRootLogin;
|
||||||
|
# Automatically remove stale sockets
|
||||||
|
StreamLocalBindUnlink = "yes";
|
||||||
|
# Allow forwarding ports to everywhere
|
||||||
|
GatewayPorts = "clientspecified";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
54
nixos/modules/nixos/system/pushover/default.nix
Normal file
54
nixos/modules/nixos/system/pushover/default.nix
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{ lib
|
||||||
|
, config
|
||||||
|
, pkgs
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.system.systemd.pushover-alerts;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.system.systemd.pushover-alerts.enable = mkEnableOption "Pushover alerts for systemd failures" // { default = true; };
|
||||||
|
options.systemd.services = mkOption {
|
||||||
|
type = with types; attrsOf (
|
||||||
|
submodule {
|
||||||
|
config.onFailure = [ "notify-pushover@%n.service" ];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# Warn if backups are disable and machine isnt a dev box
|
||||||
|
warnings = [
|
||||||
|
(mkIf (!cfg.enable && config.mySystem.purpose != "Development") "WARNING: Pushover SystemD notifications are disabled!")
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services."notify-pushover@" = mkIf cfg.enable {
|
||||||
|
enable = true;
|
||||||
|
onFailure = lib.mkForce [ ]; # cant refer to itself on failure
|
||||||
|
description = "Notify on failed unit %i";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
EnvironmentFile = config.sops.secrets."services/pushover/env".path;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Script calls pushover with some deets.
|
||||||
|
# Here im using the systemd specifier %i passed into the script,
|
||||||
|
# which I can reference with bash $1.
|
||||||
|
scriptArgs = "%i %H";
|
||||||
|
script = ''
|
||||||
|
${pkgs.curl}/bin/curl --fail -s -o /dev/null \
|
||||||
|
--form-string "token=$PUSHOVER_API_KEY" \
|
||||||
|
--form-string "user=$PUSHOVER_USER_KEY" \
|
||||||
|
--form-string "priority=1" \
|
||||||
|
--form-string "html=1" \
|
||||||
|
--form-string "timestamp=$(date +%s)" \
|
||||||
|
--form-string "url=https://$2:9090/system/services#/$1" \
|
||||||
|
--form-string "url_title=View in Cockpit" \
|
||||||
|
--form-string "title=Unit failure: '$1' on $2" \
|
||||||
|
--form-string "message=<b>$1</b> has failed on <b>$2</b><br><u>Journal tail:</u><br><br><i>$(journalctl -u $1 -n 10 -o cat)</i>" \
|
||||||
|
https://api.pushover.net/1/messages.json 2&>1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
45
nixos/modules/nixos/system/security.nix
Normal file
45
nixos/modules/nixos/system/security.nix
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.security;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.security = {
|
||||||
|
sshAgentAuth.enable = lib.mkEnableOption "openssh";
|
||||||
|
wheelNeedsSudoPassword = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "If wheel group users need password for sudo";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
increaseWheelLoginLimits = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "If wheel group users receive increased login limits";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
{
|
||||||
|
security = {
|
||||||
|
sudo.wheelNeedsPassword = cfg.wheelNeedsSudoPassword;
|
||||||
|
# Don't bother with the lecture or the need to keep state about who's been lectured
|
||||||
|
sudo.extraConfig = "Defaults lecture=\"never\"";
|
||||||
|
pam.sshAgentAuth.enable = cfg.sshAgentAuth.enable;
|
||||||
|
# Increase open file limit for sudoers
|
||||||
|
pam.loginLimits = mkIf cfg.increaseWheelLoginLimits [
|
||||||
|
{
|
||||||
|
domain = "@wheel";
|
||||||
|
item = "nofile";
|
||||||
|
type = "soft";
|
||||||
|
value = "524288";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
domain = "@wheel";
|
||||||
|
item = "nofile";
|
||||||
|
type = "hard";
|
||||||
|
value = "1048576";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
20
nixos/modules/nixos/system/systempackages.nix
Normal file
20
nixos/modules/nixos/system/systempackages.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.system;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.system = {
|
||||||
|
packages = mkOption
|
||||||
|
{
|
||||||
|
type = with types; listOf package;
|
||||||
|
description = "List of system level package installs";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# System packages deployed globally.
|
||||||
|
# This is NixOS so lets keep this liiight?
|
||||||
|
# Ideally i'd keep most of it to home-manager user only stuff
|
||||||
|
# and keep server role as light as possible
|
||||||
|
config.environment.systemPackages = cfg.packages;
|
||||||
|
}
|
22
nixos/modules/nixos/system/time.nix
Normal file
22
nixos/modules/nixos/system/time.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.time;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.mySystem.time = {
|
||||||
|
timeZone = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Timezone of system";
|
||||||
|
default = "America/Chicago";
|
||||||
|
};
|
||||||
|
hwClockLocalTime = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "If hardware clock is set to local time (useful for windows dual boot)";
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
time.timeZone = cfg.timeZone;
|
||||||
|
time.hardwareClockInLocalTime = cfg.hwClockLocalTime;
|
||||||
|
};
|
||||||
|
}
|
40
nixos/modules/nixos/system/zfs.nix
Normal file
40
nixos/modules/nixos/system/zfs.nix
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.mySystem.system.zfs;
|
||||||
|
in
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.mySystem.system.zfs = {
|
||||||
|
enable = lib.mkEnableOption "zfs";
|
||||||
|
mountPoolsAtBoot = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
# setup boot
|
||||||
|
boot = {
|
||||||
|
supportedFilesystems = [
|
||||||
|
"zfs"
|
||||||
|
];
|
||||||
|
zfs = {
|
||||||
|
forceImportRoot = false; # if stuck on boot, modify grub options , force importing isnt secure
|
||||||
|
extraPools = cfg.mountPoolsAtBoot;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.zfs = {
|
||||||
|
autoScrub.enable = true;
|
||||||
|
# Defaults to weekly and is a bit too regular for my NAS
|
||||||
|
autoScrub.interval = "weekly";
|
||||||
|
trim.enable = true;
|
||||||
|
};
|
||||||
|
# Pushover notifications
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
busybox
|
||||||
|
];
|
||||||
|
services.zfs.zed.settings = {
|
||||||
|
ZED_PUSHOVER_TOKEN = "$(${pkgs.busybox}/bin/cat ${config.sops.secrets.pushover-api-key.path})";
|
||||||
|
ZED_PUSHOVER_USER = "$(${pkgs.busybox}/bin/cat ${config.sops.secrets.pushover-user-key.path})";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
18
nixos/profiles/README.md
Normal file
18
nixos/profiles/README.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
## Profiles
|
||||||
|
|
||||||
|
Here are the profiles that each host picks from to build up a system.
|
||||||
|
|
||||||
|
Pair a role with a device type and the correct software and settings will be enabled for that configuration.
|
||||||
|
Where possible use the `mySystem` option list to configure defaults via these profiles, so they _can_ be overridden later.
|
||||||
|
|
||||||
|
## Global
|
||||||
|
|
||||||
|
Default global settings that will apply to every device. Things like locale, timezone, etc that wont change machine to machine
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
|
||||||
|
Hardware settings so I can apply per set of machines as standard- i.e. all Raspi4's may benefit from a specific set of additions/hardware overlays.
|
||||||
|
|
||||||
|
## Role
|
||||||
|
|
||||||
|
The roles the machine has. Machines may have multiple roles.
|
44
nixos/profiles/global.nix
Normal file
44
nixos/profiles/global.nix
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
# NOTE
|
||||||
|
# Some 'global' areas have defaults set in their respective modules.
|
||||||
|
# These will be applied when the modules are loaded
|
||||||
|
# Not the global role.
|
||||||
|
# Not sure at this point a good way to manage globals in one place
|
||||||
|
# without mono-repo config.
|
||||||
|
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix") # Generated by nixos-config-generate
|
||||||
|
./global
|
||||||
|
];
|
||||||
|
config = {
|
||||||
|
boot.tmp.cleanOnBoot = true;
|
||||||
|
mySystem = {
|
||||||
|
# basics for all devices
|
||||||
|
time.timeZone = "America/Chicago";
|
||||||
|
security.increaseWheelLoginLimits = true;
|
||||||
|
system.packages = [ pkgs.bat ];
|
||||||
|
domain = "hsn.dev";
|
||||||
|
shell.fish.enable = true;
|
||||||
|
|
||||||
|
# But wont enable plugins globally, leave them for workstations
|
||||||
|
# TODO: Make per device option
|
||||||
|
system.resticBackup.remote.location = "s3:https://x.r2.cloudflarestorage.com/nixos-restic";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
curl
|
||||||
|
wget
|
||||||
|
dnsutils
|
||||||
|
jq
|
||||||
|
yq
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
networking.domain = config.mySystem.domain;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
8
nixos/profiles/global/default.nix
Normal file
8
nixos/profiles/global/default.nix
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./nix.nix
|
||||||
|
./sops.nix
|
||||||
|
./system.nix
|
||||||
|
./users.nix
|
||||||
|
];
|
||||||
|
}
|
47
nixos/profiles/global/nix.nix
Normal file
47
nixos/profiles/global/nix.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
{ lib, nixpkgs, ... }:
|
||||||
|
{
|
||||||
|
## Below is to align shell/system to flake's nixpkgs
|
||||||
|
## ref: https://nixos-and-flakes.thiscute.world/best-practices/nix-path-and-flake-registry
|
||||||
|
|
||||||
|
# Make `nix repl '<nixpkgs>'` use the same nixpkgs as the one used by this flake.
|
||||||
|
environment.etc."nix/inputs/nixpkgs".source = "${nixpkgs}";
|
||||||
|
nix = {
|
||||||
|
# make `nix run nixpkgs#nixpkgs` use the same nixpkgs as the one used by this flake.
|
||||||
|
registry.nixpkgs.flake = nixpkgs;
|
||||||
|
channel.enable = false; # remove nix-channel related tools & configs, we use flakes instead.
|
||||||
|
|
||||||
|
# but NIX_PATH is still used by many useful tools, so we set it to the same value as the one used by this flake.
|
||||||
|
# https://github.com/NixOS/nix/issues/9574
|
||||||
|
settings.nix-path = lib.mkForce "nixpkgs=/etc/nix/inputs/nixpkgs";
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
# Enable flakes
|
||||||
|
experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Substitutions
|
||||||
|
substituters = [
|
||||||
|
"https://hsndev.cachix.org"
|
||||||
|
"https://nix-community.cachix.org"
|
||||||
|
"https://numtide.cachix.org"
|
||||||
|
];
|
||||||
|
|
||||||
|
trusted-public-keys = [
|
||||||
|
"hsndev.cachix.org-1:vN1/XGBZtMLnTFYDmTLDrullgZHSUYY3Kqt+Yg/C+tE="
|
||||||
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||||
|
"numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE="
|
||||||
|
];
|
||||||
|
|
||||||
|
# Fallback quickly if substituters are not available.
|
||||||
|
connect-timeout = 25;
|
||||||
|
# Avoid copying unnecessary stuff over SSH
|
||||||
|
builders-use-substitutes = true;
|
||||||
|
trusted-users = [ "root" "@wheel" ];
|
||||||
|
warn-dirty = false;
|
||||||
|
# The default at 10 is rarely enough.
|
||||||
|
log-lines = lib.mkDefault 25;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
53
nixos/profiles/global/secrets.sops.yaml
Normal file
53
nixos/profiles/global/secrets.sops.yaml
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
services:
|
||||||
|
pushover:
|
||||||
|
env: ENC[AES256_GCM,data:Ug92K492ytxkRMHTw6fmYKgpkz47gBg9aLxqivo+t5GejJbIU1cOewo88/7ASmslceTAiY57NcBTM56eHw7U9+HEq1IjX6RukM/OxZ27R4aMkLCdf1c7DNJ5GOOvX2Zo,iv:uVXUIervTvgLnr60oeWeysB08TR/jy9AjNMWLW75teo=,tag:l2ZGGzMKcVTdnKx5q7XJiA==,type:str]
|
||||||
|
pushover-user-key: ENC[AES256_GCM,data:EWMIbhjq6+CH958H661xlxcVNLSKWHgxVyjTCU50,iv:Ph6z7Tri64WoPnCbTtrCA2ziprID1VXg8rynx6j6OOg=,tag:MZvq0AE1gp9Ga/73s6MWOw==,type:str]
|
||||||
|
pushover-api-key: ENC[AES256_GCM,data:1rnQ/dgls1iLtx3efKT37PyrZyArVbRe7BjmKYqZ,iv:pRvkTjRtpf5PhXG555OR+TVmgzwmJnF8+Pb2wfbTKWU=,tag:3DFYTgLxQFQIT4qTP9cQgQ==,type:str]
|
||||||
|
jahanson-password: ENC[AES256_GCM,data:HPLOlKHCpQIhat5qKKg=,iv:AawKpXj+2ZfEXg/eO2On4qtqHsoxksdRxH6nr+/oTGE=,tag:4wWfOGXybP6B88iGdFMF9A==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age18kj3xhlvgjeg2awwku3r8d95w360uysu0w5ejghnp4kh8qmtge5qwa2vjp
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGSTUzM1RzZEFVZTJBdFAz
|
||||||
|
UnlYSmllNUdWa3BEa1BWQnBtbXZ1YTBnR25RClVIdy9YTUFyZ2VOdHlyVnNxTS9W
|
||||||
|
Smw5dDc2S053ZElsdHZpdTRQc2dCWGsKLS0tIGZXUzNMTFlxaVFWNE1GREphanBu
|
||||||
|
Rkdyd2lXUE5ucUVYT1FOZVlJR0hORGcKC5k9U3D+rfp4yEOx88APxmobjvOnf9jn
|
||||||
|
POshirAInB/FjEOCb6gwmX8Y/0KJK1A69vwrx3+C4S+8xWcTQwnHqA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1z3vjvkead2h934n3w4m5m7tg4tj5qlzagsq6ly84h3tcu7x4ldsqd3s5fg
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMeCtkNnllZ3RHSjdVWHpq
|
||||||
|
N0pXM3B3RVJ2QnNwVXpvN2Q3R09mSFU1QWtnCnRvYnR6eVZCaEJkMjMxeEFzRHZ2
|
||||||
|
enVodXlHUVFGcEZpTnFHT1VkTGwzbFkKLS0tIFhCTzQ3Ny9TOVBTamZ5SHIzKzFZ
|
||||||
|
L2NsSjFGWHR4ZDBQR0FFZUdCUXpPRmcKdC6gSCxkHvThXEhp94b3Gx/5Tz4E2B6C
|
||||||
|
TcwMZVgCC2VkSMASj1Jg08AX+xmJ92gc2xl/v9hQ3MWJbR38KBkaBw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1a8z3p24v32l9yxm5z2l8h7rpc3nhacyfv4jvetk2lenrvsdstd3sdu2kaf
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvMk1XRjdHQUtYbnNrb1oy
|
||||||
|
SnlwVjBEUTd3dFdlaWh6UGlFTzR1RmpKYjE4CmhSKzFBOFFJSmtnM3Zwc3pKUy9j
|
||||||
|
SmJiNFhoVmd0ZzE0V2xDK0dzaGhZRGMKLS0tIHlqbWozZHV1R3JSclQ0ZWNRejlD
|
||||||
|
b1Q4RjJSWm1uSjRVNWd1WjBld1hUbk0KOB+7u0eLMslPCBE745dk7P8kVgELGp6m
|
||||||
|
glDmVIqsKmvutZ54AhCtI/pOuL5vlmnstRn8MCXcZgXbm3a80BSNFg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1d9p83j52m2xg0vh9k7q0uwlxwhs3y6tlv68yg9s2h9mdw2fmmsqshddz5m
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOcUFiQk5yMGJBUitabTB6
|
||||||
|
UHFVRXFVVWFoREV2dXZXcVJ0cG11TlhCUEVVCnAxQkJUUkU1VUhSaWNLQStpcUJu
|
||||||
|
ZzJBQjlUQXhuZk9PZXRJSktnQWFHZmcKLS0tIFI4TUNwREF5cXNXZEd1NUJ3MGFH
|
||||||
|
OFVrMXovMDVZTU5obE42NXkwektRa0UKmd1VNqD43WmhwICUohG2DLsZ9wYsGujp
|
||||||
|
IERwiWAiCppqOEULQeZti8ioPHJDs6tjpuAR+vZ1TD/uhdJP4xsfcA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-05-18T16:39:41Z"
|
||||||
|
mac: ENC[AES256_GCM,data:EXz+9dIdcI21WlJ9r/lewrfx9MjynA1eS82MMnO0BBiE2KV6XcMvrxStMIerXY/0nr2XGoZii8amo072naaHBTCwCsaDlx0Ry3oMyZYZNFwTM2mqIK93CymIkhe/qhMyNxDTmKc3QFEiRtimLnUx8YW27leS1b4mNFHcauXYNHA=,iv:EEmK39VBNXnJayk6z4MfHHsfj7OuwXUeLZQ06q2y2cE=,tag:9PLLS5BbwB1wmA+UV/oIwA==,type:str]
|
||||||
|
pgp: []
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.8.1
|
14
nixos/profiles/global/sops.nix
Normal file
14
nixos/profiles/global/sops.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
|
# Secret for machine-specific pushover
|
||||||
|
sops.secrets."services/pushover/env" = {
|
||||||
|
sopsFile = ./secrets.sops.yaml;
|
||||||
|
};
|
||||||
|
sops.secrets.pushover-user-key = {
|
||||||
|
sopsFile = ./secrets.sops.yaml;
|
||||||
|
};
|
||||||
|
sops.secrets.pushover-api-key = {
|
||||||
|
sopsFile = ./secrets.sops.yaml;
|
||||||
|
};
|
||||||
|
}
|
13
nixos/profiles/global/system.nix
Normal file
13
nixos/profiles/global/system.nix
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
system = {
|
||||||
|
# Enable printing changes on nix build etc with nvd
|
||||||
|
activationScripts.report-changes = ''
|
||||||
|
PATH=$PATH:${lib.makeBinPath [ pkgs.nvd pkgs.nix ]}
|
||||||
|
nvd diff $(ls -dv /nix/var/nix/profiles/system-*-link | tail -2)
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Do not change unless you know what you are doing
|
||||||
|
stateVersion = "24.11";
|
||||||
|
};
|
||||||
|
}
|
39
nixos/profiles/global/users.nix
Normal file
39
nixos/profiles/global/users.nix
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
let
|
||||||
|
ifTheyExist = groups: builtins.filter (group: builtins.hasAttr group config.users.groups) groups;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sops.secrets = {
|
||||||
|
jahanson-password = {
|
||||||
|
sopsFile = ./secrets.sops.yaml;
|
||||||
|
neededForUsers = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.jahanson = {
|
||||||
|
isNormalUser = true;
|
||||||
|
shell = pkgs.fish;
|
||||||
|
hashedPasswordFile = config.sops.secrets.jahanson-password.path;
|
||||||
|
extraGroups =
|
||||||
|
[
|
||||||
|
"wheel"
|
||||||
|
]
|
||||||
|
++ ifTheyExist [
|
||||||
|
"network"
|
||||||
|
"samba-users"
|
||||||
|
"docker"
|
||||||
|
"podman"
|
||||||
|
"audio" # pulseaudio
|
||||||
|
"libvirtd"
|
||||||
|
];
|
||||||
|
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsUe5YF5z8vGcEYtQX7AAiw2rJygGf2l7xxr8nZZa7w"
|
||||||
|
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH3VVFenoJfnu+IFUlD79uxl7L8SFoRup33J2HGny4WEdRgGR41s0MpFKDBmxXZHy4O9Nh8NMMnpy5VhUefnIKI="
|
||||||
|
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPHFQ3hDjjrKsecn3jmSWYlRXy4IJCrepgU1HaIV5VcmB3mUFmIZ/pCZnPmIG/Gbuqf1PP2FQDmHMX5t0hTYG9A="
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIETR70eQJiXaJuB+qpI1z+jFOPbEZoQNRcq4VXkojWfU"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIATyScd8ZRhV7uZmrQNSAbRTs9N/Dbx+Y8tGEDny30sA"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJyA/yMPPo+scxBaDFUk7WeEyMAMhXUro5vi4feOKsJT jahanson@durincore"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
27
nixos/profiles/hw-generic-x86.nix
Normal file
27
nixos/profiles/hw-generic-x86.nix
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
mySystem.system.packages = with pkgs; [
|
||||||
|
ntfs3g
|
||||||
|
];
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
|
||||||
|
initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
||||||
|
kernelModules = [ ];
|
||||||
|
extraModulePackages = [ ];
|
||||||
|
|
||||||
|
# for managing/mounting ntfs
|
||||||
|
supportedFilesystems = [ "ntfs" ];
|
||||||
|
|
||||||
|
loader = {
|
||||||
|
systemd-boot.enable = true;
|
||||||
|
efi.canTouchEfiVariables = true;
|
||||||
|
grub.memtest86.enable = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
|
||||||
|
}
|
26
nixos/profiles/hw-hetzner-cax.nix
Normal file
26
nixos/profiles/hw-hetzner-cax.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ lib, ... }: {
|
||||||
|
imports = [ ];
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "virtio_pci" "virtio_scsi" "usbhid" "sr_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
mySystem = {
|
||||||
|
services.openssh.enable = true;
|
||||||
|
security.wheelNeedsSudoPassword = false;
|
||||||
|
|
||||||
|
# Restic backups disabled.
|
||||||
|
# TODO: configure storagebox for hetzner backups
|
||||||
|
system.resticBackup =
|
||||||
|
{
|
||||||
|
local.enable = false;
|
||||||
|
remote.enable = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
||||||
|
}
|
30
nixos/profiles/hw-thinkpad-t470.nix
Normal file
30
nixos/profiles/hw-thinkpad-t470.nix
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
{
|
||||||
|
boot = {
|
||||||
|
# Use the systemd-boot EFI boot loader.
|
||||||
|
loader = {
|
||||||
|
systemd-boot = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
efi = {
|
||||||
|
canTouchEfiVariables = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Kernel mods
|
||||||
|
initrd = {
|
||||||
|
availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" ];
|
||||||
|
kernelModules = [ ];
|
||||||
|
};
|
||||||
|
kernelModules = [ "kvm-intel" ];
|
||||||
|
extraModulePackages = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
useDHCP = lib.mkDefault true;
|
||||||
|
};
|
||||||
|
# networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
36
nixos/profiles/role-dev.nix
Normal file
36
nixos/profiles/role-dev.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{ config, lib, pkgs, imports, boot, self, inputs, ... }:
|
||||||
|
# Role for dev stations
|
||||||
|
# Could be a workstatio or a headless server.
|
||||||
|
|
||||||
|
with config;
|
||||||
|
{
|
||||||
|
# git & vim are in global
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
jq
|
||||||
|
yq
|
||||||
|
btop
|
||||||
|
dnsutils
|
||||||
|
nix
|
||||||
|
|
||||||
|
# nix dev
|
||||||
|
dnscontrol # for updating internal DNS servers with homelab services
|
||||||
|
|
||||||
|
# TODO Move
|
||||||
|
nil
|
||||||
|
nixpkgs-fmt
|
||||||
|
statix
|
||||||
|
# nvd
|
||||||
|
gh
|
||||||
|
|
||||||
|
# bind # for dns utils like named-checkconf
|
||||||
|
inputs.nix-inspect.packages.${pkgs.system}.default
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.direnv = {
|
||||||
|
# TODO move to home-manager
|
||||||
|
enable = true;
|
||||||
|
nix-direnv.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
47
nixos/profiles/role-server.nix
Normal file
47
nixos/profiles/role-server.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
# Role for headless servers
|
||||||
|
# covers raspi's, sbc, NUC etc, anything
|
||||||
|
# that is headless and minimal for running services
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
# Enable monitoring for remote scraiping
|
||||||
|
mySystem.services.promMonitoring.enable = true;
|
||||||
|
mySystem.services.rebootRequiredCheck.enable = true;
|
||||||
|
mySystem.security.wheelNeedsSudoPassword = false;
|
||||||
|
mySystem.services.cockpit.enable = true;
|
||||||
|
mySystem.system.motd.enable = true;
|
||||||
|
mySystem.services.gatus.monitors = [{
|
||||||
|
name = config.networking.hostName;
|
||||||
|
group = "servers";
|
||||||
|
url = "icmp://${config.networking.hostName}";
|
||||||
|
interval = "1m";
|
||||||
|
conditions = [ "[CONNECTED] == true" ];
|
||||||
|
}];
|
||||||
|
|
||||||
|
nix.settings = {
|
||||||
|
# TODO factor out into mySystem
|
||||||
|
# Avoid disk full issues
|
||||||
|
max-free = lib.mkDefault (1000 * 1000 * 1000);
|
||||||
|
min-free = lib.mkDefault (128 * 1000 * 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
services.logrotate.enable = mkDefault true;
|
||||||
|
environment = {
|
||||||
|
noXlibs = mkDefault true;
|
||||||
|
systemPackages = [ pkgs.lazygit ];
|
||||||
|
};
|
||||||
|
documentation = {
|
||||||
|
enable = mkDefault false;
|
||||||
|
doc.enable = mkDefault false;
|
||||||
|
info.enable = mkDefault false;
|
||||||
|
man.enable = mkDefault false;
|
||||||
|
nixos.enable = mkDefault false;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.command-not-found.enable = mkDefault false;
|
||||||
|
sound.enable = false;
|
||||||
|
hardware.pulseaudio.enable = false;
|
||||||
|
services.udisks2.enable = mkDefault false;
|
||||||
|
};
|
||||||
|
}
|
75
nixos/profiles/role-workstation.nix
Normal file
75
nixos/profiles/role-workstation.nix
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
# Role for workstations
|
||||||
|
# Covers desktops/laptops, expected to have a GUI and do workloads
|
||||||
|
# Will have home-manager installs
|
||||||
|
|
||||||
|
with config;
|
||||||
|
{
|
||||||
|
mySystem = {
|
||||||
|
|
||||||
|
de.gnome.enable = true;
|
||||||
|
|
||||||
|
# Lets see if fish everywhere is OK on the pi's
|
||||||
|
# TODO decide if i drop to bash on pis?
|
||||||
|
shell.fish.enable = true;
|
||||||
|
|
||||||
|
# TODO make nfs server configurable
|
||||||
|
# nfs.nas = {
|
||||||
|
# enable = true;
|
||||||
|
# lazy = true;
|
||||||
|
# };
|
||||||
|
|
||||||
|
system.resticBackup.local.enable = false;
|
||||||
|
system.resticBackup.remote.enable = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
binfmt.emulatedSystems = [ "aarch64-linux" ]; # Enabled for raspi4 compilation
|
||||||
|
plymouth.enable = true; # hide console with splash screen
|
||||||
|
};
|
||||||
|
|
||||||
|
nix.settings = {
|
||||||
|
# TODO factor out into mySystem
|
||||||
|
# Avoid disk full issues
|
||||||
|
max-free = lib.mkDefault (1000 * 1000 * 1000);
|
||||||
|
min-free = lib.mkDefault (128 * 1000 * 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
# set xserver videodrivers if used
|
||||||
|
services.xserver.enable = true;
|
||||||
|
|
||||||
|
services = {
|
||||||
|
fwupd.enable = config.boot.loader.systemd-boot.enable; # fwupd does not work in BIOS mode
|
||||||
|
thermald.enable = true;
|
||||||
|
smartd.enable = true;
|
||||||
|
|
||||||
|
# required for yubikey
|
||||||
|
udev.packages = [ pkgs.yubikey-personalization ];
|
||||||
|
pcscd.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware = {
|
||||||
|
enableAllFirmware = true;
|
||||||
|
sensor.hddtemp = {
|
||||||
|
enable = true;
|
||||||
|
drives = [ "/dev/disk/by-id/*" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
# Sensors etc
|
||||||
|
lm_sensors
|
||||||
|
cpufrequtils
|
||||||
|
cpupower-gui
|
||||||
|
vscode
|
||||||
|
vivaldi
|
||||||
|
termius
|
||||||
|
];
|
||||||
|
|
||||||
|
i18n = {
|
||||||
|
defaultLocale = lib.mkDefault "en_US.UTF-8";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.mtr.enable = true;
|
||||||
|
}
|
13
renovate.json
Normal file
13
renovate.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:base"
|
||||||
|
],
|
||||||
|
"nix": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"lockFileMaintenance": {
|
||||||
|
"enabled": true,
|
||||||
|
"extends": ["schedule:daily"]
|
||||||
|
}
|
||||||
|
}
|
30
shell.nix
Normal file
30
shell.nix
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Shell for bootstrapping flake-enabled nix and home-manager
|
||||||
|
{ pkgs ? let
|
||||||
|
# If pkgs is not defined, instantiate nixpkgs from locked commit
|
||||||
|
lock = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.nixpkgs.locked;
|
||||||
|
nixpkgs = fetchTarball {
|
||||||
|
url = "https://github.com/nixos/nixpkgs/archive/${lock.rev}.tar.gz";
|
||||||
|
sha256 = lock.narHash;
|
||||||
|
};
|
||||||
|
system = builtins.currentSystem;
|
||||||
|
overlays = [ ]; # Explicit blank overlay to avoid interference
|
||||||
|
in
|
||||||
|
import nixpkgs { inherit system overlays; }
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
pkgs.mkShell {
|
||||||
|
# Enable experimental features without having to specify the argument
|
||||||
|
NIX_CONFIG = "experimental-features = nix-command flakes";
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
nix
|
||||||
|
home-manager
|
||||||
|
git
|
||||||
|
nil
|
||||||
|
nixpkgs-fmt
|
||||||
|
go-task
|
||||||
|
sops
|
||||||
|
pre-commit
|
||||||
|
gitleaks
|
||||||
|
];
|
||||||
|
}
|
Loading…
Reference in a new issue