在Ubuntu运维工作中,经常需要批量生成强密码用于测试环境、临时账户或者自动化脚本验证,最直接高效的工具就是系统自带的mkpasswd命令。它属于expect包的一部分,支持生成指定长度、包含特殊字符的随机密码,也支持根据明文密码生成MD5或SHA加密哈希值。很多运维人员不知道这个工具已经预装在系统中,或者只会用最基础的用法,实际上mkpasswd的参数组合非常灵活,完全能覆盖日常测试场景中对密码生成的各种需求。

下面从安装、基本用法、高级参数、实际场景、安全注意事项几个维度,把mkpasswd这个工具彻底讲透。

mkpasswd的安装与确认

Ubuntu系统中mkpasswd并不是独立安装的,它包含在expect软件包里。如果你的系统提示找不到命令,先执行以下安装操作:

sudo apt update
sudo apt install expect -y

安装完成后,可以用以下命令确认版本和路径:

which mkpasswd
mkpasswd --version

正常情况下会返回类似"/usr/bin/mkpasswd"的路径,版本信息也会显示出来。如果你用的是Ubuntu Server最小化安装,expect包默认可能没装,这一步一定要先做,否则后面所有操作都跑不通。

mkpasswd的基本语法结构

mkpasswd的核心语法非常简单,基本格式如下:

mkpasswd [选项] [密码长度]

其中"密码长度"是可选参数,默认生成10位字符的密码。如果不指定长度,直接输入mkpasswd就会输出一个10位随机密码。这个默认行为在快速测试时很方便,但在需要精确控制密码复杂度的场景下,必须用参数来调整。

生成指定长度的随机强密码

最常用的场景就是生成指定长度的随机密码。比如需要一个16位的密码用于数据库测试账户:

mkpasswd 16

输出类似:aB3$kL9!mN2@pQ7#

如果需要更长的密码,比如32位:

mkpasswd 32

这里要注意,mkpasswd生成的随机密码默认包含大小写字母、数字和特殊字符,但字符集并不是完全均匀分布的。如果你对密码的字符组成有严格要求,需要配合其他参数来控制。

控制密码字符集的高级参数

mkpasswd提供了几个关键参数来控制生成密码的字符范围,这在不同测试场景下非常重要。

参数-l表示只使用小写字母:

mkpasswd -l 12

参数-d表示只使用数字:

mkpasswd -d 8

参数-C表示只使用大写字母:

mkpasswd -C 10

参数-s表示只使用特殊字符:

mkpasswd -s 6

这些参数可以组合使用。比如需要一个只包含小写字母和数字的12位密码:

mkpasswd -l -d 12

如果需要包含所有类型字符(大小写+数字+特殊符号),可以不加任何限制参数,或者明确指定:

mkpasswd -L -D -C -S 20

其中-L是小写、-D是数字、-C是大写、-S是特殊字符。不过实际测试中,不加参数直接生成的效果和加全参数基本一致,因为默认就是全字符集。

使用mkpasswd生成密码哈希值

在Ubuntu运维中,另一个高频需求是生成密码的加密哈希值,用于直接写入/etc/shadow文件或者配置文件中。mkpasswd支持两种哈希算法:MD5和SHA-256(通过-5参数)以及SHA-512(通过-5参数的变体)。

生成MD5哈希:

mkpasswd -m "MyTestPass123"

生成SHA-256哈希:

mkpasswd -5 "MyTestPass123"

生成SHA-512哈希:

mkpasswd -S "MyTestPass123"

这里有个关键点:生成的哈希值前面会带有算法标识符,比如$1$表示MD5,$5$表示SHA-256,$6$表示SHA-512。这个格式可以直接用于shadow文件,不需要额外处理。实际运维中,如果你需要手动创建一个测试用户并设置密码,可以这样操作:

HASH=$(mkpasswd -m "TestPass@2024")
sudo useradd -m testuser -p "$HASH"

不过要提醒一点,MD5在现代安全标准下已经不推荐使用,测试环境如果模拟生产配置,建议用SHA-512:

HASH=$(mkpasswd -S "TestPass@2024")
sudo useradd -m testuser -p "$HASH"
在自动化脚本中批量生成密码

运维工作中经常需要一次性生成多个密码,比如创建批量测试账户。可以写一个简单的bash脚本配合mkpasswd来实现:

#!/bin/bash
# 批量生成20个16位强密码并保存到文件
for i in $(seq 1 20); do
    PASSWORD=$(mkpasswd 16)
    echo "testuser${i}: ${PASSWORD}" >> /tmp/test_passwords.txt
done
echo "密码文件已生成:/tmp/test_passwords.txt"

如果需要生成密码并同时创建对应的系统用户:

#!/bin/bash
for i in $(seq 1 10); do
    USERNAME="test${i}"
    PASSWORD=$(mkpasswd 16)
    HASH=$(mkpasswd -S "$PASSWORD")
    sudo useradd -m "$USERNAME" -p "$HASH"
    echo "用户: $USERNAME 密码: $PASSWORD" >> /tmp/user_credentials.txt
done

这种脚本在搭建测试环境、做压力测试、模拟多用户场景时非常实用。生成的凭据文件记得设置严格权限:

chmod 600 /tmp/test_passwords.txt
mkpasswd与其他密码生成工具的对比

在Ubuntu系统中,生成随机密码的工具不止mkpasswd一个,还有openssl、pwgen、apg等。简单对比一下各自的适用场景:

openssl rand方式生成的是随机字节流,需要配合base64编码才能变成可读密码:

openssl rand -base64 12

pwgen可以生成容易记忆的密码,但需要单独安装:

sudo apt install pwgen -y
pwgen -s 16 10

apg也是一个可选工具,支持多种算法:

sudo apt install apg -y
apg -m 16 -M SNCL

对比下来,mkpasswd的优势在于:系统自带或极易安装、支持哈希生成、参数直观、不需要额外编码处理。缺点是随机性的熵源依赖系统的/dev/urandom,在极端情况下(比如虚拟机刚启动熵池不足时)生成速度可能略慢,但日常运维完全够用。

实际运维场景中的典型应用

场景一:搭建测试数据库时需要创建多个具有强密码的数据库用户。用mkpasswd生成密码后,直接通过SQL语句设置:

DB_PASS=$(mkpasswd 20)
mysql -u root -p -e "CREATE USER 'testdb'@'localhost' IDENTIFIED BY '${DB_PASS}'; GRANT ALL ON testdb.* TO 'testdb'@'localhost';"

场景二:配置Nginx或Apache的基本认证时,需要生成htpasswd兼容的密码。mkpasswd生成的密码可以直接配合htpasswd命令使用:

PASS=$(mkpasswd 12)
echo "testuser:${PASS}" | sudo tee /etc/nginx/.htpasswd
sudo htpasswd -b /etc/nginx/.htpasswd testuser "$PASS"

场景三:SSH密钥对之外,临时需要给某个账户设置密码登录进行调试。生成密码并设置:

TEMP_PASS=$(mkpasswd 14)
sudo passwd debuguser <<< "$TEMP_PASS"
echo "临时密码: $TEMP_PASS" | wall

场景四:在CI/CD流水线中,自动化测试需要模拟真实用户密码强度。可以在pipeline脚本中调用mkpasswd生成符合策略的密码,注入到测试配置中。

安全注意事项与最佳实践

虽然是测试环境,但密码管理的基本原则不能丢。以下几点必须注意:

第一,生成的密码不要硬编码在脚本里。用变量存储,用完即销毁或者定期轮换。

第二,测试密码文件不要放在可被其他用户读取的目录下,权限设为600,并且不要提交到版本控制系统中。

第三,mkpasswd生成的密码依赖/dev/urandom,如果你在容器环境中运行,确保容器的随机数设备是正常挂载的。可以检查:

ls -la /dev/urandom

第四,如果测试环境模拟的是生产环境,密码策略要尽量对齐。比如生产要求最少14位、必须包含特殊字符,那测试生成时也要用mkpasswd -l -d -C -S 14这样的参数来满足。

第五,测试结束后,所有用mkpasswd生成的临时账户和密码都应该清理干净,避免留下安全隐患。

常见问题排查

问题一:执行mkpasswd报错"command not found"。解决方法就是安装expect包,前面已经讲过了。

问题二:生成的密码中出现不期望的字符,比如反斜杠或引号。这是因为默认字符集包含了这些特殊符号。如果需要排除某些字符,可以用tr命令过滤:

mkpasswd 16 | tr -d '\\"'

问题三:在脚本中使用mkpasswd时输出带有换行符,导致变量赋值异常。解决方法是用tr去掉换行:

PASSWORD=$(mkpasswd 16 | tr -d '\n')

问题四:需要生成完全不重复的密码列表。可以配合sort和uniq来去重:

for i in $(seq 1 50); do mkpasswd 12; done | sort -u | head -20
总结

mkpasswd是Ubuntu运维中一个被低估的实用工具,安装简单、功能明确、覆盖了随机密码生成和哈希计算两大核心需求。无论是日常测试账户创建、自动化脚本集成,还是模拟生产环境的密码策略验证,它都能高效胜任。掌握它的各种参数组合和实际应用技巧,能让你的运维工作更规范、更高效。记住,工具本身不复杂,关键是知道在什么场景下用什么参数,以及如何把它嵌入到你的工作流程中去。