Detect whether an IP address belongs to a major cloud provider — offline, with no API calls at lookup time.
This library converts the IP range lists published by each cloud provider into pre-generated regular expressions, bundled with the library, so your application can answer "is this a cloud server IP?" with a simple local match.
Both IPv4 and IPv6 are supported.
- Offline lookup — range data ships inside the jar; no network access at runtime
- IPv4 + IPv6 — full CIDR support, including non-16-bit-aligned IPv6 prefixes
- Provider / region filtering — restrict matching to one provider or one region
- Detailed match results —
findMatchtells you which provider, region, and pattern matched - Safe input handling — never throws for bad input, never performs a DNS lookup
- Refreshable data — one Gradle task re-fetches every provider's published ranges
| Provider | Source | IPv4 | IPv6 |
|---|---|---|---|
| Amazon (AWS) | ip-ranges.amazonaws.com | ✅ | ✅ |
| Microsoft (Azure) | ServiceTags (AzureCloud) | ✅ | ✅ |
| Google (GCP) | cloud.json | ✅ | ✅ |
| CloudFlare | ips-v4 / ips-v6 | ✅ | ✅ |
| DigitalOcean | geo feed | ✅ | ✅ |
| Oracle (OCI) | public_ip_ranges.json | ✅ | — |
| Tencent | Chat service IP list API | ✅ | — |
Oracle and Tencent publish IPv4-only feeds.
- JDK 11+
- Kotlin 1.9+ (for Kotlin consumers; works from Java as well)
Published via JitPack. Add the repository and dependency:
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
mavenCentral()
maven("https://jitpack.io")
}
}// build.gradle.kts
dependencies {
implementation("com.github.developerlee79:server-ip-ranges:v1.0.1")
}Groovy DSL
// settings.gradle
dependencyResolutionManagement {
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
// build.gradle
dependencies {
implementation 'com.github.developerlee79:server-ip-ranges:v1.0.1'
}import com.devlee.ipranges.util.IPRangeUtil
class Test {
fun validateIP(ip: String?): Boolean {
return IPRangeUtil.isServerIP(ip)
}
}import com.devlee.ipranges.util.IPRangeUtil
import com.devlee.ipranges.core.provider.Provider
class Test {
fun validateIP(ip: String?): Boolean {
return IPRangeUtil.isServerIP(ip, Provider.Amazon)
}
fun validateIPWithRegion(ip: String?, region: String): Boolean {
return IPRangeUtil.isServerIP(ip, Provider.Amazon, region)
}
}import com.devlee.ipranges.util.IPRangeUtil
class Test {
fun describeIP(ip: String?) {
val match = IPRangeUtil.findMatch(ip) ?: return
println("provider=${match.provider}, region=${match.region}, pattern=${match.matchedPattern}")
}
}null, blank, and non-IP-literal input (including hostnames) returnfalse/null— no exception is thrown for bad input.- Hostnames are rejected before any
InetAddresscall, so no DNS lookup is ever performed. - Addresses are normalized before matching: compressed IPv6 (
2001:db8::1), uppercase hex, and IPv4-mapped IPv6 (::ffff:1.2.3.4) all work. - A
falseresult covers both "not a cloud IP" and "unparseable input"; usefindMatchplus your own validation when you need to distinguish them.
- Each provider's published range document is parsed into region-grouped CIDR blocks (
range/<provider>/ip-range.json). - Every CIDR block is converted into a regular expression that matches exactly the addresses inside the block (
range/<provider>/ip-regex.json). - At runtime the pre-generated regexes are loaded once per provider (from the working directory if present, otherwise from the jar) and cached.
isServerIP/findMatchnormalize the input address and test it against the cached patterns.
Providers change their ranges over time. Regenerate all data files from a repo checkout:
./gradlew updateRangeFilesThis fetches every provider's live feed, rewrites range/*/ip-range.json and range/*/ip-regex.json, and reports per-provider failures without aborting the whole run. The default ./gradlew test task is hermetic and never touches the network.
Issues and pull requests welcome — provider additions, data corrections, and feature ideas alike.