Opinionated, idempotent helper script to enable passwordless sudo (and optionally polkit) for a single user on Linux.
This script exists for a very specific use case: a single-user, personal or lab machine where convenience matters more than strict isolation.
- I wanted a way to log into my normal account and have full admin power immediately, without constantly typing my password for every
sudoorsu. - I also wanted this to be repeatable and transparent: instead of hand-editing
/etc/sudoersor PAM files by trial and error on every new install, I can run one well-documented script. - The script is designed to be idempotent and self-checking: it validates syntax with
visudo, makes backups when overwriting, and avoids adding duplicate lines, so I can safely re-run it on my own systems.
Because of that, this project is not meant for multi-user servers, shared machines, or security-sensitive environments. It is explicitly an automation of "make this one user effectively root with no password prompts" for people (like me) who:
- Are comfortable accepting that any compromise of that user account is a full system compromise.
- Prefer fast, passwordless admin workflows on their own machines.
- Want the configuration to be auditable and reproducible instead of a pile of manual tweaks.
This repository provides:
setup-passwordless-fb.sh– a robust helper script that:- Configures passwordless sudo for a single user via
/etc/sudoers.d/… - Optionally also configures polkit to always approve actions for that user
- Can also ensure
/etc/sudoersitself contains aNOPASSWDentry for the user - (Best-effort) adjusts the PAM
suservice so that members of thewheelgroup can usesuwithout a password on PAM-based Linux distros where asu/su-lservice exists - Is safe by design: uses
visudofor syntax validation and makes backups before replacing system files - Is idempotent: re-running the script does not keep appending duplicate lines or duplicating PAM
pam_wheel.soentries
- Configures passwordless sudo for a single user via
You must read this entire README (including all warnings and option descriptions) before running setup-passwordless-fb.sh. If you choose to run the script without fully understanding this document, you accept that any damage, data loss, or security compromise is entirely your responsibility.
This script gives the target user essentially root-equivalent power without any password prompt and may also add them to highly privileged system groups (such as root, disk, shadow, and kmem).
- The target user can run any command as root with
sudowithout being asked for a password. - If polkit configuration is enabled (default), that user will also get automatic approval for polkit-controlled actions (e.g. graphical administrative actions).
- If group membership is modified, the target user may gain direct access to disks, kernel interfaces, and sensitive files (including password hashes) even without
sudo.
- Full system compromise is possible if this user account is ever abused or compromised.
- Local malware running as that user can trivially escalate to full root.
- Traditional protections such as
sudopassword prompts and some polkit dialogs will no longer provide meaningful defense.
In addition to configuring passwordless sudo and (optionally) polkit, this script can:
-
Add the target user to highly privileged system groups such as
root,disk,wheel,systemd-journal,network,video,audio,input,render,kvm,tty,tape,shadow,kmem, andadm.
This can give the user direct access to raw disks, password hashes, kernel interfaces and system configuration, even without usingsudo. The script will only add the user to groups that actually exist on the system (as returned bygetent group). If you later install software that creates additional groups from this list and re-run the script, it will then add the user to those newly-present groups as well. -
Optionally relax mandatory access controls (MAC) when
--relax-macis used, by stopping AppArmor (if present) and attempting to switch SELinux to permissive mode.
This removes an important layer of defense on top of normal Unix permissions and sudo. -
Optionally configure polkit so that the user receives automatic approval for all polkit actions (no graphical confirmation dialogs).
-
Optionally (with
--full-file-permissions) run a recursive ACL change equivalent to:sudo setfacl -R -m u:<TARGET_USER>:rwx /
This grants the target user read/write/execute permissions on almost everything under
/that supports ACLs.
In practice this is a filesystem-wide superuser grant that is more invasive and harder to undo than passwordless sudo itself.
These options are off by default, but if you enable them you should assume that the machine is effectively permanently and irreversibly weakened from a security standpoint.
Do not enable them on any machine where you care about multi‑user isolation, strong security boundaries, or reliable long‑term integrity.
Before using this script, read and understand all of the following:
-
Single-user, non-critical systems only
Use this only on machines where you are the sole user and there is no untrusted local user. Avoid production servers or shared multi-user systems. -
Physical and account security
- Use a strong login passphrase for the target account and full disk encryption where possible.
- Lock your screen when unattended.
- Do not reuse the same password on other systems/services.
-
Network and remote access
- Be extremely careful enabling SSH or other remote access for this user.
- If you must, use key-based auth, disable password login, and restrict who can connect (firewall,
AllowUsers, etc.).
-
Limit browser and untrusted software risk
- Treat running a web browser, email client, or untrusted binaries under this account as if you are running them as root.
- Avoid executing random scripts from the internet. Review them first.
-
Backups and recovery
- Keep known-good backups of
/etc/sudoers,/etc/sudoers.d/, and any polkit rules. - Consider creating a second, more restricted admin account you can fall back to.
- Keep known-good backups of
-
Log out / reboot after changes
- After group membership changes, log out and back in (or reboot) to ensure group changes take effect and test carefully.
- This script and documentation are provided “as is”, without any warranty of any kind, express or implied.
- I am the original author of this script and make no guarantees about its safety, correctness, fitness for a particular purpose, or suitability for your environment.
- You are solely responsible for reviewing the code, understanding what it does, and deciding whether it is appropriate to run on your systems.
- By using this script, you accept all risk, including but not limited to data loss, security breaches, service outages, and legal or policy violations.
If you do not fully understand or accept these risks, do not run this script.
- Works with common Linux distros (supports
apt,dnf,yum,pacman,zypper,apk) - Detects the target user automatically (the user running the script), or allows
--user USER - Configures:
/etc/sudoers.d/<user>-passwordlesswith:<user> ALL=(ALL:ALL) NOPASSWD: ALLDefaults:<user> !authenticate
- (Optionally)
/etc/sudoersitself to include the sameNOPASSWDline - (Optionally) a polkit rule in
/etc/polkit-1/rules.d/00-allow-<user>-everything.rules
- Idempotent:
- Checks if config already matches the desired state before writing
- Avoids duplicating lines or re-appending the same comment blocks
- Safety:
- Uses
visudoto validate temporary files before installing them - Backs up existing files with timestamped
.bak.<timestamp>suffix when overwriting (only when--forceis used) - Refuses to do unsafe things by default (e.g. doesn’t overwrite existing config unless you explicitly ask it to)
- Uses
- A Linux system with:
sudoinstalled and available- A functional
visudobinary bashavailable (e.g./bin/bash); the script uses Bash-specific features and must not be run withsh,dash, or other non-Bash shells.
- A user account with:
- Existing
sudorights (can runsudowith password at least once)
- Existing
- Optional (for polkit integration):
- A polkit installation (
polkit/policykit-1) pkcheck/pkactionbinaries
- A polkit installation (
The script will:
- Detect and optionally install missing dependencies (if you allow it)
- Detect the package manager among:
apt,dnf,yum,pacman,zypper,apk
Clone this repo, or just copy the script to somewhere in your home directory and make it executable:
git clone https://github.com/<your-username>/Password-less.git
cd Password-less
chmod +x setup-passwordless-fb.shYou can also rename
setup-passwordless-fb.shto something else; the name is not special except for logging/comments.
Basic usage:
./setup-passwordless-fb.sh [--user USER] [--sudo-only] [--no-install] [--relax-mac] [--yes] [--force] [--dry-run] [--full-file-permissions] [--install-full-file-permissions-service] [--uninstall-full-file-permissions-service] [--all-groups] [--default-config]Important: This is a Bash-only script. Run it as
./setup-passwordless-fb.sh ...orbash setup-passwordless-fb.sh .... Do not run it withsh,dash, or/bin/sh, as that may cause errors likeunbound variableor syntax errors.
-
--user USER
Target username (must already exist).
If omitted, the script uses the user who is invoking the script:TARGET_USER = $(id -un) -
--sudo-only
Only configure passwordless sudo.
Skip polkit rule creation. -
--no-install
Do not attempt to install missing dependencies (e.g.polkit).
If dependencies are missing, the script will abort and ask you to install them yourself. -
--relax-mac
Dangerous, optional: best-effort attempt to relax Mandatory Access Control (MAC) systems:- Stop the AppArmor service at runtime (if present).
- Set SELinux to permissive at runtime (if present).
This does not change UIDs/groups/sudoers, but it removes important enforcement layers, making any existing privileges more powerful.
The script will still prompt you for confirmation unless--yesis also provided.
In--verifymode,--relax-macdoes not relax anything, but the script will always print a detailed MAC status report (AppArmor present/active, SELinux mode).
-
--full-file-permissions
Nuclear option, experimental, NOT READY FOR NORMAL USE and ACL-only mode: when you invoke the script with this flag (and not in--restore/--verify/--install-.../--uninstall-...modes), it skips the normal passwordless sudo/polkit/group/PAM configuration and runs only a recursive ACL grant equivalent to:setfacl -R -m u:<TARGET_USER>:rwx /
Internally, the script now uses a
findpipeline that skips several sensitive trees to reduce the chance of breaking core services:- Pseudo-filesystems:
/proc,/sys,/dev,/run,/boot/efi,/snap - Network stacks (best-effort, cross-distro):
- NetworkManager:
/etc/NetworkManager,/var/lib/NetworkManager,/usr/lib/NetworkManager - systemd-networkd:
/etc/systemd/network,/var/lib/systemd/network - connman:
/etc/connman,/var/lib/connman - wpa_supplicant:
/etc/wpa_supplicant,/var/lib/wpa_supplicant - wicked (SUSE):
/etc/wicked,/var/lib/wicked
- NetworkManager:
Even with these exclusions, this feature is experimental and very likely to permanently break parts of your system (for example: networking, display manager, container runtimes, or system services whose permissions assumptions are violated by the ACLs). You should expect to need a full reinstall or offline repair after serious experimentation with this flag.
The current implementation wraps the ACL pass in extra confirmations, logs detailed progress using
pv(including an item count and approximate items/sec), and prints a concise summary at the end. A small sample of distinctsetfaclerrors (e.g. read-only filesystems, unsupported ACLs) is shown at the end so you can see what failed without being flooded by thousands of lines.
This mode is still work in progress and exists primarily for my own experimentation; treat it as an opt-in "I am trying to break my system on purpose" tool, not a supported configuration step. - Pseudo-filesystems:
-
--install-full-file-permissions-service
Install a systemd service + timer (passwordless-fb-fullacl.service/passwordless-fb-fullacl.timer) that periodically re-applies--full-file-permissionsin the background.
When you invoke the script with only this flag (no other modes like--full-file-permissions,--restore,--verify, etc.), it runs in a "installer-only" mode:- Asks for confirmation once.
- Writes/updates
/etc/passwordless-fb-fullacl.conf(described in detail below). - Generates/installs the systemd service + timer units.
- Runs
systemctl daemon-reloadandsystemctl enable --now passwordless-fb-fullacl.timer. - Exits without touching sudoers, polkit, groups, or anything else.
-
--uninstall-full-file-permissions-service
Uninstall the periodic full-ACL reapply service/timer.
When used by itself, this also runs in an exclusive uninstaller mode:- Shows a confirmation prompt.
- Disables and stops
passwordless-fb-fullacl.timerif it exists. - Removes
passwordless-fb-fullacl.service,passwordless-fb-fullacl.timer, and/etc/passwordless-fb-fullacl.conf(if present). - Runs
systemctl daemon-reload. - Exits without modifying sudoers, polkit, or other configuration.
-
--default-config
Reset/etc/passwordless-fb-fullacl.confback to its default template and exit without touching sudoers, polkit, groups, or systemd units.- Sets
ACL_TARGET_USERto the currentTARGET_USER(orid -unif unset). - Sets
ACL_EXTRA_ARGS="--sudo-only --no-install --yes". - Sets
ACL_ONCALENDAR="daily". - Respects
--dry-run(prints what it would do instead of writing). - Also accepts the misspelled alias
--defualt-configfor convenience.
- Sets
-
--all-groups
Extremely dangerous: enumerate every group on the system viagetent groupand add the target user to all of them (except those they are already a member of).
This effectively removes almost all group-based isolation between the user and system services, daemons, and device nodes.
Use this only if you fully understand that it turns the user into a "member of everything" and are prepared to reinstall the system if something breaks. -
--verify-pam-nullok -
Historical option name, now wired to a combined PAM + SSH empty-password audit that makes no changes. It will:
-
- Scan
/etc/pam.dforauthlines usingpam_unix/pam_unix.soand detect:
- Scan
-
- bare
nullokwithoutnullok_secure(local auth stacks that truly accept empty passwords), and
- bare
-
nullok_secure(TTY-only empty passwords, e.g. console login).
-
- Inspect the effective SSH server configuration (preferring
sshd -Twhen available, with a text fallback) to see whetherPermitEmptyPasswords yesis active anywhere.
- Inspect the effective SSH server configuration (preferring
-
- Print a concise summary:
-
PAM Status: ...(SAFE or RISK),
-
SSH Status: ...(SAFE or RISK), and
-
- a final CRITICAL/WARNING/RESULT line explaining whether empty passwords are possible locally, remotely, or both.
-
This is the safest way to see whether your system’s overall auth stack (both PAM and SSH) could meaningfully honor an empty Unix password before you consider changing any passwords yourself.
-
--root-unlock
Extremely dangerous, KDE-focused, experimental: run the script in a standalone "root desktop unlock" mode that tweaks only the root account, and then exits without touching normal passwordless sudo / polkit for other users. In this mode the script will:- Ensure the
rootaccount is a member of several desktop / device groups (audio,video,input,render,tty, etc.) so a root GUI session can see ALSA / PipeWire devices. - Adjust
/etc/pulse/client.confsoautospawn = yesandallow-autospawn-for-root = yes, and optionally unmute ALSA mixer channels usingamixer, then persist ALSA volume withalsactl store. - Bridge root audio to your regular desktop user’s PipeWire / PulseAudio server by exporting
PULSE_SERVER=unix:/run/user/<UID>/pulse/native(and matchingXDG_RUNTIME_DIR/DBUS_SESSION_BUS_ADDRESS) into/root/.bashrcand/root/.profile(and/root/.zshrcif it exists). In practice, this makes apps started as root talk to the non-root user’s sound server. - Optionally detect if the root account itself is locked in
/etc/shadow(password field begins with!or*) and, only if you explicitly confirm, runpasswd -u rootto unlock it so GUI/TTY root logins are possible. This is never done silently and is skipped entirely in--dry-runmode. - Write a small state file at
/etc/passwordless-fb-root-unlock.stateso the changes can later be reverted with--root-unlock-restore.
This mode is primarily designed and tested for KDE Plasma + PipeWire on single-user desktops. GNOME, XFCE, Hyprland, and other environments are not tested and may behave differently or break. Using
--root-unlockimplies you are comfortable running a full root GUI session, with all the risk that entails. - Ensure the
-
--root-unlock-restore
Companion to--root-unlock: attempts to undo as many of the root desktop tweaks as possible using the state file and timestamped backups created by the unlock run. In particular it will:- Restore
/etc/pulse/client.conffrom the most recent.bak.<timestamp>backup (if present). - Attempt to restore
/root/.config/pulse,/root/.config/pipewire, and/root/.local/state/wireplumberfrom the latest*.bak.<timestamp>directories that--root-unlockmoved aside. - Restore the previous
lingerstate for root (enable/disable), and the previoussystemctlenable/active state forpulseaudio.service, if they were successfully recorded in the state file. - Remove the
XDG_RUNTIME_DIR,DBUS_SESSION_BUS_ADDRESS, andPULSE_SERVERexports (and their comments) from/root/.bashrc,/root/.profile, and/root/.zshrcif they were added by--root-unlock. - Optionally remove root from any groups that
--root-unlockrecorded as newly added, returning root’s group membership as closely as possible to its prior state.
Because this restore flow depends on the presence and correctness of
/etc/passwordless-fb-root-unlock.stateand backups from the unlock run, it is a best-effort undo, not a guarantee. You should still treat--root-unlockas a high-risk, hard-to-fully-revert operation. - Restore
Adding the --all-groups flag to add your user to every group on the system is a classic case of confused security boundaries: it looks like a shortcut to "ultimate power", but it actually breaks how Linux separates services from users.
-
You become the "victim" for service accounts
Many daemons run under special accounts and groups (e.g.www-data,nginx,mail,dbus,rpc, etc.).- If you join a web-server-related group and accidentally store files with group-write or group-read permissions, the web server may now be able to read or modify them.
- If that service is compromised, the attacker can pivot directly into your data, because you bridged the gap between a confined service and your personal files via group membership.
-
The "nobody" / "nogroup" paradox
Groups likenobody/nogroupare designed as least-privilege sinks. Some security checks treat them specially.- Joining such groups can interact badly with mechanisms that expect only unprivileged, throwaway processes to be in them.
- You risk tripping logic that was never written with "a real interactive user in this group" in mind.
-
Fighting the seat manager (audio/video and device groups)
Modern Linux desktops use seat management (e.g.systemd-logind) to grant access to hardware devices (audio, video, input, GPUs, TTYs) dynamically to the currently active session.- Hard-coding yourself into groups like
audio,video,render,kvm,tty,disk,tape, etc. can confuse or override these mechanisms. - This can lead to strange bugs such as other users on the same machine losing sound, display, or device access because your account "owns" those devices via group membership all the time.
- Hard-coding yourself into groups like
-
Unintended privilege-escalation backdoors
Some groups are effectively root aliases:docker,lxd,libvirt– can start privileged containers/VMs and break out; effectively root.shadow– read access to password hashes.disk– raw block device access (bypassing filesystem permissions entirely).kmem– direct access to kernel memory on some systems.
By joining every group, you enable all of these escalation paths at once, plus many more subtle ones. This creates a permissions landscape that is extremely hard to audit or revert cleanly.
Summary:
--all-groups is imprecise and noisy:
- It adds you to dangerous groups (which already gives you "root-alike" power).
- It also adds you to service groups (which weakens isolation without useful extra power).
- It pulls you into legacy/system groups where your presence may surprise or confuse both the OS and security tooling.
For most scenarios, a curated set of "supreme" groups (e.g. root, disk, wheel, systemd-journal, network, video, audio, input, render, kvm, tty, tape, shadow, kmem, adm) already yields near-total control while being somewhat more predictable and documented than --all-groups.
In addition, the script will (where a su PAM service is present – either directly in /etc/pam.d/su or /etc/pam.d/su-l, or via a vendor file in /usr/lib/pam.d that it copies into /etc/pam.d) adjust the PAM configuration so that users in the wheel group can run su without a password by adding the trust option to the pam_wheel.so line. This logic is designed to be idempotent and cross‑distro friendly:
- It first looks for an existing
pam_wheel.soline and, if present, only addstrust(without duplicating the line). - If no
pam_wheel.soline exists, it inserts a singleauth sufficient pam_wheel.so use_uid trust group=wheelline in a sensible place (typically after thepam_rootok.soauth line, or near the top of the file as a fallback). - It only touches PAM configs when a
su/su-lservice file exists (either in/etc/pam.dor as a vendor file under/usr/lib/pam.d).
This makes su effectively passwordless for your admin user, on top of passwordless sudo, on most PAM-based Linux distributions where a wheel group is present.
Important: this PAM change does not create or modify groups; it only changes how su authenticates users who are already members of wheel. On systems where wheel does not exist or is not used for admin access, you may need to adjust the PAM group= setting or create/assign the wheel group yourself.
-
--yes
Non-interactive mode. Assume “yes” to prompts where applicable. -
--force
Allow overwriting existing/etc/sudoers.dand polkit rule files for this user and/etc/sudoers(where relevant).
Before overwriting, the script creates a backup: e.g./etc/sudoers.bak.20250101-123456. -
--dry-run
Show what would be done, without actually writing any files.
Useful to review changes before applying them. -
--restore
Restore the latest backups for/etc/sudoers,/etc/sudoers.d/<user>-passwordless, and/etc/polkit-1/rules.d/00-allow-<user>-everything.rules(if they exist).
Useful for rolling back changes made by this script. -
--verify-only/--verify
Run verification checks only: confirm that passwordless sudo works for the target user, and (if not using--sudo-only) run a best-effort polkit sanity check.
Makes no configuration changes. -
-h,--help
Print usage and exit.
-
Refuses to run as
root:if [[ "$(id -u)" -eq 0 ]]; then die "Do not run as root. Run as the target user with sudo access." fi
-
Determines
TARGET_USER:- If
--useris provided: validates that user exists (getent passwd). - Otherwise:
TARGET_USER="$(id -un)".
- If
-
Refuses to operate on
rootas target user:if [[ "$TARGET_USER" == "root" ]]; then die "Refusing to configure passwordless access for root." fi
-
Ensures
sudois installed and available, then refreshes sudo credentials:sudo -v
- Checks for
sudoand, if polkit is not disabled by--sudo-only, checks presence ofpkcheckorpkactionas a proxy for polkit. - If dependencies are missing:
- If
--no-installis set: aborts with an error and tells you what to install. - Otherwise:
- Detects package manager (
apt,dnf,yum,pacman,zypper,apk). - Asks you for confirmation (unless
--yesis set). - Installs required packages (e.g.
sudo,policykit-1,polkit).
- Detects package manager (
- If
-
Creates a small sudoers snippet in a temp file, e.g.:
<user> ALL=(ALL:ALL) NOPASSWD: ALL Defaults:<user> !authenticate -
Validates this temp file with:
sudo visudo -c -f "$SUDOERS_TMP" -
Compares with existing
/etc/sudoers.d/<user>-passwordless(if any):- If identical, it logs “already configured” and does not overwrite.
- If different, it backs up the old file (if
--forceis used) and installs the new one with correct permissions (0440, owned byroot:root).
-
After installation, it validates the entire sudoers configuration with:
sudo visudo -c
-
Runs a simple check as the target user:
sudo -u "$TARGET_USER" -H bash -lc 'sudo -n true'
-
If that command fails, the script aborts and tells you to inspect the files.
In addition to using /etc/sudoers.d, the script can ensure the main /etc/sudoers file contains a line:
<TARGET_USER> ALL=(ALL:ALL) NOPASSWD: ALL
How it does this safely:
-
Copies
/etc/sudoersto a temp file. -
Checks if a matching
NOPASSWDline already exists (supports small formatting differences):sudo grep -Eq "^${TARGET_USER}[[:space:]]+ALL=\(ALL(:ALL)?\)[[:space:]]+NOPASSWD:?[[:space:]]+ALL" "$tmp"
-
Also checks for the marker comment from a previous run, to avoid re-adding the same block:
# Added by <script-name> for passwordless sudo for <user> -
If neither is present, it appends:
# Added by <script-name> for passwordless sudo for <user> <user> ALL=(ALL:ALL) NOPASSWD: ALL -
Validates the modified sudoers (using
visudo -c -f <temp>). -
Backs up the original
/etc/sudoers(if--forceis used). -
Installs the new validated file with strict permissions (
0440,root:root).
This means you can re-run the script multiple times and it won’t keep appending new lines.
Unless --sudo-only is passed, the script attempts to create a polkit rule which grants the target user unconditional approval. It also includes tightened detection for newer polkit versions where JavaScript rules may no longer be honored.
-
Writes
/etc/polkit-1/rules.d/00-allow-<user>-everything.rulessimilar to:// Generated by setup-passwordless-fb.sh // WARNING: This approves all polkit actions for "<user>". polkit.addRule(function(action, subject) { if (subject.user === "<user>") { return polkit.Result.YES; } });
-
Ensures the directory
/etc/polkit-1/rules.dexists. -
Checks if the existing rule (if any) is identical; if so, it does not overwrite.
-
Otherwise, backs up the old one (if
--forceis used) and installs the new rule. -
Attempts to restart polkit (best effort), using either
systemctlorservice.
Before writing or relying on the JS rule, the script:
-
Uses
pkaction --versionto detect polkit versions 124+ (where upstream dropped JS rules). -
If a newer polkit is detected, it searches common rules directories such as:
/etc/polkit-1/rules.d/usr/share/polkit-1/rules.d/usr/lib/polkit-1/rules.d
for
.rulesfiles that containpolkit.addRule. If any are found, it assumes JS rules are still supported by the distro. -
If no such JS rules are found, it marks JS rules as "maybe unsupported" and logs a warning. In this situation the script does not change your Unix password automatically. Instead, it advises you to:
-
- Run
--verify-pam-nullok(or the standalonepam-nullok-check.shhelper) to see whether your PAM stack actually accepts empty passwords viapam_unix nullok.
- Run
-
- If, and only if, you fully understand the implications and your PAM stack is configured to honor empty passwords, you may choose to run
passwd -d <USER>yourself to drop the local Unix password. This is always a manual, explicit action; the script will not runpasswd -dfor you.
- If, and only if, you fully understand the implications and your PAM stack is configured to honor empty passwords, you may choose to run
If pkcheck is available, the script runs a small, non-fatal sanity check to ensure polkit is at least responsive.
This doesn’t guarantee everything is configured, but can catch obvious issues.
cd /path/to/Password-less
./setup-passwordless-fb.sh --sudo-only --yes --force- Targets the current user (
id -un). - Configures
/etc/sudoers.d/<user>-passwordless. - Ensures
/etc/sudoersitself has aNOPASSWDline for<user>. - Skips polkit rules.
- Doesn’t ask interactive questions (
--yes). - Allows overwriting existing config with backups (
--force).
./setup-passwordless-fb.sh --user alice --yes --force- Targets
alice. - Configures both
sudoers.dand/etc/sudoers. - Also sets polkit rule for
alice. - Non-interactive and allows overwrites with backups.
./setup-passwordless-fb.sh --user alice --sudo-only --dry-run- Shows what would be written/changed.
- Does not actually write anything.
If you want a background job that periodically re-applies --full-file-permissions for a user (for example after package updates or filesystem changes), you can install the systemd service/timer without running the rest of the setup:
./setup-passwordless-fb.sh --install-full-file-permissions-serviceWhat this does:
-
Prompts you with a clear warning that a periodic full-ACL job is being installed.
-
Writes (or reuses)
/etc/passwordless-fb-fullacl.conf, which controls the behavior of the timer + service. A freshly created default file looks like:# Environment for passwordless-fb-fullacl # User that should receive full-file-permissions ACLs. # Change this to a different user name if needed. ACL_TARGET_USER=<your-username> # Extra arguments passed to setup-passwordless-fb.sh when run from the service. # By default we avoid reinstalling anything and run non-interactively. ACL_EXTRA_ARGS="--sudo-only --no-install --yes" # How often to run the full-file-permissions service. This is copied directly # into the systemd timer's OnCalendar= setting. Examples: # ACL_ONCALENDAR="daily" # once per day (default) # ACL_ONCALENDAR="hourly" # every hour # ACL_ONCALENDAR="Mon..Fri 02:00" # weekdays at 02:00 ACL_ONCALENDAR="daily"
ACL_TARGET_USER– which user receives the ACLs. If unset, the installer resolves it to the invoking user and bakes that into the unit.ACL_EXTRA_ARGS– extra arguments passed to the script when run from the service. If you remove this line, the installer safely defaults it back to--sudo-only --no-install --yesso the unit stays valid.ACL_ONCALENDAR– systemd calendar expression controlling how often the job runs. If omitted, it falls back todaily.
-
Creates
passwordless-fb-fullacl.servicethat runs roughly:ExecStart=/usr/bin/env bash /path/to/setup-passwordless-fb.sh --user ACL_TARGET_USER --full-file-permissions ACL_EXTRA_ARGS -
Creates
passwordless-fb-fullacl.timerthat triggers the service according toACL_ONCALENDAR. -
Reloads systemd units and immediately enables/starts the timer.
The service uses the same
pv-backed progress, runtime measurement, and ACL error sampling as the interactive--full-file-permissionsrun. It is still extremely dangerous and should only be used on machines where you fully accept the security and stability trade-offs.
To remove the service/timer and its config without touching anything else:
./setup-passwordless-fb.sh --uninstall-full-file-permissions-serviceThis:
- Confirms with you interactively (unless
--yesis also given). - Disables and stops the timer if it exists.
- Deletes the service unit, timer unit, and
/etc/passwordless-fb-fullacl.conf(if present). - Reloads systemd.
You can run the script multiple times without it:
- Adding duplicate
NOPASSWDlines to/etc/sudoers. - Re-creating the same drop-in under
/etc/sudoers.d. - Re-installing identical polkit rule files.
It detects:
- Matching contents in
/etc/sudoers.d/<user>-passwordless. - Existing
NOPASSWDlines in/etc/sudoerswith minor format variations. - Its own marker comment in
/etc/sudoers. - Identical contents in
/etc/polkit-1/rules.d/00-allow-<user>-everything.rules.
When things are already configured, it logs info like:
[info] Sudoers already configured (... is identical); skipping install.
[info] Main sudoers already has a NOPASSWD line for <user>; skipping.
[info] Polkit rule already configured (... is identical); skipping install/restart.
To undo the configuration for a given user <user>:
-
Remove the sudoers drop-in:
sudo rm -f /etc/sudoers.d/${user}-passwordless -
Edit
/etc/sudoersviavisudoand remove the block:# Added by setup-passwordless-fb.sh for passwordless sudo for <user> <user> ALL=(ALL:ALL) NOPASSWD: ALLThen validate via:
sudo visudo -c
-
Remove the polkit rule (if created):
sudo rm -f /etc/polkit-1/rules.d/00-allow-${user}-everything.rules -
Optionally restart polkit or reboot.
If you used --force, backups like "/etc/sudoers.bak.<timestamp>" will exist. 
You can restore them manually if needed:
sudo cp /etc/sudoers.bak.<timestamp> /etc/sudoers
sudo chown root:root /etc/sudoers
sudo chmod 0440 /etc/sudoers
sudo visudo -cModern Linux PAM stacks often control whether empty passwords are accepted via options on pam_unix:
nullok– allows empty passwords for that auth stack (e.g.system-auth,password-auth).nullok_secure– allows empty passwords only on secure TTYs (e.g. local console), but not for GUI/SSH/other sessions.
This script uses a conservative heuristic:
- It considers the system to "accept empty passwords" only if it finds at least one
auth pam_unix(.so)line that: -
- Contains bare
nullok, and
- Contains bare
-
- Does not contain
nullok_secureon the same line, and
- Does not contain
-
- Is not commented out.
- The mere existence of
nullok_securein some other file (for example/etc/pam.d/login) does not cause a global failure; it is common to usenullok_securefor TTY logins while using barenullokfor other paths.
You can inspect this behavior in two ways:
./setup-passwordless-fb.sh --verify-pam-nullok– runs the unified PAM + SSH audit embedded in the main script to:-
- Print all relevant
pam_unixlines in/etc/pam.dcontainingnullokornullok_secure.
- Print all relevant
-
- Show a per-file summary of where bare
nullokis present (empty passwords accepted) vs. wherenullok_secureis present (TTY-only empty passwords).
- Show a per-file summary of where bare
-
- Inspect the effective SSH configuration (via
sshd -Twhen possible, with a text fallback) to detect anyPermitEmptyPasswords yessettings.
- Inspect the effective SSH configuration (via
-
- Summarize results as
PAM Status,SSH Status, and a final CRITICAL/WARNING/RESULT line.
- Summarize results as
sudo bash pam-nullok-check.sh– standalone helper script with similar semantics focused primarily on PAM (with its own SSH awareness) that you can run independently of the full setup flow.
Important:
- The script no longer deletes Unix passwords automatically under any circumstances.
- If you ever decide to remove your local password (e.g.
sudo passwd -d $USER), you must: -
- First use the tools above to confirm your PAM stack is truly configured to honor empty passwords in the contexts you care about.
-
- Then run
passwd -dyourself, fully accepting the risk of lockout if your assessment is wrong.
- Then run
-
Check that the drop-in file exists and is correct:
sudo cat /etc/sudoers.d/${USER}-passwordless -
Check combined config validity:
sudo visudo -c
-
Make sure there are no conflicting entries for that user or group in
/etc/sudoersor other files in/etc/sudoers.d/.
-
Ensure you did not run with
--sudo-only. -
Check that the polkit rule file exists:
sudo ls -l /etc/polkit-1/rules.d/ sudo cat /etc/polkit-1/rules.d/00-allow-${USER}-everything.rules -
Some distros ship polkit >= 124, where JavaScript rules may be disabled.
In such cases, this script will warn you, but the rule might still not be honored.
-
If it says something like:
Refusing to overwrite existing /etc/sudoers.d/... Re-run with --forcethen re-run the script with
--forceto allow overwriting (with backups).
This repository contains setup-passwordless-fb.sh, a helper script for configuring passwordless sudo (and, optionally, polkit) for a single user on Linux systems.
The script includes an opt-in flag named --full-file-permissions. When enabled, and after additional confirmation, the script runs the following command for the chosen target user:
sudo setfacl -R -m u:<TARGET_USER>:rwx /This means:
- It applies recursive (
-R) POSIX ACL changes starting at the root directory/. - It grants the target user explicit read, write, and execute (
rwx) permissions on every file and directory that is reachable from/and supports ACLs. - This ACL grant is additive – it does not replace the existing owner/group/mode bits – it layers an additional access rule on top. In effect, the chosen user becomes able to read/modify/delete/execute almost anything on the system, regardless of traditional Unix permissions.
When you run with --full-file-permissions, the script also:
-
Detects and installs
pvwhen needed (via your distro’s package manager) so that large ACL runs have a proper progress indicator. -
Counts how many filesystem entries will be touched and prints a line such as:
[info] Found 234882 items. Starting ACL application with progress bar... -
Streams paths through
pvwith-l(line-based) and labels the streamApplying ACLs, so you see a live bar like:Applying ACLs: [======>...] 45% 105,000 / 234,882 3.2k/s 00:35 -
Measures runtime and prints a summary with an approximate throughput, e.g.:
[info] Successfully applied ACLs to approximately 234882 items in 42s (~5592 items/sec). -
Captures
setfaclstderr into a temporary log, filters out the usual noisy lines (like operations on read-only or unsupported filesystems), and at the end prints up to five unique error samples such as:[info] Sample of ACL errors (up to 5 unique messages): [acl-error] /sys/...: Operation not supported [acl-error] /run/...: Read-only file system
This gives you a clear sense of how much was processed, how fast, and what kind of things failed, without drowning you in raw error spam.
Because of the breadth and depth of this change, using --full-file-permissions is still much more invasive than simply granting passwordless sudo.
On systems with a desktop session and notify-send available, the script also emits desktop notifications for full-ACL runs:
- When a
--full-file-permissionsrun starts (either interactive or via the systemd service):- A notification such as: "Applying recursive ACLs on / for . This may take a while and can affect many files."
- When it finishes:
- If it completed cleanly: "ACL application on / for is complete. Full-file-permissions are now in effect."
- If there were errors: "ACL application on / for finished with some errors. Check terminal output if you care about 100% coverage."
The script best-effort targets the user’s graphical session (via the user’s D-Bus session bus) when running as root (e.g. from the systemd service). If no GUI or notify-send is available, these notifications are silently skipped.
Passwordless sudo is already equivalent to giving a user full administrative control over the machine: they can run arbitrary commands as root, change system configuration, install software, access most data, etc. That said, sudo-based elevation is:
- Transient and explicit: the user must run
sudo <command>, which is at least a clear, explicit action. - Policy-aware: changes can be logged and restricted via sudoers policies.
- Relatively reversible: you can remove or tighten sudoers configuration and immediately affect future sudo behavior.
In contrast, recursively applying ACLs on /:
- Silently rewrites the access model of the entire filesystem. Existing security assumptions based on Unix owner/group/mode bits become invalid in subtle ways.
- Persists across sessions and configuration changes. Even if you later remove passwordless sudo or revoke group memberships, the ACL entries will remain until they are explicitly removed.
- Applies to everything under
/that supports ACLs, including:- System binaries and libraries (e.g.
/usr/bin,/lib,/usr/lib) - Configuration files under
/etc - User homes under
/home - Application data under
/varand/opt - Potentially mounted filesystems beneath
/(depending on how ACLs are handled by the underlying filesystem and mount options)
- System binaries and libraries (e.g.
Once this ACL has been applied, the target user can:
- Modify or delete system binaries and libraries, making integrity checking and debugging much more difficult.
- Read and alter configuration for services they would not normally have access to.
- Read other users’ data under
/home(unless specifically protected by other mechanisms such as encryption or separate mounts without ACLs). - Tamper with logs, databases, and caches under
/var. - Plant or modify code in locations that other users or system services trust.
From a security perspective, this effectively turns the chosen user into a superuser in the filesystem sense, which can be even more chaotic than traditional sudo-based access.
Using --full-file-permissions introduces several classes of risk:
-
Accidental data loss or corruption
- Any command that the target user runs (even without
sudo) now has the ability to write into locations that would normally be protected. - Mis-typed commands, erroneous scripts, or poorly tested tools can unintentionally overwrite or delete critical system files.
- Automated tools, editors, or IDEs may suddenly "helpfully" rewrite files under
/etc,/usr, or/varthat they could not touch before.
- Any command that the target user runs (even without
-
Security boundary collapse
- Traditional Unix permissions, which separate system data from user data, no longer provide meaningful protection against the target user.
- Multi-user environments become effectively single-trust-domain from the perspective of that user: they can read or change almost anything other users store in normal locations.
- Any compromise of the target user account (e.g. stolen credentials, malware, or remote exploit) becomes instantly catastrophic: the attacker does not even need to leverage sudo; they already have direct filesystem-level control.
-
Difficult recovery
- ACLs are stored as extended attributes, not visible in plain
ls -loutput. Debugging "why can this user access this file?" becomes more complex. - Undoing a recursive ACL change on
/is non-trivial. In theory, you could attempt the inverse operation (e.g.setfacl -R -x u:<TARGET_USER> /), but:- You must be sure of the exact ACL entries you added.
- Other ACL-based changes made later might be entangled with these entries.
- Some filesystems or mounts may handle ACL inheritance in unexpected ways.
- In many real-world scenarios, the safest recovery path after such a broad ACL change is a full system reinstall or bare-metal restore.
- ACLs are stored as extended attributes, not visible in plain
-
Interference with system tools and security software
- Backup tools, intrusion detection systems, and integrity checkers might misbehave or produce noisy reports because permissions no longer match expected baselines.
- Certain security-sensitive services assume that some directories are only writable by root or a dedicated service account. Granting a regular user
rwxmay circumvent these assumptions in ways that are hard to audit.
This option exists primarily for very narrow, specialized, and short-lived scenarios, for example:
- Disposable test environments where the machine can be thrown away and rebuilt at any time.
- Highly controlled lab setups where you intentionally want to model a "filesystem-compromised" environment.
- Personal single-user systems where you fully understand the impact and you are comfortable with potentially reinstalling if something goes wrong.
Even in these cases, there are usually better alternatives, such as:
- Using virtual machines or containers, and giving yourself full control inside the isolated guest/container instead of on the host.
- Mounting specific directories with permissive settings or separate ACLs, instead of modifying the entire root filesystem.
- Relying on passwordless sudo alone, which is already powerful but does not rewrite ACLs on every file.
If you find yourself needing this power repeatedly, consider pushing it into a disposable VM or container rather than your main OS, or at minimum using the systemd timer so you understand when ACLs are being refreshed instead of re-running the script manually in ad-hoc ways.
If you still decide to enable it, the typical usage is:
./setup-passwordless-fb.sh --user <your-username> --full-file-permissionsThe script will:
- Detect and validate the target user.
- Configure passwordless sudo (and polkit, unless
--sudo-onlyis passed). - Prompt you with clear warnings about the dangers of
--full-file-permissions. - Ask for explicit confirmation again before running
setfacl -R -m u:<TARGET_USER>:rwx /.
To see what would happen without making changes, you should always first run:
./setup-passwordless-fb.sh --user <your-username> --full-file-permissions --dry-runThis prints the commands that would be executed, including the ACL modification, but does not actually change anything.
There is no simple, guaranteed-safe one-liner to fully undo the effects of recursively granting u:<TARGET_USER>:rwx on /:
-
You can attempt to remove the ACL entry with a matching recursive command, for example:
sudo setfacl -R -x u:<TARGET_USER> /
However, this assumes that all ACL entries for that user were created by this script and that no other legitimate ACLs have been added later.
-
Some filesystems, mount points, or system directories may have their own ACL policies, inheritance rules, or may not support ACLs in a uniform way, making the exact end state hard to reason about.
For systems where you care about integrity and correctness, the most reliable way to fully revert is usually:
- Back up essential data.
- Reinstall or re-image the OS.
- Restore user data from a known-good backup.
Because of this, you should treat --full-file-permissions as a "nuclear" option: once used, you should assume the machine’s security posture is permanently altered.
--full-file-permissionsis not required for passwordless sudo or everyday administrative convenience.- It performs a sweeping ACL change that effectively gives the chosen user root-like filesystem access everywhere under
/. - This is highly dangerous, hard to audit, and difficult to fully undo.
- You should avoid this option in any environment where security, multi-user isolation, or long-term system stability matters.
If you are not absolutely certain you understand all of the above, do not use --full-file-permissions.
In addition to sudoers and (optionally) polkit, the script makes a few desktop-related adjustments to align graphical tools with the passwordless setup.
On KDE/Plasma systems where kwriteconfig5 is available and the desktop session is detected as KDE/Plasma, the script configures the kdesu helper to use sudo instead of su.
- This is done by writing to the
kdesurcconfiguration using:kwriteconfig5 --file kdesurc --group super-user-command --key super-user-command sudo
- Effect: graphical "Run as root" prompts will respect the same passwordless sudo configuration you have just set up, instead of asking for a separate
rootpassword. - If
kwriteconfig5is not present or the session is not KDE/Plasma, this step is skipped.
As described earlier, the script also adjusts PAM configuration for su/su-l so that users in the wheel group can invoke su without a password, by adding the trust option to the pam_wheel.so line in a safe, idempotent way. This change only applies when a suitable PAM su service file exists and is copied into /etc/pam.d if necessary.
These integrations are optional and best-effort, but they help align GUI tools and the classic su command with the passwordless sudo configuration, so you don’t end up in a state where some tools recognize the passwordless setup and others still prompt unexpectedly.
Contributions are welcome:
- Support for more distros or package managers
- Handling more polkit configurations (especially for newer polkit versions)
- Better detection of edge cases in sudoers layouts
Please open issues or pull requests on the repo.
Choose and state your license here, for example:
- MIT
- GPLv3
- Apache-2.0