Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into staging-next
Browse files Browse the repository at this point in the history
  • Loading branch information
K900 committed Feb 4, 2025
2 parents 4e1833c + a495480 commit 3ddda10
Show file tree
Hide file tree
Showing 89 changed files with 1,551 additions and 864 deletions.
6 changes: 6 additions & 0 deletions maintainers/maintainer-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -25076,6 +25076,12 @@
githubId = 6162814;
keys = [ { fingerprint = "21E1 6B8D 2EE8 7530 6A6C 9968 D830 77B9 9F8C 6643"; } ];
};
wrvsrx = {
name = "wrvsrx";
email = "[email protected]";
github = "wrvsrx";
githubId = 42770726;
};
wscott = {
email = "[email protected]";
github = "wscott";
Expand Down
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2505.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@

- `services.avahi.ipv6` now defaults to true.

- The Home Assistant module has new options {option}`services.home-assistant.blueprints.automation`, `services.home-assistant.blueprints.script`, and {option}`services.home-assistant.blueprints.template` that allow for the declarative installation of [blueprints](https://www.home-assistant.io/docs/blueprint/) into the appropriate configuration directories.

- For matrix homeserver Synapse we are now following the upstream recommendation to enable jemalloc as the memory allocator by default.

- `services.kmonad` now creates a determinate symlink (in `/dev/input/by-id/`) to each of KMonad virtual devices.
Expand Down
224 changes: 118 additions & 106 deletions nixos/modules/profiles/hardened.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,114 +12,126 @@
pkgs,
...
}:
let
inherit (lib)
mkDefault
mkOverride
mkEnableOption
mkIf
maintainers
;
in
{
options.profiles.hardened = mkEnableOption "hardened" // {
default = true;
example = false;
};
config = mkIf config.profiles.hardened {
meta = {
maintainers = [
maintainers.joachifm
maintainers.emily
];
};

with lib;
boot.kernelPackages = mkDefault pkgs.linuxPackages_hardened;

{
meta = {
maintainers = [
maintainers.joachifm
maintainers.emily
nix.settings.allowed-users = mkDefault [ "@users" ];

environment.memoryAllocator.provider = mkDefault "scudo";
environment.variables.SCUDO_OPTIONS = mkDefault "ZeroContents=1";

security.lockKernelModules = mkDefault true;

security.protectKernelImage = mkDefault true;

security.allowSimultaneousMultithreading = mkDefault false;

security.forcePageTableIsolation = mkDefault true;

# This is required by podman to run containers in rootless mode.
security.unprivilegedUsernsClone = mkDefault config.virtualisation.containers.enable;

security.virtualisation.flushL1DataCache = mkDefault "always";

security.apparmor.enable = mkDefault true;
security.apparmor.killUnconfinedConfinables = mkDefault true;

boot.kernelParams = [
# Don't merge slabs
"slab_nomerge"

# Overwrite free'd pages
"page_poison=1"

# Enable page allocator randomization
"page_alloc.shuffle=1"

# Disable debugfs
"debugfs=off"
];

boot.blacklistedKernelModules = [
# Obscure network protocols
"ax25"
"netrom"
"rose"

# Old or rare or insufficiently audited filesystems
"adfs"
"affs"
"bfs"
"befs"
"cramfs"
"efs"
"erofs"
"exofs"
"freevxfs"
"f2fs"
"hfs"
"hpfs"
"jfs"
"minix"
"nilfs2"
"ntfs"
"omfs"
"qnx4"
"qnx6"
"sysv"
"ufs"
];
};

boot.kernelPackages = mkDefault pkgs.linuxPackages_hardened;

nix.settings.allowed-users = mkDefault [ "@users" ];

environment.memoryAllocator.provider = mkDefault "scudo";
environment.variables.SCUDO_OPTIONS = mkDefault "ZeroContents=1";

security.lockKernelModules = mkDefault true;

security.protectKernelImage = mkDefault true;

security.allowSimultaneousMultithreading = mkDefault false;

security.forcePageTableIsolation = mkDefault true;

# This is required by podman to run containers in rootless mode.
security.unprivilegedUsernsClone = mkDefault config.virtualisation.containers.enable;

security.virtualisation.flushL1DataCache = mkDefault "always";

security.apparmor.enable = mkDefault true;
security.apparmor.killUnconfinedConfinables = mkDefault true;

boot.kernelParams = [
# Don't merge slabs
"slab_nomerge"

# Overwrite free'd pages
"page_poison=1"

# Enable page allocator randomization
"page_alloc.shuffle=1"

# Disable debugfs
"debugfs=off"
];

boot.blacklistedKernelModules = [
# Obscure network protocols
"ax25"
"netrom"
"rose"

# Old or rare or insufficiently audited filesystems
"adfs"
"affs"
"bfs"
"befs"
"cramfs"
"efs"
"erofs"
"exofs"
"freevxfs"
"f2fs"
"hfs"
"hpfs"
"jfs"
"minix"
"nilfs2"
"ntfs"
"omfs"
"qnx4"
"qnx6"
"sysv"
"ufs"
];

# Hide kptrs even for processes with CAP_SYSLOG
boot.kernel.sysctl."kernel.kptr_restrict" = mkOverride 500 2;

# Disable bpf() JIT (to eliminate spray attacks)
boot.kernel.sysctl."net.core.bpf_jit_enable" = mkDefault false;

# Disable ftrace debugging
boot.kernel.sysctl."kernel.ftrace_enabled" = mkDefault false;

# Enable strict reverse path filtering (that is, do not attempt to route
# packets that "obviously" do not belong to the iface's network; dropped
# packets are logged as martians).
boot.kernel.sysctl."net.ipv4.conf.all.log_martians" = mkDefault true;
boot.kernel.sysctl."net.ipv4.conf.all.rp_filter" = mkDefault "1";
boot.kernel.sysctl."net.ipv4.conf.default.log_martians" = mkDefault true;
boot.kernel.sysctl."net.ipv4.conf.default.rp_filter" = mkDefault "1";

# Ignore broadcast ICMP (mitigate SMURF)
boot.kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = mkDefault true;

# Ignore incoming ICMP redirects (note: default is needed to ensure that the
# setting is applied to interfaces added after the sysctls are set)
boot.kernel.sysctl."net.ipv4.conf.all.accept_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.all.secure_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.default.accept_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.default.secure_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv6.conf.all.accept_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv6.conf.default.accept_redirects" = mkDefault false;

# Ignore outgoing ICMP redirects (this is ipv4 only)
boot.kernel.sysctl."net.ipv4.conf.all.send_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.default.send_redirects" = mkDefault false;
# Hide kptrs even for processes with CAP_SYSLOG
boot.kernel.sysctl."kernel.kptr_restrict" = mkOverride 500 2;

# Disable bpf() JIT (to eliminate spray attacks)
boot.kernel.sysctl."net.core.bpf_jit_enable" = mkDefault false;

# Disable ftrace debugging
boot.kernel.sysctl."kernel.ftrace_enabled" = mkDefault false;

# Enable strict reverse path filtering (that is, do not attempt to route
# packets that "obviously" do not belong to the iface's network; dropped
# packets are logged as martians).
boot.kernel.sysctl."net.ipv4.conf.all.log_martians" = mkDefault true;
boot.kernel.sysctl."net.ipv4.conf.all.rp_filter" = mkDefault "1";
boot.kernel.sysctl."net.ipv4.conf.default.log_martians" = mkDefault true;
boot.kernel.sysctl."net.ipv4.conf.default.rp_filter" = mkDefault "1";

# Ignore broadcast ICMP (mitigate SMURF)
boot.kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = mkDefault true;

# Ignore incoming ICMP redirects (note: default is needed to ensure that the
# setting is applied to interfaces added after the sysctls are set)
boot.kernel.sysctl."net.ipv4.conf.all.accept_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.all.secure_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.default.accept_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.default.secure_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv6.conf.all.accept_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv6.conf.default.accept_redirects" = mkDefault false;

# Ignore outgoing ICMP redirects (this is ipv4 only)
boot.kernel.sysctl."net.ipv4.conf.all.send_redirects" = mkDefault false;
boot.kernel.sysctl."net.ipv4.conf.default.send_redirects" = mkDefault false;
};
}
68 changes: 67 additions & 1 deletion nixos/modules/services/home-automation/home-assistant.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@ let
attrByPath
attrValues
concatMap
concatStrings
converge
elem
escapeShellArg
escapeShellArgs
filter
filterAttrsRecursive
flatten
hasAttrByPath
isAttrs
isDerivation
isList
isStorePath
literalExpression
mapAttrsToList
mergeAttrsList
mkEnableOption
mkIf
mkMerge
Expand All @@ -28,6 +33,7 @@ let
recursiveUpdate
singleton
splitString
substring
types
unique
;
Expand Down Expand Up @@ -502,6 +508,41 @@ in {
type = types.bool;
description = "Whether to open the firewall for the specified port.";
};

blueprints = mergeAttrsList (
map
(domain: {
${domain} = mkOption {
default = [ ];
description = ''
List of ${domain}
[blueprints](https://www.home-assistant.io/docs/blueprint/) to
install into {file}`''${configDir}/blueprints/${domain}`.
'';
example =
if domain == "automation" then
literalExpression ''
[
(pkgs.fetchurl {
url = "https://github.com/home-assistant/core/raw/2025.1.4/homeassistant/components/automation/blueprints/motion_light.yaml";
hash = "sha256-4HrDX65ycBMfEY2nZ7A25/d3ZnIHdpHZ+80Cblp+P5w=";
})
]
''
else if domain == "template" then
literalExpression "[ \"\${pkgs.home-assistant.src}/homeassistant/components/template/blueprints/inverted_binary_sensor.yaml\" ]"
else
literalExpression "[ ./blueprint.yaml ]";
type = types.listOf (types.coercedTo types.path (x: "${x}") types.pathInStore);
};
})
# https://www.home-assistant.io/docs/blueprint/schema/#domain
[
"automation"
"script"
"template"
]
);
};

config = mkIf cfg.enable {
Expand Down Expand Up @@ -576,11 +617,36 @@ in {
ln -fns "''${paths[@]}" "${cfg.configDir}/custom_components/"
done
'';
removeBlueprints = ''
# remove blueprints symlinked in from below the /nix/store
readarray -d "" blueprints < <(find "${cfg.configDir}/blueprints" -maxdepth 2 -type l -print0)
for blueprint in "''${blueprints[@]}"; do
if [[ "$(readlink "$blueprint")" =~ ^${escapeShellArg builtins.storeDir} ]]; then
rm "$blueprint"
fi
done
'';
copyBlueprint =
domain: blueprint:
let
filename =
if isStorePath blueprint then substring 33 (-1) (baseNameOf blueprint) else baseNameOf blueprint;
path = "${cfg.configDir}/blueprints/${domain}";
in
''
mkdir -p ${escapeShellArg path}
ln -s ${escapeShellArg blueprint} ${escapeShellArg "${path}/${filename}"}
'';
copyBlueprints = concatStrings (
flatten (mapAttrsToList (domain: map (copyBlueprint domain)) cfg.blueprints)
);
in
(optionalString (cfg.config != null) copyConfig) +
(optionalString (cfg.lovelaceConfig != null) copyLovelaceConfig) +
copyCustomLovelaceModules +
copyCustomComponents
copyCustomComponents +
removeBlueprints +
copyBlueprints
;
environment.PYTHONPATH = package.pythonPath;
serviceConfig = let
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ in
${concatStringsSep " \\\n " cfg.extraFlags}
'';
serviceConfig = {
CacheDirectory = "restic-exporter";
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
LoadCredential = [
"RESTIC_PASSWORD_FILE:${cfg.passwordFile}"
Expand All @@ -156,6 +157,7 @@ in
LISTEN_ADDRESS = cfg.listenAddress;
LISTEN_PORT = toString cfg.port;
REFRESH_INTERVAL = toString cfg.refreshInterval;
RESTIC_CACHE_DIR = "$CACHE_DIRECTORY";
}
// (mapAttrs' (
name: value: nameValuePair (rcloneAttrToOpt name) (toRcloneVal value)
Expand Down
Loading

0 comments on commit 3ddda10

Please sign in to comment.