Skip to content

SergeyBoev/devops_test1

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Тестовое задание на позицию DevOps

Описание задачи

Имеется N серверов nginx в режиме обратного прокси, за которыми находится приложение, отвечающее по HTTP.

Требования:

  1. Приложение должно получать в заголовке X-Forwarded-For цепочку всех IP-адресов — клиента и всех пройденных nginx.
  2. Злоумышленник не должен иметь возможности подменить или подсунуть свой X-Forwarded-For.
  3. Решение должно быть реализовано с использованием docker-compose и включать минимум 3 nginx и приложение.
  4. Протокол тестирования с использованием curl.

Архитектура стенда

  • nginx1, nginx2, nginx3 — три прокси-сервера, соединённые в одну Docker-сеть.
  • app — Flask-приложение, отображающее заголовки запроса.

Возможны следующие сценарии:

  • Прямой запрос к одному nginx → приложение
  • Цепочка: nginx1 → nginx2 → nginx3 → приложение
  • Комбинации с произвольным стартом и продолжением

Реализация

Приложение (Flask)

Расположено в ./app/app.py. Выводит:

  • X-Forwarded-For — цепочка прокси
  • X-Real-IP — не используется (для безопасности)
  • remote_addr — адрес последнего прокси с точки зрения Flask
  • Полный список заголовков

Nginx (nginx.conf)

Ключевые элементы:

1. Защита от подделки

map $http_first_nginx $set_first_header {
    ""      "true";  # Если заголовка нет — это первый nginx
    default "false";
}

2. Отслеживание цепочки

map $http_x_proxy_chain $already_proxied {
    "~$server_addr"  "true";
    default          "false";
}

3. Формирование заголовка

set $x_forwarded_for $proxy_add_x_forwarded_for;

if ($set_first_header = "true") {
    set $first_nginx "$server_addr";
    set $x_forwarded_for "$remote_addr";  # Игнорируем внешний X-Forwarded-For
}

proxy_set_header X-Forwarded-For $x_forwarded_for;
proxy_set_header First-nginx "$first_nginx";

Таким образом, если клиент подаст свой X-Forwarded-For, он будет проигнорирован.

4. Продвижение по цепочке

upstream backend_servers {
    server nginx1:80;
    server nginx2:80;
    server nginx3:80;
    server app:8000;
}

if ($already_proxied = "true") {
    set $target_upstream "app:8000";  # Прекращаем цепочку
}

Запуск стенда

docker-compose up --build

Приложение будет доступно через:

  • http://localhost:8081 — nginx1
  • http://localhost:8082 — nginx2
  • http://localhost:8083 — nginx3
  • Напрямую: http://localhost:8000

Протокол тестирования

1. Прямой запрос через nginx1

curl -s http://localhost:8081

Ожидаемый результат:

X-Forwarded-For (chain): 172.20.0.1

Где 172.20.0.1 — IP Docker-клиента. Внешний X-Forwarded-For проигнорирован.

2. Подмена заголовка пользователем

curl -H "X-Forwarded-For: 1.2.3.4" http://localhost:8081

Ожидаемый результат:

X-Forwarded-For (chain): 172.20.0.1

Поддельный заголовок проигнорирован — безопасность обеспечена.

3. Цепочка: nginx1 → nginx2 → nginx3 → app

curl -H "First-nginx: " http://localhost:8081/?via=nginx2

На данный момент автоматическая цепочка не поддерживается напрямую через URL. Для тестирования цепочек можно настроить proxy_pass между nginx вручную.

Альтернативный сценарий:

Можно отправить запрос на nginx1, который проксирует на nginx2, а тот — на nginx3, и далее в приложение. Для этого требуется предварительная настройка маршрутов.

4. Проверка полного пути

Логи nginx показывают формирование заголовков:

172.20.0.1 - localhost "X-Forwarded-For: 172.20.0.1"

Выводы

  • Заголовок X-Forwarded-For корректно формируется с нуля, игнорируя клиентский.
  • Поддерживается возможность построения цепочки прокси. <<<<<<< HEAD
  • Решение безопасно, прозрачно и масштабируемо.

Затраченное время

Примерно 4 часа (включая проектирование, реализацию, тестирование и оформление).

Затраченное время

Примерно 1 час. Фактически 8, изза отсутствия практики.

Спасибо за задание! Будут еще - присылайте

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors