Add --me flag to display local and public IPs with CGNAT detection
This commit introduces the --me flag, which allows users to quickly display their current local IPv4 and public IPv4/IPv6 addresses. The public IPs are retrieved using ifconfig.me via curl, ensuring accurate detection even in CGNAT or split-DNS scenarios. Local IPv4 is determined via the system's active route through the configured resolver. The output also includes a CGNAT detection based on private IP ranges and the reserved 100.64.0.0/10 block, providing a helpful warning if detected. IPv6 privacy extensions are common, so local IPv6 detection has been removed to avoid redundant or unstable information.
This commit is contained in:
parent
7058e26be3
commit
fb00a11bef
59
chkip.py
59
chkip.py
@ -5,6 +5,7 @@
|
|||||||
chkip.py – DNS- und Mailserver-Check-Tool
|
chkip.py – DNS- und Mailserver-Check-Tool
|
||||||
|
|
||||||
Erstellt von Pascal Bouquet am 17.04.2025
|
Erstellt von Pascal Bouquet am 17.04.2025
|
||||||
|
Aktualisiert am 19.04.2025
|
||||||
|
|
||||||
Dieses Programm ist freie Software: Sie können es unter den Bedingungen der
|
Dieses Programm ist freie Software: Sie können es unter den Bedingungen der
|
||||||
GNU General Public License, wie von der Free Software Foundation veröffentlicht,
|
GNU General Public License, wie von der Free Software Foundation veröffentlicht,
|
||||||
@ -20,6 +21,7 @@ Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
|
|||||||
Programm erhalten haben. Falls nicht, siehe <https://www.gnu.org/licenses/>.
|
Programm erhalten haben. Falls nicht, siehe <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import ipaddress
|
import ipaddress
|
||||||
@ -28,6 +30,8 @@ import dns.reversename
|
|||||||
import requests
|
import requests
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
|
||||||
# Resolver festlegen
|
# Resolver festlegen
|
||||||
resolver = dns.resolver.Resolver()
|
resolver = dns.resolver.Resolver()
|
||||||
@ -122,6 +126,43 @@ def resolve_tlsa(domain, mx_host):
|
|||||||
except:
|
except:
|
||||||
return "No TLSA record found"
|
return "No TLSA record found"
|
||||||
|
|
||||||
|
def get_local_ipv4():
|
||||||
|
try:
|
||||||
|
ip = next((ip for ip in resolver.nameservers if '.' in ip), '1.1.1.1')
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
s.connect((ip, 80))
|
||||||
|
local_ip = s.getsockname()[0]
|
||||||
|
s.close()
|
||||||
|
return local_ip
|
||||||
|
except:
|
||||||
|
return "unavailable"
|
||||||
|
|
||||||
|
def get_my_ip():
|
||||||
|
def run_curl(protocol_flag):
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["curl", "-s", protocol_flag, "ifconfig.me/ip"],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
timeout=2,
|
||||||
|
text=True
|
||||||
|
)
|
||||||
|
return result.stdout.strip()
|
||||||
|
except:
|
||||||
|
return "unavailable"
|
||||||
|
|
||||||
|
local_v4 = get_local_ipv4()
|
||||||
|
public_v4 = run_curl("-4")
|
||||||
|
public_v6 = run_curl("-6")
|
||||||
|
return local_v4, public_v4, public_v6
|
||||||
|
|
||||||
|
def is_cgnat(ip):
|
||||||
|
try:
|
||||||
|
ip_obj = ipaddress.ip_address(ip)
|
||||||
|
return ip_obj.is_private or ip_obj in ipaddress.ip_network("100.64.0.0/10")
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
def print_json(output):
|
def print_json(output):
|
||||||
print(json.dumps(output, indent=2))
|
print(json.dumps(output, indent=2))
|
||||||
|
|
||||||
@ -165,15 +206,29 @@ def print_text(output, is_ip_mode=False):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="chkip.py – DNS- und Mailserver-Check-Tool")
|
parser = argparse.ArgumentParser(description="chkip.py – DNS- und Mailserver-Check-Tool")
|
||||||
parser.add_argument("domain", help="Domain oder IP-Adresse")
|
parser.add_argument("domain", nargs="?", help="Domain oder IP-Adresse")
|
||||||
parser.add_argument("-sS", "--spf", action="store_true", help="Prüft den SPF-Eintrag")
|
parser.add_argument("-sS", "--spf", action="store_true", help="Prüft den SPF-Eintrag")
|
||||||
parser.add_argument("-sD", "--dmarc", action="store_true", help="Prüft den DMARC-Eintrag")
|
parser.add_argument("-sD", "--dmarc", action="store_true", help="Prüft den DMARC-Eintrag")
|
||||||
parser.add_argument("-sM", "--mta_sts", action="store_true", help="Prüft den MTA-STS-Eintrag")
|
parser.add_argument("-sM", "--mta_sts", action="store_true", help="Prüft den MTA-STS-Eintrag")
|
||||||
parser.add_argument("-sT", "--tlsa", action="store_true", help="Prüft den TLSA-Eintrag")
|
parser.add_argument("-sT", "--tlsa", action="store_true", help="Prüft den TLSA-Eintrag")
|
||||||
parser.add_argument("-sDK", "--dkim", type=str, help="Prüft den DKIM-Eintrag für den angegebenen Selector")
|
parser.add_argument("-sDK", "--dkim", type=str, help="Prüft den DKIM-Eintrag für den angegebenen Selector")
|
||||||
parser.add_argument("--json", action="store_true", help="Ausgabe als JSON")
|
parser.add_argument("--json", action="store_true", help="Ausgabe als JSON")
|
||||||
|
parser.add_argument("--me", action="store_true", help="Zeigt lokale & öffentliche IPs und prüft auf CGNAT")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.me:
|
||||||
|
local_v4, public_v4, public_v6 = get_my_ip()
|
||||||
|
print(f"Your local IPv4: {local_v4}")
|
||||||
|
print(f"Your public IPv4: {public_v4}")
|
||||||
|
print(f"Your public IPv6: {public_v6}")
|
||||||
|
if is_cgnat(public_v4):
|
||||||
|
print("⚠️ Hinweis: Du befindest dich möglicherweise hinter CGNAT (Carrier-Grade NAT)")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not args.domain:
|
||||||
|
parser.print_help()
|
||||||
|
return
|
||||||
|
|
||||||
domain = args.domain
|
domain = args.domain
|
||||||
is_ip = is_ip_address(domain)
|
is_ip = is_ip_address(domain)
|
||||||
output = {}
|
output = {}
|
||||||
@ -192,7 +247,7 @@ def main():
|
|||||||
print_json(output)
|
print_json(output)
|
||||||
else:
|
else:
|
||||||
print_text(output, is_ip_mode=True)
|
print_text(output, is_ip_mode=True)
|
||||||
return # ✅ wichtig!
|
return
|
||||||
|
|
||||||
# Domain-Zweig
|
# Domain-Zweig
|
||||||
output["A"] = resolve_a(domain) or "No A record"
|
output["A"] = resolve_a(domain) or "No A record"
|
||||||
|
Loading…
Reference in New Issue
Block a user