2 Commits

Author SHA1 Message Date
5a76f7703f flake.lock: Update
Flake lock file updates:

• Updated input 'agenix':
    'github:ryantm/agenix/457669db4259ff69d1ac1183aaa6000420940c1f' (2023-12-23)
  → 'github:ryantm/agenix/417caa847f9383e111d1397039c9d4337d024bf0' (2023-12-24)
• Updated input 'nixos-hardware':
    'github:NixOS/nixos-hardware/7763c6fd1f299cb9361ff2abf755ed9619ef01d6' (2023-12-13)
  → 'github:NixOS/nixos-hardware/a15b6e525f5737a47b4ce28445c836996fb2ea8c' (2023-12-25)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/d65bceaee0fb1e64363f7871bc43dc1c6ecad99f' (2023-12-20)
  → 'github:NixOS/nixpkgs/0b3d618173114c64ab666f557504d6982665d328' (2023-12-21)
• Updated input 'secrets':
    'git+ssh://git@git.vimium.com/jordan/nix-secrets.git?ref=refs/heads/master&rev=4ec3e87d6a7b1f14d23c12c60cad62a6e43be4ca' (2023-12-25)
  → 'git+ssh://git@git.vimium.com/jordan/nix-secrets.git?ref=refs/heads/master&rev=ef1f91b155f3bdc4efb2824ad0c47b21b8b1bbfa' (2023-12-25)
2023-12-26 00:33:08 +00:00
e642de2d19 Add WIP modules for matrix and coturn 2023-12-26 00:31:31 +00:00
53 changed files with 832 additions and 1638 deletions

View File

@ -9,16 +9,8 @@ System and user configuration for NixOS-based systems.
| **Theme:** | adwaita |
| **Terminal:** | Console |
## Provisioning
> [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) is the module used for provisioning
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).
Then run;
```
nix run github:nix-community/nixos-anywhere -- \
--disk-encryption-keys /tmp/secret.key /tmp/secret.key \
--extra-files "$temp" \
--flake .#<hostname> \
root@<ip>
```
## Quick start
1. Copy SSH keypair and `known_hosts` to `~/.ssh`
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`
1. `sudo nixos-rebuild switch --flake .#`

81
flake.lock generated
View File

@ -8,11 +8,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1707830867,
"narHash": "sha256-PAdwm5QqdlwIqGrfzzvzZubM+FXtilekQ/FA0cI49/o=",
"lastModified": 1703433843,
"narHash": "sha256-nmtA4KqFboWxxoOAA6Y1okHbZh+HsXaMPFkYHsoDRDw=",
"owner": "ryantm",
"repo": "agenix",
"rev": "8cb01a0e717311680e0cbca06a76cbceba6f3ed6",
"rev": "417caa847f9383e111d1397039c9d4337d024bf0",
"type": "github"
},
"original": {
@ -50,11 +50,11 @@
"utils": "utils"
},
"locked": {
"lastModified": 1708091384,
"narHash": "sha256-dTGGw2y8wvfjr+J9CjQbfdulOq72hUG17HXVNxpH1yE=",
"lastModified": 1703087360,
"narHash": "sha256-0VUbWBW8VyiDRuimMuLsEO4elGuUw/nc2WDeuO1eN1M=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "0a0187794ac7f7a1e62cda3dabf8dc041f868790",
"rev": "b709d63debafce9f5645a5ba550c9e0983b3d1f7",
"type": "github"
},
"original": {
@ -63,34 +63,14 @@
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1709439398,
"narHash": "sha256-MW0zp3ta7SvdpjvhVCbtP20ewRwQZX2vRFn14gTc4Kg=",
"owner": "nix-community",
"repo": "disko",
"rev": "1f76b318aa11170c8ca8c225a9b4c458a5fcbb57",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1708965002,
"narHash": "sha256-gIBZCPB0sA8Gagrxd8w4+y9uUkWBnXJBmq9Ur5BYTQU=",
"lastModified": 1703023593,
"narHash": "sha256-M+Cw6vh7xCDmIhyVuEPNmaNVUwpmdFQq8zlsXZTKees=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "4e966509c180f93ba8665cd73cad8456bf44baab",
"rev": "bad853333d9021e7012adb9b8fbfe7a7003f26bc",
"type": "github"
},
"original": {
@ -143,11 +123,11 @@
]
},
"locked": {
"lastModified": 1706981411,
"narHash": "sha256-cLbLPTL1CDmETVh4p0nQtvoF+FSEjsnJTFpTxhXywhQ=",
"lastModified": 1703367386,
"narHash": "sha256-FMbm48UGrBfOWGt8+opuS+uLBLQlRfhiYXhHNcYMS5k=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "652fda4ca6dafeb090943422c34ae9145787af37",
"rev": "d5824a76bc6bb93d1dce9ebbbcb09a9b6abcc224",
"type": "github"
},
"original": {
@ -159,11 +139,11 @@
},
"nixos-hardware": {
"locked": {
"lastModified": 1709410583,
"narHash": "sha256-esOSUoQ7mblwcsSea0K17McZuwAIjoS6dq/4b83+lvw=",
"lastModified": 1703545041,
"narHash": "sha256-nvQA+k1rSszrf4kA4eK2i/SGbzoXyoKHzzyzq/Jca1w=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "59e37017b9ed31dee303dbbd4531c594df95cfbc",
"rev": "a15b6e525f5737a47b4ce28445c836996fb2ea8c",
"type": "github"
},
"original": {
@ -188,21 +168,6 @@
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1709237383,
"narHash": "sha256-cy6ArO4k5qTx+l5o+0mL9f5fa86tYUX3ozE1S+Txlds=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1536926ef5621b09bba54035ae2bb6d806d72ac8",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1702272962,
@ -221,11 +186,11 @@
},
"nixpkgs_3": {
"locked": {
"lastModified": 1709309926,
"narHash": "sha256-VZFBtXGVD9LWTecGi6eXrE0hJ/mVB3zGUlHImUs2Qak=",
"lastModified": 1703200384,
"narHash": "sha256-q5j06XOsy0qHOarsYPfZYJPWbTbc8sryRxianlEPJN0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "79baff8812a0d68e24a836df0a364c678089e2c7",
"rev": "0b3d618173114c64ab666f557504d6982665d328",
"type": "github"
},
"original": {
@ -238,12 +203,10 @@
"inputs": {
"agenix": "agenix",
"deploy-rs": "deploy-rs",
"disko": "disko",
"firefox-gnome-theme": "firefox-gnome-theme",
"home-manager": "home-manager_2",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_3",
"nixpkgs-unstable": "nixpkgs-unstable",
"secrets": "secrets",
"thunderbird-gnome-theme": "thunderbird-gnome-theme"
}
@ -251,11 +214,11 @@
"secrets": {
"flake": false,
"locked": {
"lastModified": 1709495020,
"narHash": "sha256-eiz0qUjUbdeb6m28XPY7OVnrGMZ45JiT2dZZ0Bmq2X0=",
"lastModified": 1703545643,
"narHash": "sha256-FS/acsRQ01Gj39P1t5CQ6cKOdwADmenk//vVmpA/EgU=",
"ref": "refs/heads/master",
"rev": "d135b4d6d5f0079999188895f8b5f35e821b0d4b",
"revCount": 14,
"rev": "ef1f91b155f3bdc4efb2824ad0c47b21b8b1bbfa",
"revCount": 9,
"type": "git",
"url": "ssh://git@git.vimium.com/jordan/nix-secrets.git"
},

View File

@ -3,14 +3,8 @@
inputs = {
nixpkgs.url = "nixpkgs/nixos-23.11";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
# nixpkgs-master.url = "nixpkgs";
agenix.url = "github:ryantm/agenix";
deploy-rs.url = "github:serokell/deploy-rs";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager/release-23.11";
inputs.nixpkgs.follows = "nixpkgs";
@ -30,28 +24,21 @@
};
};
outputs = inputs @ { self, nixpkgs, nixpkgs-unstable, agenix, deploy-rs, disko, home-manager, nixos-hardware, secrets, ... }:
outputs = inputs @ { self, nixpkgs, agenix, deploy-rs, home-manager, nixos-hardware, secrets, ... }:
let
mkPkgsForSystem = system: inputs.nixpkgs;
nixpkgsForSystem = system: inputs.nixpkgs;
overlays = [
agenix.overlays.default
(import ./overlays/gnome.nix)
(
final: prev: {
unstable = import inputs.nixpkgs-unstable { system = final.system; };
custom = self.packages { system = final.system; };
}
)
];
commonModules = [
agenix.nixosModules.age
disko.nixosModules.disko
home-manager.nixosModule
./modules
];
mkNixosSystem = { system, name, extraModules ? [] }:
nixosSystem = { system, name, extraModules ? [] }:
let
nixpkgs = mkPkgsForSystem system;
nixpkgs = nixpkgsForSystem system;
lib = (import nixpkgs { inherit overlays system; }).lib;
in
inputs.nixpkgs.lib.nixosSystem {
@ -66,6 +53,9 @@
config.allowUnfree = true;
};
networking.hostName = name;
nix = {
extraOptions = "experimental-features = nix-command flakes";
};
})
./hosts/${name}
] ++ extraModules;
@ -73,47 +63,24 @@
in
{
nixosConfigurations = {
atlas = mkNixosSystem { system = "x86_64-linux"; name = "atlas"; };
eos = mkNixosSystem { system = "x86_64-linux"; name = "eos"; };
helios = mkNixosSystem { system = "x86_64-linux"; name = "helios"; };
hypnos = mkNixosSystem { system = "x86_64-linux"; name = "hypnos"; };
library = mkNixosSystem { system = "x86_64-linux"; name = "library"; };
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"; };
atlas = nixosSystem { system = "x86_64-linux"; name = "atlas"; };
eos = nixosSystem { system = "x86_64-linux"; name = "eos"; };
helios = nixosSystem { system = "x86_64-linux"; name = "helios"; };
odyssey = nixosSystem { system = "x86_64-linux"; name = "odyssey"; };
pi = nixosSystem { system = "aarch64-linux"; name = "pi"; extraModules = [ nixos-hardware.nixosModules.raspberry-pi-4 ]; };
};
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
buildInputs = [
deploy-rs.packages.x86_64-linux.deploy-rs
];
};
deploy = {
magicRollback = true;
autoRollback = true;
deploy.nodes.pi = {
hostname = "10.0.1.191";
sshUser = "root";
nodes = {
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;
# };
# };
profiles.system = {
user = "root";
path = deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.pi;
};
};
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
];
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking = {
hostId = "8425e349";
networkmanager.enable = true;
};
networking.hostName = "atlas";
networking.hostId = "8425e349";
networking.networkmanager.enable = true;
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
modules = {
desktop = {
@ -42,20 +48,9 @@
gpg.enable = true;
pass.enable = true;
};
services = {
borgmatic = {
enable = true;
directories = [
"/home/jordan/Documents"
];
repoPath = "ssh://uzu2y5b1@uzu2y5b1.repo.borgbase.com/./repo";
};
};
shell = {
git.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;
allowed-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, ... }:
{
imports = [
./common.nix
];
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";
services.printing.enable = true;
services.openssh.startWhenNeeded = true;
services.openssh = {
enable = true;
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
PermitRootLogin = "no";
};
startWhenNeeded = true;
};
sound.enable = true;
hardware.pulseaudio.enable = false;
@ -18,11 +39,10 @@
pulse.enable = true;
};
fileSystems."/mnt/library" = {
device = "library.mesh.vimium.net:/mnt/library";
fsType = "nfs";
options = [ "nfsvers=4.2" "soft" "nocto" "ro" "x-systemd.automount" "noauto" ];
};
environment.systemPackages = with pkgs; [
git
neovim
];
system.autoUpgrade = {
enable = true;
@ -30,8 +50,29 @@
randomizedDelaySec = "10min";
};
modules = {
desktop.gnome.enable = true;
networking.tailscale.enable = true;
nix = {
settings = {
connect-timeout = 5;
log-lines = 25;
min-free = 128000000;
max-free = 1000000000;
fallback = true;
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";
};
};
modules.desktop.gnome.enable = true;
modules.networking.tailscale.enable = true;
}

View File

@ -6,15 +6,22 @@
../desktop.nix
];
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking = {
hostId = "cc858347";
networkmanager.enable = true;
};
networking.hostName = "eos";
networking.hostId = "cc858347";
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 = {
"org/gnome/desktop/interface" = {
@ -44,6 +51,4 @@
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -15,10 +15,20 @@
};
networking = {
hostName = "helios";
hostId = "47d23505";
networkmanager.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
users.defaultUserShell = pkgs.zsh;
system.stateVersion = "22.11";
modules = {
desktop = {
apps.qbittorrent.enable = true;
@ -50,6 +60,4 @@
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

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,43 +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;
};
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,27 +0,0 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
initrd.kernelModules = [ ];
kernelModules = [ "applesmc" "kvm-intel" "wl" ];
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;
nvidia = {
modesetting.enable = true;
powerManagement.enable = true;
};
};
}

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,175 +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
];
interfaces."podman+" = {
allowedUDPPorts = [ 53 ];
allowedTCPPorts = [ 53 ];
};
};
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 = {
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;
}

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 = [
./hardware-configuration.nix
./audio.nix
../desktop.nix
];
boot.loader = {
systemd-boot = {
enable = true;
graceful = true;
netbootxyz.enable = true;
};
efi.canTouchEfiVariables = true;
boot.loader.systemd-boot = {
enable = true;
graceful = true;
netbootxyz.enable = true;
};
boot.loader.efi.canTouchEfiVariables = true;
networking = {
hostId = "c5e68d78";
networkmanager.enable = true;
firewall.trustedInterfaces = [ "lxdbr0" "virbr0" ]; # Work around https://github.com/NixOS/nixpkgs/issues/263359
};
networking.hostName = "odyssey";
networking.hostId = "c5e68d78";
networking.networkmanager.enable = true;
virtualisation = {
libvirtd.enable = true;
lxd.enable = true;
};
nix.package = pkgs.nixFlakes;
nix.extraOptions = ''
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 = {
enable = true;
@ -48,12 +59,8 @@
firefox.enable = true;
};
gaming.emulators = {
gamecube.enable = true;
ps2.enable = true;
ps3.enable = true;
psp.enable = true;
wii.enable = true;
xbox.enable = true;
};
media.graphics = {
modeling.enable = true;
@ -72,7 +79,6 @@
neovim.enable = true;
vscode.enable = true;
};
hardware.presonus-studio.enable = true;
security = {
gpg.enable = true;
pass.enable = true;
@ -91,6 +97,4 @@
zsh.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

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

View File

@ -16,10 +16,3 @@ SD card | `/dev/mmcblk0` (ext4, NixOS Root)
### Networks
- DHCP on `10.0.1.0/24` subnet.
- 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 = {
enable = true;
filter = "*rpi-4-*.dtb";
overlays = [
{
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>;
};
};
};
'';
}
{ name = "hifiberry-digi-pro"; dtboFile = "${pkgs.device-tree_rpi.overlays}/hifiberry-digi-pro.dtbo"; }
];
};
firmware = with pkgs; [
@ -105,66 +35,25 @@
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
systemWide = true;
};
age.secrets."files/services/home-assistant/secrets.yaml" = {
file = "${inputs.secrets}/files/services/home-assistant/secrets.yaml.age";
path = "${config.services.home-assistant.configDir}/secrets.yaml";
owner = "hass";
group = "hass";
};
services.home-assistant = {
enable = true;
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;
};
virtualisation.oci-containers = {
backend = "podman";
containers.homeassistant = {
volumes = [ "home-assistant:/config" ];
environment.TZ = config.time.timeZone;
image = "ghcr.io/home-assistant/home-assistant:stable";
extraOptions = [
"--network=host"
"--device=/dev/ttyUSB0:/dev/ttyUSB0"
];
};
};
services.mosquitto = {
enable = true;
listeners = [{
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
port = 1883;
settings = {
allow_anonymous = true;
@ -180,17 +69,10 @@
};
services.zigbee2mqtt = {
package = pkgs.unstable.zigbee2mqtt;
enable = true;
dataDir = "/var/lib/zigbee2mqtt";
settings = {
homeassistant = lib.optionalAttrs config.services.home-assistant.enable {
discovery_topic = "homeassistant";
status_topic = "hass/status";
legacy_entity_attributes = true;
legacy_triggers = true;
};
availability = true;
homeassistant = true;
frontend = true;
device_options = {
retain = true;
@ -203,7 +85,6 @@
network_key = "!secret.yaml network_key";
pan_id = 13001;
ext_pan_id = [ 79 1 73 47 250 136 124 222 ];
transmit_power = 20;
};
mqtt = {
version = 5;
@ -231,16 +112,7 @@
};
};
# Connection to ONKYO HT-R990
networking.interfaces.end0 = {
ipv4.addresses = [{
address = "172.16.0.1";
prefixLength = 30;
}];
};
environment.systemPackages = with pkgs; [
python311Packages.onkyo-eiscp
libraspberrypi
raspberrypi-eeprom
];

View File

@ -1,20 +1,47 @@
{ config, lib, pkgs, ... }:
{
imports = [
./common.nix
];
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";
documentation.enable = false;
security = {
acme.acceptTerms = true;
auditd.enable = true;
audit = {
enable = true;
rules = [
"-a exit,always -F arch=b64 -S execve"
];
services.openssh = {
enable = true;
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
environment.systemPackages = with pkgs; [
git
neovim
];
nix = {
settings = {
auto-optimise-store = true;
};
gc = {
automatic = true;
dates = "weekly";
options = "-d --delete-older-than 7d";
};
};

View File

@ -1,18 +0,0 @@
# vps1
## Overview
VPS 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: `vps1.mesh.vimium.net`.

View File

@ -1,69 +0,0 @@
{ config, lib, pkgs, inputs, ... }:
{
imports = [
./hardware-configuration.nix
../server.nix
];
networking = {
hostId = "08bf6db3";
domain = "mesh.vimium.net";
firewall = {
enable = true;
allowedTCPPorts = [
22 # SSH
];
};
};
users = {
users = {
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"
];
};
};
groups = {
jellyfin = { };
};
};
services.openssh.settings.PermitRootLogin = lib.mkForce "prohibit-password";
security.acme.defaults = {
email = "hostmaster@vimium.com";
group = "nginx";
webroot = "/var/lib/acme/acme-challenge";
};
modules = {
services = {
borgmatic = {
enable = true;
directories = [
"/home"
"/var/lib"
"/var/www"
];
repoPath = "ssh://p91y8oh7@p91y8oh7.repo.borgbase.com/./repo";
};
coturn.enable = true;
gitea.enable = true;
headscale.enable = true;
matrix-synapse.enable = true;
nginx.enable = true;
};
};
system.stateVersion = "22.11";
}

View File

@ -1,26 +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.device = "/dev/sda";
tmp.cleanOnBoot = true;
};
zramSwap.enable = true;
fileSystems = {
"/" = {
device = "/dev/sda1";
fsType = "ext4";
};
};
}

View File

@ -25,17 +25,13 @@
./dev/zig.nix
./editors/neovim
./editors/vscode.nix
./hardware/presonus-studio.nix
./networking/tailscale.nix
./networking/wireless.nix
./security/gpg.nix
./security/pass.nix
./services/borgmatic
./services/coturn
./services/gitea
./services/headscale
./services/matrix-synapse
./services/nginx
./services/matrix
./shell/git
./shell/zsh
];

View File

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

View File

@ -17,7 +17,6 @@ in {
};
services.flatpak.enable = true;
services.fwupd.enable = true;
programs.dconf.enable = true;
dconf.settings = {
@ -103,12 +102,6 @@ in {
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.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" = {
show-hidden = true;
sort-directories-first = true;
@ -138,13 +131,12 @@ in {
};
"org/gnome/mutter" = {
center-new-windows = true;
edge-tiling = true;
experimental-features = [ "scale-monitor-framebuffer" ];
};
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
enable-hot-corners = false;
monospace-font-name = "UbuntuMono Nerd Font 11";
monospace-font-name = "Ubuntu Mono 11";
};
"org/gnome/desktop/wm/keybindings" = {
switch-group = [ "<Super>grave" ];
@ -157,33 +149,16 @@ in {
fonts.packages = with pkgs; [
noto-fonts
(nerdfonts.override { fonts = [ "BigBlueTerminal" "ComicShannsMono" "UbuntuMono" ]; })
ubuntu_font_family
];
user.packages = with pkgs; [
authenticator
bottles
bustle
celluloid
d-spy
drawing
fragments
gnome.ghex
# gnome-builder
gnome-decoder
gnome-firmware
gnome-frog
gnome-obfuscate
gnome-podcasts
identity
mission-center
newsflash
schemes
shortwave
];
environment.systemPackages = with pkgs; [
adw-gtk3
bind
bmon
fd
@ -219,7 +194,6 @@ in {
# gnomeExtensions.worksets
# gnomeExtensions.workspace-matrix
iotop
unstable.morewaita-icon-theme
ripgrep
rsync
tcpdump

View File

@ -2,6 +2,7 @@
let
cfg = config.modules.editors.neovim;
dev = config.modules.dev;
in {
options.modules.editors.neovim = {
enable = lib.mkOption {
@ -11,15 +12,124 @@ in {
};
config = lib.mkIf cfg.enable {
user.packages = with pkgs.unstable; [
lunarvim
];
user.packages = with pkgs; [
(neovim.override {
configure = {
customRC = ''
luafile ~/.config/nvim/init.lua
'';
packages.myPlugins = with pkgs.vimPlugins; {
start = [
(nvim-treesitter.withPlugins (
plugins: with plugins; [
bash
c
cmake
cpp
css
dockerfile
elm
glsl
graphql
haskell
http
html
java
javascript
jsdoc
json
json5
latex
lua
markdown
ninja
nix
org
perl
php
pug
python
regex
rst
ruby
rust
scala
scss
toml
tsx
typescript
vim
yaml
zig
]
))
nvim-treesitter-context
nvim-treesitter-textobjects
nvim-lspconfig
];
};
};
})
] ++
env.EDITOR = "lvim";
# Install appropriate language servers
(if dev.cc.enable then [
ccls # C/C++
] else []) ++
(if dev.java.enable then [
java-language-server # Java
ltex-ls # LaTeX
] else []) ++
(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 []);
home.configFile = {
"nvim/init.lua".source = ./init.lua;
"nvim/lua" = { source = ./lua; recursive = true; };
"nvim/lua/config/lsp.lua".text = ''
-- This file is autogenerated, do not edit.
${if dev.cc.enable then "require('config.lsp.cc')\n" else ""}
${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 ""}
${if dev.python.enable then "require('config.lsp.python')\n" else ""}
${if dev.rust.enable then "require('config.lsp.rust')\n" else ""}
${if dev.scala.enable then "require('config.lsp.scala')\n" else ""}
${if dev.zig.enable then "require('config.lsp.zig')\n" else ""}
'';
};
env.EDITOR = "nvim";
environment.shellAliases = {
vim = "lvim";
v = "lvim";
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,69 +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)
];
environment.etc = {
"pipewire/pipewire.conf.d/10-network.conf".text = ''
context.modules = [
{
name = libpipewire-module-rtp-session
args = {
stream.props = {
node.name = "rtp-source"
}
}
}
]
'';
"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

@ -26,35 +26,11 @@ in {
wireless = {
enable = true;
interfaces = cfg.interfaces;
environmentFile = config.age.secrets."passwords/networks".path;
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

@ -39,11 +39,15 @@ in {
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;
storage = {
encryption_passcommand = "cat ${config.age.secrets."passwords/services/borg/${hostname}-passphrase".path}";
ssh_command = "ssh -i /etc/ssh/ssh_host_ed25519_key";
};
retention = {
keep_daily = 7;
keep_weekly = 4;
keep_monthly = 6;
};
};
};

View File

@ -4,6 +4,7 @@ with lib;
let
cfg = config.modules.services.coturn;
domain = "vimium.com";
in {
options.modules.services.coturn = {
enable = mkOption {
@ -12,7 +13,11 @@ in {
};
};
config = mkIf cfg.enable {
config = {
age.secrets."passwords/services/coturn/secret" = {
file = "${inputs.secrets}/passwords/services/coturn/secret.age";
};
networking.firewall = {
allowedTCPPorts = [
5349 # STUN TLS
@ -23,24 +28,12 @@ in {
];
};
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";
static-auth-secret = ""; # TODO: Pass as extraConfig
realm = "turn.${domain}";
relay-ips = [
"198.244.190.160"
];
@ -51,10 +44,16 @@ in {
no-multicast-peers
'';
secure-stun = true;
cert = "/var/lib/acme/turn.vimium.com/fullchain.pem";
pkey = "/var/lib/acme/turn.vimium.com/key.pem";
cert = "/var/lib/acme/turn.${domain}/fullchain.pem";
pkey = "/var/lib/acme/turn.${domain}/key.pem";
min-port = 49152;
max-port = 49999;
};
security.acme.certs = {
"turn.${domain}" = {
reloadServices = [ "coturn" ];
};
};
};
}

View File

@ -1,83 +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";
};
};
};
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 = {
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";
};
};
};
}

View File

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

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

@ -0,0 +1,120 @@
{ config, lib, pkgs, inputs, ... }:
with lib;
let
cfg = config.modules.services.matrix;
domain = "vimium.com";
clientConfig = {
"m.homeserver" = {
base_url = "https://matrix.${domain}";
server_name = domain;
};
"m.identity_server" = {};
};
serverConfig."m.server" = "matrix.${domain}:443";
mkWellKnown = data: ''
more_set_headers 'Content-Type: application/json';
return 200 '${builtins.toJSON data}';
'';
in {
options.modules.services.matrix = {
enable = mkOption {
default = false;
example = true;
};
coturn = mkOption {
default = config.services.coturn.enable;
example = true;
};
elementWeb = mkOption {
default = true;
example = true;
};
};
config = mkIf cfg.enable {
networking.firewall = {
allowedTCPPorts = [
8448 # Matrix federation
];
};
services.nginx = {
virtualHosts = {
"${domain}" = {
# Assume this listener is already setup
locations."= /.well-known/matrix/server".extraConfig = (mkWellKnown serverConfig);
locations."= /.well-known/matrix/client".extraConfig = (mkWellKnown clientConfig);
};
"matrix.${domain}" = {
forceSSL = true;
useACMEHost = "matrix.${domain}";
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 ${services.matrix-synapse.settings.max_upload_size};
'';
};
"/_synapse/client".proxyPass = "http://localhost:8008";
};
};
"chat.${domain}" = mkIf cfg.elementWeb {
forceSSL = true;
useACMEHost = "matrix.${domain}";
root = pkgs.element-web.override {
conf = {
default_server_config = clientConfig;
brand = "Vimium Chat";
branding = {
auth_header_logo_url = "https://vimium.com/images/logo.svg";
auth_footer_links = [
{ text = "Vimium.com"; url = "https://www.vimium.com"; }
];
};
};
};
};
};
};
services.matrix-synapse = {
enable = true;
settings = {
database.name = "sqlite3";
enable_registration = false;
server_name = domain;
turn_shared_secret_file = mkIf cfg.coturn config.age.secrets."passwords/services/coturn/secret".path;
turn_uris = mkIf cfg.coturn [
"turn:${config.services.coturn.realm}:5349?transport=udp"
"turn:${config.services.coturn.realm}:5350?transport=udp"
"turn:${config.services.coturn.realm}:5349?transport=tcp"
"turn:${config.services.coturn.realm}:5350?transport=tcp"
];
};
};
security.acme.certs = {
"matrix.${domain}" = {
extraDomainNames = mkIf cfg.elementWeb [ "chat.${domain}" ];
reloadServices = [ "matrix-synapse" ];
};
};
};
}

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");
};
};
}