Управление доступом к приложению с помощью групп безопасности

AWSBeginner
Практиковаться сейчас

Введение

Публичный путь к приложению доставки уже работает, но предоставленное правило разрешает HTTP от любого источника IPv4. Вы назначите приложению отдельную группу безопасности, разрешающую только нужного клиента и порт. Реальные запросы покажут влияние ограничений источника и порта, а также ответов с учётом состояния соединения.

Сначала завершите лабораторную работу «Подключение публичной подсети к Интернету». Эта новая среда предоставляет собственные сеть, публичный адрес, маршруты и приложение, не используя предыдущую VM. CLI уже настроен. Сохраните предоставленные ресурсы и постороннюю эталонную сеть. Удалить потребуется только новую учебную группу безопасности.

Связь с сертификацией

Лабораторная работа даёт практику по следующим темам экзаменов.

  • Cloud Practitioner (CLF-C02) · Задача 3.5: управление доступом через группы безопасности в VPC.
  • Solutions Architect – Associate (SAA-C03) · Задача 1.2: базовые меры безопасности приложения для сетевых источников, портов и протоколов.
  • CloudOps Engineer – Associate (SOA-C03) · Задачи 5.1 и 5.3: базовая настройка групп безопасности и проверка её влияния на связность.
  • Security – Specialty (SCS-C03) · Задача 3.3: базовая практика разрешения и блокирования необходимого трафика группами безопасности.

Назначение пустой учебной группы безопасности

На этом шаге вы проверите работающее приложение и замените группу с широким доступом своей пустой группой.

Выполняйте команды в Terminal и откройте AWS View рядом с ним. Представление читает то же состояние ресурсов, что и CLI. Оно показывает application-network, публичную и приватную подсети и приложение с приватным адресом 10.20.1.10. Публичный адрес и маршрут к интернет-шлюзу уже предоставлены; не меняйте их.

cd /home/labex/project

Выберите VPC по тегу Name. --filters ограничивает результаты сервера, --query выбирает ID, а $(...) сохраняет результат в переменной оболочки:

VPC_ID=$(aws ec2 describe-vpcs \
  --filters Name=tag:Name,Values=application-network \
  --query 'Vpcs[0].VpcId' \
  --output text)

Выберите предоставленный интерфейс приложения внутри этой VPC:

ENI_ID=$(aws ec2 describe-network-interfaces \
  --filters "Name=vpc-id,Values=$VPC_ID" Name=tag:Name,Values=application-interface \
  --query 'NetworkInterfaces[0].NetworkInterfaceId' \
  --output text)

Группа безопасности управляет разрешённым трафиком на сетевом интерфейсе связанного ресурса. Входящие правила разрешают трафик к приложению; исходящие — трафик, который оно инициирует. Сохраните ID единственной предоставленной группы для восстановления при очистке. [0] выбирает первый элемент этого списка из одной группы:

SUPPLIED_GROUP_ID=$(aws ec2 describe-network-interfaces \
  --network-interface-ids "$ENI_ID" \
  --query 'NetworkInterfaces[0].Groups[0].GroupId' \
  --output text)

Прочитайте правила, не изменяя их:

aws ec2 describe-security-groups \
  --group-ids "$SUPPLIED_GROUP_ID" \
  --query 'SecurityGroups[].{ID:GroupId,Inbound:IpPermissions,Outbound:IpPermissionsEgress}' \
  --output json

Предоставленная группа разрешает входящий TCP-порт 80 от 0.0.0.0/0, то есть любого источника IPv4, и весь исходящий трафик. HTTP использует запросы и ответы; порт определяет принимающий сервис. Приложение обслуживает HTTP на TCP-портах 80 и 8081, но предоставленное правило разрешает только 80.

В AWS View нажмите Request application · client A, затем Request application · client B. Оба вернут Success и Application online на порту 80. Клиент A использует 198.51.100.10, B — 198.51.100.20. Нажмите Request port 8081; этот запрос клиента A завершится неудачей, поскольку порт не разрешён.

Создайте отдельную группу в той же VPC. --group-name задаёт имя, --description объясняет назначение, а спецификация тегов в кавычках добавляет теги принадлежности одним аргументом. Сохраните новый ID:

GROUP_ID=$(aws ec2 create-security-group \
  --group-name parcel-web \
  --description "Parcel HTTP access" \
  --vpc-id "$VPC_ID" \
  --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=parcel-web},{Key=Project,Value=parcel}]' \
  --query 'GroupId' \
  --output text)

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

--groups заменяет список групп интерфейса. Назначьте только новую группу: сохранение широкой группы рядом с ней объединит разрешения и по-прежнему позволит доступ обоим клиентам:

aws ec2 modify-network-interface-attribute \
  --network-interface-id "$ENI_ID" \
  --groups "$GROUP_ID"

Успешное изменение не выводит результат. Убедитесь, что интерфейсу назначена только ваша группа:

aws ec2 describe-network-interfaces \
  --network-interface-ids "$ENI_ID" \
  --query 'NetworkInterfaces[].{ID:NetworkInterfaceId,Groups:Groups}' \
  --output json

AWS View теперь показывает parcel-web и Inbound · none. Отправьте новые запросы от A и B; оба дадут Connection failed. Публичный адрес и маршрут остаются, но пустая группа не разрешает входящие запросы. Не закрывайте этот Terminal, чтобы сохранить переменные с ID.

Разрешение только нужного HTTP-клиента

На этом шаге вы разрешите клиенту A доступ к порту 80 и проверите, что другой источник и другой порт остаются заблокированы.

Входящее правило задаёт протокол, диапазон портов и источник. --protocol tcp выбирает TCP, --port 80 — один этот порт, --cidr 198.51.100.10/32 — только IPv4-адрес клиента A. /32 содержит один IPv4-адрес и уже, чем 0.0.0.0/0.

Добавьте правило в свою группу, а не в предоставленную:

aws ec2 authorize-security-group-ingress \
  --group-id "$GROUP_ID" \
  --protocol tcp \
  --port 80 \
  --cidr 198.51.100.10/32

Ответ указывает на успех и может содержать ID нового правила. Прочитайте все входящие правила:

aws ec2 describe-security-groups \
  --group-ids "$GROUP_ID" \
  --query 'SecurityGroups[].IpPermissions' \
  --output json

Есть одно TCP-правило с FromPort и ToPort, равными 80, и источником 198.51.100.10/32. AWS View показывает тот же входящий источник и порт.

Нажмите Request application · client A. Результат — Success, источник 198.51.100.10, порт назначения 80, тело Application online. Это реальный ответ предоставленного приложения.

Теперь нажмите Request application · client B и Request port 8081. Оба вернут Connection failed. У первого запроса неверный источник, у второго клиент A, но неверный порт. Публичный адрес и маршрут дают путь, а группа безопасности определяет, какой трафик может им пользоваться.

Проверка и удаление временного разрешения порта

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

Предоставленное приложение также обслуживает HTTP на порту 8081. Сохраните тот же разрешённый источник и добавьте временное правило для этого порта:

aws ec2 authorize-security-group-ingress \
  --group-id "$GROUP_ID" \
  --protocol tcp \
  --port 8081 \
  --cidr 198.51.100.10/32

Снова прочитайте правила:

aws ec2 describe-security-groups \
  --group-ids "$GROUP_ID" \
  --query 'SecurityGroups[].IpPermissions' \
  --output json

Теперь есть два TCP-правила: порты 80 и 8081, каждый ограничен клиентом A. AWS View показывает оба. Нажмите Request port 8081. Результат сменится на Success с портом назначения 8081 и телом Application online. Это подтверждает работу второго сервиса: предыдущая неудача была ограничением правила доступа.

Временное правило TCP 8081 разрешает реальный запрос клиента A

Пример AWS View: оба узких входящих правила присутствуют, и клиент A получает ответ приложения на порту 8081. Созданные ID ресурсов в вашей среде будут отличаться.

Упражнению нужен только порт 80. Отзыв правила удаляет его разрешение. Укажите те же протокол, порт и источник, чтобы удалить только временное правило:

aws ec2 revoke-security-group-ingress \
  --group-id "$GROUP_ID" \
  --protocol tcp \
  --port 8081 \
  --cidr 198.51.100.10/32

Ответ указывает на успех. Запросите итоговые правила:

aws ec2 describe-security-groups \
  --group-ids "$GROUP_ID" \
  --query 'SecurityGroups[].IpPermissions' \
  --output json

Остаётся только правило клиента A для порта 80. Когда AWS View уберёт правило 8081, снова нажмите Request port 8081; теперь запрос не пройдёт. Клиент A на порту 80 по-прежнему успешен, а B на 80 по-прежнему заблокирован. Вы изменили разрешение одного порта, не заменяя приложение или маршрут.

Наблюдение HTTP-ответов с учётом состояния

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

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

Прочитайте текущие исходящие разрешения:

aws ec2 describe-security-groups \
  --group-ids "$GROUP_ID" \
  --query 'SecurityGroups[].IpPermissionsEgress' \
  --output json

В новой группе задано назначение по умолчанию 0.0.0.0/0 для всего трафика. В следующей команде --ip-permissions принимает JSON-список спецификаций правил одним аргументом в кавычках. Значение -1 в IpProtocol означает все протоколы, а IpRanges задаёт назначения исходящего правила. Удалите именно это правило по умолчанию:

aws ec2 revoke-security-group-egress \
  --group-id "$GROUP_ID" \
  --ip-permissions '[{"IpProtocol":"-1","IpRanges":[{"CidrIp":"0.0.0.0/0"}]}]'

Ответ указывает на успех. Прочитайте правила обоих направлений:

aws ec2 describe-security-groups \
  --group-ids "$GROUP_ID" \
  --query 'SecurityGroups[].{Inbound:IpPermissions,Outbound:IpPermissionsEgress}' \
  --output json

Входящие правила по-прежнему разрешают только A на порту 80, исходящие пусты. AWS View показывает Outbound · none. Снова нажмите Request application · client A. Success и Application online всё ещё возвращаются: ответ относится к разрешённому входящему соединению.

Повторно проверьте Request application · client B и Request port 8081. Оба по-прежнему не проходят. Ответы с учётом состояния не дают нового входящего доступа другому источнику или порту. Этот тест подтверждает поведение ответов, но не проверяет новое исходящее соединение, инициированное приложением.

Разрешённый входящий HTTP-запрос получает ответ без исходящих разрешений

Пример AWS View: входящий доступ разрешён только A на порту 80, исходящие правила пусты, а реальный HTTP-ответ всё ещё успешен. Созданные ID ресурсов в вашей среде будут отличаться.

Восстановление предоставленной группы и удаление своей

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

Группу, связанную с сетевым интерфейсом, нельзя удалить. Сначала замените свою группу сохранённой предоставленной группой; не удаляйте и не изменяйте предоставленную группу:

aws ec2 modify-network-interface-attribute \
  --network-interface-id "$ENI_ID" \
  --groups "$SUPPLIED_GROUP_ID"

Подтвердите связь:

aws ec2 describe-network-interfaces \
  --network-interface-ids "$ENI_ID" \
  --query 'NetworkInterfaces[].{ID:NetworkInterfaceId,Groups:Groups}' \
  --output json

Связана только исходная группа supplied-application. Теперь удалите свою неиспользуемую группу:

aws ec2 delete-security-group --group-id "$GROUP_ID"

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

aws ec2 describe-security-groups \
  --query 'SecurityGroups[].{ID:GroupId,Name:GroupName,VPC:VpcId}' \
  --output table

parcel-web отсутствует. Предоставленная и стандартные группы остаются, как и VPC, подсети, интерфейс приложения, публичный адрес и маршруты. Ошибка запроса списка не доказывает удаление.

AWS View снова показывает supplied-application. Нажмите кнопки запросов A и B: оба запроса к порту 80 вернут Success, как в исходном состоянии. Request port 8081 не пройдёт, поскольку неизменённая предоставленная группа разрешает только 80.

Выполните проверку завершения этого шага.

Итоги

Вы создали и назначили отдельную группу безопасности, разрешили только клиента A на TCP-порту 80, проверили и отозвали временное разрешение второго порта и подтвердили HTTP-ответы с учётом состояния без исходящих разрешений. Реальные запросы отличили разрешённый трафик от заблокированного. В конце вы восстановили предоставленную группу и удалили только свою учебную группу.

Продолжите работу «Предоставление приватной подсети исходящего доступа», чтобы построить исходящий путь приватного приложения без разрешения незапрошенного внешнего доступа.