feat(modules): system services, security, polkit and apparmor
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
620af4f502
commit
1d90e18860
2 changed files with 957 additions and 0 deletions
405
modules/services.nix
Normal file
405
modules/services.nix
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.omni;
|
||||
in
|
||||
{
|
||||
# XDG portal config is in modules/desktop/hyprland.nix
|
||||
|
||||
# Tuigreet display manager
|
||||
# Write HM's generated Hyprland config to /etc so it's available before HM activation
|
||||
environment.etc."hypr/hyprland.conf" = lib.mkIf (config.programs.hyprland.enable or false) {
|
||||
source = config.home-manager.users.${cfg.user}.xdg.configFile."hypr/hyprland.conf".source;
|
||||
};
|
||||
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
settings.default_session.command =
|
||||
let
|
||||
hyprland-session = pkgs.writeShellScript "hyprland-session" ''
|
||||
export HOME="''${HOME:-/home/$(whoami)}"
|
||||
mkdir -p "$HOME/.config/hypr"
|
||||
cp -f /etc/hypr/hyprland.conf "$HOME/.config/hypr/hyprland.conf" 2>/dev/null || true
|
||||
exec start-hyprland
|
||||
'';
|
||||
in
|
||||
"${pkgs.tuigreet}/bin/tuigreet --time --cmd ${hyprland-session}";
|
||||
};
|
||||
|
||||
# System services configuration
|
||||
services = {
|
||||
# Display server
|
||||
xserver = {
|
||||
enable = true;
|
||||
excludePackages = [ pkgs.xterm ];
|
||||
|
||||
xkb = {
|
||||
layout = "us";
|
||||
variant = "";
|
||||
options = "caps:escape,compose:ralt";
|
||||
};
|
||||
};
|
||||
|
||||
# Display Manager (disabled - using greetd instead)
|
||||
displayManager.gdm.enable = false;
|
||||
|
||||
# Touchpad support
|
||||
libinput = {
|
||||
enable = true;
|
||||
touchpad = {
|
||||
naturalScrolling = true;
|
||||
tapping = true;
|
||||
clickMethod = "clickfinger";
|
||||
};
|
||||
};
|
||||
|
||||
# Printing support
|
||||
printing = {
|
||||
enable = true;
|
||||
drivers = with pkgs; [
|
||||
gutenprint
|
||||
gutenprintBin
|
||||
hplip
|
||||
epson-escpr
|
||||
epson-escpr2
|
||||
];
|
||||
};
|
||||
|
||||
# Sound — disable PulseAudio in favor of PipeWire
|
||||
pulseaudio.enable = false;
|
||||
pipewire = {
|
||||
enable = true;
|
||||
alsa = {
|
||||
enable = true;
|
||||
support32Bit = true;
|
||||
};
|
||||
pulse.enable = true;
|
||||
jack.enable = true;
|
||||
wireplumber = {
|
||||
enable = true;
|
||||
# Workaround: libldac-dec decoder init crashes (LDACBT_ERR_FATAL) on
|
||||
# PipeWire 1.6.2, causing silent audio failure with no fallback.
|
||||
# Remove once nixpkgs#502690 lands in our channel.
|
||||
extraConfig."bluetooth" = {
|
||||
"monitor.bluez.properties" = {
|
||||
"bluez5.codecs" = [
|
||||
"sbc"
|
||||
"sbc_xq"
|
||||
"aac"
|
||||
"aptx"
|
||||
"aptx_hd"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Network
|
||||
resolved = {
|
||||
enable = true;
|
||||
settings.Resolve = {
|
||||
DNSSEC = "true";
|
||||
Domains = [ "~." ];
|
||||
FallbackDNS = [
|
||||
"1.1.1.1"
|
||||
"8.8.8.8"
|
||||
"1.0.0.1"
|
||||
"8.8.4.4"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Bluetooth
|
||||
blueman.enable = true;
|
||||
|
||||
# Power management
|
||||
power-profiles-daemon.enable = true;
|
||||
thermald.enable = true;
|
||||
upower = {
|
||||
enable = true;
|
||||
percentageLow = 15;
|
||||
percentageCritical = 5;
|
||||
percentageAction = 3;
|
||||
};
|
||||
|
||||
# System monitoring
|
||||
smartd = {
|
||||
enable = true;
|
||||
autodetect = true;
|
||||
};
|
||||
|
||||
# File indexing and search
|
||||
locate = {
|
||||
enable = true;
|
||||
interval = "daily";
|
||||
package = pkgs.plocate;
|
||||
};
|
||||
|
||||
# Backup service (optional)
|
||||
restic = {
|
||||
backups = {
|
||||
# Example backup configuration
|
||||
# home = {
|
||||
# paths = [ "/home/${cfg.user}" ];
|
||||
# repository = "/backup/restic";
|
||||
# passwordFile = "/etc/restic/password";
|
||||
# timerConfig = {
|
||||
# OnCalendar = "daily";
|
||||
# Persistent = true;
|
||||
# };
|
||||
# pruneOpts = [
|
||||
# "--keep-daily 7"
|
||||
# "--keep-weekly 4"
|
||||
# "--keep-monthly 12"
|
||||
# ];
|
||||
# };
|
||||
};
|
||||
};
|
||||
|
||||
# SSH daemon
|
||||
openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PermitRootLogin = "no";
|
||||
PasswordAuthentication = false;
|
||||
KbdInteractiveAuthentication = false;
|
||||
X11Forwarding = false;
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall
|
||||
fail2ban = {
|
||||
enable = true;
|
||||
maxretry = 3;
|
||||
bantime = "1h";
|
||||
bantime-increment.enable = true;
|
||||
};
|
||||
|
||||
# System maintenance
|
||||
fstrim = {
|
||||
enable = true;
|
||||
interval = "weekly";
|
||||
};
|
||||
|
||||
# Scheduled tasks
|
||||
cron = {
|
||||
enable = true;
|
||||
systemCronJobs = [
|
||||
# Example: Update system database daily
|
||||
# "0 3 * * * root ${pkgs.nix-index}/bin/nix-index"
|
||||
];
|
||||
};
|
||||
|
||||
# Syncthing for file synchronization
|
||||
syncthing = {
|
||||
enable = false; # Set to true to enable
|
||||
user = cfg.user;
|
||||
dataDir = "/home/${cfg.user}/Documents";
|
||||
configDir = "/home/${cfg.user}/.config/syncthing";
|
||||
};
|
||||
|
||||
# Tailscale VPN
|
||||
tailscale = {
|
||||
enable = false; # Set to true to enable
|
||||
useRoutingFeatures = "client";
|
||||
};
|
||||
|
||||
# Flatpak support
|
||||
flatpak.enable = config.xdg.portal.enable;
|
||||
|
||||
# GVFS for mounting and trash support
|
||||
gvfs.enable = true;
|
||||
|
||||
# Thumbnail generation
|
||||
tumbler.enable = true;
|
||||
|
||||
# Notification daemon is handled by mako in Hyprland config
|
||||
|
||||
# System daemons
|
||||
dbus = {
|
||||
enable = true;
|
||||
packages = with pkgs; [ dconf ];
|
||||
};
|
||||
|
||||
# Secret storage for Electron apps (Signal, Ferdium, etc.)
|
||||
gnome.gnome-keyring.enable = true;
|
||||
|
||||
# Avahi for network discovery
|
||||
avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
publish = {
|
||||
enable = true;
|
||||
addresses = true;
|
||||
domain = true;
|
||||
workstation = true;
|
||||
userServices = true;
|
||||
};
|
||||
};
|
||||
|
||||
# ACPI daemon for power management
|
||||
acpid.enable = true;
|
||||
|
||||
# Firmware updates via LVFS
|
||||
fwupd.enable = true;
|
||||
|
||||
# Automatic upgrades (disabled by default)
|
||||
# system.autoUpgrade = {
|
||||
# enable = true;
|
||||
# allowReboot = false;
|
||||
# dates = "04:00";
|
||||
# flake = "/etc/nixos#omni";
|
||||
# };
|
||||
|
||||
# Earlyoom - out of memory killer
|
||||
earlyoom = {
|
||||
enable = true;
|
||||
freeMemThreshold = 5;
|
||||
freeSwapThreshold = 10;
|
||||
};
|
||||
|
||||
# Logrotate
|
||||
logrotate = {
|
||||
enable = true;
|
||||
settings = {
|
||||
"/var/log/omni/*.log" = {
|
||||
frequency = "weekly";
|
||||
rotate = 4;
|
||||
compress = true;
|
||||
delaycompress = true;
|
||||
notifempty = true;
|
||||
create = "644 root root";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Systemd services
|
||||
systemd = {
|
||||
# User session environment.
|
||||
# systemd.user.extraConfig was removed upstream; the [Manager] section is
|
||||
# now expressed via the structured systemd.user.settings.Manager attrset.
|
||||
user.settings.Manager.DefaultEnvironment = ''"PATH=/run/wrappers/bin:/home/${cfg.user}/.nix-profile/bin:/etc/profiles/per-user/${cfg.user}/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin"'';
|
||||
|
||||
# Automatic cleanup
|
||||
timers.clear-tmp = {
|
||||
description = "Clear /tmp weekly";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "weekly";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
|
||||
services.clear-tmp = {
|
||||
description = "Clear /tmp directory";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.coreutils}/bin/find /tmp -type f -atime +7 -delete";
|
||||
};
|
||||
};
|
||||
|
||||
# Custom Omarchy services
|
||||
services.omni-init = {
|
||||
description = "Omarchy initialization service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = pkgs.writeShellScript "omni-init" ''
|
||||
#!/usr/bin/env bash
|
||||
echo "Initializing Omarchy..."
|
||||
|
||||
# Create necessary directories
|
||||
mkdir -p /var/log/omni
|
||||
mkdir -p /var/lib/omni
|
||||
mkdir -p /etc/omni
|
||||
|
||||
# Set up initial configuration
|
||||
if [ ! -f /etc/omni/initialized ]; then
|
||||
echo "$(date): Omnixient initialized" > /etc/omni/initialized
|
||||
echo "Welcome to Omarchy!" > /etc/motd
|
||||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Unlock gnome-keyring on login
|
||||
security.pam.services.greetd.enableGnomeKeyring = true;
|
||||
|
||||
# Signal Messenger uses its own self-signed root CA for certificate pinning.
|
||||
# Add it to the system trust store so Electron/curl can connect.
|
||||
security.pki.certificates = [
|
||||
''
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
9qfgAJizyy3kqM4lOwBH
|
||||
-----END CERTIFICATE-----
|
||||
''
|
||||
];
|
||||
|
||||
# Security policies
|
||||
security = {
|
||||
# Required for PipeWire real-time scheduling
|
||||
rtkit.enable = true;
|
||||
|
||||
polkit = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
/* Allow members of wheel group to manage systemd services without password */
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.freedesktop.systemd1.manage-units" &&
|
||||
subject.isInGroup("wheel")) {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
'';
|
||||
};
|
||||
|
||||
# AppArmor
|
||||
apparmor = {
|
||||
enable = true;
|
||||
packages = with pkgs; [
|
||||
apparmor-utils
|
||||
apparmor-profiles
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue