В принципе это тривиальная операция
описанная в документации к Nginx, но немного усложняет этот процесс необходимость создавать htpasswd файл, причем в самом Nginx средств для его создания нет (и это правильно), но предлагается создавать его используя утилиту htpasswd входящую в состав Apache.
Что самое смешное, на многих серверах, где используется Nginx, апача нет и не ожидается. Более того, большинство администраторов хостингов, "познавших" для себя Nginx начинают нескрываемо недолюбливать апач и верят, что наступит тот час, когда для Nginx наконец сделают аналог htaccess и апач, исправно служивший им долгие годы, наконец-то сгинет в небытие. Чтобы исправить сей досадный факт, добавлю в статью онлайн-формочку для генерации htpasswd фйла.
Давайте для примера создадим отдельный поддомен для хранения секретной информации с доступом по логину/паролю и в нагрузку в ней будут директория для доступа к которой понадобится дополнительная пара логин/пароль и директория с включенным листингом файлов тоже с отдельным доступом. Т.е. структура примерно такая:
/ (доступ к файлам по _логин-пароль_1)
--otherpass/ (доступ к файлам по _логин-пароль_2)
--listed/ (включен автоиндекс файлов, т.е. можнго просмотреть какие файлы тут лежат, доступ к файлам по _логин-пароль_3)
Создадим виртуалхост Nginx
Допустим, для поддомена adminka.example.com. Для этого создадим файл
sudo nano /etc/nginx/sites-available/adminka.example.com
со следующим содержимым:
server { listen 80; server_name adminka.example.com; access_log /var/log/nginx/adminka_example_com.log;#можно написать /var/log/nginx/$host.log но придется заранее создать лог-файл и выставить на него правильные права root /var/www/$host/htdocs; index index.html index.htm index.php; }
Ок, сохраняем, делаем этот хост доступным (включаем в конфиг нджинкса):
sudo ln -s /etc/nginx/sites-available/adminka.example.com /etc/nginx/sites-enabled/adminka.example.com
Создаем директории для htdocs
mkdir /var/www/{adminka.example.com,adminka.example.com/htdocs,adminka.example.com/htdocs/{otherpass,listed}
Если кто не понял, эта команда делает то же, что и 4 следующие:
mkdir /var/www/adminka.example.com mkdir /var/www/adminka.example.com/htdocs mkdir /var/www/adminka.example.com/htdocs/otherpass mkdir /var/www/adminka.example.com/htdocs/listed
Рестартим Nginx
sudo service nginx configtest sudo service nginx restart
Проверяем:
http://adminka.example.com/
Ага
403 Forbidden
nginx/0.7.64
Пароли не просит, листинг директории у нас не включен и index файла мы не создавали. То же самое для директорий otherpass и listed. Соответственно получаем 403 ошибку "доступ запрещен".
Добавим листинг (если нужен)
Мы договорились, что в директории listed у нас разрешен просмотр содержимого директории... Редактируем конфиг
sudo nano /etc/nginx/sites-available/adminka.example.com
server {
listen 80;
server_name adminka.example.com;
access_log /var/log/nginx/adminka_example_com.log;
root /var/www/$host/htdocs;
index index.html index.htm index.php;
location /listed/ {
autoindex on;
}
}
Сохраняем, перезапускаем, пробуем:
http://adminka.example.com/listed/
Ага, работает:
Index of /listed/
_________
../
_________
Но где же обещанные пароли? Спокойно, сейчас все будет!
Добавляем Basic HTTP authorization.
Пароли для разных директорий будем хранить в разных htpasswd файлах за пределами htdocs. Например так:
/var/www/adminka.example.com/ --/root_htpasswd --/listed_htpasswd --/otherpass_htpasswd
server {
listen 80;
server_name adminka.example.com;
access_log /var/log/nginx/adminka_example_com.log;
root /var/www/$host/htdocs;
index index.html index.htm index.php;
location / {
auth_basic "Unauthorized"; # текст сообщения сервера с предложением ввести пароль
auth_basic_user_file /var/www/$host/root_htpasswd; # путь к htpasswd файлу
}
location /listed/ {
auth_basic "Unauthorized";
auth_basic_user_file /var/www/$host/listed_htpasswd;
autoindex on;
}
location /otherpass/ {
auth_basic "Unauthorized";
auth_basic_user_file /var/www/$host/otherpass_htpasswd;
autoindex on;
}
}
Создаем htpasswd файлы (см. далее), сохраняем, перезапускаем, проверяем!
Генерация хеша пароля
HTTP авторизация в Nginx работает так же как и в Apache, т.е. с использованием htpasswd файла, но с тем лишь ограничением, что для шифрования пароля можно использовать только стандартный алгоритм DES с двухсимвольной солью. В Linux для этого используется C-функция crypt() (см
man 3 crypt
).
Можно использовать утилиту htpasswd из комплекта поставки Apache
htpasswd -nd seriy New password: Re-type new password:
seriy:4lQ0JcanrGr9E
Вывод этой утилиты состоит из 3-х частей: первая, до двоеточия "seriy" - это имя пользователя, "4l" - это двухсимвольная соль для функции crypt() и остальная часть "Q0JcanrGr9E" - это сам хеш пароля. Единственная проблема такого подхода - придется устанавливать apache.
Вот пара примеров кода для генерации htpasswd (
your_password - ваш пароль,
salt - соль для пароля, должна содержать 2(!!!) символа из набора "./0-9A-Za-z"):
используя php:
php -r 'echo crypt("your_password", "salt");'
используя Python:
python -c 'import crypt; print crypt.crypt("your_password", "salt")'
Если кто предложит примеры на других языках - (perl, ruby) буду благодарен. Возможно для этого можно использовать утилиту mcrypt но я в ней не смог разобраться.
В завершение - вот простенькая веб-формочка для генерации htpasswd онлайн.
[…] PS пишет: server { listen 80; server_name adminka.example.com; access_log /var/log/nginx/adminka_example_com.log;#можно написать /var/log/nginx/$host.log но придется заранее создать лог-файл и выставить на него правильные права root … htpasswd -nd seriy New password: Re-type new password: seriy:4lQ0JcanrGr9E. Вывод этой утилиты состоит из 3-х частей: первая, до двоеточия «seriy» – это имя пользователя, «4l» – это двухсимвольная соль для функции crypt() и остальная часть … […]
А вот так осуществляется контроль доступа к файлам на Nginx и PHP:
http://odiszapc.ru/2012/02/26/nginx-access/
Что тут писать-то?
у меня почему к listed постоянно пароль запрашивает, а к корневой один раз ввел в браузере и после этого открывается без запроса пароля, так и должно быть?
как нибудь время жизни пароля задать можно?
Апач устанавливать не нужно, достаточно установить apache2-utils.
Для Debian Linux:
aptitude install apache2-utils
Спасибо. Да, верное замечание.
На crypt на ruby:
'password'.crypt('salt')
Парсер лох, ковычки нужны одинарые или двайные «лапки»
Я починил, спасибо.
Каталоги можно сделать командой покороче, если использовать ключик -p
mkdir -p /var/www/adminka.example.com/htdocs/{otherpass,listed}
Продам мопед.