AWS Amazon Server : cURL error could not resolve host - php

I've been using a fanless ubuntu server for a couple of months and been transferred my Laravel API Passport to different servers like Ubuntu and for development Windows.
The current version of my api is working fine on these servers. Not until when I transferred the laravel project to my AWS Amazon server and getting the error like this
{
"message": "cURL error 6: Could not resolve host: api-a.mydomain.comoauth (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)",
"exception": "GuzzleHttp\\Exception\\ConnectException",
"file": "/var/www/html/api_tk_a/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php",
"line": 185,
"trace": [
{
....some line of multiple errors
}
]
}
I tried to add some line of code to my etc/hosts file
like this
52.***.***.205 api-a.mydomain.com
52.***.***.205 api-b.mydomain.com
or
127.0.0.1 api-a.mydomain.com
127.0.0.1 api-b.mydomain.com
tried also my inet addr:171.*.**.** to put on my hosts file still getting the same error
I have 2 different api that's why there's a and b
But nothing of these works.
Can anyone point out the reason why I'm getting this error.
Some thread says this has nothing to do with the Guzzle but clearly states to the IP and DNS. But I can't find a good way to figure this out.
UPDATE
My .env file has something like this
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:1AEVUl5JHMzLkhxU7MDlDHtfZ6KB9UybjzUxLaYp9vg=
APP_DEBUG=true
APP_URL=http://localhost
I tried to put the APP_URL as https://api-a.mydomain.com still not working..
API CODE This code is working fine
$http = new Client;
$response = $http->post(url('oauth/token'), [
'form_params' => [
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => '8mEsN0RZkljKZlbiJFfnNKahcbcOVkoQVG7C2Xwl',
'username' => $user->email,
'password' => $request->password,
'scope' => '',
],
]);
This is my routes/api.php
use Illuminate\Http\Request;
Route::post('/login','Auth\Api\AuthController#login');
EC2 Ping

For ping to work in EC2 instance, you have to open ICMP port in Security Group for your IP. Also for curl, verify have you opened port 8080/80 for your instance.

I found a solution:
I used $http->post('https://api-a.mydomain.com' . '/oauth/token', [
Laravel passport trying to get oauth/token. Guzzle keeps hanging, also on other Guzzle calls

Related

AWS Lambda send SMS via AWS-PHP-SDK doesn't work

Problem description:
I am unable to send SMS from AWS Lambda.
Controller Code
try {
$sms = AwsFacade::createClient('sns');
$result = $sms->publish([
'MessageAttributes' => [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'CyQuer',
],
'AWS.SNS.SMS.SMSType' => [
'DataType' => 'String',
'StringValue' => 'Transactional',
],
],
'Message' => "Hello John Doe".PHP_EOL."Use following Code to Login:".PHP_EOL."123456",
'PhoneNumber' => $phone,
]);
Log::info($result);
} catch (Exception $e) {
Log::error($e->getMessage());
}
Error message:
via web
{"message": "Internal server error"}Task timed out after 28.00 seconds
via Artisan
Task timed out after 120.00 seconds
Setup
Laravel application running on AWS Lambda using bref/laravel-bridge
IAM user for this application has been created. Locally everything works. Online everything works too except sending SMS.
Tried solutions:
The following packages were tried.
https://github.com/aws/aws-sdk-php
https://github.com/aws/aws-sdk-php-laravel
All the following described approaches worked locally on AWS Lambda but not.
Write AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY directly into config/aws.php
Write AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY directly in the code
$sms = AwsFacade::createClient('sns',[
'credentials' => [
'key' => '********************',
'secret' => '****************************************',
],
'region' => env('AWS_REGION', 'eu-central-1'),
'version' => 'latest',
'ua_append' => [
'L5MOD/' . AwsServiceProvider::VERSION,
],
]);
Giving all IAM users full admin access didn't work either.
Locally, all alternative solutions have also always worked!
Does anyone know the problem and have a solution for it? I've been trying to find a way for more than 24 hours. My last approach would be to rebuild the complete call via CURL and try it out, but I hope someone has/finds a solution.
For anyone facing similar issue, this could be/ most likely is due to lambda being configured in a VPC (most likely to give it access to RDS) and therefore losing internet connection, and by extension of that, access to other AWS services. One of the ways to work around this is to enable internet access to your VPC-bound lambda via setting up a NAT gateway (guide here). Alternatively, you can also use VPC Endpoints if the desired AWS service is supported. More info here.
In my experience, I had issues being unable to use specific credentials for certain clients in the AWS PHP SDK. I've seen that the best solution is to include the IAM permissions needed in the policy statements for the lambda function itself.
In this case for example, you may need to include the relevant statement for SNS like below:
{
"Action": [
"ses:*"
],
"Resource": "*",
"Effect": "Allow"
}
If you're using serverless to deploy, you may define it under provider.iamRoleStatements in the serverless.yml file like below:
provider:
name: aws
iamRoleStatements:
- Effect: Allow
Action:
- sns:*
Resource: '*'
IMPORTANT: Do provide only the minimum permissions that your lambda needs. The above statements are just examples.
After the relevant permissions are applied in this way, you may drop the specific credentials from the constructor of your AWS client.

Error retrieving credentials from the instance profile metadata server error in AWS SDK

I am developing an web application using PHP. I am storing the user credentials on the AWS Cognito service. I am logging in the user to the Cognito using PHP SDK.
I developed the feature successfully. I tested it locally on my machine, it was working. Then I deployed it onto the staging server, it was working on the staging server as well. But when I deployed it on to the live server, it gave me this error:
(1/1) CredentialsException
Error retrieving credentials from the instance profile metadata server. (cURL error 7: Failed to connect to 169.254.169.254 port 80: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html))
This is my code
try{
$client = new CognitoIdentityProviderClient([
'version' => 'latest',
'region' => 'eu-west-2'// env('AWS_REGION', '')
]);
$result = $client->adminInitiateAuth([
'AuthFlow' => 'ADMIN_NO_SRP_AUTH',
'ClientId' => COGNITO_APP_CLIENT_ID,
'UserPoolId' => COGNITO_USER_POOL_ID,
'AuthParameters' => [
'USERNAME' => $request->email,
'PASSWORD' => $request->password,
],
]);
$auth_result = $result->get('AuthenticationResult');
$cognito_access_token = $auth_result['AccessToken'];
if(!empty($cognito_access_token))
{
//register the user
$reg_user = $this->accRepo->register($request);
if($reg_user)
{
Auth::login($reg_user);
$token = $reg_user->createToken($this->tokenTag)->accessToken;
unset($reg_user->password);
return response()->json([ 'success' => true, 'access_token' => $token, 'account' => $reg_user ], SUCCESS_RESPONSE_CODE);
}
}
}
catch(Exception $e)
{
}
I am using the exact code and setting and credentials as the local machine and the staging server for the live server. But it does not work on the live server. Working on the other environments. What might be the error? I am deploying it on Heroku.
I am not familiar with Cognito, but the error you're seeing is that your code is attempting to access the Instance Metadata available in EC2. The AWS PHP SDK has a specific order in which it attempts to locate credentials. Here is an outline of different credential methods using the PHP SDK.
So, I suspect it works on your local machine because you have an IAM profile configured using the AWS CLI aws configure command.
It most likely works on your staging server because that server has an IAM Role attached to the EC2 instance. The PHP doesn't find a locally configured IAM profile, so it then skips to attempting to access the EC2 metadata, which it does successfully, so it gets authenticated.
Now, when you deploy to Heroku, it is no longer on an EC2 instance, or in your local environment. So, your CredentialProvider fails. My suggestion would be to utilize Config Vars in Heroku, then change your code to use CredentialProvider::env() as outlined here. You would need to create an IAM user with the same role as your EC2 instance that works (or enough permissions to do what you need to do). This would allow your application to securely access Cognito from an environment external to AWS.

How to retrieve queue from aws SQS using laravel?

In my client server, I send queue to AWS SQS using Artisan::queue. In .env file I configured QUEUE_DRIVER=sqs and in config/queue.php file I configured like below.
'default' => env('QUEUE_DRIVER', 'sqs'),
'sqs' => [
'driver' => 'sqs',
'key' => 'MY_AWS_KEY',
'secret' => 'MY_AWS_SECRET',
'prefix' => 'https://sqs.us-west-2.amazonaws.com/1234567890',
'queue' => 'queue-name',
'region' => 'us-west-2',
],
Now when I call Artisan::queue from Controller I see message is created in SQS. I can see them in AWS console and they are like below.
{"job":"Illuminate\\Foundation\\Console\\QueuedJob",
"data":[{"some_data_key":"some_data_value"}]}
Everything is fine so far I believe. But my worker tier never receives data. I have configured in Worker tier>Configuration>Worker Details like below:
Worker queue: queue-name
Worker queue URL: https://sqs.us-west-2.amazonaws.com/1234567890/queue-name
HTTP path: /worker
Here, my problem is that I always get 404 error on /worker address. As soon as message was sent, I see one count up in "Messages in Flight" in AWS SQS console and when I check Worker tier's log file, I see bunch of
`127.0.0.1 (-) - - [28/Jun/2017:08:37:10 +0000] "POST /worker HTTP/1.1" 404 204 "-" "aws-sqsd/2.3"`
I checked if post request to /worker returned error but it works okay in different server (I couldn't check in worker tier as I don't have URL address for it). At this point, Worker tier server has only
Route::match(['GET', 'POST'], 'worker', function () {
return 200;
});
in routes/web.php to see if POST request could reach there.
What did I do wrong? Did I miss something? Or implement it in wrong way?
If your are using your worker environment in elastic beanstalk, make sure your
Configuration->Software Configuration->Container Option->Document Root
is set to value
/public
Also check your route provider somewhere like
app/Providers/RouteServiceProvider.php
There check map() function to see if you are creating your http routes to appropriate file. There can be reference to multiple route files like web.php and api.php etc

sending mail in Laravel 5.4 using Mailgun get error code " 401 UNAUTHORIZED` response: Forbidden "

I'm trying to send mail in Laravel 5.4 project with Mailgun. I think I set the configuration correctly. But, I got this error message such as
ClientException in RequestException.php line 111:
Client error: POST https://api.mailgun.net/v3/sandboxfeb88d58f18841738b2fc81d7cbc7631.mailgun.org/messages.mime >resulted in a 401 UNAUTHORIZED response:
Forbidden
Here is my configuration:
in .env file
MAIL_DRIVER=mailgun
MAILGUN_DOMAIN=sandboxfeb88d58f18841738b2fc81d7cbc7631.mailgun.org
MAILGUN_SECRET=pubkey-1767e**********
in mail.php file
'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'richi.htoo#gmail.com'),
'name' => env('MAIL_FROM_NAME', 'Richi Htoo'),
],
in services.php file
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
and I wrote mail sending code in default route such as
Route::get('/', function () {
//return view('welcome');
$data = [
'title' => 'Hi student I hope you like the course',
'content' => 'This laravel course was created with a lot of love and dedication for you'
];
Mail::send('emails.test', $data, function($message){
$message->to('white.nuzzle#gmail.com', 'White Nuzzle')->subject('Hello student how are you?');
});
});
And I also installed Laravel Package "guzzlehttp/guzzle" version 6.2 to send mail.
But when I call that default home route, I got an error message as I mention above.
I can't find any solution for my error in any where including this forum "stackoverflow.com".
Can anyone help me please?
Ok found it,
In the file "vendor\laravel\framework\src\Illuminate\Mail\Transport\MailgunTransport.php", the endpoint used is US one.
As said in documentation, https://documentation.mailgun.com/en/latest/api-intro.html#mailgun-regions, you have an endpoint for US and EU.
If you are european, you must use "api.eu.mailgun.net" or you get a 401.
Just change the endpoint: Laravel is powerful and they think about that. You can add an 'endpoint' key to the config/services.php/mailgun entry.
Frankly it was quite an ordeal, I made the sandbox work as following
Added authorized recipient - Apparently sandbox can't send email to
anyone, you need to add them as authorized recipient.
Use proper credentials in .env File added MAILGUN_DOMAIN and MAILGUN_SECRET too as services.php uses them. Remember MAILGUN_SECRET is the private key and starts with key-, don't use public key here
Put
MAIL_DRIVER=mailgun MAIL_HOST=smtp.mailgun.org MAIL_PORT=587 MAIL_USERNAME=postmaster#sandboxcc*****************.mailgun.org MAIL_PASSWORD=****************** MAIL_ENCRYPTION=tls
!!!MOST IMPORTANT!!!! RESTART YOUR SERVER to load the new .env file.
If you are not using the United States Mailgun region, you can define your region's endpoint in the services configuration file:
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.eu.mailgun.net'),
],
Alternatively, one can define the MAILGUN_ENDPOINT in the .env file:
MAILGUN_ENDPOINT="api.eu.mailgun.net"
Make sure to check your credentials for the mailgun, make sure that those are correct.
Dont copy the Public Validation Key.
please copy the Private API Key
Default Mail Driver: Mailgun
MAILGUN_DOMAIN=*your-domain*.mailgun.org
MAILGUN_SECRET=pubkey-*your-public-key*
Default Mail Driver: SMTP
MAIL_USERNAME=postmaster#*your-domain*.mailgun.org
MAIL_PASSWORD=*your-password*
Don't forget to php artisan config:clear
I had the same issue. Check your DNS settings in the Mailgun Sending domain checklist. I found I could not get an EU MG setting to work so I suggest you use a US MG server
Ok, I just want to summarize what I had to do to make Mailgun work in Laravel 8.
1. Install guzzle
composer require guzzlehttp/guzzle
2. EU or US?
I'm from EU. The Laravel Doc for Mailgun says to configure mailgun for usage in EU. This is WRONG if you're using the sandbox because it is located in the US apparently. I have a small US flag next to my sandbox url and it took me ages to figure this out.
If you want to use the sandbox put this into \config\services.php:
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
],
If you want to use a domain that is registered for EU you will need to make this change:
'endpoint' => env('MAILGUN_ENDPOINT', 'api.eu.mailgun.net'),
If you put the wrong region, your log should throw 401 UNAUTHORIZED response
3. Authorize Recipients
If you're using the sandbox you need to authorize recipients. Go to your mailgun account and to your sandbox domain and authorize recipients in the email field. If you try to send an email to non-authorized recipients your log should throw an 403 FORBIDDEN response
4. Default Mailer
If you want mailgun to be your default mailer you can change this in your \config\mail.php:
'default' => env('MAIL_MAILER', 'mailgun'),
5. Credentials
These credentials made it work for me, hopefully they will make it work for you too. Put them in .env:
MAIL_DRIVER=mailgun
MAILGUN_DOMAIN=sandboxXXXXXXXXXXXXXXXXXXXXXXXXXXXX.mailgun.org
MAILGUN_SECRET=2dfXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_ENCRYPTION=tls
MAILGUN_SECRET is your private api key which can be found when go to your mailgun account and click on your profile logo -> api keys.
MAILGUN_DOMAIN is your (I believe currently used) domain and can be accessed in your mailgun account either through the dashboard or through sending->domains in the navpanel. The only not messy reference field for your domain seems to be in sending->overview-> select SMTP and copy the end part of the Username field (without postmaster#)
I hope this saves time for someone because it took forever to get it to work.
Personally I never got the sandbox account to work. I just did this a little over a month ago. Sandbox never worked, but the live account I created did. Try switching to the live account and let me know if that works for you.
Just go to the config folder. and made some changes..
'mailgun' => [
'domain' => env('your_domainxxxxxxx.mailgun.org'),
'secret' => env('key-xxxxxxxx_private_API_keyxxxx'),
],
error will be resolved.
In case if you use API base mailgun, check if the domain exists.
I removed my testing domain and after it tried to send a new email message from that domain. I got 401 error.
I had the same problem in Symfony. Yes, it's not Laravel but they're close.
In .env file I had
MAILER_DSN=mailgun://KEY:DOMAIN#default
The error disappeared after I changed it to
MAILER_DSN=mailgun://KEY:DOMAIN#default?region=eu

Guzzle Curl Failing With Connection Refused

I am trying to figure out why my Guzzle request is throwing a number 7 error when cURLing.
Here is my guzzle code:
use GuzzleHttp\Client;
$client = new Client([
'base_url' => ['http://mysite.local:8000/api/v1.0.0', []],
'defaults' => [
'proxy' => 'http://mysite.local:8000'
]
]);
$request = $client->createRequest('GET', 'simplecontroller/index', [
'query' => ['foo' => 'bar']
]);
$response = $client->send($request);
var_dump($response); // <-- is not happening becauase:
It is failing on CurlAdapter::send(). The cURL request is throwing an error, and thus being handled by the handleError method. Here is the error message:
string 'Failed to connect to mysite.local port 8000: Connection refused'
Any idea of what might need to change? I am working on a project that talks to an API, and that api code also happens to be in development as well on my local machine. I am also using Vagrant Homestead if that helps. As far as I can tell, it should be possible to cURL to a local url for testing purposes. If it is not, please let me know.
Thanks!

Categories