Pull to refresh

Comments 12

auth pam? Там же можно правами пользователей все разрулить… Пользователь без консоли может в nginx и ничего более, а остальные не авторизуются на nginx… Нет, ваш способ работает, но чем система проще, тем меньше точнее отказа.

А на auth basic проще натянуть fail2ban или что-то подобное, например...

fail2ban — это всё таки установка доп. ПО, чего Я хотел избежать.
Lua тоже не часть Nginx, а сторонний модуль, который надо ставить отдельно, на скок я помню.

А так — Обычная авторизация по htpasswd (nginx_auth) + Fail2ban для защиты от брута вполне достаточно.
Какие на Ваш взгляд, у предложенного решения, недостатки,
возможно, есть что-то в планах добавить / улучшить? Например, по
«Хотя бы минимальная защита от перебора»

Спасибо.
На мой взгляд, счётчиков вполне достаточно. Тем более у меня дополнительная защита по принципу "Неуловимого Джо"
А в планах: У меня уже реализована общая страница с псевдооконным интерфейсом на jquery ui, чтобы работать с несколькими сервисами, возможно оформлю это в статью, но пока там маловато информации даже на заметку…
Чтобы включить ngx_http_auth_request_module нужно пересобирать nginx с этим модулем, по умолчанию это модуль не включен даже в nginx-extras
Рассмотрите вариант с аутентификацией по сертификатам TLS. В самой конфигурации nginx нужно будет тогда всего-навсего добавить две строчки вида:
ssl_client_certificate /path/to/nginx/ssl/ca.crt;
ssl_verify_client on;

Использование сертификатов даёт максимальную защиту от перебора. TLS-аутентификация не пересекается с Basic-аутентификацией защищаемых сервисов, если они таковую имеют, и поэтому можно считать, что требование с отдельной страницей входа соблюдено. Поскольку такое решение опирается на основополагающие механизмы, то можно сказать, что минималистичность требований к устанавливаемому ПО аж зашкаливает — ведь в этой схеме не нужен даже Lua.

На хабре есть статья про настройку аутентификации клиентов через TLS, однако там используются ручные команды openssl. Гораздо проще воспользоваться скриптами из пакета easy-rsa, чтобы автоматизировать процесс выпуска упакованных сертификатов и генерации CRL, если нужно.

Предложу Вашему вниманию несколько замечаний по lua-коду:
  1. Несмотря на то, что функции вынесены в общий словарь, счётчики у каждого рабочего процесса будут свои. В документации к модулю lua написано о возможных подходах к разделению данных между рабочими процессами.
  2. Крайне рекомендуется везде использовать локальные переменные. Глобальные переменные в случае nginx добавляют только проблем и всё равно не решают вопрос с разделением данных хотя бы даже между запросами одного рабочего процесса nginx. Для того, чтобы проверить ваш код имеется специальная утилита lua-releng, подготовленная разработчиком модуля lua для nginx.
  3. В nginx есть встроенные функции для вычисления md5 и sha1. Для вашей задачи с криптографической точки зрения корректно использовать только функцию hmac_sha1 вместо манипуляций с конкатенацией строки для хэширования. Подробнее об этом будет ниже.
  4. Функцию nvl можно заменить идиомой
    (val or default)
    , которая будет принимать значение default во всех случаях, когда val == nil либо val = false (и только тогда).
  5. Чтение из файла — блокирующая операция, которая приостановит выполнение ВСЕХ запросов рабочим процессом. Сетевые операции, осуществляемые через специальное API косокетов в Nginx, напротив, не блокируют выполнение остальных запросов. Поэтому часто можно увидеть использование Redis или других БД из модулей lua в nginx.
  6. «Токен» валиден в пределах тех же суток, в которые выдан. Это достаточно непрактично в окрестности полуночи. Вместо этого обычно открытым текстом записывают прямо в токен срок окончания действия и всю строку подписывают HMAC-ом. Пример реализации того же самого в nginx (но куки ставит отдельный сервер, это легко переделать).
  7. Ваш код уязвим к атаке удлинением сообщения. Предположим, пользователь в прошлом имел доступ к некоторому сервису и получил токен в виде хэшсуммы из секретного ключа, юзерагента и даты. Тогда даже после смены пароля или отзыва доступа он может обойти аутентификацию, рассчитав удлинённый хэш от своего старого значения юзерагента + старой даты + требуемого для удлинения паддинга + текущей даты. Подставив в юзерагент всё кроме даты он пройдёт проверку. Вот поэтому нужно применять HMAC, а не конкатенацию строк, чтобы не наступать на грабли при использовании криптографических примитивов.
Про аутентификацию по сертификату думал, но отказался ввиду неудобности лично для меня: Например в гостях захочу включить какой-нибудь фильм с чужого ПК, для этого у меня с собой должна быть флешка с клиентским сертификатом. Логин/пароль в данном плане удобнее — он всегда с собой, в голове.
1. Дополнительно изучу этот вопрос. Но проверка показывала, что счётчики общие при попытках доступа с разных IP/ПК.
2. Проверю, Я вроде бы везде старался использовать локальные переменные.
3. А вот за это — Спасибо! Поменяю. Как-то Я их упустил…
4. Поменяю. Всё таки полчаса на изучения lua перед реализацией, видимо, не достаточно.
5. Всё-таки у меня не та нагрузка, чтобы это могло принести какие-либо неудобства. Я даже с трудом могу представить кейс, когда мне может потребоваться одновременная аутентификация из двух разных мест. Но решение однозначно не промышленное, для личного пользования…
6, 7. Посмотрю варианты реализации через HMAC.

Спасибо за конструктивную критику.
Думаю, в ближайшее время решение претерпит некоторые изменения.
Only those users with full accounts are able to leave comments. Log in, please.