В официальной документации по #cross_account #s3_replication ошибки - пример указан с неполными правами в #bucket_policy для аккаунта источника:
...
Полные указаны в примере предыдущего поста. Их нужно добавить и для роли источника, особенно с учётом, если нужно менять владельца.
Потому, для простоты, можно сразу давать полные
...
"Action":["s3:ReplicateObject", "s3:ReplicateDelete"],...
Полные указаны в примере предыдущего поста. Их нужно добавить и для роли источника, особенно с учётом, если нужно менять владельца.
Потому, для простоты, можно сразу давать полные
s3:* - т.е. в приведённой ссылке на документацию по #cross_region #s3 #replication будет работать, если сделать так:{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "Full access for other account",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "s3:*" ,
"Resource": [
"arn:aws:s3:::replication-bucket",
"arn:aws:s3:::replication-bucket/*"
]
}
]
}
Аналогично сделать и в роли аккаунта источника:- Effect: Allow
Action: 's3:*'
Resource: ## destination bucket
- 'arn:aws:s3:::replication-bucket'
- 'arn:aws:s3:::replication-bucket/*'Amazon
Example 2: Configure CRR When Source and Destination
Buckets Are Owned by Different AWS Accounts - Amazon Simple Storage…
Buckets Are Owned by Different AWS Accounts - Amazon Simple Storage…
Example of configuring Amazon S3 cross-region replication (CRR) when source and destination buckets are owned by a different AWS accounts.
Для доступа к #s3 можно использовать #iam, #bucket_policy и #bucket_acl - что же лучше использовать?
Если коротко, то всегда лучше выбирать #IAM.
Когда не получается или нужен как раз #resource_based подход - выбираем #bucket_policy (без него не обойтись для случаев #cross_account).
Использовать ACL не стоит ни разу - это и старое и неудобное.
Если коротко, то всегда лучше выбирать #IAM.
Когда не получается или нужен как раз #resource_based подход - выбираем #bucket_policy (без него не обойтись для случаев #cross_account).
Использовать ACL не стоит ни разу - это и старое и неудобное.
Amazon
IAM Policies and Bucket Policies and ACLs! Oh, My! (Controlling Access to S3 Resources) | Amazon Web Services
September 11, 2023: This post has been updated. Updated on July 6, 2023: This post has been updated to reflect the current guidance around the usage of S3 ACL and to include S3 Access Points and the Block Public Access for accounts and S3 buckets. Updated…
Пример реализации #bucket_policy для нескольких #OriginAccessIdentity в одном #s3 бакете.
policyBucketFiles:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref bucketFiles
PolicyDocument:
Statement:
- Sid: Access for Cloudfront-files
Effect: Allow
Principal:
CanonicalUser: !GetAtt [originAccessIdentityBucketFiles, 'S3CanonicalUserId']
Action:
- 's3:GetObject'
Resource:
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/files/*']]
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/files_public/*']]
- Sid: Access for SwitchOver Cloudfront-files
Effect: Allow
Principal:
CanonicalUser: !Ref CanonicalUserFilesSwitchOver
Action:
- 's3:GetObject'
Resource:
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/files/*']]
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/files_public/*']]
- Sid: Access for replication account
Effect: Allow
Principal:
AWS: !Join ['',['arn:aws:iam::', !Ref AccountReplication, ':root']]
Action:
- 's3:*'
Resource:
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles ]]
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/*']]
#CloudFormation #templates #examples
policyBucketFiles:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref bucketFiles
PolicyDocument:
Statement:
- Sid: Access for Cloudfront-files
Effect: Allow
Principal:
CanonicalUser: !GetAtt [originAccessIdentityBucketFiles, 'S3CanonicalUserId']
Action:
- 's3:GetObject'
Resource:
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/files/*']]
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/files_public/*']]
- Sid: Access for SwitchOver Cloudfront-files
Effect: Allow
Principal:
CanonicalUser: !Ref CanonicalUserFilesSwitchOver
Action:
- 's3:GetObject'
Resource:
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/files/*']]
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/files_public/*']]
- Sid: Access for replication account
Effect: Allow
Principal:
AWS: !Join ['',['arn:aws:iam::', !Ref AccountReplication, ':root']]
Action:
- 's3:*'
Resource:
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles ]]
- !Join ['',['arn:aws:s3:::', !Ref bucketFiles, '/*']]
#CloudFormation #templates #examples
AWS Notes
Бывает, что, казалось бы, банальное копирование файлов в #s3 бакет: aws s3 cp ./ s3://some-bucket/files --recursive Когда это происходит из другого аккаунта, когда бакет расположен в другом регионе или с локального компьютера (между бакетами и т.п. не самые…
Спасительный флажок bucket-owner-full-control, решающий вопросы доступа в #s3 бакет для двух аккаунтов, не поможет для ситуации с тремя и более аккаунтами. Это когда файл копируется из аккаунта A в бакет аккаунта B, а после нужно расшарить это для аккаунта C (также имеющего доступ в бакет аккаунта B).
Использование
An error occurred (AccessDenied) when calling the GetObjectAcl operation: Access Denied
Хотя точно у всех есть нужные #IAM #permissions и прописаны правильные #bucket_policy в #shared_bucket.
Дело в тех же owner-ах, как и для "двух-аккаунтной" схемы, только решается много сложней. Объекты в shared-bucket имеют лишь права для этих двух аккаутов A и B, аккаунт C имеет доступ в бакет, но его нет среди owner-ов объектов, потому ничего с ними сделать не может.
Решается ситуация лишь из аккаута owner-а, т.е. из аккаунта A — при копировании нужно добавить в список owner-ов сразу все аккаунты (т.е. в т.ч. C). Обычная #aws_cli команда
my-shared-bucket — бакет в аккаунте B
--key — путь к файлу в этом бакете
--body — локальный путь к файлу (на виртуалке)
--grant-full-control id=s3-canonical-A,id=s3-canonical-B,id=s3-canonical-C — #s3_canonical аккаунтов A, B и C (именно в таком виде - через запятую без пробела, чего нет в доке, враги)
Не нужно путать S3 Сanonical ID с тем, что используется для CloudFront при доступе в непубличный бакет (S3 canonical user ID). Это уникальный ID для аккаунта, который идёт в паре с AWS ID и может быть получен с помощью
"Owner": {
"DisplayName": "my-account-A",
"ID": "d0cecf42b8a1bed065b8a1b2fdbf76c1b6acda99e0338822e3cece21a8c71058"
},
"Buckets": []
...
Это
Потому если нужно раздавать (непубличные) файлы для переменного количества аккаунтов, то #s3 не лучший способ при таком сценарии. В рекомендациях от Амазона это решается с помощью роли в аккаунте A или B, в которую должен переключиться юзер из аккаунта C для получения файла, однако такое (переключение в роль) не всегда возможно сделать в уже имеющемся ПО и библиотеках.
Использование
--acl bucket-owner-full-control не поможет и получим #error:An error occurred (AccessDenied) when calling the GetObjectAcl operation: Access Denied
Хотя точно у всех есть нужные #IAM #permissions и прописаны правильные #bucket_policy в #shared_bucket.
Дело в тех же owner-ах, как и для "двух-аккаунтной" схемы, только решается много сложней. Объекты в shared-bucket имеют лишь права для этих двух аккаутов A и B, аккаунт C имеет доступ в бакет, но его нет среди owner-ов объектов, потому ничего с ними сделать не может.
Решается ситуация лишь из аккаута owner-а, т.е. из аккаунта A — при копировании нужно добавить в список owner-ов сразу все аккаунты (т.е. в т.ч. C). Обычная #aws_cli команда
s3 cp так не умеет — нужно использовать #s3api:aws --region=us-east-1 s3api put-object --bucket my-shared-bucket --key my-bucket-dir/conf.tar.gz --body my-local-dir/conf.tar.gz --grant-full-control id=d0cecf42b8a1bed065b8a1b2fdbf76c1b6acda99e0338822e3cece21a8c71058,id=1208ecf5e61d2b67a525edee13f7667ab45d2be85b1fdb11a9338a60609ee5f9,id=780e8bdf2b68d6cc2da2cfcaa6192fac4f437190322277db24ce81ce9aa698f9Очень непростая и плохо документированная, но рабочая конструкция.
my-shared-bucket — бакет в аккаунте B
--key — путь к файлу в этом бакете
--body — локальный путь к файлу (на виртуалке)
--grant-full-control id=s3-canonical-A,id=s3-canonical-B,id=s3-canonical-C — #s3_canonical аккаунтов A, B и C (именно в таком виде - через запятую без пробела, чего нет в доке, враги)
Не нужно путать S3 Сanonical ID с тем, что используется для CloudFront при доступе в непубличный бакет (S3 canonical user ID). Это уникальный ID для аккаунта, который идёт в паре с AWS ID и может быть получен с помощью
aws s3api list-buckets
{"Owner": {
"DisplayName": "my-account-A",
"ID": "d0cecf42b8a1bed065b8a1b2fdbf76c1b6acda99e0338822e3cece21a8c71058"
},
"Buckets": []
...
Это
ID значение получаем для каждого аккаунта, который должен иметь доступ к данному файлу в shared-bucket. Если потребуется расшарить к новому аккаунту - придётся повторить процедуру для каждого файла (объекта).Потому если нужно раздавать (непубличные) файлы для переменного количества аккаунтов, то #s3 не лучший способ при таком сценарии. В рекомендациях от Амазона это решается с помощью роли в аккаунте A или B, в которую должен переключиться юзер из аккаунта C для получения файла, однако такое (переключение в роль) не всегда возможно сделать в уже имеющемся ПО и библиотеках.
Большинство сервисов для #IAM #policy не допускает использовать пробелы в "Sid", однако #s3 их разрешает, а потому можно (нужно) писать человеческие комментарии к используемым #bucket_policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Full access for Blue, Green",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789012:root",
"arn:aws:iam::234567890123:root"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
},
{
"Sid": "ReadOnly access for Dev, Stage",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::345678901234:root",
"arn:aws:iam::456789012345:root"
]
},
"Action": [
"s3:GetObject",
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}Проверочная опция --dryrun при работе с S3
Если вы боитесь или не уверены в том, что произойдёт с вашим #s3 бакетом после запуска команды aws s3 sync или aws s3 cp, то не забывайте про иногда спасительный ключик --dryrun, добавив который, увидите, как бы вы всё поломали, если бы его не добавили:
В строчках добавлено
Опция --dryrun покажет проблемы #IAM доступа (правильно ли прописаны #bucket_policy), т.е. даст такую же ошибку как и с "нормальной" командой.
Особенно --dryrun помогает, когда вы хотите залить большой объём данных в "пересекающиеся" директории важного объёмного бакета, которые после упаритесь вылавливать-исправлять (или не сможете совсем). Тут можно было бы посоветовать скопировать данные в другой бакет, но часто это многие гигабайты или просто невозможно.
В общем, --dryrun сэкономит ваши нервы и время. Даже если у бакета включено #versioning.
Если вы боитесь или не уверены в том, что произойдёт с вашим #s3 бакетом после запуска команды aws s3 sync или aws s3 cp, то не забывайте про иногда спасительный ключик --dryrun, добавив который, увидите, как бы вы всё поломали, если бы его не добавили:
aws s3 sync --dryrun ./my-folder s3://my-bucket/some-path
(dryrun) upload: my-folder/my-cert.crt to s3://my-bucket/some-path/my-cert.crt
(dryrun) upload: my-folder/my-cert.key to s3://my-bucket/some-path/my-cert.key
В строчках добавлено
(dryrun), обозначающее, что команда бы сделала без этого ключика. А так ничего не происходит.Опция --dryrun покажет проблемы #IAM доступа (правильно ли прописаны #bucket_policy), т.е. даст такую же ошибку как и с "нормальной" командой.
Особенно --dryrun помогает, когда вы хотите залить большой объём данных в "пересекающиеся" директории важного объёмного бакета, которые после упаритесь вылавливать-исправлять (или не сможете совсем). Тут можно было бы посоветовать скопировать данные в другой бакет, но часто это многие гигабайты или просто невозможно.
В общем, --dryrun сэкономит ваши нервы и время. Даже если у бакета включено #versioning.
S3 bucket ACL cross-account access
С одной стороны, многим, если не большинству, кто ходил больше раза в амазоновскую консоль, знакома закладка Access Control List в разделе Permissions.
С другой стороны, многим, если не большинству, даже из тех, кто потыкался и попытался разобраться, так и осталось тайной, что она в реальности собой представляет и как там что-то работает. Потому что погуглив получение Canonical ID и попыташись с помощью него расшарить доступ в бакет из другого аккаунта - наверняка ничего не работало.
Понятной документации не так много, т.к. во всей новой не рекомендуется использовать ACL, а пользоваться для этого (кросс-аккаунта, да и всего прочего) Bucket Policy и IAM.
Но оно ж там ещё почему-то есть! Если бы не работало, убрали бы, наверное.
Ларчик открывается просто. Если у вас не заработало, значит вы честно выполняли рекомендации бестпрактиксов и делали это не из-под root-юзера, т.е. логинились в консоль как обычный IAM-юзер. А для того, чтобы эти артефакты работали и работали как надо - требуются руты и только руты.
Т.е. работать и логиниться в консоль для работы с ACL нужно из-под рута, шарить доступ в другой аккаунт и там тоже только рут (для консоли) и credentials рута (если программно). И никаких ролей.
Почему? Это было в предыдущих частях по #s3_history - мы же ведь ещё не придумали #bucket_policy и #IAM, у нас на дворе нулевые, а их завезли лишь в 2010-м. Поэтому только руты, только #ACL, только хардкор.
С одной стороны, многим, если не большинству, кто ходил больше раза в амазоновскую консоль, знакома закладка Access Control List в разделе Permissions.
С другой стороны, многим, если не большинству, даже из тех, кто потыкался и попытался разобраться, так и осталось тайной, что она в реальности собой представляет и как там что-то работает. Потому что погуглив получение Canonical ID и попыташись с помощью него расшарить доступ в бакет из другого аккаунта - наверняка ничего не работало.
Понятной документации не так много, т.к. во всей новой не рекомендуется использовать ACL, а пользоваться для этого (кросс-аккаунта, да и всего прочего) Bucket Policy и IAM.
Но оно ж там ещё почему-то есть! Если бы не работало, убрали бы, наверное.
Ларчик открывается просто. Если у вас не заработало, значит вы честно выполняли рекомендации бестпрактиксов и делали это не из-под root-юзера, т.е. логинились в консоль как обычный IAM-юзер. А для того, чтобы эти артефакты работали и работали как надо - требуются руты и только руты.
Т.е. работать и логиниться в консоль для работы с ACL нужно из-под рута, шарить доступ в другой аккаунт и там тоже только рут (для консоли) и credentials рута (если программно). И никаких ролей.
Почему? Это было в предыдущих частях по #s3_history - мы же ведь ещё не придумали #bucket_policy и #IAM, у нас на дворе нулевые, а их завезли лишь в 2010-м. Поэтому только руты, только #ACL, только хардкор.
S3 Access Points - первый взгляд
Недавно появившиеся S3 Access Points стали попыткой начать избавляться от наследия S3 с её требованием к глобальной уникальности имени бакета (т.е. когда имя приходится каждый раз придумывать новое по каким-то паттернам, т.к. иначе получаем ошибку создания бакета).
Теперь же можно создавать и использовать условные "ссылки на бакет" - S3 Access Points. Такие ссылки имеют имя (например,
Технически попробовать просто - в S3 консоли переходите на вкладку S3 Access Points и создаёте endpoint с каким-то именем. Добавляете к нему #bucket_policy, как к обычному бакету, только в качестве ресурса нужно будет указать arn в виде (он указан на странице вашего Access Point):
"Resource": "arn:aws:s3:
Этот ресурс есть "ссылка на бакет" и к нему можно применять обычные команды #aws_cli (лишь с поправкой, что её придётся для этого обновить, иначе будет ругаться на имя бакета "Bucket name must match..."). Например, можно сделать привычный листинг
Однако в случае cross-account доступа крайне неудобно, т.к. приходится прописывать политики и на самом бакете и на каждой "ссылке" (Access Point). И #CRR (Cross-Region Replication) не работает для S3 Access Points.
И набор других особенностей и ограничений. Так что пока сырое, нужно учитывать данный момент.
Предположительный сценарий использования S3 Access Points - вы обрабатываете данные из одного (общего для всех, единственного) бакета, раздавая ссылки на него со своими политиками для каждого из окружений. Можно также как-то задействовать в Blue-Green сценариях и ещё какие-то специцифичные случаи.
В общем S3AP пополнили длинный список фич Амазона под названием "придумай зачем". Однако это шаг в правильном направлении и будучи допиленным, наверняка станет best practices, т.к. даёт дополнительную абстракцию, позволяя гибко управлять и избавляя от некоторых legacy ограничений.
#S3 #S3AP
Недавно появившиеся S3 Access Points стали попыткой начать избавляться от наследия S3 с её требованием к глобальной уникальности имени бакета (т.е. когда имя приходится каждый раз придумывать новое по каким-то паттернам, т.к. иначе получаем ошибку создания бакета).
Теперь же можно создавать и использовать условные "ссылки на бакет" - S3 Access Points. Такие ссылки имеют имя (например,
ext из примера), которое должно быть уникальным лишь в конкретном регионе и аккаунте. Что может быть удобным при использовании в мульти-аккаунт схеме, где одно приложение в одном аккаунте, значит можно спокойно использовать одинаковые имена (ссылки на бакет).Технически попробовать просто - в S3 консоли переходите на вкладку S3 Access Points и создаёте endpoint с каким-то именем. Добавляете к нему #bucket_policy, как к обычному бакету, только в качестве ресурса нужно будет указать arn в виде (он указан на странице вашего Access Point):
"Resource": "arn:aws:s3:
eu-west-1:896118698909:accesspoint/ext"Этот ресурс есть "ссылка на бакет" и к нему можно применять обычные команды #aws_cli (лишь с поправкой, что её придётся для этого обновить, иначе будет ругаться на имя бакета "Bucket name must match..."). Например, можно сделать привычный листинг
aws s3 ls arn_ссылки_на_бакет (на картинке). Однако в случае cross-account доступа крайне неудобно, т.к. приходится прописывать политики и на самом бакете и на каждой "ссылке" (Access Point). И #CRR (Cross-Region Replication) не работает для S3 Access Points.
И набор других особенностей и ограничений. Так что пока сырое, нужно учитывать данный момент.
Предположительный сценарий использования S3 Access Points - вы обрабатываете данные из одного (общего для всех, единственного) бакета, раздавая ссылки на него со своими политиками для каждого из окружений. Можно также как-то задействовать в Blue-Green сценариях и ещё какие-то специцифичные случаи.
В общем S3AP пополнили длинный список фич Амазона под названием "придумай зачем". Однако это шаг в правильном направлении и будучи допиленным, наверняка станет best practices, т.к. даёт дополнительную абстракцию, позволяя гибко управлять и избавляя от некоторых legacy ограничений.
#S3 #S3AP
Официальные разъяснения по использованию появившейся возможности с помощью Conditions
https://aws.amazon.com/blogs/security/how-to-define-least-privileged-permissions-for-actions-called-by-aws-services/
Показывается на примере ограничения доступа к бакету лишь для Athena и в определённой VPC. Правда я б в последнем #bucket_policy использовал бы не Principal на роль, а Condition на организацию, но это уже по вкусу.
#IAM
aws:CalledVia ограничивать IAM на уровне сервисов Амазона:https://aws.amazon.com/blogs/security/how-to-define-least-privileged-permissions-for-actions-called-by-aws-services/
Показывается на примере ограничения доступа к бакету лишь для Athena и в определённой VPC. Правда я б в последнем #bucket_policy использовал бы не Principal на роль, а Condition на организацию, но это уже по вкусу.
#IAM
Amazon
How to define least-privileged permissions for actions called by AWS services | Amazon Web Services
August 31, 2021: AWS KMS is replacing the term customer master key (CMK) with AWS KMS key and KMS key. The concept has not changed. To prevent breaking changes, AWS KMS is keeping some variations of this term. More info. February 21, 2020: We fixed a missing…
Allow + NotPrincipal
Стоит быть внимательным и не допускать использования связки
Где вы как бы хотите запретить доступ в бакет каким-то юзерам из каких-то аккаунтов.
В результате они (эти два юзера из примера выше) туда, действительно, не получат доступа. Однако кроме этого, незаметно, в бакет
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html#specifying-notprincipal-allow
Потому в общем случае всегда нужно использовать связку запретить+кроме (
#s3 #bucket_policy
Стоит быть внимательным и не допускать использования связки
Allow + NotPrincipal при написании S3 Bucket Policy, например, типа такого варианта:{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"NotPrincipal": {"AWS": [
"arn:aws:iam::111111111111:user/SomeUser1",
"arn:aws:iam::222222222222:user/SomeUser2"
]},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}]
}Где вы как бы хотите запретить доступ в бакет каким-то юзерам из каких-то аккаунтов.
В результате они (эти два юзера из примера выше) туда, действительно, не получат доступа. Однако кроме этого, незаметно, в бакет
my-bucket получат доступ не просто другие ваши пользователи, но и вообще все, включая гостей (anonymous users) из интернета!https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html#specifying-notprincipal-allow
Потому в общем случае всегда нужно использовать связку запретить+кроме (
Deny+NotPrincipal).#s3 #bucket_policy