Делаем nginx безопасным

5412

TL;DR: абсолютно устойчивых систем не существует, поэтому ответ — никак. Но можно значительно упростить себе жизнь с помощью Docker-контейнера bunkerized-nginx. О том, чем он отличается от стандартного образа nginx и что интересного умеет, поговорим под катом.

Системный администратор

Сервер в бункере


Вообще у меня слово bunkerized применительно к серверу ассоциируется исключительно с CyberBunker, и здесь эта аналогия в принципе уместна. Французская команда Bunkerity разрабатывает готовые защищённые образы для nginx, mariadb, php и phpmyadmin, обещая защиту от проникновения, ботов и индексаторов, брутфорса и опасных файлов, как владельцы пиратского бункера когда-то гарантировали безопасность и анонимность.

Сканеры не видят сервер https://demo-nginx.bunkerity.com/, хотя он доступен в браузере

Реальные фичи


Помимо стандартных плюсов nginx’a в докере мы получаем:

  • Поддержку HTTPS с автоматическим продлением Let’s Encrypt,
  • Актуальную веб-защиту: HTTP-заголовки безопасности, php.ini hardening, предотвращение утечек памяти и другое
  • Встроенный межсетевой экран Modsecurity с правилами OWASP Core Rule Set
  • Автоматическую блокировку подозрительных действий через fail2ban
  • Защиту от бот-атак — обязательная проверка по капче/кукам/кастомному js (аналог Attack mode в Cloudflare)
  • Блокировку луковичных соединений, прокси, по подозрительному/запрещённому юзер-агенту и даже по стране запроса
  • Автоматическую проверку IP в черном списке DNSBL
  • Защиту от брутфорса (лимит на запросы)
  • Обнаружение опасных/поврежденных файлов с помощью ClamAV
  • Компактную конфигурацию через переменные среды
  • Поддержку нестандартных архитектур вроде arm32v7


Что-то выглядит банально, что-то может показаться излишним (зачем мне пересобирать nginx, если я запускаю контейнер на x86_64?), но благодаря гибкой настройке почти всё можно настроить на свой вкус и под свои нужды.

Запуск


Установка

docker pull bunkerity/bunkerized-nginx


HTTP-сервер с настройками по умолчанию

docker run -p 80:80 -v /path/to/web/files:/www bunkerity/bunkerized-nginx


Файлы раздаются из каталога /www.

HTTPS-сервер с автоматическим управлением Let’s Encrypt

docker run -p 80:80 -p 443:443 -v /path/to/web/files:/www -v /where/to/save/certificates:/etc/letsencrypt -e SERVER_NAME=www.yourdomain.com -e AUTO_LETS_ENCRYPT=yes -e REDIRECT_HTTP_TO_HTTPS=yes bunkerity/bunkerized-nginx


Сертификаты хранятся в каталоге /etc/letsencrypt directory. Можно запретить серверу слушать HTTP, добавив LISTEN_HTTP: no. Не забудьте настроить перенаправление, потому что Let’s Encrypt нуждается в открытом 80 порту.

Здесь были использованы следующие переменные:

SERVER_NAME — FQDN (полное доменное имя) вашего сервера
AUTO_LETS_ENCRYPT — автоматически создаёт и обновляет сертификаты Let’s Encrypt
REDIRECT_HTTP_TO_HTTPS — перенаправляет HTTP на HTTPS (кэп)

Работа в режиме обратного прокси

Собственно конфигурация обратного прокси ложится на пользователя:

  location / {
    if ($host = www.website1.com) {
      proxy_pass http://192.168.42.10$request_uri;
    }
  
    if ($host = www.website2.com) {
      proxy_pass http://192.168.42.11$request_uri;
    }
  }


Все файлы конфигурации (.conf) в каталоге /server-confs будут включены в серверный контекст. Достаточно просто примонтировать том с конфигами к контейнеру:

docker run -p 80:80 -e SERVER_NAME="www.website1.com www.website2.com" -e SERVE_FILES=no -e DISABLE_DEFAULT_SERVER=yes -v /path/to/server/conf:/server-confs bunkerity/bunkerized-nginx


Здесь:

SERVER_NAME — список валидных заголовков Host, посылаемых клиентом
SERVE_FILES — разрешает (yes) или запрещает (no) nginx раздавать файлы из /www
DISABLE_DEFAULT_SERVER — nginx не будет отвечать на запросы, у которых Host не будет находиться в списке SERVER_NAME
Здесь можно найти больше средств гибкой настройки

Работа за обратным прокси

docker run -p 80:80 -v /path/to/web/files:/www -e PROXY_REAL_IP=yes bunkerity/bunkerized-nginx


При включении PROXY_REAL_IP: yes активируется nginx модуль ngx_http_realip_module для получения реального IP клиента из-за прокси.

Обязательная антибот-проверка

docker run -p 80:80 -v /path/to/web/files:/www -e USE_ANTIBOT=captcha bunkerity/bunkerized-nginx


При USE_ANTIBOT: captcha все пользователи при заходе будут вынуждены проходить капчу. Также доступны варианты cookiejavascriptrecaptcha. Доки здесь.

Ещё есть примеры в репозитории, здесь.

Заключение


bunkerized-nginx это удобный вариант для тех, кому нужно быстро запустить nginx и не париться в будущем о его безопасности, закрытии уязвимостей и конфиденциальности. Буквально в одну строчку можно запустить готовый контейнер и забыть про него. При этом, несмотря на простой старт, это всё ещё полноценный nginx с его огромнейшим функционалом, что позволяет максимально гибко всё настроить.

источник