htpasswd
Файл логинов и паролей для HTTP Basic-авторизации — создание, bcrypt, удаление, проверка, nginx auth_basic
htpasswd (пакет apache2-utils) ведёт файл вида логин:хеш_пароля — по строке на пользователя. Такой файл читают Apache и nginx (auth_basic_user_file), чтобы закрыть часть сайта паролем. Сам пароль в файле не хранится — только хеш.
Синтаксис
htpasswd [-c] [-B] файл пользователь # спросит пароль дважды
htpasswd -b [-c] [-B] файл пользователь пароль # пароль из командной строки
htpasswd -n[b] [-B] пользователь [пароль] # не трогать файл, вывести строку
htpasswd -D файл пользователь # удалить
htpasswd -v[b] файл пользователь [пароль] # проверить пароль
Без -c файл должен уже существовать; пользователь в нём добавляется или его пароль меняется.
Опции
Что сделать
| Опция | Что делает |
|---|---|
-c | создать файл; если он есть — перезаписать с нуля |
-n | не трогать файл, напечатать строку логин:хеш в stdout |
-D | удалить пользователя |
-v | проверить пароль пользователя: код 0 — верный, 3 — нет |
Откуда пароль
| Опция | Что делает |
|---|---|
| (нет) | спросить в терминале дважды |
-b | взять последним аргументом (виден в ps и истории оболочки) |
-i | прочитать из stdin, без повтора — для скриптов |
Алгоритм хеша
| Опция | Хеш | Префикс в файле |
|---|---|---|
-m | MD5 в варианте Apache (по умолчанию) | $apr1$ |
-B | bcrypt — рекомендуемый | $2y$ |
-C N | «стоимость» bcrypt, 4–17 (по умолчанию 5); больше — медленнее подбор | |
-s | SHA-1 без соли, небезопасно | {SHA} |
-d | старый crypt, пароль обрезается до 8 символов | |
-p | открытым текстом — не используй |
Коды выхода
| Код | Значение |
|---|---|
0 | успех |
1 | проблема с файлом: нет файла без -c, нет прав |
2 | ошибка синтаксиса командной строки |
3 | пароль не совпал (при -v или при повторном вводе) |
5 | слишком длинное значение |
6 | недопустимый символ в имени (например, :) |
7 | файл не похож на файл паролей |
nginx: auth_basic
location /admin/ {
auth_basic "Restricted"; # текст в окне браузера
auth_basic_user_file /etc/nginx/.htpasswd; # файл от htpasswd
}
auth_basic off; во вложенном location снимает защиту. После правки конфига: nginx -t && nginx -s reload. Сам файл паролей nginx перечитывает на каждый запрос — после htpasswd перезагрузка не нужна.
Примеры
# создать файл с первым пользователем, bcrypt, пароль спросит
htpasswd -c -B /etc/nginx/.htpasswd alice
# добавить ещё одного (без -c!), пароль в аргументе
htpasswd -B -b /etc/nginx/.htpasswd bob 'S3cret!'
# пароль из stdin — не светится в списке процессов
printf '%s\n' "$PASS" | htpasswd -i -B /etc/nginx/.htpasswd carol
# сменить пароль — та же команда, что и добавление
htpasswd -B /etc/nginx/.htpasswd alice
# удалить пользователя
htpasswd -D /etc/nginx/.htpasswd bob
# проверить пароль
htpasswd -v -b /etc/nginx/.htpasswd alice 'S3cret!' && echo верный
# получить строку, не трогая файл (например, для Secret в Kubernetes)
htpasswd -nbB alice 'S3cret!'
# проверить защиту: без пароля 401, с паролем 200
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/admin/
curl -s -o /dev/null -w '%{http_code}\n' -u alice:'S3cret!' http://localhost/admin/
Подводные камни
-cна существующем файле стирает всех пользователей. Добавляй новых без-c.- По умолчанию MD5 (
$apr1$), не bcrypt. Для новых файлов явно указывай-B. - Файл должен быть читаем воркерами nginx (пользователь
www-data). С правами600и владельцем root nginx вернёт500, а вerror.log—open() "…/.htpasswd" failed (13: Permission denied). Подойдёт640с группойwww-dataили644. 401и500— разные беды.401— неверный логин или пароль (вerror.log:password mismatchилиuser … was not found);500— nginx не смог прочитать файл.-Dнесуществующего пользователя возвращает0и только пишетUser … not found. Не полагайся на код выхода.-bоставляет пароль в истории оболочки и вps. В скриптах бери-i.-nпечатает после строки ещё пустую строку — при копировании в конфиг или YAML убирай её.- Двоеточие в имени запрещено — это разделитель полей (
username contains illegal character ':', код6). - Basic-авторизация без HTTPS передаёт пароль почти открытым текстом (base64). Закрывай так только то, что идёт по TLS или по внутренней сети.