Manage Linux Users and sudo Permissions on a VPS
Every shared-root server has the same origin story. One person spins up the VPS, a second needs access so they get handed the root password, a contractor joins and gets it too, and within a year nobody can say who logged in last week or who still knows the password that protects everything. When something is deleted at 3 a.m., the audit trail is a single word: root. Proper user management is the cure, and on Linux it is neither hard nor optional — give every human their own account, grant privilege narrowly through sudo, and the question "who did this?" always has a real answer. This guide sets that up from a fresh server.
adduser, then grant elevation through sudo rather than sharing root. Scope privileges with drop-in files in /etc/sudoers.d/, always edited via visudo so a syntax error cannot lock everyone out. Disable direct root SSH login (PermitRootLogin no), audit access by listing the sudo group and reading /var/log/auth.log, and remove departed users cleanly with deluser.Create a Real Account for Each Person
Start by giving every human their own login. On Debian and Ubuntu, adduser is the friendly wrapper — it creates the home directory, sets up the user's group, and prompts for a password — where the lower-level useradd makes you specify all of that by hand:
1sudo adduser jordan
Answer the password prompt and you have a working account. The principle underneath is simple and worth stating plainly: one account per person, never a shared one. Shared accounts destroy accountability and make off-boarding impossible, because revoking access for one person means changing a password everyone else depends on. A named account, by contrast, can be removed the day someone leaves without disturbing anyone else.
Grant Privilege with sudo, Not the Root Password
A new user can log in but cannot administer the system — that is correct. Rather than handing out the root password, you grant specific users the ability to run commands as root through sudo, which has two decisive advantages: every elevated command is logged against the real user, and you can scope exactly what each person may do. The blunt approach is to add a trusted administrator to the group that already has full sudo rights — sudo on Debian/Ubuntu, wheel on RHEL-family systems:
1sudo usermod -aG sudo jordan
The -aG is critical: -a means append, and forgetting it replaces all of the user's other group memberships instead of adding one. After the change, the user logs out and back in for the new group to take effect, then confirms it works:
1sudo -l
sudo -l lists exactly what the current user is permitted to run — the first thing to check after granting (or suspecting) access.
Scope Privileges with /etc/sudoers.d
Full sudo is right for administrators but wrong for a deploy account or a junior who should only restart one service. The clean, upgrade-safe way to grant narrow rights is a drop-in file under /etc/sudoers.d/ rather than editing the main /etc/sudoers. Drop-ins keep each grant isolated, easy to read, and easy to remove. Create one with the dedicated editor:
1sudo visudo -f /etc/sudoers.d/deploy
Inside, grant a user permission to run only specific commands — here, restarting and reloading one service without a password:
1deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp, /bin/systemctl reload myapp
That line reads: user deploy, on ALL hosts, may run as ALL users, with no password prompt, exactly those two commands and nothing else. Trying to run anything broader is denied and logged. This is the principle of least privilege made concrete — the deploy account can do its job and cannot wander.
Always Edit With visudo
The single most important habit in this entire topic: never open a sudoers file in a plain text editor. A syntax error in /etc/sudoers does not fail gracefully — it can make sudo refuse to run for everyone, and if you have already disabled root login (next section), you have locked yourself out of your own server. visudo exists precisely to prevent this. It locks the file against concurrent edits and, crucially, checks the syntax before saving; if you have made a mistake it refuses to write the broken file and lets you fix or discard it:
1sudo visudo
The same protection applies to drop-ins via visudo -f /etc/sudoers.d/<name>, as above. The rule has no exceptions: every change to sudo configuration goes through visudo, every time. If you want to confirm the whole configuration parses cleanly at any point, visudo -c checks it without opening an editor.
Lock Down the Root Login
With named accounts holding sudo, nobody needs to log in as root over SSH — and disabling it removes the single most-attacked account on any internet-facing server. Edit the SSH daemon configuration:
1sudo nano /etc/ssh/sshd_config
Set the directive (uncomment it if present):
1PermitRootLogin no
Apply it by reloading the daemon — reload rather than restart so an existing session survives in case something is wrong:
1sudo systemctl reload sshd
Before you close that session, open a second terminal and confirm your named account can still log in and run sudo. Verifying the new path works before you rely on it is the difference between a routine hardening step and a lockout. With root login disabled, an attacker must now guess both a valid username and its password or key, instead of pounding on the one account they already know exists.
Audit Who Has Access
Access granted is access you must be able to review. Two commands answer "who can become root on this box?" List the members of the privileged group:
1getent group sudo
And read the authentication log to see who has actually been using elevation and from where:
1sudo grep sudo /var/log/auth.log | tail -n 50
(On RHEL-family systems the equivalent log is /var/log/secure.) Every sudo invocation records the real user, the command, and the time — which is the entire payoff of the named-account model. The vague root did it is replaced by a precise line naming a person, a command, and a timestamp. Make this audit a periodic habit, not a post-incident scramble.
Remove Users Cleanly
Off-boarding is where shared-root setups fall apart and named accounts shine. When someone leaves, disable or remove their single account and their access is gone — no password rotation, no scramble. To revoke access immediately while preserving their files for handover, lock the account:
1sudo passwd -l jordan
To remove the user entirely once their files are no longer needed, deluser (the Debian/Ubuntu counterpart to userdel) handles it, optionally taking the home directory with it:
1sudo deluser --remove-home jordan
Then, just as importantly, remove any drop-in that referenced them — sudo rm /etc/sudoers.d/jordan if one existed — so no stale grant lingers. Clean removal is the proof that the whole model worked: one person's departure touches exactly one account and nobody else's access.
Accountability by Design
None of these steps is difficult, and together they replace "everyone knows the root password" with a system where every action traces to a person, every privilege is scoped to a need, and a departure is a one-line cleanup. Named accounts with adduser, narrow grants through /etc/sudoers.d/ edited only via visudo, root SSH login disabled, and a periodic read of the auth log — that is the whole discipline. Set it up on day one of a new VPS and you never have to reconstruct who did what from a log that only ever says root.
References
Posts in this series
- Linux VPS Performance Tuning: sysctl & swap 2026
- Systemd Service Hardening: Sandbox a Unit (2026)
- Fail2ban on Ubuntu VPS: Stop SSH Brute Force 2026
- UFW Firewall Rules for a Public VPS: 2026 Setup
- How to Harden SSH on an Ubuntu VPS (2026 Guide)
- Automated Backups with Rsync and Cron on Linux 2026
- TLS Certificates with Certbot on an Ubuntu VPS 2026
- Harden Nginx on Ubuntu: Headers, TLS & Limits 2026
- Automatic Security Updates on Ubuntu: 2026 Setup
- Logrotate for Nginx and App Logs on a Linux VPS
- Systemd Timers: Replace Cron Jobs on a Linux VPS
- Manage Linux Users and sudo Permissions on a VPS
- Linux VPS Disk and Inode Cleanup: du, find, lsof
- journald Logs: Retention, Size Limits and Queries