Where to start First steps track · 15 stages
Linux Labs

nologin — a shell that refuses login

4 min Ubuntu 24.04; Bash 5.2 for shell builtins

A login-shell replacement that reports refusal and exits instead of opening an interactive shell.

Cheat sheet

5 commands Printable version
  • getent passwd labsvc inspect the shell field
  • id labsvc inspect UID and groups
  • type -a nologin locate the installed program
  • /usr/sbin/nologin observe refusal, without changing shell
  • printf '%s\n' "$?" immediately read its nonzero status

Overview

nologin is a login-shell replacement: an ordinary invocation refuses login and exits with a nonzero status. It is useful for a service account that does not need an interactive shell.

The account retains its UID, groups, and file ownership. A service can continue running under its identity. The shell field is not a global prohibition on the kernel creating processes with that UID.

Options

2

The main use is setting the program's path in the user's shell field. The program itself has only --help and --version; every other invocation always ends in refusal. Verify the local path before changing an account; training examples use /usr/sbin/nologin.

Do not confuse the program with /etc/nologin and PAM-based login restrictions. These are different interfaces. Use man 8 nologin for documentation about the program specifically.

Option What it does Example
-h --help Print a short help text and exit (not the login refusal). /usr/sbin/nologin -h
-V --version Print the program version and exit. /usr/sbin/nologin -V

Nothing found. Try a shorter query.

Recipes

3

Assign the training account's shell

Only for a prepared labsvc, when the exercise requests this change:

bash
sudo usermod -s /usr/sbin/nologin labsvc
getent passwd labsvc

Inspect the final account field. This verifies the setting; conclusions about a particular remote access method require a separate check of the relevant service.

Demonstrate the program's refusal

bash
/usr/sbin/nologin
refusal_status=$?
printf 'status=%s\n' "$refusal_status"

The message may depend on locale and system configuration. The refusal and nonzero status matter for this observation, rather than an exact sentence on screen.

Test the restriction's boundary

When permitted by sudo policy:

bash
sudo -u labsvc id

A successful run shows that executing a command under a UID and opening a login shell are different actions. It neither proves SSH login is possible nor removes the shell restriction.

Troubleshooting

2

The service runs although the shell is blocked

This can be expected: the service manager launches a program directly as the designated user. Compare the service account and process before deciding that the setting failed.

sudo still permits a command as that user

Inspect sudo rules. Assigning nologin does not revoke permissions granted there. An access-revocation task must check those mechanisms separately.

Danger zone

Do not assign nologin to your sole administrator account. Do not change global login-restriction files to affect a single training user.

Changing the shell neither deletes SSH keys nor stops existing processes, and is not complete account deactivation. State the requirement precisely: which new access must stop, and which services must keep working.

See also

  • users-groups — account record fields.
  • chage — account expiration.
  • sudo — permission to execute specific commands.
  • systemd — running services under service accounts.
Loading…