1 Commits
24.05 ... vps1

Author SHA1 Message Date
d73239251c Initial vps1 config migration 2023-12-24 13:03:38 +00:00
69 changed files with 971 additions and 3219 deletions

View File

@ -1,15 +0,0 @@
name: Check flake
on:
push:
branches: ['master']
jobs:
build-amd64-linux:
runs-on: nix
steps:
- uses: actions/checkout@v4
with:
ref: master
- name: Check flake
run: |
echo "Checking flake at ${{ gitea.ref }}"
nix flake check

View File

@ -9,47 +9,8 @@ System and user configuration for NixOS-based systems.
| **Theme:** | adwaita | | **Theme:** | adwaita |
| **Terminal:** | Console | | **Terminal:** | Console |
## Provisioning a new host ## Quick start
> [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) is the module used 1. Copy SSH keypair and `known_hosts` to `~/.ssh`
> for provisioning 1. Import GPG keys and set ultimate trust with `echo "KEYID:6:" | gpg --import-ownertrust`
1. `git clone git@git.vimium.com:jordan/nix-config.git projects/jordan/nix-config`
Generate a new SSH host key in "$temp/etc/ssh" as per [this guide](https://nix-community.github.io/nixos-anywhere/howtos/secrets.html#example-decrypting-an-openssh-host-key-with-pass). 1. `sudo nixos-rebuild switch --flake .#`
```
ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key
```
Update [nix-secrets](/jordan/nix-secrets) with the new host key to enable the system to decrypt
any relevant secrets.
In order to use the borgmatic module for backups, go to [borgbase.com](https://borgbase.com).
Add the generated SSH host key and create a new repository for the system.
Create a new directory under `hosts/` with a system configuration and disk layout.
Boot the NixOS installer (or any Linux distribution) on the target.
Then run:
```
nix run github:nix-community/nixos-anywhere -- \
--disk-encryption-keys /tmp/secret.key /tmp/secret.key \
--extra-files "$temp" \
--flake .#<hostname> \
root@<target-ip>
```
### Post install
If backups are configured, you'll need to run:
```
borgmatic init --encryption repokey-blake2
```
then restart `borgmatic`.
To join the Tailscale network, run:
```
tailscale up --login-server https://headscale.vimium.net
```
then visit the URL, SSH onto `vps1` and run `headscale --user mesh nodes register --key <key>`.
The new node can optionally be given a friendly name with `headscale node rename -i <index> <hostname>`.

460
flake.lock generated
View File

@ -8,11 +8,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1716561646, "lastModified": 1703371241,
"narHash": "sha256-UIGtLO89RxKt7RF2iEgPikSdU53r6v/6WYB0RW3k89I=", "narHash": "sha256-f7ZcabJ5iAH2IRfVuI55xSPZ9TbegFzvFxoKtIPNEn8=",
"owner": "ryantm", "owner": "ryantm",
"repo": "agenix", "repo": "agenix",
"rev": "c2fc0762bbe8feb06a2e59a364fa81b3a57671c9", "rev": "457669db4259ff69d1ac1183aaa6000420940c1f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -21,22 +21,6 @@
"type": "github" "type": "github"
} }
}, },
"blobs": {
"flake": false,
"locked": {
"lastModified": 1604995301,
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "blobs",
"type": "gitlab"
}
},
"darwin": { "darwin": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -66,11 +50,11 @@
"utils": "utils" "utils": "utils"
}, },
"locked": { "locked": {
"lastModified": 1715699772, "lastModified": 1703087360,
"narHash": "sha256-sKhqIgucN5sI/7UQgBwsonzR4fONjfMr9OcHK/vPits=", "narHash": "sha256-0VUbWBW8VyiDRuimMuLsEO4elGuUw/nc2WDeuO1eN1M=",
"owner": "serokell", "owner": "serokell",
"repo": "deploy-rs", "repo": "deploy-rs",
"rev": "b3ea6f333f9057b77efd9091119ba67089399ced", "rev": "b709d63debafce9f5645a5ba550c9e0983b3d1f7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -79,56 +63,14 @@
"type": "github" "type": "github"
} }
}, },
"devshell": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1713532798,
"narHash": "sha256-wtBhsdMJA3Wa32Wtm1eeo84GejtI43pMrFrmwLXrsEc=",
"owner": "numtide",
"repo": "devshell",
"rev": "12e914740a25ea1891ec619bb53cf5e6ca922e40",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1717177033,
"narHash": "sha256-G3CZJafCO8WDy3dyA2EhpUJEmzd5gMJ2IdItAg0Hijw=",
"owner": "nix-community",
"repo": "disko",
"rev": "0274af4c92531ebfba4a5bd493251a143bc51f3c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"firefox-gnome-theme": { "firefox-gnome-theme": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1716813977, "lastModified": 1703023593,
"narHash": "sha256-8fabA8OY1n2OcJFbbE03+bMydVANSBrNGo8hkzhXxxU=", "narHash": "sha256-M+Cw6vh7xCDmIhyVuEPNmaNVUwpmdFQq8zlsXZTKees=",
"owner": "rafaelmardojai", "owner": "rafaelmardojai",
"repo": "firefox-gnome-theme", "repo": "firefox-gnome-theme",
"rev": "8171c0578feb835ce66d49edba7429f46b7ac3f6", "rev": "bad853333d9021e7012adb9b8fbfe7a7003f26bc",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -153,172 +95,6 @@
"type": "github" "type": "github"
} }
}, },
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_3": {
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"revCount": 57,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
}
},
"flake-compat_4": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1715865404,
"narHash": "sha256-/GJvTdTpuDjNn84j82cU6bXztE0MSkdnTWClUCRub78=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "8dc45382d5206bd292f9c2768b8058a8fd8311d9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-root": {
"locked": {
"lastModified": 1713493429,
"narHash": "sha256-ztz8JQkI08tjKnsTpfLqzWoKFQF4JGu2LRz8bkdnYUk=",
"owner": "srid",
"repo": "flake-root",
"rev": "bc748b93b86ee76e2032eecda33440ceb2532fcd",
"type": "github"
},
"original": {
"owner": "srid",
"repo": "flake-root",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_4"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"git-hooks": {
"inputs": {
"flake-compat": "flake-compat_4",
"gitignore": "gitignore",
"nixpkgs": [
"nixvim",
"nixpkgs"
],
"nixpkgs-stable": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1716213921,
"narHash": "sha256-xrsYFST8ij4QWaV6HEokCUNIZLjjLP1bYC60K8XiBVA=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "0e8fcc54b842ad8428c9e705cb5994eaf05c26a0",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "git-hooks.nix",
"type": "github"
}
},
"gitea-github-theme": {
"flake": false,
"locked": {
"lastModified": 1715978309,
"narHash": "sha256-L9FYLtrK8Lm/wBeafb6eTRL5l2BYov6X6nJOL6rYZvY=",
"ref": "main",
"rev": "1b61f3f5cb38a1198d0a525d059a5a1905f2cfca",
"revCount": 96,
"type": "git",
"url": "ssh://git@git.vimium.com/jordan/gitea-github-theme.git"
},
"original": {
"ref": "main",
"type": "git",
"url": "ssh://git@git.vimium.com/jordan/gitea-github-theme.git"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"nixvim",
"git-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"home-manager": { "home-manager": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -347,69 +123,27 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1716736833, "lastModified": 1703367386,
"narHash": "sha256-rNObca6dm7Qs524O4st8VJH6pZ/Xe1gxl+Rx6mcWYo0=", "narHash": "sha256-FMbm48UGrBfOWGt8+opuS+uLBLQlRfhiYXhHNcYMS5k=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "a631666f5ec18271e86a5cde998cba68c33d9ac6", "rev": "d5824a76bc6bb93d1dce9ebbbcb09a9b6abcc224",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "nix-community",
"ref": "release-24.05", "ref": "release-23.11",
"repo": "home-manager", "repo": "home-manager",
"type": "github" "type": "github"
} }
}, },
"home-manager_3": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1717052710,
"narHash": "sha256-LRhOxzXmOza5SymhOgnEzA8EAQp+94kkeUYWKKpLJ/U=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "29c69d9a466e41d46fd3a7a9d0591ef9c113c2ae",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1716993688,
"narHash": "sha256-vo5k2wQekfeoq/2aleQkBN41dQiQHNTniZeVONWiWLs=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "c0d5b8c54d6828516c97f6be9f2d00c63a363df4",
"type": "github"
},
"original": {
"owner": "lnl7",
"repo": "nix-darwin",
"type": "github"
}
},
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1716987116, "lastModified": 1702453208,
"narHash": "sha256-uuEkErFVsFdg2K0cKbNQ9JlFSAm/xYqPr4rbPLI91Y8=", "narHash": "sha256-0wRi9SposfE2wHqjuKt8WO2izKB/ASDOV91URunIqgo=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "8251761f93d6f5b91cee45ac09edb6e382641009", "rev": "7763c6fd1f299cb9361ff2abf755ed9619ef01d6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -418,29 +152,6 @@
"type": "github" "type": "github"
} }
}, },
"nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"flake-compat": "flake-compat_2",
"nixpkgs": [
"nixpkgs"
],
"utils": "utils_2"
},
"locked": {
"lastModified": 1714720456,
"narHash": "sha256-e0WFe1BHqX23ADpGBc4ZRu38Mg+GICCZCqyS6EWCbHc=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "41059fc548088e49e3ddb3a2b4faeb5de018e60f",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1703013332, "lastModified": 1703013332,
@ -457,21 +168,6 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-unstable": {
"locked": {
"lastModified": 1716948383,
"narHash": "sha256-SzDKxseEcHR5KzPXLwsemyTR/kaM9whxeiJohbL04rs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "ad57eef4ef0659193044870c731987a6df5cf56b",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1702272962, "lastModified": 1702272962,
@ -490,60 +186,27 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1717144377, "lastModified": 1703068421,
"narHash": "sha256-F/TKWETwB5RaR8owkPPi+SPJh83AQsm6KrQAlJ8v/uA=", "narHash": "sha256-WSw5Faqlw75McIflnl5v7qVD/B3S2sLh+968bpOGrWA=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "805a384895c696f802a9bf5bf4720f37385df547", "rev": "d65bceaee0fb1e64363f7871bc43dc1c6ecad99f",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "nixos-24.05", "ref": "nixos-23.11",
"type": "indirect" "type": "indirect"
} }
}, },
"nixvim": {
"inputs": {
"devshell": "devshell",
"flake-compat": "flake-compat_3",
"flake-parts": "flake-parts",
"flake-root": "flake-root",
"git-hooks": "git-hooks",
"home-manager": "home-manager_3",
"nix-darwin": "nix-darwin",
"nixpkgs": [
"nixpkgs"
],
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1717188043,
"narHash": "sha256-qg8Tq7OcKtc0BS4RVUYrMZ+KofgMv6DiXOnqz7TN8CA=",
"owner": "nix-community",
"repo": "nixvim",
"rev": "1bbd58b6b293840716355e63fb3d5aa5af00d389",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixvim",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
"deploy-rs": "deploy-rs", "deploy-rs": "deploy-rs",
"disko": "disko",
"firefox-gnome-theme": "firefox-gnome-theme", "firefox-gnome-theme": "firefox-gnome-theme",
"gitea-github-theme": "gitea-github-theme",
"home-manager": "home-manager_2", "home-manager": "home-manager_2",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixos-mailserver": "nixos-mailserver",
"nixpkgs": "nixpkgs_3", "nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable",
"nixvim": "nixvim",
"secrets": "secrets", "secrets": "secrets",
"thunderbird-gnome-theme": "thunderbird-gnome-theme" "thunderbird-gnome-theme": "thunderbird-gnome-theme"
} }
@ -551,11 +214,11 @@
"secrets": { "secrets": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1716018239, "lastModified": 1702936962,
"narHash": "sha256-Ai13Sbj4DzuQSIrX2rjO0PG6PPpmvfwbCpTxX0kB7FI=", "narHash": "sha256-uIZ2uPE26JKJ58463ejHMiAOpqBwflyN6tCmZ89vaSQ=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "c2adb575ca3a816287c7d8f3c23cde6dfd316e6f", "rev": "c6db5c3ba8bff0e618fc3e31c9680863c5e53800",
"revCount": 19, "revCount": 5,
"type": "git", "type": "git",
"url": "ssh://git@git.vimium.com/jordan/nix-secrets.git" "url": "ssh://git@git.vimium.com/jordan/nix-secrets.git"
}, },
@ -594,44 +257,14 @@
"type": "github" "type": "github"
} }
}, },
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"thunderbird-gnome-theme": { "thunderbird-gnome-theme": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1710774977, "lastModified": 1701889124,
"narHash": "sha256-nQBz2PW3YF3+RTflPzDoAcs6vH1PTozESIYUGAwvSdA=", "narHash": "sha256-K+6oh7+J6RDBFkxphY/pzf0B+q5+IY54ZMKZrFSKXlc=",
"owner": "rafaelmardojai", "owner": "rafaelmardojai",
"repo": "thunderbird-gnome-theme", "repo": "thunderbird-gnome-theme",
"rev": "65d5c03fc9172d549a3ea72fd366d544981a002b", "rev": "966e9dd54bd2ce9d36d51cd6af8c3bac7a764a68",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -640,27 +273,6 @@
"type": "github" "type": "github"
} }
}, },
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixvim",
"nixpkgs"
]
},
"locked": {
"lastModified": 1715940852,
"narHash": "sha256-wJqHMg/K6X3JGAE9YLM0LsuKrKb4XiBeVaoeMNlReZg=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "2fba33a182602b9d49f0b2440513e5ee091d838b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"utils": { "utils": {
"inputs": { "inputs": {
"systems": "systems_2" "systems": "systems_2"
@ -678,24 +290,6 @@
"repo": "flake-utils", "repo": "flake-utils",
"type": "github" "type": "github"
} }
},
"utils_2": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1709126324,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

106
flake.nix
View File

@ -2,36 +2,18 @@
description = "NixOS system configuration"; description = "NixOS system configuration";
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-24.05"; nixpkgs.url = "nixpkgs/nixos-23.11";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
# nixpkgs-master.url = "nixpkgs";
agenix.url = "github:ryantm/agenix"; agenix.url = "github:ryantm/agenix";
deploy-rs.url = "github:serokell/deploy-rs"; deploy-rs.url = "github:serokell/deploy-rs";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = { home-manager = {
url = "github:nix-community/home-manager/release-24.05"; url = "github:nix-community/home-manager/release-23.11";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
firefox-gnome-theme = { firefox-gnome-theme = {
url = "github:rafaelmardojai/firefox-gnome-theme"; url = "github:rafaelmardojai/firefox-gnome-theme";
flake = false; flake = false;
}; };
gitea-github-theme = {
url = "git+ssh://git@git.vimium.com/jordan/gitea-github-theme.git?ref=main";
flake = false;
};
nixos-hardware.url = "github:NixOS/nixos-hardware"; nixos-hardware.url = "github:NixOS/nixos-hardware";
nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim = {
url = "github:nix-community/nixvim";
inputs.nixpkgs.follows = "nixpkgs";
};
secrets = { secrets = {
url = "git+ssh://git@git.vimium.com/jordan/nix-secrets.git"; url = "git+ssh://git@git.vimium.com/jordan/nix-secrets.git";
flake = false; flake = false;
@ -42,29 +24,21 @@
}; };
}; };
outputs = inputs @ { self, nixpkgs, nixpkgs-unstable, agenix, deploy-rs, disko, home-manager, nixos-hardware, nixos-mailserver, secrets, ... }: outputs = inputs @ { self, nixpkgs, agenix, deploy-rs, home-manager, nixos-hardware, secrets, ... }:
let let
mkPkgsForSystem = system: inputs.nixpkgs; nixpkgsForSystem = system: inputs.nixpkgs;
overlays = [ overlays = [
agenix.overlays.default agenix.overlays.default
(import ./overlays/gnome.nix) (import ./overlays/gnome.nix)
(
final: prev: {
unstable = import inputs.nixpkgs-unstable { system = final.system; };
custom = self.packages { system = final.system; };
}
)
]; ];
commonModules = [ commonModules = [
agenix.nixosModules.age agenix.nixosModules.age
disko.nixosModules.disko
nixos-mailserver.nixosModule
home-manager.nixosModule home-manager.nixosModule
./modules ./modules
]; ];
mkNixosSystem = { system, name, extraModules ? [] }: nixosSystem = { system, name, extraModules ? [] }:
let let
nixpkgs = mkPkgsForSystem system; nixpkgs = nixpkgsForSystem system;
lib = (import nixpkgs { inherit overlays system; }).lib; lib = (import nixpkgs { inherit overlays system; }).lib;
in in
inputs.nixpkgs.lib.nixosSystem { inputs.nixpkgs.lib.nixosSystem {
@ -79,6 +53,9 @@
config.allowUnfree = true; config.allowUnfree = true;
}; };
networking.hostName = name; networking.hostName = name;
nix = {
extraOptions = "experimental-features = nix-command flakes";
};
}) })
./hosts/${name} ./hosts/${name}
] ++ extraModules; ] ++ extraModules;
@ -86,56 +63,35 @@
in in
{ {
nixosConfigurations = { nixosConfigurations = {
atlas = mkNixosSystem { system = "x86_64-linux"; name = "atlas"; }; atlas = nixosSystem { system = "x86_64-linux"; name = "atlas"; };
eos = mkNixosSystem { system = "x86_64-linux"; name = "eos"; }; eos = nixosSystem { system = "x86_64-linux"; name = "eos"; };
helios = mkNixosSystem { system = "x86_64-linux"; name = "helios"; }; helios = nixosSystem { system = "x86_64-linux"; name = "helios"; };
hypnos = mkNixosSystem { system = "x86_64-linux"; name = "hypnos"; }; odyssey = nixosSystem { system = "x86_64-linux"; name = "odyssey"; };
library = mkNixosSystem { system = "x86_64-linux"; name = "library"; }; pi = nixosSystem { system = "aarch64-linux"; name = "pi"; extraModules = [ nixos-hardware.nixosModules.raspberry-pi-4 ]; };
mail = mkNixosSystem { system = "x86_64-linux"; name = "mail"; }; vps1 = nixosSystem { system = "x86_64-linux"; name = "vps1"; };
odyssey = mkNixosSystem { system = "x86_64-linux"; name = "odyssey"; };
pi = mkNixosSystem { system = "aarch64-linux"; name = "pi"; extraModules = [ nixos-hardware.nixosModules.raspberry-pi-4 ]; };
vps1 = mkNixosSystem { system = "x86_64-linux"; name = "vps1"; };
}; };
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell { deploy.nodes = {
buildInputs = [ pi = {
deploy-rs.packages.x86_64-linux.deploy-rs hostname = "10.0.1.191";
]; sshUser = "jordan";
}; user = "root";
deploy = { profiles.system = {
magicRollback = true; user = "root";
autoRollback = true; path = deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.pi;
sshUser = "root";
nodes = {
mail = {
hostname = "mail.mesh.vimium.net";
profiles.system = {
user = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.mail;
};
}; };
vps1 = {
hostname = "vps1.mesh.vimium.net";
profiles.system = {
user = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.vps1;
};
};
# pi = {
# hostname = "10.0.1.191";
#
# profiles.system = {
# user = "root";
# path = deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.pi;
# };
# };
}; };
vps1 = {
magicRollback = true;
autoRollback = true;
hostname = "vps1.mesh.vimium.net";
profiles.system = {
user = "root";
path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.vps1;
}; };
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib; # checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
}; };
} }

View File

@ -6,15 +6,21 @@
../desktop.nix ../desktop.nix
]; ];
boot.loader = { boot.loader.systemd-boot.enable = true;
systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true;
efi.canTouchEfiVariables = true;
};
networking = { networking.hostName = "atlas";
hostId = "8425e349"; networking.hostId = "8425e349";
networkmanager.enable = true; networking.networkmanager.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
modules = { modules = {
desktop = { desktop = {
@ -36,25 +42,15 @@
}; };
editors = { editors = {
neovim.enable = true; neovim.enable = true;
vscode.enable = true;
}; };
security = { security = {
gpg.enable = true; gpg.enable = true;
pass.enable = true; pass.enable = true;
}; };
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
];
repoPath = "ssh://uzu2y5b1@uzu2y5b1.repo.borgbase.com/./repo";
};
};
shell = { shell = {
git.enable = true; git.enable = true;
zsh.enable = true; zsh.enable = true;
}; };
}; };
system.stateVersion = "22.11";
} }

View File

@ -1,72 +0,0 @@
{ config, lib, pkgs, ... }:
{
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
console.keyMap = "uk";
security.sudo.execWheelOnly = true;
services.openssh = {
enable = true;
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
services.journald.extraConfig = ''
SystemMaxUse=4G
MaxRetentionSec=90day
'';
users.defaultUserShell = pkgs.zsh;
programs.zsh.enable = true;
nix = {
package = pkgs.nixFlakes;
extraOptions = ''
experimental-features = nix-command flakes
'';
settings = {
connect-timeout = 5;
log-lines = 25;
min-free = 128000000;
max-free = 1000000000;
fallback = true;
trusted-users = [ "@wheel" ];
auto-optimise-store = true;
substituters = [
"http://odyssey.mesh.vimium.net"
"https://cache.nixos.org"
];
trusted-public-keys = [
"odyssey.mesh.vimium.net:ZhQhjscPWjoN4rlZwoMELznEiBnZ9O26iyGA27ibilQ="
];
};
gc = {
automatic = true;
dates = "weekly";
options = "-d --delete-older-than 7d";
};
};
environment.systemPackages = with pkgs; [
git
neovim
];
}

View File

@ -1,12 +1,33 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ time.timeZone = "Europe/London";
./common.nix
]; i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
console.keyMap = "uk";
services.printing.enable = true; services.printing.enable = true;
services.openssh.startWhenNeeded = true; services.openssh = {
enable = true;
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
PermitRootLogin = "no";
};
startWhenNeeded = true;
};
sound.enable = true; sound.enable = true;
hardware.pulseaudio.enable = false; hardware.pulseaudio.enable = false;
@ -18,21 +39,10 @@
pulse.enable = true; pulse.enable = true;
}; };
fileSystems."/mnt/library" = { environment.systemPackages = with pkgs; [
device = "library.mesh.vimium.net:/mnt/library"; git
fsType = "nfs"; neovim
options = [ ];
"nfsvers=4.2"
"bg"
"soft"
"timeo=20"
"retry=5"
"nocto"
"ro"
"x-systemd.automount"
"noauto"
];
};
system.autoUpgrade = { system.autoUpgrade = {
enable = true; enable = true;
@ -40,35 +50,29 @@
randomizedDelaySec = "10min"; randomizedDelaySec = "10min";
}; };
systemd.services.NetworkManager-wait-online.enable = false; nix = {
settings = {
fonts.packages = with pkgs; [ connect-timeout = 5;
noto-fonts log-lines = 25;
(nerdfonts.override { fonts = [ "BigBlueTerminal" "ComicShannsMono" "Terminus" "UbuntuMono" ]; }) min-free = 128000000;
]; max-free = 1000000000;
fallback = true;
modules = { auto-optimise-store = true;
desktop.gnome.enable = true; substituters = [
networking.tailscale.enable = true; "http://odyssey.mesh.vimium.net"
"https://cache.nixos.org"
];
trusted-public-keys = [
"odyssey.mesh.vimium.net:ZhQhjscPWjoN4rlZwoMELznEiBnZ9O26iyGA27ibilQ="
];
};
gc = {
automatic = true;
dates = "weekly";
options = "-d --delete-older-than 7d";
};
}; };
environment.systemPackages = with pkgs; [ modules.desktop.gnome.enable = true;
bind modules.networking.tailscale.enable = true;
bmon
fd
ffmpeg
iotop
unstable.nix-du
# unstable.nix-melt
unstable.nix-tree
unstable.nix-visualize
ripgrep
rsync
tcpdump
tokei
tree
wl-clipboard
];
environment.sessionVariables.NIXOS_OZONE_WL = "1";
} }

View File

@ -6,15 +6,22 @@
../desktop.nix ../desktop.nix
]; ];
boot.loader = { boot.loader.systemd-boot.enable = true;
systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true;
efi.canTouchEfiVariables = true;
};
networking = { networking.hostName = "eos";
hostId = "cc858347"; networking.hostId = "cc858347";
networkmanager.enable = true; networking.networkmanager.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
nix.settings.auto-optimise-store = true;
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
dconf.settings = { dconf.settings = {
"org/gnome/desktop/interface" = { "org/gnome/desktop/interface" = {
@ -44,6 +51,4 @@
zsh.enable = true; zsh.enable = true;
}; };
}; };
system.stateVersion = "22.11";
} }

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, inputs, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ imports = [
@ -6,18 +6,22 @@
../desktop.nix ../desktop.nix
]; ];
boot = { boot.loader.grub.enable = true;
loader.grub = { boot.loader.grub.device = "/dev/sda";
enable = true; boot.loader.grub.zfsSupport = true;
device = "/dev/sda";
zfsSupport = true;
};
};
networking = { networking.hostName = "helios";
hostId = "47d23505"; networking.hostId = "47d23505";
networkmanager.enable = true; networking.networkmanager.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
modules = { modules = {
desktop = { desktop = {
@ -36,20 +40,9 @@
gpg.enable = true; gpg.enable = true;
pass.enable = true; pass.enable = true;
}; };
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
];
repoPath = "ssh://b9cjl9hq@b9cjl9hq.repo.borgbase.com/./repo";
};
};
shell = { shell = {
git.enable = true; git.enable = true;
zsh.enable = true; zsh.enable = true;
}; };
}; };
system.stateVersion = "22.11";
} }

View File

@ -1,102 +0,0 @@
From d310ddee0fb8e7a5a8b89668c6cb8f9dc863ce94 Mon Sep 17 00:00:00 2001
From: Jordan Holt <jordan@vimium.com>
Date: Sun, 28 Apr 2024 15:59:52 +0100
Subject: [PATCH] Add apple_set_os EFI boot service
---
drivers/firmware/efi/libstub/x86-stub.c | 59 +++++++++++++++++++++++++
include/linux/efi.h | 1 +
2 files changed, 60 insertions(+)
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index d5a8182cf..be722c43a 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -449,6 +449,63 @@ static void setup_graphics(struct boot_params *boot_params)
}
}
+typedef struct {
+ u64 version;
+ void (*set_os_version) (const char *os_version);
+ void (*set_os_vendor) (const char *os_vendor);
+} apple_set_os_interface_t;
+
+static efi_status_t apple_set_os()
+{
+ apple_set_os_interface_t *set_os;
+ efi_guid_t set_os_guid = APPLE_SET_OS_PROTOCOL_GUID;
+ efi_status_t status;
+ void **handles;
+ unsigned long i, nr_handles, size = 0;
+
+ status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL,
+ &set_os_guid, NULL, &size, handles);
+
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
+ size, &handles);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL,
+ &set_os_guid, NULL, &size, handles);
+ }
+
+ if (status != EFI_SUCCESS)
+ goto free_handle;
+
+ nr_handles = size / sizeof(void *);
+ for (i = 0; i < nr_handles; i++) {
+ void *h = handles[i];
+
+ status = efi_bs_call(handle_protocol, h,
+ &set_os_guid, &set_os);
+
+ if (status != EFI_SUCCESS || !set_os)
+ continue;
+
+ if (set_os->version > 0) {
+ efi_bs_call((unsigned long)set_os->set_os_version,
+ "Mac OS X 10.9");
+ }
+
+ if (set_os->version >= 2) {
+ efi_bs_call((unsigned long)set_os->set_os_vendor,
+ "Apple Inc.");
+ }
+ }
+
+free_handle:
+ efi_bs_call(free_pool, uga_handle);
+
+ return status;
+}
static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status)
{
@@ -951,6 +1008,8 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
setup_unaccepted_memory();
+ apple_set_os();
+
status = exit_boot(boot_params, handle);
if (status != EFI_SUCCESS) {
efi_err("exit_boot() failed!\n");
diff --git a/include/linux/efi.h b/include/linux/efi.h
index d59b0947f..81158014f 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -385,6 +385,7 @@ void efi_native_runtime_setup(void);
#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
#define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
#define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0)
+#define APPLE_SET_OS_PROTOCOL_GUID EFI_GUID(0xc5c5da95, 0x7d5c, 0x45e6, 0xb2, 0xf1, 0x3f, 0xd5, 0x2b, 0xb1, 0x00, 0x77)
#define EFI_TCG2_PROTOCOL_GUID EFI_GUID(0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f)
#define EFI_TCG2_FINAL_EVENTS_TABLE_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
#define EFI_LOAD_FILE_PROTOCOL_GUID EFI_GUID(0x56ec3091, 0x954c, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
--
2.42.0

View File

@ -1,35 +0,0 @@
# Hypnos
## Overview
15-inch MacBook Pro 11,3 (Mid 2014).
## Specs
* CPU - Intel Core i7-4870HQ @ 2.50GHz
* Memory - 16 GB DDR3
* GPU - Intel Iris Pro 5200
* GPU - NVIDIA GeForce GT 750M
* NIC - Broadcom BCM43xx 802.11ac
### Disks
Device | Partitions _(filesystem, size, usage)_
--- | ---
Apple SSD SM0512F | `/dev/sda1` (EFI, 256 MiB, NixOS Boot) <br> `/dev/sda2` (ZFS, 500 GiB, NixOS Root)
#### ZFS pool layout
```
rpool/
├── local
│ ├── nix
│ └── tmp
├── system
│ ├── root
│ └── var
└── user
└── home
```
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind these datasets.
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `hypnos.mesh.vimium.net`.

View File

@ -1,45 +0,0 @@
{ config, lib, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./disko-config.nix
../desktop.nix
];
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
networking.hostId = "cf791898";
modules = {
desktop = {
browsers = {
firefox.enable = true;
};
gnome.enable = lib.mkForce false;
kde.enable = true;
media.recording = {
audio.enable = true;
};
};
dev = {
node.enable = true;
};
editors = {
neovim.enable = true;
};
security = {
gpg.enable = true;
pass.enable = true;
};
shell = {
git.enable = true;
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,126 +0,0 @@
{ lib, ... }:
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/ata-APPLE_SSD_SM0512F_S1K5NYBF736152";
content = {
type = "gpt";
partitions = {
ESP = {
size = "256M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
zfs = {
size = "100%";
content = {
type = "zfs";
pool = "rpool";
};
};
};
};
};
};
zpool = {
rpool = {
type = "zpool";
options = {
ashift = "12";
};
rootFsOptions = {
canmount = "off";
mountpoint = "none";
dnodesize = "auto";
xattr = "sa";
};
postCreateHook = "zfs snapshot rpool@blank";
datasets = {
local = {
type = "zfs_fs";
options = {
mountpoint = "none";
};
};
"local/nix" = {
type = "zfs_fs";
mountpoint = "/nix";
options = {
atime = "off";
mountpoint = "legacy";
};
};
"local/tmp" = {
type = "zfs_fs";
mountpoint = "/tmp";
options = {
setuid = "off";
devices = "off";
mountpoint = "legacy";
};
};
system = {
type = "zfs_fs";
mountpoint = "/";
options = {
mountpoint = "legacy";
};
};
"system/var" = {
type = "zfs_fs";
mountpoint = "/var";
options = {
mountpoint = "legacy";
};
};
"system/var/tmp" = {
type = "zfs_fs";
mountpoint = "/var/tmp";
options = {
devices = "off";
mountpoint = "legacy";
};
};
"system/var/log" = {
type = "zfs_fs";
mountpoint = "/var/log";
options = {
compression = "on";
acltype = "posix";
mountpoint = "legacy";
};
};
user = {
type = "zfs_fs";
options = {
mountpoint = "none";
encryption = "aes-256-gcm";
keyformat = "passphrase";
keylocation = "file:///tmp/secret.key";
};
# use this to read the key during boot
postCreateHook = ''
zfs set keylocation="prompt" "rpool/$name";
'';
};
"user/home" = {
type = "zfs_fs";
mountpoint = "/home";
options = {
setuid = "off";
devices = "off";
mountpoint = "legacy";
};
};
};
};
};
};
}

View File

@ -1,41 +0,0 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
kernelModules = [ "applesmc" "kvm-intel" "wl" ];
kernelPatches = [
{
name = "spoof-mac-os-x";
patch = ./0001-Add-apple_set_os-EFI-boot-service.patch;
}
];
extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
};
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware = {
cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
opengl = {
enable = true;
extraPackages = with pkgs; [
intel-vaapi-driver
intel-media-driver
libvdpau-va-gl
];
driSupport = true;
};
};
environment.variables = {
VDPAU_DRIVER = "va_gl";
};
}

View File

@ -1,46 +0,0 @@
# Library
## Overview
Media and public file server.
## Specs
* CPU - AMD Ryzen 5 5600G @ 3.90GHz
* Chipset - AMD B550
* Memory - 64 GB DDR4
* Motherboard - ASRock B550M Pro4
* Case - Fractal Design Node 804
### Disks
Device | Partitions _(filesystem, size, usage)_
--- | ---
Samsung 980 Evo | `/dev/nvme0n1p1` (EFI, 512 MiB, NixOS Boot) <br> `/dev/nvme0n1p2` (ZFS `rpool`, 200 GiB, NixOS Root)
#### ZFS datasets
```
rpool/
├── local
│ ├── nix
│ └── tmp
├── system
│ ├── root
│ └── var
└── user
└── home
library/
├── books
├── fonts
├── movies
├── music
├── software
├── tv
├── videos
└── web
```
See [Graham Christensen's article](https://grahamc.com/blog/nixos-on-zfs/#datasets) for the motivation behind the `rpool` datasets.
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `library.mesh.vimium.net`.

View File

@ -1,172 +0,0 @@
{ config, lib, pkgs, ... }:
with lib.my;
{
imports = [
./hardware-configuration.nix
../server.nix
];
boot = {
loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = true;
zfs.extraPools = [ "library" ];
};
networking = {
domain = "mesh.vimium.net";
hostId = "d24ae953";
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
];
};
networkmanager.enable = true;
};
services.zfs = {
autoScrub = {
enable = true;
pools = [ "library" ];
};
autoSnapshot = {
enable = true;
flags = "-k -p --utc";
frequent = 0;
hourly = 0;
daily = 7;
monthly = 1;
};
};
services.nfs.server = {
enable = true;
};
services.prometheus = {
enable = true;
port = 9001;
exporters = {
node = {
enable = true;
enabledCollectors = [ "systemd" ];
port = 9002;
};
zfs = {
enable = true;
port = 9003;
};
};
scrapeConfigs = [
{
job_name = "library";
static_configs = [{
targets = [
"127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
"127.0.0.1:${toString config.services.prometheus.exporters.zfs.port}"
];
}];
}
];
};
systemd.services.vps1-tunnel = {
enable = true;
description = "vps1.mesh.vimium.net SSH tunnel";
after = [
"network-online.target"
"jellyfin.service"
];
wants = [ "network-online.target" ];
serviceConfig = {
Type="simple";
ExecStart=pkgs.lib.mkForce ''
${pkgs.openssh}/bin/ssh \
-NT \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=60 \
-o TCPKeepAlive=no \
-i %h/.ssh/id_jellyfin \
-R localhost:8000:localhost:8000 \
jellyfin@vps1.mesh.vimium.net
'';
Restart="always";
RestartSec=20;
};
wantedBy = [ "default.target" ];
};
services.nginx = let
proxyConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
in {
enable = true;
package = pkgs.openresty;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
clientMaxBodySize = "2G";
virtualHosts = {
"library.mesh.vimium.net" = {
locations."/" = {
root = "/mnt/library";
extraConfig = ''
autoindex on;
'';
};
};
"jellyfin.vimium.com" = {
default = true;
listen = [
{
addr = "127.0.0.1";
port = 8000;
}
];
locations."/" = {
proxyPass = "http://localhost:8096";
extraConfig = proxyConfig;
};
locations."/metrics" = {
return = "404";
};
};
};
};
services.jellyfin.enable = true;
modules = {
podman.enable = true;
security = {
gpg.enable = true;
};
shell = {
zsh.enable = true;
};
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan"
];
repoPath = "ssh://b61758r4@b61758r4.repo.borgbase.com/./repo";
};
};
};
system.stateVersion = "22.11";
}

View File

@ -1,68 +0,0 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" ];
initrd.kernelModules = [ ];
kernelModules = [ "kvm-amd" ];
extraModulePackages = [ ];
};
fileSystems."/" = {
device = "rpool/system/root";
fsType = "zfs";
};
fileSystems."/var" = {
device = "rpool/system/var";
fsType = "zfs";
};
fileSystems."/var/log" = {
device = "rpool/system/var/log";
fsType = "zfs";
};
fileSystems."/var/tmp" = {
device = "rpool/system/var/tmp";
fsType = "zfs";
};
fileSystems."/var/lib/containers/storage" = {
device = "rpool/system/var/lib-containers-storage";
fsType = "zfs";
};
fileSystems."/nix" = {
device = "rpool/local/nix";
fsType = "zfs";
};
fileSystems."/tmp" = {
device = "rpool/local/tmp";
fsType = "zfs";
};
fileSystems."/home" = {
device = "rpool/user/home";
fsType = "zfs";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/F697-F1C0";
fsType = "vfat";
};
swapDevices = [ ];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -1,18 +0,0 @@
# Mail server
## Overview
Mail server hosted in OVH.
## Specs
* CPU - ??
* Memory - ??
### Disks
Device | Partitions _(filesystem, usage)_
--- | ---
NVMe | `/dev/sda1` (ext4, NixOS Root)
### Networks
- DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `mail.mesh.vimium.net`.

View File

@ -1,49 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
{
imports = [
./hardware-configuration.nix
./disko-config.nix
../server.nix
];
networking = {
hostId = "08ac2f14";
domain = "mesh.vimium.net";
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
];
};
};
users = {
users = {
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
};
};
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
modules = {
services = {
borgmatic = {
enable = true;
directories = [
"/var/dkim"
"/var/lib"
"/var/vmail"
];
repoPath = "ssh://kg2mpt28@kg2mpt28.repo.borgbase.com/./repo";
};
mail.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,55 +0,0 @@
{ lib, ... }:
{
disko.devices = {
disk.disk1 = {
device = lib.mkDefault "/dev/sda";
type = "disk";
content = {
type = "gpt";
partitions = {
boot = {
name = "boot";
size = "2M";
type = "EF02";
};
esp = {
name = "ESP";
size = "300M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
name = "root";
size = "100%";
content = {
type = "lvm_pv";
vg = "pool";
};
};
};
};
};
lvm_vg = {
pool = {
type = "lvm_vg";
lvs = {
root = {
size = "100%FREE";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [
"defaults"
];
};
};
};
};
};
};
}

View File

@ -1,22 +0,0 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot = {
initrd = {
availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
kernelModules = [ "nvme" ];
};
loader.grub = {
efiSupport = true;
efiInstallAsRemovable = true;
};
tmp.cleanOnBoot = true;
};
zramSwap.enable = true;
}

45
hosts/odyssey/audio.nix Normal file
View File

@ -0,0 +1,45 @@
{ config, pkgs, ... }:
let
snd-usb-audio-module = pkgs.callPackage ./snd-usb-audio.nix {
kernel = config.boot.kernelPackages.kernel;
};
upmixConfig = ''
stream.properties = {
channelmix.upmix = true
channelmix.upmix-method = psd
}
'';
in {
boot.extraModulePackages = [
(snd-usb-audio-module.overrideAttrs (_: {
patches = [ ./0001-Update-device-ID-for-PreSonus-1824c.patch ];
}))
];
environment.etc = {
"pipewire/pipewire.conf.d/surround.conf".text = ''
context.modules = [
{
name = libpipewire-module-loopback
args = {
node.description = "Genelec 4.1 Surround"
capture.props = {
node.name = "Genelec_Speakers"
media.class = "Audio/Sink"
audio.position = [ FL FR SL SR LFE ]
}
playback.props = {
node.name = "playback.Genelec_Speakers"
audio.position = [ AUX0 AUX1 AUX3 AUX4 AUX5 ]
target.object = "alsa_output.usb-PreSonus_Studio_1824c_SC4E21110775-00.multichannel-output"
stream.dont-remix = true
node.passive = true
}
}
}
]
'';
"pipewire/pipewire-pulse.conf.d/40-upmix.conf".text = upmixConfig;
"pipewire/client-rt.conf.d/40-upmix.conf".text = upmixConfig;
};
}

View File

@ -3,28 +3,39 @@
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
./audio.nix
../desktop.nix ../desktop.nix
]; ];
boot.loader = { boot.loader.systemd-boot = {
systemd-boot = { enable = true;
enable = true; graceful = true;
graceful = true; netbootxyz.enable = true;
netbootxyz.enable = true;
};
efi.canTouchEfiVariables = true;
}; };
boot.loader.efi.canTouchEfiVariables = true;
networking = { networking.hostName = "odyssey";
hostId = "c5e68d78"; networking.hostId = "c5e68d78";
networkmanager.enable = true; networking.networkmanager.enable = true;
firewall.trustedInterfaces = [ "lxdbr0" "virbr0" ]; # Work around https://github.com/NixOS/nixpkgs/issues/263359
};
virtualisation = { nix.package = pkgs.nixFlakes;
libvirtd.enable = true; nix.extraOptions = ''
lxd.enable = true; experimental-features = nix-command flakes
}; '';
virtualisation.libvirtd.enable = true;
virtualisation.lxd.enable = true;
# Work around https://github.com/NixOS/nixpkgs/issues/263359
networking.firewall.trustedInterfaces = [ "lxdbr0" "virbr0" ];
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
services.journald.extraConfig = ''
SystemMaxUse=4G
MaxRetentionSec=90day
'';
services.nix-serve = { services.nix-serve = {
enable = true; enable = true;
@ -41,22 +52,43 @@
}; };
}; };
age.secrets."passwords/services/borg/odyssey-passphrase" = {
file = "${inputs.secrets}/passwords/services/borg/odyssey-passphrase.age";
};
services.borgmatic = {
enable = true;
settings = {
source_directories = [
"/home/jordan/Documents"
];
repositories = [
{ label = "borgbase"; path = "ssh://iqwu22oq@iqwu22oq.repo.borgbase.com/./repo"; }
];
storage = {
encryption_passcommand = "cat ${config.age.secrets."passwords/services/borg/odyssey-passphrase".path}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
};
retention = {
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
};
};
# Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true;
modules = { modules = {
desktop = { desktop = {
apps.qbittorrent.enable = true; apps.qbittorrent.enable = true;
browsers = { browsers = {
firefox.enable = true; firefox.enable = true;
}; };
gaming = { gaming.emulators = {
emulators = { ps2.enable = true;
gamecube.enable = true; psp.enable = true;
ps2.enable = true;
ps3.enable = true;
psp.enable = true;
wii.enable = true;
xbox.enable = true;
};
lutris.enable = true;
}; };
media.graphics = { media.graphics = {
modeling.enable = true; modeling.enable = true;
@ -73,33 +105,15 @@
}; };
editors = { editors = {
neovim.enable = true; neovim.enable = true;
vscode.enable = true;
}; };
hardware.presonus-studio.enable = true;
security = { security = {
gpg.enable = true; gpg.enable = true;
pass.enable = true; pass.enable = true;
}; };
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
"/home/jordan/Downloads"
"/home/jordan/Music"
"/home/jordan/Pictures"
"/home/jordan/projects"
"/home/jordan/Videos"
"/home/jordan/.mozilla"
];
repoPath = "ssh://iqwu22oq@iqwu22oq.repo.borgbase.com/./repo";
};
gitea-runner.enable = true;
};
shell = { shell = {
git.enable = true; git.enable = true;
zsh.enable = true; zsh.enable = true;
}; };
}; };
system.stateVersion = "22.11";
} }

View File

@ -64,9 +64,5 @@
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
environment.systemPackages = [
pkgs.apfs-fuse
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
} }

View File

@ -16,10 +16,3 @@ SD card | `/dev/mmcblk0` (ext4, NixOS Root)
### Networks ### Networks
- DHCP on `10.0.1.0/24` subnet. - DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `pi.mesh.vimium.net`. - Tailscale on `100.64.0.0/10` subnet. FQDN: `pi.mesh.vimium.net`.
## Devices and connections
- SONOFF Zigbee 3.0 USB Dongle Plus (connected to USB 2.0 port to avoid [interference](https://www.unit3compliance.co.uk/2-4ghz-intra-system-or-self-platform-interference-demonstration/))
- HDMI to ONKYO HT-R990
- S/PDIF to ONKYO HT-R990
- Ethernet to ONKYO HT-R990

View File

@ -17,78 +17,8 @@
}; };
deviceTree = { deviceTree = {
enable = true; enable = true;
filter = "*rpi-4-*.dtb";
overlays = [ overlays = [
{ { name = "hifiberry-digi-pro"; dtboFile = "${pkgs.device-tree_rpi.overlays}/hifiberry-digi-pro.dtbo"; }
name = "audio-off-overlay";
dtsText = ''
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2711";
fragment@0 {
target = <&vchiq>;
__overlay__ {
status = "disabled";
};
};
};
'';
}
{
# Adapted from: https://github.com/raspberrypi/linux/blob/rpi-6.1.y/arch/arm/boot/dts/overlays/hifiberry-digi-pro-overlay.dts
# changes:
# - modified top-level "compatible" field from bcm2835 to bcm2711
# - s/i2s_clk_consumer/i2s/ (name on bcm2711 platform)
name = "hifiberry-digi-pro";
dtsText = ''
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2711";
fragment@0 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
wm8804@3b {
#sound-dai-cells = <0>;
compatible = "wlf,wm8804";
reg = <0x3b>;
PVDD-supply = <&vdd_3v3_reg>;
DVDD-supply = <&vdd_3v3_reg>;
status = "okay";
};
};
};
fragment@2 {
target = <&sound>;
__overlay__ {
compatible = "hifiberry,hifiberry-digi";
i2s-controller = <&i2s>;
status = "okay";
clock44-gpio = <&gpio 5 0>;
clock48-gpio = <&gpio 6 0>;
};
};
};
'';
}
]; ];
}; };
firmware = with pkgs; [ firmware = with pkgs; [
@ -99,72 +29,46 @@
sound.enable = true; sound.enable = true;
age.secrets."passwords/networks.age" = {
file = "${inputs.secrets}/passwords/networks.age";
};
networking = {
wireless = {
enable = true;
interfaces = [ "wlan0" ];
environmentFile = config.age.secrets."passwords/networks.age".path;
networks = {
"Apollo 600 Mbps".psk = "@PSK_APOLLO@";
};
};
};
security.rtkit.enable = true; security.rtkit.enable = true;
services.pipewire = { services.pipewire = {
enable = true; enable = true;
alsa.enable = true; alsa.enable = true;
alsa.support32Bit = true; alsa.support32Bit = true;
pulse.enable = true; pulse.enable = true;
systemWide = true;
}; };
age.secrets."files/services/home-assistant/secrets.yaml" = { virtualisation.oci-containers = {
file = "${inputs.secrets}/files/services/home-assistant/secrets.yaml.age"; backend = "podman";
path = "${config.services.home-assistant.configDir}/secrets.yaml"; containers.homeassistant = {
owner = "hass"; volumes = [ "home-assistant:/config" ];
group = "hass"; environment.TZ = config.time.timeZone;
}; image = "ghcr.io/home-assistant/home-assistant:stable";
extraOptions = [
services.home-assistant = { "--network=host"
enable = true; "--device=/dev/ttyUSB0:/dev/ttyUSB0"
extraComponents = [ ];
"api"
"alert"
"auth"
"backup"
"command_line"
"default_config"
"homekit_controller"
"homekit"
"http"
"icloud"
"jellyfin"
"metoffice"
"mqtt"
"onkyo"
"ping"
"proximity"
"radio_browser"
"scrape"
"sensor"
"system_health"
];
config = {
default_config = {};
backup = {};
homeassistant = {
name = "Home";
latitude = "!secret latitude";
longitude = "!secret longitude";
country = "GB";
temperature_unit = "C";
time_zone = config.time.timeZone;
unit_system = "metric";
};
mqtt = { };
scene = "!include scenes.yaml";
automation = "!include automations.yaml";
system_health = { };
recorder = {
purge_keep_days = 365;
};
}; };
}; };
services.mosquitto = { services.mosquitto = {
enable = true; enable = true;
listeners = [{ listeners = [{
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
port = 1883; port = 1883;
settings = { settings = {
allow_anonymous = true; allow_anonymous = true;
@ -180,17 +84,10 @@
}; };
services.zigbee2mqtt = { services.zigbee2mqtt = {
package = pkgs.unstable.zigbee2mqtt;
enable = true; enable = true;
dataDir = "/var/lib/zigbee2mqtt"; dataDir = "/var/lib/zigbee2mqtt";
settings = { settings = {
homeassistant = lib.optionalAttrs config.services.home-assistant.enable { homeassistant = true;
discovery_topic = "homeassistant";
status_topic = "hass/status";
legacy_entity_attributes = true;
legacy_triggers = true;
};
availability = true;
frontend = true; frontend = true;
device_options = { device_options = {
retain = true; retain = true;
@ -203,7 +100,6 @@
network_key = "!secret.yaml network_key"; network_key = "!secret.yaml network_key";
pan_id = 13001; pan_id = 13001;
ext_pan_id = [ 79 1 73 47 250 136 124 222 ]; ext_pan_id = [ 79 1 73 47 250 136 124 222 ];
transmit_power = 20;
}; };
mqtt = { mqtt = {
version = 5; version = 5;
@ -212,35 +108,36 @@
}; };
}; };
modules = { age.secrets."passwords/services/borg/pi-passphrase" = {
networking = { file = "${inputs.secrets}/passwords/services/borg/pi-passphrase.age";
wireless = { };
enable = true;
interfaces = [ "wlan0" ]; services.borgmatic = {
enable = true;
settings = {
source_directories = [
"/var/lib/mosquitto"
"/var/lib/zigbee2mqtt"
];
repositories = [
{ label = "borgbase"; path = "ssh://qcw86s11@qcw86s11.repo.borgbase.com/./repo"; }
];
storage = {
encryption_passcommand = "cat ${config.age.secrets."passwords/services/borg/pi-passphrase".path}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
}; };
}; retention = {
services = { keep_daily = 7;
borgmatic = { keep_weekly = 4;
enable = true; keep_monthly = 6;
directories = [
"/var/lib/mosquitto"
"/var/lib/zigbee2mqtt"
];
repoPath = "ssh://qcw86s11@qcw86s11.repo.borgbase.com/./repo";
}; };
}; };
}; };
# Connection to ONKYO HT-R990 # Without this override, `cat` is unavailable for `encryption_passcommand`
networking.interfaces.end0 = { systemd.services.borgmatic.confinement.fullUnit = true;
ipv4.addresses = [{
address = "172.16.0.1";
prefixLength = 30;
}];
};
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
python311Packages.onkyo-eiscp
libraspberrypi libraspberrypi
raspberrypi-eeprom raspberrypi-eeprom
]; ];

View File

@ -1,57 +1,48 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ {
imports = [ time.timeZone = "Europe/London";
./common.nix
]; i18n.defaultLocale = "en_GB.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_GB.UTF-8";
LC_IDENTIFICATION = "en_GB.UTF-8";
LC_MEASUREMENT = "en_GB.UTF-8";
LC_MONETARY = "en_GB.UTF-8";
LC_NAME = "en_GB.UTF-8";
LC_NUMERIC = "en_GB.UTF-8";
LC_PAPER = "en_GB.UTF-8";
LC_TELEPHONE = "en_GB.UTF-8";
LC_TIME = "en_GB.UTF-8";
};
console.keyMap = "uk";
documentation.enable = false; documentation.enable = false;
fonts.fontconfig.enable = false; services.openssh = {
security = {
acme = {
acceptTerms = true;
defaults = {
email = "hostmaster@vimium.com";
group = "nginx";
webroot = "/var/lib/acme/acme-challenge";
};
};
auditd.enable = true;
audit = {
enable = true;
rules = [
"-a exit,always -F arch=b64 -S execve"
];
};
};
systemd = {
enableEmergencyMode = false;
sleep.extraConfig = ''
AllowSuspend=no
AllowHibernation=no
'';
watchdog = {
runtimeTime = "20s";
rebootTime = "30s";
};
};
services.fail2ban = {
enable = true; enable = true;
bantime = "1h"; settings = {
bantime-increment = { KbdInteractiveAuthentication = false;
enable = true; PasswordAuthentication = false;
maxtime = "24h"; PermitRootLogin = "no";
rndtime = "7m"; };
};
environment.systemPackages = with pkgs; [
git
neovim
];
nix = {
settings = {
auto-optimise-store = true;
};
gc = {
automatic = true;
dates = "weekly";
options = "-d --delete-older-than 7d";
}; };
ignoreIP = [
"100.64.0.0/10"
];
}; };
modules.networking.tailscale = { modules.networking.tailscale = {

View File

@ -15,4 +15,3 @@ NVMe | `/dev/sda1` (ext4, NixOS Root)
### Networks ### Networks
- DHCP on `10.0.1.0/24` subnet. - DHCP on `10.0.1.0/24` subnet.
- Tailscale on `100.64.0.0/10` subnet. FQDN: `vps1.mesh.vimium.net`. - Tailscale on `100.64.0.0/10` subnet. FQDN: `vps1.mesh.vimium.net`.

View File

@ -7,58 +7,189 @@
]; ];
networking = { networking = {
hostId = "08bf6db3"; hostId = "???";
hostName = "vps1";
domain = "mesh.vimium.net"; domain = "mesh.vimium.net";
firewall = { firewall = {
enable = true; enable = true;
allowedTCPPorts = [ allowedTCPPorts = [
22 # SSH 22 # SSH
8448 # Matrix federation
80 # HTTP
443 # HTTPS
5349 # STUN TLS
5350 # STUN TLS alt
];
allowedUDPPortRanges = [
{ from = 49152; to = 49999; } # TURN relay
]; ];
}; };
}; };
users = { users.users = {
users = { git = {
jellyfin = { isSystemUser = true;
isSystemUser = true; useDefaultShell = true;
group = "jellyfin"; group = "git";
shell = "/bin/sh"; extraGroups = [ "gitea" ];
openssh.authorizedKeys.keys = [ home = config.services.gitea.stateDir;
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOaaS+KMAEAymZhIJGC4LK8aMhUzhpmloUgvP2cxeBH4 jellyfin"
];
};
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
};
}; };
groups = { jellyfin = {
jellyfin = { }; isSystemUser = true;
group = "jellyfin";
shell = "/bin/sh";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOaaS+KMAEAymZhIJGC4LK8aMhUzhpmloUgvP2cxeBH4 jellyfin"
];
};
root = {
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILVHTjsyMIV4THNw6yz0OxAxGnC+41gX72UrPqTzR+OS jordan@vimium.com"
];
}; };
}; };
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password"; users.groups = {
git = { };
jellyfin = { };
};
modules = { age.secrets."passwords/services/borg/vps1-passphrase" = {
services = { file = "${inputs.secrets}/passwords/services/borg/vps1-passphrase.age";
borgmatic = { };
enable = true;
directories = [ services.borgmatic = {
"/home" enable = true;
"/var/lib" settings = {
"/var/www" source_directories = [
]; "/home"
repoPath = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo"; "/var/lib"
"/var/www"
];
repositories = [
{ label = "borgbase"; path = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo"; }
];
storage = {
encryption_passcommand = "cat ${config.age.secrets."passwords/services/borg/vps1-passphrase".path}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
};
retention = {
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
}; };
coturn.enable = true;
gitea.enable = true;
headscale.enable = true;
matrix-synapse.enable = true;
nginx.enable = true;
photoprism.enable = true;
}; };
}; };
# Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true;
age.secrets."passwords/services/coturn/shared-secret" = {
file = "${inputs.secrets}/passwords/services/coturn/shared-secret.age";
};
services.coturn = {
enable = true;
lt-cred-mech = true;
use-auth-secret = true;
static-auth-secret = "???";
realm = "turn.vimium.com";
relay-ips = [
"198.244.190.160"
];
no-tcp-relay = true;
extraConfig = ''
cipher-list="HIGH"
no-loopback-peers
no-multicast-peers
'';
secure-stun = true;
cert = "/var/lib/acme/turn.vimium.com/fullchain.pem";
pkey = "/var/lib/acme/turn.vimium.com/key.pem";
min-port = 49152;
max-port = 49999;
};
services.gitea = rec {
package = pkgs.gitea;
enable = true;
user = "git";
appName = "Vimium Git";
stateDir = "/var/lib/gitea";
repositoryRoot = "${stateDir}/repositories";
database = {
type = "sqlite3";
inherit user;
path = "${stateDir}/gitea.db";
};
lfs = {
enable = true;
contentDir = "${stateDir}/lfs";
};
settings = {
server = {
SSH_USER = "git";
SSH_DOMAIN = "git.vimium.com";
SSH_PORT = lib.head config.services.openssh.ports;
OFFLINE_MODE = true;
PROTOCOL = "http+unix";
DOMAIN = config.networking.domain;
ROOT_URL = "https://git.vimium.com/";
};
service.DISABLE_REGISTRATION = true;
session.COOKIE_SECURE = true;
log.ROOT_PATH = "${stateDir}/log";
ui = {
THEMES = "gitea,arc-green,github-dark,bthree-dark";
DEFAULT_THEME = "github-dark";
};
actions.ENABLED = true;
indexer = {
REPO_INDEXER_ENABLED = true;
};
packages.CHUNKED_UPLOAD_PATH = lib.mkForce "${stateDir}/data/tmp/package-upload";
};
};
services.headscale = {
enable = true;
port = 8080;
settings = {
server_url = "https://headscale.vimium.net";
dns_config = {
base_domain = "vimium.net";
};
logtail.enabled = false;
};
};
services.matrix-synapse = {
enable = true;
settings = {
database.name = "sqlite3";
enable_registration = false;
server_name = "vimium.com";
turn_shared_secret = "???";
turn_uris = [
"turn:turn.vimium.com:5349?transport=udp"
"turn:turn.vimium.com:5350?transport=udp"
"turn:turn.vimium.com:5349?transport=tcp"
"turn:turn.vimium.com:5350?transport=tcp"
];
};
};
services.tailscale.enable = true;
networking.firewall = {
checkReversePath = "loose";
trustedInterfaces = [ "tailscale0" ];
allowedUDPPorts = [ config.services.tailscale.port ];
};
environment.systemPackages = with pkgs; [
config.services.headscale.package
];
system.stateVersion = "22.11"; system.stateVersion = "22.11";
} }

View File

@ -1,10 +1,7 @@
{ {
imports = [ imports = [
./options.nix ./options.nix
./podman.nix
./desktop/gnome.nix ./desktop/gnome.nix
./desktop/hyprland.nix
./desktop/kde.nix
./desktop/mimeapps.nix ./desktop/mimeapps.nix
./desktop/apps/qbittorrent.nix ./desktop/apps/qbittorrent.nix
./desktop/apps/slack.nix ./desktop/apps/slack.nix
@ -28,21 +25,9 @@
./dev/zig.nix ./dev/zig.nix
./editors/neovim ./editors/neovim
./editors/vscode.nix ./editors/vscode.nix
./hardware/presonus-studio.nix
./networking/tailscale.nix ./networking/tailscale.nix
./networking/wireless.nix
./security/gpg.nix ./security/gpg.nix
./security/pass.nix ./security/pass.nix
./services/borgmatic
./services/chrony
./services/coturn
./services/gitea
./services/gitea-runner
./services/headscale
./services/mail
./services/matrix-synapse
./services/nginx
./services/photoprism
./shell/git ./shell/git
./shell/zsh ./shell/zsh
]; ];

View File

@ -19,10 +19,6 @@ in {
default = false; default = false;
example = true; example = true;
}; };
ps1.enable = lib.mkOption {
default = false;
example = true;
};
ps2.enable = lib.mkOption { ps2.enable = lib.mkOption {
default = false; default = false;
example = true; example = true;
@ -39,36 +35,25 @@ in {
default = false; default = false;
example = true; example = true;
}; };
switch.enable = lib.mkOption {
default = false;
example = true;
};
wii.enable = lib.mkOption { wii.enable = lib.mkOption {
default = false; default = false;
example = true; example = true;
}; };
xbox.enable = lib.mkOption {
default = false;
example = true;
};
}; };
config = { config = {
user.packages = with pkgs; [ user.packages = with pkgs; [
(lib.mkIf cfg.ps1.enable duckstation) (lib.mkIf cfg.ps2.enable pcsx2)
(lib.mkIf cfg.ps2.enable unstable.pcsx2)
(lib.mkIf cfg.ps3.enable rpcs3) (lib.mkIf cfg.ps3.enable rpcs3)
(lib.mkIf cfg.psp.enable unstable.ppsspp) (lib.mkIf cfg.psp.enable ppsspp)
(lib.mkIf cfg.ds.enable desmume) (lib.mkIf cfg.ds.enable desmume)
(lib.mkIf (cfg.gba.enable || (lib.mkIf (cfg.gba.enable ||
cfg.gb.enable || cfg.gb.enable ||
cfg.snes.enable) cfg.snes.enable)
higan) higan)
(lib.mkIf cfg.switch.enable yuzuPackages.mainline)
(lib.mkIf (cfg.wii.enable || (lib.mkIf (cfg.wii.enable ||
cfg.gamecube.enable) cfg.gamecube.enable)
dolphin-emu) dolphin-emu)
(lib.mkIf cfg.xbox.enable unstable.xemu)
]; ];
}; };
} }

View File

@ -10,13 +10,8 @@ in {
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [ user.packages = with pkgs; [
(lutris.override { lutris
extraPkgs = pkgs: [
winePackages.staging
wine64Packages.staging
];
})
vulkan-loader vulkan-loader
vulkan-tools vulkan-tools
]; ];

View File

@ -17,7 +17,6 @@ in {
}; };
services.flatpak.enable = true; services.flatpak.enable = true;
services.fwupd.enable = true;
programs.dconf.enable = true; programs.dconf.enable = true;
dconf.settings = { dconf.settings = {
@ -100,14 +99,8 @@ in {
window-gap = 8; window-gap = 8;
}; };
"org/gnome/desktop/background" = { "org/gnome/desktop/background" = {
picture-uri = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-l.jxl"; picture-uri = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-l.jpg";
picture-uri-dark = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-d.jxl"; picture-uri-dark = "file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/adwaita-d.jpg";
};
"org/gnome/desktop/peripherals/touchpad" = {
tap-to-click = true;
};
"org/gnome/desktop/search-providers" = {
disabled = [ "org.gnome.Epiphany.desktop" ];
}; };
"org/gtk/settings/file-chooser" = { "org/gtk/settings/file-chooser" = {
show-hidden = true; show-hidden = true;
@ -135,18 +128,15 @@ in {
}; };
"org/gnome/Console" = { "org/gnome/Console" = {
font-scale = 1.4; font-scale = 1.4;
use-system-font = false;
custom-font = "ComicShannsMono Nerd Font 10";
}; };
"org/gnome/mutter" = { "org/gnome/mutter" = {
center-new-windows = true; center-new-windows = true;
edge-tiling = true;
experimental-features = [ "scale-monitor-framebuffer" ]; experimental-features = [ "scale-monitor-framebuffer" ];
}; };
"org/gnome/desktop/interface" = { "org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
enable-hot-corners = false; enable-hot-corners = false;
icon-theme = "MoreWaita"; monospace-font-name = "Ubuntu Mono 11";
monospace-font-name = "UbuntuMono Nerd Font 11";
}; };
"org/gnome/desktop/wm/keybindings" = { "org/gnome/desktop/wm/keybindings" = {
switch-group = [ "<Super>grave" ]; switch-group = [ "<Super>grave" ];
@ -157,30 +147,22 @@ in {
}; };
}; };
fonts.packages = with pkgs; [
noto-fonts
ubuntu_font_family
];
user.packages = with pkgs; [ user.packages = with pkgs; [
authenticator
# bottles
# bustle
celluloid celluloid
# d-spy fragments
# drawing
# fragments
gnome.ghex
# gnome-builder
gnome-decoder
gnome-firmware
gnome-frog
# gnome-obfuscate
gnome-podcasts
identity
mission-center mission-center
newsflash
# schemes
shortwave
]; ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
adw-gtk3 bind
bmon
fd
ffmpeg
gnome.gnome-boxes gnome.gnome-boxes
gnomeExtensions.another-window-session-manager gnomeExtensions.another-window-session-manager
# gnomeExtensions.bifocals # gnomeExtensions.bifocals
@ -188,7 +170,7 @@ in {
gnomeExtensions.browser-tabs gnomeExtensions.browser-tabs
gnomeExtensions.burn-my-windows gnomeExtensions.burn-my-windows
gnomeExtensions.desktop-cube gnomeExtensions.desktop-cube
# gnomeExtensions.desktop-zoom gnomeExtensions.desktop-zoom
gnomeExtensions.espresso gnomeExtensions.espresso
gnome44Extensions."flypie@schneegans.github.com" gnome44Extensions."flypie@schneegans.github.com"
# gnomeExtensions.forge # gnomeExtensions.forge
@ -211,11 +193,17 @@ in {
# gnomeExtensions.window-is-ready-remover # gnomeExtensions.window-is-ready-remover
# gnomeExtensions.worksets # gnomeExtensions.worksets
# gnomeExtensions.workspace-matrix # gnomeExtensions.workspace-matrix
unstable.morewaita-icon-theme iotop
ripgrep
rsync
tcpdump
tokei
tree
wl-clipboard
] ++ (if config.virtualisation.podman.enable then [ ] ++ (if config.virtualisation.podman.enable then [
pods pods
] else []); ] else []);
home.services.gpg-agent.pinentryPackage = pkgs.pinentry-gnome3; home.services.gpg-agent.pinentryFlavor = "gnome3";
}; };
} }

View File

@ -1,27 +0,0 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.hyprland;
in {
options.modules.desktop.hyprland = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
programs.hyprland.enable = true;
networking.networkmanager.enable = true;
user.packages = with pkgs; [
mpv
];
environment.systemPackages = with pkgs; [
adw-gtk3
];
home.services.gpg-agent.pinentryPackage = pkgs.pinentry-gnome3;
};
}

View File

@ -1,35 +0,0 @@
{ config, lib, pkgs, ... }:
let cfg = config.modules.desktop.kde;
in {
options.modules.desktop.kde = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
services.xserver = {
enable = true;
displayManager.sddm = {
enable = true;
wayland.enable = true;
};
desktopManager.plasma5.enable = true;
};
networking.networkmanager.enable = true;
user.packages = with pkgs; [
kmail
mpv
];
environment.systemPackages = with pkgs; [
adw-gtk3
];
home.services.gpg-agent.pinentryPackage = pkgs.pinentry-qt;
};
}

View File

@ -11,10 +11,7 @@ in {
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
user.packages = with pkgs; [ user.packages = with pkgs; [
(if config.modules.desktop.kde.enable == true then libreoffice-qt else libreoffice) libreoffice
hunspell
hunspellDicts.en-gb-large
hunspellDicts.en-us-large
]; ];
}; };
} }

View File

@ -2,6 +2,7 @@
let let
cfg = config.modules.editors.neovim; cfg = config.modules.editors.neovim;
dev = config.modules.dev;
in { in {
options.modules.editors.neovim = { options.modules.editors.neovim = {
enable = lib.mkOption { enable = lib.mkOption {
@ -11,129 +12,124 @@ in {
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
home.programs.nixvim = { user.packages = with pkgs; [
enable = true; (neovim.override {
defaultEditor = true; configure = {
customRC = ''
viAlias = true; luafile ~/.config/nvim/init.lua
vimAlias = true; '';
packages.myPlugins = with pkgs.vimPlugins; {
options = { start = [
number = true; (nvim-treesitter.withPlugins (
tabstop = 2; plugins: with plugins; [
shiftwidth = 2; bash
expandtab = true; c
foldlevel = 99; cmake
splitbelow = true; cpp
splitright = true; css
undofile = true; dockerfile
updatetime = 100; elm
list = true; glsl
}; graphql
haskell
globals = { http
mapleader = ","; html
maplocalleader = ","; java
}; javascript
jsdoc
clipboard = { json
register = "unnamedplus"; json5
latex
providers.wl-copy.enable = true; lua
}; markdown
ninja
plugins.comment.enable = true; nix
org
plugins.hmts.enable = true; perl
php
plugins.lightline.enable = true; pug
python
plugins.luasnip.enable = true; regex
rst
plugins.lsp = { ruby
enable = true; rust
servers = { scala
bashls.enable = true; scss
ccls.enable = true; toml
cssls.enable = true; tsx
eslint.enable = true; typescript
gopls.enable = true; vim
html.enable = true; yaml
lua-ls.enable = true; zig
pylsp.enable = true; ]
nixd.enable = true; ))
rust-analyzer = { nvim-treesitter-context
enable = true; nvim-treesitter-textobjects
installCargo = true; nvim-lspconfig
installRustc = true; ];
};
tsserver.enable = true;
};
};
plugins.nvim-autopairs.enable = true;
plugins.cmp = {
enable = true;
autoEnableSources = true;
settings = {
sources = [
{ name = "nvim_lsp"; }
{ name = "path"; }
{ name = "buffer"; }
];
mapping = {
"<Tab>" = "cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'})";
"<S-Tab>" = "cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})";
"<CR>" = "cmp.mapping.confirm({ select = true })";
}; };
}; };
}; })
] ++
plugins.telescope = { # Install appropriate language servers
enable = true; (if dev.cc.enable then [
keymaps = { ccls # C/C++
"<leader>ff" = "find_files"; ] else []) ++
"<leader>fg" = "live_grep"; (if dev.java.enable then [
"<leader>b" = "buffers"; java-language-server # Java
"<leader>fh" = "help_tags"; ltex-ls # LaTeX
"<C-p>" = "git_files"; ] else []) ++
"<C-f>" = "live_grep"; (if dev.lua.enable then [
}; sumneko-lua-language-server # Lua
}; ] else []) ++
(if dev.node.enable then [
nodePackages.bash-language-server # Bash
nodePackages.dockerfile-language-server-nodejs # Dockerfile
nodePackages.graphql-language-service-cli # GraphQL
nodePackages.purescript-language-server # PureScript
nodePackages.svelte-language-server # Svelte
nodePackages.typescript-language-server # JavaScript/TypeScript
nodePackages.vim-language-server # Vim
nodePackages.vscode-langservers-extracted # HTML, CSS, JSON, ESLint
nodePackages.vue-language-server # Vue.js
nodePackages.yaml-language-server # YAML
] else []) ++
(if dev.python.enable then [
cmake-language-server # CMake
python310Packages.python-lsp-server # Python
] else []) ++
(if dev.rust.enable then [
rust-analyzer # Rust
] else []) ++
(if dev.scala.enable then [
metals # Scala
] else []) ++
(if dev.zig.enable then [
zls # Zig
] else []);
plugins.treesitter = { home.configFile = {
enable = true; "nvim/init.lua".source = ./init.lua;
"nvim/lua" = { source = ./lua; recursive = true; };
nixvimInjections = true; "nvim/lua/config/lsp.lua".text = ''
-- This file is autogenerated, do not edit.
folding = true; ${if dev.cc.enable then "require('config.lsp.cc')\n" else ""}
indent = true; ${if dev.java.enable then "require('config.lsp.java')\n" else ""}
}; ${if dev.lua.enable then "require('config.lsp.lua')\n" else ""}
${if dev.node.enable then "require('config.lsp.node')\n" else ""}
plugins.treesitter-refactor = { ${if dev.python.enable then "require('config.lsp.python')\n" else ""}
enable = true; ${if dev.rust.enable then "require('config.lsp.rust')\n" else ""}
highlightDefinitions = { ${if dev.scala.enable then "require('config.lsp.scala')\n" else ""}
enable = true; ${if dev.zig.enable then "require('config.lsp.zig')\n" else ""}
clearOnCursorMove = false; '';
};
};
plugins.undotree.enable = true;
# plugins.gitsigns.enable = true;
# plugins.gitgutter.enable = true;
# plugins.goyo.enable = true;
# plugins.fugitive.enable = true;
# plugins.fzf-lua.enable = true;
# plugins.neo-tree.enable = true;
# plugins.none-ls.enable = true;
# plugins.nvim-tree.enable = true;
# plugins.oil.enable = true;
# plugins.project-nvim.enable = true;
# plugins.surround.enable = true;
}; };
env.EDITOR = "nvim"; env.EDITOR = "nvim";
environment.shellAliases = {
vim = "nvim";
v = "nvim";
};
}; };
} }

View File

@ -0,0 +1,6 @@
require("config.core")
require("config.keymap")
require("config.treesitter")
require("config.plugins")
require("config.lsp")

View File

@ -0,0 +1,36 @@
local o = vim.opt
local wo = vim.wo
local bo = vim.bo
-- Global dirs
local cachedir = os.getenv("XDG_CACHE_HOME")
o.backupdir = cachedir .. "/nvim/backup/"
o.directory = cachedir .. "/nvim/swap/"
o.undodir = cachedir .. "/nvim/undo/"
-- Global
o.breakindent = true
o.clipboard = "unnamedplus"
o.compatible = false
o.encoding = "utf-8"
o.expandtab = true
o.foldlevel = 99
o.hidden = true
o.hlsearch = false
o.ignorecase = true
o.laststatus = 2
o.listchars = { eol = '', tab = '', trail = '·' }
o.relativenumber = true
o.shiftwidth = 2
o.showmode = false
o.smartcase = true
o.smarttab = true
o.softtabstop = 2
o.synmaxcol = 150
o.tabstop = 4
o.undofile = true
o.wildmenu = true
-- Window
-- Buffer

View File

@ -0,0 +1,35 @@
local keymap = vim.keymap.set
local opts = { noremap = true, silent = true }
vim.g.mapleader = ","
-- Modes
-- Normal = "n",
-- Insert = "i",
-- Visual = "v",
-- Visual Block = "x",
-- Term = "t",
-- Command = "c"
keymap("n", "<Left>", "<Nop>", opts)
keymap("n", "<Right>", "<Nop>", opts)
keymap("n", "<Up>", "<Nop>", opts)
keymap("n", "<Down>", "<Nop>", opts)
keymap("n", "<C-h>", "<C-w>h", { noremap = true })
keymap("n", "<C-j>", "<C-w>j", { noremap = true })
keymap("n", "<C-k>", "<C-w>k", { noremap = true })
keymap("n", "<C-l>", "<C-w>l", { noremap = true })
keymap("n", "gV", "`[v`]", opts)
keymap("n", ";", ":", { noremap = true })
-- Bubble single lines with vim-unimpaired
keymap("n", "<C-Up>", "[e", opts)
keymap("n", "<C-Down>", "]e", opts)
-- Bubble multiple lines with vim-unimpaired
keymap("v", "<C-Up>", "[egv", opts)
keymap("v", "<C-Down>", "]egv", opts)

View File

@ -0,0 +1,5 @@
lspconfig = require('lspconfig')
-- Requires C/C++
lspconfig.ccls.setup{}

View File

@ -0,0 +1,6 @@
lspconfig = require('lspconfig')
-- Requires Java
lspconfig.java_language_server.setup{}
lspconfig.ltex.setup{}

View File

@ -0,0 +1,22 @@
lspconfig = require('lspconfig')
-- Requires Lua
lspconfig.sumneko_lua.setup {
settings = {
Lua = {
runtime = {
-- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
version = 'LuaJIT',
},
diagnostics = {
-- Get the language server to recognize the `vim` global
globals = {'vim'},
},
-- Do not send telemetry data containing a randomized but unique identifier
telemetry = {
enable = false,
},
},
},
}

View File

@ -0,0 +1,17 @@
lspconfig = require('lspconfig')
-- Requires Node.js
lspconfig.bashls.setup{}
lspconfig.cssls.setup{}
lspconfig.dockerls.setup{}
lspconfig.eslint.setup{}
lspconfig.graphql.setup{}
lspconfig.html.setup{}
lspconfig.jsonls.setup{}
lspconfig.purescriptls.setup{}
lspconfig.svelte.setup{}
lspconfig.tsserver.setup{}
lspconfig.vimls.setup{}
lspconfig.vuels.setup{}
lspconfig.yamlls.setup{}

View File

@ -0,0 +1,6 @@
lspconfig = require('lspconfig')
-- Requires Python
lspconfig.cmake.setup{}
lspconfig.pylsp.setup{}

View File

@ -0,0 +1,5 @@
lspconfig = require('lspconfig')
-- Requires Rust
lspconfig.rls.setup{}

View File

@ -0,0 +1,5 @@
lspconfig = require('lspconfig')
-- Requires Scala
lspconfig.metals.setup{}

View File

@ -0,0 +1,5 @@
lspconfig = require('lspconfig')
-- Requires Zig
lspconfig.zls.setup{}

View File

@ -0,0 +1,77 @@
local fn = vim.fn
local install_path = fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim"
if fn.empty(fn.glob(install_path)) > 0 then
PACKER_BOOTSTRAP = fn.system {
"git",
"clone",
"--depth",
"1",
"https://github.com/wbthomason/packer.nvim",
install_path,
}
print "Installing packer close and reopen Neovim..."
vim.cmd [[packadd packer.nvim]]
end
vim.cmd [[
augroup packer_user_config
autocmd!
autocmd BufWritePost plugins.lua source <afile> | PackerSync
augroup end
]]
local status_ok, packer = pcall(require, "packer")
if not status_ok then
return
end
packer.init {
display = {
open_fn = function()
return require("packer.util").float { border = "rounded" }
end,
},
}
return packer.startup(function(use)
-- Utilities
use { "wbthomason/packer.nvim", opt = true }
use { "mbbill/undotree" }
use { "nvim-lua/plenary.nvim" }
use { "tpope/vim-fugitive", event = "User InGitRepo" }
-- Editing
use { "andymass/vim-matchup" }
use { "godlygeek/tabular" }
use { "JoosepAlviste/nvim-ts-context-commentstring" }
use { "kana/vim-textobj-user" }
use { "mg979/vim-visual-multi", branch = "master" }
use { "p00f/nvim-ts-rainbow" }
use { "terryma/vim-expand-region" }
use { "tommcdo/vim-exchange", event = "VimEnter" }
use { "tpope/vim-abolish" }
use { "tpope/vim-commentary", event = "VimEnter" }
use { "tpope/vim-repeat", event = "VimEnter" }
use { "tpope/vim-surround", event = "VimEnter" }
use { "windwp/nvim-autopairs" }
use { "windwp/nvim-ts-autotag" }
-- UI
use { "junegunn/goyo.vim" }
use { "junegunn/limelight.vim" }
use { "markonm/traces.vim" }
-- Searching
use { "nvim-telescope/telescope.nvim", config = [[require('config.telescope')]] }
use { "cljoly/telescope-repo.nvim", requires = "telescope.nvim" }
use { "dyng/ctrlsf.vim" }
-- LSP
use { "jose-elias-alvarez/null-ls.nvim" }
if PACKER_BOOTSTRAP then
require("packer").sync()
end
end)

View File

@ -0,0 +1,46 @@
local status_ok, telescope = pcall(require, "telescope")
if not status_ok then
return
end
local actions = require("telescope.actions")
telescope.setup({
defaults = {
file_ignore_patterns = { ".git/", "node_modules" },
},
mappings = {
i = {
["<Down>"] = actions.cycle_history_next,
["<Up>"] = actions.cycle_history_prev,
["<C-j>"] = actions.move_selection_next,
["<C-k>"] = actions.move_selection_previous,
},
},
extensions = {
repo = {
list = {
fd_opts = {
"--no-ignore-vcs",
},
search_dirs = {
"~/projects",
"~/repos",
"~/workspace",
},
},
},
},
})
telescope.load_extension("repo")
local keymap = vim.keymap.set
local opts = { noremap = true, silent = true }
keymap("n", "<Leader>ff", "<cmd>Telescope find_files<cr>", opts)
keymap("n", "<Leader>fg", "<cmd>Telescope live_grep<cr>", opts)
keymap("n", "<Leader>fb", "<cmd>Telescope buffers<cr>", opts)
keymap("n", "<Leader>fh", "<cmd>Telescope help_tags<cr>", opts)
keymap("n", "<Leader>fr", "<cmd>Telescope repo list<cr>", opts)

View File

@ -0,0 +1,35 @@
require("nvim-treesitter.configs").setup({
ignore_install = {},
highlight = {
enable = true,
disable = {},
},
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "gnn",
node_incremental = "grn",
scope_incremental = "grc",
node_decremental = "grm",
},
},
-- Extensions
autotag = { enable = true },
context_commentstring = { enable = true },
matchup = { enable = true },
rainbow = { enable = true },
textobjects = {
select = {
enable = true,
keymaps = {
["af"] = "@function.outer",
["if"] = "@function.inner",
},
},
},
})
vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "nvim_treesitter#foldexpr()"

View File

@ -1,88 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.modules.hardware.presonus-studio;
snd-usb-audio-module = pkgs.callPackage ./snd-usb-audio.nix {
kernel = config.boot.kernelPackages.kernel;
};
patched = snd-usb-audio-module.overrideAttrs (prev: {
patches = [ ./0001-Update-device-ID-for-PreSonus-1824c.patch ];
});
upmixConfig = {
"stream.properties" = {
"channelmix.upmix" = true;
"channelmix.upmix-method" = "psd";
};
};
in {
options.modules.hardware.presonus-studio = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
boot.kernelModules = [ "snd-usb-audio" ];
boot.extraModulePackages = [
(patched)
];
# Workaround for mainline module loading instead of patched module
systemd.services.reload-snd-usb-audio = {
description = "Reload snd_usb_audio kernel module";
wantedBy = [ "sound.target" ];
serviceConfig.Type = "oneshot";
path = with pkgs; [
kmod
];
script = ''
# Only reload if device hasn't been initialised
if ! cat /proc/asound/card*/usbmixer | grep -q "Mute Main Out Switch"; then
rmmod snd_usb_audio
insmod /run/booted-system/kernel-modules/lib/modules/$(uname -r)/extra/snd-usb-audio.ko.xz
fi
'';
};
services.pipewire.extraConfig = {
pipewire = {
"10-network" = {
"context.modules" = [
{
"name" = "libpipewire-module-rtp-session";
"args" = {
"stream.props" = {
"node.name" = "rtp-source";
};
};
}
];
};
"surround" = {
"context.modules" = [
{
"name" = "libpipewire-module-loopback";
"args" = {
"node.description" = "Genelec 4.1 Surround";
"capture.props" = {
"node.name" = "Genelec_Speakers";
"media.class" = "Audio/Sink";
"audio.position" = [ "FL" "FR" "SL" "SR" "LFE" ];
};
"playback.props" = {
"node.name" = "playback.Genelec_Speakers";
"audio.position" = [ "AUX0" "AUX1" "AUX3" "AUX4" "AUX5" ];
"target.object" = "alsa_output.usb-PreSonus_Studio_1824c_SC4E21110775-00.multichannel-output";
"stream.dont-remix" = true;
"node.passive" = true;
};
};
}
];
};
};
pipewire-pulse."40-upmix" = upmixConfig;
client-rt."40-upmix" = upmixConfig;
};
};
}

View File

@ -1,9 +1,6 @@
{ config, inputs, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let cfg = config.modules.networking.tailscale;
cfg = config.modules.networking.tailscale;
headscale = "https://headscale.vimium.net";
hostname = config.networking.hostName;
in { in {
options.modules.networking.tailscale = { options.modules.networking.tailscale = {
enable = lib.mkOption { enable = lib.mkOption {
@ -17,24 +14,8 @@ in {
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
age.secrets."passwords/services/tailscale/${hostname}-authkey" = { services.tailscale.enable = true;
file = "${inputs.secrets}/passwords/services/tailscale/${hostname}-authkey.age";
};
environment.systemPackages = [ pkgs.tailscale ];
services.tailscale = {
enable = true;
authKeyFile = config.age.secrets."passwords/services/tailscale/${hostname}-authkey".path;
extraUpFlags = [
"--login-server"
headscale
];
};
services.openssh.openFirewall = !cfg.restrictSSH; services.openssh.openFirewall = !cfg.restrictSSH;
networking.firewall = { networking.firewall = {
checkReversePath = "loose"; checkReversePath = "loose";
trustedInterfaces = [ "tailscale0" ]; trustedInterfaces = [ "tailscale0" ];

View File

@ -1,60 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let cfg = config.modules.networking.wireless;
in {
options.modules.networking.wireless = {
enable = mkOption {
default = false;
example = true;
description = mdDoc "Automatically connect to known networks";
};
interfaces = mkOption {
default = [ ]; # All interfaces
example = [ "wlan0" ];
description = mdDoc "Interfaces for `wpa_supplicant` to bind to";
};
};
config = mkIf cfg.enable {
age.secrets."passwords/networks" = {
file = "${inputs.secrets}/passwords/networks.age";
};
networking = {
wireless = {
enable = true;
interfaces = cfg.interfaces;
environmentFile = config.age.secrets."passwords/networks".path;
networks = {
"Apollo 600 Mbps".psk = "@PSK_APOLLO@";
};
};
networkmanager.ensureProfiles.profiles = {
"Apollo" = {
connection = {
id = "Apollo 600 Mbps";
type = "wifi";
};
wifi = {
mode = "infrastructure";
ssid = "Apollo 600 Mbps";
};
wifi-security = {
auth-alg = "open";
key-mgmt = "wpa-psk";
psk = "";
};
ipv4 = {
method = "auto";
};
ipv6 = {
addr-gen-mode = "stable-privacy";
method = "auto";
};
};
};
};
};
}

View File

@ -66,10 +66,6 @@ with lib;
}; };
dconf.settings = mkAliasDefinitions options.dconf.settings; dconf.settings = mkAliasDefinitions options.dconf.settings;
}; };
sharedModules = [
inputs.nixvim.homeManagerModules.nixvim
];
}; };
users.users.${config.user.name} = mkAliasDefinitions options.user; users.users.${config.user.name} = mkAliasDefinitions options.user;

View File

@ -1,45 +0,0 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.podman;
in {
options.modules.podman = {
enable = mkOption {
default = false;
example = true;
description = mdDoc "Enable podman on this host";
};
};
config = mkIf cfg.enable {
virtualisation = {
docker.enable = false;
podman = {
enable = true;
defaultNetwork.settings.dns_enabled = true;
autoPrune = {
enable = true;
dates = "weekly";
flags = [ "--all" ];
};
extraPackages = [ pkgs.zfs ];
};
containers.storage.settings.storage = {
driver = "zfs";
graphroot = "/var/lib/containers/storage";
runroot = "/run/containers/storage";
};
oci-containers.backend = "podman";
};
networking.firewall.interfaces."podman+" = {
allowedUDPPorts = [ 53 ];
allowedTCPPorts = [ 53 ];
};
};
}

View File

@ -1,53 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.services.borgmatic;
hostname = config.networking.hostName;
in {
options.modules.services.borgmatic = {
enable = mkOption {
default = false;
example = true;
description = mdDoc "Enable backups on this host with `borgmatic`";
};
directories = mkOption {
type = types.listOf types.str;
default = [];
example = [
"/home/jordan/Documents"
];
description = mdDoc "List of directories to backup";
};
repoPath = mkOption {
type = types.str;
example = "ssh://example@example.repo.borgbase.com/./repo";
description = mdDoc "Destination borg repository for backup";
};
};
config = mkIf cfg.enable {
age.secrets."passwords/services/borg/${hostname}-passphrase" = {
file = "${inputs.secrets}/passwords/services/borg/${hostname}-passphrase.age";
};
services.borgmatic = {
enable = true;
settings = {
source_directories = cfg.directories;
repositories = [
{ label = "borgbase"; path = cfg.repoPath; }
];
encryption_passcommand = "cat ${config.age.secrets."passwords/services/borg/${hostname}-passphrase".path}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
};
# Without this override, `cat` is unavailable for `encryption_passcommand`
systemd.services.borgmatic.confinement.fullUnit = true;
};
}

View File

@ -1,41 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.modules.services.chrony;
in {
options.modules.services.chrony = {
enable = mkOption {
default = false;
example = true;
description = "Enable chrony NTP deamon";
};
config = mkIf cfg.enable {
services.chrony = {
enable = true;
servers = [
"uk.pool.ntp.org"
"time.cloudflare.com"
];
extraConfig = ''
makestep 1.0 3
bindaddress 0.0.0.0
port 123
allow
'';
};
services.timesyncd.enable = mkForce false;
networking.firewall = {
allowedUDPPorts = [ 123 ];
allowedTCPPorts = [ 123 ];
};
};
};
}

View File

@ -1,60 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.services.coturn;
in {
options.modules.services.coturn = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
networking.firewall = {
allowedTCPPorts = [
5349 # STUN TLS
5350 # STUN TLS alt
];
allowedUDPPortRanges = [
{ from = 49152; to = 49999; } # TURN relay
];
};
security.acme.certs = {
"turn.vimium.com" = {
reloadServices = [ "coturn" ];
};
};
age.secrets."passwords/services/coturn/shared-secret" = {
file = "${inputs.secrets}/passwords/services/coturn/shared-secret.age";
owner = "turnserver";
group = "turnserver";
};
services.coturn = {
enable = true;
lt-cred-mech = true;
use-auth-secret = true;
static-auth-secret-file = config.age.secrets."passwords/services/coturn/shared-secret".path;
realm = "turn.vimium.com";
relay-ips = [
"198.244.190.160"
];
no-tcp-relay = true;
extraConfig = ''
cipher-list="HIGH"
no-loopback-peers
no-multicast-peers
'';
secure-stun = true;
cert = "/var/lib/acme/turn.vimium.com/fullchain.pem";
pkey = "/var/lib/acme/turn.vimium.com/key.pem";
min-port = 49152;
max-port = 49999;
};
};
}

View File

@ -1,226 +0,0 @@
{ pkgs, config, lib, inputs, ... }:
# Based on: https://git.clan.lol/clan/clan-infra/src/branch/main/modules/web01/gitea/actions-runner.nix
with lib;
let
cfg = config.modules.services.gitea-runner;
hostname = config.networking.hostName;
giteaUrl = "https://git.vimium.com";
storeDepsBins = with pkgs; [
coreutils
findutils
gnugrep
gawk
git
nix
nix-update
bash
jq
nodejs
];
storeDeps = pkgs.runCommand "store-deps" { } ''
mkdir -p $out/bin
for dir in ${toString storeDepsBins}; do
for bin in "$dir"/bin/*; do
ln -s "$bin" "$out/bin/$(basename "$bin")"
done
done
# Add SSL CA certs
mkdir -p $out/etc/ssl/certs
cp -a "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" $out/etc/ssl/certs/ca-bundle.crt
'';
in
{
options.modules.services.gitea-runner = {
enable = mkOption {
default = false;
example = true;
description = mdDoc "Enable a runner for Gitea Actions on this host";
};
};
config = mkIf cfg.enable {
modules.podman.enable = true;
systemd.services = {
gitea-runner-nix-image = {
wantedBy = [ "multi-user.target" ];
after = [ "podman.service" ];
requires = [ "podman.service" ];
path = [ config.virtualisation.podman.package pkgs.gnutar pkgs.shadow pkgs.getent ];
script = ''
set -eux -o pipefail
mkdir -p etc/nix
# Create an unpriveleged user that we can use also without the run-as-user.sh script
touch etc/passwd etc/group
groupid=$(cut -d: -f3 < <(getent group nix-ci-user))
userid=$(cut -d: -f3 < <(getent passwd nix-ci-user))
groupadd --prefix $(pwd) --gid "$groupid" nix-ci-user
emptypassword='$6$1ero.LwbisiU.h3D$GGmnmECbPotJoPQ5eoSTD6tTjKnSWZcjHoVTkxFLZP17W9hRi/XkmCiAMOfWruUwy8gMjINrBMNODc7cYEo4K.'
useradd --prefix $(pwd) -p "$emptypassword" -m -d /tmp -u "$userid" -g "$groupid" -G nix-ci-user nix-ci-user
cat <<NIX_CONFIG > etc/nix/nix.conf
accept-flake-config = true
experimental-features = nix-command flakes
NIX_CONFIG
cat <<NSSWITCH > etc/nsswitch.conf
passwd: files mymachines systemd
group: files mymachines systemd
shadow: files
hosts: files mymachines dns myhostname
networks: files
ethers: files
services: files
protocols: files
rpc: files
NSSWITCH
# list the content as it will be imported into the container
tar -cv . | tar -tvf -
tar -cv . | podman import - gitea-runner-nix
'';
serviceConfig = {
RuntimeDirectory = "gitea-runner-nix-image";
WorkingDirectory = "/run/gitea-runner-nix-image";
Type = "oneshot";
RemainAfterExit = true;
};
};
gitea-runner-nix = {
after = [ "gitea-runner-nix-image.service" ];
requires = [ "gitea-runner-nix-image.service" ];
serviceConfig = {
# Hardening (may overlap with DynamicUser=)
# The following options are only for optimizing output of systemd-analyze
AmbientCapabilities = "";
CapabilityBoundingSet = "";
# ProtectClock= adds DeviceAllow=char-rtc r
DeviceAllow = "";
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RemoveIPC = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
UMask = "0066";
ProtectProc = "invisible";
SystemCallFilter = [
"~@clock"
"~@cpu-emulation"
"~@module"
"~@mount"
"~@obsolete"
"~@raw-io"
"~@reboot"
"~@swap"
# needed by go?
#"~@resources"
"~@privileged"
"~capset"
"~setdomainname"
"~sethostname"
];
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" "AF_NETLINK" ];
# Needs network access
PrivateNetwork = false;
# Cannot be true due to Node
MemoryDenyWriteExecute = false;
# The more restrictive "pid" option makes `nix` commands in CI emit
# "GC Warning: Couldn't read /proc/stat"
# You may want to set this to "pid" if not using `nix` commands
ProcSubset = "all";
# Coverage programs for compiled code such as `cargo-tarpaulin` disable
# ASLR (address space layout randomization) which requires the
# `personality` syscall
# You may want to set this to `true` if not using coverage tooling on
# compiled code
LockPersonality = false;
# Note that this has some interactions with the User setting; so you may
# want to consult the systemd docs if using both.
DynamicUser = true;
};
};
};
users.users.nix-ci-user = {
group = "nix-ci-user";
description = "Used for running nix-based CI jobs";
home = "/var/empty";
isSystemUser = true;
};
users.groups.nix-ci-user = { };
age.secrets."files/services/gitea-runner/${hostname}-token" = {
file = "${inputs.secrets}/files/services/gitea-runner/${hostname}-token.age";
group = "podman";
};
services.gitea-actions-runner.instances = {
act = {
enable = true;
url = giteaUrl;
name = "act-runner-${hostname}";
tokenFile = config.age.secrets."files/services/gitea-runner/${hostname}-token".path;
settings = {
cache.enabled = true;
runner.capacity = 4;
};
labels = [
"debian-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest"
"ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest"
];
};
nix = {
enable = true;
url = giteaUrl;
name = "nix-runner-${hostname}";
tokenFile = config.age.secrets."files/services/gitea-runner/${hostname}-token".path;
settings = {
cache.enabled = true;
container = {
options = "-e NIX_BUILD_SHELL=/bin/bash -e PAGER=cat -e PATH=/bin -e SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt --device /dev/kvm -v /nix:/nix -v ${storeDeps}/bin:/bin -v ${storeDeps}/etc/ssl:/etc/ssl --user nix-ci-user";
network = "host";
valid_volumes = [
"/nix"
"${storeDeps}/bin"
"${storeDeps}/etc/ssl"
];
};
runner.capacity = 4;
};
labels = [
"nix:docker://gitea-runner-nix"
];
};
};
};
}

View File

@ -1,94 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.services.gitea;
in {
options.modules.services.gitea = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
users = {
users.git = {
isSystemUser = true;
useDefaultShell = true;
group = "git";
extraGroups = [ "gitea" ];
home = config.services.gitea.stateDir;
};
groups.git = { };
};
services.nginx = {
upstreams.gitea = {
servers = {
"unix:${config.services.gitea.settings.server.HTTP_ADDR}" = { };
};
};
virtualHosts = {
"git.vimium.com" = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://gitea";
};
};
};
systemd.tmpfiles.rules = [
"d '${config.services.gitea.customDir}/public/assets/css' 0750 ${config.services.gitea.user} ${config.services.gitea.group} - -"
"L+ '${config.services.gitea.customDir}/public/assets/css/theme-github.css' - - - - ${inputs.gitea-github-theme}/theme-github.css"
"L+ '${config.services.gitea.customDir}/public/assets/css/theme-github-auto.css' - - - - ${inputs.gitea-github-theme}/theme-github-auto.css"
"L+ '${config.services.gitea.customDir}/public/assets/css/theme-github-dark.css' - - - - ${inputs.gitea-github-theme}/theme-github-dark.css"
];
services.gitea = rec {
package = pkgs.unstable.gitea;
enable = true;
user = "git";
appName = "Vimium Git";
stateDir = "/var/lib/gitea";
repositoryRoot = "${stateDir}/repositories";
database = {
type = "sqlite3";
inherit user;
path = "${stateDir}/gitea.db";
};
lfs = {
enable = true;
contentDir = "${stateDir}/lfs";
};
settings = {
server = {
DOMAIN = config.networking.domain;
LANDING_PAGE = "explore";
OFFLINE_MODE = true;
PROTOCOL = "http+unix";
SSH_USER = "git";
SSH_DOMAIN = "git.vimium.com";
SSH_PORT = lib.head config.services.openssh.ports;
ROOT_URL = "https://git.vimium.com/";
};
service.DISABLE_REGISTRATION = true;
session.COOKIE_SECURE = true;
log = {
ROOT_PATH = "${stateDir}/log";
DISABLE_ROUTER_LOG = true;
};
ui = {
THEMES = "gitea,arc-green,github,github-auto,github-dark";
DEFAULT_THEME = "github-dark";
};
actions.ENABLED = true;
indexer = {
REPO_INDEXER_ENABLED = true;
};
packages.CHUNKED_UPLOAD_PATH = lib.mkForce "${stateDir}/data/tmp/package-upload";
};
};
};
}

View File

@ -1,47 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.services.headscale;
fqdn = "headscale.vimium.net";
in {
options.modules.services.headscale = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.headscale ];
services.headscale = {
enable = true;
port = 8080;
settings = {
ip_prefixes = [
"100.64.0.0/10"
];
server_url = "https://${fqdn}";
dns_config = {
base_domain = "vimium.net";
};
logtail.enabled = false;
};
};
services.nginx.virtualHosts = {
"${fqdn}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.headscale.port}";
proxyWebsockets = true;
};
};
};
};
}

View File

@ -1,69 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.modules.services.mail;
domains = [
"h0lt.com"
"jdholt.com"
"jordanholt.xyz"
"vimium.co"
"vimium.com"
"vimium.co.uk"
"vimium.info"
"vimium.net"
"vimium.org"
"vimium.xyz"
];
in {
options.modules.services.mail = {
enable = lib.mkOption {
default = false;
example = true;
};
};
config = lib.mkIf cfg.enable {
services.roundcube = {
enable = true;
hostName = config.mailserver.fqdn;
extraConfig = ''
$config['smtp_server'] = "tls://${config.mailserver.fqdn}";
$config['smtp_user'] = "%u";
$config['smtp_pass'] = "%p";
'';
};
services.nginx.enable = true;
networking.firewall.allowedTCPPorts = [ 80 443 ];
mailserver = {
enable = true;
fqdn = "mail.vimium.com";
domains = domains;
indexDir = "/var/lib/dovecot/indices";
certificateDomains = [
"imap.vimium.com"
"smtp.vimium.com"
];
certificateScheme = "acme-nginx";
fullTextSearch.enable = true;
loginAccounts = {
"jordan@vimium.com" = {
hashedPasswordFile = config.users.users.jordan.hashedPasswordFile;
catchAll = domains;
};
};
extraVirtualAliases = {
"hostmaster@vimium.com" = "jordan@vimium.com";
"postmaster@vimium.com" = "jordan@vimium.com";
"webmaster@vimium.com" = "jordan@vimium.com";
"abuse@vimium.com" = "jordan@vimium.com";
};
};
};
}

View File

@ -1,127 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.services.matrix-synapse;
matrixClientConfig = {
"m.homeserver" = {
base_url = "https://matrix.vimium.com";
server_name = "vimium.com";
};
"m.identity_server" = {};
};
matrixServerConfig."m.server" = "matrix.vimium.com:443";
mkWellKnown = data: ''
more_set_headers 'Content-Type: application/json';
return 200 '${builtins.toJSON data}';
'';
in {
options.modules.services.matrix-synapse = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [
8448 # Matrix federation
];
security.acme.certs = {
"matrix.vimium.com" = {
reloadServices = [ "matrix-synapse" ];
};
};
services.nginx.virtualHosts = {
"chat.vimium.com" = {
forceSSL = true;
enableACME = true;
root = pkgs.unstable.element-web.override {
conf = {
default_server_config = matrixClientConfig;
brand = "Vimium Chat";
branding = {
auth_header_logo_url = "https://vimium.com/images/logo.svg";
auth_footer_links = [
{ "text" = "Vimium.com"; "url" = "https://vimium.com"; }
];
};
};
};
};
"matrix.vimium.com" = {
forceSSL = true;
enableACME = true;
listen = [
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "0.0.0.0";
port = 8448;
ssl = true;
}
{
addr = "[::1]";
port = 443;
ssl = true;
}
{
addr = "[::1]";
port = 80;
}
{
addr = "[::1]";
port = 8448;
ssl = true;
}
];
locations = {
"/" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
'';
};
"/_matrix" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
client_max_body_size 50M;
'';
};
"/_synapse/client".proxyPass = "http://localhost:8008";
};
};
"vimium.com" = {
locations."= /.well-known/matrix/server".extraConfig = (mkWellKnown matrixServerConfig);
locations."= /.well-known/matrix/client".extraConfig = (mkWellKnown matrixClientConfig);
};
};
services.matrix-synapse = {
enable = true;
settings = {
database.name = "sqlite3";
enable_registration = false;
server_name = "vimium.com";
# turn_shared_secret = "???";
# turn_uris = [
# "turn:turn.vimium.com:5349?transport=udp"
# "turn:turn.vimium.com:5350?transport=udp"
# "turn:turn.vimium.com:5349?transport=tcp"
# "turn:turn.vimium.com:5350?transport=tcp"
# ];
};
};
};
}

View File

@ -1,157 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.services.nginx;
nginxErrorPages = ''
location @error_pages {
rewrite ^.*$ /''${status}.html break;
root "/var/www/html/errors";
}
'';
nginxEdgeHeaders = ''
more_set_headers 'Server: Vimium';
more_set_headers 'Access-Control-Allow-Origin: *';
add_header Expect-CT max-age=30 always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header Vimium-Responding-Instance $hostname;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options nosniff always;
'';
nginxStrictHeaders = ''
add_header X-Frame-Options SAMEORIGIN always;
add_header Permissions-Policy "fullscreen=(self), sync-xhr=(self)" always;
'';
mkRedirect = from: to: {
"${from}" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.${from}" ];
locations."/".return = "301 https://${to}$request_uri";
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
};
};
in {
options.modules.services.nginx = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [
80 # HTTP
443 # HTTPS
];
services.nginx = {
enable = true;
package = pkgs.openresty;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
clientMaxBodySize = "2G";
sslProtocols = "TLSv1.2 TLSv1.3";
sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
appendHttpConfig = ''
error_page 400 @error_pages;
error_page 401 @error_pages;
error_page 403 @error_pages;
error_page 404 @error_pages;
error_page 405 @error_pages;
error_page 429 @error_pages;
error_page 500 @error_pages;
error_page 501 @error_pages;
error_page 502 @error_pages;
error_page 503 @error_pages;
error_page 504 @error_pages;
client_body_buffer_size 16k;
client_header_buffer_size 8k;
'';
appendConfig = ''
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 50000;
'';
eventsConfig = ''
worker_connections 20000;
multi_accept off;
'';
virtualHosts = {
## Static sites
"jellyfin.vimium.com" = {
forceSSL = true;
enableACME = true;
extraConfig = nginxErrorPages + nginxEdgeHeaders;
locations."/" = {
proxyPass = "http://localhost:8000";
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
};
"pki.vimium.com" = {
addSSL = true;
forceSSL = false;
enableACME = true;
extraConfig = ''
${nginxErrorPages}
more_set_headers 'Server: Vimium';
'';
locations."/" = {
root = "/var/www/pki.vimium.com";
};
};
"suhailhussain.com" = {
forceSSL = true;
enableACME = true;
serverAliases = [ "www.suhailhussain.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders;
locations."/" = {
root = "/var/www/suhailhussain.com";
};
};
"vimium.com" = {
default = true;
forceSSL = true;
enableACME = true;
serverAliases = [ "www.vimium.com" ];
extraConfig = nginxErrorPages + nginxEdgeHeaders + nginxStrictHeaders + ''
add_header Content-Security-Policy "default-src 'self' https://vimium.com https://www.vimium.com; style-src 'unsafe-inline'; object-src 'none'; upgrade-insecure-requests" always;
'';
locations."/" = {
root = "/var/www/vimium.com";
};
};
}
## Redirects
// (mkRedirect "h0lt.com" "jdholt.com")
// (mkRedirect "jordanholt.xyz" "jdholt.com")
// (mkRedirect "jdholt.com" "vimium.com")
// (mkRedirect "omnimagic.com" "vimium.com")
// (mkRedirect "omnimagic.net" "vimium.com")
// (mkRedirect "thelostlegend.com" "suhailhussain.com")
// (mkRedirect "vimium.co" "vimium.com")
// (mkRedirect "vimium.co.uk" "vimium.com")
// (mkRedirect "vimium.info" "vimium.com")
// (mkRedirect "vimium.net" "vimium.com")
// (mkRedirect "vimium.org" "vimium.com")
// (mkRedirect "vimium.xyz" "vimium.com");
};
};
}

View File

@ -1,57 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let cfg = config.modules.services.photoprism;
in {
options.modules.services.photoprism = {
enable = mkOption {
default = false;
example = true;
};
};
config = mkIf cfg.enable {
services.nginx = {
virtualHosts = {
"gallery.vimium.com" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.photoprism.port}";
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
};
};
};
age.secrets."passwords/services/photoprism/admin" = {
file = "${inputs.secrets}/passwords/services/photoprism/admin.age";
};
services.photoprism = {
enable = true;
address = "localhost";
passwordFile = config.age.secrets."passwords/services/photoprism/admin".path;
originalsPath = "${config.services.photoprism.storagePath}/originals";
settings = {
PHOTOPRISM_APP_NAME = "Vimium Gallery";
PHOTOPRISM_SITE_AUTHOR = "Vimium";
PHOTOPRISM_SITE_TITLE = "Vimium Gallery";
PHOTOPRISM_SITE_CAPTION = "Vimium Gallery";
PHOTOPRISM_DISABLE_TLS = "true";
PHOTOPRISM_SPONSOR = "true";
};
};
};
}

View File

@ -3,8 +3,8 @@ self: super:
gnome = super.gnome.overrideScope' (gself: gsuper: { gnome = super.gnome.overrideScope' (gself: gsuper: {
mutter = gsuper.mutter.overrideAttrs (oldAttrs: { mutter = gsuper.mutter.overrideAttrs (oldAttrs: {
src = super.fetchurl { src = super.fetchurl {
url = "https://gitlab.gnome.org/Community/Ubuntu/mutter/-/archive/triple-buffering-v4-46/mutter-triple-buffering-v4-46.tar.gz"; url = "https://gitlab.gnome.org/Community/Ubuntu/mutter/-/archive/triple-buffering-v4-45/mutter-triple-buffering-v4-45.tar.gz";
sha256 = "Rdao3TR6wG7YcpoD+nFFiCaE+97G0MreBgwsQJa3GCE="; sha256 = "tN+zQ5brk+hc+louIipqPV/Bqft42ghKOzjZZMj5Q8A=";
}; };
}); });
}); });