Compare commits

...

15 commits

22 changed files with 335 additions and 13 deletions

View file

@ -12,5 +12,6 @@ _: {
./btop.nix
./bottom.nix
./bat.nix
./nix-index.nix
];
}

View file

@ -17,7 +17,7 @@ in
userEmail = myGitConf.userEmail;
signing = {
signByDefault = myGitConf.signing.enabled;
signByDefault = myGitConf.signing.enable;
key = myGitConf.signing.key;
};

View file

@ -0,0 +1,12 @@
{ config, ... }: {
programs = {
# nix-index is a file database for nixpkgs
# this provides `nix-locate` command.
nix-index = {
enable = true;
# Attempt to find the package that contains the non-existent command
enableBashIntegration = config.programs.bash.enable;
enableZshIntegration = config.programs.zsh.enable;
};
};
}

View file

@ -16,6 +16,7 @@ in
./vbox_nix
inputs.home-manager.nixosModules.home-manager
inputs.impermanence.nixosModules.impermanence
inputs.lanzaboote.nixosModules.lanzaboote
] ++ shared;
};

View file

@ -59,6 +59,13 @@
hasTPM = true;
};
security = {
auditd = {
enable = true;
autoPrune.enable = true;
};
};
workstation = {
printing.enable = true;
};
@ -70,7 +77,7 @@
userName = "ItsDrike";
userEmail = "itsdrike@protonmail.com";
signing = {
enabled = true;
enable = true;
key = "FA2745890B7048C0";
};
};

View file

@ -22,19 +22,48 @@
system = {
hostname = "vboxnix";
username = "itsdrike";
impermanence = {
root.enable = false;
autoWipeBtrfs.enable = false;
};
boot = {
secure-boot.enable = false;
tmpOnTmpfs = false;
};
};
device = {
type = "desktop";
virtual-machine = true;
roles = {
type = "desktop";
virtual-machine = true;
};
cpu.type = "amd";
hasTPM = false;
};
security = {
auditd = {
enable = true;
autoPrune.enable = true;
};
};
workstation = {
printing.enable = false;
};
home-manager = {
enable = true;
stateVersion = "23.11";
git = {
userName = "ItsDrike";
userEmail = "itsdrike@protonmail.com";
signing.key = "FA2745890B7048C0";
signing = {
enable = true;
key = "FA2745890B7048C0";
};
};
};
};

View file

@ -4,5 +4,6 @@ _: {
./home
./system
./workstation
./security
];
}

View file

@ -15,7 +15,7 @@ in
};
signing = {
enabled = mkEnableOption ''
enable = mkEnableOption ''
git commit signing.
Requires `myOptions.home-manager.git.signing.key` to be set.
'';

View file

@ -0,0 +1,61 @@
{ lib, config, ... }: with lib; let
inherit (lib) mkEnableOption mkOption literalExpression types;
in
{
options.myOptions.security.auditd = {
enable = mkEnableOption "the audit daemon.";
autoPrune = {
enable = mkEnableOption ''
automatic pruning of audit logs.
Enabling this is HEAVILY recommended, as audit logs
can grow very large very quickly.
'';
size = mkOption {
type = types.int;
default = 524288000; # roughly 500MB
description = ''
The maximum size of the audit log in bytes.
The default is 500MB.
'';
};
schedule = mkOption {
type = types.str;
default = "daily";
example = "weekly";
description = "How often cleaning is triggered. Passed to systemd.time";
};
};
extraFiles = mkOption {
default = [];
type = types.listOf types.path;
example = literalExpression ''["/etc/nix/id_rsa"]'';
description = ''
Additional files in root to link to persistent storage.
'';
};
extraDirectories = mkOption {
default = [];
type = types.listOf types.path;
example = literalExpression ''["/etc/nix/id_rsa"]'';
description = ''
Additional directories in root to link to persistent storage.
'';
};
persistentMountPoint = mkOption {
default = "/persist";
description = ''
Path to a persistent directory (usually a mount point to a
standalone partition / subvolume), which will hold the persistent
system state files.
'';
};
};
}

View file

@ -0,0 +1,5 @@
{
imports = [
./auditd.nix
];
}

View file

@ -85,4 +85,13 @@ in
};
};
};
config = {
assertions = [
{
assertion = cfg.autoWipeBtrfs.enable -> cfg.root.enable;
message = "myOptions.system.impermanence.autoWipeBtrfs requires myOptions.system.impermanence.root to be enabled.";
}
];
};
}

View file

@ -1,5 +1,6 @@
{
imports = [
./misc.nix
./physlock.nix
];
}

View file

@ -0,0 +1,8 @@
{
# Screen locker which works across all virtual terminals
# Use `systemctl start physlock` to securely lock the screen
services.physlock = {
enable = true;
lockMessage = "System is locked...";
};
}

View file

@ -6,6 +6,7 @@ _: {
./nix
./environment
./impermanence
./security
./programs.nix
./system.nix
./network.nix

View file

@ -1,10 +1,17 @@
{
{lib, ...}: let
inherit (lib) mkForce;
in {
# Install an actually usable system-wide editor
programs.neovim = {
enable = true;
defaultEditor = true;
vimAlias = true;
viAlias = true;
programs = {
# Explicitly disable nano, it sucks and I don't want it
nano.enable = mkForce false;
# Install an actually usable system-wide editor
neovim = {
enable = true;
defaultEditor = true;
vimAlias = true;
viAlias = true;
};
};
}

View file

@ -0,0 +1,60 @@
{ config, pkgs, ... }: {
services.dbus.apparmor = "enabled";
environment.systemPackages = with pkgs; [
apparmor-pam
apparmor-utils
apparmor-parser
apparmor-profiles
apparmor-bin-utils
apparmor-kernel-patches
libapparmor
];
# apparmor configuration
security.apparmor = {
enable = true;
# whether to enable AppArmor cache
# in /var/cache/apparmor
enableCache = true;
# whether to kill processes which have an AppArmor profile enabled
# but are not confined (AppArmor can only confine new processes)
killUnconfinedConfinables = true;
# packages to be added to AppArmor's include path
packages = [pkgs.apparmor-profiles];
# AppArmor policies
policies = {
"default_deny" = {
enforce = false;
enable = false;
profile = ''
profile default_deny /** {}
'';
};
"sudo" = {
enforce = false;
enable = false;
profile = ''
${pkgs.sudo}/bin/sudo {
file /** rwlkUx
}
'';
};
"nix" = {
enforce = false;
enable = false;
profile = ''
${config.nix.package}/bin/nix {
unconfined
}
'';
};
};
};
}

View file

@ -0,0 +1,52 @@
{ config, lib, ... }: let
inherit (lib) mkIf;
cfg = config.myOptions.security.auditd;
in {
config = mkIf cfg.enable {
security = {
auditd.enable = true;
audit = {
enable = true;
# maximum number of outstanding audit buffers allowed
# exceeding this is considered a failure and handled in
# a manner specified by failureMode
backlogLimit = 8192;
# how to handle critical errors in the auditing system
failureMode = "printk"; # "silent" | "printk" | "panic"
rules = [
"-a exit,always -F arch=b64 -S execve"
];
};
};
systemd = mkIf cfg.autoPrune.enable {
# Systemd timer to clean /var/log/audit.log on configured schedule
timers."clean-audit-log" = {
description = "Periodically clean audit log";
wantedBy = ["timers.target"];
timerConfig = {
OnCalendar = cfg.autoPrune.schedule;
Persistent = true;
};
};
# clean audit log if it's larger than the configured size
services."clean-audit-log" = {
script = ''
set -eu
if [[ $(stat -c "%s" /var/log/audit/audit.log) -gt ${builtins.toString cfg.autoPrune.size} ]]; then
echo "Clearing Audit Log";
rm -rvf /var/log/audit/audit.log;
echo "Done!"
fi
'';
serviceConfig = {
Type = "oneshot";
User = "root";
};
};
};
};
}

View file

@ -0,0 +1,7 @@
{
imports = [
./apparmor.nix
./auditd.nix
./polkit.nix
];
}

View file

@ -0,0 +1,14 @@
{ config, lib, ... }: {
security.polkit = {
enable = true;
debug = lib.mkDefault true;
# Have polkit log all actions, if debug is enabled
extraConfig = lib.mkIf config.security.polkit.debug ''
/* Log authorization checks. */
polkit.addRule(function(action, subject) {
polkit.log("user " + subject.user + " is attempting action " + action.id + " from PID " + subject.pid);
});
'';
};
}

View file

@ -5,5 +5,7 @@ _: {
./logrotate.nix
./oomd.nix
./thermald.nix
./journald.nix
./fstrim.nix
];
}

View file

@ -0,0 +1,35 @@
{ config, lib, ... }: let
inherit (lib.modules) mkIf;
in {
# if lvm is enabled, then tell it to issue discards
# (this is good for SSDs and has almost no downsides on HDDs, so
# it's a good idea to enable it unconditionally)
environment.etc."lvm/lvm.conf".text = mkIf config.services.lvm.enable ''
devices {
issue_discards = 1
}
'';
# discard blocks that are not in use by the filesystem, good for SSDs
services.fstrim = {
# we may enable this unconditionally across all systems becuase it's performance
# impact is negligible on systems without a SSD - which means it's a no-op with
# almost no downsides aside from the service firing once per week
enable = true;
# the default value, good enough for average-load systems
interval = "weekly";
};
# tweak fstim service to run only when on AC power
# and to be nice to other processes
# (this is a good idea for any service that runs periodically)
systemd.services.fstrim = {
unitConfig.ConditionACPower = true;
serviceConfig = {
Nice = 19;
IOSchedulingClass = "idle";
};
};
}

View file

@ -0,0 +1,9 @@
{
# Limit systemd journal size, as the default is unlimited and
# journals get big really fast
services.journald.extraConfig = ''
SystemMaxUse=100M
RuntimeMaxUse=50M
SystemMaxFileSize=50M
'';
}