When configuring Linux systems, password policies vary depending on the authentication backend being used. The fundamental constraints come from:
- The system's PAM (Pluggable Authentication Modules) configuration
- The specific hashing algorithm in use (SHA-512, bcrypt, etc.)
- Any additional restrictions in /etc/security/pwquality.conf
For traditional /etc/passwd and /etc/shadow files, Linux typically accepts:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
!\"#$%&'()*+,-./:;<=>?@[\\]^_{|}~
Example password that would work on most systems:
P@$$w0rd_With-Spec!al-Ch@rs
Some characters may need escaping in shell environments:
# These need special handling:
! $ & * ( ) [ ] { } | ; ' " < > ? ~
For system-generated passwords, consider this Python example:
import random
import string
def generate_linux_password(length=16):
chars = string.ascii_letters + string.digits + "!@#$%^&*()_-+=[]{}|;:,.<>?~"
return ''.join(random.SystemRandom().choice(chars) for _ in range(length))
print(generate_linux_password())
On modern systems using pam_pwquality, check the configuration:
# View current settings:
grep ^min /etc/security/pwquality.conf
# Common parameters:
minlen = 8
minclass = 4
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
Use chpasswd to test password validity:
echo "testuser:NewP@ssw0rd$" | sudo chpasswd
For debugging PAM authentication:
# Add to /etc/pam.d/common-password
password required pam_pwquality.so debug
For OpenLDAP or Active Directory integration, additional restrictions may apply:
- OpenLDAP typically inherits system PAM policies
- AD integration may impose additional character set limitations
- Some special characters may need URL encoding
Example of an AD-compatible password generator:
# PowerShell snippet for AD-compatible passwords
function Get-AdPassword {
param([int]$Length=12)
$chars = [char[]]"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?"
$rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
$bytes = New-Object byte[]($Length)
$rng.GetBytes($bytes)
$result = ""
foreach ($byte in $bytes) {
$result += $chars[$byte % $chars.Length]
}
return $result
}
When configuring authentication on Linux systems, the allowable password characters primarily depend on two factors:
- The PAM (Pluggable Authentication Modules) configuration
- The specific authentication backend being used (passwd/shadow, LDAP, etc.)
For traditional /etc/passwd
and /etc/shadow
authentication, most Linux systems accept the following character set:
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 !@#$%^&*()-_=+[]{}|;:'",.<>/?~
The actual limitations come from several sources:
- PAM cracklib: Often enforces complexity rules but doesn't restrict character types
- System crypt(): The hashing function must support the characters
- Terminal/shell escaping: Special characters may need escaping when entered
You can test character support with this simple bash script:
#!/bin/bash for char in \! \\ \" \# \$ % \& \' $$ \* \+ \, \- \. \/ \: \; \< \= \> \? \@ $$\\$$ \^ \_ \ \{ \| \} \~ do echo "Testing character: $char" if sudo passwd --stdin testuser <<< "password$char" &>/dev/null; then echo "$char - ALLOWED" else echo "$char - REJECTED" fi done
Different authentication backends may impose additional restrictions:
Backend | Special Character Notes |
---|---|
LDAP | May reject characters that need URL encoding |
Active Directory | Often has stricter rules than standard Linux |
PAM limits | Can be modified in /etc/security/pwquality.conf |
When creating password policies that involve special characters:
- Test your exact authentication stack
- Document allowed characters for your organization
- Consider UI implications (web interfaces may have different rules)
- Account for international keyboards if relevant
To customize character restrictions in RHEL/CentOS:
# Edit /etc/security/pwquality.conf minlen = 14 minclass = 4 maxrepeat = 3 dictcheck = 1 usercheck = 1 enforcing = 1 # No direct character restrictions here, but controls complexity