How can I use an API to detect if an IP address is a VPN in OpenResty?

To detect if an IP address is a VPN using IP2Location.io in OpenResty, you can use the IP2Location.io API to retrieve geolocation and related data.

  1. We'll assume that you have already installed OpenResty and we won't cover that here. You will also need a paid subscription to the Security plan. Subscribe now!
  2. In the command line, run the command below to install the dependency using opm if you don't have it installed.
    Bash
    
    sudo opm get ledgetech/lua-resty-http
    			
  3. Save the below code into a file called test.conf on your computer.
    Nginx
    
    worker_processes  1;
    error_log logs/error.log;
    events {
        worker_connections 1024;
    }
    http {
        resolver 8.8.8.8 ipv6=off;
        server {
            listen 8080 reuseport;
            location / {
                default_type text/html;
                content_by_lua_block {
                    local cjson = require("cjson")
    
                    local key = "YOUR_API_KEY"
                    local ip = "8.8.8.8"
                    local httpc = require("resty.http").new()
    
                    local jsonstr = ""
                    local code = 0
                    local myhost = "api.ip2location.io"
    
                    params = {
                        format = "json",
                        key = key,
                        ip = ip,
                    }
    
                    local ok, err, ssl_session = httpc:connect({
                        scheme = "http",
                        host = myhost,
                        port = 80,
                    })
                    if not ok then
                        ngx.log(ngx.ERR, "connection failed: ", err)
                        return
                    end
    
                    local res, err = httpc:request({
                        path = "/",
                        query = params,
                        headers = {
                            ["Host"] = myhost,
                        },
                    })
                    if not res then
                        ngx.log(ngx.ERR, "request failed: ", err)
                        return
                    end
    
                    local reader = res.body_reader
                    local buffer_size = 8192
                    code = res.status
    
                    repeat
                        local buffer, err = reader(buffer_size)
                        if err then
                            ngx.log(ngx.ERR, err)
                            return
                        end
    
                        if buffer then
                            jsonstr = jsonstr .. buffer
                        end
                    until not buffer
    
                    local trailer = res:read_trailers()
    
                    if trailer then
                        jsonstr = jsonstr .. trailer
                    end
    
                    local ok, err = httpc:set_keepalive()
                    if not ok then
                        ngx.say("failed to set keepalive: ", err)
                        return
                    end
    
                    if code == 200 then
                        local result = cjson.decode(jsonstr)
                        if result["proxy"] ~= nil then
                            if result.proxy.is_vpn then
                                ngx.say("The IP " .. ip .. " is a VPN.")
                            else
                                ngx.say("The IP " .. ip .. " is NOT a VPN.")
                            end
                        else
                            ngx.say("ERROR: The is_vpn field requires a paid subscription to the Security plan.")
                        end
                    elseif code == 400 or code == 401 then
                        local result = cjson.decode(jsonstr)
                        if result["error"] ~= nil then
                            ngx.say("ERROR: " .. result.error.error_message)
                        else
                            ngx.say(jsonstr)
                        end
                    else
                        ngx.say("ERROR: Unable to connect to API.")
                    end
                }
            }
        }
    }
    			
  4. In the command line, run the below command to export the path to the Nginx that is bundled with OpenResty. Modify the path if yours is different. If you have the normal Nginx service installed, make sure it is stopped.
    Bash
    
    export PATH=/usr/local/openresty/nginx/sbin:$PATH
    			
  5. In the command line, run the below commands to start the Nginx and run the test code.
    Bash
    
    nginx -p `pwd`/ -c test.conf
    curl http://localhost:8080/
    			

This script will check if the specified IP address is a VPN. Make sure to replace 8.8.8.8 with the IP address you want and replace YOUR_API_KEY to your own API key.

Other Languages

Unlock Location Insights For Free

Empower your applications with accurate IP geolocation information now.

Try It for Free