thelinuxvault guide

Advanced Tips for Hardening User Accounts in Linux

User accounts are the gateway to a Linux system, making them a prime target for attackers. While basic hardening (e.g., strong passwords, disabling root SSH) is essential, advanced threats require sophisticated defenses. This blog dives into **advanced user account hardening techniques** to fortify your Linux environment against brute-force attacks, credential theft, privilege escalation, and insider threats. We’ll cover password policies, multi-factor authentication (MFA), privilege management, login security, monitoring, and more—with practical commands and configuration examples.

Table of Contents

  1. Enforce Granular Password Policies
  2. Implement Multi-Factor Authentication (MFA)
  3. Limit User Privileges with Precision
  4. Secure Login Mechanisms (SSH, TTY, and Beyond)
  5. Monitor and Audit User Activity
  6. Harden Service Accounts
  7. Adopt Emerging Practices: Passwordless Authentication & Centralized IDM
  8. Conclusion
  9. References

1. Enforce Granular Password Policies

Weak or reused passwords remain a top attack vector. Beyond basic “strong password” advice, advanced hardening requires enforcing strict, granular policies via system-wide configurations and PAM (Pluggable Authentication Modules).

1.1 Password Aging and Expiration

Prevent users from keeping the same password indefinitely with chage (change age) and /etc/login.defs.

  • Check current password aging:

    chage -l <username>  

    Output includes Last password change, Password expires, and Account expires.

  • Enforce global defaults in /etc/login.defs:

    PASS_MAX_DAYS   90   # Max days before password change  
    PASS_MIN_DAYS   10   # Min days before password can be changed  
    PASS_WARN_AGE   14   # Days to warn before expiration  
  • Set per-user policies (overrides global defaults):

    chage -M 60 -m 7 -W 10 <username>  # 60-day max, 7-day min, 10-day warning  

1.2 Prevent Password Reuse

Use pam_pwhistory to block reuse of recent passwords.

  • Install the PAM module (usually preinstalled on most distros):

    sudo apt install libpam-pwhistory  # Debian/Ubuntu  
    sudo dnf install pam-pwhistory     # RHEL/CentOS  
  • Configure in /etc/pam.d/common-password (Debian/Ubuntu) or /etc/pam.d/system-auth (RHEL):

    password    required    pam_pwhistory.so remember=5 use_authtok  # Block last 5 passwords  

1.3 Enforce Strong Password Hashing

Linux historically used MD5 for password hashing, but modern systems default to SHA-512. For advanced security, use Argon2 (winner of the Password Hashing Competition) or yescrypt (default in recent Debian/Ubuntu).

  • Verify current hashing algorithm:
    Check /etc/pam.d/common-password for pam_unix.so with sha512, yescrypt, or argon2:

    password    [success=1 default=ignore]  pam_unix.so yescrypt shadow try_first_pass use_authtok  
  • Enable Argon2 (if supported):
    Install libpam-argon2 and update PAM:

    sudo apt install libpam-argon2  

    Edit /etc/pam.d/common-password:

    password    required    pam_argon2.so rounds=3 memory=4096 time=3  # Adjust cost factors  

2. Implement Multi-Factor Authentication (MFA)

MFA adds a second layer of defense, ensuring even compromised passwords won’t grant access.

2.1 TOTP-Based MFA (e.g., Google Authenticator)

Use time-based one-time passwords (TOTP) with apps like Google Authenticator or Authy.

  • Install the PAM module:

    sudo apt install libpam-google-authenticator  # Debian/Ubuntu  
    sudo dnf install google-authenticator-libpam  # RHEL/CentOS  
  • Configure for a user:
    Run google-authenticator as the user; follow prompts to scan the QR code and save emergency codes.

  • Enforce MFA for SSH (edit /etc/pam.d/sshd):

    auth    required    pam_google_authenticator.so  
  • Update SSH config (/etc/ssh/sshd_config) to require both password and MFA:

    ChallengeResponseAuthentication yes  
    AuthenticationMethods publickey,password publickey,keyboard-interactive  # Combine with SSH keys  

2.2 Hardware Tokens (FIDO2/U2F)

For enterprise-grade security, use FIDO2/U2F devices (e.g., YubiKey) with pam_u2f.

  • Install pam_u2f:

    sudo apt install libpam-u2f  # Debian/Ubuntu  
  • Register a YubiKey for a user:

    mkdir -p ~/.config/Yubico  
    pamu2fcfg > ~/.config/Yubico/u2f_keys  # Follow on-device prompts  
  • Enforce in PAM (e.g., for sudo access, edit /etc/pam.d/sudo):

    auth    required    pam_u2f.so authfile=/home/<username>/.config/Yubico/u2f_keys  

3. Limit User Privileges with Precision

Overly permissive users are a major risk. Use the principle of least privilege to restrict access.

3.1 Secure the sudoers File

The sudoers file grants elevated privileges—misconfigurations here are catastrophic.

  • Always edit with visudo (prevents syntax errors):

    sudo visudo  
  • Restrict commands per user/group:
    Instead of ALL=(ALL:ALL) ALL, specify allowed commands:

    alice  ALL=(root) /usr/bin/apt update, /usr/bin/apt upgrade  # Only allow apt update/upgrade  
  • Disable passwordless sudo:
    Remove NOPASSWD: from sudoers entries unless absolutely necessary.

  • Use groups for role-based access:
    Create a sysadmins group and grant privileges to the group:

    %sysadmins  ALL=(root) /usr/bin/systemctl restart apache2  # Group-level access  

3.2 Disable su for Non-Administrators

Prevent users from switching to root with su by restricting access to the wheel group.

  • Edit /etc/pam.d/su:

    auth    required    pam_wheel.so use_uid  # Only wheel group can use su  
  • Add trusted users to wheel:

    sudo usermod -aG wheel <username>  

4. Secure Login Mechanisms (SSH, TTY, and Beyond)

Attackers often target login interfaces like SSH or physical TTYs. Harden these entry points.

4.1 Harden SSH Access

SSH is the primary remote access method—lock it down.

  • Disable root login:
    Edit /etc/ssh/sshd_config:

    PermitRootLogin no  
  • Use SSH keys instead of passwords:
    Generate keys for users:

    ssh-keygen -t ed25519 -C "[email protected]"  # Ed25519 is more secure than RSA  

    Copy public key to the server:

    ssh-copy-id [email protected]  

    Disable password auth in sshd_config:

    PasswordAuthentication no  
    ChallengeResponseAuthentication no  
  • Limit SSH users/groups:

    AllowUsers alice [email protected]/24  # Only alice, and bob from 192.168.1.0/24  
    AllowGroups ssh-users               # Only users in ssh-users group  
  • Change default SSH port:
    Reduce brute-force attempts by changing from port 22:

    Port 2222  # Update firewall rules to allow this port!  

4.2 Block Brute-Force Attacks with fail2ban

fail2ban bans IPs after repeated failed login attempts.

  • Install and enable fail2ban:

    sudo apt install fail2ban  
    sudo systemctl enable --now fail2ban  
  • Configure SSH protection (create /etc/fail2ban/jail.local):

    [sshd]  
    enabled = true  
    port = 2222  # Match your SSH port  
    filter = sshd  
    logpath = /var/log/auth.log  
    maxretry = 3  # Ban after 3 failed attempts  
    bantime = 3600  # Ban for 1 hour  

5. Monitor and Audit User Activity

Detect breaches early with robust monitoring and auditing.

5.1 Track Login Attempts

Use last (successful logins) and lastb (failed logins) to review activity:

last -i  # Show IP addresses  
lastb    # Show failed attempts (requires root)  

5.2 Audit with auditd

The auditd daemon logs system events (e.g., file modifications, user actions).

  • Install and start auditd:

    sudo apt install auditd  
    sudo systemctl enable --now auditd  
  • Add rules to monitor sensitive files:
    Track changes to /etc/passwd or /etc/sudoers:

    sudo auditctl -w /etc/passwd -p w -k passwd_changes  # Log writes to passwd  
    sudo auditctl -w /etc/sudoers -p rw -k sudoers_changes  # Log reads/writes to sudoers  
  • Search audit logs:

    sudo ausearch -k passwd_changes  # Search for passwd change events  

5.3 Centralize Logs

Aggregate logs from multiple systems with tools like ELK Stack (Elasticsearch, Logstash, Kibana) or Graylog for easier analysis.

6. Harden Service Accounts

Service accounts (e.g., www-data, postgres) are often overlooked but critical—compromising them can lead to data breaches.

6.1 Disable Shell Access

Service accounts don’t need interactive shells. Set their shell to /usr/sbin/nologin or /bin/false:

sudo usermod -s /usr/sbin/nologin www-data  

6.2 Secure Home Directories

Ensure service account home directories are owned by root and have strict permissions:

sudo chown root:root /home/serviceuser  
sudo chmod 700 /home/serviceuser  

6.3 Rotate Service Account Credentials

Use tools like ansible-vault or hashicorp vault to manage and rotate service account passwords/keys regularly.

7. Adopt Emerging Practices: Passwordless Authentication & Centralized IDM

7.1 Passwordless SSH with Ed25519 Keys

Replace passwords with SSH keys using the Ed25519 algorithm (more secure and faster than RSA):

ssh-keygen -t ed25519 -C "[email protected]"  # Generate key  
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server  # Deploy key  

7.2 Centralized Identity Management

Use FreeIPA or Active Directory (via SSSD) to enforce policies across fleets of Linux systems. These tools centralize password policies, MFA, and access control.

8. Conclusion

User account hardening is a continuous process, not a one-time task. By combining strict password policies, MFA, least-privilege access, robust monitoring, and emerging practices like passwordless authentication, you can significantly reduce your attack surface. Always test changes in a staging environment, and stay updated on new threats and tools.

9. References