LinuxIII · Filesystems and FilesAttributes
Extended attributes, immutable attributes, and capabilities
What you'll learn
- Read and set extended attributes with getfattr and setfattr
- Use chattr flags like immutable and append-only to lock down files
- Recognise when file capabilities replace setuid
- Apply xattrs and chattr safely in production
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09
Beyond standard permissions and ACLs, Linux supports two more metadata layers: extended attributes (xattrs) and filesystem attributes (chattr flags). Together with file capabilities, they let you lock down files in ways that survive chmod.
Extended attributes (xattrs)
xattrs are arbitrary name:value pairs attached to a file. The
namespace determines who can set them:
| Namespace | Prefix | Who can read | Who can set |
|---|---|---|---|
| User | user. | The owner | The owner |
| Trusted | trusted. | Root only | Root only |
| System | system. | Root only | The kernel |
| Security | security. | The owner and root | Root only |
$ getfattr -d -m ".*" /etc/passwd# file: etc/passwd
Illustrative output
$ setfattr -n user.origin -v production-import /etc/passwd; getfattr -n user.origin /etc/passwd# file: etc/passwd
user.origin=production-importIllustrative output
Common xattrs in production:
| xattr | Purpose |
|---|---|
security.selinux | SELinux context (when SELinux is enabled) |
security.capability | File capabilities (covered later) |
user.origin | Often used by configuration management to mark managed files |
trusted.* | Used by some security tools (e.g., AIDE) for integrity hashes |
system.posix_acl_access | POSIX ACL (handled via getfacl/setfacl, not directly) |
Filesystem attributes (chattr)
chattr sets flags that live at the filesystem level and are
enforced by the kernel. Two flags matter most in production:
| Flag | Effect |
|---|---|
+i (immutable) | The file cannot be modified, deleted, renamed, or have its metadata changed (even by root). |
+a (append-only) | The file can only be opened for appending; existing content cannot be modified. |
+u (undeletable) | When deleted, contents are saved for later undelete (rarely used; depends on filesystem). |
+c (compressed) | Mark for transparent compression on filesystems that support it. |
+s (secure deletion) | Blocks are zeroed on delete. |
$ chattr +i /etc/passwd; lsattr /etc/passwd----i---------e------- /etc/passwdIllustrative output
File capabilities
Capabilities are the kernel’s replacement for setuid. A binary with
CAP_NET_BIND_SERVICE can bind to port 80 without being root. A
binary with CAP_DAC_OVERRIDE can read any file.
There are two ways to grant capabilities:
- Process capabilities — granted to a running process.
- File capabilities — attached to a binary; the process receives them when it execs the binary.
The file capabilities are stored in security.capability xattr:
$ getcap /usr/bin/ping /usr/sbin/mount.nfs/usr/bin/ping = cap_net_raw+ep
/usr/sbin/mount.nfs = cap_dac_override,cap_sys_admin+epIllustrative output
$ setcap cap_net_bind_service+ep /opt/myapp/bin/web; getcap /opt/myapp/bin/web/opt/myapp/bin/web = cap_net_bind_service+epIllustrative output
| Flag | Meaning |
|---|---|
+ep | Effective and Permitted — both the active capability and the inheritable set |
+p | Permitted only — the capability is added to the permitted set but not raised into effective automatically |
+ei | Effective and Inheritable — the capability propagates to child processes |
Putting it together
For a hardened production binary:
# Application needs to bind to port 443 without being root
chown appuser:appgroup /opt/myapp/bin/web
chmod 0750 /opt/myapp/bin/web
setcap cap_net_bind_service+ep /opt/myapp/bin/web
The application runs as appuser, has only its group able to read
or execute it, and can bind to port 443 because it holds the
relevant capability. No setuid, no full root, no broader attack
surface.
For a config file that should not change:
chattr +i /etc/ssh/sshd_config
chattr +i /etc/sudoers
chattr +i /etc/pam.d/su
Any modification attempt, including by root, fails. The file is
locked until chattr -i removes the flag.
Knowledge check
Knowledge check · 3 questions
Q1. Which command makes a file impossible to modify, even by root, until the flag is explicitly removed?
Q2. File capabilities can replace setuid for many use cases.
Q3. Which of the following are common production uses of extended attributes or chattr flags? Select all that apply.
Passing score: 75%. Answers are checked in this browser.