2024-06-02 09:48:17 +00:00
{ config , lib , pkgs , . . . }:
{
networking . modemmanager . package = pkgs . modemmanager-split . daemon . overrideAttrs ( upstream : {
# patch to allow the dbus endpoints to be owned by networkmanager user
postInstall = ( upstream . postInstall or " " ) + ''
substitute $ out/share/dbus-1/system.d/org.freedesktop.ModemManager1.conf \
$ out/share/dbus-1/system.d/networkmanager-org.freedesktop.ModemManager1.conf \
- - replace-fail ' user = " r o o t " ' ' group = " n e t w o r k m a n a g e r " '
'' ;
} ) ;
systemd . services . ModemManager = {
# aliases = [ "dbus-org.freedesktop.ModemManager1.service" ];
# after = [ "polkit.service" ];
# requires = [ "polkit.service" ];
wantedBy = [ " n e t w o r k . t a r g e t " ] ; #< default is `multi-user.target`, somehow it doesn't auto-start with that...
# path = [ "/run/current-system/sw" ]; #< so it can find `sanebox`
# serviceConfig.Type = "dbus";
# serviceConfig.BusName = "org.freedesktop.ModemManager1";
# only if started with `--debug` does mmcli let us issue AT commands like
# `mmcli --modem any --command=<AT_CMD>`
serviceConfig . ExecStart = [
" " # first blank line is to clear the upstream `ExecStart` field.
" ${ lib . getExe' config . networking . modemmanager . package " M o d e m M a n a g e r " } - - d e b u g "
] ;
# --debug sets DEBUG level logging: so reset
serviceConfig . ExecStartPost = " ${ lib . getExe config . sane . programs . mmcli . package } - - s e t - l o g g i n g = I N F O " ;
# v this is what upstream ships
# serviceConfig.Restart = "on-abort";
# serviceConfig.StandardError = "null";
# serviceConfig.CapabilityBoundingSet = "CAP_SYS_ADMIN CAP_NET_ADMIN";
2024-06-03 16:25:45 +00:00
# serviceConfig.ProtectSystem = true; # makes empty: /boot, /usr
# serviceConfig.ProtectHome = true; # makes empty: /home, /root, /run/user
2024-06-02 09:48:17 +00:00
# serviceConfig.PrivateTmp = true;
# serviceConfig.RestrictAddressFamilies = "AF_NETLINK AF_UNIX AF_QIPCRTR";
# serviceConfig.NoNewPrivileges = true;
2024-06-03 16:25:45 +00:00
serviceConfig . CapabilityBoundingSet = [ " C A P _ N E T _ A D M I N " ] ; #< TODO: make sure this is *really* taking effect, and isn't supplemental to upstream's `CAP_SYS_ADMIN` setting
serviceConfig . LockPersonality = true ;
# serviceConfig.PrivateUsers = true; #< untried, not likely to work since it needs capabilities
serviceConfig . PrivateTmp = true ;
serviceConfig . ProtectClock = true ; # syscall filter to prevent changing the RTC
serviceConfig . ProtectControlGroups = true ;
serviceConfig . ProtectHome = true ; # makes empty: /home, /root, /run/user
serviceConfig . ProtectHostname = true ; # prevents changing hostname
serviceConfig . ProtectKernelLogs = true ; # disable /proc/kmsg, /dev/kmsg
serviceConfig . ProtectKernelModules = true ; # syscall filter to prevent module calls
serviceConfig . ProtectKernelTunables = true ;
serviceConfig . ProtectSystem = " s t r i c t " ; # makes read-only all but /dev, /proc, /sys
serviceConfig . RestrictAddressFamilies = [
" A F _ N E T L I N K "
" A F _ Q I P C R T R "
" A F _ U N I X "
] ;
serviceConfig . RestrictSUIDSGID = true ;
serviceConfig . SystemCallArchitectures = " n a t i v e " ; # prevents e.g. aarch64 syscalls in the event that the kernel is multi-architecture.
# from earlier `landlock` sandboxing, i know it needs these directories:
2024-06-02 09:48:17 +00:00
# - # "/"
# - "/dev" #v modem-power + net are not enough
# - # "/dev/modem-power"
# - # "/dev/net"
# - "/proc"
# - # /run #v can likely be reduced more
# - "/run/dbus"
# - "/run/NetworkManager"
# - "/run/resolvconf"
# - "/run/systemd"
# - "/run/udev"
# - "/sys"
} ;
# so that ModemManager can discover when the modem appears
# services.udev.packages = lib.mkIf cfg.enabled [ cfg.package ];
}