Restrict su to a Group with pam_wheel
You will configure the PAM stack for su so that only members of a chosen group can become root, then test and undo the change safely. The examples match Linux-PAM pam_wheel version 1.5.3-5ubuntu5.7 from the installed libpam-modules:amd64 package.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need root access, a second account for testing, and a group whose membership you have checked. This changes authentication policy, so keep an existing root shell or console session open while testing. Do not make the edit over your only remote session.
1. Check the installed module and the target service
Read the local service file before editing it. The file name selects the PAM service, and each rule has a management type, control, module and optional arguments:
$ dpkg-query -W -f='${Package} ${Version}\n' libpam-modules:amd64
libpam-modules:amd64 1.5.3-5ubuntu5.7
$ grep -nE 'pam_rootok|pam_wheel|common-auth' /etc/pam.d/su
6:auth sufficient pam_rootok.so
15:# auth required pam_wheel.so
30:@include common-auth
The installed file already documents the usual placement. pam_rootok.so is sufficient, so root can use su without a password. The wheel rule must come before the common Unix authentication rule if it is to reject a disallowed applicant before a password prompt.
Checkpoint: confirm the module is present without changing anything:
$ command -v su
/usr/bin/su
$ ls -l /lib/*/security/pam_wheel.so
-rwxr-xr-x ... /lib/x86_64-linux-gnu/security/pam_wheel.so
2. Choose and inspect the group
By default, pam_wheel looks for a group named wheel. If that group does not exist, the installed module uses group ID 0 instead. That fallback is easy to misunderstand: it is not the same as the Debian or Ubuntu sudo group. Name the group explicitly when your policy is about sudo or another local group.
$ getent group ADMIN_GROUP
ADMIN_GROUP:x:1234:alice,operator
$ id alice
uid=... (alice) gid=... (alice) groups=...,1234(ADMIN_GROUP)
Replace ADMIN_GROUP with a real group name. The account you test must appear in the group's supplementary membership. A new membership may require a new login session before id shows it.
3. Back up the PAM file before the security change
This is the first elevated step. Make a backup with a distinct name and verify it exists:
# sudo cp -a /etc/pam.d/su /etc/pam.d/su.before-pam-wheel
# sudo test -s /etc/pam.d/su && echo 'PAM backup created'
PAM backup created
Do not skip the backup. A malformed or over-restrictive PAM rule can prevent logins or privilege changes. The recovery command at the end restores this exact file.
4. Add a required group check
Edit /etc/pam.d/su as root and add this line immediately after the existing pam_rootok line:
auth required pam_wheel.so group=ADMIN_GROUP
Replace the placeholder with the group from the previous step. The required control means a failure eventually makes the authentication stack fail, although later modules may still run. Keep the existing pam_rootok line above it so root retains the documented root-only shortcut.
For a stricter policy that should apply only when the target account is UID 0, add root_only:
auth required pam_wheel.so group=ADMIN_GROUP root_only
root_only limits the membership check to attempts to become root. Without it, the module's check can also affect other target users. Do not add trust casually: it returns success for a group member instead of PAM_IGNORE, which can let that member reach root without a password depending on the rest of the stack.
5. Test the allow and deny paths
Start a fresh login as a member of the group and run an ordinary, non-destructive test:
$ id
uid=... groups=...,1234(ADMIN_GROUP)
$ su -c 'id -u'
Password:
0
The password prompt is expected unless you deliberately configured trust or another rule bypasses it. The final 0 confirms that su ran the command as root.
Now test with an account that is not in the group:
$ su -c 'id -u'
su: Permission denied
The exact error text can vary with the application and PAM stack. The useful result is that the non-member cannot become root. If a member is rejected, check the new session's groups first, then inspect the line for a spelling error. Do not respond by adding trust or changing several PAM controls at once.
6. Recover or remove the restriction
If the edit causes trouble, use the root shell or console session you kept open. Restore the known-good file:
# sudo cp -a /etc/pam.d/su.before-pam-wheel /etc/pam.d/su
# sudo grep -n 'pam_wheel' /etc/pam.d/su || echo 'pam_wheel rule removed'
pam_wheel rule removed
This affects new su attempts; it does not terminate an already-running root shell. Once the replacement has been tested, remove the backup only if you no longer need it. That deletion is irreversible:
# sudo rm /etc/pam.d/su.before-pam-wheel
Done means
- The chosen group exists and contains the intended accounts.
- The
pam_wheel.sorule names that group and sits afterpam_rootok.so. - A member can run
suto root, and a non-member cannot. - A root shell or console recovery path remains available.