users: enable pam_cap for "login" program

This commit is contained in:
Colin 2024-01-28 17:55:19 +00:00
parent 24c70c3683
commit 381da74e6c

View File

@ -53,45 +53,125 @@
security.pam.mount.enable = true;
# in the future, may add this to sshd/login/sudo
# security.pam.services.systemd-user.rules = {
# auth.pam_cap = {
# order = 11500;
# # order = 12500; # before pam_unix but after all the others
# control = "required"; # ?
# modulePath = "${pkgs.libcap.pam}/lib/security/pam_cap.so";
# };
# };
# security.pam.services.greetd.rules = {
# auth.pam_cap = {
# order = 12500; # before pam_unix but after all the others
# control = "required"; # ?
# modulePath = "${pkgs.libcap.pam}/lib/security/pam_cap.so";
# };
# };
# environment.etc."/security/capability.conf".text = ''
# # The pam_cap.so module accepts the following arguments:
# #
# # debug - be more verbose logging things (unused by pam_cap for now)
# # config=<file> - override the default config for the module with file
# # keepcaps - workaround for applications that setuid without this
# # autoauth - if you want pam_cap.so to always succeed for the auth phase
# # default=<iab> - provide a fallback IAB value if there is no '*' rule
# #
# # format:
# # <CAP>[,<CAP>...] USER|@GROUP|*
# #
# # the part of each line before the delimiter (" \t\n") is parsed with `cap_iab_from_text`.
# # so each CAP can be prefixed to indicate which set it applies to:
# # [!][^][%]<CAP>
# # where ! adds to the NB set
# # ^ for AI
# # % (or empty) for I
# pam.d ordering:
# /etc/pam.d/greetd:
# auth optional pam_unix.so likeauth nullok # unix-early (order 11600)
# auth optional /nix/store/051v0pwqfy1z7ld6087y99fdrv12113n-pam_mount-2.20/lib/security/pam_mount.so disable_interactive # mount (order 12000)
# auth optional /nix/store/82zqzh7i88pxybcf48zapnz4v0jf19nm-gnome-keyring-42.1/lib/security/pam_gnome_keyring.so # gnome_keyring (order 12200)
# auth sufficient pam_unix.so likeauth nullok try_first_pass # unix (order 12800)
# auth required pam_deny.so # deny (order 13600)
# /etc/pam.d/login:
# auth optional pam_unix.so likeauth nullok # unix-early (order 11600)
# auth optional /nix/store/051v0pwqfy1z7ld6087y99fdrv12113n-pam_mount-2.20/lib/security/pam_mount.so disable_interactive # mount (order 12000)
# auth optional /nix/store/82zqzh7i88pxybcf48zapnz4v0jf19nm-gnome-keyring-42.1/lib/security/pam_gnome_keyring.so # gnome_keyring (order 12200)
# auth sufficient pam_unix.so likeauth nullok try_first_pass # unix (order 12800)
# auth required pam_deny.so # deny (order 13600)
# /etc/pam.d/sshd: `auth required pam_deny.so # deny (order 12400)`
# /etc/pam.d/sudo:
# auth optional pam_unix.so likeauth # unix-early (order 11600)
# auth optional /nix/store/051v0pwqfy1z7ld6087y99fdrv12113n-pam_mount-2.20/lib/security/pam_mount.so disable_interactive # mount (order 12000)
# auth sufficient pam_unix.so likeauth try_first_pass # unix (order 12800)
# auth required pam_deny.so # deny (order 13600)
# /etc/pam.d/systemd-user:
# auth sufficient pam_unix.so likeauth try_first_pass # unix (order 11600)
# auth required pam_deny.so # deny (order 12400)
# ^cap_net_admin,^cap_new_raw colin
# # include this `none *` line otherwise non-matching users get maximum inheritable capabilities
# none *
# '';
# brief overview of PAM order/control:
# - rules are executed sequentially
# - a rule marked "optional": doesn't affect control flow.
# - a rule marked "sufficient": on success, early-returns a success value and no further rules are executed.
# on failure, control flow is normal.
# - a rule marked "required": on failure, early-returns a fail value and no further rules are executed.
# on success, control flow is normal.
# hence, supplementary things like pam_mount, pam_cap, should be marked "optional" and occur before the first "sufficient" rule.
#
# pam_cap module args are in pam_cap/pam_cap.c:parse_args:
# - debug
# - config=<filename>
# - keepcaps
# - autoauth
# - default=<string>
# - defer
#
# about propagating capabilities to PAM consumers:
# - `setuid` call typically drops all ambient capabilities.
# but setting keepcaps first will preserve the caps across a setuid call
# - pam_cap bug, and fix: <https://bugzilla.kernel.org/show_bug.cgi?id=212945#c5>
# - may need to use keepcaps + defer: <https://bugzilla.kernel.org/show_bug.cgi?id=214377#c3>
# security.pam.services.greetd.rules = {
# # 2024/01/28: greetd seems to get its caps from systemd (pid1), no matter what i do.
# auth.pam_cap = {
# order = 12700;
# control = "optional";
# modulePath = "${pkgs.libcap.pam}/lib/security/pam_cap.so";
# # args = [ "keepcaps" "defer" ]; #< doesn't take effect
# # args = [ "keepcaps" ]; #< doesn't take effect
# # args = []; #< doesn't take effect
# };
# };
security.pam.services.login.rules = {
# keepcaps + defer WORKS
auth.pam_cap = {
order = 12700;
control = "optional";
modulePath = "${pkgs.libcap.pam}/lib/security/pam_cap.so";
args = [ "keepcaps" "defer" ];
};
};
# security.pam.services.sshd.rules = {
# 2024/01/28: sshd only supports caps in the I set, because of the keep-caps/setuid issue (above)
# auth.pam_cap = {
# order = 12300;
# control = "optional";
# modulePath = "${pkgs.libcap.pam}/lib/security/pam_cap.so";
# args = [ "keepcaps" "defer" ]; #< doesn't take effect
# };
# };
# security.pam.services.sudo.rules = {
# 2024/01/28: sudo only supports caps in the I set, because of the keep-caps/setuid issue (above)
# auth.pam_cap = {
# # order = 11500;
# order = 12700;
# control = "optional";
# modulePath = "${pkgs.libcap.pam}/lib/security/pam_cap.so";
# args = [ "keepcaps" "defer" ]; #< doesn't take effect
# };
# };
security.pam.services.systemd-user.rules = {
# 2024/01/28: systemd-user seems to override whatever pam_cap tries to set (?)
auth.pam_cap = {
order = 11500;
control = "optional";
modulePath = "${pkgs.libcap.pam}/lib/security/pam_cap.so";
# args = [ "keepcaps" "defer" ]; #< doesn't take effect
args = [ "keepcaps" ];
};
};
environment.etc."/security/capability.conf".text = ''
# The pam_cap.so module accepts the following arguments:
#
# debug - be more verbose logging things (unused by pam_cap for now)
# config=<file> - override the default config for the module with file
# keepcaps - workaround for applications that setuid without this
# autoauth - if you want pam_cap.so to always succeed for the auth phase
# default=<iab> - provide a fallback IAB value if there is no '*' rule
#
# format:
# <CAP>[,<CAP>...] USER|@GROUP|*
#
# the part of each line before the delimiter (" \t\n") is parsed with `cap_iab_from_text`.
# so each CAP can be prefixed to indicate which set it applies to:
# [!][^][%]<CAP>
# where ! adds to the NB set (bounding)
# ^ for AI (ambient + inherited)
# % (or empty) for I (inherited)
#
# special capabilities "all" and "none" enable all/none of the caps known to the system.
^cap_net_admin,^cap_net_raw colin
# include this `none *` line otherwise non-matching users get maximum inheritable capabilities
none *
'';
# grant myself extra capabilities so that i can e.g.:
# - run wireshark without root/setuid
@ -100,6 +180,13 @@
#
# userName and uid have to be explicitly set here, to pass systemd's sanity checks.
# other values like `home`, `shell` can be omitted and systemd will grab those from other sources (/etc/passwd)
#
# user records are JSON dicts, keys are found in systemd: src/shared/user-record.c:user_record_load
# notable keys:
# - capabilityBoundingSet
# - capabilityAmbientSet
# - service
# - privileged
environment.etc."userdb/colin.user".text = ''
{
"userName" : "colin",