How to detect vpn in django?

I want to find out if a user is using a VPN when a user sends a request to the API (to warn the user that he is using a VPN and to use the API he must turn off the VPN)

I get the user’s IP using the following code:

def get_client_ip(request):
   x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
   if x_forwarded_for:
       ip_list = x_forwarded_for.split(',')
       return ip_list[0].strip()
   return request.META.get('REMOTE_ADDR')

But there are different ways to detect the use of VPN by the user, which are limited and also not free Is there a way to solve this problem?

Are you looking to detect someone using any VPN, or using one specific (e.g. corporate) VPN?

If it’s a corporate VPN situation, then you should be able to identify the subnet that the VPN is configured to use.

No i want to detect someone using any type of VPN not specific!

That’s an interesting topic! I just searched the internet for “detect VPN connection” and found a number of blog posts, etc, that talk about this issue.

The bottom line is that no method is going to be 100% effective and it’s a never-ending battle between those creating VPN enpoints and the people trying to detect them. (And, from what I can see, a “private” VPN used by a very small number of people is going to be nearly impossible to identify.)

Yes, tell me about it
Apparently, there is no 100% solution for this issue
But I want to increase this percentage as much as possible
And honestly, one solution is to have a list of VPV IPs that should always be updated and through it we can find out whether the user is using VPN or not, which is a very difficult task.

I don’t know if this has been resolved, but you can use the Maxmind Anonymous IP database.

>>> import geoip2.database
>>>
>>> # This creates a Reader object. You should use the same object
>>> # across multiple requests as creation of it is expensive.
>>> with geoip2.database.Reader('/path/to/GeoIP2-Anonymous-IP.mmdb') as reader:
>>>
>>>     response = reader.anonymous_ip('203.0.113.0')
>>>
>>>     response.is_anonymous
True
>>>     response.is_anonymous_vpn
False
>>>     response.is_hosting_provider
False
>>>     response.is_public_proxy
False
>>>     response.is_residential_proxy
False
>>>     response.is_tor_exit_node
True
>>>     response.ip_address
'203.0.113.0'
>>>     response.network
IPv4Network('203.0.113.0/24')

not 100% effective, just like what @KenWhitesell said, but still works, and I hope you can increase the percentage as much as possible.