Skip to main content

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

  1. Understand what lsattr shows vs. traditional permissions.
  2. Core syntax and all practical flags.
  3. How to read the attribute string (---i-----e---) column by column.
  4. WordPress/VPS use cases (auditing immutable/append-only).
  5. Safe workflows to verify attributes recursively.
  6. Troubleshooting gotchas (non-ext FS, inside containers, symlinks).
  7. Quick Lab, Cheat Sheet, and Mini-Quiz.

5W + 1H Framework

QuestionAnswer
Whatlsattr lists extended file attributes of files/dirs (e.g., immutable i, append-only a, no-atime A).
WhyTo audit hardening states (e.g., +i on wp-config.php) and explain “can’t edit/delete” behavior that normal permissions don’t cover.
WhereOn Linux systems, mainly effective on ext2/3/4 filesystems (attributes are filesystem-specific).
WhenAfter applying/removing attributes via chattr, during security reviews, or when operations fail unexpectedly.
WhoSysadmins managing WordPress servers, DevOps, security engineers.
HowRun 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 by lsattr) **modify kernel behavior for files/dirs (e.g., immutable, append-only).
  • Attributes can **block writes/renames/deletes even if chmod/chown would allow them.

Command & Options

Core Syntax

lsattr [options] [file... | dir...]

Common Options (Practical)

OptionDescriptionWhen to Use
-RRecurse into subdirectories.Whole-site audits (/var/www/...).
-aInclude entries starting with .To see .htaccess, hidden files.
-dList directory entries themselves (not their contents).To check a directory’s own attributes (e.g., wp-content/uploads).
-vShow file version/generation (if supported).Rarely used; forensic audits.
--helpDisplay help.Quick reference.
--versionShow 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:

FlagMeaningEffect
iImmutableCannot modify, delete, rename, or link. Blocks writes regardless of chmod.
aAppend-onlyOnly appends allowed; no truncate/overwrite. Useful for logs.
ANo atime updatesAccess times not updated (reduces writes).
dNo dumpExcluded from dump backups (legacy tool).
DSynchronous dir updatesDirectory updates are written synchronously.
eExtents formatInformational: file uses extents (normal on ext4).
jData journalingFile data is journaled (rare; performance cost).
sSecure deletionAttempt to zero blocks on delete (not guaranteed on modern storage).
SSynchronous updatesWrites are synchronous (slower; durability).
tNo tail-mergingDisables tail packing (legacy optimization).
TTop of dir hierarchyDirectory hint for Orlov allocator.
uUndeletable (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

  1. **Audit hardening: Confirm i on critical files:
  • wp-config.php, .user.ini, .htaccess/ols.conf equivalents.
  1. **Uploads safety: Ensure **no i/a on wp-content/uploads/ (uploads must be writable).
  2. **Log integrity: Set a on custom logs (append-only) and verify with lsattr.
  3. **Post-deployment checks: After enabling/disabling immutable on themes/plugins during deploys, verify recursively.
  4. **Malware response: Temporarily set i on sensitive files while investigating; use lsattr to verify state.

Implementation Steps (Auditing a WP Install)

  1. Check site root quickly

    cd /var/www/example.com/public_html
    lsattr -a -d .

  2. Check critical files

    lsattr wp-config.php .user.ini .htaccess 2>/dev/null

  3. Verify directories themselves

    lsattr -d wp-content wp-content/uploads wp-content/plugins wp-content/themes

  4. Recursive sweep (report only)

    lsattr -R -a .

  5. Targeted filters (immutable only)

    lsattr -R . | awk '/^-*i-*/ {print'

  6. 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

  1. **Use attributes sparingly: +i is powerfulgreat for finished configs, risky for dynamic paths.
  2. **Never +i on writable WP paths: wp-content/uploads, cache dirs, and any path needing writes.
  3. **Document changes: Save lsattr -R reports before/after deployments.
  4. **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 with lsattr.
  5. **Know your FS: On non-ext filesystems, lsattr may be incomplete or not applicable.

Static vs. Dynamic Framing

  • **Static (hardened/rarely changed): wp-config.php, .user.ini potentially +i (verify via lsattr).
  • **Dynamic (frequently written): uploads/, caches, logs no +i/+a, except controlled append-only logs.

Go-Live Checklist (Verification with lsattr)

  1. wp-config.php immutable? lsattr wp-config.php shows i.
  2. .user.ini immutable? Shows i.
  3. uploads/ dir **not immutable? No i on directory itself.
  4. Plugins/themes folders not immutable during normal ops.
  5. No unexpected a attributes on app data files.
  6. Save an audit file: lsattr -R -a . > /root/reports/lsattr-$(date +%F).txt.

Troubleshooting Matrix

SymptomLikely CauseCheck with lsattrFix
“Permission denied” on edit/delete despite chmod okFile is immutablelsattr file shows isudo chattr -i file then re-test; re-apply if needed.
Logs not truncating/rotatingAppend-onlyShows asudo chattr -a /var/log/… then rotate.
Deploy pipeline cannot replace theme fileTarget has iShows iTemporarily chattr -i, deploy, then chattr +i if policy requires.
lsattr shows nothing unusual but still errorsNon-ext FSAttributes may not applyVerify filesystem type (df -T), adjust expectations/tools.
Directory behaves oddly on writesS/D flagsShows S/DRemove if unnecessary: chattr -S / -D (where supported).

Quick Lab

  1. In a WP docroot:

    cd /var/www/example.com/public_html
    sudo touch test.txt
    sudo chattr +i test.txt
    lsattr test.txt
    echo "hello" | sudo tee -a test.txt
    sudo rm test.txt

Expected:

  • lsattr shows i.
  • Append and delete fail with Operation not permitted (even as root without i removed).
  1. Cleanup:

    sudo chattr -i test.txt
    sudo 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

  1. Does lsattr change attributes?

**Answer: No. It only lists. Use chattr to change.

  1. If chmod 644 wp-config.php still wont let you edit, what lsattr flag would explain it?

**Answer: i (immutable).

  1. Should wp-content/uploads ever show i?

**Answer: Nouploads must remain writable.

  1. Which option shows a directorys own attributes rather than its contents?

**Answer: -d.

  1. Which option would you add to include .htaccess in listings?

**Answer: -a.

Notes & Constraints

  • lsattr is 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 lsattr audits with standard checks: ls -l, namei -om path, and your deployment policy.