622 lines
15 KiB
Nix
622 lines
15 KiB
Nix
{ config, pkgs, lib, ... }:
|
|
let
|
|
importedVars = import ./variables.nix { inherit config pkgs lib; };
|
|
in
|
|
with importedVars;
|
|
{
|
|
nixpkgs.config = {
|
|
allowUnfreePredicate = pkg:
|
|
builtins.elem (lib.getName pkg) [
|
|
# "claude-code"
|
|
"obsidian"
|
|
"packer"
|
|
"reaper"
|
|
# "n8n"
|
|
"vscode"
|
|
"terraform"
|
|
"zoom"
|
|
# "charlatan3"
|
|
# "steam"
|
|
# "steam-original"
|
|
# "steam-unwrapped"
|
|
# "steam-run"
|
|
# "tokenizer.json" # goose-cli
|
|
];
|
|
};
|
|
nixpkgs.overlays = [
|
|
(self: super: {
|
|
# n8n = unstable.n8n;
|
|
|
|
ansible = super.ansible.overrideAttrs (oldAttrs: {
|
|
propagatedBuildInputs = oldAttrs.propagatedBuildInputs ++ [ super.python312Packages.jmespath ];
|
|
}); # Add jmespath to ansible build inputs
|
|
|
|
# https://blaukraut.info/
|
|
# charlatan3 = super.callPackage ./overlays/clap/charlatan3.nix { };
|
|
})
|
|
];
|
|
|
|
imports = [
|
|
./hardware-configuration.nix
|
|
<home-manager/nixos>
|
|
];
|
|
|
|
boot = {
|
|
loader = {
|
|
systemd-boot.enable = true;
|
|
efi.canTouchEfiVariables = true;
|
|
};
|
|
};
|
|
|
|
hardware = {
|
|
bluetooth.enable = true;
|
|
keyboard.qmk.enable = true;
|
|
|
|
graphics = { # https://wiki.nixos.org/wiki/Accelerated_Video_Playback
|
|
enable = true;
|
|
extraPackages = with pkgs; [
|
|
intel-media-driver
|
|
];
|
|
};
|
|
};
|
|
|
|
networking = {
|
|
hostName = "${host_name}";
|
|
firewall.enable = false;
|
|
interfaces = {
|
|
enp100s0.ipv4.addresses = [{
|
|
address = "192.168.1.35";
|
|
prefixLength = 24;
|
|
}];
|
|
};
|
|
defaultGateway = {
|
|
address = "192.168.1.1";
|
|
interface = "enp100s0";
|
|
};
|
|
# TODO https://nixos.wiki/wiki/Encrypted_DNS
|
|
nameservers = [ "1.1.1.1" "8.8.8.8" ];
|
|
extraHosts = ''
|
|
192.168.1.1 shinx.${host_fqdn}
|
|
'';
|
|
localCommands = ''
|
|
ip route add 10.19.21.11/32 dev ${config.networking.defaultGateway.interface} via ${config.networking.defaultGateway.address} || true # timburr
|
|
ip route add 10.19.21.34/32 dev ${config.networking.defaultGateway.interface} via ${config.networking.defaultGateway.address} || true # weavile
|
|
'';
|
|
};
|
|
|
|
time.timeZone = "America/Los_Angeles";
|
|
|
|
i18n.defaultLocale = "en_US.UTF-8";
|
|
console = {
|
|
font = "Lat2-Terminus16";
|
|
# keyMap = "us";
|
|
useXkbConfig = true; # use xkbOptions in tty.
|
|
};
|
|
|
|
users = {
|
|
groups = {
|
|
glance = {};
|
|
};
|
|
users = {
|
|
|
|
root = {
|
|
openssh.authorizedKeys.keyFiles = [
|
|
/etc/nixos/ssh/authorized_keys
|
|
];
|
|
};
|
|
|
|
blee = {
|
|
openssh.authorizedKeys.keyFiles = [
|
|
/etc/nixos/ssh/authorized_keys
|
|
];
|
|
isNormalUser = true;
|
|
extraGroups = [
|
|
"wheel"
|
|
"adbusers"
|
|
"docker"
|
|
"glance"
|
|
];
|
|
packages = with pkgs; [
|
|
# unstable.goose-cli
|
|
mariadb
|
|
notify-client
|
|
gh
|
|
brave
|
|
chromium
|
|
element-desktop
|
|
firefox
|
|
haruna
|
|
gimp
|
|
gnumake
|
|
home-manager
|
|
jellyfin-media-player
|
|
kdePackages.kate #kwrite
|
|
kdePackages.kdenlive
|
|
kdePackages.kcalc
|
|
# libsForQt5.kcalc
|
|
# unstable.logseq # warning: https://github.com/logseq/logseq/issues/10851#issuecomment-2402925912
|
|
# unstable.ghostty
|
|
moonlight-qt
|
|
nmap
|
|
obs-studio
|
|
obsidian
|
|
# pavucontrol
|
|
qbittorrent
|
|
rclone
|
|
# rtorrent
|
|
sq
|
|
# synergy
|
|
tenacity
|
|
thunderbird
|
|
tor-browser
|
|
via
|
|
vlc
|
|
vscode
|
|
yt-dlp
|
|
zoom-us
|
|
|
|
# Build vim huge with clipboard support
|
|
(vim_configurable.overrideAttrs (oldAttrs: {
|
|
features = "huge";
|
|
}))
|
|
|
|
awscli2
|
|
aws-sam-cli
|
|
packer
|
|
terraform
|
|
ansible
|
|
python311
|
|
python311Packages.pip
|
|
python311Packages.ipython
|
|
libreoffice-qt
|
|
hunspell
|
|
hunspellDicts.en-us
|
|
# postman # nope, auth is broken
|
|
nodejs_20
|
|
yarn
|
|
deno
|
|
nix-init
|
|
nix-tree
|
|
nurl
|
|
# music apps
|
|
reaper
|
|
spek
|
|
];
|
|
};
|
|
|
|
glance = {
|
|
isSystemUser = true;
|
|
group = "glance";
|
|
home = "/var/lib/glance";
|
|
createHome = true;
|
|
description = "Glance service user";
|
|
# shell = pkgs.bash;
|
|
};
|
|
|
|
};
|
|
};
|
|
# home-manager.users.blee = { imports = [ ./home.nix ]; };
|
|
|
|
environment = {
|
|
systemPackages = with pkgs; [
|
|
arp-scan
|
|
binutils
|
|
coreutils
|
|
cryptsetup
|
|
curl
|
|
difftastic
|
|
dig
|
|
dnscontrol
|
|
dnsutils
|
|
doas
|
|
exiftool
|
|
ffmpeg
|
|
file
|
|
fzf
|
|
git
|
|
go
|
|
htop
|
|
iftop
|
|
imagemagick
|
|
iperf
|
|
jq
|
|
lego
|
|
libressl
|
|
lm_sensors
|
|
mediainfo
|
|
net-snmp # snmpwalk
|
|
netcat
|
|
nettools
|
|
nix-output-monitor
|
|
parted
|
|
pass
|
|
pciutils # lspci
|
|
psmisc
|
|
qrencode
|
|
rsync
|
|
screen
|
|
tcpdump
|
|
tmux
|
|
tree
|
|
unzip
|
|
vim
|
|
vulkan-tools
|
|
wget
|
|
whois
|
|
wireguard-tools
|
|
zbar
|
|
zip
|
|
];
|
|
|
|
shellInit = ''
|
|
pheonix() {
|
|
systemctl restart "$1"
|
|
journalctl -fu "$1"
|
|
}
|
|
'';
|
|
|
|
# vscode on Wayland
|
|
sessionVariables.NIXOS_OZONE_WL = "1";
|
|
# TODO: https://github.com/nix-community/plasma-manager
|
|
plasma6.excludePackages = with pkgs.kdePackages; [
|
|
plasma-browser-integration
|
|
];
|
|
|
|
etc."gitconfig".text = ''
|
|
[init]
|
|
defaultBranch = main
|
|
'';
|
|
};
|
|
|
|
programs = {
|
|
adb.enable = true;
|
|
appimage = {
|
|
enable = true;
|
|
binfmt = true;
|
|
package = pkgs.appimage-run.override {
|
|
extraPkgs = pkgs: [
|
|
pkgs.libthai # lume
|
|
];
|
|
};
|
|
};
|
|
# hyprland = {
|
|
# enable = true;
|
|
# xwayland.enable = true;
|
|
# };
|
|
|
|
fish.enable = true;
|
|
vim = {
|
|
enable = true;
|
|
defaultEditor = true;
|
|
};
|
|
bash = {
|
|
shellAliases = {
|
|
ll = "ls -lAF --classify --group-directories-first";
|
|
l = "ls -lF --classify --group-directories-first";
|
|
};
|
|
# https://nixos.wiki/wiki/Fish
|
|
interactiveShellInit = ''
|
|
if [[ $(${pkgs.procps}/bin/ps --no-header --pid=$PPID --format=comm) != "fish" && -z ''${BASH_EXECUTION_STRING} ]]
|
|
then
|
|
shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION=""
|
|
exec ${pkgs.fish}/bin/fish $LOGIN_OPTION
|
|
fi
|
|
'';
|
|
};
|
|
mtr.enable = true;
|
|
gnupg.agent = {
|
|
enable = true;
|
|
enableSSHSupport = true;
|
|
};
|
|
kdeconnect.enable = true;
|
|
chromium = {
|
|
enable = true;
|
|
extraOpts = {
|
|
"SpellcheckEnabled" = false;
|
|
"DefaultSearchProviderEnabled" = true;
|
|
"DefaultSearchProviderName" = "Kagi";
|
|
"DefaultSearchProviderSearchURL" = "https://kagi.com/search?q={searchTerms}";
|
|
"SearchSuggestEnabled" = false;
|
|
"DefaultSearchProviderSuggestURL" = "";
|
|
};
|
|
};
|
|
};
|
|
|
|
security = {
|
|
sudo.enable = false;
|
|
doas = {
|
|
enable = true;
|
|
extraRules = [
|
|
{
|
|
users = [ "blee" ];
|
|
persist = true;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
|
|
services = {
|
|
|
|
openssh.enable = true;
|
|
udev.packages = [ pkgs.via ];
|
|
|
|
# https://discourse.nixos.org/t/bluetooth-a2dp-sink-not-showing-up-in-pulseaudio-on-nixos/32447/4?u=bleetube
|
|
pipewire = {
|
|
enable = true;
|
|
pulse.enable = true;
|
|
alsa.enable = true; # for tenacity
|
|
# jack.enable = true; # this might be useful for reaper, but enabling it breaks stereo audio for some reason
|
|
};
|
|
# avahi = { # for resolving start9 hostname
|
|
# enable = true;
|
|
# nssmdns4 = true; # Enable NSS support for mDNS
|
|
# };
|
|
|
|
syncthing = {
|
|
enable = true;
|
|
user = "blee";
|
|
dataDir = "/home/blee/Documents";
|
|
};
|
|
journald.extraConfig = "MaxRetentionSec=30day";
|
|
|
|
# https://github.com/NixOS/nixpkgs/blob/nixos-23.05/nixos/modules/services/monitoring/prometheus/exporters.nix
|
|
prometheus.exporters.node = {
|
|
enable = true;
|
|
port = 8030;
|
|
# openFirewall = true;
|
|
enabledCollectors = [
|
|
"cpu.info"
|
|
"interrupts"
|
|
"netstat"
|
|
"vmstat"
|
|
"systemd"
|
|
"tcpstat"
|
|
"processes"
|
|
];
|
|
};
|
|
|
|
caddy = {
|
|
enable = true;
|
|
package = caddyWithPlugins;
|
|
|
|
# logFormat = "output discard";
|
|
logFormat = "level DEBUG";
|
|
extraConfig = let
|
|
tlsConfig = ''
|
|
tls {
|
|
dns namecheap {
|
|
api_key {env.NAMECHEAP_API_KEY}
|
|
user {env.NAMECHEAP_API_USER}
|
|
api_endpoint https://api.namecheap.com/xml.response
|
|
}
|
|
}
|
|
'';
|
|
in ''
|
|
${host_fqdn} {
|
|
${tlsConfig}
|
|
reverse_proxy http://127.0.0.1:8034 # open-webui
|
|
|
|
# handle /files/* {
|
|
# root /mnt/usb/
|
|
# file_server browse
|
|
# }
|
|
|
|
}
|
|
|
|
${host_fqdn}:4430 {
|
|
${tlsConfig}
|
|
reverse_proxy http://127.0.0.1:8030 # node_exporter
|
|
}
|
|
|
|
${host_fqdn}:4432 {
|
|
${tlsConfig}
|
|
reverse_proxy http://127.0.0.1:8032 # glance
|
|
}
|
|
|
|
${host_fqdn}:4434 {
|
|
${tlsConfig}
|
|
reverse_proxy http://127.0.0.1:8034 # open-webui
|
|
}
|
|
|
|
${host_fqdn}:4435 {
|
|
${tlsConfig}
|
|
reverse_proxy http://127.0.0.1:8035 # mealie
|
|
}
|
|
|
|
${host_fqdn}:4436 {
|
|
${tlsConfig}
|
|
reverse_proxy http://127.0.0.1:8036 # litellm
|
|
}
|
|
|
|
:9999 {
|
|
respond "success"
|
|
}
|
|
'';
|
|
};
|
|
|
|
open-webui = {
|
|
enable = true;
|
|
port = 8034;
|
|
};
|
|
|
|
litellm = {
|
|
enable = true;
|
|
port = 8036;
|
|
environmentFile = litellmEnvFile;
|
|
settings = {
|
|
litellm_settings = {
|
|
set_verbose = true;
|
|
};
|
|
model_list = [
|
|
{
|
|
model_name = "grok-3";
|
|
litellm_params = {
|
|
model = "xai/grok-3-latest";
|
|
api_key = "os.environ/XAI_API_KEY"; # LiteLLM reads this env var
|
|
};
|
|
}
|
|
{
|
|
model_name = "deepseek-r1-distill-llama-70b";
|
|
litellm_params = {
|
|
model = "groq/deepseek-r1-distill-llama-70b";
|
|
api_key = "os.environ/GROK_API_KEY"; # LiteLLM reads this env var
|
|
};
|
|
}
|
|
{
|
|
model_name = "claude-3.5-sonnet";
|
|
litellm_params = {
|
|
model = "anthropic/claude-3-5-sonnet-latest";
|
|
api_key = "os.environ/ANTHROPIC_API_KEY"; # LiteLLM reads this env var
|
|
};
|
|
}
|
|
{
|
|
model_name = "gemini-2.0-flash";
|
|
litellm_params = {
|
|
model = "gemini/gemini-2.0-flash-exp";
|
|
api_key = "os.environ/GOOGLE_API_KEY"; # LiteLLM reads this env var
|
|
safety_settings = [
|
|
{ category = "HARM_CATEGORY_HARASSMENT"; threshold = "BLOCK_NONE"; }
|
|
{ category = "HARM_CATEGORY_HATE_SPEECH"; threshold = "BLOCK_NONE"; }
|
|
{ category = "HARM_CATEGORY_SEXUALLY_EXPLICIT"; threshold = "BLOCK_NONE"; }
|
|
{ category = "HARM_CATEGORY_DANGEROUS_CONTENT"; threshold = "BLOCK_NONE"; }
|
|
];
|
|
};
|
|
}
|
|
];
|
|
};
|
|
};
|
|
|
|
|
|
mealie = {
|
|
enable = true;
|
|
port = 8035;
|
|
# listenAddress = "127.0.0.1";
|
|
listenAddress = "0.0.0.0";
|
|
# package = unstable.mealie;
|
|
};
|
|
|
|
# n8n.enable = true;
|
|
|
|
strongswan = {
|
|
enable = false;
|
|
secrets = [
|
|
"/etc/nixos/ipsec.secrets"
|
|
];
|
|
connections = {
|
|
"aws-vpn" = {
|
|
type = "tunnel";
|
|
authby = "secret";
|
|
left = "%defaultroute";
|
|
leftsubnet = "0.0.0.0/0";
|
|
right = "${secrets.aws-vpn.tunnel-address}";
|
|
rightsubnet = "10.0.64.0/24"; # subnet-0f2b39fd2ed6a88d7 "private-lambda-us-west-2d"
|
|
ike = "aes256-sha2_256-modp2048!";
|
|
esp = "aes256-sha2_256!";
|
|
ikelifetime = "8h";
|
|
keylife = "1h";
|
|
keyingtries = "3";
|
|
auto = "start";
|
|
installpolicy = "yes"; # Install IPsec policies
|
|
routing = "yes"; # Install routes
|
|
dpdaction = "restart"; # Restart connection if peer is unreachable
|
|
dpddelay = "30s"; # Dead peer detection delay
|
|
closeaction = "restart"; # Restart connection if it drops
|
|
};
|
|
};
|
|
setup = {
|
|
charondebug = "esp 2, ike 2, cfg 2, net 2, enc 2";
|
|
};
|
|
};
|
|
|
|
desktopManager.plasma6.enable = true;
|
|
displayManager = {
|
|
sddm.enable = true;
|
|
sddm.wayland.enable = true;
|
|
#defaultSession = "plasmawayland";
|
|
};
|
|
xserver.enable = true;
|
|
};
|
|
|
|
systemd = {
|
|
|
|
services.glance = {
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "network.target" ];
|
|
serviceConfig = {
|
|
User = "glance";
|
|
Group = "glance";
|
|
WorkingDirectory = "/var/lib/glance";
|
|
# Environment = "LOG_LEVEL=debug"; # https://github.com/glanceapp/glance/issues/196
|
|
ExecStart = "${pkgs.glance}/bin/glance --config config.yaml";
|
|
};
|
|
};
|
|
|
|
services.ena-vpn = {
|
|
description = "ENA Corp VPN";
|
|
# wantedBy = [ "multi-user.target" ]; # 2fa required, avoid startup
|
|
after = [ "network-online.target" ];
|
|
wants = [ "network-online.target" ];
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
User = "root";
|
|
ExecStart = "${pkgs.openfortivpn}/bin/openfortivpn -c /etc/openfortivpn/config";
|
|
};
|
|
};
|
|
|
|
services.mealie.environment = {
|
|
# https://docs.mealie.io/documentation/getting-started/installation/open-ai/
|
|
OPENAI_API_KEY = "${secrets.mealie.openai-api-key}";
|
|
};
|
|
|
|
# services.n8n.environment = {
|
|
# N8N_EDITOR_BASE_URL = "https://${host_fqdn}:4433";
|
|
# N8N_DIAGNOSTICS_ENABLED = "false"; # Also disables "Ask AI" in the code node
|
|
# N8N_HIRING_BANNER_ENABLED = "false";
|
|
# N8N_METRICS = "true";
|
|
# N8N_PORT = "8033";
|
|
# };
|
|
|
|
tmpfiles.rules = [
|
|
"d /srv/src 0775 root users - -"
|
|
];
|
|
|
|
};
|
|
|
|
# Create the OpenFortiVPN config directory and file
|
|
environment.etc = {
|
|
"openfortivpn/config" = {
|
|
text = ''
|
|
host = fortivpn.ena.net
|
|
port = 443
|
|
username = ${secrets.ena-vpn.username}
|
|
password = ${secrets.ena-vpn.password}
|
|
set-dns = 0
|
|
set-routes = 1
|
|
trusted-cert = fa59c235354ec625b0e560e4263b1eff793480f399a39b7f80b18fb865184ecd
|
|
'';
|
|
mode = "0600";
|
|
};
|
|
|
|
"ipsec.secrets" = {
|
|
text = ''
|
|
${secrets.aws-vpn.tunnel-address} : PSK "${secrets.aws-vpn.psk}"
|
|
'';
|
|
mode = "0600";
|
|
};
|
|
};
|
|
|
|
virtualisation.docker = {
|
|
enable = true;
|
|
rootless = {
|
|
enable = true;
|
|
setSocketVariable = true;
|
|
};
|
|
autoPrune = {
|
|
enable = true;
|
|
dates = "monthly";
|
|
};
|
|
};
|
|
|
|
system.stateVersion = "23.05";
|
|
}
|