Faced (again!) with the need for a reliable and straightforward external IP lookup service, I was searching again for the next external IP service. I have run into SaaS service, DDNS providers, Chrome Extension scrapers – the works.
I decided to come up with a better way that will fix this forever – which I will never have to change again – ever!
- No credits to manage or run out.
- No separate accounts to keep track of.
- No changes in service that need management
- No SaaS models with recurring costs, subscription fees, credit card updates and Terms of Service
- No Management!
I already have an AWS Account – and our company will have this account – forever. So I decided to leverage AWS Lambda to create the simple service and ‘hides’ it behind an obfusticated URL that one will be able to guess.
Here’s How I Did It:
- Start a New Lambda Function: Within your AWS account, navigate to the Lambda service and initiate a new function.
- Insert the Code: Copy and paste the following code into the Lambda code editor:
lambda_handler(event, context):
client_ip = event['requestContext']['http']['sourceIp']
return {
'statusCode': 200,
'body': f'{client_ip}'
}
- Deploy Your Function: Click “Deploy” to save your changes.
- Enable Public Access: Click “Configuration” and then “Function URL” and enable the public URL. (Enable ‘CORS’ to use this from Javascript or in a browser)
- Open: Click the provided function URL – and use this in any script.
Configuration
- Use the minimum configuration – 128 MB memory and 512MB of ephemeral storage
- Enable the Function URL in order to be able to access this remotely / from your browser
- Permissions – none needed! if you need permissions you are doing something custom (and I would love to know about it)
Understanding the Costs:
If you use fewer than 1 Million requests a month – it is in their Free Tier
- I wanted to know the actual cost – so I went to their calculator and started adding zeros to the number requests until it registered a cost. It would take 100,000 requests a month (3,000 per day) and it would cost $0.04.
- Since I use may 500 / per month – I think the cost is too low to calculate.
- Here is my screen shot of their calculations from their calculator
Frequently Asked Questions:
- Is it secure?
- I don’t know, you tell me – it has a function URL which functions like an API key – only you know that URL until you expose it to someone…..
- Can I integrate this with my applications?
- Yes! some examples below
- Do I track the usage?
- No, i can look at the cloud watch logs but when I look at the Lambda costs on my AWS bill and it is less an $0.01 I dont care.
Language/Framework | One-Liner Usage |
---|---|
PHP | $ip = file_get_contents("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/"); |
jQuery | $.get("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/", function(ip) { console.log(ip); }); |
JavaScript (Fetch API) | fetch("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/").then(response => response.text()).then(ip => console.log(ip)); |
Python | import requests\nip = requests.get("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/").text |
Go | resp, _ := http.Get("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/")\nbody, _ := ioutil.ReadAll(resp.Body)\nfmt.Println(string(body)) |
ASP.NET (C#) | var ip = new WebClient().DownloadString("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/"); |
TypeScript (Fetch API) | fetch("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/").then(response => response.text()).then(ip => console.log(ip)); |
Ruby | ip = URI.open("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/").read |
Java | String ip = new Scanner(new URL("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/").openStream(), "UTF-8").useDelimiter("\\A").next(); |
Node.js (Axios) | const axios = require('axios');\naxios.get("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/").then(response => console.log(response.data)); |
Swift (URLSession) | URLSession.shared.dataTask(with: URL(string: "https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/")!) { data, _, _ in\nif let data = data { print(String(data: data, encoding: .utf8)!) }}.resume() |
Kotlin (HttpURLConnection) | val url = URL("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/")\nval ip = url.readText() |
Perl | use LWP::Simple;\n$ip = get("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/"); |
Rust (reqwest) | let resp = reqwest::blocking::get("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/")?.text()?; |
Dart (http package) | var url = Uri.parse('https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/');\nvar response = await http.get(url);\nprint(response.body); |
Shell (curl) | ip=$(curl -s https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/) |
Scala (scala.io.Source) | val ip = scala.io.Source.fromURL("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/").mkString |
Clojure (clj-http) | (require '[clj-http.client :as client])\n(let [response (client/get "https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/")]\n (println (:body response))) |
Elixir (HTTPoison) | case HTTPoison.get("https://xyxxyxyxyxyxyxyxyx.lambda-url.us-west-2.on.aws/") do\n {:ok, %HTTPoison.Response{body: body}} -> IO.puts(body)\n {:error, _} -> IO.puts("Error")\nend |