Get your public IP, VPN/proxy status and risk score with one curl command
DEV Community

Get your public IP, VPN/proxy status and risk score with one curl command

Get your public IP, VPN/proxy status and risk score with one curl command

Most "what's my IP" sites are built for browsers. Call them from a script and you get a full HTML page back, or you're asked to sign up for an API key just to read one line of text. I run checkip.me, a free IP lookup service, and I wanted it to work well from a terminal. So this post is partly a how-to and partly a plug. Everything below works without an account or a key.

Basic usage

Just curl it:

curl checkip.me
203.0.113.42

You get plain text back, which is what you want in a script. On Windows 10/11 use curl.exe, because in PowerShell curl is an alias for Invoke-WebRequest.

Choosing IPv4 or IPv6

If you have both IPv4 and IPv6, curl may pick either one. Add -4 or -6 to choose:

curl -4 checkip.me
curl -6 checkip.me

JSON and field-specific endpoints

/details or /json gives you the network and location info for your own IP. Put another address in the path to look that one up instead:

curl checkip.me/json
curl checkip.me/1.1.1.1
{
  "ip": "203.0.113.42",
  "asn": "AS45899",
  "isp": "VNPT Corp",
  "country": "Vietnam",
  "city": "Hanoi",
  "timezone": "Asia/Bangkok",
  "vpn": false,
  "proxy": false,
  "tor": false,
  "hosting": false,
  ...
}

If you only need one value, add the field name to the path. It comes back as plain text, so you don't need jq:

curl checkip.me/country        # Vietnam
curl checkip.me/1.1.1.1/isp    # Cloudflare, Inc.
curl checkip.me/1.1.1.1/hosting # true
curl checkip.me/vpn            # false

curl checkip.me/help lists every field.

A tiny dynamic DNS script

This is the most common reason to fetch your IP from a script. It remembers the last address and only does something when it changes:

#!/usr/bin/env bash
set -euo pipefail

STATE_FILE="$HOME/.last_ip"
CURRENT=$(curl -fs -4 --max-time 10 checkip.me)
LAST=$(cat "$STATE_FILE" 2>/dev/null || true)

if [ "$CURRENT" != "$LAST" ]; then
  echo "IP changed: ${LAST:-none} -> $CURRENT"
  # call your DNS provider's API here
  echo "$CURRENT" > "$STATE_FILE"
fi

Run it from cron every few minutes. -f makes curl fail on an HTTP error instead of saving the error message as your "IP", -s keeps the progress meter out of the variable, and --max-time stops a slow network from hanging the job.

Locking SSH to your current IP with Terraform

If you manage a bastion host with Terraform, you can pass your address in at apply time:

variable "my_ip" {
  type = string
}

resource "aws_security_group_rule" "ssh_from_me" {
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["${var.my_ip}/32"]
  security_group_id = aws_security_group.bastion.id
}
terraform apply -var "my_ip=$(curl -s -4 checkip.me)"

Don't drop the -4. If curl picks IPv6, you end up with an IPv6 address followed by /32, and Terraform refuses it as an invalid CIDR block.

From code

CORS is enabled, so this works from a browser as well as from Node 18+. The JavaScript snippet uses top-level await, so run it in an ES module or the browser console.

Python:

import requests

ip = requests.get("https://checkip.me/ip", timeout=10).text.strip()
info = requests.get(f"https://checkip.me/{ip}", timeout=10).json()
print(ip, info["country"], info["isp"])

JavaScript:

const info = await fetch("https://checkip.me/json").then(r => r.json());
console.log(info.ip, info.country, info.vpn);

Limits

  • Looking up your own IP has no limit. Looking up other IPs is capped at 60 per hour per visitor. Past that you get HTTP 429 with a Retry-After header.
  • Results for other IPs are cached, so they can be up to 30 days old.
  • Location comes from IP geolocation data. The country is usually right, but the city is often only approximate, like with every service of this kind.
  • The VPN, proxy and Tor flags are good hints, but don't rely on them for anything security-critical.

Docs are at checkip.me/api.

What would you add?

I'm deciding which fields and endpoints come next, so tell me what you'd actually use. I run checkip.me. I wrote this post with help from an AI assistant and tested every command before publishing.

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.