1. 为什么还需要自己手动配用户名密码认证
前阵子有个朋友问我,他搭了个内部资料站,团队十几个人共用,不想让无关人员访问,但又不想引入一套完整的权限管理系统。他的第一反应是问有没有现成的插件,我说Apache本身就内置了基于用户名的密码认证,不用装额外的东西,几行配置就能搞定。他听完挺意外的,因为很多人总觉得这种“古老”的功能早就被淘汰了,实际恰恰相反。
Apache的mod_authn_file配合mod_auth_basic,是Web服务端最经典的一套身份认证方案。它的核心思路很简单:服务端维护一个专门的用户密码文件,浏览器访问受保护资源时弹出登录框,输入的用户名和密码经Base64编码后放进HTTP请求头里,服务器比对通过才返回资源。这套机制从Apache 1.x时代就有了,到现在仍然是轻量级访问控制的主流选择。
你可能会问,现在不都流行OAuth、JWT、SSO那套东西了吗?确实,对于复杂的业务系统,那些方案更合适。但如果你的需求只是“让一小部分人访问某个目录,其他人一律挡住”,那Apache自带的基本认证反而是最省事、最稳的。不需要数据库,不需要写代码,不需要单独的应用层逻辑,改个配置重启就能上线。
而且这玩意儿有个好处是它工作在Web服务端这一层,跟后端程序完全解耦。不管你的目录里放的是静态HTML、PHP程序、图片资源还是压缩包下载,只要落到Apache托管路径下,认证都能生效。我做过的几个场景里,有给监控面板加访问门槛的,有给测试环境加白名单的,还有给客户做临时文件交付的,基本都是这套方案。
本文适合的人群也很明确:自己管理服务器、有Apache运维需求、需要一个轻量但可靠的访问控制方案的开发者或运维人员。不需要你有很深的原理功底,会编辑配置文件就行,但你最好能理解“认证是在Web服务层完成的,与应用层无关”这个基本逻辑,后面所有操作都是围绕这个展开的。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 前置准备与核心工具链:认识htpasswd、认证文件和相关模块
2.1 三大基础组件:模块、配置文件、密码存储文件
在动手之前,先把整个认证链路里涉及的三样东西搞清楚。第一是模块,Apache通过模块加载认证功能,核心模块是mod_auth_basic(负责弹出登录框和校验流程),真正去读取密码文件的是mod_authn_file(从纯文本文件中查找用户和密码哈希)。这两个在主流发行版的Apache中默认都是开启的,但CentOS系和Debian系加载模块的配置文件路径不同,后面我会单独说。
第二是Apache的主配置或虚拟主机配置文件。你可以在全局httpd.conf里写认证规则,也可以在VirtualHost里写,还可以放到.htaccess文件里。实践中最推荐的是放在VirtualHost或Directory配置块中,因为这样配置改动不需要在站点根目录放额外的隐藏文件,性能上也比.htaccess好。
第三是用户密码存储文件。这个文件是纯文本格式,每一行代表一个用户,格式为用户名:加密后的密码。
code复制zhangsan:$apr1$eWhZ3xuU$YvbjGQh6kMp8nZJvTbDqR0
lisi:$apr1$mYbFjPqa$KvHYa2vM8XHpJWRrq3C4y1
这里密码不是明文,而是经过哈希计算的字符串。$apr1$开头表示使用的是Apache专有的MD5哈希变体,$2y$开头则是bcrypt算法。这个文件不需要放在Web目录之外,甚至可以放在用户主目录里,只要运行Apache的用户(通常是www-data或apache)有读取权限就行。
2.2 htpasswd命令:认证文件的增删改查
负责管理这个密码文件的工具叫htpasswd,它随Apache一起安装。Deiban/Ubuntu系统上它的路径是/usr/bin/htpasswd,在apache2-utils包里;CentOS/RHEL上则归httpd-tools包管理,路径通常是/usr/sbin/htpasswd。如果命令找不到,说明工具包没装全,按对应发行版补装就行。
基本用法分几种场景。新建密码文件并添加第一个用户:
bash复制htpasswd -c /etc/apache2/conf.d/auth_users zhangsan
执行后会提示输入两次密码,然后生成文件。注意-c参数只在第一次创建文件时使用,后续再添加用户时绝对不能加-c,否则会覆盖整个文件,之前的所有用户全部丢失。
向已有文件添加新用户:
bash复制htpasswd /etc/apache2/conf.d/auth_users lisi
修改已有用户的密码也是同样的命令,它会检测到用户已存在并交互式地提示输入新密码。删除用户则需要用-D参数:
bash复制htpasswd -D /etc/apache2/conf.d/auth_users lisi
还有两个常用参数值得了解一下。-b参数允许在命令行中直接携带密码,适合写脚本自动化场景,但它的安全性较差,执行命令时密码会出现在shell历史记录里,我一般只在临时测试环境用。-B参数是强制使用bcrypt加密算法生成密码哈希,如果你运行的是Apache 2.4.4以上版本,我强烈建议用这个参数,安全性远高于默认的MD5变体,抵御暴力破解的能力强得多。
bash复制htpasswd -B -c /etc/apache2/conf.d/auth_users zhangsan
2.3 不同操作系统的模块加载差异与路径约定
处理认证配置时最容易踩的坑就是不同系统的配置路径不一样,我在这上面浪费过不少时间。Debian/Ubuntu系的Apache主配置是/etc/apache2/apache2.conf,模块的独立配置文件放在/etc/apache2/mods-enabled/目录下面,需要确认auth_basic.load和authn_file.load这两个文件是否存在于mods-enabled目录里(用apache2ctl -M可以列出所有已加载模块,方便排查)。
CentOS/RHEL系的Apache主配置是/etc/httpd/conf/httpd.conf,模块加载通过主配置里的LoadModule指令完成。多数情况下这两个认证模块在安装后就是启用的,不用额外操作,但如果用httpd -M查看模块列表时发现少了mod_auth_basic,就需要在配置里手动加上LoadModule。
还有密码文件的存放位置,虽然没有硬性规定,但建议放在Apache配置目录下的独立文件夹中,比如/etc/apache2/conf.d/或/etc/httpd/auth/。这个目录要确保Apache主进程有读权限,同时注意不要让Web服务直接暴露这个目录。放/etc/apache2/下面还有个好处是备份时更容易连同配置一起打包,方便迁移。
3. 完整实操:从空目录到密码保护上线
3.1 场景设定与文件规划
先明确一个具体场景,方便后面一步步跟着操作。假设我有一台Ubuntu 22.04服务器,Apache 2.4版本,网站根目录是/var/www/html,其中有一个子目录/var/www/html/internal用于存放内部项目文档,希望只有我和团队成员能访问。
在这个场景里,认证文件规划为/etc/apache2/conf.d/auth_users,认证组文件(如果需要按团队分组管理)规划为/etc/apache2/conf.d/auth_groups。之所以不把密码文件放进Web目录,是为了防止因配置失误导致密码文件被直接下载。曾经有段时间我图方便把auth_users丢在/var/www/html/下面,后来某次VirtualHost配置写错,目录列表功能没关,直接暴露了密码文件路径,吓得我立刻改了所有账号。
3.2 创建密码文件并添加用户
第一步自然是创建密码文件。用htpasswd工具新增文件并添加第一个用户:
bash复制htpasswd -B -c /etc/apache2/conf.d/auth_users zhangsan
这里用了-B参数走bcrypt算法,密码会以$2y$开头存储。输入密码时终端不会显示任何字符,这是正
