├── README.md ├── getipintel.go ├── getipintel.net.php ├── getipintel.py └── getipintel.sh /README.md: -------------------------------------------------------------------------------- 1 | # IP Intelligence is a free tool that attempts to determine how likely an IP address is a proxy / VPN / bad IP using mathematical and modern computing techniques 2 | 3 | * Greatly reduce fraud on e-commerce sites (anti-fraud) 4 | * Protect your site from automated hacking attempts such as XSS, SQLi, brute force attacks, application scanning and many others 5 | * Protect your site from crawlers that steal your content 6 | * Prevent users from abusing promotional offers / multiple sign-ups / affiliate abuse 7 | * Stop bots from scraping your content or bots spamming your website 8 | * Serve traffic / content to real users, not bots. Reduce fake views, clicks, and activity that results in click fraud and view fraud (anti-bot detection) 9 | * Prevent trolls / people that are trying to bypass a ban 10 | * Adjust your system to limit access (such as not allowing them to change their password, their email, etc) to prevent account hijacking 11 | * Since the system returns a real value and there's different flag options, you can customize the level of protection for a particular time frame and adjust accordingly 12 | * Use it with a combination of another fraud prevention service to make it even better. Some fraud prevention services do not explicitly look for proxy / VPN / bad IPs 13 | 14 | The system is serving millions of API requests a week and growing as more people find it useful in protecting their online infrastructure. 15 | 16 | ### How it works 17 | 18 | Given an IP address, the system will return a probabilistic value (between a value of ```0``` and ```1```) of how likely the IP is a VPN / proxy / hosting / bad IP. A value of ```1``` means that IP is explicitly banned (a web host, VPN, or TOR node) by our dynamic lists. Otherwise, the output will return a real number value between ```0``` and ```1```, of how likely the IP is bad / VPN / proxy, which is inferred through **machine learning & probability theory techniques** using dynamic checks with large datasets. On average, billions of new records are parsed each month to ensure the datasets have the latest information and old records automatically expire. The system is designed to be efficient, fast, simple, and accurate. 19 | 20 | 21 | ### Interpretation of the Results 22 | If a value of 0.50 is returned, then it is as good as flipping a 2 sided fair coin, which implies it's not very accurate. From my personal experience, values > 0.95 should be looked at and values > 0.99 are most likely proxies. Anything below the value of 0.90 is considered as "low risk". Since a real value is returned, different levels of protection can be implemented. It is best for a system admin to test some sample datasets with this system and adjust implementation accordingly. **I only recommend automated action on high values ( > 0.99 or even > 0.995 ) but it's good practice to manually review IPs that return high values.** For example, mark an order as "under manual review" and don't automatically provision the product for high proxy values. Be sure to experiment with the results of this system before you use it live on your projects. If you believe the result is wrong, don't hesitate to contact me, I can tell you why. If it's an error on my end, I'll correct it. If you email me, expect a reply within 12 hours. 23 | 24 | ___ 25 | 26 | 27 | For a deeper understanding of how the API works and the different ```flags``` and ```oflags``` options available, please visit the [API page](https://getipintel.net/free-proxy-vpn-tor-detection-api/). Standard recommendation is to start off with ```flags=m``` option if only proxy / VPN detection is needed. If ```flags=m``` does not have a noticeable impact, then use ```flags=b```. The default query (no flags) is mostly used infront of a payment gateway to protect against fraud because bad IP detection is included. 28 | 29 | Here are some example code to use GetIPIntel in various code formats. They mainly serve as a proof of concept and should not be implemented directly into your system. 30 | 31 | ### Easy to use Web interface without any coding 32 | A simple web interface lookup is available via https://getipintel.net/free-proxy-vpn-tor-ip-lookup/ 33 | 34 | 35 | ### Full API documentation 36 | No registration or sign up required, only a valid contact email is needed. 37 | 38 | Full API Documentation URL: https://getipintel.net/free-proxy-vpn-tor-detection-api/ 39 | 40 | ___ 41 | 42 | ‎⚠️ If your website / service is proxied through Cloudflare, make sure you're looking up ```CF-Connecting-IP``` in the headers. Any similiar infrastructure setup should also be aware that the correct IP is looked up. 43 | 44 | ### PHP 45 | * requires php curl 46 | 47 | ### Bash 48 | * requires curl 49 | 50 | ### Installation 51 | * **Please change the email variable to your own email** 52 | * Read the documentation on the website for the latest features. If you wish to use flags, change query string. 53 | 54 | ### New features 55 | * added Jun. 2023 - ```oflags=a``` will return the ASN number(s) of the IP that's being looked up. More information is available on the [API page](https://getipintel.net/free-proxy-vpn-tor-detection-api/). 56 | * added Jun. 2023 - ```oflags=i``` will include Google One and Google Fi VPN IPs. 57 | * added Dec. 2021 - ```oflags=i``` for iCloud Relay Egress IPs - by definition it is still a proxy / VPN a user willingly enables, but this option will allow more flexibility on how to handle these IPs. More information is available on the [API page](https://getipintel.net/free-proxy-vpn-tor-detection-api/). 58 | 59 | ### New Changes & Notes 60 | - Feb. 07 2025 - By request of a user, the web interface now returns the looked up IP along with the score. 61 | * Apr. 21 2024 - Added a self lookup IP feature on the web interface. Easy 1 click lookup of your own IP. 62 | * Nov. 23 2023 - Malicious / abnormal traffic dataset has been fully incorporated into the proxy / VPN detection API. As always, you can use oflags=b option to see if an IP behaved badly or not. 63 | * added Nov. 3 2023 - A noticeable sized dataset related to malicious / abnormal traffic is being incorporated into the proxy / VPN detection API. It passed internal testing so I've rolled it out to the free API. I'll keep an eye on the weights and if there's no issues, I'll push it to all services. Feel free to reach out if you have any questions. 64 | -------------------------------------------------------------------------------- /getipintel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | "strconv" 8 | "time" 9 | "os" 10 | ) 11 | 12 | const ( 13 | getIPIntelURL = "http://check.getipintel.net/check.php?" //change URL here if you want to add more arguments 14 | timeout = 5 * time.Second // 5 seconds 15 | maxProbability = 0.99 16 | contactEmail = "yourContactEmail" //Replace with your contact email 17 | ) 18 | 19 | func checkIP(ip string) (bool, error) { 20 | client := &http.Client{Timeout: timeout} 21 | 22 | // Construct the request URL 23 | url := fmt.Sprintf("%sip=%s&contact=%s", getIPIntelURL, ip, contactEmail) 24 | 25 | req, err := http.NewRequest("GET", url, nil) 26 | if err != nil { 27 | return false, fmt.Errorf("error creating request: %w", err) 28 | } 29 | 30 | // Send the request and handle potential errors 31 | resp, err := client.Do(req) 32 | if err != nil { 33 | return false, fmt.Errorf("error sending request: %w", err) 34 | } 35 | defer resp.Body.Close() 36 | 37 | // Read the response body and convert to float 38 | body, err := ioutil.ReadAll(resp.Body) 39 | if err != nil { 40 | return false, fmt.Errorf("error reading response body: %w", err) 41 | } 42 | probability, err := strconv.ParseFloat(string(body), 64) // Use ParseFloat for precision 43 | 44 | if err != nil { 45 | return false, fmt.Errorf("error parsing probability: %w", err) 46 | } 47 | if resp.StatusCode != http.StatusOK { 48 | return false, fmt.Errorf("GetIPIntel API returned error: %s, GetIPIntel error code: %.0f", resp.Status, probability) 49 | } 50 | 51 | return probability > maxProbability, nil 52 | } 53 | 54 | func main() { 55 | // Get the IP address from command-line arguments or user input 56 | if len(os.Args) != 2 { 57 | fmt.Println("Usage: go run main.go ") 58 | return 59 | } 60 | ip := os.Args[1] 61 | 62 | // Check the IP and handle errors 63 | isSuspicious, err := checkIP(ip) 64 | if err != nil { 65 | fmt.Printf("Error: %v\n", err) 66 | return 67 | } 68 | 69 | if isSuspicious { 70 | fmt.Printf("%s is probably a proxy / VPN / bad IP.\n", ip) 71 | } else { 72 | fmt.Printf("%s is probably NOT a proxy / VPN / bad IP.\n", ip) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /getipintel.net.php: -------------------------------------------------------------------------------- 1 | $banOnProbability) { 32 | return true; 33 | } else { 34 | if ($response < 0 || strcmp($response, "") == 0 ) { 35 | //The server returned an error, you might want to do something 36 | //like write to a log file or email yourself 37 | //This could be true due to an invalid input or you've exceeded 38 | //the number of allowed queries. Figure out why this is happening 39 | //because you aren't protected by the system anymore 40 | //Leaving this section blank is dangerous because you assume 41 | //that you're still protected, which is incorrect 42 | //and you might think GetIPIntel isn't accurate anymore 43 | //which is also incorrect. 44 | 45 | //failure to implement error handling is bad for the both of us 46 | 47 | } 48 | return false; 49 | } 50 | } 51 | 52 | 53 | $ip=$_SERVER['REMOTE_ADDR']; 54 | 55 | if (checkProxy($ip)) { 56 | /* A proxy has been detected based on your criteria 57 | * Do whatever you want to here 58 | */ 59 | echo "It appears you're a Proxy / VPN / bad IP, please contact [put something here] for more information
"; 60 | } 61 | 62 | ?> 63 | -------------------------------------------------------------------------------- /getipintel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import requests 3 | import sys 4 | def checkIP(ip): 5 | #change this variable to your email address 6 | contactEmail="YourEmailAddress" 7 | #if probability from getIPIntel is grater than this value, return 1 8 | maxProbability=0.99 9 | timeout=5.00 10 | #if you wish to use flags or json format, edit the request below 11 | result = requests.get("http://check.getipintel.net/check.php?ip="+ip+"&contact="+contactEmail, timeout=timeout) 12 | if (result.status_code != 200) or (float(result.content) < 0): 13 | sys.stderr.write("An error occured while querying GetIPIntel") 14 | if (float(result.content) > maxProbability): 15 | return 1 16 | else: 17 | return 0 18 | 19 | -------------------------------------------------------------------------------- /getipintel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #you must change this to your own email address 4 | contactEmail="ValidContactEamilAddress"; 5 | 6 | if [[ "$1" == "" || "$1" == "-h" || "$1" == "--help" ]]; then 7 | echo "GetIPIntel.net query script takes a filename as a parameter or an IP address 8 | Example: bash getipintel.sh IPList 9 | bash getipintel.sh 127.0.0.1 10 | The file should have each IP on a new line. 11 | IP and score are separated by a comma. 12 | Please add a valid contact email and read the comments before using. 13 | Full API documentation: https://getipintel.net/free-proxy-vpn-tor-detection-api/" 14 | 15 | exit 0; 16 | fi 17 | 18 | 19 | if [ -f "$1" ]; then 20 | for f in `cat $1`; do 21 | echo -n "$f,"; 22 | curl -s "https://check.getipintel.net/check.php?ip=$f&contact=$contactEmail"; 23 | echo ""; 24 | #uncomment the sleep if you're using the free API to adhere to the 15 queries per minute limit 25 | #sleep 4; 26 | done 27 | else 28 | echo -n "$1,"; 29 | curl -s "https://check.getipintel.net/check.php?ip=$1&contact=$contactEmail"; 30 | echo ""; 31 | fi 32 | --------------------------------------------------------------------------------