Модуль 1.1: Глибоке занурення в AWS Identity & Access Management (IAM)
Складність: [MEDIUM] | Час на виконання: 2 год | Передумови: Cloud Native 101
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»У серпні 2019 року масовий витік даних вразив велику фінансову установу, розкривши особисту інформацію понад 100 мільйонів клієнтів. Причиною став не складний експлуатант нульового дня чи хакерська група державного рівня. Це був неправильно налаштований файрвол веб-застосунків (WAF), який дозволив атаку типу server-side request forgery (SSRF). SSRF дозволив зловмиснику надіслати запит до сервісу метаданих екземпляра AWS EC2, отримавши креденшали IAM-ролі, приєднаної до екземпляра. Оскільки ця IAM-роль була надмірно дозволеною і мала доступ на читання до десятків конфіденційних S3-бакетів із даними клієнтів, зловмисник просто синхронізував бакети зі своїм власним середовищем. Фінансові наслідки перевищили сотні мільйонів доларів у вигляді штрафів, виплат та репутаційних збитків.
Цей інцидент підкреслює фундаментальну істину хмарної безпеки: ідентифікація — це новий периметр. У традиційному локальному дата-центрі безпека часто означала побудову міцного мережевого периметра з файрволами та системами виявлення вторгнень. Опинившись усередині мережі, було відносно легко пересуватися горизонтально. В AWS мережевий периметр все ще має значення, але він є вторинним порівняно з периметром ідентифікації. Кожен API-виклик — чи то запуск екземпляра EC2, читання об’єкта з S3, чи видалення бази даних — автентифікується та авторизується через Identity and Access Management (IAM).
Якщо ви помилитеся в IAM, ніщо інше не матиме значення. Ви можете побудувати найбезпечнішу віртуальну приватну хмару (VPC) із заблокованими групами безпеки та приватними підмережами, але якщо зловмисник скомпрометує IAM-ключ з адміністративними привілеями, він зможе обійти всі ці мережеві контролі одним API-викликом. У цьому модулі ви вивчите механіку AWS IAM, вийшовши за межі базових користувачів та груп, щоб зрозуміти силу ролей, нюанси оцінки політик та критичну важливість принципу найменших привілеїв. Ви навчитеся проєктувати контроль доступу для складних багатоакаунтних середовищ, забезпечуючи, щоб як люди-оператори, так і машинні ідентифікатори мали саме ті дозволи, які їм потрібні — і абсолютно нічого більше.
Архітектура IAM: Принципали та Політики
Розділ «Архітектура IAM: Принципали та Політики»За своєю суттю IAM покликаний відповісти на одне питання: Хто може робити що з якими ресурсами за яких умов?
Для відповіді на це AWS використовує дві основні концепції: Принципали (principals — “хто”) та Політики (policies — правила, що визначають “що”, “які ресурси” та “які умови”).
Принципали: Користувачі, Групи та Ролі
Розділ «Принципали: Користувачі, Групи та Ролі»Принципал — це сутність, яка може зробити запит на дію або операцію над ресурсом AWS. Розуміння відмінностей між трьома типами принципалів є важливим — вони не є взаємозамінними, а вибір неправильного типу є основною причиною інцидентів безпеки.
- IAM Користувачі (Users): Думайте про користувача як про конкретну людину або застосунок, якому потрібні довгострокові креденшали. Користувачі мають ім’я, пароль (для доступу до консолі) та ключі доступу (для програмного доступу через CLI/SDK). Однак створення довгострокових IAM-користувачів для людей все частіше вважається анти-патерном. Ключі доступу витікають. Паролі перевикористовуються. Сама компанія AWS тепер рекомендує IAM Identity Center для всього людського доступу.
- IAM Групи (Groups): Колекція IAM-користувачів. Групи спрощують адміністрування. Замість того, щоб приєднувати політику до десяти окремих розробників, ви приєднуєте її до групи “Розробники” і додаєте користувачів до цієї групи. Примітка: Група не є принципалом; вона не може сама робити запити. Це суто адміністративне групування. Ви не можете посилатися на групу в блоці
Principalполітики ресурсу. - IAM Ролі (Roles): Це найпотужніша та найважливіша концепція в IAM. Роля схожа на користувача тим, що це ідентифікатор із політиками дозволів, які визначають, що він може і чого не може робити. Однак, замість того, щоб бути унікально пов’язаною з однією людиною, роля призначена для прийняття (assume) будь-ким (або будь-яким сервісом), кому вона потрібна. Ролі не мають стандартних довгострокових креденшалів (паролів чи ключів доступу). Замість цього, коли ви приймаєте ролю, AWS надає вам тимчасові креденшали безпеки для вашої сесії.
Порівняння: IAM Користувачі vs Ролі vs Сервісні ролі
Розділ «Порівняння: IAM Користувачі vs Ролі vs Сервісні ролі»| Функція | IAM Користувач | IAM Роля | Сервісна роля (Service-Linked) |
|---|---|---|---|
| Креденшали | Довгострокові (пароль, ключі) | Тимчасові (STS токени, 1-12 год) | Тимчасові (керуються AWS) |
| Хто використовує | Люди, застарілі додатки | EC2, Lambda, крос-акаунт, федерація | Сервіси AWS (напр., ELB, RDS) |
| Ким створено | Вами (адмін) | Вами (адмін) | AWS (автоматично або за запитом) |
| Trust policy | Н/Д | Ви визначаєте, хто може прийняти | Визначено AWS, незмінно |
| Можна прийняти? | Ні | Так, через sts:AssumeRole | Тільки пов’язаним сервісом AWS |
| Рекомендовано для людей | Ні (використ. Identity Center) | Так (через федерацію) | Н/Д |
| Потрібна ротація | Так (ключі, паролі) | Ні (авто-ротація STS) | Ні (керується AWS) |
| Макс. тривалість сесії | Необмежено | 1-12 годин (налаштовується) | Залежить від сервісу |
Сервісні ролі (Service-Linked Roles) заслуговують на особливу увагу. Це ролі, які сервіси AWS створюють у вашому акаунті для виконання дій від вашого імені. Наприклад, коли ви створюєте Application Load Balancer, AWS автоматично створює сервісну ролю (AWSServiceRoleForElasticLoadBalancing), яка дозволяє сервісу ELB керувати мережевими інтерфейсами (ENI) та групами безпеки у вашій VPC. Ви не можете змінити їхню політику дозволів або політику довіри — обидві наперед визначені та контролюються AWS. Щоб вивести їх список:
# Список усіх сервісних ролей у вашому акаунтіaws iam list-roles --query 'Roles[?starts_with(Path, `/aws-service-role/`)].[RoleName,Arn]' --output table
# Огляд конкретної сервісної роліaws iam get-role --role-name AWSServiceRoleForElasticLoadBalancingМеханізм прийняття ролі (STS)
Розділ «Механізм прийняття ролі (STS)»AWS Security Token Service (STS) — це рушій, що стоїть за IAM-ролями. Коли сутність (наприклад, екземпляр EC2 або федеративний користувач) потребує прийняття ролі, вона робить виклик до STS (зокрема, sts:AssumeRole).
Ось що відбувається “під капотом”:
┌──────────────────────────────────────────────────────┐ │ STS: Потік AssumeRole │ └──────────────────────────────────────────────────────┘
┌─────────────┐ 1. AssumeRole(RoleARN) ┌─────────────┐ │ │ ─────────────────────────────────────────> │ │ │ Запитувач │ │ STS │ │ (EC2, Корис-│ 2. Перевірка Trust Policy │ Сервіс │ │ тувач, │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ │ Lambda) │ Чи дозволено запитувачу? │ │ │ │ │ │ │ │ 3. Повернення тимчасових креденшалів │ │ │ │ <═════════════════════════════════════════ │ │ │ │ AccessKeyId + SecretKey + Token │ │ └──────┬──────┘ (Дійсні 1-12 годин) └─────────────┘ │ │ 4. Виконання API-викликів за допомогою тимчасових креденшалів │ ▼ ┌─────────────┐ │ Цільовий │ 5. IAM оцінює Політику дозволів │ сервіс │ САМЕ РОЛІ │ AWS │ (а не початкові права запитувача) │ (S3, EC2) │ └─────────────┘Крок за кроком:
- Запитувач викликає
AssumeRole, вказуючи Amazon Resource Name (ARN) ролі, яку він хоче прийняти. - STS перевіряє Політику довіри (Trust Policy) цільової ролі (також відому як assume role policy). Ця політика визначає, хто має право приймати ролю. Якщо запитувач не вказаний у політиці довіри, запит відхиляється.
- Якщо політика довіри дозволяє це, STS генерує тимчасові, короткострокові креденшали (Access Key ID, Secret Access Key та Session Token).
- Запитувач використовує ці тимчасові креденшали для наступних викликів AWS API. Ці виклики оцінюються на основі Політики дозволів (Permissions Policy), приєднаної до ролі, а не початкових дозволів запитувача.
// Приклад Trust Policy: Тільки екземпляри EC2 можуть приймати цю ролю{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ]}Існує кілька варіантів AssumeRole для різних сценаріїв федерації:
| Виклик STS API | Сценарій використання | Джерело креденшалів |
|---|---|---|
AssumeRole | Крос-акаунт доступ, рольові ланцюжки | Існуючі креденшали AWS |
AssumeRoleWithSAML | SAML 2.0 федерація (Okta, Azure AD) | SAML assertion від IdP |
AssumeRoleWithWebIdentity | Федерація веб-ідентичності (Cognito, OIDC) | Токен від веб-IdP |
GetSessionToken | Доступ до API із захистом MFA | Креденшали IAM-користувача + MFA токен |
GetFederationToken | Власний брокер ідентифікації | Креденшали IAM-користувача |
Подивимося на це в дії через CLI:
# Перевірка, хто ви заразaws sts get-caller-identity
# Прийняття ролі та захоплення тимчасових креденшалівCREDS=$(aws sts assume-role \ --role-arn arn:aws:iam::123456789012:role/MyRole \ --role-session-name my-session \ --duration-seconds 3600 \ --query 'Credentials')
# Розбір та експорт тимчасових креденшалівexport AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r '.AccessKeyId')export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r '.SecretAccessKey')export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r '.SessionToken')
# Перевірка, що ви тепер працюєте від імені прийнятої роліaws sts get-caller-identity# Вивід покаже ARN ролі та ім'я сесії
# По завершенню скасуйте змінні, щоб повернутися до початкової ідентичностіunset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKENIAM Політики: Анатомія авторизації
Розділ «IAM Політики: Анатомія авторизації»Політики — це JSON-документи, які визначають дозволи. Коли принципал робить запит до AWS, двигун оцінки IAM переглядає всі застосовні політики, щоб визначити, чи слід дозволити або заборонити запит.
Керовані vs. Вбудовані політики
Розділ «Керовані vs. Вбудовані політики»- AWS Managed Policies (Керовані AWS): Створені та підтримувані AWS (наприклад,
AdministratorAccess,AmazonS3ReadOnlyAccess). Вони зручні, але часто порушують принцип найменших привілеїв, оскільки розраховані на широкі сценарії використання. AWS оновлює їх при виході нових сервісів або дій. - Customer Managed Policies (Керовані клієнтом): Окремі політики, створені та керовані вами у вашому акаунті AWS. Ви можете приєднувати їх до кількох користувачів, груп або ролей. Це рекомендований підхід для повторного використання та контролю версій. Ви можете мати до 5 версій такої політики, що дозволяє відкотитися, якщо зміна спричинила проблеми.
- Inline Policies (Вбудовані): Політики, вбудовані безпосередньо в одного користувача, групу або ролю. Вони підтримують суворе співвідношення 1-до-1. Використовуйте їх лише тоді, коли хочете гарантувати, що політика не буде випадково приєднана до іншої сутності.
# Список усіх політик, керованих AWS (їх сотні)aws iam list-policies --scope AWS --query 'Policies[].PolicyName' --output table
# Список ваших власних керованих політикaws iam list-policies --scope Local --output table
# Перегляд JSON керованої політики (потрібен ID версії)aws iam get-policy-version \ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \ --version-id v1
# Список вбудованих політик на роліaws iam list-role-policies --role-name MyRole
# Отримання JSON вбудованої політикиaws iam get-role-policy --role-name MyRole --policy-name MyInlinePolicyСтруктура документа політики
Розділ «Структура документа політики»Кожна інструкція політики IAM вимагає кількох ключових елементів: Effect, Action та Resource.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowS3ReadAccess", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-company-data-bucket", "arn:aws:s3:::my-company-data-bucket/*" ], "Condition": { "IpAddress": { "aws:SourceIp": "192.0.2.0/24" } } } ]}- Version: Завжди використовуйте
"2012-10-17". Це поточна версія мови політик. Старіша версія"2008-10-17"не підтримує змінні політик, як-от${aws:username}, та деякі оператори умов. Немає причин використовувати її. - Sid (Statement ID, опційно): Людиночитана мітка для інструкції. Корисна для відлагодження, коли політика має багато інструкцій.
- Effect: Або
Allow(Дозволити), абоDeny(Заборонити). (За замовчуванням — Deny). - Action: Конкретні API-виклики, які дозволяються або обмежуються (наприклад,
ec2:StartInstances,dynamodb:PutItem). Підтримуються маски:s3:Get*відповідає всім діям S3 Get. - Resource: Конкретні сутності AWS, до яких застосовується дія, визначені їхнім ARN. Використання
*тут небезпечне — це означає “кожен ресурс цього типу в акаунті”. - Condition (Умова, опційно): Правила, що визначають, коли політика діє (наприклад, тільки якщо запит надходить із певної IP-адреси або за наявності MFA).
Розуміння формату ARN
Розділ «Розуміння формату ARN»ARN (Amazon Resource Names) — це спосіб, за допомогою якого AWS унікально ідентифікує кожен ресурс. Розуміння їхнього формату критичне для написання політик із обмеженою областю дії:
arn:partition:service:region:account-id:resource-type/resource-id
Приклади:arn:aws:s3:::my-bucket # Багет S3 (без регіону/акаунта - глобальний)arn:aws:s3:::my-bucket/* # Усі об'єкти ВСЕРЕДИНІ бакетаarn:aws:ec2:us-east-1:123456789012:instance/i-abc123 # Конкретний екземпляр EC2arn:aws:iam::123456789012:user/alice # IAM-користувач (без регіону - глобальний)arn:aws:lambda:eu-west-1:123456789012:function:my-func # Lambda функціяТипова помилка: для S3 вам потрібні два записи ресурсів — один для самого бакета (для ListBucket) і один для об’єктів у ньому (для GetObject, PutObject). ARN бакета та ARN об’єкта — це різні ресурси.
Потужні ключі умов (Condition Keys)
Розділ «Потужні ключі умов (Condition Keys)»Умови — це те, де політики IAM стають справді потужними. Ось найкорисніші ключі умов:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "RequireMFAForDelete", "Effect": "Deny", "Action": ["s3:DeleteObject", "s3:DeleteBucket"], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } }, { "Sid": "RestrictToOrgOnly", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::shared-data/*", "Condition": { "StringEquals": { "aws:PrincipalOrgID": "o-abc123def4" } } }, { "Sid": "EnforceEncryptedTransport", "Effect": "Deny", "Action": "s3:*", "Resource": "arn:aws:s3:::secure-bucket/*", "Condition": { "Bool": { "aws:SecureTransport": "false" } } }, { "Sid": "RestrictByTag", "Effect": "Allow", "Action": "ec2:StopInstances", "Resource": "*", "Condition": { "StringEquals": { "ec2:ResourceTag/Environment": "development" } } } ]}Ключові оператори умов, які варто знати:
| Оператор | Сценарій використання |
|---|---|
StringEquals | Точна відповідність рядка (чутливо до регістру) |
StringLike | Співставлення з масками (*, ?) |
ArnLike / ArnEquals | Співставлення патернів ARN |
IpAddress / NotIpAddress | Обмеження за діапазоном вихідних IP |
DateGreaterThan / DateLessThan | Вікна доступу за часом |
Bool | Булеві умови (aws:SecureTransport, aws:MultiFactorAuthPresent) |
NumericLessThan | Числові порівняння (напр., макс. тривалість сесії) |
Логіка оцінки політики
Розділ «Логіка оцінки політики»Логіка оцінки IAM сувора і слідує чітко визначеному порядку для кожного окремого API-запиту. Розуміння цього потоку є необхідним для відлагодження проблем із доступом.
┌──────────────────────────────────────────────────────────────────────┐ │ Потік оцінки політик IAM │ │ (Запит у межах одного акаунта) │ └──────────────────────────────────────────────────────────────────────┘
Надходить API-запит │ ▼ ┌─────────────────┐ ТАК │ Явна ЗАБОРОНА │──────────> ВІДХИЛЕНО (фінально, не можна змінити) │ у БУДЬ-ЯКІЙ │ │ політиці? │ └────────┬────────┘ │ НІ ▼ ┌─────────────────┐ ТАК │ SCP дозволяє це? │◄──── Діє тільки якщо акаунт в AWS Org │ (якщо застосовно)│ └────────┬────────┘ │ ТАК (або Н/Д) ▼ ┌─────────────────┐ НІ │ Політика ресурсу │──────────┐ │ дозволяє? │ │ └────────┬────────┘ │ │ ТАК │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ ДОЗВОЛЕНО │ │ Політика ідентич-│ НІ │ (якщо той самий │ │ ності дозволяє? │──────> ВІДХИЛЕНО (неявно) │ акаун і пол. рес.│ └────────┬────────┘ │ має явне Allow) │ │ ТАК └─────────────────┘ ▼ ┌─────────────────┐ │ Межа дозволів │ НІ │ (Boundary) дозв? │──────> ВІДХИЛЕНО (неявно) └────────┬────────┘ │ ТАК ▼ ┌─────────────────┐ │ Політика сесії │ НІ │ дозволяє? │──────> ВІДХИЛЕНО (неявно) │ (якщо застосовно)│ └────────┬────────┘ │ ТАК ▼ ДОЗВОЛЕНОЧотири ключові правила:
- Заборона за замовчуванням (Default Deny): За замовчуванням усі запити відхиляються. Доступ має бути наданий явно.
- Явна заборона (Explicit Deny): Рушій оцінює всі політики. Якщо хоча б одна інструкція відповідає запиту і має
EffectякDeny, запит негайно відхиляється. Явна заборона завжди переважає над Дозволом. Жодна кількість інструкцій Allow ніде не може її скасувати. - Явний дозвіл (Explicit Allow): Якщо явної заборони не знайдено, рушій шукає явну інструкцію
Allow. Якщо її знайдено (і вона проходить усі перевірки меж/SCP), запит виконується. - Неявна заборона (Implicit Deny): Якщо рушій завершив оцінку всіх політик і не знайшов ні явної заборони, ні явного дозволу, запит відхиляється (повертаючись до заборони за замовчуванням).
Повчальна історія: Команда три дні шукала причину, чому їхній конвеєр Jenkins не міг записати дані в S3-бакет. Вони приєднали політику, що надавала s3:PutObject IAM-ролі Jenkins. Вони перевірили політики бакета та ACL. Все виглядало ідеально. Виявилося, що хтось застосував SCP (Service Control Policy) на рівні AWS Organizations, яка явно забороняла всі записи в S3 за межами регіону us-east-1, а Jenkins працював у us-west-2. Оскільки Explicit Deny переважає всі дозволи, локальні права IAM-ролі не мали значення.
Крос-акаунт оцінка: Інший звір
Розділ «Крос-акаунт оцінка: Інший звір»Коли запитувач і ресурс знаходяться в різних акаунтах AWS, логіка оцінки змінюється. Обидві сторони повинні надати доступ:
- Політика на основі ідентичності в акаунті запитувача повинна дозволяти дію.
- Політика на основі ресурсу на цільовому ресурсі також повинна дозволяти доступ принципалу запитувача.
Думайте про це як про візит до іншої країни: вам потрібна і виїзна віза (дозвіл вашого акаунта), і в’їзна віза (дозвіл власника ресурсу). Якщо будь-яка сторона каже “ні”, доступ заборонено.
# Приклад: Політика бакета, що дозволяє крос-акаунт доступ# (застосовується до бакета в Акаунті Б)cat << 'EOF'{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCrossAccountRead", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111111111111:role/AppRole" }, "Action": ["s3:GetObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::account-b-bucket", "arn:aws:s3:::account-b-bucket/*" ] } ]}EOFВикористання IAM Policy Simulator
Розділ «Використання IAM Policy Simulator»Перед розгортанням політик у продакшн завжди тестуйте їх. IAM Policy Simulator дозволяє перевірити, чи буде дозволена або заборонена певна дія для принципала:
# Симуляція того, чи може роля виконувати s3:GetObjectaws iam simulate-principal-policy \ --policy-source-arn arn:aws:iam::123456789012:role/MyAppRole \ --action-names s3:GetObject \ --resource-arns arn:aws:s3:::my-bucket/data.csv
# Симуляція кількох дій одночасноaws iam simulate-principal-policy \ --policy-source-arn arn:aws:iam::123456789012:role/MyAppRole \ --action-names s3:GetObject s3:PutObject s3:DeleteObject \ --resource-arns "arn:aws:s3:::my-bucket/*"
# Симуляція кастомного документа політики (перед його приєднанням)aws iam simulate-custom-policy \ --policy-input-list file://my-new-policy.json \ --action-names ec2:DescribeInstances ec2:TerminateInstances \ --resource-arns "*"Сучасна ідентифікація: IAM Identity Center та Межі дозволів
Розділ «Сучасна ідентифікація: IAM Identity Center та Межі дозволів»У міру масштабування організацій управління окремими IAM-користувачами в десятках акаунтів AWS стає жахом для безпеки та адміністративним “вузьким місцем”.
AWS IAM Identity Center (раніше AWS SSO)
Розділ «AWS IAM Identity Center (раніше AWS SSO)»IAM Identity Center — це сучасний наступник стандартних IAM-користувачів. Замість створення користувачів безпосередньо в AWS, ви підключаєте AWS до зовнішнього постачальника ідентифікації (IdP), такого як Okta, Azure AD або Google Workspace.
Користувачі входять у портал за допомогою своїх стандартних корпоративних креденшалів. Портал показує їм акаунти та ролі AWS, до яких вони мають доступ. При натисканні на ролю Identity Center використовує SAML-федерацію для безшовного виклику sts:AssumeRoleWithSAML, перекидаючи користувача безпосередньо в консоль AWS (або надаючи короткострокові CLI креденшали) без створення постійного IAM-користувача в AWS.
Чому це важливо для інженерів Kubernetes: якщо ви запускаєте EKS, Identity Center інтегрується з aws eks get-token для надання короткострокових креденшалів для доступу до kubectl. Більше ніяких спільних kubeconfig-файлів із вбудованими довгостроковими токенами.
# Налаштування AWS CLI для використання Identity Center (одноразове налаштування)aws configure sso# Слідуйте підказкам: SSO start URL, SSO Region, account, role
# Вхід та отримання тимчасових креденшалівaws sso login --profile my-sso-profile
# Використовуйте профіль для всіх наступних командaws s3 ls --profile my-sso-profileaws eks update-kubeconfig --name my-cluster --profile my-sso-profileМежі дозволів (Permission Boundaries)
Розділ «Межі дозволів (Permission Boundaries)»Як дозволити розробникам створювати власні IAM-ролі (для приєднання до їхніх Lambda-функцій або екземплярів EC2), не даючи їм можливості надати собі доступ адміністратора?
Межі дозволів (Permission Boundaries) вирішують цю проблему підвищення привілеїв. Межа дозволів — це просунута функція IAM, де ви використовуєте керовану політику для встановлення максимальних дозволів, які політика на основі ідентичності може надати сутності IAM.
Думайте про це як про паркан навколо ігрового майданчика. Діти (розробники) можуть грати де завгодно всередині паркану, але паркан (межа) заважає їм вибігти на вулицю (продакшн бази даних, білінг, адміністрування IAM).
Уявіть, що розробник хоче створити ролю для Lambda-функції. Ви надаєте розробнику дозвіл iam:CreateRole, але додаєте Умову: вони мусять приєднати конкретну політику межі дозволів (наприклад, Boundary-Developer-Max-Access) до будь-якої ролі, яку вони створюють.
Якщо Boundary-Developer-Max-Access дозволяє S3 та DynamoDB, але забороняє EC2, то навіть якщо розробник приєднає AdministratorAccess до своєї нової Lambda-ролі, фактичні дозволі будуть обмежені лише S3 та DynamoDB. Межа обмежує максимально можливу стелю доступу.
// Політика, приєднана до розробника: вони можуть створювати ролі, але МУСЯТЬ// приєднати межу. Без умови межі вони могли б// підвищити привілеї, створивши ролю адміністратора.{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCreateRoleWithBoundary", "Effect": "Allow", "Action": "iam:CreateRole", "Resource": "*", "Condition": { "StringEquals": { "iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/Boundary-Developer-Max-Access" } } }, { "Sid": "DenyRemovingBoundary", "Effect": "Deny", "Action": [ "iam:DeleteRolePermissionsBoundary", "iam:PutRolePermissionsBoundary" ], "Resource": "*" } ]}# Створення ролі з межею дозволівaws iam create-role \ --role-name LambdaDataProcessorRole \ --assume-role-policy-document file://lambda-trust.json \ --permissions-boundary arn:aws:iam::123456789012:policy/Boundary-Developer-Max-Access
# Перевірка, яка межа приєднана до роліaws iam get-role --role-name LambdaDataProcessorRole \ --query 'Role.PermissionsBoundary'Service Control Policies (SCP): Обмежувачі для організацій
Розділ «Service Control Policies (SCP): Обмежувачі для організацій»Якщо межі дозволів — це паркани для окремих ідентичностей, то Service Control Policies (SCP) — це стіни навколо цілих акаунтів AWS. SCP є функцією AWS Organizations і визначають максимально доступні дозволи для всіх принципалів у дочірньому акаунті.
SCP не надають дозволів — вони лише обмежують. Навіть root-користувач дочірнього акаунта обмежений дією SCP.
Типові патерни SCP:
// Заборонити всі дії за межами дозволених регіонів{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyNonApprovedRegions", "Effect": "Deny", "Action": "*", "Resource": "*", "Condition": { "StringNotEquals": { "aws:RequestedRegion": ["us-east-1", "eu-west-1"] }, "ArnNotLike": { "aws:PrincipalARN": "arn:aws:iam::*:role/OrganizationAdmin" } } } ]}# Список SCP у вашій організаціїaws organizations list-policies --filter SERVICE_CONTROL_POLICY
# Перегляд контенту SCPaws organizations describe-policy --policy-id p-abc123def4Найкращі практики IAM: Принцип найменших привілеїв у дії
Розділ «Найкращі практики IAM: Принцип найменших привілеїв у дії»Найменші привілеї — це не одноразова акція. Це безперервний процес надання мінімально необхідних дозволів, моніторингу реального використання та подальшого обмеження.
Крок 1: Починайте з нуля і додавайте
Розділ «Крок 1: Починайте з нуля і додавайте»Ніколи не починайте з широких дозволів із планом обмежити їх пізніше — ви цього не зробите. Починайте з нульових дозволів і додавайте тільки те, без чого система не працює.
Крок 2: Використовуйте IAM Access Analyzer
Розділ «Крок 2: Використовуйте IAM Access Analyzer»AWS надає інструменти для корекції дозволів на основі реальної активності CloudTrail:
# Генерація політики на основі реальних API-викликів, зроблених роллю# (вимагає увімкненого логування CloudTrail)aws accessanalyzer start-policy-generation \ --policy-generation-details '{ "principalArn": "arn:aws:iam::123456789012:role/MyAppRole", "cloudTrailDetails": { "trailArn": "arn:aws:cloudtrail:us-east-1:123456789012:trail/my-trail", "startTime": "2025-01-01T00:00:00Z", "endTime": "2025-03-01T00:00:00Z" } }'
# Пошук невикористаного доступу (ролі, ключі, дозволи)aws accessanalyzer list-findings \ --analyzer-arn arn:aws:accessanalyzer:us-east-1:123456789012:analyzer/my-analyzer
# Перевірка, коли ключ доступу використовувався востаннєaws iam get-access-key-last-used --access-key-id AKIAIOSFODNN7EXAMPLE
# Список усіх користувачів та їхньої останньої активностіaws iam generate-credential-reportaws iam get-credential-report --query 'Content' --output text | base64 -dКрок 3: Контроль доступу на основі тегів (ABAC)
Розділ «Крок 3: Контроль доступу на основі тегів (ABAC)»Замість створення окремої політики для кожного проєкту, використовуйте теги для створення динамічних, масштабованих політик:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowActionsOnOwnResources", "Effect": "Allow", "Action": ["ec2:StartInstances", "ec2:StopInstances"], "Resource": "*", "Condition": { "StringEquals": { "aws:ResourceTag/Project": "${aws:PrincipalTag/Project}" } } } ]}Ця єдина політика працює для кожної команди. Якщо Аліса має тег Project: payments, а Боб — Project: search, кожен із них зможе керувати лише тими EC2-екземплярами, що мають тег відповідного проєкту. Оновлення політик при створенні нового проєкту не потрібне.
Чи знали ви?
Розділ «Чи знали ви?»- Система AWS IAM обробляє понад півмільярда API-викликів на секунду по всьому світу, оцінюючи складні JSON-політики за мілісекунди без помітної затримки запитів. Це робить її однією з найпродуктивніших систем авторизації, коли-небудь побудованих.
- IAM — це глобально розподілений сервіс. Однак, оскільки він значною мірою покладається на “eventual consistency” (узгодженість у кінцевому підсумку), зміни в політиках IAM іноді можуть займати хвилину-дві, щоб поширитися на всі ендпоінти AWS по всьому світу. Ось чому ви можете створити ролю і негайно отримати “AccessDenied” при спробі її використати — зміна ще не поширилася. Вирішенням є коротке повторення спроби з експоненціальною витримкою (exponential backoff).
- Ви можете використовувати ключ умови
aws:PrincipalOrgIDу політиці ресурсу (наприклад, політиці бакета S3), щоб миттєво обмежити доступ лише принципалами, що походять з акаунтів вашої конкретної організації AWS, створюючи потужний рівень ешелонованого захисту. Цей єдиний ключ замінює необхідність перелічувати ID кожного акаунта окремо. - Максимальний розмір документа політики IAM становить 6 144 символи для вбудованих політик та 6 144 символи на версію для керованих політик. Це може здатися великим обсягом, поки ви не почнете писати детальні політики для складних додатків. При досягненні цього ліміту рішенням є розділення на кілька політик (до 10 керованих політик на ролю) або стратегічне використання масок (wildcards). Ви також можете використовувати змінні політик, як-от
${aws:username}, щоб зменшити повторення.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це стається | Як виправити |
|---|---|---|
Надмірне використання Resource: "*" | Це простіше, ніж шукати точний ARN, особливо коли треба швидко запустити скрипт. | Завжди обмежуйте політики конкретними необхідними ARN. Використовуйте теги та ключі умов, якщо ARN динамічні. Перевіряйте через aws iam simulate-principal-policy. |
| Створення IAM-користувачів для додатків | Передача ключів доступу в додатки здається природною для розробників, звиклих до рядків підключення БД. | Завжди використовуйте IAM-ролі (через EC2 Instance Profiles, EKS IRSA/Pod Identity або Lambda execution roles) для надання тимчасових креденшалів обчислювальним ресурсам. |
| Ігнорування політики довіри (Trust Policy) | Команди фокусуються на тому, що роля може робити (Permissions Policy), і забувають захистити те, хто може її прийняти (Trust Policy). | Ретельно перевіряйте політики довіри. Ніколи не використовуйте Principal: "*" у політиці довіри, якщо це не вкрай необхідно і не захищено потужними блоками Condition (напр., sts:ExternalId). |
| Відсутність ротації ключів доступу | Люди з постійними ключами тримають їх роками, бо “вони працюють”, а ротація вимагає оновлення локальних файлів .aws/credentials. | Впроваджуйте примусову ротацію ключів через правила AWS Config. А ще краще — повністю відмовтеся від постійних ключів, перейшовши на IAM Identity Center для доступу через CLI. |
| Тестування дозволів у продакшні | Розробники змінюють JSON-політики прямо в консолі, поки помилка не зникне, часто надаючи при цьому надмірні права. | Використовуйте IAM Policy Simulator (aws iam simulate-principal-policy). Аналізуйте логи AWS CloudTrail, щоб побачити, який саме виклик не вдався і чому, а потім надавайте дозвіл тільки на цю дію. |
| Нерозуміння неявної vs явної заборони | Віра в те, що видалення інструкції Allow активно запобігає дії, забуваючи, що інша політика все ще може її дозволяти. | Розумійте, що для доступу потрібен явний Allow і ВІДСУТНІСТЬ явної заборони (Deny) будь-де в ланцюжку оцінки (політики ідентичності, ресурсу, межі, SCP). |
| Забудькуватість про подвійний ARN у S3 | Надання s3:GetObject на ARN бакета (без /*) або s3:ListBucket на ARN об’єктів (з /*). | Пам’ятайте: ListBucket діє на бакет (arn:aws:s3:::bucket), GetObject/PutObject діють на об’єкти (arn:aws:s3:::bucket/*). Завжди включайте обидва записи ресурсів. |
| Невикористання сесійних тегів або ExternalId для третіх сторін | Сліпа довіра крос-акаунт прийняттю ролі, бо “вендор сказав налаштувати саме так”. | Завжди вимагайте sts:ExternalId у політиках довіри для доступу третіх сторін. Без цього ви вразливі до атаки Confused Deputy. Генеруйте унікальний випадковий ExternalId для кожного вендора. |
Тест
Розділ «Тест»Питання 1: У вас є IAM-роля, приєднана до екземпляра EC2. Політика ролі явно дозволяє `s3:GetObject` для `arn:aws:s3:::financial-reports/*`. Проте екземпляр EC2 отримує помилку Access Denied при спробі завантажити файл. Розробник зауважує, що на бакеті `financial-reports` є S3 Bucket Policy. Що повинна містити політика бакета, щоб завантаження було успішним?
Відповідь: Політика бакета не обов’язково повинна щось містити для дозволу дії, але вона НЕ ПОВИННА містити явну заборону (Explicit Deny) для цієї ролі або дії. Оскільки IAM-роля вже надає явний Allow, логіка оцінки дозволяє дію, поки жодна політика ресурсу (Bucket Policy) або організаційна політика (SCP) явно її не забороняє. Якщо бакет і екземпляр EC2 знаходяться в одному акаунті, достатньо лише політики IAM.
Однак, якби це був сценарій крос-акаунт доступу (EC2 в Акаунті А, бакет в Акаунті Б), то політика бакета в Акаунті Б повинна була б явно дозволити роль EC2 з Акаунта А, оскільки крос-акаунт доступ вимагає дозволу з обох сторін.
Питання 2: У чому полягає основна перевага безпеки використання IAM-ролі замість IAM-користувача для додатка, що працює в AWS?
Відповідь: IAM-ролі використовують тимчасові креденшали безпеки, які динамічно генеруються STS. Термін дії цих креденшалів закінчується автоматично (зазвичай через 1 годину, налаштовується до 12 годин). Якщо зловмиснику вдасться викрасти ці тимчасові креденшали, його “вікно можливостей” вкрай обмежене, і креденшали не можна буде використати після закінчення терміну. IAM-користувачі покладаються на довгострокові ключі доступу, які залишаються дійсними нескінченно довго, поки не будуть вручну змінені або видалені, що створює набагато більший радіус ураження при компрометації. Крім того, креденшали ролі автоматично ротуються SDK — додатку ніколи не потрібно керувати логікою ротації.
Питання 3: Розробник хоче надати вендору доступ до S3-бакета у вашому акаунті. Вендор має власний акаунт AWS. Чи варто вам створити IAM-користувача у вашому акаунті для вендора, чи налаштувати крос-акаунт доступ через ролю?
Відповідь: Вам слід налаштувати крос-акаунт доступ через ролю. Ви створюєте ролю у вашому акаунті з політикою довіри, яка дозволяє акаунту вендора (або конкретній ролі в їхньому акаунті) приймати її, разом із обов’язковою умовою sts:ExternalId. Користувачі вендора автентифікуються у своєму акаунті, а потім викликають AssumeRole для доступу до ваших ресурсів. Це позбавляє вас необхідності керувати життєвим циклом, паролями, MFA та ротацією ключів зовнішніх користувачів. Коли стосунки з вендором закінчуються, ви просто видаляєте ролю — жодних “осиротілих” креденшалів.
Питання 4: Ви застосували межу дозволів (Permission Boundary) до IAM-користувача. Політика межі дозволяє `ec2:*` та `s3:*`. Приєднана політика дозволів користувача дозволяє `s3:*` та `rds:*`. Які фактичні дозволи має користувач?
Відповідь: Фактичний дозвіл користувача — тільки s3:*. Фактичні дозволи — це перетин межі дозволів та політики ідентичності. Межа дозволяє EC2, але політика ідентичності його не надає. Політика ідентичності надає RDS, але межа його не дозволяє. Тільки S3 фігурує в обох політиках, тому дозволені лише дії S3.
Межа дозволів: { ec2:*, s3:* } Політика ідентичності: { s3:*, rds:* } ────────────────────────────────────── Фактично: { s3:* } (перетин)Питання 5: Яка мета параметра `ExternalId` при налаштуванні крос-акаунт прийняття ролі для стороннього SaaS-провайдера?
Відповідь: ExternalId запобігає проблемі “Confused Deputy” (заплутаного заступника). Якщо багато клієнтів використовують той самий сторонній SaaS, зловмисник, який також є клієнтом, міг би змусити систему SaaS-провайдера прийняти IAM-ролю вашого акаунта, вказавши ваш Role ARN (який можна вгадати). Вимагаючи унікальний ExternalId (який ви генеруєте і налаштовуєте як у порталі SaaS, так і у вашій Trust Policy), ви гарантуєте, що SaaS-провайдер приймає вашу ролю тільки тоді, коли діє саме від вашого імені. Зловмисник не може вгадати ваш ExternalId, тому навіть якщо він надасть ваш Role ARN, умова політики довіри не буде виконана.
Питання 6: Акаунт є частиною AWS Organizations. SCP на акаунті забороняє `ec2:TerminateInstances`. IAM-роля в цьому акаунті має приєднану політику з `Allow` на `ec2:*`. Чи може роля видаляти екземпляри?
Відповідь: Ні. Service Control Policies визначають максимальні дозволи, доступні в акаунті. Навіть якщо політика IAM явно дозволяє ec2:*, SCP явно забороняє ec2:TerminateInstances. Явна заборона в SCP переважає будь-який дозвіл у політиці ідентичності. Насправді, навіть root-користувач акаунта не може обійти SCP (за винятком кількох специфічних дій, як-от закриття акаунта). SCP є найвищим обмежувачем у ланцюжку авторизації.
Питання 7: Lambda-функція повинна читати з DynamoDB і писати в чергу SQS. Молодший інженер створює IAM-користувача, генерує ключі доступу і жорстко прописує їх у змінних оточення Lambda. Назвіть принаймні три помилки в цьому підході.
Відповідь:
- Довгострокові креденшали: Ключі доступу IAM-користувача ніколи не закінчуються автоматично. Якщо вони витечуть (наприклад, у логах CloudWatch або коміті), вони залишаться дійсними до ручного видалення.
- Захардкоджені секрети: Вбудовування креденшалів у змінні оточення (або, що ще гірше, у вихідний код) порушує всі фреймворки безпеки. Якщо конфігурація Lambda буде експортована або залогована, ключі будуть розкриті.
- Відсутність автоматичної ротації: Ключі залишатимуться незмінними вічно, поки хтось не змінить їх вручну. Lambda має вбудований механізм (execution roles), який надає тимчасові креденшали, що автоматично ротуються.
- Неправильний тип принципала: Lambda нативно підтримує IAM-ролі через ролі виконання (execution roles). Немає жодної причини використовувати IAM-користувача. Роля виконання надає тимчасові креденшали STS функції під час виклику.
Правильний підхід: створити IAM-ролю з політикою довіри для lambda.amazonaws.com, приєднати політику дозволів з обмеженою областю дії, що дозволяє тільки dynamodb:GetItem (не dynamodb:*) та sqs:SendMessage, і призначити її як ролю виконання Lambda.
Питання 8: Чому організація може обрати використання AWS Managed Policies замість Customer Managed Policies, і в чому полягає компроміс?
Відповідь: Політики, керовані AWS (AWS Managed Policies), підтримуються та оновлюються самою компанією AWS. Коли AWS випускає новий сервіс або додає нову функцію (і нову API-дію) до існуючого сервісу, вони автоматично оновлюють відповідні керовані політики (наприклад, ReadOnlyAccess або ViewOnlyAccess). Це позбавляє адміністраторів операційних витрат на постійне оновлення власних кастомних політик у відповідь на релізи AWS.
Компроміс полягає у зменшенні контролю та потенційному наданні надмірних прав. AmazonS3FullAccess надає доступ до всіх бакетів S3 в акаунті. PowerUserAccess надає доступ майже до всього, крім управління IAM. Ці широкі дозволи порушують принцип найменших привілеїв. Рекомендований підхід — використовувати власні керовані політики (customer managed policies) для продакшн-навантажень, а політики від AWS залишати для швидкого прототипування або ролей аудиту “тільки для читання”.
Практична вправа: Мульти-акаунт IAM та найменші привілеї
Розділ «Практична вправа: Мульти-акаунт IAM та найменші привілеї»У цій вправі ми симулюємо сценарій, де додаток, що працює в середовищі “Development”, повинен зчитувати дані конфігурації з централізованого середовища “Shared Services”. Ми використаємо дві IAM-ролі в межах одного акаунта, щоб симулювати крос-акаунт межу та попрактикуватися в механіці AssumeRole через CLI.
Що ви будете практикувати:
- Створення ролей із кастомними політиками довіри
- Написання політик дозволів з обмеженою областю дії (найменші привілеї)
- Використання STS для прийняття ролі та отримання тимчасових креденшалів
- Перевірку роботи принципу найменших привілеїв (дозволені дії проходять, решта — ні)
- Використання меж дозволів (Permission Boundaries) для обмеження підвищення привілеїв
- Очищення всіх ресурсів
Завдання 1: Налаштування змінних оточення
Розділ «Завдання 1: Налаштування змінних оточення»# Отримайте ID свого акаунта (він знадобиться протягом вправи)export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)echo "Account ID: $ACCOUNT_ID"
# Встановіть унікальне ім'я бакетаexport CONFIG_BUCKET="dojo-shared-config-$(date +%s)"echo "Bucket name: $CONFIG_BUCKET"
# Перевірте вашу поточну ідентичністьaws sts get-caller-identityЗавдання 2: Створення джерела даних (бакета S3)
Розділ «Завдання 2: Створення джерела даних (бакета S3)»Спочатку створимо бакет, який буде нашим централізованим сховищем конфігурацій.
# Створення бакетаaws s3 mb s3://$CONFIG_BUCKET
# Створення прикладів файлів конфігурації та їх завантаженняecho '{"db_port": 5432, "api_endpoint": "api.internal.local"}' > config.jsonecho '{"secret": "do-not-read-this"}' > secret.json
aws s3 cp config.json s3://$CONFIG_BUCKET/app/config.jsonaws s3 cp secret.json s3://$CONFIG_BUCKET/secrets/secret.json
# Перевірка завантаженняaws s3 ls s3://$CONFIG_BUCKET --recursiveЗавдання 3: Створення цільової ролі (ролі, яку будемо приймати)
Розділ «Завдання 3: Створення цільової ролі (ролі, яку будемо приймати)»Ця роля представляє дозволи, необхідні в акаунті Shared Services. Ми приєднаємо сувору політику, що дозволяє доступ на читання тільки до префікса app/ у цьому конкретному бакеті — не до префікса secrets/.
# 1. Створення документа політики довіри, що дозволяє вашій поточній ідентичності приймати ролюcat << EOF > trust-policy.json{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::${ACCOUNT_ID}:root" }, "Action": "sts:AssumeRole" } ]}EOF
# Перевірте, чи виглядає політика довіри правильноcat trust-policy.json | jq .
# 2. Створення роліaws iam create-role \ --role-name DojoSharedConfigReaderRole \ --assume-role-policy-document file://trust-policy.json
# 3. Створення політики дозволів із суворо обмеженою областю дії# Примітка: ми дозволяємо читання тільки з префікса app/*, НЕ secrets/*cat << EOF > permissions-policy.json{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowListBucket", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::${CONFIG_BUCKET}", "Condition": { "StringLike": { "s3:prefix": ["app/*"] } } }, { "Sid": "AllowReadAppConfig", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::${CONFIG_BUCKET}/app/*" } ]}EOF
# Перевірте політику дозволівcat permissions-policy.json | jq .
# 4. Приєднання вбудованої політики до роліaws iam put-role-policy \ --role-name DojoSharedConfigReaderRole \ --policy-name S3ConfigReadAccess \ --policy-document file://permissions-policy.json
# 5. Перевірка правильності створення роліaws iam get-role --role-name DojoSharedConfigReaderRole --query 'Role.Arn'aws iam get-role-policy --role-name DojoSharedConfigReaderRole --policy-name S3ConfigReadAccessЗавдання 4: Прийняття ролі через CLI
Розділ «Завдання 4: Прийняття ролі через CLI»Тепер уявіть, що ви — додаток. Вам потрібно викликати STS, щоб отримати тимчасові креденшали для DojoSharedConfigReaderRole.
# Отримання ARN роліROLE_ARN=$(aws iam get-role --role-name DojoSharedConfigReaderRole --query 'Role.Arn' --output text)echo "Assuming role: $ROLE_ARN"
# Прийняття ролі через STS (запит сесії на 1 годину)aws sts assume-role \ --role-arn $ROLE_ARN \ --role-session-name AppConfigSession \ --duration-seconds 3600 > assume-role-output.json
# Огляд результату — зверніть увагу на поле Expirationcat assume-role-output.json | jq '.Credentials.Expiration'
# Вилучення та експорт тимчасових креденшалівexport AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' assume-role-output.json)export AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' assume-role-output.json)export AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' assume-role-output.json)Завдання 5: Перевірка найменших привілеїв (критичні тести)
Розділ «Завдання 5: Перевірка найменших привілеїв (критичні тести)»Тепер, коли ви працюєте від імені прийнятої ролі, перевірте, що ви можете і чого не можете робити. Кожен тест валідує певний аспект вашої політики.
# Перевірте вашу активну ідентичність (має бути прийнята роля, а не ваш початковий користувач)aws sts get-caller-identity# Очікується: "Arn" містить "assumed-role/DojoSharedConfigReaderRole/AppConfigSession"
# --- ТЕСТ 1: Читання дозволеного файлу конфігурації (МАЄ БУТИ УСПІШНИМ) ---aws s3 cp s3://$CONFIG_BUCKET/app/config.json /tmp/downloaded-config.jsoncat /tmp/downloaded-config.jsonecho "ТЕСТ 1 ПРОЙДЕНО: Успішно прочитано конфігурацію додатка"
# --- ТЕСТ 2: Список об'єктів у префіксі app/ (МАЄ БУТИ УСПІШНИМ) ---aws s3 ls s3://$CONFIG_BUCKET/app/echo "ТЕСТ 2 ПРОЙДЕНО: Успішно отримано список у префіксі app/"
# --- ТЕСТ 3: Читання секретного файлу (МАЄ НЕ ВДАТИСЯ - Access Denied) ---aws s3 cp s3://$CONFIG_BUCKET/secrets/secret.json /tmp/secret.json 2>&1 || \ echo "ТЕСТ 3 ПРОЙДЕНО: Доступ до secrets/ правильно заборонено"
# --- ТЕСТ 4: Запис у бакет (МАЄ НЕ ВДАТИСЯ - Access Denied) ---echo "hacked" > /tmp/test.txtaws s3 cp /tmp/test.txt s3://$CONFIG_BUCKET/app/test.txt 2>&1 || \ echo "ТЕСТ 4 ПРОЙДЕНО: Доступ на запис правильно заборонено"
# --- ТЕСТ 5: Доступ до зовсім іншого сервісу AWS (МАЄ НЕ ВДАТИСЯ) ---aws ec2 describe-instances 2>&1 || \ echo "ТЕСТ 5 ПРОЙДЕНО: Доступ до EC2 правильно заборонено"
# --- ТЕСТ 6: Спроба підвищити привілеї, створивши нову ролю (МАЄ НЕ ВДАТИСЯ) ---aws iam create-role --role-name HackerRole \ --assume-role-policy-document '{"Version":"2012-10-17","Statement":[]}' 2>&1 || \ echo "ТЕСТ 6 ПРОЙДЕНО: Доступ до IAM правильно заборонено"Завдання 6: Створення межі дозволів (Бонус)
Розділ «Завдання 6: Створення межі дозволів (Бонус)»Давайте також попрактикуємося у створенні межі дозволів (Permission Boundary). Спочатку поверніться до своєї початкової ідентичності.
# Повернення до початкової ідентичностіunset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKENaws sts get-caller-identity
# Створення межі дозволів, яка дозволяє тільки S3 та DynamoDBcat << EOF > boundary-policy.json{ "Version": "2012-10-17", "Statement": [ { "Sid": "BoundaryAllowS3AndDynamo", "Effect": "Allow", "Action": [ "s3:*", "dynamodb:*" ], "Resource": "*" } ]}EOF
# Створення межі як керованої політикиaws iam create-policy \ --policy-name DojoBoundaryPolicy \ --policy-document file://boundary-policy.json
BOUNDARY_ARN="arn:aws:iam::${ACCOUNT_ID}:policy/DojoBoundaryPolicy"
# Створення нової ролі З приєднаною межеюcat << EOF > bounded-trust.json{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::${ACCOUNT_ID}:root"}, "Action": "sts:AssumeRole" } ]}EOF
aws iam create-role \ --role-name DojoBoundedRole \ --assume-role-policy-document file://bounded-trust.json \ --permissions-boundary $BOUNDARY_ARN
# Приєднання політики, яка намагається надати ec2:* (межа має це заблокувати)cat << EOF > overreach-policy.json{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:*", "ec2:*", "dynamodb:*"], "Resource": "*" } ]}EOF
aws iam put-role-policy \ --role-name DojoBoundedRole \ --policy-name OverreachPolicy \ --policy-document file://overreach-policy.json
# Прийняття обмеженої ролі та тестуванняBOUNDED_ROLE_ARN=$(aws iam get-role --role-name DojoBoundedRole --query 'Role.Arn' --output text)aws sts assume-role \ --role-arn $BOUNDED_ROLE_ARN \ --role-session-name BoundaryTest > bounded-output.json
export AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' bounded-output.json)export AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' bounded-output.json)export AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' bounded-output.json)
# S3 має працювати (є і в політиці, і в межі)aws s3 ls 2>&1 && echo "BOUNDARY ТЕСТ 1: S3 дозволено (очікувано)"
# EC2 має не вдатися (є в політиці, але НЕМАЄ в межі)aws ec2 describe-instances 2>&1 || echo "BOUNDARY ТЕСТ 2: EC2 заблоковано межею (очікувано)"Очищення
Розділ «Очищення»Видаліть тимчасові креденшали з вашого оточення та видаліть усі створені ресурси.
# Видалення тимчасових креденшалів для повернення до адмін-ідентичностіunset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
# Перевірка поверненняaws sts get-caller-identity
# Видалення обмеженої ролі та її ресурсівaws iam delete-role-policy --role-name DojoBoundedRole --policy-name OverreachPolicyaws iam delete-role --role-name DojoBoundedRoleaws iam delete-policy --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/DojoBoundaryPolicy
# Видалення ролі читача конфігурацій та її ресурсівaws iam delete-role-policy --role-name DojoSharedConfigReaderRole --policy-name S3ConfigReadAccessaws iam delete-role --role-name DojoSharedConfigReaderRole
# Видалення бакета S3aws s3 rm s3://$CONFIG_BUCKET --recursiveaws s3 rb s3://$CONFIG_BUCKET
# Видалення локальних файлівrm -f trust-policy.json permissions-policy.json config.json secret.json \ assume-role-output.json boundary-policy.json bounded-trust.json \ overreach-policy.json bounded-output.json /tmp/test.txt /tmp/downloaded-config.json /tmp/secret.json
echo "Усі ресурси успішно видалено."Критерії успіху
Розділ «Критерії успіху»- Я створив ролю з кастомною політикою довіри та перевірив її через
get-role. - Я використав
sts assume-roleдля генерації тимчасових креденшалів та перевірив нову ідентичність черезget-caller-identity. - Я підтвердив, що роля може читати префікс
app/, але їй заборонено доступ до префіксаsecrets/(демонстрація обмеження на рівні шляхів). - Я підтвердив, що ролі заборонено запис у S3, і вона не має доступу до EC2 або IAM.
- Я створив межу дозволів (Permission Boundary) і перевірив, що вона обмежує фактичні дозволи до перетину межі та політики ідентичності.
- Я очистив усі ресурси (ролі, політики, бакет, локальні файли) і підтвердив повернення до початкової ідентичності.
Наступний модуль
Розділ «Наступний модуль»Готові побудувати мережевий фундамент, у якому працюватимуть ваші ідентичності? Переходьте до Модуля 1.2: VPC та основні мережі.