0

I'm trying to get users' public IP address logged to CloudWatch logs in AWS API Gateway.

I created a Model named SourceIP and tried to add the following schema as per the AWS offical docs, but it gives me errors.

Code :

{
     "source_ip" : "$context.identity.sourceIp"
    
}

Error :

Invalid model specified: Validation Result: warnings : [], errors : [Invalid model schema specified. Unsupported keyword(s): ["source_ip"]]

What may be the issue on my schema ?

enter image description here

Any help would be greatly appreciated.

Thanks.

Madura Dissanayake
  • 8,309
  • 5
  • 25
  • 34
  • How are you integrating the lambda with API Gateway? For Lambda proxy integrations, the source IP is included in the event passed to the function. E.g. event.requestContext.identity.sourceIp. [Integration passthrough behaviors](https://docs.aws.amazon.com/apigateway/latest/developerguide/integration-passthrough-behaviors.html?shortFooter=true). You can checkout this post [How can I retrieve a user's public IP address via Amazon API Gateway + Lambda (node)](https://stackoverflow.com/questions/33062097/how-can-i-retrieve-a-users-public-ip-address-via-amazon-api-gateway-lambda-n) – samtoddler Feb 18 '21 at 11:37
  • @samtoddler I'm using lambda proxy integration with API Gateway – Madura Dissanayake Feb 18 '21 at 11:44
  • In that case , API Gateway passes the entire request through to your backend. If you wanna log the. You can actually log. the requests [How do I enable CloudWatch Logs for troubleshooting my API Gateway REST API or WebSocket API?](https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudwatch-logs/) – samtoddler Feb 18 '21 at 11:48
  • @samtoddler I'm looking to log source IP in CloudWatch, but how can it be done ? – Madura Dissanayake Feb 18 '21 at 11:54
  • I added detailed steps in the answer. – samtoddler Feb 18 '21 at 12:16
  • @samtoddler do you have any idea why I get above Error in the description I've added. That's the error I get. – Madura Dissanayake Feb 18 '21 at 12:36
  • 1
    Mapping template overrides cannot be used with proxy integration endpoints, which lack data mappings and `mapping templates` and `models` are two different things. If you are not using `proxy` integration then you can add the mappings by going to `method ->integration -> at the bottom Mapping Template` – samtoddler Feb 18 '21 at 13:50
  • @samtoddler thanks for your detail description in the answer and it helped me a lot.. – Madura Dissanayake Feb 19 '21 at 05:48

1 Answers1

3

Use a mapping template to override an API's request and response parameters and status codes

Mapping template overrides cannot be used with proxy integration endpoints, which lack data mappings

  • Models are only for representing input and output formats
  • Mapping templates for transforming data

You can enable the logging in API gateway by following the steps:

  1. Create an IAM with arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs permissions attached and following trust policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
  1. Set this IAM role in the
- In the API Gateway console, on the APIs pane, choose the name of an API that you created.
- In the left navigation pane, at the bottom, choose Settings.
- Under Settings, for CloudWatch log role ARN, paste the IAM role ARN that you copied.
- Choose Save.

Now there are two methods for logging the IP address

  • Go to your AWS API Gateway instance within the AWS Console. Select Stages on the left menu and then select the Logs/Tracing tab Toggle on Enable CloudWatch Logs and select Log Level as INFO

and then

You can enable the mapping template by going enter image description here

which results in the access logs like:

enter image description here

On top of this you can see the ip address in the Method request headers as well

(b1fe0021-8064-4be8-a548-203c6fd795a6) Method request headers: 

{accept-language=en-us, User-Agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15, 
X-Forwarded-Proto=https, 
X-Forwarded-For=8.xx.xx.xx, 
Host=xxxxx.execute-api.eu-central-1.amazonaws.com, 
X-Forwarded-Port=443, accept-encoding=gzip, deflate, br,
X-Amzn-Trace-Id=Root=1-602e74b0-439e58b379ac537c27664a34, accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8}

If you don't enable the CloudWatch Loggin this information for the IP address via the mapping template will be passed to the endpoint as well. Like descirbed in this answer, for example lambda.

'use strict';
console.log('Loading function');
exports.handler = (event, context, callback) => {
    console.log('SourceIP =', event.identity.sourceIP);
    callback(null, event.identity.sourceIP);
};

OR

  • Go to your AWS API Gateway instance within the AWS Console. Select Stages on the left menu and then select the Logs/Tracing tab Toggle on Enable Access Logging and add your cloudwatch log group where you want to log.

    • Add the JSON log , I added few more along with IP address.
{   
    "ip": "$context.identity.sourceIp", 
    "apiId": "$context.apiId",
    "requestId": "$context.requestId", 
    "requestTime": "$context.requestTime", 
    "protocol": "$context.protocol", 
...

...
}
  • Click Save Changes and that’s it! API logs should start showing up after a few minutes.

enter image description here

How do I enable CloudWatch Logs for troubleshooting my API Gateway REST API or WebSocket API?

samtoddler
  • 8,463
  • 2
  • 26
  • 21