I have a Symfony 4 project that is deployed to the Digital Ocean Ubuntu server.
In order to store files, I am using Amazon S3 bucket.
I've used aws/aws-sdk-php library to interact with the Amazon S3 bucket.
I've created the global credentials file at ~/.aws/credentials and managed to make it work.
The problem is that it doesn't work on the server.
I copied the credentials file to the server's ~/.aws/ directory, but I am getting this error.
Error retrieving credentials from the instance profile metadata server. (Client error: `GET http://169.254.169.254/latest/meta-data/iam/security-credentials/` resulted in a `404 Not Found` response: not found)
I did some research on this error - it seems that the php server isn't finding the credentials file.
How do I fix this?
All AWS SDKs search for credentials from various sources in a specific order of priority. You can see this order in the boto3 documentation.
Typically, if the SDK is unable to find any credentials from any of the sources in which it searches, then it reports an error retrieving credentials from the final credential provider in its search list, and that's usually (and perhaps always) STS credentials from the instance metadata service.
In your case, you're not even running on AWS so the instance metadata service is not relevant and the error message you see is a red herring.
Here is what I suspect is happening: you are trying to supply credentials via a ~/.aws/credentials file but the AWS PHP SDK is not finding credentials there. So, one of the following may be happening:
your PHP application is running as a different Linux user and hence its home directory is not the same as the one you placed the .aws/credentials file in
your ~/.aws/credentials file is invalid in some way or has zero credentials in it (unlikely, I would say)
My vote is on #1.
Related
I wanna host a php file that retrieve data from a mysql DB how ever aws is not authorizing POST method.
I need to know how can I add the code in PHP knowing I already configured the Bucket policy and CORS
You can only serve static content from an S3 - PHP will not be processed.
If you want to set up a dynamic PHP website on AWS have a look at LightSail and its LAMP stack.
You should try Amazon API Gateway.
For my connection I am using Use the AWS shared credentials file default profile. I have .aws/credentials setup containing aws_access_key_id aws_secret_access_key. This works fine for localhost to S3 connectivity using S3Client.
However, I want to do client side encryption/decryption using S3EncryptionClient and here is where the problems start. Using PHP 3.6 and aws-sdk-php 3.5. I had to manually install Crypto directories since for whatever reason composer would not get them even though as far as I understand support was added in v3.38.
putObject following Amazon S3 Client-Side Encryption with the AWS SDK for PHP Version 3 example fails with "Error retrieving credentials from the instance profile metadata server". I am using the same user, key, secret in both cases when using S3Client or when using S3EncryptionClient. I assume KmsMaterialsProvider does not require 'credentials' => $provider to be specified, but I have tried that as well.
Edit:
Tried the same in IAM Policy Simulator. Perhaps policy is not setup correctly. But not quite sure what is required. Tried a bunch of different variations without any success. Keep getting "denied Implicitly denied (no matching statements)." for actions such as: Encrypt, Decrypt even though policy has these actions. Is the problem that I am doing this from my local machine? But then I would have thought it would fail the same way for non encrypted write/reads.
Figured this out, in case anyone runs into the same issue as it looks like at least a few people did without an answer. Creating KmsClient on dev environment (localhost) needed to specify 'credentials' => $provider, even if already specified for S3EncryptionClient . Also make sure that permission policy is setup for the key and KMS service.
I am not entirely sure if this is the question I should be asking so feel free to submit edits.
I am developing a desktop app I plan to distribute and use amazon Polly to read text the user enters. I am having trouble understanding how to securely allow users to access the service under our program without exposing the access key.
I saw in a previous example that I should create a request to use the resource, have the access and secret access key in a server and it sign the request. Then send it back to the user on the desktop application.
If this is correct could someone explain and give me a simple example of how to accomplish this in python? Thank you. :)
Here is what I have so far that I would like to be on the code clients download:
from boto3 import client
import boto3
import StringIO
from contextlib import closing
polly = boto3.client(
'polly',
region_name='us-east-1',
aws_access_key_id='I_want_to_protect_this',
aws_secret_access_key='I_also_want_to_protect_this'
)
response = polly.synthesize_speech(
Text="Good Morning. My Name is Rajesh. I am Testing Polly AWS Service For Voice Application.",
OutputFormat="mp3",
VoiceId="Raveena")
print(response)
if "AudioStream" in response:
with closing(response["AudioStream"]) as stream:
data = stream.read()
fo = open("pollytest.mp3", "w+")
fo.write( data )
fo.close()
The correct approach for providing people with access to AWS services and resources stored on AWS is to take a client/server approach.
The client in your case is a Desktop application, but it could equally be a mobile app or a web app. The client is basically untrusted and should not be given any credentials for accessing AWS.
The server is an application running somewhere (typically on Amazon EC2 or AWS Lambda) that receives requests from the client, applies business logic (eg verifying the user's identity and determining what actions they are permitted to take) and calls AWS services.
Then there are two approaches to making calls to AWS:
The server can make all the calls to AWS (using credentials that are available only to the server) and pass back results to the client. This isolates the client from AWS and allows you to insert custom business logic within the server. (eg When you use Netflix, your TV doesn't call AWS directly.) Or...
The server can verify the identity of the client (eg the user logs into the client app, which sends the login details to server) by consulting a database of authorized application users, generate temporary AWS credentials, pass them back to the client and then the client can call AWS directly. (eg Many mobile apps do this to talk with Amazon S3.)
The temporary AWS credentials can be generated by the server by calling the AWS Security Token Service and specifying the permissions and duration sought. STS will then return a set of time-limited credentials that have the desired permissions. The client application can use these credentials to call AWS services (eg Amazon Polly as per your code sample).
This way, no credentials are stored in the client code and the server controls whether the client is permitted to access AWS, which API calls can be used and how long the access should be granted.
I am using this script to populate DynamoDB: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LoadDataPHP.html
I'm getting this error using the AWS SDK:
PHP Fatal error: Uncaught exception
'Aws\Exception\CredentialsException' with message 'Cannot read
credentials from /root/.aws/credentials' in
/var/www/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php:263
According to https://docs.aws.amazon.com/aws-sdk-php/v2/guide/credentials.html
If you do not explicitly provide credentials to the client object and no environment variable credentials are available, the SDK attempts to retrieve instance profile credentials from an Amazon EC2 instance metadata server. These credentials are available only when running on Amazon EC2 instances that have been configured with an IAM role.
I have an IAM role attached to my instance with full power user access. I have confirmed the role is working fine via the AWS CLI, which can access DynamoDB without any credential configuration.
Any suggestions as to what I could be doing wrong? I am under the impression (and interpret that credentials document to say) that I don't need to configure any credentials, hence the use of the IAM role.
I just wanted to expand a bit on this for anyone else that may end up in this situation.
If you use an IAM role on a EC2 instance as your method of credentials
Then don't use the profile line when creating a client. If you do specify profile in your client it tells the SDK to override any form of credentials you set in the client with a profile from the credentials ini file.
Mentioned (but buried a bit) in the PHP SDK V3 documentation here:
https://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html#profile
Example Code
$client = new SqsClient([
'profile' => 'default', // <--- Don't use this line if you're using IAM Roles for credentials
'region' => 'us-west-2',
'version' => '2012-11-05'
]);
Misleading Documentation
The PHP SDK documentation recommends using IAM roles above all other credentials for EC2 instances. That's fine and makes total sense. The misleading part to new comers is for example this scenario;
Say someone new to the SDK reads the Basic SDK Usage in the getting started section.
Sets up a S3 client for testing as per the docs.
Once they have working S3 code, the developer decides to skip to the code examples section to setup a client for a different AWS service.
The problem here is that all of the code examples (with the exception of the S3 examples) contain the profile setting that breaks the IAM role credential method.
The code examples should at least have a reference to what profile does.
This line in the code:
'profile' => 'default',
is what was causing my issue. If you are using an IAM role you do not require the profile line, and removing it will fix the "Cannot read credentials" error.
I have a server, which should provide temporary AWS credentials to the client. The credentials will be transmitted using HTTPS.
The client should be able to upload S3 files, as well as download them. The concern I have is the following:
I have multiple users accessing ONLY their own directory: /Users/someUser/myfile.png
You can set policies to allow or deny S3 in general, but you can't grant only the access to a specific path.
What should I do about this? Will the HTTPS transmission be enough?
Then my second question.
If I hear "temporary credentials", I have a key in mind, that is valid for a couple of hours and then expires. But I'm not sure if IAM is really built for that.
Should I provide the same credentials for all users?
Or do I generate a key-pair for each client?
The server runs with PHP, the client with Objective-C.
You can specify permissions on a path in Amazon S3. For more details see the following:
Using IAM Policies
Also, if you want to create "temporary credentials" you can use the AWS Security Token Service. This service allows you to create credentials that last from 1 - 36 hours and you can put a policy on those credentials to limit their access. For more details about the service see:
Security Token Service API Reference
Finally, there is an article written for the AWS Mobile SDKs that does something similar. It has a server to issue temporary credentials to users that use an Amazon S3 bucket. It limits the users to a "sub-folder" of the bucket and also limits their actions. You can read and this sample here:
Credential Management for Mobile Applications
Hope this helps you get to the information you need.