How to create a sudo user and disable root login on Ubuntu and Debian

Add a normal user with sudo rights on Ubuntu or Debian, give it your SSH key, then stop root logging in over SSH without locking yourself out.

Tested on Ubuntu 24.04 LTS, Debian 13 Stable

Before you start

  • A server running Ubuntu or Debian
  • An SSH session as root with a key
  • Your public SSH key (the one you log in with)

To create a sudo user on Ubuntu or Debian, run adduser deploy and then usermod -aG sudo deploy; members of the sudo group can run any command as root. To disable root login, copy your SSH key to the new user, check you can log in and use sudo, then put PermitRootLogin no in a file under /etc/ssh/sshd_config.d/ and reload SSH.

The order matters: if you turn root login off before the new user works, you are locked out. Keep your root session open until the last step has passed its check.

The examples use deploy as the user name and 203.0.113.10 as the server's address. Use your own.

Create the user

Log in as root and create the user. adduser asks for a password and some optional details (press Enter to skip them):

bash
adduser deploy

The password is what sudo asks for, not an SSH password: SSH keeps using your key. Pick a long one and keep it in your password manager.

On Debian, the cloud image may not include sudo at all. Install it if command -v sudo prints nothing:

bash
apt update && apt install -y sudo

Now add the user to the sudo group:

bash
usermod -aG sudo deploy

-a appends to the user's groups. Without it, -G replaces them.

Check it worked

bash
id deploy

The output should list 27(sudo) among the groups, for example uid=1001(deploy) gid=1001(deploy) groups=1001(deploy),27(sudo),100(users). The rule that gives the group its rights is already in /etc/sudoers on both distributions: %sudo ALL=(ALL:ALL) ALL.

Give the user your SSH key

Root already has your key in /root/.ssh/authorized_keys. Copy it to the new user with the right owner and permissions in one go:

bash
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys

SSH ignores an authorized_keys file that other users can write to, so the 700 and 600 modes are not optional. If you would rather give deploy a different key from root's, paste that public key into /home/deploy/.ssh/authorized_keys instead and keep the same modes.

Check it worked

From your own computer, in a new terminal (leave the root session open):

bash
ssh deploy@203.0.113.10
sudo whoami

sudo asks for the password you set with adduser, then prints root. If either step fails, fix it now, from the root session, before going on.

Disable root login over SSH

OpenSSH reads every file in /etc/ssh/sshd_config.d/ in name order and keeps the first value it finds for each setting. A file starting with 01- therefore beats anything the image or another guide put there, such as 50-cloud-init.conf or the 10-hardening.conf from our SSH keys guide. As root (or with sudo from the new user):

bash
echo 'PermitRootLogin no' | sudo tee /etc/ssh/sshd_config.d/01-no-root-login.conf

Test the configuration, then reload. The service is called ssh on both Ubuntu and Debian:

bash
sudo sshd -t && sudo systemctl reload ssh

sshd -t prints nothing when the configuration is valid. A reload keeps your open sessions.

Check it worked

Ask SSH which value it is really using:

bash
sudo sshd -T | grep -i '^permitrootlogin'

It should print permitrootlogin no. Then try both logins from your computer, in new terminals:

bash
ssh root@203.0.113.10      # refused: Permission denied (publickey)
ssh deploy@203.0.113.10    # works

Only when the second one works should you close the root session.

Work as the new user

From now on, log in as deploy and put sudo in front of commands that need root:

bash
sudo apt update

For a longer stretch of admin work, sudo -i opens a root shell (type exit to leave it). sudo logs every command to the system journal, which sudo journalctl _COMM=sudo shows.

Root itself still exists and still has its password, if you set one. That's what you use on the serial console, which doesn't go through SSH. Don't lock or delete the root account.

Troubleshooting

deploy is not in the sudoers file. This incident will be reported. The user isn't in the sudo group, or it is but you're still in a session that started before you added it. Run usermod -aG sudo deploy as root, then log out and back in: group changes only apply to new sessions.

Permission denied (publickey) for the new user. The key isn't where SSH looks, or the permissions are too open. As root, check ls -la /home/deploy/.ssh: the folder should be drwx------ and the file -rw-------, both owned by deploy. journalctl -u ssh -n 20 usually names the problem, for example Authentication refused: bad ownership or modes.

Root can still log in after the change. Another file set PermitRootLogin first. Run grep -ri permitrootlogin /etc/ssh/sshd_config /etc/ssh/sshd_config.d/ and check yours has the lowest number, then reload again.

sudo: command not found on Debian. The image doesn't ship it. As root, apt install -y sudo.

Locked out completely. Use the serial console with root's password, or rescue mode if root has none, and delete /etc/ssh/sshd_config.d/01-no-root-login.conf.

Next steps

Doing it on VPSNine

New VPSNine servers let you in as root with the SSH key you chose when you ordered, and already refuse SSH passwords. The secure server setup script does everything on this page on first boot if you'd rather not do it by hand. Pick Ubuntu 24.04 or Debian 13 when you order, on any of the plans.

Be first when orders open

Join the waitlist and we'll send you one email when VPSNine launches. Pick a plan if you already know which one you want, and we'll size the first servers around it.

  • One email, on launch day
  • Monthly or yearly, no lock-in
  • 14-day money-back guarantee