Linux Namespaces and Shell Commands: Overview and Complete Guide
Linux Namespaces and Shell Commands: Overview and Complete Guide
Kernel Version
user, trusted, system, security
Storage Format
Attached Per File
Key Terms
By default, a Linux file stores fixed metadata — owner, permissions, timestamps, size. That is all you get from a standard stat() call. Extended Attributes (EAs) let you attach any extra metadata to a file without changing the file’s content.
Think of it like sticky notes you can attach to a file. Each note has a name and a value. For example:
user.description = "quarterly report"user.mime_type = "application/pdf"security.selinux = "system_u:object_r:etc_t:s0"
EAs are stored in the file’s i-node, not inside the file data itself. They were added to the Linux kernel in version 2.6.
EAs are attached to a file’s i-node, not to the file’s data blocks.
| File Data Blocks Actual content of the file (text, binary, etc.) |
⟶ | i-node permissions, owner, timestamps, size, data block pointers + Extended Attributes ✓ |
⟶ | EA Storage user.x = “hello” user.y = “world” security.label = “…” |
EA support must come from both the kernel configuration and the underlying file system.
| File System | EA Support | Notes |
|---|---|---|
| ext2 / ext3 / ext4 | ✓ Yes | Needs user_xattr mount option for user EAs |
| Btrfs | ✓ Yes | Modern CoW filesystem, full EA support |
| XFS | ✓ Yes | Good EA support built-in |
| JFS | ✓ Yes | Also supports extra os2 namespace |
| Reiserfs | ✓ Yes | Available since Linux 2.6.7 |
| FAT / NTFS | ✗ No | Not supported natively |
Every EA name has the format namespace.name. The namespace separates EAs into different categories with different access rules.
Extended Attribute Name Format: namespace . name |
|||
|
👤
user Example:
user.comment = "draft" |
🔒
trusted Example:
trusted.overlay = "..." |
⚙️
system Example:
system.posix_acl_access |
🛡️
security Example:
security.selinux = "..." |
The user namespace is the one you will use most in application programming.
- Any unprivileged process can read/write user EAs, subject to file permissions.
- To read a user EA — you need read permission on the file.
- To write/modify a user EA — you need write permission on the file.
- On ext2/ext3/ext4 and Reiserfs, the filesystem must be mounted with
user_xattr. - EA names in the user namespace can be any arbitrary string.
# Mount ext4 filesystem with user_xattr support
mount -o user_xattr /dev/sdb1 /mnt/data
# Or add to /etc/fstab permanently:
# /dev/sdb1 /mnt/data ext4 defaults,user_xattr 0 2
The trusted namespace works like user but requires elevated privileges.
- Process must have
CAP_SYS_ADMINcapability (i.e., run as root or have the cap). - Unprivileged processes cannot read or write trusted EAs.
- Used by system-level tools like overlayfs, backup daemons, and container runtimes.
/* Only root can do this */
#include <sys/xattr.h>
int main() {
const char *val = "backup-server-1";
/* This will fail with EPERM if not root */
if (setxattr("/var/data/file.db", "trusted.backup_origin",
val, strlen(val), 0) == -1) {
perror("setxattr trusted");
return 1;
}
return 0;
}
The system namespace is exclusively for the kernel. You cannot create arbitrary system EAs from userspace. The kernel uses this namespace to attach objects to files — currently Access Control Lists (ACLs).
- Only names the kernel explicitly permits are accepted.
- Example:
system.posix_acl_accessandsystem.posix_acl_default. - Managed indirectly through ACL commands like
setfacl/getfacl.
# View system (ACL) EAs indirectly
getfacl /var/www/html/index.html
# View the raw system EA name
getfattr -m system -d /var/www/html/index.html
The security namespace is used by kernel security modules (LSMs) such as SELinux and AppArmor.
- Stores security labels that control mandatory access control (MAC).
- Also stores file capabilities (what a binary is allowed to do when executed).
- Originally created for SELinux (http://www.nsa.gov/research/selinux/).
# View SELinux security context of a file
ls -Z /etc/passwd
# Output: system_u:object_r:passwd_file_t:s0 /etc/passwd
# View the raw security EA
getfattr -n security.selinux /etc/passwd
Linux provides two command-line utilities to work with EAs: setfattr(1) and getfattr(1). They are part of the attr package.
# Install on Debian/Ubuntu
sudo apt install attr
# Install on Fedora/RHEL
sudo dnf install attr
# Create a file to test
touch myfile.txt
# Set a user EA: -n = name, -v = value
setfattr -n user.author -v "Ravi Kumar" myfile.txt
# Set another EA
setfattr -n user.version -v "1.0" myfile.txt
# Set an EA with an empty string value (valid, not undefined)
setfattr -n user.notes myfile.txt
# Overwrite an existing EA value
setfattr -n user.version -v "2.0" myfile.txt
# Remove an EA: -x = remove
setfattr -x user.notes myfile.txt
setfattr -n user.notes myfile.txt without -v) creates an EA with an empty value. This is different from the EA not existing at all.# Read a specific EA by name
getfattr -n user.author myfile.txt
# Output:
# file: myfile.txt
# user.author="Ravi Kumar"
# Dump ALL user EAs (default: only user namespace shown)
getfattr -d myfile.txt
# Output:
# file: myfile.txt
# user.author="Ravi Kumar"
# user.version="2.0"
# List ALL EAs from ALL namespaces (use "-m -" pattern)
getfattr -m - -d myfile.txt
# List only security EAs
getfattr -m "^security\." -d myfile.txt
# List EAs matching a pattern (e.g. names starting with "user.v")
getfattr -m "^user\.v" -d myfile.txt
getfattr -d uses the pattern ^user\. which means it only shows user-namespace EAs. To see all namespaces, use -m - (a dash means match everything).This example walks through the full lifecycle of an extended attribute:
## STEP 1: Create a test file
$ touch testfile.txt
## STEP 2: Set two user EAs
$ setfattr -n user.quote1 -v "The past is not dead." testfile.txt
$ setfattr -n user.quote2 -v "In fact, it's not even past." testfile.txt
## STEP 3: Read one specific EA
$ getfattr -n user.quote1 testfile.txt
# file: testfile.txt
user.quote1="The past is not dead."
## STEP 4: Dump all user EAs
$ getfattr -d testfile.txt
# file: testfile.txt
user.quote1="The past is not dead."
user.quote2="In fact, it's not even past."
## STEP 5: Change quote1 to empty string
$ setfattr -n user.quote1 testfile.txt # no -v = empty value
## STEP 6: Dump again — note quote1 shows no value
$ getfattr -d testfile.txt
# file: testfile.txt
user.quote1 # empty string
user.quote2="In fact, it's not even past."
## STEP 7: Remove quote2 entirely
$ setfattr -x user.quote2 testfile.txt
## STEP 8: Dump again — only quote1 remains
$ getfattr -d testfile.txt
# file: testfile.txt
user.quote1 # empty string, still exists
user.quote1 with an empty string value is NOT the same as user.quote1 not existing. An empty string is still a valid EA value.| Use Case | Namespace | Example EA |
|---|---|---|
| File versioning | user |
user.version = "3.1.2" |
| MIME type tagging | user |
user.mime_type = "image/png" |
| Access Control Lists | system |
system.posix_acl_access |
| SELinux labels | security |
security.selinux = "..." |
| File capabilities | security |
security.capability = "..." |
| Backup metadata | trusted |
trusted.backup_date = "..." |
| Overlay filesystem | trusted |
trusted.overlay.opaque = "y" |
user_xattr mount option on ext4?getfattr -d output with no value shown. An EA that doesn’t exist returns ENODATA when you try to read it. They are two distinct states. This matters when using flags like XATTR_CREATE and XATTR_REPLACE in setxattr.security namespace, specifically security.selinux. This label controls what a process or file is allowed to do under SELinux’s mandatory access control policy. Without EA support on the file system, SELinux cannot enforce per-file labels.Continue Learning
Next: Dive into EA implementation limits and restrictions
