Skip to content

bitinerant/myorigin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MyOrigin

Fast, fault-tolerant public IP address retrieval from Python or CLI.

The primary goal of this project is to find the public IP address (sometimes called an external IP address) reliably. This means it works with or without UPnP, dual NAT, DNS manipulation by the ISP, a VPN, or any single public web API or STUN server. It simultaneously queries multiple external sources at random from a long list, recovers gracefully from failed queries, and does not return an IP address unless all the responses agree.

Installation

pip install myorigin

Command line usage

$ myorigin -v
08:54:32.904 INFO requests (need 2 matches):
08:54:33.552 INFO     http://zx2c4.com/ip → 88.123.8.180 (640 ms; 33 of 34 succeeded)
08:54:33.743 INFO     https://myip.dnsomatic.com/ → 429 Too Many Requests (30 of 35 succeeded)
08:54:34.573 INFO     http://ip.websupport.sk/ → 88.123.8.180 (814 ms; 34 of 34 succeeded)
08:54:34.584 INFO IP found: 88.123.8.180 (2 successes, 1 failures)
88.123.8.180
$ 
$ myorigin --help
usage: myorigin [-h] [-t TIMEOUT] [--minimum-match MINIMUM_MATCH]
                [--overkill OVERKILL] [--majority-ratio MAJORITY_RATIO]
                [--max-failures MAX_FAILURES]
                [--max-connections MAX_CONNECTIONS] [--dbfile DBFILE]
                [--show-api-providers] [-4] [-6] [-l LOGFILE] [-q] [-v]

options:
  -h, --help                         show this help message and exit
  -t TIMEOUT, --timeout TIMEOUT      approximate timeout for http and https
                                     requests in milliseconds (default: 12000)
  --minimum-match MINIMUM_MATCH      an IP address is considered valid after
                                     this number of idential responses
                                     (default: 2)
  --overkill OVERKILL                number of initial requests to make beyond
                                     minimum-match (default: 0)
  --majority-ratio MAJORITY_RATIO    minimum ratio needed to overrule a
                                     conflicting response; must be an integer;
                                     a value of 2 means 2:1, or that 6
                                     responses of 8.7.8.7 are needed to
                                     overrule 3 responses of 7.8.4.4 (default:
                                     3)
  --max-failures MAX_FAILURES        maximum number of failed requests allowed
                                     (default: 10)
  --max-connections MAX_CONNECTIONS  maximum number of simultaneous network
                                     connections allowed (default: 10)
  --dbfile DBFILE                    path for database file ('-' for memory-
                                     only; default:
                                     ~/.config/myorigin/data.sqlite)
  --show-api-providers               display the database of IP address API
                                     providers in a human-readable form and
                                     exit
  -4, --ipv4                         use IPv4 only; note this or --ipv6 is
                                     highly recommended if both IPv4 and IPv6
                                     are available, in order to avoid wasteful
                                     network traffic and unpredictable results
                                     (sometimes --minimum-match IPv4 addresses
                                     will be received first, and sometimes
                                     IPv6 will win)
  -6, --ipv6                         use IPv6 only
  -l LOGFILE, --logfile LOGFILE      path for log file (default: write to
                                     STDERR)
  -q, --quiet                        silence warning messages
  -v, --verbose                      increase verbosity
$ 

Library import usage

>>> import myorigin
>>> args = myorigin.MyoriginArgs()
>>> args.minimum_match = 4
>>> myorigin.my_ip(args)
'88.123.8.180'
>>> 
>>> args.exception_level = 2
>>> args.ip_version = 6  # but there is no IPv6 on this LAN
>>> try:
...     myorigin.my_ip(args)
... except myorigin.NetworkError as e:
...     print(f"got error: {e}")
... 
got error: 10 requests failed; giving up
>>> 

Features

  • retrieves your IP address from any of 135 IP address providers
  • confirms the correct IP address by checking muliple providers (default 2)
  • recovers from failures by making additional requests of other providers
  • keeps a record of past successes and prioritizes the fastest and most reliable providers from your location
  • makes simultaneous IP address requests
  • supports http, https, IPv4, IPv6

Limitations

  • has only been tested on Ubuntu Linux, though, being 100% Python, this should work on Windows, macOS, other Linux and BSDs, etc.
  • has not been field-tested

Similiar projects

  • Go External IP: "a Golang library to get your external ip from multiple services"
  • gip: "a command-line tool to get global IP address"; written in Rust
  • Discovering public IP programmatically: Stack Overflow discussion (16 answers)
  • PyNAT: "Discover external IP addresses and NAT topologies using STUN"
  • pubip: "get public IP address"; written in Go

Did you find a mistake or have a suggestion? With a GitHub account, it's easy to suggest changes.

About

Fast, fault-tolerant public IP address retrieval from Python or CLI.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages