Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in AWS by (19.1k points)

I'm working on setting up an ElasticSearch instance on AWS. My goal is to only allow http request from my Lambda function to the ElasticSearch instance. I have created one policy, that gives the 'Lambdaaccess to theElasticSearchinstance. The part I'm struggling with is the inline resource policy forElasticSearchthat will deny all other requests that aren't from the 'Lambda.

I have tried setting the ElasticSearch resource policy to Deny all request and then giving my Lambda a role with access to ElasticSearch. While the Lambda is using that role I am signing my http requests using Axios and aws4 but the request are rejected with The request signature we calculated does not match the signature you provided. I don't think the issue is the actual signing of the request but instead, the polices I created. If anyone can steer me in the right direction that would really help.

Lambda Policy

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Sid": "VisualEditor0",

            "Effect": "Allow",

            "Action": [

                "es:ESHttpGet",

                "es:CreateElasticsearchDomain",

                "es:DescribeElasticsearchDomainConfig",

                "es:ListTags",

                "es:ESHttpDelete",

                "es:GetUpgradeHistory",

                "es:AddTags",

                "es:ESHttpHead",

                "es:RemoveTags",

                "es:DeleteElasticsearchDomain",

                "es:DescribeElasticsearchDomain",

                "es:UpgradeElasticsearchDomain",

                "es:ESHttpPost",

                "es:UpdateElasticsearchDomainConfig",

                "es:GetUpgradeStatus",

                "es:ESHttpPut"

            ],

            "Resource": "arn:aws:es:us-east-1:,accountid>:domain/<es-instance>"

        },

        {

            "Sid": "VisualEditor1",

            "Effect": "Allow",

            "Action": [

                "es:PurchaseReservedElasticsearchInstance",

                "es:DeleteElasticsearchServiceRole"

            ],

            "Resource": "*"

        }

    ]

}

ElasticSearch Inline Policy

{

  "Version": "2012-10-17",

  "Statement": [

    {

      "Effect": "Deny",

      "Principal": {

        "AWS": [

          "*"

        ]

      },

      "Action": [

        "es:*"

      ],

      "Resource": "arn:aws:es:us-east-1:<account-number>:domain/<es-instance>/*"

    }

  ]

}

Lambda Code Using Aws4 and Axios

//process.env.HOST = search-<es-instance>-<es-id>.us-east-1.es.amazonaws.com

function createRecipesIndex(url, resolve, reject){

         axios(aws4.sign({

            host: process.env.HOST,

            method: "PUT",

            url: "https://" + process.env.HOST,

            path: '/recipes/',

       }))

      .then(response => {

          console.log("----- SUCCESS INDEX CREATED -----");

        resolve();

      })

      .catch(error => {

          console.log("----- FAILED TO CREATE INDEX -----");

        console.log(error);

        reject();

      });

}

Note: I have tried creating my index with the inline policy on ElasticSearch set to allow *(all) and removing the aws4 library signature and it works fine. Right now I just want to secure access to this resource.

1 Answer

0 votes
by (44.4k points)

There are two issues:

1. This is with the policy. The resource policy needs to be updated in accordance with Lambda.

2. The second issue might be with aws4. The path and URL have to match.

So, this is how your Elastic Search Policy would look like:

{

  "Version": "2012-10-17",

  "Statement": [

    {

      "Effect": "Allow",

      "Principal": {

        "AWS": "arn:aws:iam::<account-id>:role/service-role/<role-name>"

      },

      "Action": "es:*",

      "Resource": "arn:aws:es:us-east-1:<account-id>:domain/<es-instance>/*"

    }

  ]

}

Related questions

Want to get 50% Hike on your Salary?

Learn how we helped 50,000+ professionals like you !

Browse Categories

...