Compare commits

...

2 commits

Author SHA1 Message Date
chayleaf 33b4fe95c2 add server config 2023-05-11 05:33:08 +07:00
chayleaf 8655459e46 update inputs
sway doesn't work with vulkan anymore, so make vulkan sway an option
2023-05-10 16:42:56 +07:00
28 changed files with 1266 additions and 145 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
private.nix
private/

View file

@ -23,11 +23,11 @@
"pinned": false,
"src": {
"name": null,
"sha256": "sha256-tPL8d5fJzT428UJImJgzW9ECI+ENkvbD1fCPmjU7Yhk=",
"sha256": "sha256-gof4yL5sHPKXDC4mDfPyBIvPtWxxxVy6gHx58yoTEbQ=",
"type": "url",
"url": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-54/GE-Proton7-54.tar.gz"
"url": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton8-2/GE-Proton8-2.tar.gz"
},
"version": "GE-Proton7-54"
"version": "GE-Proton8-2"
},
"yomichan": {
"cargoLocks": null,

View file

@ -11,10 +11,10 @@
};
proton-ge = {
pname = "proton-ge";
version = "GE-Proton7-54";
version = "GE-Proton8-2";
src = fetchurl {
url = "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-54/GE-Proton7-54.tar.gz";
sha256 = "sha256-tPL8d5fJzT428UJImJgzW9ECI+ENkvbD1fCPmjU7Yhk=";
url = "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton8-2/GE-Proton8-2.tar.gz";
sha256 = "sha256-gof4yL5sHPKXDC4mDfPyBIvPtWxxxVy6gHx58yoTEbQ=";
};
};
yomichan = {

View file

@ -324,8 +324,10 @@ in
};
menu = "${rofiSway}/bin/rofi -show drun";
}; in commonConfig // swayConfig;
extraSessionCommands = ''
# export WLR_RENDERER=vulkan
extraSessionCommands = (lib.optionalString config.wayland.windowManager.sway.vulkan ''
export WLR_RENDERER=vulkan
'') + ''
export SDL_VIDEODRIVER=wayland,x11,kmsdrm,windows,directx
# SDL3
export SDL_VIDEO_DRIVER=wayland,x11,kmsdrm,windows

View file

@ -1,4 +1,4 @@
{ config, pkgs, lib, ... }:
{ config, pkgs, lib, notlua, ... }:
{
imports = [ ./options.nix ];
/*
@ -14,9 +14,8 @@
# welcome to my cursed DSL
programs.neovim = let
notlua = config.notlua;
notlua-nvim = notlua.neovim { inherit (config.programs.neovim) plugins extraLuaPackages; };
inherit (notlua.keywords) CALL PROP SET LET DEFUN IF APPLY OR EQ RETURN ELSE IDX MCALL LETREC;
inherit (notlua.keywords) CALL PROP SET LET DEFUN IF APPLY OR EQ RETURN ELSE IDX LETREC;
inherit (notlua.utils) compile;
inherit (notlua-nvim.stdlib) vim string require print;
inherit (notlua-nvim.keywords) REQ REQ';
@ -294,11 +293,14 @@
ps.cmp_luasnip
ps.cmp-nvim-lsp
{ plugin = ps.nvim-autopairs;
config = compile "nvim_autopairs" (LET (REQ "nvim-autopairs.completion.cmp") (REQ "nvim-autopairs") (cmp-autopairs: nvim-autopairs: L [
config = compile "nvim_autopairs" (LET
(REQ "cmp") (REQ "nvim-autopairs.completion.cmp") (REQ "nvim-autopairs")
(cmp: cmp-autopairs: nvim-autopairs:
L [
nvim-autopairs.setup {
disable_filetype = [ "TelescopePrompt" "vim" ];
} _
MCALL cmp.event "on" "confirm_done" (cmp-autopairs.on_confirm_done {}) _
cmp.event.on cmp.event "confirm_done" (cmp-autopairs.on_confirm_done {}) _
])); }
{ plugin = ps.comment-nvim;
config = compile' "comment_nvim" [

View file

@ -10,10 +10,15 @@ with lib; {
};
};
};
options.wayland.windowManager.sway.vulkan = mkOption {
type = types.bool;
default = false;
description = "set WLR_RENDERER to vulkan";
};
options.terminals = mkOption {
type = with types; listOf str;
description = "terminal kinds (possible values are alacritty, urxvt, kitty, foot)";
default = ["alacritty"];
default = [ "alacritty" ];
};
options.terminalBin = mkOption {
type = types.str;

View file

@ -15,6 +15,7 @@ in {
terminalBin = getTerminalBin (builtins.head config.terminals);
terminalBinX = getTerminalBin (lib.lists.findFirst (term: term != "foot") null config.terminals);
colors = {
# dont forget to change waybar.css (yes I'm lazy like that)
base = [
"523b3f" # black
"e66e6e" # red
@ -35,8 +36,7 @@ in {
];
foreground = "ebdadd";
background = "24101a";
# 0.75 with opengl sway
alpha = 0.95;
alpha = if config.wayland.windowManager.sway.vulkan then 0.97 else 0.85;
};
programs.tmux.shell = shell;
programs.alacritty = {

View file

@ -1,4 +1,4 @@
@define-color bg rgba(36, 16, 26, /*.75*/ .95); /*#24101ac0;*/
@define-color bg rgba(36, 16, 26, .75); /*#24101ac0;*/
@define-color blue #87e5cf;
@define-color green #8cbf73;
@define-color yellow #ebbe5f;

View file

@ -4,15 +4,14 @@
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"utils": "utils"
]
},
"locked": {
"lastModified": 1680597706,
"narHash": "sha256-ZqJ3T+BxzjPH9TnmeUwS4Uu9ZQPeBXAFC9sUWlharT4=",
"lastModified": 1683651229,
"narHash": "sha256-HN0Mw8g1XQIrcdyzqT00YW0Uqi/V/BUUUAgvcK1pcSM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "ec06f419af79207b33d797064dfb3fc9dbe1df4a",
"rev": "983f8a1bb965b261492123cd8e2d07da46d4d50a",
"type": "github"
},
"original": {
@ -28,11 +27,11 @@
]
},
"locked": {
"lastModified": 1680655986,
"narHash": "sha256-u6gs9B6ckuL3dXjI/LdATeXltEh04DYxCk6vZtF/WEs=",
"lastModified": 1683465499,
"narHash": "sha256-7dufJBJ/AY4vd5x+2kR9Xj39ydmFf9JhzoDAF/NxeLM=",
"owner": "fufexan",
"repo": "nix-gaming",
"rev": "9ba4a24198646582e208ec8cdf5e8324be23e2d7",
"rev": "6e2819c51586b34106360e261bad1e1c4d4f783b",
"type": "github"
},
"original": {
@ -43,10 +42,10 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1680669251,
"narHash": "sha256-AVNE+0u4HlI3v96KCXE9risH7NKqj0QDLLfSckYXIbA=",
"path": "/nix/store/qw9nnl2wmvx0ad0f9aqvdbw5cl5mirvc-source",
"rev": "9c8ff8b426a8b07b9e0a131ac3218740dc85ba1e",
"lastModified": 1683408522,
"narHash": "sha256-9kcPh6Uxo17a3kK3XCHhcWiV1Yu1kYj22RHiymUhMkU=",
"path": "/nix/store/zjpd6dn9kza8zl3l17cwgyifsxbvi3nb-source",
"rev": "897876e4c484f1e8f92009fd11b7d988a121a4e7",
"type": "path"
},
"original": {
@ -61,11 +60,11 @@
]
},
"locked": {
"lastModified": 1682122379,
"narHash": "sha256-AxO/KWnMuxTA/WrRitIwUJzc7F90BPjxdej6jLJi0So=",
"lastModified": 1682202201,
"narHash": "sha256-3r5izcrgfO2RxV1gU7aWQnGAky5Ek3wyzM+9eQtG4M4=",
"owner": "chayleaf",
"repo": "notlua",
"rev": "5b8280bc82fd0b4624af9256388f0f7804a1bb4d",
"rev": "cd89a08083cc43a07ac1f6ced0594fa7f49c5cf2",
"type": "github"
},
"original": {
@ -77,11 +76,11 @@
},
"nur": {
"locked": {
"lastModified": 1680758135,
"narHash": "sha256-gmTwQ6VHbXAfXbBgeqXZyyuEb0Hhroi8IOM/nokBOwM=",
"lastModified": 1683707801,
"narHash": "sha256-fEoovtx4OXwftUoiRTnPP+dCDJKUE3KXO/rKxNqueQ8=",
"owner": "nix-community",
"repo": "NUR",
"rev": "9570cfc60f7ca32fdcdc4292f1e24ea5c62977bd",
"rev": "c524842d10fe65f19e0bb544b39d805e0b5d6d8e",
"type": "github"
},
"original": {
@ -98,21 +97,6 @@
"notlua": "notlua",
"nur": "nur"
}
},
"utils": {
"locked": {
"lastModified": 1678901627,
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",

View file

@ -51,10 +51,10 @@
];
};
extraSpecialArgs = {
notlua = notlua.lib.${system};
# pkgs-wayland = nixpkgs-wayland.packages.${system};
};
modules = [
notlua.nixosModules.default
nur.nixosModules.nur
./hosts/nixmsi.nix
(getPriv "nixmsi")

View file

@ -13,9 +13,9 @@ in
clang-tools_latest = pkgs.clang-tools_15;
clang_latest = pkgs.clang_15;
home-daemon = callPackage ./home-daemon { };
ghidra = pkgs.ghidra.overrideAttrs (old: {
/*ghidra = pkgs.ghidra.overrideAttrs (old: {
patches = old.patches ++ [ ./ghidra-stdcall.patch ];
});
});*/
lalrpop = callPackage ./lalrpop { };
# pin version
looking-glass-client = pkgs.looking-glass-client.overrideAttrs (old: {

View file

@ -1,12 +1,47 @@
{
"nodes": {
"flake-utils": {
"blobs": {
"flake": false,
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"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"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1668681692,
"narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "009399224d5e398d03b22badca40a37ac85412a1",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
@ -32,11 +67,11 @@
},
"impermanence": {
"locked": {
"lastModified": 1675359654,
"narHash": "sha256-FPxzuvJkcO49g4zkWLSeuZkln54bLoTtrggZDJBH90I=",
"lastModified": 1682268411,
"narHash": "sha256-ICDKQ7tournRVtfM8C2II0qHiOZOH1b3dXVOCsgr11o=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "6138eb8e737bffabd4c8fc78ae015d4fd6a7e2fd",
"rev": "df1692e2d9f1efc4300b1ea9201831730e0b817d",
"type": "github"
},
"original": {
@ -52,11 +87,11 @@
]
},
"locked": {
"lastModified": 1680655986,
"narHash": "sha256-u6gs9B6ckuL3dXjI/LdATeXltEh04DYxCk6vZtF/WEs=",
"lastModified": 1683465499,
"narHash": "sha256-7dufJBJ/AY4vd5x+2kR9Xj39ydmFf9JhzoDAF/NxeLM=",
"owner": "fufexan",
"repo": "nix-gaming",
"rev": "9ba4a24198646582e208ec8cdf5e8324be23e2d7",
"rev": "6e2819c51586b34106360e261bad1e1c4d4f783b",
"type": "github"
},
"original": {
@ -67,11 +102,11 @@
},
"nixos-hardware": {
"locked": {
"lastModified": 1680070330,
"narHash": "sha256-aoT2YZCd9LEtiEULFLIF0ykKydgE72X8gw/k9/pRS5I=",
"lastModified": 1683269598,
"narHash": "sha256-KNsb+nBbB1Fmxd07dt4E0KXMT4YeKJB7gQaA6Xfk+mo=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "a6aa8174fa61e55bd7e62d35464d3092aefe0421",
"rev": "51559e691f1493a26f94f1df1aaf516bb507e78b",
"type": "github"
},
"original": {
@ -80,13 +115,39 @@
"type": "github"
}
},
"nixos-mailserver": {
"inputs": {
"blobs": "blobs",
"flake-compat": "flake-compat",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-22_11": [
"nixpkgs"
],
"utils": "utils"
},
"locked": {
"lastModified": 1671738303,
"narHash": "sha256-PRgqtaWf2kMSYqVmcnmhTh+UsC0RmvXRTr+EOw5VZUA=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "6d0d9fb966cc565a3df74d3b686f924c7615118c",
"type": "gitlab"
},
"original": {
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"type": "gitlab"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1680669251,
"narHash": "sha256-AVNE+0u4HlI3v96KCXE9risH7NKqj0QDLLfSckYXIbA=",
"lastModified": 1683408522,
"narHash": "sha256-9kcPh6Uxo17a3kK3XCHhcWiV1Yu1kYj22RHiymUhMkU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9c8ff8b426a8b07b9e0a131ac3218740dc85ba1e",
"rev": "897876e4c484f1e8f92009fd11b7d988a121a4e7",
"type": "github"
},
"original": {
@ -101,9 +162,10 @@
"impermanence": "impermanence",
"nix-gaming": "nix-gaming",
"nixos-hardware": "nixos-hardware",
"nixos-mailserver": "nixos-mailserver",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay",
"utils": "utils"
"utils": "utils_2"
}
},
"rust-overlay": {
@ -114,11 +176,11 @@
]
},
"locked": {
"lastModified": 1680747499,
"narHash": "sha256-E9rcxSTsqRqNd4SD+D/4aqm3qfFyVw0S9YseCks7h+c=",
"lastModified": 1683708507,
"narHash": "sha256-i5zgWcuyZcNBnlrzVjhpAFQdJWr4OyhvQ1owAEHFFKw=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "8ad3b5ee01a2074b54274216ff2cf0ab844a7426",
"rev": "ed55dc022aa23ed3c42f383cf1782290b3b939d5",
"type": "github"
},
"original": {
@ -127,7 +189,37 @@
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"utils": {
"locked": {
"lastModified": 1605370193,
"narHash": "sha256-YyMTf3URDL/otKdKgtoMChu4vfVL3vCMkRqpGifhUn0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5021eac20303a61fafe17224c087f5519baed54d",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"utils_2": {
"inputs": {
"flake-utils": "flake-utils_2"
},

View file

@ -15,14 +15,25 @@
url = "github:fufexan/nix-gaming";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-mailserver = {
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
inputs.nixpkgs.follows = "nixpkgs";
inputs.nixpkgs-22_11.follows = "nixpkgs";
};
};
outputs = inputs@{ self, nixpkgs, utils, nixos-hardware, impermanence, nix-gaming, ... }:
outputs = inputs@{ self, nixpkgs, utils, nixos-hardware, impermanence, nix-gaming, nixos-mailserver, ... }:
let
hw = nixos-hardware.nixosModules;
# IRL-related stuff I'd rather not put into git
priv = if builtins.pathExists ./private.nix then (import ./private.nix) else { };
getPriv = (hostname: with builtins; if hasAttr hostname priv then getAttr hostname priv else { });
priv = if builtins.pathExists ./private/default.nix then (import ./private)
else if builtins.pathExists ./private.nix then (import ./private.nix)
else { };
getPriv = hostname: with builtins; if hasAttr hostname priv then getAttr hostname priv else { };
common = hostname: [ (getPriv hostname) impermanence.nixosModule ];
extraArgs = {
inherit nixpkgs;
};
in utils.lib.mkFlake {
inherit self inputs;
hostDefaults.modules = [
@ -44,18 +55,24 @@
system = "x86_64-linux";
modules = [
./hosts/nixmsi.nix
impermanence.nixosModule
nix-gaming.nixosModules.pipewireLowLatency
hw.common-pc-ssd # enables fstrim
hw.common-cpu-amd # microcode
hw.common-cpu-amd-pstate # amd-pstate
hw.common-gpu-amd # configures drivers
hw.common-pc-laptop # enables tlp
(getPriv "nixmsi")
];
extraArgs = {
inherit nixpkgs;
};
] ++ common "nixmsi";
inherit extraArgs;
};
nixserver = {
system = "x86_64-linux";
modules = [
./hosts/nixserver
nixos-mailserver.nixosModules.default
hw.common-pc-hdd
hw.common-cpu-intel
] ++ common "nixserver";
inherit extraArgs;
};
};
};

View file

@ -9,6 +9,27 @@ let
dataPart = "/dev/disk/by-uuid/f1447692-fa7c-4bd6-9cb5-e44c13fddfe3";
datarootUuid = "fa754b1e-ac83-4851-bf16-88efcd40b657";
dataroot = "/dev/disk/by-uuid/${datarootUuid}";
/*
# for old kernel versions
zenKernels = pkgs.callPackage "${nixpkgs}/pkgs/os-specific/linux/kernel/zen-kernels.nix";
zenKernel = (version: sha256: (zenKernels {
kernelPatches = [
pkgs.linuxKernel.kernelPatches.bridge_stp_helper
pkgs.linuxKernel.kernelPatches.request_key_helper
];
argsOverride = {
src = pkgs.fetchFromGitHub {
owner = "zen-kernel";
repo = "zen-kernel";
rev = "v${version}-zen1";
inherit sha256;
};
inherit version;
modDirVersion = lib.versions.pad 3 "${version}-zen1";
};
}).zen);
zenKernelPackages = version: sha256: pkgs.linuxPackagesFor (zenKernel version sha256);
*/
in {
system.stateVersion = "22.11";
@ -45,6 +66,11 @@ in {
"resume_offset=533760"
"fbcon=font:TER16x32"
"consoleblank=60"
# disable PSR to *hopefully* avoid random hangs
# this one didnt help
"amdgpu.dcdebugmask=0x10"
# maybe this one will?
"amdgpu.noretry=0"
];
loader = {
grub = {
@ -65,29 +91,12 @@ in {
"vm.swappiness" = 40;
};
kernelPackages = lib.mkDefault pkgs.linuxPackages_zen;
/*kernelPackages = zenKernelPackages "6.1.9" "0fsmcjsawxr32fxhpp6sgwfwwj8kqymy0rc6vh4qli42fqmwdjgv";*/
};
# for testing different zen kernel versions:
# specialisation = let
# zenKernels = pkgs.callPackage "${nixpkgs}/pkgs/os-specific/linux/kernel/zen-kernels.nix";
# zenKernel = (version: sha256: (zenKernels {
# kernelPatches = [
# pkgs.linuxKernel.kernelPatches.bridge_stp_helper
# pkgs.linuxKernel.kernelPatches.request_key_helper
# ];
# argsOverride = {
# src = pkgs.fetchFromGitHub {
# owner = "zen-kernel";
# repo = "zen-kernel";
# rev = "v${version}-zen1";
# inherit sha256;
# };
# inherit version;
# modDirVersion = lib.versions.pad 3 "${version}-zen1";
# };
# }).zen);
# in {
# zen619.configuration.boot.kernelPackages = pkgs.linuxPackagesFor (zenKernel "6.1.9" "0fsmcjsawxr32fxhpp6sgwfwwj8kqymy0rc6vh4qli42fqmwdjgv");
# specialisation = {
# zen619.configuration.boot.kernelPackages = zenKernelPackages "6.1.9" "0fsmcjsawxr32fxhpp6sgwfwwj8kqymy0rc6vh4qli42fqmwdjgv";
# };
nixpkgs.config.allowUnfreePredicate = pkg: (lib.getName pkg) == "steam-original";
@ -99,6 +108,12 @@ in {
opengl.extraPackages = with pkgs; [ vulkan-validation-layers ];
};
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
};
services.tlp.enable = true;
services.tlp.settings = {
USB_EXCLUDE_PHONE = 1;
START_CHARGE_THRESH_BAT0 = 75;
@ -197,7 +212,6 @@ in {
++ (lib.range 1714 1764);
networking.firewall.allowedUDPPorts = lib.range 1714 1764;
# networking.hostName = "nixmsi";
networking.wireless.iwd.enable = true;
#networking.networkmanager.enable = true;
@ -235,9 +249,14 @@ in {
# I couldn't get lightdm to start sway, so let's just do this
displayManager.startx.enable = true;
windowManager.i3.enable = true;
};*/
};
*/
programs.sway.enable = true;
programs.firejail.enable = true;
# doesn't work:
# programs.wireshark.enable = true;
# users.groups.wireshark.members = [ "user "];
environment.systemPackages = with pkgs; [
vim
wget
@ -312,17 +331,6 @@ in {
documentation.dev.enable = true;
### RANDOM PATCHES ###
# I've had some weird issues with the entire system breaking after
# suspend because of /dev/shm getting nuked, maybe this'll help
services.logind.extraConfig = ''
RemoveIPC=no
'';
# why is this not part of base NixOS?
systemd.tmpfiles.rules = [ "d /var/lib/systemd/pstore 0755 root root 14d" ];
# autologin once after boot
# --skip-login means directly call login instead of first asking for username
# (normally login asks for username too, but getty prefers to do it by itself for whatever reason)

View file

@ -0,0 +1,464 @@
{ lib
, pkgs
, config
, ... }:
let
cfg = config.server;
# TODO: move to lib
quotePotentialIpV6 = addr:
if lib.hasInfix ":" addr then "[${addr}]" else addr;
efiPart = "/dev/disk/by-uuid/3E2A-A5CB";
rootUuid = "6aace237-9b48-4294-8e96-196759a5305b";
rootPart = "/dev/disk/by-uuid/${rootUuid}";
hosted-domains =
map
(prefix: if prefix == null then cfg.domainName else "${prefix}.${cfg.domainName}")
[
null
"dns"
"mumble"
"mail"
"music"
"www"
"matrix"
"search"
"git"
"cloud"
"ns1"
"ns2"
];
in {
imports = [
./options.nix
./matrix.nix
./fdroid.nix
./mumble.nix
];
system.stateVersion = "22.11";
boot = {
initrd = {
availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" "sr_mod" "rtsx_pci_sdmmc" ];
};
kernelModules = [ "kvm-intel" ];
kernelParams = [
"consoleblank=60"
];
loader = {
grub = {
enable = true;
device = "nodev";
version = 2;
efiSupport = true;
efiInstallAsRemovable = true;
gfxmodeEfi = "1920x1080";
gfxmodeBios = "1920x1080";
};
efi.efiSysMountPoint = "/boot/efi";
};
};
hardware.enableRedistributableFirmware = true;
fileSystems = {
"/" = { device = "none"; fsType = "tmpfs"; neededForBoot = true;
options = [ "defaults" "size=2G" "mode=755" ]; };
"/persist" =
{ device = rootPart; fsType = "btrfs"; neededForBoot = true;
options = [ "compress=zstd:15" ]; };
"/boot" =
{ device = rootPart; fsType = "btrfs"; neededForBoot = true;
options = [ "compress=zstd:15" "subvol=boot" ]; };
"/boot/efi" =
{ device = efiPart; fsType = "vfat"; };
};
zramSwap.enable = true;
swapDevices = [ ];
impermanence = {
enable = true;
path = /persist;
directories = [
{ directory = /var/www/${cfg.domainName}; }
{ directory = /var/lib/maubot; }
{ directory = /var/lib/fdroid; }
{ directory = config.mailserver.dkimKeyDirectory; }
{ directory = config.mailserver.mailDirectory; }
{ directory = /home/user; }
{ directory = /root; }
{ directory = /nix; }
];
};
services.beesd = {
filesystems.root = {
spec = "UUID=${rootUuid}";
hashTableSizeMB = 128;
extraOptions = [ "--loadavg-target" "8.0" ];
};
};
i18n.defaultLocale = lib.mkDefault "en_US.UTF-8";
i18n.supportedLocales = lib.mkDefault [
"C.UTF-8/UTF-8"
"en_US.UTF-8/UTF-8"
"en_DK.UTF-8/UTF-8"
];
# ISO-8601
i18n.extraLocaleSettings.LC_TIME = "en_DK.UTF-8";
console.font = "${pkgs.terminus_font}/share/consolefonts/ter-v24n.psf.gz";
networking.useDHCP = true;
networking.resolvconf.extraConfig = ''
name_servers="127.0.0.1 ::1"
'';
networking.firewall = {
enable = true;
allowedTCPPorts = [
# ssh
22
# dns
53 853
# http/s
80 443
];
allowedUDPPorts = [
# dns
53 853
# wireguard
# 5553
];
};
# UNBOUND
services.unbound = {
enable = true;
package = pkgs.unbound-with-systemd.override {
withPythonModule = true;
python = pkgs.python3.withPackages (pkgs: with pkgs; [ pydbus dnspython ]);
};
localControlSocketPath = "/run/unbound/unbound.ctl";
resolveLocalQueries = false;
settings = {
server = {
interface = [ "0.0.0.0" "::" ];
access-control = [ "${cfg.lanCidrV4} allow" "${cfg.lanCidrV6} allow" ];
aggressive-nsec = true;
do-ip6 = true;
module-config = ''"validator iterator"'';
local-zone = [
''"local." static''
] ++ (lib.optionals (cfg.localIpV4 != null || cfg.localIpV6 != null) [
''"${cfg.domainName}." typetransparent''
]);
local-data = builtins.concatLists (map (domain:
lib.optionals (cfg.localIpV4 != null) [
''"${domain}. A ${cfg.localIpV4}"''
] ++ (lib.optionals (cfg.localIpV6 != null) [
''"${domain}. A ${cfg.localIpV6}"''
])) hosted-domains);
};
python.python-script = toString (pkgs.fetchurl {
url = "https://raw.githubusercontent.com/NLnetLabs/unbound/a912786ca9e72dc1ccde98d5af7d23595640043b/pythonmod/examples/avahi-resolver.py";
sha256 = "0r1iqjf08wrkpzvj6pql1jqa884hbbfy9ix5gxdrkrva09msiqgi";
});
remote-control.control-enable = true;
};
};
systemd.services.unbound.environment.MDNS_ACCEPT_NAMES = "^.*\\.local\\.$";
# just in case
networking.hosts."127.0.0.1" = [ "localhost" ] ++ hosted-domains;
# CUPS
services.printing = {
enable = true;
allowFrom = [ cfg.lanCidrV4 cfg.lanCidrV6 ];
browsing = true;
clientConf = ''
ServerName ${cfg.domainName}
'';
defaultShared = true;
drivers = [ pkgs.hplip ];
startWhenNeeded = false;
};
programs.fish.enable = true;
users.defaultUserShell = pkgs.fish;
users.users.user = {
isNormalUser = true;
extraGroups = [ "wheel" config.services.unbound.group ];
};
environment.systemPackages = with pkgs; [
comma
git
vim
wget
# rxvt-unicode-unwrapped.terminfo
kitty.terminfo
tmux
];
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_13;
nix = {
settings = {
allowed-users = [ "user" ];
auto-optimise-store = true;
};
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
package = pkgs.nixFlakes;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
systemd.services.nix-daemon.serviceConfig.LimitSTACKSoft = "infinity";
# SSH
services.openssh = {
enable = true;
settings.PermitRootLogin = "no";
settings.PasswordAuthentication = false;
listenAddresses = [{
addr = "0.0.0.0";
} {
addr = "::";
}];
};
services.fail2ban.enable = true;
# SEARXNG
services.searx.enable = true;
services.searx.package = pkgs.searxng.overrideAttrs (_: {
src = pkgs.fetchFromGitHub {
owner = "searxng";
repo = "searxng";
rev = "cb1c3741d7de1354b524589114617f183009f6a8";
sha256 = "sha256-7erY5Bd1ZoTpAIDbhIupu64Xd1PQspaW6vBqu7knzNI=";
};
});
services.searx.runInUwsgi = true;
services.searx.uwsgiConfig = let inherit (config.services.searx) settings; in {
socket = "${quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}";
};
users.groups.searx.members = [ "nginx" ];
services.searx.environmentFile = "/etc/nixos/private/searx.env";
services.searx.settings = {
use_default_settings = true;
search = {
safe_search = 0; # Filter results. 0: None, 1: Moderate, 2: Strict
autocomplete = "duckduckgo"; # Existing autocomplete backends: "dbpedia", "duckduckgo", "google", "startpage", "swisscows", "qwant", "wikipedia" - leave blank to turn it off by default
default_lang = ""; # Default search language - leave blank to detect from browser information or use codes from 'languages.py'
};
server = {
port = 8888;
bind_address = "::1";
secret_key = "@SEARX_SECRET_KEY@";
base_url = "https://search.${cfg.domainName}/";
image_proxy = true;
default_http_headers = {
X-Content-Type-Options = "nosniff";
X-XSS-Protection = "1; mode=block";
X-Download-Options = "noopen";
X-Robots-Tag = "noindex, nofollow";
Referrer-Policy = "no-referrer";
};
};
outgoing = {
request_timeout = 5.0; # default timeout in seconds, can be override by engine
max_request_timeout = 15.0; # the maximum timeout in seconds
pool_connections = 100; # Maximum number of allowable connections, or null
pool_maxsize = 10; # Number of allowable keep-alive connections, or null
enable_http2 = true; # See https://www.python-httpx.org/http2/
};
/* = {
name = "soundcloud";
disabled = true;
};*/
};
services.nginx.virtualHosts."search.${cfg.domainName}" = let inherit (config.services.searx) settings; in {
enableACME = true;
forceSSL = true;
# locations."/".proxyPass = "http://${quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}";
locations."/".extraConfig = ''
uwsgi_pass "${quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}";
include ${config.services.nginx.package}/conf/uwsgi_params;
'';
};
# NGINX
services.nginx.enable = true;
services.nginx.streamConfig =
let
cert = config.security.acme.certs."${cfg.domainName}".directory + "/fullchain.pem";
certKey = config.security.acme.certs."${cfg.domainName}".directory + "/key.pem";
trustedCert = config.security.acme.certs."${cfg.domainName}".directory + "/chain.pem";
in ''
upstream dns {
zone dns 64k;
server 127.0.0.1:53;
}
server {
listen 853 ssl;
ssl_certificate ${cert};
ssl_certificate_key ${certKey};
ssl_trusted_certificate ${trustedCert};
proxy_pass dns;
}
'';
services.nginx.commonHttpConfig = "log_format postdata '{\"ip\":\"$remote_addr\",\"time\":\"$time_iso8601\",\"referer\":\"$http_referer\",\"body\":\"$request_body\",\"ua\":\"$http_user_agent\"}';";
services.nginx.recommendedTlsSettings = true;
services.nginx.recommendedOptimisation = true;
services.nginx.recommendedGzipSettings = true;
services.nginx.recommendedProxySettings = true;
# BLOG
services.nginx.virtualHosts."${cfg.domainName}" = {
enableACME = true;
forceSSL = true;
extraConfig = "autoindex on;";
locations."/".root = "/var/www/${cfg.domainName}/";
locations."/src".root = "/var/www/${cfg.domainName}/";
locations."/src".extraConfig = "index force_dirlisting;";
locations."/submit_comment".extraConfig = ''
access_log /var/log/nginx/comments.log postdata;
proxy_pass https://${cfg.domainName}/submit.htm;
break;
'';
locations."/submit.htm" = {
extraConfig = ''
return 200 '<!doctype html><html><head><base href="/"/><link rel="preload" href="style.css" as="style"><title>Success!</title><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><link rel="icon" type="image/jpeg" href="pfp.jpg"><link rel="alternate" type="application/rss+xml" title="RSS" href="https://${cfg.domainName}/blog/index.xml"><link href="style.css" rel="stylesheet" /><script src="main.js"></script><meta http-equiv="refresh" content="10; url=$http_referer" /></head><body onload="documentLoaded()"><hr/><div class="main-body"><p>Success! It may take a while for your comment to get moderated.</p><p>Please wait for 10 seconds until you get redirected back...</p><p>Or just go there <a href="$http_referer">manually</a>.</p></div><hr/></body></html>';
'';
};
};
services.nginx.virtualHosts."www.${cfg.domainName}" = {
enableACME = true;
globalRedirect = cfg.domainName;
};
# MAILSERVER
# roundcube
services.nginx.virtualHosts."mail.${cfg.domainName}" = {
enableACME = true;
};
services.roundcube = {
enable = true;
package = pkgs.roundcube.withPlugins (plugins: [ plugins.persistent_login ]);
dicts = with pkgs.aspellDicts; [ en ru ];
hostName = "mail.${cfg.domainName}";
maxAttachmentSize = 100;
plugins = [ "persistent_login" ];
};
mailserver = {
enable = true;
fqdn = "mail.${cfg.domainName}";
domains = [ cfg.domainName ];
certificateScheme = 1;
certificateFile = config.security.acme.certs."mail.${cfg.domainName}".directory + "/fullchain.pem";
keyFile = config.security.acme.certs."mail.${cfg.domainName}".directory + "/key.pem";
localDnsResolver = false;
recipientDelimiter = "-";
lmtpSaveToDetailMailbox = "no";
hierarchySeparator = "/";
};
# Only allow local connections to noreply account
mailserver.loginAccounts."noreply@${cfg.domainName}" = {
# password is set in private.nix
hashedPassword = cfg.hashedNoreplyPassword;
sendOnly = true;
};
services.dovecot2.extraConfig =
let passwd = builtins.toFile "dovecot2-local-passwd" ''
noreply@${cfg.domainName}:{plain}${cfg.unhashedNoreplyPassword}::::::allow_nets=local,127.0.0.0/8,::1
'';
in ''
passdb {
driver = passwd-file
args = ${passwd}
}
'';
# GITEA
services.nginx.virtualHosts."git.${cfg.domainName}" = let inherit (config.services.gitea) settings; in {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://${quotePotentialIpV6 settings.server.HTTP_ADDR}:${toString settings.server.HTTP_PORT}";
};
services.gitea = {
enable = true;
database = {
createDatabase = false;
passwordFile = "/var/lib/gitea/db_password";
type = "postgres";
};
settings = {
mailer = {
ENABLED = true;
FROM = "Gitea <noreply@${cfg.domainName}>";
MAILER_TYPE = "smtp";
HOST = "mail.${cfg.domainName}:587";
USER = "noreply@${cfg.domainName}";
PASSWD = cfg.unhashedNoreplyPassword;
SKIP_VERIFY = true;
};
session = {
COOKIE_SECURE = true;
};
server = {
ROOT_URL = "https://git.${cfg.domainName}";
HTTP_ADDR = "::1";
HTTP_PORT = 3310;
DOMAIN = "git.${cfg.domainName}";
# START_SSH_SERVER = true;
# SSH_PORT = 2222;
};
service = {
DISABLE_REGISTRATION = true;
REGISTER_EMAIL_CONFIRM = true;
};
};
};
# NEXTCLOUD
services.nginx.virtualHosts."cloud.${cfg.domainName}" = {
enableACME = true;
forceSSL = true;
};
services.nextcloud = {
enable = true;
enableBrokenCiphersForSSE = false;
package = pkgs.nextcloud26;
autoUpdateApps.enable = true;
# TODO: use socket auth and remove the next line
database.createLocally = false;
config = {
adminpassFile = "/var/lib/nextcloud/admin_password";
dbpassFile = "/var/lib/nextcloud/db_password";
dbtype = "pgsql";
dbhost = "/run/postgresql";
overwriteProtocol = "https";
};
hostName = "cloud.${cfg.domainName}";
https = true;
};
systemd.services.pleroma.path = [ pkgs.exiftool pkgs.gawk ];
services.nginx.virtualHosts."pleroma.${cfg.domainName}" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:9970";
};
/*locations."/dns-query".extraConfig = ''
grpc_pass grpc://127.0.0.1:53453;
'';*/
# TODO: firefox sync?
}

View file

@ -0,0 +1,51 @@
{ config
, pkgs
, lib
, ... }:
let
cfg = config.server;
quotePotentialIpV6 = addr:
if lib.hasInfix ":" addr then "[${addr}]" else addr;
in {
services.nginx.virtualHosts."${cfg.domainName}" = {
locations."/fdroid/".alias = "/var/lib/fdroid/repo/";
};
users.users.fdroid = {
home = "/var/lib/fdroid";
group = "fdroid";
isSystemUser = true;
};
users.groups.fdroid = { };
systemd.timers.update-fdroid = {
wantedBy = [ "timers.target" ];
partOf = [ "update-fdroid.service" ];
# slightly unusual time to reduce server load
timerConfig.OnCalendar = [ "*-*-* 00:40:00" ]; # every day
};
systemd.services.update-fdroid = {
serviceConfig = let
inherit (pkgs) fdroidserver;
fdroidScript = pkgs.writeText "update-froid.py" ''
import requests, subprocess, os, sys
x = requests.get('https://api.github.com/repos/ppy/osu/releases').json()
for q in x:
for w in q.get('assets', []):
if w.get('name', "").endswith('.apk'):
os.chdir('/var/lib/fdroid')
subprocess.run(['${pkgs.wget}/bin/wget', w['browser_download_url'], '-O', '/var/tmp/lazer.apk'], check=True)
os.rename('/var/tmp/lazer.apk', '/var/lib/fdroid/repo/sh.ppy.osulazer.apk')
subprocess.run(['${fdroidserver}/bin/fdroid', 'update', '--allow-disabled-algorithms'])
sys.exit()
'';
fdroidPython = pkgs.python3.withPackages (p: with p; [ requests ]);
in {
Type = "oneshot";
ExecStart = "${fdroidPython} ${fdroidScript}";
};
environment.JAVA_HOME = "${pkgs.jdk11_headless}";
path = [ pkgs.jdk11_headless ];
};
}

View file

@ -0,0 +1,122 @@
{ config
, pkgs
, lib
, ... }:
let
cfg = config.server;
quotePotentialIpV6 = addr:
if lib.hasInfix ":" addr then "[${addr}]" else addr;
matrixServerJson = {
"m.server" = "matrix.${cfg.domainName}:443";
};
matrixClientJson = {
"m.homeserver" = { base_url = "https://matrix.${cfg.domainName}"; };
"m.identity_server" = { base_url = "https://vector.im"; };
};
matrixServerConfigResponse = ''
add_header Content-Type application/json;
return 200 '${builtins.toJSON matrixServerJson}';
'';
matrixClientConfigResponse = ''
add_header Content-Type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '${builtins.toJSON matrixClientJson}';
'';
matrixAddr = "::1";
matrixPort = 8008;
in {
imports = [ ./maubot.nix ];
networking.firewall.allowedTCPPorts = [ 8008 8448 ];
systemd.services.matrix-synapse.serviceConfig.TimeoutStartSec = 180;
services.nginx.virtualHosts."${cfg.domainName}" = {
locations."= /.well-known/matrix/server".extraConfig = matrixServerConfigResponse;
locations."= /.well-known/matrix/client".extraConfig = matrixClientConfigResponse;
};
services.nginx.virtualHosts."matrix.${cfg.domainName}" = {
enableACME = true;
forceSSL = true;
locations = {
"= /.well-known/matrix/server".extraConfig = matrixServerConfigResponse;
"= /.well-known/matrix/client".extraConfig = matrixClientConfigResponse;
"/".proxyPass = "http://${quotePotentialIpV6 matrixAddr}:${toString matrixPort}";
};
};
systemd.services.heisenbridge.wants = [ "matrix-synapse.service" ];
systemd.services.heisenbridge.after = [ "matrix-synapse.service" ];
services.heisenbridge = {
enable = true;
homeserver = "http://${quotePotentialIpV6 matrixAddr}:${toString matrixPort}/";
};
# so synapse can read the registration
users.groups.heisenbridge.members = [ "matrix-synapse" ];
services.matrix-synapse = {
enable = true;
extraConfigFiles = [ "/var/lib/matrix-synapse/config.yaml" ];
settings = {
app_service_config_files = [
"/var/lib/heisenbridge/registration.yml"
];
allow_guest_access = true;
url_preview_enabled = true;
tls_certificate_path = config.security.acme.certs."matrix.${cfg.domainName}".directory + "/fullchain.pem";
tls_private_key_path = config.security.acme.certs."matrix.${cfg.domainName}".directory + "/key.pem";
public_baseurl = "https://matrix.${cfg.domainName}/";
server_name = "matrix.${cfg.domainName}";
max_upload_size = "100M";
email = {
smtp_host = "mail.pavluk.org";
smtp_port = 587;
smtp_user = "noreply";
smtp_password = cfg.unhashedNoreplyPassword;
notif_from = "${cfg.domainName} matrix homeserver <noreply@${cfg.domainName}>";
app_name = cfg.domainName;
notif_for_new_users = false;
enable_notifs = true;
};
listeners = [{
port = matrixPort;
bind_addresses = [ matrixAddr ];
type = "http";
tls = false;
x_forwarded = true;
resources = [{
names = [ "client" "federation" ];
compress = false;
}];
}];
};
};
# maubot
users.users.maubot = {
home = "/var/lib/maubot";
group = "maubot";
isSystemUser = true;
};
users.groups.maubot = { };
systemd.services.maubot = {
description = "Maubot";
wants = [ "matrix-synapse.service" "nginx.service" ];
after = [ "matrix-synapse.service" "nginx.service" ];
wantedBy = [ "multi-user.target" ];
environment = {
LD_LIBRARY_PATH = "${pkgs.stdenv.cc.cc.lib}/lib";
};
serviceConfig = {
User = "maubot";
Group = "maubot";
WorkingDirectory = "/var/lib/maubot/data";
};
script = "${pkgs.python3.withPackages (pks: with pks; [
pkgs.maubot (pkgs.pineapplebot.override {
magic = cfg.pizzabotMagic;
}) feedparser levenshtein python-dateutil pytz
])}/bin/python3 -m maubot";
};
}

View file

@ -0,0 +1,45 @@
{ config
, pkgs
, lib
, ... }:
let
cfg = config.server;
quotePotentialIpV6 = addr:
if lib.hasInfix ":" addr then "[${addr}]" else addr;
# i've yet to create a maubot module so this is hardcoded
maubotAddr = "127.0.0.1";
maubotPort = 29316;
in {
services.nginx.virtualHosts."matrix.${cfg.domainName}".locations = {
"/_matrix/maubot/" = {
proxyPass = "http://${quotePotentialIpV6 maubotAddr}:${toString maubotPort}";
proxyWebsockets = true;
};
};
users.users.maubot = {
home = "/var/lib/maubot";
group = "maubot";
isSystemUser = true;
};
users.groups.maubot = { };
systemd.services.maubot = {
description = "Maubot";
wants = [ "matrix-synapse.service" "nginx.service" ];
after = [ "matrix-synapse.service" "nginx.service" ];
wantedBy = [ "multi-user.target" ];
environment = {
LD_LIBRARY_PATH = "${pkgs.stdenv.cc.cc.lib}/lib";
};
serviceConfig = {
User = "maubot";
Group = "maubot";
WorkingDirectory = "/var/lib/maubot/data";
};
script = "${pkgs.python3.withPackages (pks: with pks; [
pkgs.maubot (pkgs.pineapplebot.override {
magic = cfg.pizzabotMagic;
}) feedparser levenshtein python-dateutil pytz
])}/bin/python3 -m maubot";
};
}

View file

@ -0,0 +1,81 @@
{ config
, lib
, ... }:
let
cfg = config.server;
quotePotentialIpV6 = addr:
if lib.hasInfix ":" addr then "[${addr}]" else addr;
in {
services.murmur = {
enable = true;
imgMsgLength = 0;
textMsgLength = 0;
registerName = "mumble.${cfg.domainName}";
registerHostname = "mumble.${cfg.domainName}";
sslCa = config.security.acme.certs."mumble.${cfg.domainName}".directory + "/chain.pem";
sslCert = config.security.acme.certs."mumble.${cfg.domainName}".directory + "/fullchain.pem";
sslKey = config.security.acme.certs."mumble.${cfg.domainName}".directory + "/key.pem";
# clientCertRequired = true;
extraConfig = ''
bandwidth=320000
opusthreshold=0
'';
};
# Allow murmur to read the certificate
security.acme.certs."mumble.${cfg.domainName}" = {
group = "nginxandmurmur";
postRun = "systemctl try-reload-or-restart murmur";
};
users.groups.nginxandmurmur.members = [ "murmur" "nginx" ];
# Mumble music bot
services.nginx.virtualHosts."mumble.${cfg.domainName}" = let inherit (config.services.botamusique) settings; in {
enableACME = true;
forceSSL = true;
globalRedirect = cfg.domainName;
locations."/music".extraConfig = "return 301 https://mumble.${cfg.domainName}/music/;";
locations."/music/".proxyPass = "http://${quotePotentialIpV6 settings.webinterface.listening_addr}:${toString settings.webinterface.listening_port}/";
};
services.botamusique = {
enable = true;
settings = {
youtube_dl = {
cookiefile = "/var/lib/botamusique/cookie_ydl";
};
webinterface = {
enabled = true;
listening_addr = "::1";
listening_port = 8181;
is_web_proxified = true;
access_address = "https://mumble.${cfg.domainName}/music";
auth_method = "token";
upload_enabled = true;
max_upload_file_size = "100MB";
delete_allowed = true;
};
bot = {
bandwidth = 200000;
volume = 1.0;
ducking = true;
ducking_volume = 0.75;
};
server.certificate = "/var/lib/botamusique/cert.pem";
};
};
systemd.services.botamusique.wants = [ "murmur.service" ];
systemd.services.botamusique.after = [ "murmur.service" ];
networking.firewall = {
allowedTCPPorts = [
64738
# Used for mumble-web signaling (not sure if it needs TCP or UDP)
# 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 20010
];
allowedUDPPorts = [
64738
# 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 20010
];
};
}

View file

@ -0,0 +1,58 @@
{ lib
, ... }:
{
options.server = with lib; mkOption {
type = types.submodule {
options = {
domainName = mkOption {
type = types.str;
default = "pavluk.org";
description = "domain name";
};
lanCidrV4 = mkOption {
type = types.str;
description = "LAN mask (IPv4)";
example = "192.168.1.0/96";
default = "0.0.0.0/0";
};
lanCidrV6 = mkOption {
type = types.str;
description = "LAN mask (IPv6)";
example = "fd01:abcd::/64";
default = "::/0";
};
localIpV4 = mkOption {
type = with types; nullOr str;
description = "server's local IPv4 address";
example = "192.168.1.2";
default = null;
};
localIpV6 = mkOption {
type = with types; nullOr str;
description = "server's local IPv6 address";
example = "fd01:abcd::2";
default = null;
};
noreplyPassword = mkOption {
type = types.str;
description = "noreply (only available via localhost) account password";
default = "totallysafe";
};
hashedNoreplyPassword = mkOption {
type = types.str;
description = "hashed noreply password via mkpasswd -sm bcrypt";
};
unhashedNoreplyPassword = mkOption {
type = types.str;
description = "unhashed noreply password. \
This should preferably be different from the password that is hashed for better security (yes, really)";
};
pizzabotMagic = mkOption {
type = types.str;
default = "<PIZZABOT_MAGIC_SEP>";
};
};
};
description = "server settings";
};
}

View file

@ -4,7 +4,7 @@
config.programs.ccache.cacheDir
"/var/cache/sccache"
];
environment.persistence."/persist".directories = lib.mkIf config.programs.ccache.enable [
impermanence.directories = lib.mkIf config.programs.ccache.enable [
config.programs.ccache.cacheDir
"/var/cache/sccache"
];

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }:
{ config, lib, ... }:
let
cfg = config.impermanence;
@ -16,7 +16,7 @@ in {
description = "Default path for persistence";
};
directories = mkOption {
type = with types; listOf path;
type = with types; listOf (either path attrs);
default = [ ];
description = "Extra directories to persist";
};
@ -36,41 +36,90 @@ in {
default = { };
};
config = lib.mkIf cfg.enable {
# why is this not part of base NixOS?
systemd.tmpfiles.rules = [ "d /var/lib/systemd/pstore 0755 root root 14d" ];
# as weird as it sounds, I won't use tmpfs for /tmp in case I'll have to put files over 2GB there
boot.cleanTmpDir = lib.mkIf cfg.persistTmp true;
boot.tmp.cleanOnBoot = lib.mkIf cfg.persistTmp true;
environment.persistence.${toString cfg.path} = {
hideMounts = true;
directories = map toString ([
directories = map (x:
if builtins.isPath x then toString x
else if builtins.isAttrs x && x?directory && builtins.isPath x.directory then x // { directory = toString x.directory; }
else x)
([
# nixos files
/etc/nixos
/var/lib/nixos
{ directory = /etc/nixos; user = "root"; group = "root"; mode = "0755"; }
{ directory = /var/lib/nixos; user = "root"; group = "root"; mode = "0755"; }
/var/log
{ directory = /var/log; user = "root"; group = "root"; mode = "0755"; }
# persist this since everything here is cleaned up by systemd-tmpfiles over time anyway
# ...or so I'd like to believe
/var/lib/systemd
/var/tmp
{ directory = /var/lib/systemd; user = "root"; group = "root"; mode = "0755"; }
{ directory = /var/tmp; user = "root"; group = "root"; mode = "1777"; }
{ directory = /var/spool; user = "root"; group = "root"; mode = "0777"; }
] ++ (lib.optionals cfg.persistTmp [
/tmp
{ directory = /tmp; user = "root"; group = "root"; mode = "1777"; }
]) ++ (lib.optionals config.services.mullvad-vpn.enable [
/etc/mullvad-vpn
/var/cache/mullvad-vpn
{ directory = /etc/mullvad-vpn; user = "root"; group = "root"; mode = "0700"; }
{ directory = /var/cache/mullvad-vpn; user = "root"; group = "root"; mode = "0755"; }
]) ++ (lib.optionals config.virtualisation.libvirtd.enable ([
/var/cache/libvirt
/var/lib/libvirt
# { directory = /var/cache/libvirt; user = "root"; group = "root"; mode = "0755"; }
{ directory = /var/lib/libvirt; user = "root"; group = "root"; mode = "0755"; }
] ++ (lib.optionals config.virtualisation.libvirtd.qemu.swtpm.enable [
/var/lib/swtpm-localca
{ directory = /var/lib/swtpm-localca; user = "root"; group = "root"; mode = "0750"; }
]))) ++ (lib.optionals config.networking.wireless.iwd.enable [
/var/lib/iwd
{ directory = /var/lib/iwd; user = "root"; group = "root"; mode = "0700"; }
]) ++ (lib.optionals (builtins.any (x: x.useDHCP) (builtins.attrValues config.networking.interfaces) || config.networking.useDHCP) [
/var/db/dhcpcd
{ directory = /var/db/dhcpcd; user = "root"; group = "root"; mode = "0755"; }
]) ++ (lib.optionals config.services.gitea.enable [
{ directory = /var/lib/gitea; user = "gitea"; group = "gitea"; mode = "0755"; }
]) ++ (lib.optionals config.services.matrix-synapse.enable [
{ directory = /var/lib/matrix-synapse; user = "matrix-synapse"; group = "matrix-synapse"; mode = "0700"; }
]) ++ (lib.optionals config.services.heisenbridge.enable [
{ directory = /var/lib/heisenbridge; user = "heisenbridge"; group = "heisenbridge"; mode = "0755"; }
]) ++ (lib.optionals config.services.murmur.enable [
{ directory = /var/lib/murmur; user = "murmur"; group = "murmur"; mode = "0700"; }
]) ++ (lib.optionals config.services.nextcloud.enable [
{ directory = /var/lib/nextcloud; user = "nextcloud"; group = "nextcloud"; mode = "0750"; }
]) ++ (lib.optionals config.services.botamusique.enable [
{ directory = /var/lib/private/botamusique; user = "root"; group = "root"; mode = "0750"; }
]) ++ (lib.optionals config.security.acme.acceptTerms [
{ directory = /var/lib/acme; user = "acme"; group = "acme"; mode = "0755"; }
]) ++ (lib.optionals config.services.printing.enable [
{ directory = /var/lib/cups; user = "root"; group = "root"; mode = "0755"; }
]) ++ (lib.optionals config.services.fail2ban.enable [
{ directory = /var/lib/fail2ban; user = "fail2ban"; group = "fail2ban"; mode = "0750"; }
]) ++ (lib.optionals config.services.opendkim.enable [
{ directory = /var/lib/opendkim; user = "opendkim"; group = "opendkim"; mode = "0700"; }
]) ++ (lib.optionals config.services.pleroma.enable [
{ directory = /var/lib/pleroma; user = "pleroma"; group = "pleroma"; mode = "0700"; }
]) ++ (lib.optionals config.services.postfix.enable [
{ directory = /var/lib/postfix; user = "root"; group = "root"; mode = "0755"; }
]) ++ (lib.optionals config.services.postgresql.enable [
{ directory = /var/lib/postgresql; user = "postgres"; group = "postgres"; mode = "0755"; }
]) ++ (lib.optionals config.services.unbound.enable [
{ directory = /var/lib/unbound; user = "unbound"; group = "unbound"; mode = "0755"; }
]) ++ (lib.optionals config.services.roundcube.enable [
{ directory = /var/lib/roundcube; user = "roundcube"; group = "roundcube"; mode = "0700"; }
]) ++ (lib.optionals config.services.rspamd.enable [
{ directory = /var/lib/rspamd; user = "rspamd"; group = "rspamd"; mode = "0700"; }
]) ++ (lib.optionals (
(builtins.hasAttr "rspamd" config.services.redis.servers)
&& (builtins.hasAttr "enable" config.services.redis.servers.rspamd)
&& config.services.redis.servers.rspamd.enable
) [
{ directory = /var/lib/redis-rspamd; user = "redis-rspamd"; group = "redis-rspamd"; mode = "0700"; }
]) ++ (lib.optionals config.services.dovecot2.enable [
{ directory = /var/lib/dhparams; user = "root"; group = "root"; mode = "0755"; }
{ directory = /var/lib/dovecot; user = "root"; group = "root"; mode = "0755"; }
]) ++ (lib.optionals config.security.sudo.enable [
/var/db/sudo/lectured
{ directory = /var/db/sudo/lectured; user = "root"; group = "root"; mode = "0700"; }
]) ++ cfg.directories);
files = map toString ([
# hardware-related
/etc/adjtime
# needed at least for /var/log
/etc/machine-id
] ++ cfg.files);
};

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }:
{ options, config, lib, pkgs, ... }:
let
cfg = config.vfio;
in {
@ -73,9 +73,10 @@ in {
description = "VFIO settings";
default = { };
};
# compatibility so this module loads on non-amd hardware
config = let
enableIvshmem = config.vfio.lookingGlass.enable && (builtins.length config.vfio.lookingGlass.ivshmem) > 0;
in lib.mkIf config.vfio.enable {
enableIvshmem = cfg.lookingGlass.enable && (builtins.length cfg.lookingGlass.ivshmem) > 0;
in lib.mkIf cfg.enable {
# add a custom kernel param for early loading vfio drivers
# because if we change boot.initrd options in a specialization, two initrds will be built
# and we don't want to build two initrds
@ -151,9 +152,13 @@ in {
SUBSYSTEM=="kvmfr", KERNEL=="kvmfr${toString i}", OWNER="${ivshmem.owner}", GROUP="kvm", MODE="0660"
'')
cfg.lookingGlass.ivshmem));
# disable early KMS so GPU can be properly unbound
hardware.amdgpu.loadInInitrd = lib.mkIf (!cfg.nvidiaGpu) false;
hardware.opengl.enable = true;
hardware = {
opengl.enable = true;
} // (lib.optionalAttrs (cfg.enable && !(cfg.nvidiaGpu)) {
# disable early KMS so GPU can be properly unbound
# can't use mkif because the option may not even exist
amdgpu.loadInInitrd = false;
});
# needed for virt-manager
programs.dconf.enable = true;
virtualisation.libvirtd = {

View file

@ -1,3 +1,5 @@
{ pkgs, ... }: let inherit (pkgs) callPackage; in {
system76-scheduler = callPackage ../pkgs/system76-scheduler.nix { };
system76-scheduler = callPackage ./system76-scheduler.nix { };
maubot = callPackage ./maubot.nix { };
pineapplebot = callPackage ./pineapplebot.nix { };
}

95
system/pkgs/maubot.nix Normal file
View file

@ -0,0 +1,95 @@
{ lib
, fetchpatch
, python3
, runCommand
, encryptionSupport ? true
}:
let
python = python3.override {
packageOverrides = self: super: {
sqlalchemy = super.buildPythonPackage rec {
pname = "SQLAlchemy";
version = "1.3.24";
src = super.fetchPypi {
inherit pname version;
sha256 = "sha256-67t3fL+TEjWbiXv4G6ANrg9ctp+6KhgmXcwYpvXvdRk=";
};
postInstall = ''
sed -e 's:--max-worker-restart=5::g' -i setup.cfg
'';
doCheck = false;
};
};
};
self = with python.pkgs; buildPythonPackage rec {
pname = "maubot";
version = "0.4.1";
disabled = pythonOlder "3.8";
src = fetchPypi {
inherit pname version;
sha256 = "sha256-Ro2PPgF8818F8JewPZ3AlbfWFNNHKTZkQq+1zpm3kk4=";
};
patches = [
# add entry point
(fetchpatch {
url = "https://patch-diff.githubusercontent.com/raw/maubot/maubot/pull/146.patch";
sha256 = "0yn5357z346qzy5v5g124mgiah1xsi9yyfq42zg028c8paiw8s8x";
})
];
propagatedBuildInputs = [
# requirements.txt
mautrix
aiohttp
yarl
sqlalchemy
asyncpg
aiosqlite
CommonMark
ruamel-yaml
attrs
bcrypt
packaging
click
colorama
questionary
jinja2
]
# optional-requirements.txt
++ lib.optionals encryptionSupport [
python-olm
pycryptodome
unpaddedbase64
];
passthru.tests = {
simple = runCommand "${pname}-tests" { } ''
${self}/bin/mbc --help > $out
'';
};
# Setuptools is trying to do python -m maubot test
dontUseSetuptoolsCheck = true;
pythonImportsCheck = [
"maubot"
];
meta = with lib; {
description = "A plugin-based Matrix bot system written in Python";
homepage = "https://github.com/maubot/maubot";
changelog = "https://github.com/maubot/maubot/blob/v${version}/CHANGELOG.md";
license = licenses.agpl3Plus;
maintainers = with maintainers; [ chayleaf ];
};
};
in
self

View file

@ -0,0 +1,34 @@
{ python3
, fetchFromGitHub
, rustPlatform
, magic ? "<PIZZABOT_MAGIC_SEP>"
, ... }:
python3.pkgs.buildPythonPackage rec {
pname = "pineapplebot";
version = "0.1.0";
src = fetchFromGitHub {
owner = "chayleaf";
repo = "pizzabot_v3";
rev = "master";
sha256 = "sha256-ZLskMlllZfmqIlbSr0pNHHJehDycohiwqgYbuEYP7Qc=";
};
preBuild = ''
head -n13 Cargo.toml > Cargo.toml.new
mv Cargo.toml.new Cargo.toml
'';
sourceRoot = "source/pineapplebot";
cargoDeps = rustPlatform.fetchCargoTarball {
inherit src sourceRoot;
name = "${pname}-${version}";
sha256 = "14jxgykwg1apy97gy1j8mz7ny2cqg4q9s03a2bk9kx2y6ibm4668";
};
nativeBuildInputs = with rustPlatform; [
cargoSetupHook
maturinBuildHook
];
doCheck = false;
doInstallCheck = true;
pythonImportsCheck = [ "pineapplebot" ];
PIZZABOT_MAGIC = magic;
}

View file

@ -1,5 +0,0 @@
{
nixmsi = { ... }: {
# insert private config here
};
}

View file

@ -0,0 +1,9 @@
{
nixmsi = { pkgs, lib, ... }: {
# insert private config here
# time.timeZone = ...;
# users.users.root.initialHashedPassword = ...;
# users.users.user.initialHashedPassword = ...;
};
nixserver = { ... }: { };
}