Появилась задача обезопасить админскую часть на сайте. Причём это надо было сделать без внесения изменений в код самого сайта. Лучшее, что смог я найти — oauth2_proxy и nginx-google-oauth, но они требовали обработку коллбэков. Эти решения мне не понравились и я их отверг.
Пришлось обратиться к одному из модулей nginx и комплектующим для велосипеда.
Т.к. я не являюсь программистом, то с радостью приму замечания по моему маргарин-коду. И так. Я набросал простое приложение.
Пример установки будет на основе Debian/Ubuntu.
Установка:
Настройка приложения:
Последняя команда выдаст что-то подобное:
Scan QR: http://2qr.ru/otpauth://totp/OTPAuth:test1?secret=LOS5VMN5WI3FUTE4&issuer=OTPAuth
Or add manually SECRET KEY: LOS5VMN5WI3FUTE4
Emergency codes: 39816948,88908661,07327337,95159743,24616032
Добавляем это в ваш OTP-генератор. Я думаю, что у вас уже установлен Google Authentificator или подобное. Если же нет, тогда придётся установить. Тут помощь от Гугла. При добавлении пользователей генерируются ещё и резервные коды, на случай, если вы потеряете свой телефон.
Переходим к настройке nginx. Для выбранного location надо добавить:
А эти location делают авторизацию:
Запускаем наше приложение и рестартуем nginx:
Теперь при открытии site.name/private вы увидите страницу ввода одноразового пароля:
Что реализовано:
Что в планах:
Пришлось обратиться к одному из модулей nginx и комплектующим для велосипеда.
Т.к. я не являюсь программистом, то с радостью приму замечания по моему маргарин-коду. И так. Я набросал простое приложение.
Пример установки будет на основе Debian/Ubuntu.
Установка:
# установим nginx с поддержкой модуля ngx_http_auth_request_module
nginx -V 2>&1 | grep -qF -- --with-http_auth_request_module && echo "OK" || sudo aptitude update && sudo aptitude install nginx-extras
# клонируем репозитарий
git clone git@github.com:loukash/otp-auth.git # или git clone git@bitbucket.org:loukash/otp-auth.git
# установим все зависимости
cd otp-auth
pip install -r requirements.txt
Настройка приложения:
# создадим базу пользователей
python manage.py initdb
# добавим пользователя
python manage.py useradd -l test
Последняя команда выдаст что-то подобное:
Scan QR: http://2qr.ru/otpauth://totp/OTPAuth:test1?secret=LOS5VMN5WI3FUTE4&issuer=OTPAuth
Or add manually SECRET KEY: LOS5VMN5WI3FUTE4
Emergency codes: 39816948,88908661,07327337,95159743,24616032
Добавляем это в ваш OTP-генератор. Я думаю, что у вас уже установлен Google Authentificator или подобное. Если же нет, тогда придётся установить. Тут помощь от Гугла. При добавлении пользователей генерируются ещё и резервные коды, на случай, если вы потеряете свой телефон.
Переходим к настройке nginx. Для выбранного location надо добавить:
location /private {
...
auth_request /auth;
error_page 401 /login;
...
}
А эти location делают авторизацию:
location = /auth {
internal;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_pass http://127.0.0.1:5000;
}
location = /login {
proxy_pass http://127.0.0.1:5000;
}
Запускаем наше приложение и рестартуем nginx:
sudo service nginx reload
python manage.py runserver
Теперь при открытии site.name/private вы увидите страницу ввода одноразового пароля:
Что реализовано:
- Проверка одноразового пароля
- Управление пользователями
- Резервные коды
Что в планах:
- Сделать приложение настраиваемым
- Демонизация
- Логгирование
Комментарии (13)
M_Muzafarov
21.09.2015 10:24Заголовок про защиту на уровне nginx, на деле же получаем еще большое приложение с зависимостями.
но они требовали обработку коллбэков. Эти решения мне не понравились и я их отверг.
И странное следствие из этого:
И так. Я набросал простое приложение.
Ну и да, выше заметили, что в данный момент приложение не устойчиво к брутфорсу. Скажем, если у меня не удастся успешно попасть в одноразовый пароль, судя по коду приложения, мне ничто не мешает перебрать 8 цифр и получить emergency.
lukashin
21.09.2015 13:56Вообще не вижу противоречий. Одно дело вносить изменения в код сайта, а другое — написать аж 100-200 строк на flask'e. Готов посмотреть ваше решение на голом nginx или с каким-нибудь модулем.
Опять же, для безопасности веб-сервисов применяется комплекс мер, и это — одна из мер.
foxmuldercp
28.09.2015 18:13Я себе не представляю сервер, выпушенный в продакшен, на котором нет fail2ban. Вот честно, не представляю. Последние лет 5 я таких серверов не видел.
BOPOHA
29.09.2015 06:00+1Последние лет 5 я таких серверов не видел
fail2ban — парсер логов, с постлогикой. Если проект весомо нагружен посетителями, то access логи могут отсутствовать, либо быть весьма кастомными (структура, размера буфера, etc.), что так же не очень хорошо. Из этого можно сделать несколько выводов относительно ваших слов.
В общем поделитесь своими правилами fail2ban, или поправьте меня.lukashin
29.09.2015 07:15Согласен, что fail2ban не особо нужен.
Лучше ограничить количество запросов с помощью haproxy или nginx.
lolipop
А почему не гитхаб?