Post

Non-Interactive Shell

How to Create Non-Interactive & Restricted Shell Users in Linux

Non-Interactive Shell

A practical guide to locking down user access while keeping your system functional

The Problem

You need users to run specific tasks on your Linux server — Git pushes, file uploads, or service processes — but you don’t want them browsing your filesystem or running arbitrary commands.

The solution? Non-interactive shells and restricted environments.

Let me show you exactly how to set this up.


The Basics — Non-Interactive Users

These users can own processes and files, but cannot get a shell.

Quick Setup

1
2
3
4
5
# For service accounts (recommended)
sudo useradd -s /sbin/nologin -r username

# For existing users
sudo usermod -s /sbin/nologin username

How to Verify Non-Interactive Users Without Logging In

You don’t need to actually log in as the user to confirm they’re non-interactive. Here are 5 ways to verify from your admin account.

Check the Shell Assignment (Quickest)

1
2
3
4
5
# View the user's shell directly
grep username /etc/passwd

# Or using getent (works with LDAP/SSSD)
getent passwd username
1
username:x:1001:1001::/home/username:/sbin/nologin

If the last field is /sbin/nologin, /bin/false, or another restricted shell → non-interactive

Test Command Execution (Safest)

Run a command as the user without starting a shell:

bash

Try to run a simple command

sudo -u username whoami

Try to list directories

sudo -u username ls -la /

Try to start a shell

sudo -u username bash -c "echo test"

Complete List of Non-Interactive Shells in Linux

Built-in System Shells

Shell Path Behavior Use Case
/sbin/nologin /sbin/nologin Shows “This account is currently not available” Most common - Service accounts
/bin/false /bin/false Exits with code 1, no output Minimal accounts, automated scripts
/bin/true /bin/true Exits with code 0, no output Placeholder accounts
/dev/null Not a shell Redirects everything to void Ultimate restriction

Application-Specific Restricted Shells

Shell Path Allowed Actions Install Command
git-shell /usr/bin/git-shell Git push/pull/fetch only sudo apt install git
scponly /usr/bin/scponly SCP/SFTP only sudo apt install scponly
rssh /usr/bin/rssh SFTP/SCP/rsync/cvs/svn sudo apt install rssh
jailkit /usr/sbin/jk_lsh Configurable allowlist sudo apt install jailkit
rbash (Restricted Bash) /bin/rbash Limited commands (configurable) Built-in (part of bash)

Special Purpose Shells

Shell Path Purpose
/usr/bin/passwd /usr/bin/passwd Password change only
/usr/sbin/chpasswd /usr/sbin/chpasswd Batch password updates
/bin/sync /bin/sync Force filesystem sync only
/sbin/halt /sbin/halt Shutdown only (rare)
/sbin/reboot /sbin/reboot Reboot only (rare)

Custom / Third-Party Shells

Tool Description Install Method
lshell Limited shell with path restrictions pip install lshell
rbash (Restricted Bash) Bash with restrictions Built-in
zsh restricted mode Restricted Zsh sudo apt install zsh
fish restricted Restricted Fish shell sudo apt install fish
chsh restricted Custom compiled shells Advanced

Complete Comparison Table

Shell Interactive? Can run commands? Shows message? Exit code Security Level
/bin/bash ✅ Yes ✅ Yes N/A 0 None
/sbin/nologin ❌ No ❌ No ✅ Yes 1 High
/bin/false ❌ No ❌ No ❌ No 1 High
/bin/true ❌ No ❌ No ❌ No 0 High
/usr/bin/git-shell ❌ No ⚠️ Git only ✅ Yes Varies Medium
/usr/bin/scponly ❌ No ⚠️ SCP/SFTP only ✅ Yes Varies Medium
/usr/sbin/jk_lsh ❌ No ⚠️ Allowlist only ✅ Yes Varies High
/bin/rbash ⚠️ Restricted ⚠️ Limited ✅ Yes Varies Medium
/usr/bin/rssh ❌ No ⚠️ Limited protocols ✅ Yes Varies Medium

This post is licensed under CC BY 4.0 by the author.

Trending Tags