Coder Social home page Coder Social logo

django-ipware's Introduction

Django IPware (Read Notice)

A Django application to retrieve client's IP address

status-image version-image coverage-image

Overview

Best attempt to get client's IP address while keeping it DRY.

Notice

There is no perfect out-of-the-box solution against fake IP addresses, aka IP Address Spoofing. You are encouraged to read the (Advanced users) section of this page and use trusted_proxies_ips and/or proxy_count features to match your needs, especially if you are planning to include ipware in any authentication, security or anti-fraud related architecture.

This is an open source project, with the source code visible to all. Therefore, it may be exploited through unimplemented, or improperly implemented features.

Please use ipware ONLY as a complement to your firewall security measures!

How to install

1. easy_install django-ipware
2. pip install django-ipware
3. git clone http://github.com/un33k/django-ipware
    a. cd django-ipware
    b. run python setup.py install
4. wget https://github.com/un33k/django-ipware/zipball/master
    a. unzip the downloaded file
    b. cd into django-ipware-* directory
    c. run python setup.py install

How to use

 # In a view or a middleware where the `request` object is available

 from ipware import get_client_ip
 client_ip, is_routable = get_client_ip(request)
 if client_ip is None:
    # Unable to get the client's IP address
 else:
     # We got the client's IP address
     if is_routable:
         # The client's IP address is publicly routable on the Internet
     else:
         # The client's IP address is private

 # Order of precedence is (Public, Private, Loopback, None)

Advanced users:

  • Precedence Order

    The default meta precedence order is top to bottom. However, you may customize the order by providing your own IPWARE_META_PRECEDENCE_ORDER by adding it to your project's settings.py

     # The default meta precedence order
     IPWARE_META_PRECEDENCE_ORDER = (
         'HTTP_X_FORWARDED_FOR', 'X_FORWARDED_FOR',  # <client>, <proxy1>, <proxy2>
         'HTTP_CLIENT_IP',
         'HTTP_X_REAL_IP',
         'HTTP_X_FORWARDED',
         'HTTP_X_CLUSTER_CLIENT_IP',
         'HTTP_FORWARDED_FOR',
         'HTTP_FORWARDED',
         'HTTP_VIA',
         'REMOTE_ADDR',
     )

    Alternatively, you can provide your custom request header meta precedence order when calling get_client_ip().

get_client_ip(request, request_header_order=['X_FORWARDED_FOR'])
get_client_ip(request, request_header_order=['X_FORWARDED_FOR', 'HTTP_X_FORWARDED_FOR'])

Private Prefixes

You may customize the prefixes to indicate an IP address is private. This is done by adding your own IPWARE_PRIVATE_IP_PREFIX to your project's settings.py. IP addresses matching the following prefixes are considered private & are not publicly routable.

# The default private IP prefixes
IPWARE_PRIVATE_IP_PREFIX = getattr(settings,
   'IPWARE_PRIVATE_IP_PREFIX', (
     '0.',  # messages to software
     '10.',  # class A private block
     '100.64.',  '100.65.',  '100.66.',  '100.67.',  '100.68.',  '100.69.',
     '100.70.',  '100.71.',  '100.72.',  '100.73.',  '100.74.',  '100.75.',
     '100.76.',  '100.77.',  '100.78.',  '100.79.',  '100.80.',  '100.81.',
     '100.82.',  '100.83.',  '100.84.',  '100.85.',  '100.86.',  '100.87.',
     '100.88.',  '100.89.',  '100.90.',  '100.91.',  '100.92.',  '100.93.',
     '100.94.',  '100.95.',  '100.96.',  '100.97.',  '100.98.',  '100.99.',
     '100.100.', '100.101.', '100.102.', '100.103.', '100.104.', '100.105.',
     '100.106.', '100.107.', '100.108.', '100.109.', '100.110.', '100.111.',
     '100.112.', '100.113.', '100.114.', '100.115.', '100.116.', '100.117.',
     '100.118.', '100.119.', '100.120.', '100.121.', '100.122.', '100.123.',
     '100.124.', '100.125.', '100.126.', '100.127.',  # carrier-grade NAT
     '169.254.',  # link-local block
     '172.16.', '172.17.', '172.18.', '172.19.',
     '172.20.', '172.21.', '172.22.', '172.23.',
     '172.24.', '172.25.', '172.26.', '172.27.',
     '172.28.', '172.29.', '172.30.', '172.31.',  # class B private blocks
     '192.0.0.',  # reserved for IANA special purpose address registry
     '192.0.2.',  # reserved for documentation and example code
     '192.168.',  # class C private block
     '198.18.', '198.19.',  # reserved for inter-network communications between two separate subnets
     '198.51.100.',  # reserved for documentation and example code
     '203.0.113.',  # reserved for documentation and example code
     '224.', '225.', '226.', '227.', '228.', '229.', '230.', '231.', '232.',
     '233.', '234.', '235.', '236.', '237.', '238.', '239.',  # multicast
     '240.', '241.', '242.', '243.', '244.', '245.', '246.', '247.', '248.',
     '249.', '250.', '251.', '252.', '253.', '254.', '255.',  # reserved
   ) + (
     '::',  # Unspecified address
     '::ffff:', '2001:10:', '2001:20:'  # messages to software
     '2001::',  # TEREDO
     '2001:2::',  # benchmarking
     '2001:db8:',  # reserved for documentation and example code
     'fc00:',  # IPv6 private block
     'fe80:',  # link-local unicast
     'ff00:',  # IPv6 multicast
   )
)

Trusted Proxies

If your Django server is behind one or more known proxy server(s), you can filter out unwanted requests by providing the trusted proxy list when calling get_client_ip(request, proxy_trusted_ips=['177.139.233.133']). In the following example, your load balancer (LB) can be seen as a trusted proxy.

 `Real` Client  <public> <---> <public> LB (Server) <private> <--------> <private> Django Server
                                                                   ^
                                                                   |
 `Fake` Client  <private> <---> <private> LB (Server) <private> ---^
# In the above scenario, use your load balancer IP address as a way to filter out unwanted requests.
client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133'])

# If you have multiple proxies, simply add them to the list
client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133', '177.139.233.134'])

# For proxy servers with fixed sub-domain and dynamic IP, use the following pattern.
client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.', '177.140'])
client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.', '177.139.240'])

Please note: By default, the right-most proxy in the chain is the trusted proxy and that is the one your django server talks to. Therefore, ipware checks to see if the right-most proxy address starts with any ip pattern that was passed in via the proxy_trusted_ips list.

Proxy Count

If your Django server is behind a known number of proxy server(s), you can filter out unwanted requests by providing the number of proxies when calling get_client_ip(request, proxy_count=1). In the following example, your load balancer (LB) can be seen as the only proxy.

 `Real` Client  <public> <---> <public> LB (Server) <private> <--------> <private> Django Server
                                                                   ^
                                                                   |
                                       `Fake` Client  <private> ---^
# In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests.
client_ip, is_routable = get_client_ip(request, proxy_count=1)

# The above may be very useful in cases where your proxy server's IP address is assigned dynamically.
# However, If you have the proxy IP address, you can use it in combination to the proxy count.
client_ip, is_routable = get_client_ip(request, proxy_count=1, proxy_trusted_ips=['177.139.233.133'])

Originating Request

If your proxy server is configured such that the right-most IP address is that of the originating client, you can indicate right-most as your proxy_order when calling get_client_ip(request, proxy_order="right-most"). Please note that the de-facto standard for the originating client IP address is the left-most as per <client>, <proxy1>, <proxy2>.

Running the tests

To run the tests against the current environment:

python manage.py test

License

Released under a (MIT) license.

Version

X.Y.Z Version

`MAJOR` version -- when you make incompatible API changes,
`MINOR` version -- when you add functionality in a backwards-compatible manner, and
`PATCH` version -- when you make backwards-compatible bug fixes.

Sponsors

Neekware Inc.

django-ipware's People

Contributors

adamchainz avatar awais786 avatar bashu avatar edsfocci avatar felixxm avatar gopackgo90 avatar illagrenan avatar jchappell82 avatar joshuadavidthomas avatar kishorkunal-raj avatar lorddaedra avatar mcroni avatar mikaraunio avatar petrdlouhy avatar sabueso avatar sinwoobang avatar therefromhere avatar un33k avatar uneekvu avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.