Understanding and Implementing Password Rotation on Unix-like Systems

You dig through the logs. You open the manpages. Somewhere in the fine print of passwd(1) and pam_pwquality(8) lies the truth. Password rotation policies, buried in configuration files, waiting for the right directive to enforce them.

Manpages are the primary source for understanding password rotation on Unix-like systems. They are terse. They assume you know where to look. Start with chage(1). This tool allows you to set password aging parameters such as -M (maximum days), -m (minimum days), and -W (warning days). Rotate passwords by setting a maximum age so users are forced to change credentials after a set period.

For deeper control, check login.defs(5). This file defines system-wide settings like PASS_MAX_DAYS and PASS_MIN_DAYS. These values apply to new accounts unless overridden. The manpages explain the defaults, but security needs demand deliberate configuration.

PAM modules add another layer. pam_unix(8) respects rotation settings; pam_pwquality(8) enforces complexity. Read pam.conf(5) or pam.d(5) for the order and conditions of these modules. Without correct stacking, a rotation policy is just words on a page.

Audit your /etc/shadow entries. Each account has a last-change date in the second field. The system calculates expiry based on this and the maximum days allowed. man 5 shadow will tell you exactly how it works. Discovering discrepancies here is critical when rotation policies fail silently.

Test your changes. Force an expiry with chage -E or passwd -e and watch the system prompt at next login. Document your manpage sources alongside the commands. Policies only enforce if both configuration and execution align.

The manpages are blunt, but they are complete. Follow them line by line and the system obeys. Skip a step and you leave an opening. Strong password rotation depends on connecting all directives from chage to login.defs to PAM.

Need to implement and verify live password rotation policies without getting lost in syntax? Go to hoop.dev, configure, and see it work in minutes.