Automated Root Password Rotation for 3000+ Heterogeneous UNIX/Linux Servers: A Modern Approach


2 views

Managing root passwords across a large, heterogeneous server environment presents several unique challenges:

  • Different password prompt formats across Solaris, AIX, and Linux variants
  • Varying password complexity requirements between systems
  • Mixed environments with legacy and modern systems
  • Audit and compliance requirements for password rotation

The legacy Expect-based approach has several pain points:

# Sample of problematic Expect code
expect {
    "New password:" { send "$newpass\r" }
    "Enter new password:" { send "$newpass\r" }
    "Changing password for root" { send "$newpass\r" }
    timeout { exit 1 }
}

This brittle pattern matching becomes unsustainable with:

  • OS version upgrades changing prompt formats
  • New security requirements like 2FA integration
  • Expansion to additional platforms

We recommend a layered approach:

1. Configuration Management Integration

For systems already managed by tools like Ansible, Salt, or Puppet:

# Ansible playbook example
- name: Rotate root passwords
  hosts: all_servers
  vars:
    new_root_password: "{{ vault_root_password }}"
  tasks:
    - name: Change root password
      user:
        name: root
        password: "{{ new_root_password | password_hash('sha512') }}"

2. API-Driven Solution for Heterogeneous Environments

For mixed environments, consider a purpose-built microservice:

// Node.js password rotation service example
const { exec } = require('child_process');
const servers = require('./inventory.json');

async function rotatePassword(server) {
  try {
    const cmd = ssh ${server} 'echo "root:${newPassword}" | chpasswd';
    await exec(cmd);
    logSuccess(server);
  } catch (err) {
    handleError(server, err);
  }
}

3. SSH Certificate Authority

Implementing SSH certificates eliminates password dependencies:

# Creating host certificates
ssh-keygen -s ca_key -I host_id -h -n server1.example.com server1.pub

# Client configuration
Host *.example.com
    CertificateFile ~/.ssh/id_rsa-cert.pub
  • Gradual rollout with canary testing
  • Automated verification of password changes
  • Integration with existing secret management (Vault, CyberArk)
  • Comprehensive logging for audit trails
# Example password generation
openssl rand -base64 32 | tr -dc 'a-zA-Z0-9!@#$%^&*()' | head -c 16

Additional recommendations:

  • Never store passwords in scripts or playbooks
  • Implement automatic password rotation scheduling
  • Enforce strict access controls for password change operations

Managing root passwords across a large heterogeneous environment (Solaris, AIX, Linux) presents several technical challenges:

  • Different passwd command behaviors across OS versions
  • SSH trust model limitations
  • Error handling at scale
  • Password policy enforcement

Instead of maintaining a monolithic Expect script, consider these architectural approaches:


# Example using Ansible (partial implementation)
- name: Rotate root password
  hosts: all_servers
  vars:
    new_password: "{{ vaulted_password }}"
  tasks:
    - name: Set root password (Linux)
      ansible.builtin.user:
        name: root
        password: "{{ new_password | password_hash('sha512') }}"
      when: ansible_os_family == 'RedHat' or ansible_os_family == 'Debian'

    - name: Set root password (AIX)
      ansible.builtin.command: /usr/bin/echo "root:{{ new_password }}" | /usr/bin/chpasswd
      when: ansible_os_family == 'AIX'

Credential Management: Use a vault system (Hashicorp Vault, Ansible Vault) to store and rotate credentials securely.

Idempotent Operations: Ensure your solution can handle partial failures and retries:


# Python example for multi-OS support
def set_root_password(host, new_password):
    try:
        if is_linux(host):
            # Linux implementation
            hash = generate_sha512_hash(new_password)
            execute_ssh_command(f"usermod -p '{hash}' root")
        elif is_aix(host):
            # AIX implementation
            execute_ssh_command(f"echo 'root:{new_password}' | chpasswd")
        # Additional OS handlers...
    except Exception as e:
        log_error(f"Failed on {host}: {str(e)}")
        return False
    return True

Implement a robust verification system:


# Verification script example
def verify_password_change(host):
    test_creds = get_temp_credentials()
    try:
        ssh = connect_with_password(host, 'root', test_creds)
        return ssh.execute('whoami') == 'root'
    except AuthenticationException:
        return False
    finally:
        rotate_temp_credentials(test_creds)

For compliance, ensure you:

  • Log all change attempts with timestamps
  • Maintain historical records of password changes
  • Implement four-eyes principle for sensitive operations

Consider these enterprise patterns:

  1. PAM Integration: Centralize authentication via LDAP/FreeIPA
  2. Ephemeral Credentials: Implement SSH certificate authority
  3. Break-glass Systems: Maintain emergency access procedures