I usually use something like this:
openssl rand -base64 20
or if openssl is not available:
head -c 20 /dev/random | base64
It encodes 20 random bytes in base64. Due to how base64 works, using 20 bytes ensures there is always an equals sign at the end. So the password contains uppercase, lowercase, numbers and special characters. Although it's not bulletproof - it could theoretically (I think) generate base64 strings without numbers or only lowercase letters etc.