Reputation: 549
I have a NodeJS/ExpressJS API that performs an HTTP request to get some JSON before sending a response. Here's the snippet of code:
const ipApiUrl = `https://ipapi.co/${ip}/json/`
const ipApiResponse = await axios.get(ipApiUrl)
console.log(ipApiResponse.data)
ipCountryCode = ipApiResponse.data.country_code
This code works fine locally. It also works fine on Heroku. However, it does NOT work the same on Google Cloud Run.
Here's what ipApiResponse.data
should be:
{
"ip": "141.117.117.76",
"city": "Toronto",
"region": "Ontario",
"region_code": "ON",
"country": "CA",
"country_code": "CA",
...
}
HOWEVER, when sending the request from Google Cloud Run the API I'm using returns something different. Instead I get this response:
{ ip: '169.254.8.129', reserved: true }
I think this problem is with either Google Cloud Run or Docker because I also have issues with making HTTP requests to other sites, like ipstack.com.
I am deploying to Google Cloud Run by using Docker. My Dockerfile
is using node:10
and exposes the PORT
environment variable like the documentation says. Everything else works fine except for this HTTP request. I've tried both axios
and fetch
.
Upvotes: 0
Views: 461
Reputation: 45214
To find a visitor's IP address on a Cloud Run application, you need to read the X-Forwarded-For
header.
When you just look at the IP address on the request or TCP connection, you'll be seeing the internal IP address of the load balancer that sends the traffic to your application. (169.254.x.x is an internal IP address space defined in RFC 3927, that's why you're seeing "reserved": true
.)
So, in Express, try doing:
var ip = req.header('X-Forwarded-For')
Upvotes: 1
Reputation: 81356
You are sending a reserved IP address from the Private IP space. This address is not valid on the public Internet. The returned response from IPAPI is correct.
IP Addresses in the CIRD block 169.254.0.0/16 are called an Automatic Private IP address. An address in this range is typically used for local reserved network functions and for systems that automatically assign IP addresses without DHCP servers on the network. This address can also be assigned as a result of network failure.
The solution is to use a valid public IP address in your request to IPAPI. If your code is detecting this address, then you have a programming bug.
Note: If you are trying to determine the IP address of your Cloud Run service by checking the network interface, you cannot. Cloud Run is a service that runs behind load balancers call the Global Frontend (GFE). You will need to use an external service to ask "what is my public IP address". The returned IP address will be for the GFE and not for your Cloud Run service.
Upvotes: 1