[feature] Extract IP address from netif credit: @comicchang

This commit is contained in:
Timothy Miller 2023-02-15 16:14:22 -05:00
parent c135a7d343
commit cb7b1804cf
4 changed files with 92 additions and 38 deletions

View File

@ -10,10 +10,12 @@ Access your home network remotely via a custom domain name without a static IP!
- 🔁 The Python runtime will re-use existing HTTP connections.
- 🗃️ Cloudflare API responses are cached to reduce API usage.
- 🤏 The Docker image is small and efficient.
- 0⃣ Zero dependencies.
- 0⃣ Zero weirdo dependencies.
- 💪 Supports all platforms.
- 🏠 Enables low cost self hosting to promote a more decentralized internet.
- 🔒 Zero-log IP provider ([cdn-cgi/trace](https://www.cloudflare.com/cdn-cgi/trace))
- 🧑‍🚀 Supports NAT and multiple network interfaces.
- 🔒 HTTP [(Zero-log IP provider)](https://www.cloudflare.com/cdn-cgi/trace)
- 💻 [Netif](https://pypi.org/project/netifaces/): `ppp0`, `eth0`, `wlan0`, etc.
- 👐 GPL-3.0 License. Open source for open audits.
## 💯 Complete Support of Domain Names, Subdomains, and IPv4 & IPv6
@ -69,6 +71,15 @@ Some ISP provided modems only allow port forwarding over IPv4 or IPv6. In this c
"aaaa": true
```
### 🧑‍🚀 Method used for getting IP address
If you have multiple network interfaces, or if you are behind nat, you may need to enable alternative way to determine your IP address(es).
```json
"method": "netif",
"interface": "ppp0"
```
### 🎛️ Other values explained
```json
@ -123,7 +134,9 @@ Do not include the base domain name in your `subdomains` config. Do not use the
"a": true,
"aaaa": true,
"purgeUnknownRecords": false,
"ttl": 300
"ttl": 300,
"method": "http",
"interface": ""
}
```
@ -181,7 +194,10 @@ If you are using API Tokens, make sure the token used supports editing your zone
],
"a": true,
"aaaa": true,
"purgeUnknownRecords": false
"purgeUnknownRecords": false,
"ttl": 300,
"method": "http",
"interface": ""
}
```

View File

@ -6,7 +6,7 @@
# A small, 🕵️ privacy centric, and ⚡
# lightning fast multi-architecture Docker image for self hosting projects.
__version__ = "1.0.2"
__version__ = "1.0.3"
import json
import os
@ -15,6 +15,7 @@ import sys
import threading
import time
import requests
import netifaces as ni
CONFIG_PATH = os.environ.get('CONFIG_PATH', os.getcwd())
@ -56,53 +57,80 @@ def getIPs():
global ipv4_enabled
global ipv6_enabled
global purgeUnknownRecords
global method
global interfaces
if ipv4_enabled:
try:
a = requests.get(
"https://1.1.1.1/cdn-cgi/trace").text.split("\n")
a.pop()
a = dict(s.split("=") for s in a)["ip"]
except Exception:
global shown_ipv4_warning
if not shown_ipv4_warning:
shown_ipv4_warning = True
print("🧩 IPv4 not detected via 1.1.1.1, trying 1.0.0.1")
# Try secondary IP check
if method == 'http':
try:
a = requests.get(
"https://1.0.0.1/cdn-cgi/trace").text.split("\n")
"https://1.1.1.1/cdn-cgi/trace").text.split("\n")
a.pop()
a = dict(s.split("=") for s in a)["ip"]
except Exception:
global shown_ipv4_warning_secondary
if not shown_ipv4_warning_secondary:
shown_ipv4_warning_secondary = True
print("🧩 IPv4 not detected via 1.0.0.1. Verify your ISP or DNS provider isn't blocking Cloudflare's IPs.")
global shown_ipv4_warning
if not shown_ipv4_warning:
shown_ipv4_warning = True
print("🧩 IPv4 not detected via 1.1.1.1, trying 1.0.0.1")
# Try secondary IP check
try:
a = requests.get(
"https://1.0.0.1/cdn-cgi/trace").text.split("\n")
a.pop()
a = dict(s.split("=") for s in a)["ip"]
except Exception:
global shown_ipv4_warning_secondary
if not shown_ipv4_warning_secondary:
shown_ipv4_warning_secondary = True
print("🧩 IPv4 not detected via 1.0.0.1. Verify your ISP or DNS provider isn't blocking Cloudflare's IPs.")
if purgeUnknownRecords:
deleteEntries("A")
else:
try:
a = ni.ifaddresses(interface)[ni.AF_INET][0]['addr']
except Exception:
global shown_ipv4_warning
if not shown_ipv4_warning:
shown_ipv4_warning = True
print("🧩 IPv4 not detected via " + interface + ". Verify your interface is up and has an IPv4 address.")
if purgeUnknownRecords:
deleteEntries("A")
if ipv6_enabled:
try:
aaaa = requests.get(
"https://[2606:4700:4700::1111]/cdn-cgi/trace").text.split("\n")
aaaa.pop()
aaaa = dict(s.split("=") for s in aaaa)["ip"]
except Exception:
global shown_ipv6_warning
if not shown_ipv6_warning:
shown_ipv6_warning = True
print("🧩 IPv6 not detected via 1.1.1.1, trying 1.0.0.1")
if method == 'http':
try:
aaaa = requests.get(
"https://[2606:4700:4700::1001]/cdn-cgi/trace").text.split("\n")
"https://[2606:4700:4700::1111]/cdn-cgi/trace").text.split("\n")
aaaa.pop()
aaaa = dict(s.split("=") for s in aaaa)["ip"]
except Exception:
global shown_ipv6_warning_secondary
if not shown_ipv6_warning_secondary:
shown_ipv6_warning_secondary = True
print("🧩 IPv6 not detected via 1.0.0.1. Verify your ISP or DNS provider isn't blocking Cloudflare's IPs.")
global shown_ipv6_warning
if not shown_ipv6_warning:
shown_ipv6_warning = True
print("🧩 IPv6 not detected via 1.1.1.1, trying 1.0.0.1")
try:
aaaa = requests.get(
"https://[2606:4700:4700::1001]/cdn-cgi/trace").text.split("\n")
aaaa.pop()
aaaa = dict(s.split("=") for s in aaaa)["ip"]
except Exception:
global shown_ipv6_warning_secondary
if not shown_ipv6_warning_secondary:
shown_ipv6_warning_secondary = True
print("🧩 IPv6 not detected via 1.0.0.1. Verify your ISP or DNS provider isn't blocking Cloudflare's IPs.")
if purgeUnknownRecords:
deleteEntries("AAAA")
else:
try:
aaaa = ni.ifaddresses(interface)[ni.AF_INET6][0]['addr']
except Exception:
global shown_ipv6_warning
if not shown_ipv6_warning:
shown_ipv6_warning = True
print("🧩 IPv6 not detected via " + interface + ". Verify your interface is up and has an IPv6 address.")
if purgeUnknownRecords:
deleteEntries("AAAA")
ips = {}
if (a is not None):
ips["ipv4"] = {
@ -232,6 +260,8 @@ if __name__ == '__main__':
ipv4_enabled = True
ipv6_enabled = True
purgeUnknownRecords = False
method = 'http'
interface = ''
if sys.version_info < (3, 5):
raise Exception("🐍 This script requires Python 3.5+")
@ -253,6 +283,11 @@ if __name__ == '__main__':
ipv4_enabled = True
ipv6_enabled = True
print("⚙️ Individually disable IPv4 or IPv6 with new config.json options. Read more about it here: https://github.com/timothymiller/cloudflare-ddns/blob/master/README.md")
try:
method = config["method"]
interface = config["interface"]
except:
print("⚙️ No config detected for 'method' - defaulting to 'http'")
try:
purgeUnknownRecords = config["purgeUnknownRecords"]
except:

View File

@ -24,5 +24,7 @@
"a": true,
"aaaa": true,
"purgeUnknownRecords": false,
"ttl": 300
"ttl": 300,
"method": "http",
"interface": ""
}

View File

@ -1 +1,2 @@
requests==2.28.2
netifaces==0.11.0