Многоуровневая защита локальной службы секретов

КибербезопасностьBeginner
Практиковаться сейчас

Введение

Эшелонированная защита (defense in depth) подразумевает использование нескольких уровней контроля одновременно, чтобы одна ошибка не привела к компрометации важного актива. Проверка токена, привязка к локальной сети, права доступа к файлам и логирование — каждый из этих механизмов защищает отдельный аспект одной и той же службы.

В этой лабораторной работе вы укрепите безопасность небольшой службы на Python, которая считывает секретный файл. Вы будете вносить по одному небольшому изменению за раз, запускать службу, тестировать её с помощью curl и проверять, как эти уровни работают вместе.

Начало работы с незащищенным секретом

На этом этапе вы изучите службу и увидите первый уровень контроля: запрос без ожидаемого токена отклоняется, в то время как запрос с токеном проходит успешно. Эшелонированная защита начинается с проверки того, что уже защищено, а что требует дополнительного уровня безопасности.

Перейдите в каталог проекта:

cd /home/labex/project

Выведите список подготовленных файлов:

ls -l

Вы должны увидеть secret_service.py, secret.txt и service-check.py.

Запустите службу в фоновом режиме. Символ & в конце указывает оболочке продолжать выполнение службы, пока вы вводите другие команды:

python3 secret_service.py > service.log 2>&1 &

Сохраните идентификатор фонового процесса (PID), чтобы позже корректно его завершить:

echo $! > service.pid

Попробуйте прочитать секрет без токена:

curl -i http://127.0.0.1:8081/secret

Ответ должен содержать 403 Forbidden. Теперь отправьте запрос с необходимым заголовком токена:

curl -s -H "X-Access-Token: lab-token-2026" http://127.0.0.1:8081/secret

Вы должны увидеть:

Project launch code: ORBIT-742

Остановите службу перед переходом к следующему шагу:

kill "$(cat service.pid)"

Запустите проверку для уровня токенов:

python3 service-check.py token

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

token: complete

Обеспечение локальной работы службы

На этом этапе вы подтвердите уровень сетевой защиты. Служба, которой требуется только локальный доступ, должна привязываться к 127.0.0.1 (также известному как localhost). Этот адрес принимает соединения только с того же компьютера.

Проверьте настройку хоста по умолчанию в службе:

grep 'default="127.0.0.1"' secret_service.py

Вы должны увидеть определение аргумента для опции --host. Это значение по умолчанию означает, что при запуске python3 secret_service.py служба начинает работу на localhost.

Снова запустите службу:

python3 secret_service.py > service.log 2>&1 &

Сохраните идентификатор процесса:

echo $! > service.pid

Используйте ss для проверки прослушиваемых TCP-сокетов. Опции -ltn означают прослушивание (listening), TCP и числовые адреса:

ss -ltn | grep ':8081'

Вывод должен показать 127.0.0.1:8081, что подтверждает работу службы только в локальной среде:

LISTEN ... 127.0.0.1:8081 ...

Остановите службу:

kill "$(cat service.pid)"

Запустите проверку для уровня localhost:

python3 service-check.py localhost

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

localhost: complete

Ограничение доступа к секретному файлу

На этом этапе вы добавите уровень прав доступа файловой системы. Даже если в службе есть уязвимость, секретный файл не должен быть доступен для чтения каждой локальной учетной записи.

Проверьте текущие права доступа к файлу:

ls -l secret.txt

Файл изначально имеет более широкие права доступа, чтобы вы могли их ограничить. Используйте chmod 600, чтобы сделать файл доступным для чтения и записи только его владельцу:

chmod 600 secret.txt

Снова проверьте права доступа:

ls -l secret.txt

Теперь биты прав доступа должны начинаться с -rw-------:

-rw------- ... secret.txt

Запустите проверку для этого уровня:

python3 service-check.py permissions

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

permissions: complete

Логирование отклоненных запросов

На этом этапе вы протестируете уровень обнаружения. Блокировка неавторизованного запроса полезна, но запись факта отклонения дает операторам доказательства того, что кто-то пытался получить доступ к защищенному маршруту.

Удалите старый файл логов, чтобы начать этот этап с чистого листа:

rm -f access.log

Запустите службу:

python3 secret_service.py > service.log 2>&1 &

Сохраните идентификатор процесса:

echo $! > service.pid

Отправьте запрос без токена:

curl -s http://127.0.0.1:8081/secret

Тело ответа должно быть:

forbidden

Просмотрите лог доступа:

cat access.log

Лог должен содержать записи rejected, /secret и missing_or_bad_token.

Остановите службу:

kill "$(cat service.pid)"

Запустите проверку для уровня логирования:

python3 service-check.py logging

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

logging: complete

Комплексная проверка уровней защиты

На этом этапе вы проверите итоговый результат эшелонированной защиты. Служба должна требовать токен, по умолчанию оставаться локальной, защищать секретный файл правами доступа только для владельца и логировать отклоненные запросы.

Запустите полную проверку:

python3 service-check.py all

Каждый уровень должен быть пройден:

token: complete
localhost: complete
permissions: complete
logging: complete

Запустите службу в последний раз:

python3 secret_service.py > service.log 2>&1 &

Сохраните идентификатор процесса:

echo $! > service.pid

Убедитесь, что секрет по-прежнему доступен при авторизованном запросе:

curl -s -H "X-Access-Token: lab-token-2026" http://127.0.0.1:8081/secret

Вы должны увидеть:

Project launch code: ORBIT-742

Остановите службу:

kill "$(cat service.pid)"

Эта финальная проверка важна, так как эшелонированная защита должна обеспечивать безопасность службы, не нарушая при этом её штатную работу для авторизованных пользователей.

Резюме

Вы отработали принципы эшелонированной защиты, применив несколько уровней контроля к одной небольшой службе. Вы проверили требование токена, привязку только к локальному интерфейсу, права доступа к файлу только для владельца и логирование отклоненных попыток доступа.

Главный урок заключается в том, что каждый уровень защищает от определенной точки отказа, при этом функциональность службы для авторизованных пользователей остается неизменной.