open atlas
↑ К треку
AWS на практике AWS · 04 · 02

Security groups и network ACL: два фильтра, две модели состояния

Два пакетных фильтра: security group (инстанс, stateful, только allow, ссылается на другую SG) и network ACL (подсеть, stateless, упорядоченный, умеет deny). Stateful против stateless кусает больнее всего: не откроешь эфемерные порты — ответы исчезнут.

AWS Middle ◷ 17 min
Уровень
ОсновыJuniorMiddleSenior

Команда запирает подсеть кастомным network ACL: входящее правило 100 разрешает 443 из интернета, остальное запрещено. Веб-серверы в этой подсети перестают отвечать. Не медленно — полностью. curl снаружи висит и отваливается по таймауту. Security group открыта на 443 настежь, таблица маршрутов в порядке, серверы здоровы. Через часы захватов трафика кто-то замечает: SYN приходит, SYN-ACK уходит с инстанса, но до клиента не доходит. NACL разрешил входящий запрос на 443 — но он так и не разрешил исходящий ответ, а тот уходит на эфемерном порту вроде 54321, а не на 443. NACL — stateless: он не помнит входящее соединение, поэтому ответный пакет — это совершенно новый поток, попавший в неявный deny. Одно исходящее правило на порты 1024-65535 всё починило. Баг был не в опечатке. Он был в том, что забыли: один из двух твоих фильтров не имеет памяти.

Два уровня, две совершенно разные модели состояния

Почему правильно настроенная security group иногда не доставляет трафик? Потому что второй фильтр — на границе подсети — живёт по совершенно другим правилам.

Пакет, идущий к твоему EC2-инстансу, пересекает два фильтра, и ведут они себя совсем по-разному. Network ACL охраняет границу подсети — он инспектирует трафик, входящий в подсеть и выходящий из неё. Security group охраняет ENI (Elastic Network Interface, эластичный сетевой интерфейс), прикреплённый к самому инстансу. Пакет из интернета сначала попадает в NACL, затем в SG; ответ уходит сначала через SG, затем через NACL. Оба должны пропустить трафик, иначе он умирает.

Определяющее различие — состояние. Security group stateful: если она разрешает входящий запрос, ответ автоматически разрешён обратно независимо от исходящих правил — а если она разрешает исходящий запрос (а дефолтная SG разрешает весь egress), ответ разрешён обратно независимо от входящих правил. SG помнит соединение. Network ACL stateless: у него нет памяти о прошлых пакетах. Если ты разрешил входящий 443, ты отдельно должен разрешить исходящий обратный трафик, и этот обратный трафик уходит не на 443 — он уходит на эфемерном порту. Клиент открыл соединение с высокого случайного порта, поэтому ответ сервера адресован именно этому порту. AWS рекомендует открывать 1024-65535 для эфемерного обратного трафика, потому что разные клиенты выбирают из разных диапазонов: NAT gateway и многие ELB используют 1024-65535, ядра Linux обычно 32768-60999, а Windows-клиенты 49152-65535. Открывай объединение, иначе часть клиентов тихо ломается.

Как оцениваются правила и что каждый фильтр умеет выразить

Эти два фильтра даже решают по-разному. Security group работает только на allow и оценивается как единое целое. В SG нельзя написать deny-правило — её единственный глагол «разреши это». Каждое правило по всем SG, прикреплённым к ENI, объединяется: если хоть одно правило пропускает пакет — он проходит. Нет порядка и нет первого совпадения; это одно большое ИЛИ из allow-правил с неявным deny для всего несовпавшего. Дефолтная SG, идущая с VPC, разрешает никакой входящий трафик и весь исходящий, и для удобства содержит самоссылающееся правило, чтобы участники могли общаться друг с другом.

Network ACL — упорядоченный список и поддерживает явный deny. У каждого правила номер от 1 до 32766; AWS оценивает сначала самый низкий номер, и первое совпадение выигрывает — дальнейшие правила не проверяются. Поскольку он умеет говорить deny, NACL может то, чего SG фундаментально не может: заблокировать конкретный плохой IP или CIDR. Поставь DENY для 198.51.100.0/24 правилом 90, выше твоего ALLOW 0.0.0.0/0 правилом 100 — и этот диапазон отрезан, пока все остальные проходят. Каждый NACL завершается неудаляемым правилом *, которое отклоняет всё несовпавшее. Дефолтный NACL разрешает весь входящий и исходящий; кастомный NACL начинает с запрета всего, пока ты не добавишь правила.

# Кастомный NACL — ВХОДЯЩИЕ правила (оценка от низкого к высокому, первое совпадение выигрывает)
Rule   Type        Port        Source            Allow/Deny
90     HTTPS       443         198.51.100.0/24   DENY    # сначала блокируем один плохой CIDR
100    HTTPS       443         0.0.0.0/0         ALLOW   # все остальные могут достучаться до 443
130    Ephemeral   1024-65535  0.0.0.0/0         ALLOW   # обратный трафик для исходящих соединений
*      ALL         ALL         0.0.0.0/0         DENY    # неявное, удалить нельзя

# Кастомный NACL — ИСХОДЯЩИЕ правила (stateless: ты ДОЛЖЕН открыть обратный путь)
Rule   Type        Port        Destination       Allow/Deny
100    Ephemeral   1024-65535  0.0.0.0/0         ALLOW   # ответы на входящий 443 уходят здесь
110    HTTPS       443         0.0.0.0/0         ALLOW   # если инстанс сам инициирует исходящий 443
*      ALL         ALL         0.0.0.0/0         DENY

Когда обнаруживаешь, что хардкодишь IP-диапазон в правило security group, спроси себя: можно ли сослаться на роль вместо адреса? Ответ почти всегда «да». Идиоматичный приём least-privilege живёт на стороне SG: ссылайся на другую security group как на источник вместо CIDR. Вместо «разреши 5432 от 10.0.2.0/24» на SG базы напиши «разреши 5432 от SG app-уровня». Теперь любой инстанс с SG app-уровня дотянется до Postgres, а больше никто — и правило продолжает работать, пока app-уровень масштабируется и его IP меняются. Ты никогда не хардкодишь адрес; ты выдаёшь доступ роли.

# Доступ к БД по least-privilege: разрешить Postgres ТОЛЬКО инстансам из SG app-уровня
aws ec2 authorize-security-group-ingress \
  --group-id sg-db0000000000db \
  --protocol tcp --port 5432 \
  --source-group sg-app00000000app
СвойствоSecurity groupNetwork ACL
Работает на уровнеИнстанс / ENIПодсеть
СостояниеStateful — обратный трафик авто-разрешёнStateless — разрешай оба направления + эфемерные порты
Глаголы правилТолько allow (нет deny)Allow и deny
ОценкаВсе правила объединены (любой allow пропускает)Нумерованные, низший первым, первое совпадение выигрывает
Может ссылаться на SG как источникДа — идиома least-privilegeНет — только CIDR
Дефолт (дефолтный объект VPC)Нет входящего, весь исходящийРазрешить всё в обе стороны
Дефолт (кастомный объект)Нет входящего, весь исходящийЗапретить всё, пока не добавишь правила
Почему это работает

Зачем нам два пересекающихся фильтра? Защита в глубину с разделением труда. Security group — твой скальпель: least-privilege на ресурс, выраженный против ролей (других SG), а не адресов, и stateful, так что про обратные пути не приходится думать. NACL — твой грубый барьер на всю подсеть: он умеет deny — поэтому может в чёрную дыру отправить известный плохой CIDR или навязать грубое правило «эти два уровня никогда не общаются», которое ни одна отдельная SG не гарантирует, потому что SG умеет только выдавать, но не запрещать. Большинство команд держат пермиссивные дефолтные NACL и делают всю реальную работу в SG, обращаясь к NACL только когда нужен deny или ограничение радиуса поражения на уровне подсети. Использовать NACL там, где место SG, — так и оказываешься в 2 часа ночи за дебагом дропнутого эфемерного обратного трафика.

Выбери лучший вариант

Нужно заблокировать один конкретный вредоносный /24 от доступа ко всем инстансам в подсети, без исключений, независимо от любого allow-правила, которое кто-то добавит позже. Какой фильтр справится?

Викторина

Кастомный network ACL подсети разрешает входящий TCP 443 от 0.0.0.0/0, и security group тоже разрешает 443, но внешние клиенты всё равно не могут завершить запрос. Самая вероятная причина?

Викторина

В security group твоей базы какое правило лучше всего выражает «только app-уровень может подключаться к Postgres» и продолжает работать при автомасштабировании app-уровня?

Вспомните перед уходом
  1. 01
    Сопоставь security group и network ACL по состоянию, глаголам правил, оценке, области и дефолтам — и объясни ловушку эфемерных портов.
  2. 02
    Когда реально используешь NACL вместо просто security group и почему SG этого не может?
Итог

Твои ресурсы AWS сидят за двумя пакетными фильтрами с противоположными характерами. Security group охраняет ENI инстанса: она stateful, поэтому ответ на любой разрешённый поток автоматически пропускается в обратную сторону; она работает только на allow, каждое прикреплённое правило объединяется, а несовпавший трафик неявно запрещён; и она может назвать другую security group источником, что есть идиоматичный паттерн least-privilege — «разреши 5432 от SG app-уровня» переживает автомасштабирование, потому что выдаёт доступ роли, а не адресу. Network ACL охраняет границу подсети: он stateless и не помнит ничего, поэтому надо разрешать оба направления и, критически, открывать эфемерные обратные порты 1024-65535, иначе ответы на разрешённое входящее соединение тихо дропаются; его правила нумерованы и оцениваются сначала по низшему, первое-совпадение-выигрывает; и он поддерживает явный deny, что позволяет ему заблокировать конкретный плохой CIDR — то, чего security group не сможет никогда, потому что у неё нет глагола deny. Используй оба в связке: SG — точный stateful скальпель на ресурс, где живёт почти весь реальный контроль доступа, а NACL — грубый, умеющий deny барьер на всю подсеть, к которому обращаешься только когда надо отправить CIDR в чёрную дыру или ограничить радиус поражения. Сеньорский инстинкт — помнить, у какого фильтра есть память, а у какого нет. Теперь, когда увидишь соединение, которое молча зависает после того, как SYN-ACK ушёл с инстанса, — сначала проверяй исходящие правила NACL на эфемерные порты, прежде чем грешить на security group.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 5 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

Примени это

Примени этот урок в реальном проекте.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.