chore: cleanup code

This commit is contained in:
Swarsel 2024-07-19 00:22:09 +02:00
parent 38b7687b5c
commit 9dc9a1fe1b
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
7 changed files with 1517 additions and 1621 deletions

View file

@ -839,17 +839,23 @@ No matter what you do, check the initial /etc/nixos/configuration.nix for notabl
}; };
# Bootloader # Bootloader
boot.loader.grub.enable = true; boot.loader.grub = {
boot.loader.grub.device = "/dev/sda"; # TEMPLATE - if only one disk, this will work enable = true;
boot.loader.grub.useOSProber = true; device = "/dev/sda"; # TEMPLATE - if only one disk, this will work
useOSProber = true;
};
# -------------------------------------- # --------------------------------------
# you might need a configuration like this instead: # you might need a configuration like this instead:
# Bootloader # Bootloader
# boot.loader.grub.enable = true; # boot = {
# boot.loader.grub.devices = ["nodev" ]; # kernelPackages = pkgs.linuxPackages_latest;
# boot.loader.grub.useOSProber = true; # loader.grub = {
# boot.kernelPackages = pkgs.linuxPackages_latest; # enable = true;
# devices = ["nodev" ];
# useOSProber = true;
# };
# };
# -------------------------------------- # --------------------------------------
networking.hostName = "TEMPLATE"; # Define your hostname. networking.hostName = "TEMPLATE"; # Define your hostname.
@ -988,31 +994,109 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
#+begin_src nix :noweb yes :tangle profiles/sandbox/nixos.nix #+begin_src nix :noweb yes :tangle profiles/sandbox/nixos.nix
{ config, pkgs, unstable, sops, ... }: let { config, pkgs, sops, ... }: let
matrixDomain = "swatrix.swarsel.win"; matrixDomain = "swatrix.swarsel.win";
in { in {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
# we import here a service that is not available yet on normal nixpkgs
# this module is hence not in the modules list, we add it ourselves
(unstable + "/nixos/modules/services/matrix/mautrix-signal.nix")
]; ];
boot.loader.grub = { boot.loader.grub = {
enable = true; enable = true;
device = "/dev/sda"; device = "/dev/sda";
useOSProber = true; useOSProber = true;
supportedFilesystems = [ "zfs" ];
zfs.forceImportRoot = false;
kernelModules = [ "tun" ];
kernel.sysctl = {
"net.ipv4.conf.all.rp_filter" = 2;
"net.ipv4.conf.default.rp_filter" = 2;
"net.ipv4.conf.enp7s0.rp_filter" = 2;
};
}; };
users.users.swarsel = { networking = {
hostId = "8a8ad84a";
hostName = "sandbox"; # Define your hostname.
enableIPv6 = true;
firewall.enable = false;
firewall.extraCommands = ''
sudo iptables -A OUTPUT ! -o lo -m owner --uid-owner vpn -j DROP
'';
iproute2 = {
enable = true;
rttablesExtraConfig = ''
200 vpn
'';
};
};
hardware.graphics = {
enable = true;
hardware.enableAllFirmware = true;
extraPackages = with pkgs; [
intel-media-driver # LIBVA_DRIVER_NAME=iHD
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
vaapiVdpau
libvdpau-va-gl
];
};
sound = {
enable = true;
};
users = {
groups = {
vpn = {};
mpd = {};
navidrome = {
gid = 61593;
};
spotifyd = {
gid = 65136;
};
};
users = {
jellyfin = {
extraGroups = [ "video" "render" ];
};
vpn = {
isNormalUser = true;
group = "vpn";
home = "/home/vpn";
};
navidrome = {
isSystemUser = true;
uid = 61593;
group = "navidrome";
extraGroups = [ "audio" "utmp" ];
};
spotifyd = {
isSystemUser = true;
uid = 65136;
group = "spotifyd";
extraGroups = [ "audio" "utmp" ];
};
mpd = {
isSystemUser = true;
group = "mpd";
extraGroups = [ "audio" "utmp" ];
};
swarsel = {
isNormalUser = true; isNormalUser = true;
description = "Leon S"; description = "Leon S";
extraGroups = [ "networkmanager" "wheel" "lp"]; extraGroups = [ "networkmanager" "wheel" "lp"];
packages = with pkgs; []; packages = with pkgs; [];
}; };
root = {
# actual config starts here openssh.authorizedKeys.keyFiles = [
../../secrets/keys/authorized_keys
];
};
};
};
fileSystems."/mnt/Eternor" = { fileSystems."/mnt/Eternor" = {
device = "//192.168.1.3/Eternor"; device = "//192.168.1.3/Eternor";
@ -1023,7 +1107,8 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=1000,gid=100"]; in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=1000,gid=100"];
}; };
environment.systemPackages = with pkgs; [ environment = {
systemPackages = with pkgs; [
git git
gnupg gnupg
ssh-to-age ssh-to-age
@ -1043,51 +1128,121 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
mpv mpv
zfs zfs
]; ];
etc = {
services.xserver = { "openvpn/iptables.sh" =
layout = "us"; { source = ../../scripts/server1/iptables.sh;
xkbVariant = "altgr-intl"; mode = "0755";
}; };
"openvpn/update-resolv-conf" =
nix.settings.experimental-features = ["nix-command" "flakes"]; { source = ../../scripts/server1/update-resolv-conf;
mode = "0755";
services.openssh = {
enable = true;
settings.PermitRootLogin = "yes";
listenAddresses = [{
port = 22;
addr = "0.0.0.0";
}];
}; };
users.users.root.openssh.authorizedKeys.keyFiles = [ "openvpn/routing.sh" =
../../secrets/keys/authorized_keys { source = ../../scripts/server1/routing.sh;
]; mode = "0755";
};
system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change "openvpn/ca.rsa.2048.crt" =
{ source = ../../secrets/certs/ca.rsa.2048.crt;
environment.shellAliases = { mode = "0644";
};
"openvpn/crl.rsa.2048.pem" =
{ source = ../../secrets/certs/crl.rsa.2048.pem;
mode = "0644";
};
};
shellAliases = {
nswitch = "cd ~/.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;"; nswitch = "cd ~/.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
}; };
};
boot.supportedFilesystems = [ "zfs" ]; systemd = {
boot.zfs.forceImportRoot = false; timers."restart-bridges" = {
networking.hostId = "8a8ad84a"; wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1d";
OnUnitActiveSec = "1d";
Unit = "restart-bridges.service";
};
};
networking.hostName = "sandbox"; # Define your hostname. services."restart-bridges" = {
networking.enableIPv6 = true; script = ''
networking.firewall.enable = false; systemctl restart mautrix-whatsapp.service
systemctl restart mautrix-signal.service
systemctl restart mautrix-telegram.service
'';
serviceConfig = {
Type = "oneshot";
User = "root";
};
};
};
nix.settings.experimental-features = ["nix-command" "flakes"];
system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
documentation = { documentation = {
enable = false; enable = false;
}; };
sops.age.sshKeyPaths = [ "/etc/ssh/sops" ]; sops = {
sops.defaultSopsFile = "/root/.dotfiles/secrets/sandbox/secrets.yaml"; age.sshKeyPaths = [ "/etc/ssh/sops" ];
sops.validateSopsFiles = false; defaultSopsFile = "/root/.dotfiles/secrets/sandbox/secrets.yaml";
sops.secrets.dnstokenfull = {owner="acme";}; validateSopsFiles = false;
sops.templates."certs.secret".content = '' secrets = {
dnstokenfull = {owner="acme";};
kavita = { owner = "kavita";};
vpnuser = {};
rpcuser = {owner="vpn";};
vpnpass = {};
rpcpass = {owner="vpn";};
vpnprot = {};
vpnloc = {};
mpdpass = { owner = "mpd";};
};
templates = {
"transmission-rpc" = {
owner = "vpn";
content = builtins.toJSON {
rpc-username = config.sops.placeholder.rpcuser;
rpc-password = config.sops.placeholder.rpcpass;
};
};
pia.content = ''
${config.sops.placeholder.vpnuser}
${config.sops.placeholder.vpnpass}
'';
vpn.content = ''
client
dev tun
proto ${config.sops.placeholder.vpnprot}
remote ${config.sops.placeholder.vpnloc}
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass ${config.sops.templates.pia.path}
compress
verb 1
reneg-sec 0
crl-verify /etc/openvpn/crl.rsa.2048.pem
ca /etc/openvpn/ca.rsa.2048.crt
disable-occ
'';
"certs.secret".content = ''
CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull} CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull}
''; '';
};
};
security.acme = { security.acme = {
acceptTerms = true; acceptTerms = true;
@ -1097,7 +1252,22 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
defaults.environmentFile = "${config.sops.templates."certs.secret".path}"; defaults.environmentFile = "${config.sops.templates."certs.secret".path}";
}; };
services.nginx = { services = {
xserver = {
layout = "us";
xkbVariant = "altgr-intl";
};
openssh = {
enable = true;
settings.PermitRootLogin = "yes";
listenAddresses = [{
port = 22;
addr = "0.0.0.0";
}];
};
nginx = {
enable = true; enable = true;
recommendedProxySettings = true; recommendedProxySettings = true;
recommendedTlsSettings = true; recommendedTlsSettings = true;
@ -1116,9 +1286,6 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
client_max_body_size 0; client_max_body_size 0;
''; '';
}; };
# "/push/" = {
# proxyPass = "http://192.168.2.5:7867";
# };
"/.well-known/carddav" = { "/.well-known/carddav" = {
return = "301 $scheme://$host/remote.php/dav"; return = "301 $scheme://$host/remote.php/dav";
}; };
@ -1204,167 +1371,48 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
}; };
}; };
}; };
}; };
}; };
kavita = {
sops.secrets.kavita = { owner = "kavita";};
services.kavita = {
enable = true; enable = true;
user = "kavita"; user = "kavita";
port = 8080; port = 8080;
tokenKeyFile = config.sops.secrets.kavita.path; tokenKeyFile = config.sops.secrets.kavita.path;
}; };
users.users.jellyfin = { jellyfin = {
extraGroups = [ "video" "render" ];
};
# nixpkgs.config.packageOverrides = pkgs: {
# vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
# };
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver # LIBVA_DRIVER_NAME=iHD
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
vaapiVdpau
libvdpau-va-gl
];
};
services.jellyfin = {
enable = true; enable = true;
user = "jellyfin"; user = "jellyfin";
# openFirewall = true; # this works only for the default ports
}; };
users.groups.vpn = {}; radarr = {
users.users.vpn = {
isNormalUser = true;
group = "vpn";
home = "/home/vpn";
};
boot.kernelModules = [ "tun" ];
services.radarr = {
enable = true; enable = true;
}; };
readarr = {
services.readarr = {
enable = true; enable = true;
}; };
services.sonarr = { sonarr = {
enable = true; enable = true;
}; };
services.lidarr = { lidarr = {
enable = true; enable = true;
}; };
services.prowlarr = { prowlarr = {
enable = true; enable = true;
}; };
openvpn.servers = {
networking.firewall.extraCommands = ''
sudo iptables -A OUTPUT ! -o lo -m owner --uid-owner vpn -j DROP
'';
networking.iproute2 = {
enable = true;
rttablesExtraConfig = ''
200 vpn
'';
};
boot.kernel.sysctl = {
"net.ipv4.conf.all.rp_filter" = 2;
"net.ipv4.conf.default.rp_filter" = 2;
"net.ipv4.conf.enp7s0.rp_filter" = 2;
};
environment.etc = {
"openvpn/iptables.sh" =
{ source = ../../scripts/server1/iptables.sh;
mode = "0755";
};
"openvpn/update-resolv-conf" =
{ source = ../../scripts/server1/update-resolv-conf;
mode = "0755";
};
"openvpn/routing.sh" =
{ source = ../../scripts/server1/routing.sh;
mode = "0755";
};
"openvpn/ca.rsa.2048.crt" =
{ source = ../../secrets/certs/ca.rsa.2048.crt;
mode = "0644";
};
"openvpn/crl.rsa.2048.pem" =
{ source = ../../secrets/certs/crl.rsa.2048.pem;
mode = "0644";
};
};
sops.secrets.vpnuser = {};
sops.secrets.rpcuser = {owner="vpn";};
sops.secrets.vpnpass = {};
sops.secrets.rpcpass = {owner="vpn";};
sops.secrets.vpnprot = {};
sops.secrets.vpnloc = {};
# sops.secrets.crlpem = {};
# sops.secrets.capem = {};
sops.templates."transmission-rpc".owner = "vpn";
sops.templates."transmission-rpc".content = builtins.toJSON {
rpc-username = config.sops.placeholder.rpcuser;
rpc-password = config.sops.placeholder.rpcpass;
};
sops.templates.pia.content = ''
${config.sops.placeholder.vpnuser}
${config.sops.placeholder.vpnpass}
'';
sops.templates.vpn.content = ''
client
dev tun
proto ${config.sops.placeholder.vpnprot}
remote ${config.sops.placeholder.vpnloc}
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass ${config.sops.templates.pia.path}
compress
verb 1
reneg-sec 0
crl-verify /etc/openvpn/crl.rsa.2048.pem
ca /etc/openvpn/ca.rsa.2048.crt
disable-occ
'';
services.openvpn.servers = {
pia = { pia = {
autoStart = true; autoStart = true;
updateResolvConf = false; updateResolvConf = false;
config = "config ${config.sops.templates.vpn.path}"; config = "config ${config.sops.templates.vpn.path}";
}; };
}; };
transmission = {
services.transmission = {
enable = true; enable = true;
credentialsFile = config.sops.templates."transmission-rpc".path; credentialsFile = config.sops.templates."transmission-rpc".path;
user = "vpn"; user = "vpn";
settings = { settings = {
alt-speed-down= 8000; alt-speed-down= 8000;
alt-speed-enabled= false; alt-speed-enabled= false;
alt-speed-time-begin= 0; alt-speed-time-begin= 0;
@ -1436,26 +1484,6 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
}; };
}; };
# services.nginx = {
# enable = true;
# virtualHosts = {
# "192.168.1.192" = {
# locations = {
# "/transmission" = {
# proxyPass = "http://127.0.0.1:9091";
# extraConfig = ''
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# '';
# };
# };
# };
# };
# };
# sops.secrets.matrixsharedsecret = {owner="matrix-synapse";}; # sops.secrets.matrixsharedsecret = {owner="matrix-synapse";};
# sops.templates."matrix_user_register.sh".content = '' # sops.templates."matrix_user_register.sh".content = ''
# register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008 # register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008
@ -1486,8 +1514,9 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
# MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET=${config.sops.placeholder.mautrixwhatsapp_shared} # MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET=${config.sops.placeholder.mautrixwhatsapp_shared}
# ''; # '';
services.postgresql.enable = true; postgresql = {
services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' enable = true;
initialScript = pkgs.writeText "synapse-init.sql" ''
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
TEMPLATE template0 TEMPLATE template0
@ -1509,8 +1538,8 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
LC_COLLATE = "C" LC_COLLATE = "C"
LC_CTYPE = "C"; LC_CTYPE = "C";
''; '';
};
services.matrix-synapse = { matrix-synapse = {
settings.app_service_config_files = [ settings.app_service_config_files = [
"/var/lib/matrix-synapse/telegram-registration.yaml" "/var/lib/matrix-synapse/telegram-registration.yaml"
"/var/lib/matrix-synapse/whatsapp-registration.yaml" "/var/lib/matrix-synapse/whatsapp-registration.yaml"
@ -1539,7 +1568,7 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
]; ];
}; };
services.mautrix-telegram = { mautrix-telegram = {
enable = false; enable = false;
environmentFile = config.sops.templates.mautrixtelegram.path; environmentFile = config.sops.templates.mautrixtelegram.path;
settings = { settings = {
@ -1575,12 +1604,6 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
"*" = "relaybot"; "*" = "relaybot";
"@swarsel:${matrixDomain}" = "admin"; "@swarsel:${matrixDomain}" = "admin";
}; };
# Animated stickers conversion requires additional packages in the
# service's path.
# If this isn't a fresh installation, clearing the bridge's uploaded
# file cache might be necessary (make a database backup first!):
# delete from telegram_file where \
# mime_type in ('application/gzip', 'application/octet-stream')
animated_sticker = { animated_sticker = {
target = "gif"; target = "gif";
args = { args = {
@ -1593,12 +1616,8 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
}; };
}; };
}; };
# systemd.services.mautrix-telegram.path = with pkgs; [
# lottieconverter # for animated stickers conversion, unfree package
# ffmpeg # if converting animated stickers to webm (very slow!)
# ];
services.mautrix-whatsapp = { mautrix-whatsapp = {
enable = false; enable = false;
# environmentFile = config.sops.templates.mautrixwhatsapp.path; # environmentFile = config.sops.templates.mautrixwhatsapp.path;
settings = { settings = {
@ -1645,9 +1664,8 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
}; };
}; };
services.mautrix-signal = { mautrix-signal = {
enable = false; enable = false;
# environmentFile = config.sops.templates.mautrixwhatsapp.path;
settings = { settings = {
homeserver = { homeserver = {
address = "http://localhost:8008"; address = "http://localhost:8008";
@ -1677,59 +1695,7 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
}; };
}; };
# restart the bridges daily. this is done for the signal bridge mainly which stops carrying navidrome = {
# messages out after a while.
systemd.timers."restart-bridges" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1d";
OnUnitActiveSec = "1d";
Unit = "restart-bridges.service";
};
};
systemd.services."restart-bridges" = {
script = ''
systemctl restart mautrix-whatsapp.service
systemctl restart mautrix-signal.service
systemctl restart mautrix-telegram.service
'';
serviceConfig = {
Type = "oneshot";
User = "root";
};
};
users.groups.navidrome = {
gid = 61593;
};
users.groups.mpd = {};
users.users.navidrome = {
isSystemUser = true;
uid = 61593;
group = "navidrome";
extraGroups = [ "audio" "utmp" ];
};
users.users.mpd = {
isSystemUser = true;
group = "mpd";
extraGroups = [ "audio" "utmp" ];
};
sound = {
enable = true;
};
hardware.enableAllFirmware = true;
sops.secrets.mpdpass = { owner = "mpd";};
services.navidrome = {
enable = true; enable = true;
settings = { settings = {
Address = "0.0.0.0"; Address = "0.0.0.0";
@ -1748,7 +1714,7 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
UIWelcomeMessage = "~SwarselSound~"; UIWelcomeMessage = "~SwarselSound~";
}; };
}; };
services.mpd = { mpd = {
enable = true; enable = true;
musicDirectory = "/mnt/Eternor/Musik"; musicDirectory = "/mnt/Eternor/Musik";
user = "mpd"; user = "mpd";
@ -1771,18 +1737,7 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
}; };
users.groups.spotifyd = { spotifyd = {
gid = 65136;
};
users.users.spotifyd = {
isSystemUser = true;
uid = 65136;
group = "spotifyd";
extraGroups = [ "audio" "utmp" ];
};
services.spotifyd = {
enable = true; enable = true;
settings = { settings = {
global = { global = {
@ -1798,7 +1753,7 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
# Network shares # Network shares
# add a user with sudo smbpasswd -a <user> # add a user with sudo smbpasswd -a <user>
services.samba = { samba = {
package = pkgs.samba4Full; package = pkgs.samba4Full;
extraConfig = '' extraConfig = ''
workgroup = WORKGROUP workgroup = WORKGROUP
@ -1831,7 +1786,7 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
}; };
services.avahi = { avahi = {
publish.enable = true; publish.enable = true;
publish.userServices = true; publish.userServices = true;
# ^^ Needed to allow samba to automatically register mDNS records without the need for an `extraServiceFile` # ^^ Needed to allow samba to automatically register mDNS records without the need for an `extraServiceFile`
@ -1840,20 +1795,11 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
enable = true; enable = true;
}; };
services.samba-wsdd = { samba-wsdd = {
# This enables autodiscovery on windows since SMB1 (and thus netbios) support was discontinued # This enables autodiscovery on windows since SMB1 (and thus netbios) support was discontinued
enable = true; enable = true;
}; };
};
} }
#+end_src #+end_src
@ -3923,7 +3869,6 @@ Lastly, the machine that runs matrix needs to regularly update, as otherwise you
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
# (unstable + "/nixos/modules/services/matrix/mautrix-signal.nix") # no longer needed; mautrix-signal was added to nixpkgs
]; ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
@ -5159,7 +5104,7 @@ Programming languages and default lsp's are defined here: [[#h:0e7e8bea-ec58-499
#+begin_src nix :tangle profiles/common/home.nix #+begin_src nix :tangle profiles/common/home.nix
{ config, pkgs, lib, fetchFromGitHub , ... }: { config, pkgs, fetchFromGitHub , ... }:
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [

View file

@ -3,7 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head> <head>
<!-- 2024-07-18 Do 23:36 --> <!-- 2024-07-19 Fr 00:29 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SwarselSystems: NixOS + Emacs Configuration</title> <title>SwarselSystems: NixOS + Emacs Configuration</title>
@ -387,7 +387,7 @@
</div> </div>
</div> </div>
<p> <p>
<b>This file has 41177 words spanning 10930 lines and was last revised on 2024-07-18 23:36:22 +0200.</b> <b>This file has 40971 words spanning 10908 lines and was last revised on 2024-07-19 00:29:02 +0200.</b>
</p> </p>
<p> <p>
@ -437,7 +437,7 @@ This section defines my Emacs configuration. For a while, I considered to use ry
</p> </p>
<p> <p>
My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2024-07-18 23:36:22 +0200) My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2024-07-19 00:29:02 +0200)
</p></li> </p></li>
</ul> </ul>
@ -1372,17 +1372,23 @@ No matter what you do, check the initial /etc/nixos/configuration.nix for notabl
}; };
# Bootloader # Bootloader
boot.loader.grub.enable = true; boot.loader.grub = {
boot.loader.grub.device = "/dev/sda"; # TEMPLATE - if only one disk, this will work enable = true;
boot.loader.grub.useOSProber = true; device = "/dev/sda"; # TEMPLATE - if only one disk, this will work
useOSProber = true;
};
# -------------------------------------- # --------------------------------------
# you might need a configuration like this instead: # you might need a configuration like this instead:
# Bootloader # Bootloader
# boot.loader.grub.enable = true; # boot = {
# boot.loader.grub.devices = ["nodev" ]; # kernelPackages = pkgs.linuxPackages_latest;
# boot.loader.grub.useOSProber = true; # loader.grub = {
# boot.kernelPackages = pkgs.linuxPackages_latest; # enable = true;
# devices = ["nodev" ];
# useOSProber = true;
# };
# };
# -------------------------------------- # --------------------------------------
networking.hostName = "TEMPLATE"; # Define your hostname. networking.hostName = "TEMPLATE"; # Define your hostname.
@ -1629,31 +1635,109 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
<div class="outline-text-6" id="text-h:23b0f629-343c-42fa-bf9b-70bea341c0d2"> <div class="outline-text-6" id="text-h:23b0f629-343c-42fa-bf9b-70bea341c0d2">
<div class="org-src-container"> <div class="org-src-container">
<pre class="src src-nix"> <pre class="src src-nix">
{ config, pkgs, unstable, sops, ... }: let { config, pkgs, sops, ... }: let
matrixDomain = "swatrix.swarsel.win"; matrixDomain = "swatrix.swarsel.win";
in { in {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
# we import here a service that is not available yet on normal nixpkgs
# this module is hence not in the modules list, we add it ourselves
(unstable + "/nixos/modules/services/matrix/mautrix-signal.nix")
]; ];
boot.loader.grub = { boot.loader.grub = {
enable = true; enable = true;
device = "/dev/sda"; device = "/dev/sda";
useOSProber = true; useOSProber = true;
supportedFilesystems = [ "zfs" ];
zfs.forceImportRoot = false;
kernelModules = [ "tun" ];
kernel.sysctl = {
"net.ipv4.conf.all.rp_filter" = 2;
"net.ipv4.conf.default.rp_filter" = 2;
"net.ipv4.conf.enp7s0.rp_filter" = 2;
};
}; };
users.users.swarsel = { networking = {
hostId = "8a8ad84a";
hostName = "sandbox"; # Define your hostname.
enableIPv6 = true;
firewall.enable = false;
firewall.extraCommands = ''
sudo iptables -A OUTPUT ! -o lo -m owner --uid-owner vpn -j DROP
'';
iproute2 = {
enable = true;
rttablesExtraConfig = ''
200 vpn
'';
};
};
hardware.graphics = {
enable = true;
hardware.enableAllFirmware = true;
extraPackages = with pkgs; [
intel-media-driver # LIBVA_DRIVER_NAME=iHD
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
vaapiVdpau
libvdpau-va-gl
];
};
sound = {
enable = true;
};
users = {
groups = {
vpn = {};
mpd = {};
navidrome = {
gid = 61593;
};
spotifyd = {
gid = 65136;
};
};
users = {
jellyfin = {
extraGroups = [ "video" "render" ];
};
vpn = {
isNormalUser = true;
group = "vpn";
home = "/home/vpn";
};
navidrome = {
isSystemUser = true;
uid = 61593;
group = "navidrome";
extraGroups = [ "audio" "utmp" ];
};
spotifyd = {
isSystemUser = true;
uid = 65136;
group = "spotifyd";
extraGroups = [ "audio" "utmp" ];
};
mpd = {
isSystemUser = true;
group = "mpd";
extraGroups = [ "audio" "utmp" ];
};
swarsel = {
isNormalUser = true; isNormalUser = true;
description = "Leon S"; description = "Leon S";
extraGroups = [ "networkmanager" "wheel" "lp"]; extraGroups = [ "networkmanager" "wheel" "lp"];
packages = with pkgs; []; packages = with pkgs; [];
}; };
root = {
# actual config starts here openssh.authorizedKeys.keyFiles = [
../../secrets/keys/authorized_keys
];
};
};
};
fileSystems."/mnt/Eternor" = { fileSystems."/mnt/Eternor" = {
device = "//192.168.1.3/Eternor"; device = "//192.168.1.3/Eternor";
@ -1664,7 +1748,8 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=1000,gid=100"]; in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=1000,gid=100"];
}; };
environment.systemPackages = with pkgs; [ environment = {
systemPackages = with pkgs; [
git git
gnupg gnupg
ssh-to-age ssh-to-age
@ -1684,51 +1769,121 @@ My old laptop, replaced by a new one, since most basic functions have stopped to
mpv mpv
zfs zfs
]; ];
etc = {
services.xserver = { "openvpn/iptables.sh" =
layout = "us"; { source = ../../scripts/server1/iptables.sh;
xkbVariant = "altgr-intl"; mode = "0755";
}; };
"openvpn/update-resolv-conf" =
nix.settings.experimental-features = ["nix-command" "flakes"]; { source = ../../scripts/server1/update-resolv-conf;
mode = "0755";
services.openssh = {
enable = true;
settings.PermitRootLogin = "yes";
listenAddresses = [{
port = 22;
addr = "0.0.0.0";
}];
}; };
users.users.root.openssh.authorizedKeys.keyFiles = [ "openvpn/routing.sh" =
../../secrets/keys/authorized_keys { source = ../../scripts/server1/routing.sh;
]; mode = "0755";
};
system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change "openvpn/ca.rsa.2048.crt" =
{ source = ../../secrets/certs/ca.rsa.2048.crt;
environment.shellAliases = { mode = "0644";
};
"openvpn/crl.rsa.2048.pem" =
{ source = ../../secrets/certs/crl.rsa.2048.pem;
mode = "0644";
};
};
shellAliases = {
nswitch = "cd ~/.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;"; nswitch = "cd ~/.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
}; };
};
boot.supportedFilesystems = [ "zfs" ]; systemd = {
boot.zfs.forceImportRoot = false; timers."restart-bridges" = {
networking.hostId = "8a8ad84a"; wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1d";
OnUnitActiveSec = "1d";
Unit = "restart-bridges.service";
};
};
networking.hostName = "sandbox"; # Define your hostname. services."restart-bridges" = {
networking.enableIPv6 = true; script = ''
networking.firewall.enable = false; systemctl restart mautrix-whatsapp.service
systemctl restart mautrix-signal.service
systemctl restart mautrix-telegram.service
'';
serviceConfig = {
Type = "oneshot";
User = "root";
};
};
};
nix.settings.experimental-features = ["nix-command" "flakes"];
system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
documentation = { documentation = {
enable = false; enable = false;
}; };
sops.age.sshKeyPaths = [ "/etc/ssh/sops" ]; sops = {
sops.defaultSopsFile = "/root/.dotfiles/secrets/sandbox/secrets.yaml"; age.sshKeyPaths = [ "/etc/ssh/sops" ];
sops.validateSopsFiles = false; defaultSopsFile = "/root/.dotfiles/secrets/sandbox/secrets.yaml";
sops.secrets.dnstokenfull = {owner="acme";}; validateSopsFiles = false;
sops.templates."certs.secret".content = '' secrets = {
dnstokenfull = {owner="acme";};
kavita = { owner = "kavita";};
vpnuser = {};
rpcuser = {owner="vpn";};
vpnpass = {};
rpcpass = {owner="vpn";};
vpnprot = {};
vpnloc = {};
mpdpass = { owner = "mpd";};
};
templates = {
"transmission-rpc" = {
owner = "vpn";
content = builtins.toJSON {
rpc-username = config.sops.placeholder.rpcuser;
rpc-password = config.sops.placeholder.rpcpass;
};
};
pia.content = ''
${config.sops.placeholder.vpnuser}
${config.sops.placeholder.vpnpass}
'';
vpn.content = ''
client
dev tun
proto ${config.sops.placeholder.vpnprot}
remote ${config.sops.placeholder.vpnloc}
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass ${config.sops.templates.pia.path}
compress
verb 1
reneg-sec 0
crl-verify /etc/openvpn/crl.rsa.2048.pem
ca /etc/openvpn/ca.rsa.2048.crt
disable-occ
'';
"certs.secret".content = ''
CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull} CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull}
''; '';
};
};
security.acme = { security.acme = {
acceptTerms = true; acceptTerms = true;
@ -1738,7 +1893,22 @@ networking.hostId = "8a8ad84a";
defaults.environmentFile = "${config.sops.templates."certs.secret".path}"; defaults.environmentFile = "${config.sops.templates."certs.secret".path}";
}; };
services.nginx = { services = {
xserver = {
layout = "us";
xkbVariant = "altgr-intl";
};
openssh = {
enable = true;
settings.PermitRootLogin = "yes";
listenAddresses = [{
port = 22;
addr = "0.0.0.0";
}];
};
nginx = {
enable = true; enable = true;
recommendedProxySettings = true; recommendedProxySettings = true;
recommendedTlsSettings = true; recommendedTlsSettings = true;
@ -1757,9 +1927,6 @@ networking.hostId = "8a8ad84a";
client_max_body_size 0; client_max_body_size 0;
''; '';
}; };
# "/push/" = {
# proxyPass = "http://192.168.2.5:7867";
# };
"/.well-known/carddav" = { "/.well-known/carddav" = {
return = "301 $scheme://$host/remote.php/dav"; return = "301 $scheme://$host/remote.php/dav";
}; };
@ -1845,167 +2012,48 @@ networking.hostId = "8a8ad84a";
}; };
}; };
}; };
}; };
}; };
kavita = {
sops.secrets.kavita = { owner = "kavita";};
services.kavita = {
enable = true; enable = true;
user = "kavita"; user = "kavita";
port = 8080; port = 8080;
tokenKeyFile = config.sops.secrets.kavita.path; tokenKeyFile = config.sops.secrets.kavita.path;
}; };
users.users.jellyfin = { jellyfin = {
extraGroups = [ "video" "render" ];
};
# nixpkgs.config.packageOverrides = pkgs: {
# vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
# };
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver # LIBVA_DRIVER_NAME=iHD
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
vaapiVdpau
libvdpau-va-gl
];
};
services.jellyfin = {
enable = true; enable = true;
user = "jellyfin"; user = "jellyfin";
# openFirewall = true; # this works only for the default ports
}; };
users.groups.vpn = {}; radarr = {
users.users.vpn = {
isNormalUser = true;
group = "vpn";
home = "/home/vpn";
};
boot.kernelModules = [ "tun" ];
services.radarr = {
enable = true; enable = true;
}; };
readarr = {
services.readarr = {
enable = true; enable = true;
}; };
services.sonarr = { sonarr = {
enable = true; enable = true;
}; };
services.lidarr = { lidarr = {
enable = true; enable = true;
}; };
services.prowlarr = { prowlarr = {
enable = true; enable = true;
}; };
openvpn.servers = {
networking.firewall.extraCommands = ''
sudo iptables -A OUTPUT ! -o lo -m owner --uid-owner vpn -j DROP
'';
networking.iproute2 = {
enable = true;
rttablesExtraConfig = ''
200 vpn
'';
};
boot.kernel.sysctl = {
"net.ipv4.conf.all.rp_filter" = 2;
"net.ipv4.conf.default.rp_filter" = 2;
"net.ipv4.conf.enp7s0.rp_filter" = 2;
};
environment.etc = {
"openvpn/iptables.sh" =
{ source = ../../scripts/server1/iptables.sh;
mode = "0755";
};
"openvpn/update-resolv-conf" =
{ source = ../../scripts/server1/update-resolv-conf;
mode = "0755";
};
"openvpn/routing.sh" =
{ source = ../../scripts/server1/routing.sh;
mode = "0755";
};
"openvpn/ca.rsa.2048.crt" =
{ source = ../../secrets/certs/ca.rsa.2048.crt;
mode = "0644";
};
"openvpn/crl.rsa.2048.pem" =
{ source = ../../secrets/certs/crl.rsa.2048.pem;
mode = "0644";
};
};
sops.secrets.vpnuser = {};
sops.secrets.rpcuser = {owner="vpn";};
sops.secrets.vpnpass = {};
sops.secrets.rpcpass = {owner="vpn";};
sops.secrets.vpnprot = {};
sops.secrets.vpnloc = {};
# sops.secrets.crlpem = {};
# sops.secrets.capem = {};
sops.templates."transmission-rpc".owner = "vpn";
sops.templates."transmission-rpc".content = builtins.toJSON {
rpc-username = config.sops.placeholder.rpcuser;
rpc-password = config.sops.placeholder.rpcpass;
};
sops.templates.pia.content = ''
${config.sops.placeholder.vpnuser}
${config.sops.placeholder.vpnpass}
'';
sops.templates.vpn.content = ''
client
dev tun
proto ${config.sops.placeholder.vpnprot}
remote ${config.sops.placeholder.vpnloc}
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass ${config.sops.templates.pia.path}
compress
verb 1
reneg-sec 0
crl-verify /etc/openvpn/crl.rsa.2048.pem
ca /etc/openvpn/ca.rsa.2048.crt
disable-occ
'';
services.openvpn.servers = {
pia = { pia = {
autoStart = true; autoStart = true;
updateResolvConf = false; updateResolvConf = false;
config = "config ${config.sops.templates.vpn.path}"; config = "config ${config.sops.templates.vpn.path}";
}; };
}; };
transmission = {
services.transmission = {
enable = true; enable = true;
credentialsFile = config.sops.templates."transmission-rpc".path; credentialsFile = config.sops.templates."transmission-rpc".path;
user = "vpn"; user = "vpn";
settings = { settings = {
alt-speed-down= 8000; alt-speed-down= 8000;
alt-speed-enabled= false; alt-speed-enabled= false;
alt-speed-time-begin= 0; alt-speed-time-begin= 0;
@ -2077,26 +2125,6 @@ networking.hostId = "8a8ad84a";
}; };
}; };
# services.nginx = {
# enable = true;
# virtualHosts = {
# "192.168.1.192" = {
# locations = {
# "/transmission" = {
# proxyPass = "http://127.0.0.1:9091";
# extraConfig = ''
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# '';
# };
# };
# };
# };
# };
# sops.secrets.matrixsharedsecret = {owner="matrix-synapse";}; # sops.secrets.matrixsharedsecret = {owner="matrix-synapse";};
# sops.templates."matrix_user_register.sh".content = '' # sops.templates."matrix_user_register.sh".content = ''
# register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008 # register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008
@ -2127,8 +2155,9 @@ networking.hostId = "8a8ad84a";
# MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET=${config.sops.placeholder.mautrixwhatsapp_shared} # MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET=${config.sops.placeholder.mautrixwhatsapp_shared}
# ''; # '';
services.postgresql.enable = true; postgresql = {
services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' enable = true;
initialScript = pkgs.writeText "synapse-init.sql" ''
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
TEMPLATE template0 TEMPLATE template0
@ -2150,8 +2179,8 @@ networking.hostId = "8a8ad84a";
LC_COLLATE = "C" LC_COLLATE = "C"
LC_CTYPE = "C"; LC_CTYPE = "C";
''; '';
};
services.matrix-synapse = { matrix-synapse = {
settings.app_service_config_files = [ settings.app_service_config_files = [
"/var/lib/matrix-synapse/telegram-registration.yaml" "/var/lib/matrix-synapse/telegram-registration.yaml"
"/var/lib/matrix-synapse/whatsapp-registration.yaml" "/var/lib/matrix-synapse/whatsapp-registration.yaml"
@ -2180,7 +2209,7 @@ networking.hostId = "8a8ad84a";
]; ];
}; };
services.mautrix-telegram = { mautrix-telegram = {
enable = false; enable = false;
environmentFile = config.sops.templates.mautrixtelegram.path; environmentFile = config.sops.templates.mautrixtelegram.path;
settings = { settings = {
@ -2216,12 +2245,6 @@ networking.hostId = "8a8ad84a";
"*" = "relaybot"; "*" = "relaybot";
"@swarsel:${matrixDomain}" = "admin"; "@swarsel:${matrixDomain}" = "admin";
}; };
# Animated stickers conversion requires additional packages in the
# service's path.
# If this isn't a fresh installation, clearing the bridge's uploaded
# file cache might be necessary (make a database backup first!):
# delete from telegram_file where \
# mime_type in ('application/gzip', 'application/octet-stream')
animated_sticker = { animated_sticker = {
target = "gif"; target = "gif";
args = { args = {
@ -2234,12 +2257,8 @@ networking.hostId = "8a8ad84a";
}; };
}; };
}; };
# systemd.services.mautrix-telegram.path = with pkgs; [
# lottieconverter # for animated stickers conversion, unfree package
# ffmpeg # if converting animated stickers to webm (very slow!)
# ];
services.mautrix-whatsapp = { mautrix-whatsapp = {
enable = false; enable = false;
# environmentFile = config.sops.templates.mautrixwhatsapp.path; # environmentFile = config.sops.templates.mautrixwhatsapp.path;
settings = { settings = {
@ -2286,9 +2305,8 @@ networking.hostId = "8a8ad84a";
}; };
}; };
services.mautrix-signal = { mautrix-signal = {
enable = false; enable = false;
# environmentFile = config.sops.templates.mautrixwhatsapp.path;
settings = { settings = {
homeserver = { homeserver = {
address = "http://localhost:8008"; address = "http://localhost:8008";
@ -2318,59 +2336,7 @@ networking.hostId = "8a8ad84a";
}; };
}; };
# restart the bridges daily. this is done for the signal bridge mainly which stops carrying navidrome = {
# messages out after a while.
systemd.timers."restart-bridges" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1d";
OnUnitActiveSec = "1d";
Unit = "restart-bridges.service";
};
};
systemd.services."restart-bridges" = {
script = ''
systemctl restart mautrix-whatsapp.service
systemctl restart mautrix-signal.service
systemctl restart mautrix-telegram.service
'';
serviceConfig = {
Type = "oneshot";
User = "root";
};
};
users.groups.navidrome = {
gid = 61593;
};
users.groups.mpd = {};
users.users.navidrome = {
isSystemUser = true;
uid = 61593;
group = "navidrome";
extraGroups = [ "audio" "utmp" ];
};
users.users.mpd = {
isSystemUser = true;
group = "mpd";
extraGroups = [ "audio" "utmp" ];
};
sound = {
enable = true;
};
hardware.enableAllFirmware = true;
sops.secrets.mpdpass = { owner = "mpd";};
services.navidrome = {
enable = true; enable = true;
settings = { settings = {
Address = "0.0.0.0"; Address = "0.0.0.0";
@ -2389,7 +2355,7 @@ networking.hostId = "8a8ad84a";
UIWelcomeMessage = "~SwarselSound~"; UIWelcomeMessage = "~SwarselSound~";
}; };
}; };
services.mpd = { mpd = {
enable = true; enable = true;
musicDirectory = "/mnt/Eternor/Musik"; musicDirectory = "/mnt/Eternor/Musik";
user = "mpd"; user = "mpd";
@ -2412,18 +2378,7 @@ networking.hostId = "8a8ad84a";
}; };
users.groups.spotifyd = { spotifyd = {
gid = 65136;
};
users.users.spotifyd = {
isSystemUser = true;
uid = 65136;
group = "spotifyd";
extraGroups = [ "audio" "utmp" ];
};
services.spotifyd = {
enable = true; enable = true;
settings = { settings = {
global = { global = {
@ -2439,7 +2394,7 @@ networking.hostId = "8a8ad84a";
# Network shares # Network shares
# add a user with sudo smbpasswd -a &lt;user&gt; # add a user with sudo smbpasswd -a &lt;user&gt;
services.samba = { samba = {
package = pkgs.samba4Full; package = pkgs.samba4Full;
extraConfig = '' extraConfig = ''
workgroup = WORKGROUP workgroup = WORKGROUP
@ -2472,7 +2427,7 @@ networking.hostId = "8a8ad84a";
}; };
services.avahi = { avahi = {
publish.enable = true; publish.enable = true;
publish.userServices = true; publish.userServices = true;
# ^^ Needed to allow samba to automatically register mDNS records without the need for an `extraServiceFile` # ^^ Needed to allow samba to automatically register mDNS records without the need for an `extraServiceFile`
@ -2481,20 +2436,11 @@ networking.hostId = "8a8ad84a";
enable = true; enable = true;
}; };
services.samba-wsdd = { samba-wsdd = {
# This enables autodiscovery on windows since SMB1 (and thus netbios) support was discontinued # This enables autodiscovery on windows since SMB1 (and thus netbios) support was discontinued
enable = true; enable = true;
}; };
};
} }
</pre> </pre>
@ -5020,7 +4966,6 @@ in {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
# (unstable + "/nixos/modules/services/matrix/mautrix-signal.nix") # no longer needed; mautrix-signal was added to nixpkgs
]; ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
@ -6363,7 +6308,7 @@ Programming languages and default lsp's are defined here: <a href="#h:0e7e8bea-e
<div class="outline-text-5" id="text-h:6ef9bb5f-c5ee-496e-86e2-d8d271a34d75"> <div class="outline-text-5" id="text-h:6ef9bb5f-c5ee-496e-86e2-d8d271a34d75">
<div class="org-src-container"> <div class="org-src-container">
<pre class="src src-nix"> <pre class="src src-nix">
{ config, pkgs, lib, fetchFromGitHub , ... }: { config, pkgs, fetchFromGitHub , ... }:
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [
@ -9387,6 +9332,39 @@ The standard Emacs behaviour for the Python process shell is a bit annoying. Thi
(python-shell-send-region (region-beginning) (region-end)) (python-shell-send-region (region-beginning) (region-end))
(python-shell-switch-to-shell)) (python-shell-switch-to-shell))
</pre>
</div>
</div>
</li>
<li><a id="org03da7a6"></a>Nix common prefix bracketer<br />
<div class="outline-text-5" id="text-4-2-1-15">
<p>
This function searches for common delimiters in region and removes them, summarizing all captured lines by it.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">
(defun swarsel/prefix-block (start end)
(interactive "r")
(save-excursion
(goto-char start)
(setq start (line-beginning-position))
(goto-char end)
(setq end (line-end-position))
(let ((common-prefix (save-excursion
(goto-char start)
(if (re-search-forward "^\\([^.\n]+\\)\\." end t)
(match-string 1)
(error "No common prefix found")))))
(save-excursion
(goto-char start)
(insert common-prefix " = {\n")
(goto-char (+ end (length common-prefix) 6))
(insert "};\n")
(goto-char start)
(while (re-search-forward (concat "^" (regexp-quote common-prefix) "\\.") end t)
(replace-match ""))))))
</pre> </pre>
</div> </div>
</div> </div>
@ -9753,6 +9731,10 @@ Lastly, I load the <code>highlight-indent-guides</code> package. This adds a nea
(set-face-attribute 'highlight-indent-guides-odd-face nil :background "gray20") (set-face-attribute 'highlight-indent-guides-odd-face nil :background "gray20")
(set-face-attribute 'highlight-indent-guides-stack-even-face nil :background "gray40") (set-face-attribute 'highlight-indent-guides-stack-even-face nil :background "gray40")
(set-face-attribute 'highlight-indent-guides-stack-odd-face nil :background "gray50")) (set-face-attribute 'highlight-indent-guides-stack-odd-face nil :background "gray50"))
(use-package aggressive-indent)
(global-aggressive-indent-mode 1)
</pre> </pre>
</div> </div>
</div> </div>
@ -12925,7 +12907,7 @@ My laptop, sadly soon to be replaced by a new one, since most basic functions ar
</div> </div>
<div id="postamble" class="status"> <div id="postamble" class="status">
<p class="author">Author: Leon Schwarzäugl</p> <p class="author">Author: Leon Schwarzäugl</p>
<p class="date">Created: 2024-07-18 Do 23:36</p> <p class="date">Created: 2024-07-19 Fr 00:29</p>
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p> <p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
</div> </div>
</body> </body>

View file

@ -15,17 +15,23 @@
}; };
# Bootloader # Bootloader
boot.loader.grub.enable = true; boot.loader.grub = {
boot.loader.grub.device = "/dev/sda"; # TEMPLATE - if only one disk, this will work enable = true;
boot.loader.grub.useOSProber = true; device = "/dev/sda"; # TEMPLATE - if only one disk, this will work
useOSProber = true;
};
# -------------------------------------- # --------------------------------------
# you might need a configuration like this instead: # you might need a configuration like this instead:
# Bootloader # Bootloader
# boot.loader.grub.enable = true; # boot = {
# boot.loader.grub.devices = ["nodev" ]; # kernelPackages = pkgs.linuxPackages_latest;
# boot.loader.grub.useOSProber = true; # loader.grub = {
# boot.kernelPackages = pkgs.linuxPackages_latest; # enable = true;
# devices = ["nodev" ];
# useOSProber = true;
# };
# };
# -------------------------------------- # --------------------------------------
networking.hostName = "TEMPLATE"; # Define your hostname. networking.hostName = "TEMPLATE"; # Define your hostname.

View file

@ -1,4 +1,4 @@
{ config, pkgs, lib, fetchFromGitHub , ... }: { config, pkgs, fetchFromGitHub , ... }:
{ {
home.packages = with pkgs; [ home.packages = with pkgs; [

View file

@ -4,7 +4,6 @@ in {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
# (unstable + "/nixos/modules/services/matrix/mautrix-signal.nix") # no longer needed; mautrix-signal was added to nixpkgs
]; ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [

View file

@ -1,28 +1,106 @@
{ config, pkgs, unstable, sops, ... }: let { config, pkgs, sops, ... }: let
matrixDomain = "swatrix.swarsel.win"; matrixDomain = "swatrix.swarsel.win";
in { in {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
# we import here a service that is not available yet on normal nixpkgs
# this module is hence not in the modules list, we add it ourselves
(unstable + "/nixos/modules/services/matrix/mautrix-signal.nix")
]; ];
boot.loader.grub = { boot.loader.grub = {
enable = true; enable = true;
device = "/dev/sda"; device = "/dev/sda";
useOSProber = true; useOSProber = true;
supportedFilesystems = [ "zfs" ];
zfs.forceImportRoot = false;
kernelModules = [ "tun" ];
kernel.sysctl = {
"net.ipv4.conf.all.rp_filter" = 2;
"net.ipv4.conf.default.rp_filter" = 2;
"net.ipv4.conf.enp7s0.rp_filter" = 2;
};
}; };
users.users.swarsel = { networking = {
hostId = "8a8ad84a";
hostName = "sandbox"; # Define your hostname.
enableIPv6 = true;
firewall.enable = false;
firewall.extraCommands = ''
sudo iptables -A OUTPUT ! -o lo -m owner --uid-owner vpn -j DROP
'';
iproute2 = {
enable = true;
rttablesExtraConfig = ''
200 vpn
'';
};
};
hardware.graphics = {
enable = true;
hardware.enableAllFirmware = true;
extraPackages = with pkgs; [
intel-media-driver # LIBVA_DRIVER_NAME=iHD
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
vaapiVdpau
libvdpau-va-gl
];
};
sound = {
enable = true;
};
users = {
groups = {
vpn = {};
mpd = {};
navidrome = {
gid = 61593;
};
spotifyd = {
gid = 65136;
};
};
users = {
jellyfin = {
extraGroups = [ "video" "render" ];
};
vpn = {
isNormalUser = true;
group = "vpn";
home = "/home/vpn";
};
navidrome = {
isSystemUser = true;
uid = 61593;
group = "navidrome";
extraGroups = [ "audio" "utmp" ];
};
spotifyd = {
isSystemUser = true;
uid = 65136;
group = "spotifyd";
extraGroups = [ "audio" "utmp" ];
};
mpd = {
isSystemUser = true;
group = "mpd";
extraGroups = [ "audio" "utmp" ];
};
swarsel = {
isNormalUser = true; isNormalUser = true;
description = "Leon S"; description = "Leon S";
extraGroups = [ "networkmanager" "wheel" "lp"]; extraGroups = [ "networkmanager" "wheel" "lp"];
packages = with pkgs; []; packages = with pkgs; [];
}; };
root = {
# actual config starts here openssh.authorizedKeys.keyFiles = [
../../secrets/keys/authorized_keys
];
};
};
};
fileSystems."/mnt/Eternor" = { fileSystems."/mnt/Eternor" = {
device = "//192.168.1.3/Eternor"; device = "//192.168.1.3/Eternor";
@ -33,7 +111,8 @@
in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=1000,gid=100"]; in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=1000,gid=100"];
}; };
environment.systemPackages = with pkgs; [ environment = {
systemPackages = with pkgs; [
git git
gnupg gnupg
ssh-to-age ssh-to-age
@ -53,51 +132,121 @@
mpv mpv
zfs zfs
]; ];
etc = {
services.xserver = { "openvpn/iptables.sh" =
layout = "us"; { source = ../../scripts/server1/iptables.sh;
xkbVariant = "altgr-intl"; mode = "0755";
}; };
"openvpn/update-resolv-conf" =
nix.settings.experimental-features = ["nix-command" "flakes"]; { source = ../../scripts/server1/update-resolv-conf;
mode = "0755";
services.openssh = {
enable = true;
settings.PermitRootLogin = "yes";
listenAddresses = [{
port = 22;
addr = "0.0.0.0";
}];
}; };
users.users.root.openssh.authorizedKeys.keyFiles = [ "openvpn/routing.sh" =
../../secrets/keys/authorized_keys { source = ../../scripts/server1/routing.sh;
]; mode = "0755";
};
system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change "openvpn/ca.rsa.2048.crt" =
{ source = ../../secrets/certs/ca.rsa.2048.crt;
environment.shellAliases = { mode = "0644";
};
"openvpn/crl.rsa.2048.pem" =
{ source = ../../secrets/certs/crl.rsa.2048.pem;
mode = "0644";
};
};
shellAliases = {
nswitch = "cd ~/.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;"; nswitch = "cd ~/.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
}; };
};
boot.supportedFilesystems = [ "zfs" ]; systemd = {
boot.zfs.forceImportRoot = false; timers."restart-bridges" = {
networking.hostId = "8a8ad84a"; wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1d";
OnUnitActiveSec = "1d";
Unit = "restart-bridges.service";
};
};
networking.hostName = "sandbox"; # Define your hostname. services."restart-bridges" = {
networking.enableIPv6 = true; script = ''
networking.firewall.enable = false; systemctl restart mautrix-whatsapp.service
systemctl restart mautrix-signal.service
systemctl restart mautrix-telegram.service
'';
serviceConfig = {
Type = "oneshot";
User = "root";
};
};
};
nix.settings.experimental-features = ["nix-command" "flakes"];
system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
documentation = { documentation = {
enable = false; enable = false;
}; };
sops.age.sshKeyPaths = [ "/etc/ssh/sops" ]; sops = {
sops.defaultSopsFile = "/root/.dotfiles/secrets/sandbox/secrets.yaml"; age.sshKeyPaths = [ "/etc/ssh/sops" ];
sops.validateSopsFiles = false; defaultSopsFile = "/root/.dotfiles/secrets/sandbox/secrets.yaml";
sops.secrets.dnstokenfull = {owner="acme";}; validateSopsFiles = false;
sops.templates."certs.secret".content = '' secrets = {
dnstokenfull = {owner="acme";};
kavita = { owner = "kavita";};
vpnuser = {};
rpcuser = {owner="vpn";};
vpnpass = {};
rpcpass = {owner="vpn";};
vpnprot = {};
vpnloc = {};
mpdpass = { owner = "mpd";};
};
templates = {
"transmission-rpc" = {
owner = "vpn";
content = builtins.toJSON {
rpc-username = config.sops.placeholder.rpcuser;
rpc-password = config.sops.placeholder.rpcpass;
};
};
pia.content = ''
${config.sops.placeholder.vpnuser}
${config.sops.placeholder.vpnpass}
'';
vpn.content = ''
client
dev tun
proto ${config.sops.placeholder.vpnprot}
remote ${config.sops.placeholder.vpnloc}
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass ${config.sops.templates.pia.path}
compress
verb 1
reneg-sec 0
crl-verify /etc/openvpn/crl.rsa.2048.pem
ca /etc/openvpn/ca.rsa.2048.crt
disable-occ
'';
"certs.secret".content = ''
CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull} CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull}
''; '';
};
};
security.acme = { security.acme = {
acceptTerms = true; acceptTerms = true;
@ -107,7 +256,22 @@ networking.hostId = "8a8ad84a";
defaults.environmentFile = "${config.sops.templates."certs.secret".path}"; defaults.environmentFile = "${config.sops.templates."certs.secret".path}";
}; };
services.nginx = { services = {
xserver = {
layout = "us";
xkbVariant = "altgr-intl";
};
openssh = {
enable = true;
settings.PermitRootLogin = "yes";
listenAddresses = [{
port = 22;
addr = "0.0.0.0";
}];
};
nginx = {
enable = true; enable = true;
recommendedProxySettings = true; recommendedProxySettings = true;
recommendedTlsSettings = true; recommendedTlsSettings = true;
@ -126,9 +290,6 @@ networking.hostId = "8a8ad84a";
client_max_body_size 0; client_max_body_size 0;
''; '';
}; };
# "/push/" = {
# proxyPass = "http://192.168.2.5:7867";
# };
"/.well-known/carddav" = { "/.well-known/carddav" = {
return = "301 $scheme://$host/remote.php/dav"; return = "301 $scheme://$host/remote.php/dav";
}; };
@ -214,167 +375,48 @@ networking.hostId = "8a8ad84a";
}; };
}; };
}; };
}; };
}; };
kavita = {
sops.secrets.kavita = { owner = "kavita";};
services.kavita = {
enable = true; enable = true;
user = "kavita"; user = "kavita";
port = 8080; port = 8080;
tokenKeyFile = config.sops.secrets.kavita.path; tokenKeyFile = config.sops.secrets.kavita.path;
}; };
users.users.jellyfin = { jellyfin = {
extraGroups = [ "video" "render" ];
};
# nixpkgs.config.packageOverrides = pkgs: {
# vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
# };
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver # LIBVA_DRIVER_NAME=iHD
vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
vaapiVdpau
libvdpau-va-gl
];
};
services.jellyfin = {
enable = true; enable = true;
user = "jellyfin"; user = "jellyfin";
# openFirewall = true; # this works only for the default ports
}; };
users.groups.vpn = {}; radarr = {
users.users.vpn = {
isNormalUser = true;
group = "vpn";
home = "/home/vpn";
};
boot.kernelModules = [ "tun" ];
services.radarr = {
enable = true; enable = true;
}; };
readarr = {
services.readarr = {
enable = true; enable = true;
}; };
services.sonarr = { sonarr = {
enable = true; enable = true;
}; };
services.lidarr = { lidarr = {
enable = true; enable = true;
}; };
services.prowlarr = { prowlarr = {
enable = true; enable = true;
}; };
openvpn.servers = {
networking.firewall.extraCommands = ''
sudo iptables -A OUTPUT ! -o lo -m owner --uid-owner vpn -j DROP
'';
networking.iproute2 = {
enable = true;
rttablesExtraConfig = ''
200 vpn
'';
};
boot.kernel.sysctl = {
"net.ipv4.conf.all.rp_filter" = 2;
"net.ipv4.conf.default.rp_filter" = 2;
"net.ipv4.conf.enp7s0.rp_filter" = 2;
};
environment.etc = {
"openvpn/iptables.sh" =
{ source = ../../scripts/server1/iptables.sh;
mode = "0755";
};
"openvpn/update-resolv-conf" =
{ source = ../../scripts/server1/update-resolv-conf;
mode = "0755";
};
"openvpn/routing.sh" =
{ source = ../../scripts/server1/routing.sh;
mode = "0755";
};
"openvpn/ca.rsa.2048.crt" =
{ source = ../../secrets/certs/ca.rsa.2048.crt;
mode = "0644";
};
"openvpn/crl.rsa.2048.pem" =
{ source = ../../secrets/certs/crl.rsa.2048.pem;
mode = "0644";
};
};
sops.secrets.vpnuser = {};
sops.secrets.rpcuser = {owner="vpn";};
sops.secrets.vpnpass = {};
sops.secrets.rpcpass = {owner="vpn";};
sops.secrets.vpnprot = {};
sops.secrets.vpnloc = {};
# sops.secrets.crlpem = {};
# sops.secrets.capem = {};
sops.templates."transmission-rpc".owner = "vpn";
sops.templates."transmission-rpc".content = builtins.toJSON {
rpc-username = config.sops.placeholder.rpcuser;
rpc-password = config.sops.placeholder.rpcpass;
};
sops.templates.pia.content = ''
${config.sops.placeholder.vpnuser}
${config.sops.placeholder.vpnpass}
'';
sops.templates.vpn.content = ''
client
dev tun
proto ${config.sops.placeholder.vpnprot}
remote ${config.sops.placeholder.vpnloc}
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass ${config.sops.templates.pia.path}
compress
verb 1
reneg-sec 0
crl-verify /etc/openvpn/crl.rsa.2048.pem
ca /etc/openvpn/ca.rsa.2048.crt
disable-occ
'';
services.openvpn.servers = {
pia = { pia = {
autoStart = true; autoStart = true;
updateResolvConf = false; updateResolvConf = false;
config = "config ${config.sops.templates.vpn.path}"; config = "config ${config.sops.templates.vpn.path}";
}; };
}; };
transmission = {
services.transmission = {
enable = true; enable = true;
credentialsFile = config.sops.templates."transmission-rpc".path; credentialsFile = config.sops.templates."transmission-rpc".path;
user = "vpn"; user = "vpn";
settings = { settings = {
alt-speed-down= 8000; alt-speed-down= 8000;
alt-speed-enabled= false; alt-speed-enabled= false;
alt-speed-time-begin= 0; alt-speed-time-begin= 0;
@ -446,26 +488,6 @@ networking.hostId = "8a8ad84a";
}; };
}; };
# services.nginx = {
# enable = true;
# virtualHosts = {
# "192.168.1.192" = {
# locations = {
# "/transmission" = {
# proxyPass = "http://127.0.0.1:9091";
# extraConfig = ''
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# '';
# };
# };
# };
# };
# };
# sops.secrets.matrixsharedsecret = {owner="matrix-synapse";}; # sops.secrets.matrixsharedsecret = {owner="matrix-synapse";};
# sops.templates."matrix_user_register.sh".content = '' # sops.templates."matrix_user_register.sh".content = ''
# register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008 # register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008
@ -496,8 +518,9 @@ networking.hostId = "8a8ad84a";
# MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET=${config.sops.placeholder.mautrixwhatsapp_shared} # MAUTRIX_WHATSAPP_BRIDGE_LOGIN_SHARED_SECRET=${config.sops.placeholder.mautrixwhatsapp_shared}
# ''; # '';
services.postgresql.enable = true; postgresql = {
services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' enable = true;
initialScript = pkgs.writeText "synapse-init.sql" ''
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
TEMPLATE template0 TEMPLATE template0
@ -519,8 +542,8 @@ networking.hostId = "8a8ad84a";
LC_COLLATE = "C" LC_COLLATE = "C"
LC_CTYPE = "C"; LC_CTYPE = "C";
''; '';
};
services.matrix-synapse = { matrix-synapse = {
settings.app_service_config_files = [ settings.app_service_config_files = [
"/var/lib/matrix-synapse/telegram-registration.yaml" "/var/lib/matrix-synapse/telegram-registration.yaml"
"/var/lib/matrix-synapse/whatsapp-registration.yaml" "/var/lib/matrix-synapse/whatsapp-registration.yaml"
@ -549,7 +572,7 @@ networking.hostId = "8a8ad84a";
]; ];
}; };
services.mautrix-telegram = { mautrix-telegram = {
enable = false; enable = false;
environmentFile = config.sops.templates.mautrixtelegram.path; environmentFile = config.sops.templates.mautrixtelegram.path;
settings = { settings = {
@ -585,12 +608,6 @@ networking.hostId = "8a8ad84a";
"*" = "relaybot"; "*" = "relaybot";
"@swarsel:${matrixDomain}" = "admin"; "@swarsel:${matrixDomain}" = "admin";
}; };
# Animated stickers conversion requires additional packages in the
# service's path.
# If this isn't a fresh installation, clearing the bridge's uploaded
# file cache might be necessary (make a database backup first!):
# delete from telegram_file where \
# mime_type in ('application/gzip', 'application/octet-stream')
animated_sticker = { animated_sticker = {
target = "gif"; target = "gif";
args = { args = {
@ -603,12 +620,8 @@ networking.hostId = "8a8ad84a";
}; };
}; };
}; };
# systemd.services.mautrix-telegram.path = with pkgs; [
# lottieconverter # for animated stickers conversion, unfree package
# ffmpeg # if converting animated stickers to webm (very slow!)
# ];
services.mautrix-whatsapp = { mautrix-whatsapp = {
enable = false; enable = false;
# environmentFile = config.sops.templates.mautrixwhatsapp.path; # environmentFile = config.sops.templates.mautrixwhatsapp.path;
settings = { settings = {
@ -655,9 +668,8 @@ networking.hostId = "8a8ad84a";
}; };
}; };
services.mautrix-signal = { mautrix-signal = {
enable = false; enable = false;
# environmentFile = config.sops.templates.mautrixwhatsapp.path;
settings = { settings = {
homeserver = { homeserver = {
address = "http://localhost:8008"; address = "http://localhost:8008";
@ -687,59 +699,7 @@ networking.hostId = "8a8ad84a";
}; };
}; };
# restart the bridges daily. this is done for the signal bridge mainly which stops carrying navidrome = {
# messages out after a while.
systemd.timers."restart-bridges" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "1d";
OnUnitActiveSec = "1d";
Unit = "restart-bridges.service";
};
};
systemd.services."restart-bridges" = {
script = ''
systemctl restart mautrix-whatsapp.service
systemctl restart mautrix-signal.service
systemctl restart mautrix-telegram.service
'';
serviceConfig = {
Type = "oneshot";
User = "root";
};
};
users.groups.navidrome = {
gid = 61593;
};
users.groups.mpd = {};
users.users.navidrome = {
isSystemUser = true;
uid = 61593;
group = "navidrome";
extraGroups = [ "audio" "utmp" ];
};
users.users.mpd = {
isSystemUser = true;
group = "mpd";
extraGroups = [ "audio" "utmp" ];
};
sound = {
enable = true;
};
hardware.enableAllFirmware = true;
sops.secrets.mpdpass = { owner = "mpd";};
services.navidrome = {
enable = true; enable = true;
settings = { settings = {
Address = "0.0.0.0"; Address = "0.0.0.0";
@ -758,7 +718,7 @@ networking.hostId = "8a8ad84a";
UIWelcomeMessage = "~SwarselSound~"; UIWelcomeMessage = "~SwarselSound~";
}; };
}; };
services.mpd = { mpd = {
enable = true; enable = true;
musicDirectory = "/mnt/Eternor/Musik"; musicDirectory = "/mnt/Eternor/Musik";
user = "mpd"; user = "mpd";
@ -781,18 +741,7 @@ networking.hostId = "8a8ad84a";
}; };
users.groups.spotifyd = { spotifyd = {
gid = 65136;
};
users.users.spotifyd = {
isSystemUser = true;
uid = 65136;
group = "spotifyd";
extraGroups = [ "audio" "utmp" ];
};
services.spotifyd = {
enable = true; enable = true;
settings = { settings = {
global = { global = {
@ -808,7 +757,7 @@ networking.hostId = "8a8ad84a";
# Network shares # Network shares
# add a user with sudo smbpasswd -a <user> # add a user with sudo smbpasswd -a <user>
services.samba = { samba = {
package = pkgs.samba4Full; package = pkgs.samba4Full;
extraConfig = '' extraConfig = ''
workgroup = WORKGROUP workgroup = WORKGROUP
@ -841,7 +790,7 @@ networking.hostId = "8a8ad84a";
}; };
services.avahi = { avahi = {
publish.enable = true; publish.enable = true;
publish.userServices = true; publish.userServices = true;
# ^^ Needed to allow samba to automatically register mDNS records without the need for an `extraServiceFile` # ^^ Needed to allow samba to automatically register mDNS records without the need for an `extraServiceFile`
@ -850,18 +799,9 @@ networking.hostId = "8a8ad84a";
enable = true; enable = true;
}; };
services.samba-wsdd = { samba-wsdd = {
# This enables autodiscovery on windows since SMB1 (and thus netbios) support was discontinued # This enables autodiscovery on windows since SMB1 (and thus netbios) support was discontinued
enable = true; enable = true;
}; };
};
} }

View file

@ -247,6 +247,27 @@ create a new one."
(python-shell-send-region (region-beginning) (region-end)) (python-shell-send-region (region-beginning) (region-end))
(python-shell-switch-to-shell)) (python-shell-switch-to-shell))
(defun swarsel/prefix-block (start end)
(interactive "r")
(save-excursion
(goto-char start)
(setq start (line-beginning-position))
(goto-char end)
(setq end (line-end-position))
(let ((common-prefix (save-excursion
(goto-char start)
(if (re-search-forward "^\\([^.\n]+\\)\\." end t)
(match-string 1)
(error "No common prefix found")))))
(save-excursion
(goto-char start)
(insert common-prefix " = {\n")
(goto-char (+ end (length common-prefix) 6))
(insert "};\n")
(goto-char start)
(while (re-search-forward (concat "^" (regexp-quote common-prefix) "\\.") end t)
(replace-match ""))))))
;; Make ESC quit prompts ;; Make ESC quit prompts
(global-set-key (kbd "<escape>") 'keyboard-escape-quit) (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
@ -475,6 +496,9 @@ create a new one."
(set-face-attribute 'highlight-indent-guides-stack-even-face nil :background "gray40") (set-face-attribute 'highlight-indent-guides-stack-even-face nil :background "gray40")
(set-face-attribute 'highlight-indent-guides-stack-odd-face nil :background "gray50")) (set-face-attribute 'highlight-indent-guides-stack-odd-face nil :background "gray50"))
(use-package aggressive-indent)
(global-aggressive-indent-mode 1)
(setq mouse-wheel-scroll-amount (setq mouse-wheel-scroll-amount
'(1 '(1
((shift) . 5) ((shift) . 5)