Введение
Публичный путь к приложению доставки уже работает, но предоставленное правило разрешает 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. Это подтверждает работу второго сервиса: предыдущая неудача была ограничением правила доступа.

Пример 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. Оба по-прежнему не проходят. Ответы с учётом состояния не дают нового входящего доступа другому источнику или порту. Этот тест подтверждает поведение ответов, но не проверяет новое исходящее соединение, инициированное приложением.

Пример 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-ответы с учётом состояния без исходящих разрешений. Реальные запросы отличили разрешённый трафик от заблокированного. В конце вы восстановили предоставленную группу и удалили только свою учебную группу.
Продолжите работу «Предоставление приватной подсети исходящего доступа», чтобы построить исходящий путь приватного приложения без разрешения незапрошенного внешнего доступа.



