跳到主要内容

htpasswd 文件怎么生成:从用户名密码到 Nginx/Apache 基本认证

一步讲清 htpasswd 文件的格式、用户名比加密密码的结构、bcrypt 和 apr1 的取舍,以及怎么在浏览器里本地生成再配到 Nginx 和 Apache 上。

发布于 作者 李雷
#htpasswd #nginx #apache #basic-auth #bcrypt

htpasswd 文件怎么生成:从用户名密码到 Nginx/Apache 基本认证

给一个 staging 站、内部面板或者 /metrics 端点加道门,最省事的方案往往不是上一整套登录系统,而是 HTTP Basic Auth 配一个 .htpasswd 文件。它历史悠久,Apache 和 Nginx 都原生支持,两行配置加一个文件就能挡住爬虫和闲人。但很多人卡在第一步:这个文件到底长什么样,密码怎么变成那一串看不懂的字符,bcrypt 和 MD5 又该选哪个。这篇把这些一次讲清楚。

.htpasswd 文件的格式:一行一个用户

文件结构简单到一句话能说完:一行一个用户,格式是 用户名:加密后的密码。冒号左边是明文用户名,右边是哈希,绝不会出现明文密码。一个真实的 bcrypt 行长这样:

team:$2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy

$2y$ 是 bcrypt 的标识,10 是计算轮数,后面跟着盐和最终摘要,全挤在一行里。换成 apr1 方案,开头就变成 $apr1$;换成 SHA-1,则是 {SHA} 加一段 Base64。三个用户就三行,每行独立加盐、互不影响:

team:$2y$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
ops:$apr1$ab12cd34$RkP9.kQxZ8oN6yW3vL5tj0
viewer:{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=

加用户就追加一行,删用户就删掉那一行,不用动其他人。这也是为什么给现有文件加管理员时,只需生成新用户那一行追加进去就够了。

为什么是哈希,不是明文

Basic Auth 校验时,服务器拿你提交的密码现算一遍哈希,再和文件里存的比对,从不还原存的那串。所以 .htpasswd 即使被人看到,也拿不到原始密码,前提是你选了靠谱的哈希。这里就引出关键的取舍。

bcrypt($2y$)是故意算得慢的,每次校验都要跑成千上万轮,暴力破解的成本被拉得极高,是当下唯一推荐的方案。apr1($apr1$)是 Apache 专用的加盐 MD5,老 htpasswd -m 默认产出它,到处都能用,但 MD5 本身已经弱了,只在服务器太老不支持 bcrypt 时才退回它。SHA-1({SHA})不加盐又快,两个用户用同一个密码会算出一模一样的哈希,彩虹表一秒就破,纯粹给硬要它的老系统留着。

我自己迁过一个全是 {SHA} 的旧文件。哈希是单向的,没法直接转换,只能逐个用户找他们要新密码、重新生成 bcrypt 行、整份重建。过程麻烦,但比留着一堆裸 SHA-1 强太多。要顺手生成几个强密码,可以配合 /zh/t/password-generator/ 一起用。

在浏览器里本地生成

传统做法是在服务器上敲 htpasswd -B /etc/nginx/.htpasswd team,但这要求机器上装了对应工具,且密码会进 shell 历史。更干净的做法是用 /zh/t/htpasswd-generator/ 直接在浏览器里生成:输用户名和密码,选方案,得到可直接粘贴的行,需要几个用户就加几行。密码、随机盐和生成的哈希全程在你的标签页里用纯 JavaScript 算,不发往服务器、不打日志、也不写进 URL。算完一键复制整份文件或下载成 .htpasswd,再放上服务器即可。

顺带一提,bcrypt 和 apr1 每次重算同一密码都会得到不同字符串,因为盐是随机的,这是对的,别慌,这些值都能校验同一个密码。

配到 Nginx 上

假设你要把一个 staging 站锁起来。先把生成的内容存成 /etc/nginx/.htpasswd,注意放在 web 根目录之外,然后在 server 块里加两行:

auth_basic "Staging";
auth_basic_user_file /etc/nginx/.htpasswd;

reload nginx 之后,每个请求都会弹浏览器登录框,爬虫直接拿到 401。如果只想保护单个端点,把这两行收进对应的 location 块即可:

location /metrics {
    auth_basic "Metrics";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

站点其余部分照常开放。对一个还不值得上完整鉴权系统的内部面板来说,这是最快又靠谱的一道门。

配到 Apache 上

Apache 这边在 .htaccess 或 vhost 配置里写四行:

AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

AuthUserFile 一定要指向文件的绝对路径,且这个文件要放在文档根目录之上。最常见的翻车点就是把 .htpasswd 丢进 /var/www/html/ 这种服务器会对外提供的目录,结果任何人都能下载到你的哈希。要拼 .htaccess 里的其余规则,可以配合 /zh/t/htaccess-generator/ 一起来。Nginx 和 Apache 的 .htpasswd 格式通用,apr1、bcrypt、SHA-1 三种哈希两边都能读,所以同一个文件搬来搬去不用改。

至此,从文件格式到上线配置就串完了。记住三条:默认选 bcrypt,文件放在 web 根目录之外,一行就是一个用户。剩下的交给浏览器本地生成,密码不出你的机器。


Made by Toolora · Updated 2026-06-13