lshell - Limited Shell
Project description
lshell
lshell is a Python-based restricted shell that limits users to a defined set of commands, enforces path and SSH transfer controls (scp, sftp, rsync, ...), logs user activity, supports session/time restrictions, and more.
PyPI project page: https://pypi.org/project/limited-shell/
Installation
Install from PyPI:
pip install limited-shell
Build/install from source:
python3 -m pip install build --user
python3 -m build
pip install . --break-system-packages
Uninstall:
pip uninstall limited-shell
Quick start
Run lshell with an explicit config:
lshell --config /path/to/lshell.conf
Default config location:
- Linux:
/etc/lshell.conf - *BSD:
/usr/{pkg,local}/etc/lshell.conf
Set lshell as login shell:
chsh -s /usr/bin/lshell user_name
Policy diagnostics
Explain the effective policy and decision for a command:
lshell policy-show \
--config /path/to/lshell.conf \
--user deploy \
--group ops \
--group release \
--command "sudo systemctl restart nginx"
Inside an interactive session:
policy-show [<command...>]policy-path(lpathalias)policy-sudo(lsudoalias)
Hide these built-ins if needed:
policy_commands : 0
Configuration
Primary template: etc/lshell.conf
Key settings to review:
allowed/forbiddenpathsudo_commandsoverssh,scp,sftp,scp_upload,scp_downloadallowed_shell_escapeallowed_file_extensionsmessageswarning_counter,strictumask
CLI overrides are supported, for example:
lshell --config /path/to/lshell.conf --log /var/log/lshell --umask 0077
Best practices
- Prefer an explicit
allowedallow-list instead of'all'. - Keep
allowed_shell_escapeshort and audit every entry. Never add tools that execute arbitrary commands (for examplefind,vim,xargs). - Use
allowed_file_extensionswhen users are expected to work with a known set of file types. - Keep
warning_counterenabled (avoid-1unless you intentionally want warning-only behavior). - Use
policy-showduring reviews to validate effective policy before assigning it to users.
Section model and precedence
Supported section types:
[global]for global lshell settings[default]for all users[username]for a specific user[grp:groupname]for a UNIX group
Precedence order:
- User section
- Group section
- Default section
Example configuration
For users foo and bar in UNIX group users:
# CONFIGURATION START
[global]
logpath : /var/log/lshell/
loglevel : 2
[default]
allowed : ['ls','pwd']
forbidden : [';', '&', '|']
warning_counter : 2
timer : 0
path : ['/etc', '/usr']
env_path : '/sbin:/usr/foo'
scp : 1
sftp : 1
overssh : ['rsync','ls']
aliases : {'ls':'ls --color=auto','ll':'ls -l'}
[grp:users]
warning_counter : 5
overssh : - ['ls']
[foo]
allowed : 'all' - ['su']
path : ['/var', '/usr'] - ['/usr/local']
home_path : '/home/users'
[bar]
allowed : + ['ping'] - ['ls']
path : - ['/usr/local']
strict : 1
scpforce : '/home/bar/uploads/'
# CONFIGURATION END
For full option details, use:
man lshellman ./man/lshell.1
Testing
Run test services directly:
docker compose up ubuntu_tests debian_tests fedora_tests
Run full validation:
just test-all
Run only SSH end-to-end checks:
just test-ssh-e2e
Justfile usage
List commands:
just --list
Run distro-specific tests:
just test-debian
just test-ubuntu
just test-fedora
Run sample configs interactively:
just sample-list
just sample-ubuntu 01_baseline_allowlist.conf
Fuzzing parser/policy checks
Run Atheris fuzzing in Debian Docker (dependencies installed in-container):
just test-fuzz-security-parser 20000
Optional local run (if you want to fuzz outside Docker):
pip install -r requirements-fuzz.txt
python3 fuzz/fuzz_parser_policy.py -runs=20000
Contributing
Open an issue or pull request: https://github.com/ghantoos/lshell/issues
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file limited_shell-0.11.1rc1.tar.gz.
File metadata
- Download URL: limited_shell-0.11.1rc1.tar.gz
- Upload date:
- Size: 122.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32c65df8b7f13746f1192250f04e6cb4e8afb54c08e39816522169a2aab6003b
|
|
| MD5 |
4109d9db373fa00b96293733d444804a
|
|
| BLAKE2b-256 |
03a31faf0ccd47c518b9abd99751fbc8364f554d512f69085a1eeea13e3e214f
|
Provenance
The following attestation bundles were made for limited_shell-0.11.1rc1.tar.gz:
Publisher:
pypi-publish.yml on ghantoos/lshell
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
limited_shell-0.11.1rc1.tar.gz -
Subject digest:
32c65df8b7f13746f1192250f04e6cb4e8afb54c08e39816522169a2aab6003b - Sigstore transparency entry: 1093972509
- Sigstore integration time:
-
Permalink:
ghantoos/lshell@eb7d5345e6891f49d8a09fc5d44ffc08cbf2bd2a -
Branch / Tag:
refs/tags/0.11.1rc1 - Owner: https://github.com/ghantoos
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@eb7d5345e6891f49d8a09fc5d44ffc08cbf2bd2a -
Trigger Event:
push
-
Statement type:
File details
Details for the file limited_shell-0.11.1rc1-py3-none-any.whl.
File metadata
- Download URL: limited_shell-0.11.1rc1-py3-none-any.whl
- Upload date:
- Size: 95.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59682a63ac6602b635b51289ed7a24163cea048e39ead29f72dc081d8bcea381
|
|
| MD5 |
1827db2e4439fcc284422e8f6479318d
|
|
| BLAKE2b-256 |
5b6bb80f9c2dbac3f13d0e825bdc019c68fc6d705176a33c616bc9b37ca82b89
|
Provenance
The following attestation bundles were made for limited_shell-0.11.1rc1-py3-none-any.whl:
Publisher:
pypi-publish.yml on ghantoos/lshell
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
limited_shell-0.11.1rc1-py3-none-any.whl -
Subject digest:
59682a63ac6602b635b51289ed7a24163cea048e39ead29f72dc081d8bcea381 - Sigstore transparency entry: 1093972517
- Sigstore integration time:
-
Permalink:
ghantoos/lshell@eb7d5345e6891f49d8a09fc5d44ffc08cbf2bd2a -
Branch / Tag:
refs/tags/0.11.1rc1 - Owner: https://github.com/ghantoos
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@eb7d5345e6891f49d8a09fc5d44ffc08cbf2bd2a -
Trigger Event:
push
-
Statement type: