1
0
Fork 0
master
Alexander Tomokhov 2023-06-19 17:59:46 +04:00
commit 8e24d268fd
2 changed files with 141 additions and 0 deletions

79
article.md Normal file
View File

@ -0,0 +1,79 @@
# hardening of systemd services in NixOS
## introduction, threat landscape and risks
Protection against outside threats: potential vulnerabilities and unauthorized access.
Generally it's better to implement as many layers of security as possible. Although, there is no way to make server 100% bullet proof - it's a huge endless topic, we can implement some feasible essential things that gives us a layer or protection.
### security principles and strategy
1. define desired security requirements
2. apply systemd hardening options, suggested by `systemd-analyze` (until they harm service functionality)
3. vulnerability scanning, penetration testing, and security audits
4. monitor and respond
Take advantage of monitoring tools.
Have a rescue plan to mitigate the impact of incidents. This might include restoring system from backups, keys and passwords reset.
Business continuity plan.
While there are many areas of server protection, like keeping the running software up to date and respond to CVEs ([deploying software with patches is easy in NixOS](https://nixos.wiki/wiki/Overlays#Adding_patches) in case it hasn't been already patched), we will focus on `systemd` means (and a bit more, where `systemd` is not sophisticated enough).
In order for the actions (measures?) taken not to be ad-hoc, but rather systematic.
## overview of systemd integration within NixOS
- configuring systemd service units in NixOS step by step (edit, rebuild (maybe in VM), `systemd status`, `systemd restart`, `systemd cat`, `htop` tree)
## resources limits strategy
## existing practices and solutions within NixOS
- https://nixos.wiki/wiki/Systemd_Hardening
- https://github.com/fort-nix/nix-bitcoin#security
- some explanation that there is no universal way: https://github.com/NixOS/nixpkgs/pull/87661#issuecomment-698945283
## list of systemd options and their implications
## cgroups
`cgroup` - control group.
_Docker's isolation implementation is also based on cgroups._
Enabling `netdata` service in NixOS enables `systemd.enableCgroupAccounting`, which in turn [enables these options in `systemd.conf`](https://github.com/NixOS/nixpkgs/blob/c223f49e6d4b4684286b8d2f9b2325930a4f62ff/nixos/modules/system/boot/systemd.nix#L493):
```
DefaultCPUAccounting=yes
DefaultIOAccounting=yes
DefaultBlockIOAccounting=yes
DefaultIPAccounting=yes
```
## hardening in available services provided by NixOS upstream
NixOS already provides more or less isolation for many services, which are available as `services.NAME_OF_SERVICE` options.
## hardening in your own systemd services
## blocking outgoing internet connections
The idea is to keep responding to incoming requests to some service, but forbid any outgoing connections, initiated by itself.
When it comes to a more sophisticated firewall, unfortunatelly systemd is not capable of such granular control. So, `iptables` configuration will be:
```nix
networking.firewall = {
extraCommands = ''
iptables -t filter -I OUTPUT 1 -m owner --uid-owner ${user} -m state --state NEW -j REJECT
'';
extraStopCommands = ''
iptables -t filter -D OUTPUT 1 -m owner --uid-owner ${user} -m state --state NEW
'';
};
```
### testing
[example-systemd-service.nix](example-systemd-service.nix) features a way to run a shell inside a systemd service in order to test our isolation in practice. You can just add path to the file to the `imports` list in `configuration.nix` and execute `nixos-rebuild switch` or `nixos-rebuild test` _(if you don't want new configuration to be permanent; however, it creates `./result` symbolic link in current directory)_.
## unsolved problems
`confinement.enable` is not compatible with systemd's `ProtectSystem`.
## related resources
- [discourse thread about systemd services hardening](https://discourse.nixos.org/t/hardening-systemd-services/17147)
- [systemd.resource-control man page](https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html)
- [systemd.exec - execution environment configuration](https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html)
- [NixOS systemd hardening wiki page](https://nixos.wiki/wiki/Systemd_Hardening)
- https://nixos.wiki/wiki/Security

View File

@ -0,0 +1,62 @@
{ pkgs, ... }:
let
service-name = "example-service";
user = "example-service-user";
in
{
users.users = {
${user} = {
group = user;
isNormalUser = true;
createHome = false;
};
};
users.groups.${user} = { };
systemd.services.${service-name} = {
serviceConfig = {
User = user;
Group = user;
# Runtime directory and mode
RuntimeDirectory = service-name;
RuntimeDirectoryMode = "0750";
# State directory and mode
StateDirectory = service-name;
StateDirectoryMode = "0750";
# Cache directory and mode
CacheDirectory = service-name;
CacheDirectoryMode = "0750";
# Logs directory and mode
LogsDirectory = service-name;
LogsDirectoryMode = "0750";
# Configuration directory and mode
ConfigurationDirectory = service-name;
ConfigurationDirectoryMode = "0755";
# Sandboxing
ProtectSystem = "full";
ProtectHome = "read-only";
PrivateTmp = true;
ProtectControlGroups = true;
PrivateMounts = true;
ExecStart = "${pkgs.tmux}/bin/tmux -S /run/${service-name}/tmux.socket new-session -s my-session -d";
ExecStop = "${pkgs.tmux}/bin/tmux -S /run/${service-name}/tmux.socket kill-session -t my-session";
Type = "forking";
};
#confinement.enable = true;
};
networking = {
firewall = {
extraCommands = ''
iptables -t filter -I OUTPUT 1 -m owner --uid-owner ${user} -m state --state NEW -j REJECT
'';
extraStopCommands = ''
iptables -t filter -D OUTPUT 1 -m owner --uid-owner ${user} -m state --state NEW
'';
};
};
}