LSATTR
LSATTR List File Attributes (Extended Attributes Module)
Use lsattr to **inspect extended file attributes (immutable, append-only, noatime, etc.) on Linux filesystemsprimarily ext2/ext3/ext4. This is essential when you harden WordPress (e.g., verifying +i on wp-config.php) or debug permission denied mysteries that arent explained by chmod/chown.
What You Will Learn
- Understand what
lsattrshows vs. traditional permissions. - Core syntax and all practical flags.
- How to read the attribute string (
---i-----e---) column by column. - WordPress/VPS use cases (auditing immutable/append-only).
- Safe workflows to verify attributes recursively.
- Troubleshooting gotchas (non-ext FS, inside containers, symlinks).
- Quick Lab, Cheat Sheet, and Mini-Quiz.
5W + 1H Framework
| Question | Answer |
|---|---|
| What | lsattr lists extended file attributes of files/dirs (e.g., immutable i, append-only a, no-atime A). |
| Why | To audit hardening states (e.g., +i on wp-config.php) and explain “can’t edit/delete” behavior that normal permissions don’t cover. |
| Where | On Linux systems, mainly effective on ext2/3/4 filesystems (attributes are filesystem-specific). |
| When | After applying/removing attributes via chattr, during security reviews, or when operations fail unexpectedly. |
| Who | Sysadmins managing WordPress servers, DevOps, security engineers. |
| How | Run lsattr [options] <path>; interpret the attribute flags per row. |
Prerequisites
- Ubuntu (22.04/24.04 or similar) with **ext4 for the target paths.
- Package **e2fsprogs installed (contains
lsattr/chattr). - Shell access with permissions to read the target directories.
Core Concepts: Permissions vs. Attributes
- **UNIX permissions (rwx) and **ownership (user/group) control standard access.
- **Extended attributes (managed by
chattr; listed bylsattr) **modify kernel behavior for files/dirs (e.g., immutable, append-only). - Attributes can **block writes/renames/deletes even if
chmod/chownwould allow them.
Command & Options
Core Syntax
lsattr [options] [file... | dir...]
Common Options (Practical)
| Option | Description | When to Use |
|---|---|---|
-R | Recurse into subdirectories. | Whole-site audits (/var/www/...). |
-a | Include entries starting with . | To see .htaccess, hidden files. |
-d | List directory entries themselves (not their contents). | To check a directory’s own attributes (e.g., wp-content/uploads). |
-v | Show file version/generation (if supported). | Rarely used; forensic audits. |
--help | Display help. | Quick reference. |
--version | Show version. | Environment documentation. |
Note: lsattr output may be undefined on non-ext filesystems (e.g., XFS, ZFS). Some flags wont appear or be meaningful.
Understanding the Attribute String
lsattr prints a **fixed-width flag column per file/dir. Example:
----i--------e----- ./wp-config.php
-----a-------e----- ./wp-content/uploads/
------------------- ./wp-content/plugins/
Common flags you will see on ext4:
| Flag | Meaning | Effect |
|---|---|---|
i | Immutable | Cannot modify, delete, rename, or link. Blocks writes regardless of chmod. |
a | Append-only | Only appends allowed; no truncate/overwrite. Useful for logs. |
A | No atime updates | Access times not updated (reduces writes). |
d | No dump | Excluded from dump backups (legacy tool). |
D | Synchronous dir updates | Directory updates are written synchronously. |
e | Extents format | Informational: file uses extents (normal on ext4). |
j | Data journaling | File data is journaled (rare; performance cost). |
s | Secure deletion | Attempt to zero blocks on delete (not guaranteed on modern storage). |
S | Synchronous updates | Writes are synchronous (slower; durability). |
t | No tail-merging | Disables tail packing (legacy optimization). |
T | Top of dir hierarchy | Directory hint for Orlov allocator. |
u | Undeletable (keep data for undeletion) | Historically allowed recovery; not reliably supported now. |
You may see other letters on different filesystems; treat them as informational unless you explicitly rely on them.
WordPress/VPS Use Cases
- **Audit hardening: Confirm
ion critical files:
wp-config.php,.user.ini,.htaccess/ols.confequivalents.
- **Uploads safety: Ensure **no
i/aonwp-content/uploads/(uploads must be writable). - **Log integrity: Set
aon custom logs (append-only) and verify withlsattr. - **Post-deployment checks: After enabling/disabling immutable on themes/plugins during deploys, verify recursively.
- **Malware response: Temporarily set
ion sensitive files while investigating; uselsattrto verify state.
Implementation Steps (Auditing a WP Install)
-
Check site root quickly
cd /var/www/example.com/public_htmllsattr -a -d . -
Check critical files
lsattr wp-config.php .user.ini .htaccess 2>/dev/null -
Verify directories themselves
lsattr -d wp-content wp-content/uploads wp-content/plugins wp-content/themes -
Recursive sweep (report only)
lsattr -R -a . -
Targeted filters (immutable only)
lsattr -R . | awk '/^-*i-*/ {print' -
Export report
lsattr -R -a . > /root/reports/lsattr-$(date +%F).txt
Examples with Expected Output
These outputs are representative; your flags may differ.
Single Files
lsattr wp-config.php
Expected:
----i--------e----- wp-config.php
Interpretation: immutable + extents. Edits/deletes will fail until chattr -i.
lsattr .user.ini
Expected:
----i--------e----- .user.ini
Directories (self vs contents)
lsattr -d wp-content
Expected:
------------------- wp-content
lsattr -R wp-content/plugins | head
Expected (sample lines):
------------------- wp-content/plugins/
------------------- wp-content/plugins/perfmatters/
------------------- wp-content/plugins/perfmatters/readme.txt
------------------- wp-content/plugins/perfmatters/perfmatters.php
Find immutable anywhere
lsattr -R . | awk '/^-*i-*/'
Expected (if any):
----i--------e----- ./wp-config.php
Append-only logs
lsattr /var/log/wp-actions.log
Expected:
-----a-------e----- /var/log/wp-actions.log
Best Practices
- **Use attributes sparingly:
+iis powerfulgreat for finished configs, risky for dynamic paths. - **Never
+ion writable WP paths:wp-content/uploads, cache dirs, and any path needing writes. - **Document changes: Save
lsattr -Rreports before/after deployments. - **Pair with config management: If you use
+i, make sure your deployment pipeline can **temporarily remove it (chattr -i), update, re-apply, and then verify withlsattr. - **Know your FS: On non-ext filesystems,
lsattrmay be incomplete or not applicable.
Static vs. Dynamic Framing
- **Static (hardened/rarely changed):
wp-config.php,.user.inipotentially+i(verify vialsattr). - **Dynamic (frequently written):
uploads/, caches, logs no+i/+a, except controlled append-only logs.
Go-Live Checklist (Verification with lsattr)
wp-config.phpimmutable?lsattr wp-config.phpshowsi..user.iniimmutable? Showsi.uploads/dir **not immutable? Noion directory itself.- Plugins/themes folders not immutable during normal ops.
- No unexpected
aattributes on app data files. - Save an audit file:
lsattr -R -a . > /root/reports/lsattr-$(date +%F).txt.
Troubleshooting Matrix
| Symptom | Likely Cause | Check with lsattr | Fix |
|---|---|---|---|
“Permission denied” on edit/delete despite chmod ok | File is immutable | lsattr file shows i | sudo chattr -i file then re-test; re-apply if needed. |
| Logs not truncating/rotating | Append-only | Shows a | sudo chattr -a /var/log/… then rotate. |
| Deploy pipeline cannot replace theme file | Target has i | Shows i | Temporarily chattr -i, deploy, then chattr +i if policy requires. |
lsattr shows nothing unusual but still errors | Non-ext FS | Attributes may not apply | Verify filesystem type (df -T), adjust expectations/tools. |
| Directory behaves oddly on writes | S/D flags | Shows S/D | Remove if unnecessary: chattr -S / -D (where supported). |
Quick Lab
-
In a WP docroot:
cd /var/www/example.com/public_htmlsudo touch test.txtsudo chattr +i test.txtlsattr test.txtecho "hello" | sudo tee -a test.txtsudo rm test.txt
Expected:
lsattrshowsi.- Append and delete fail with Operation not permitted (even as root without
iremoved).
-
Cleanup:
sudo chattr -i test.txtsudo rm test.txt
Cheat Sheet
-
List attributes (incl. hidden):
lsattr -a . -
List directory itself (not contents):
lsattr -d path/ -
Recurse entire site:
lsattr -R /var/www/example.com/public_html -
Find immutable items:
lsattr -R . | awk '/^-*i-*/' -
Verify critical files:
lsattr wp-config.php .user.ini .htaccess
Mini-Quiz
- Does
lsattrchange attributes?
**Answer: No. It only lists. Use chattr to change.
- If
chmod 644 wp-config.phpstill wont let you edit, whatlsattrflag would explain it?
**Answer: i (immutable).
- Should
wp-content/uploadsever showi?
**Answer: Nouploads must remain writable.
- Which option shows a directorys own attributes rather than its contents?
**Answer: -d.
- Which option would you add to include
.htaccessin listings?
**Answer: -a.
Notes & Constraints
lsattris meaningful primarily on **ext filesystems. On others, output may be partial or irrelevant.- Some flags are informational and cannot be set/cleared on all kernels/FS types.
- Always pair
lsattraudits with standard checks:ls -l,namei -om path, and your deployment policy.