SELinux-aware tree command for security-focused directory visualization
Display hierarchical directory structures filtered by SELinux security contexts. A wary oak - combining security awareness with the classic tree command.
sultree extends the classic tree command with SELinux context filtering - visualize directory structures filtered by security contexts.
No installation required - run the standalone script directly:
Python 3.8+ - Core runtimeattr package - Provides getfattr for SELinux queriesVerify SELinux is available and test basic functionality:
sultree is configured entirely through command-line arguments - no configuration files required. Internal constants define operational limits.
These limits are defined in constants.py and
provide security boundaries:
| Option | Type | Default | Description |
|---|---|---|---|
MAX_DEPTH | integer | 1000 | Maximum traversal depth limit |
MAX_FILE_LIMIT | integer | 100000 | Maximum files per directory limit |
MAX_PATTERN_LENGTH | integer | 1000 | Maximum pattern string length |
MAX_SELINUX_PATTERN_LENGTH | integer | 500 | Maximum SELinux pattern length |
MAX_PATH_LENGTH | integer | 4096 | Maximum file path length |
SELINUX_QUERY_TIMEOUT | seconds | 5 | Timeout for SELinux context queries |
Control what files and directories are displayed:
| Option | Type | Default | Description |
|---|---|---|---|
-a, --all | flag | false | Show all files including hidden (starting with .) |
-d, --dirs-only | flag | false | List directories only, exclude regular files |
-l, --follow-links | flag | false | Follow symbolic links as directories |
-f, --full-path | flag | false | Print full path prefix for each file |
-x, --one-file-system | flag | false | Stay on current filesystem only |
-L level | integer | none | Descend only N directories deep |
Filter files by name patterns using shell-style wildcards:
| Option | Type | Default | Description |
|---|---|---|---|
-P, --pattern <pattern> | string | none | List only files matching pattern |
-I, --ignore <pattern> | string | none | Exclude files matching pattern |
--match-dirs | flag | false | Apply patterns to directory names |
--ignore-case | flag | false | Case-insensitive pattern matching |
--filelimit N | integer | none | Skip directories with more than N files |
Filter by SELinux security contexts:
| Option | Type | Default | Description |
|---|---|---|---|
-S, --selinux <pattern> | string | none | Filter by SELinux context pattern (repeatable) |
-S passwd_file_t - Match exact type-S "*_exec_t" - Match all executable types-S "system_u:*" - Match system_u user-S httpd_* - Match Apache-related contexts| Option | Type | Default | Description |
|---|---|---|---|
--no-report | flag | false | Omit file/directory count at end |
--version | flag | - | Show version information |
sultree is a SELinux-aware variant of the standard tree
command. It displays hierarchical directory structures while filtering entries based on
SELinux security contexts.
The name is a pun: "a wary oak" - combining security/SELinux awareness with the tree command concept. Written in Python with no third-party dependencies beyond the standard library.
sultree provides deep integration with SELinux, allowing you to visualize and filter directory contents by their security contexts.
SELinux contexts follow the format: user:role:type[:level]
system_u, unconfined_u)object_r, system_r)passwd_file_t, httpd_exec_t)s0) - optional
sultree queries SELinux contexts using the getfattr
utility from the attr package:
sultree supports two types of pattern filtering: file name patterns and SELinux context patterns.
Use -P to include or -I
to exclude files by name pattern:
* - Match zero or more characters? - Match single character[seq] - Match characters in sequence[!seq] - Match characters not in sequence
The -S flag filters by SELinux context.
Multiple patterns create OR logic:
sultree uses an iterator-based traversal engine that handles large directory trees efficiently:
-x)-L)--filelimit)sultree maintains compatibility with common tree options while adding SELinux-specific features:
-a Show all files-d Directories only-L Depth limit-f Full paths-l Follow symlinks-P/-I Pattern filtering-x One filesystem-S SELinux filtering--match-dirs Pattern on dirs--ignore-case Case insensitive--filelimit Skip large dirsColor output, JSON/XML output, file size/time/permissions display, inode display, owner/group display. Use standard tree for these features.
sultree is a pure Python application with a modular architecture designed for security and performance. No third-party dependencies are required.
src/sultree/ ├── __init__.py # Version and metadata ├── __main__.py # CLI entry point ├── cli.py # Main orchestration ├── args.py # SecureArgumentParser ├── arg_definitions.py # Data-driven arg definitions ├── validators.py # Input validation ├── constants.py # Configuration limits ├── traversal.py # SecureTraverser engine ├── selinux.py # SELinux filter module └── tree_renderer.py # Visual output rendering
Each module has a single responsibility following separation of concerns:
The traversal.py module (320+ lines) implements
the core directory traversal engine:
The selinux.py module (340+ lines) provides
SELinux context handling:
# Query mechanism getfattr --only-values -n security.selinux /path # Caching strategy @lru_cache(maxsize=1024) def get_context(path_hash: int) -> Optional[SELinuxContext]
The tree_renderer.py module (333 lines) handles
visual output:
Request processing follows a clear pipeline:
sultree implements multiple security layers throughout the codebase:
; & | ` $ ( ) < > \n
Complete command-line interface reference for sultree.
sultree [OPTIONS] [directories...]
DESCRIPTION
Display directory trees with SELinux context filtering.
The name is a pun: "a wary oak" - security-aware tree.
ARGUMENTS
directories One or more directories to display (default: .) | Option | Type | Default | Description |
|---|---|---|---|
-a, --all | flag | false | Show all files including hidden (starting with .) |
-d, --dirs-only | flag | false | List directories only, exclude regular files |
-l, --follow-links | flag | false | Follow symbolic links as directories |
-f, --full-path | flag | false | Print full path prefix for each file |
-x, --one-file-system | flag | false | Stay on current filesystem only |
-L level | integer | none | Descend only N directories deep |
| Option | Type | Default | Description |
|---|---|---|---|
-P, --pattern <pattern> | string | none | List only files matching pattern |
-I, --ignore <pattern> | string | none | Exclude files matching pattern |
--match-dirs | flag | false | Apply patterns to directory names |
--ignore-case | flag | false | Case-insensitive pattern matching |
--filelimit N | integer | none | Skip directories with more than N files |
| Option | Type | Default | Description |
|---|---|---|---|
-S, --selinux <pattern> | string | none | Filter by SELinux context pattern (repeatable) |
| Option | Type | Default | Description |
|---|---|---|---|
--no-report | flag | false | Omit file/directory count at end |
--version | flag | - | Show version information |
| Option | Type | Default | Description |
|---|---|---|---|
0 | code | - | Success - tree completed without errors |
1 | code | - | General error |
2 | code | - | Invalid arguments |
3 | code | - | Permission error |
4 | code | - | Partial success (some directories failed) |
130 | code | - | Interrupted (Ctrl+C) |
Common issues and their solutions when using sultree.
Problem: Warning about missing getfattr when using SELinux features.
Solution: Install the attr package:
Problem: Using -S flag on system without SELinux.
Solution: Enable SELinux or remove the -S flag:
Problem: Cannot access certain directories.
Behavior: sultree logs warning and continues with accessible files.
Solution: Run with appropriate privileges:
Problem: Circular symlinks causing infinite traversal.
Solution: Automatic - sultree detects loops via inode tracking.
If using -l (follow-links) with circular symlinks,
use -L to limit depth.
Problem: Traversal takes too long on massive directories.
Solution: Use limiting options:
Problem: SELinux context queries timing out.
Cause: 5-second timeout on getfattr subprocess (security measure).
Solution: Check system load, try without SELinux filtering:
Problem: Pattern contains invalid/dangerous characters.
Cause: Characters like ; & | ` $ are stripped for security.
Solution: Use clean patterns:
Problem: Files not shown despite matching pattern.
Debug: Check actual context of target file:
Common issues: patterns are case-sensitive by default, pattern matches any field (not just type),
wildcards require exact syntax (? for single char, * for multiple).
Run tests and smoke checks to verify installation:
sultree --help