Отказано в доступе к общедоступному сегменту S3 с определенных IP-адресов

#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=
 

Я уже реализовал следующее, чтобы сделать корзину общедоступной:

     {
    "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 Запрещенная ошибка отладьте следующие шаги.

  1. Отсутствуют разрешения для s3:putObject или s3:PutObjectAcl
  2. Отсутствуют разрешения на использование ключа службы управления ключами AWS (AWS KMS)
  3. Явный оператор запрета в политике корзины
  4. Список управления доступом к корзине (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

Позвольте мне сначала начать со второго решения.

  1. Создайте корзину. Отключите весь общедоступный доступ к нему.
  2. Прикрепите следующую политику корзины 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/*"
            ]
        }
    ]
}
 
  1. Создайте новую роль IAM с именем ec2-instance-role . Вам НЕ нужны какие-либо политики IAM, привязанные к нему. Оставьте это поле пустым.
  2. Перейдите к своему экземпляру EC2, щелкните Actions -> Security -> Modify IAM role и выберите роль, созданную на шаге 3.
  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 (роли).

  1. Создайте корзину. Отключите весь общедоступный доступ к нему. Отключите ACL.
  2. Создайте новую роль IAM ec2-instance-role со следующей политикой:
 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::yyyyyyyyyyy",
                "arn:aws:s3:::yyyyyyyyyyy/*"
            ]
        }
    ]
}
 
  1. Перейдите к своему экземпляру EC2, щелкните Actions -> Security -> Modify IAM role и выберите роль, созданную на предыдущем шаге.
  2. Чтобы убедиться, что все работает так, как ожидалось, я использую 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