#php #amazon-web-services #amazon-s3 #amazon-ec2
#php #amazon-веб-сервисы #amazon-s3 #amazon-ec2
Вопрос:
Я попытался создать полностью общедоступную корзину S3 и получить доступ с помощью PHP SDK. Это работает, когда я запускаю приведенный ниже код доступа со своего локального компьютера:
require 'vendor/autoload.php';
use AwsS3S3Client;
use AwsS3ExceptionS3Exception;
$s3 = new S3Client([
'version' => 'latest',
'region' => 'eu-west-2',
'credentials' => [
'key' => "my correct key",
'secret' => "my correct secret"
]
]);
// //publictest2
$bucket = 'mybucketname';
$keyname = 'test_file.txt';
// Upload an object
try {
// Upload data.
$result = $s3->putObject([
'Bucket' => $bucket,
'Key' => $keyname,
'Body' => 'Hello',
'ACL' => 'public-read'
]);
// Print the URL to the object.
echo $result['ObjectURL'] . PHP_EOL;
} catch (S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
Однако, как только я запускаю его с тестового сервера (AWS EC2) Я получаю следующую ошибку:
Error executing "PutObject" on "mybucketname"; AWS HTTP error: Client error: `PUT https://mybucketname/test_file.txt` resulted in a `403 Forbidden` response: AccessDeniedAccess DeniedVTJX7V (truncated...) AccessDenied (client): Access Denied - AccessDeniedAccess DeniedVTJX7V4CCKZYG7CRTz dPA7fsZQnFxTERKxxbP IpTtMIIsS1uu23fvTruHH3w8KxwGIduCntRBM5u6tIfHdusbCoPw=
Я уже реализовал следующее, чтобы сделать корзину общедоступной:
- Отключены все настройки блокировки общего доступа, как на уровне учетной записи, так и на уровне корзины: настройки блокировки общего доступа на уровне корзины
- Редактировать владение объектом: редактировать раздел владения объектом
- Я отредактировал списки ACL следующим образом: настройки acl
- Я даже создал политику корзины, которая должна позволять любому выполнять любые действия в корзине:
{
"Version": "2012-10-17",
"Id": "S3BukcetPolicyIPAccess",
"Statement": [
{
"Sid": "DenyIfNotFromAllowedVPC",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"mybucketarn",
"mybucketarn/*"
]
}
]
}
Почему это все еще не работает при запуске с моего сервера EC2?
Комментарии:
1. Используете ли вы один и тот же ключ доступа и секретный ключ доступа при запуске в локальном и в экземпляре Ec2?
2. Вам не нужны списки управления доступом для всего этого. Вообще говоря, вам не следует использовать списки управления доступом. Кроме того, политика корзины, которая дает
s3:*
разрешение кому-либо, почти наверняка является очень плохой идеей (если только вы не делали это временно, чтобы что-то протестировать, и в этом случае это все равно плохая идея).3. Запустите эту команду на вашем экземпляре EC2 :
aws sts get-caller-identity
. Это даст вам представление о принципале AWS, от имени которого AWS CLI выполняет аутентификацию в AWS API.
Ответ №1:
Это не связано с сегментом S3 — подсказка здесь в том, что он работает с вашего локального компьютера, а это означает, что виноват не сегмент S3, а экземпляр.
Это связано с ролью, которую принимает (или не принимает) ваш экземпляр EC2 — создайте и назначьте роль IAM, которая имеет доступ для выполнения PutObject
mybucketname
.
Одним из быстрых способов проверить это было бы использовать роль с прикрепленной политикой, управляемой AWS AmazonS3FullAccess
, которая обеспечивает полный доступ ко всем сегментам S3.
После этого ваш экземпляр EC2 получит доступ к корзине S3.
Ответ №2:
для HTTP 403 Запрещенная ошибка отладьте следующие шаги.
- Отсутствуют разрешения для s3:putObject или s3:PutObjectAcl
- Отсутствуют разрешения на использование ключа службы управления ключами AWS (AWS KMS)
- Явный оператор запрета в политике корзины
- Список управления доступом к корзине (ACL) не позволяет пользователю root учетной записи AWS записывать объекты
не могли бы вы проверить эту команду из вашего экземпляра ec2
«aws s3 ls s3://doc-example-bucket/abc/»
Если эта команда выполнена успешно, то учетные данные или роль, указанные в коде вашего приложения, вызывают ошибку «Отказано в доступе». Убедитесь, что роль профиля экземпляра имеет необходимые разрешения на чтение и запись для сегментов S3. Например, действия S3 в следующей политике IAM предоставляют требуемый доступ на чтение и запись к сегменту S3.
Ответ №3:
Ваша проблема в том, что веб-сервер PHP, работающий на вашем экземпляре EC2, использует AWS PHP SDK, и на нем НЕ настроен принципал IAM, поскольку к вашему EC2 не привязан ни профиль экземпляра (роль AWS), ни профиль по умолчанию (пользователь AWS), настроенный с aws configure
помощью .
Другими словами, ваши вызовы AWS API не проходят проверку подлинности, не говоря уже о разрешении выполнять какие-либо действия против S3. Даже если вы разрешаете s3:*
для всех участников в политике корзины. Помните: политика корзины ожидает участника AWS, но ваш запрос не аутентифицирован (AWS API не может определить, кто звонит). Следовательно AccessDenied
.
Существует несколько решений вашей проблемы. Но все они могут быть сведены к:
- Использование политики IAM (рекомендуется)
- Использование политики корзины S3
Вы можете ознакомиться с этим сообщением в блоге AWS о том, какому подходу следовать, но для вашей конкретной проблемы я бы выбрал политики IAM.
Использование политики корзины S3
Позвольте мне сначала начать со второго решения.
- Создайте корзину. Отключите весь общедоступный доступ к нему.
- Прикрепите следующую политику корзины S3:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxx:role/ec2-instance-role"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::yyyyyyyyyyy",
"arn:aws:s3:::yyyyyyyyyyy/*"
]
}
]
}
- Создайте новую роль IAM с именем
ec2-instance-role
. Вам НЕ нужны какие-либо политики IAM, привязанные к нему. Оставьте это поле пустым. - Перейдите к своему экземпляру EC2, щелкните
Actions -> Security -> Modify IAM role
и выберите роль, созданную на шаге 3. - Нет необходимости перезапускать экземпляр. Чтобы убедиться, что все работает так, как ожидалось, я использую AWS CLI, но он также должен работать с любым SDK (например, PHP). Выполнить из вашего экземпляра EC2:
# Make sure the correct role is assumed
$ aws sts get-caller-identity
{
"Account": "xxxxxxxxxxx",
"UserId": "AROAYGJILC6K4AJRGLZTS:i-0aa422c12359ac00e",
"Arn": "arn:aws:sts::xxxxxxxxxxx:assumed-role/ec2-instance-role/i-0aa422c12359ac00e"
}
# Upload a test file and check the bucket
$ touch test.txt
$ aws s3 cp test.txt s3://yyyyyyyyyyy/test.txt
upload: ./test.txt to s3://yyyyyyyyyyy/test.txt
$ aws s3 ls s3://yyyyyyyyyyy
2021-12-12 11:01:51 0 test.txt
Использование политик IAM
Здесь все остается прежним, за исключением того, что вам не нужна никакая политика корзины, но вы прикрепляете политику непосредственно к профилю экземпляра IAM (роли).
- Создайте корзину. Отключите весь общедоступный доступ к нему. Отключите ACL.
- Создайте новую роль IAM
ec2-instance-role
со следующей политикой:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::yyyyyyyyyyy",
"arn:aws:s3:::yyyyyyyyyyy/*"
]
}
]
}
- Перейдите к своему экземпляру EC2, щелкните
Actions -> Security -> Modify IAM role
и выберите роль, созданную на предыдущем шаге. - Чтобы убедиться, что все работает так, как ожидалось, я использую AWS CLI, но он также должен работать с любым SDK (например, PHP). Выполнить из вашего экземпляра EC2:
# Make sure the correct role is assumed
$ aws sts get-caller-identity
{
"Account": "xxxxxxxxxxx",
"UserId": "AROAYGJILC6K4AJRGLZTS:i-0aa422c12359ac00e",
"Arn": "arn:aws:sts::xxxxxxxxxxx:assumed-role/ec2-instance-role/i-0aa422c12359ac00e"
}
# Upload a test file and check the bucket
$ touch test.txt
$ aws s3 cp test.txt s3://yyyyyyyyyyy/test.txt
upload: ./test.txt to s3://yyyyyyyyyyy/test.txt
$ aws s3 ls s3://yyyyyyyyyyy
2021-12-12 11:01:51 0 test.txt
И последнее, но не менее важное для обоих подходов: не используйте списки управления доступом (настройте свою корзину с ACLs disabled
помощью), поскольку списки управления доступом существуют для обратной совместимости в пользу политик корзины, подробности см. В том же сообщении в блоге:
Как правило, AWS рекомендует использовать политики корзины S3 или политики IAM для контроля доступа. Списки управления доступом S3 — это устаревший механизм контроля доступа, который предшествовал IAM.
В приведенных выше фрагментах:
xxxxxxxxxxx
является ли номер вашей учетной записи AWS, например561262107623
yyyyyyyyyyy
является ли ваше имя корзины, напримерmybucket