AWS: Как получить PHP на экземпляре EC2 для чтения секрета Secrets Manager? - PullRequest
0 голосов
/ 27 апреля 2020

Я установил экземпляр EC2, работающий PHP. Только для тестирования, экземпляр находится в общедоступной c su bnet с группой безопасности, которая позволяет All Traffi c до 0.0.0.0/0. Таблица маршрутов имеет локальный маршрут по умолчанию к 10.0.0.0/16 (блок CIDR VP C) и маршрут к шлюзу Inte rnet в 0.0.0.0/0. NACL, связанный с su bnet, позволяет All Traffi c входить и выходить на 0.0.0.0/0. Я знаю, что это широко открыто, но я хотел убедиться, что проблема, с которой я сталкиваюсь, не связана с группами безопасности и NACL.

Я создал секрет диспетчера секретов MySecret-xxxxx и прикрепил роль IAM к экземпляр со следующей политикой, разрешающей экземпляру доступ к секрету:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret",
                "secretsmanager:ListSecretVersionIds"
            ],
            "Resource": "arn:aws:secretsmanager:eu-west-2:xxxxxxxxx:secret:MySecret-xxxxx"
        }
    ]
}

Я установил AWS SDK для PHP на экземпляр в подпапке с именем sdks и, наконец, создал индексный файл "Hello World". php, который прекрасно работает, пока я не попытаюсь запустить getSecretValue в упрощенной версии информации о настройке, которую предоставляет AWS. Это код PHP:

<?php
    require 'sdks/aws/aws-autoloader.php';

    use Aws\SecretsManager\SecretsManagerClient;
    use Aws\Exception\AwsException;

    $client = new SecretsManagerClient( [
        'profile' => 'default',
        'version' => 'latest',
        'region' => 'eu-west-2'
    ] );

    $secretName = 'MySecret-xxxxx';

    echo '<h1>Hello World</h1>';

    $result = $client->getSecretValue([
        'SecretId' => $secretName,
    ]);
?>

Как только я включаю блок кода $result = $client->getSecretValue([..., я получаю сообщение об ошибке HTTP ERROR 500, хотя без него оно прекрасно работает. Я запустил aws secretsmanager get-secret-value --secret-id MySecret-xxxxx --region eu-west-2 на CLI, и он вернул секретные данные правильно.

1 Ответ

0 голосов
/ 01 мая 2020

Наконец-то понял - хотя я создал файл учетных данных в папке /home/ec2-user/.aws на экземпляре EC2, мне все равно пришлось получать учетные данные через SDK. Почему это исключено из примера кода Secrets Manager, который предоставляет AWS, мне не понятно. Полный рабочий код теперь выглядит так:

<?php
    require 'vendor/autoload.php';

    use Aws\Credentials\CredentialProvider;
    use Aws\SecretsManager\SecretsManagerClient;
    use Aws\Exception\AwsException;

    $provider = CredentialProvider::defaultProvider();

    $client = new SecretsManagerClient( [
        'credentials' => $provider,
        'version' => 'latest',
        'region' => 'eu-west-2'
    ] );

    $secretName = 'MySecret-xxxxx';

    try {
        $result = $client->getSecretValue( [
            'SecretId' => $secretName,
        ] );
    } catch ( AwsException $e ) {
        $error = $e->getAwsErrorCode();
        if ( $error == 'DecryptionFailureException' ) { // Can't decrypt the protected secret text using the provided AWS KMS key.
            throw $e;
        }
        if ( $error == 'InternalServiceErrorException' ) { // An error occurred on the server side.
            throw $e;
        }
        if ( $error == 'InvalidParameterException' ) { // Invalid parameter value.
            throw $e;
        }
        if ( $error == 'InvalidRequestException' ) { // Parameter value is not valid for the current state of the resource.
            throw $e;
        }
        if ( $error == 'ResourceNotFoundException' ) { // Requested resource not found
            throw $e;
        }
    }
    // Decrypts secret using the associated KMS CMK, depends on whether the secret is a string or binary.
    if ( isset( $result[ 'SecretString' ] ) ) {
        $secret = $result[ 'SecretString' ];
    } else {
        $secret = base64_decode( $result[ 'SecretBinary' ] );
    }

    // Decode the secret json
    $secrets = json_decode( $secret, true );

echo( '<p>hostname/ipaddress: ' . $secrets[ 'host' ] . '</p><p>username: ' . $secrets[ 'username' ] . '</p><p>password: ' . $secrets[ 'password' ] . '</p><p>dbname: ' . $secrets[ 'dbname' ] . '</p>' );
...