From 5621f7cedd32dbdd0e8b0ead9cba915c61b91475 Mon Sep 17 00:00:00 2001 From: Stefano Marinelli Date: Thu, 9 May 2024 15:23:06 +0200 Subject: [PATCH] Added DNS support --- README.md | 48 ++++++++++++++++++++++++++++-------------------- checkmyip.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 4a131bc..a2ac283 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,37 @@ # CheckMyIP - [myip.bsd.cafe](https://myip.bsd.cafe) -A Telnet, SSH and Simple HTTP Based Public IP Address Lookup Service +A Telnet, SSH, DNS and Simple HTTP Based Public IP Address Lookup Service ----------------------------------------- ### USAGE -- **TELNET**: - - Default: `telnet myip.bsd.cafe` - - IPv4: `telnet myip4.bsd.cafe` - - IPv6: `telnet myip6.bsd.cafe` -- **SSH**: - - Default: `ssh myip.bsd.cafe` - - IPv4: `ssh myip4.bsd.cafe` - - IPv6: `ssh myip6.bsd.cafe` - - Your SSH client may require you to enter a username. You can use anything you want (`ssh -l imrootbitch myip.bsd.cafe`) -- **CURL**: - - Default: `curl -L myip.bsd.cafe` - - IPv4: `curl -L myip4.bsd.cafe` - - IPv6: `curl -L myip6.bsd.cafe` -- **WGET**: - - Default: `wget -qO- myip.bsd.cafe` - - IPv4: `wget -qO- myip4.bsd.cafe` - - IPv6: `wget -qO- myip6.bsd.cafe` +#### DNS +- **DNS TXT Record**: + - Retrieve your IP via a DNS TXT record: `dig +short myip.bsd.cafe TXT @myip.bsd.cafe` + +#### Telnet +- **Default**: `telnet myip.bsd.cafe` +- **IPv4**: `telnet myip4.bsd.cafe` +- **IPv6**: `telnet myip6.bsd.cafe` + +#### SSH +- **Default**: `ssh myip.bsd.cafe` +- **IPv4**: `ssh myip4.bsd.cafe` +- **IPv6**: `ssh myip6.bsd.cafe` +- Your SSH client may require you to enter a username. You can use anything you want (`ssh -l username myip.bsd.cafe`) + +#### CURL +- **Default**: `curl -L myip.bsd.cafe` +- **IPv4**: `curl -L myip4.bsd.cafe` +- **IPv6**: `curl -L myip6.bsd.cafe` + +#### WGET +- **Default**: `wget -qO- myip.bsd.cafe` +- **IPv4**: `wget -qO- myip4.bsd.cafe` +- **IPv6**: `wget -qO- myip6.bsd.cafe` + ----------------------------------------- ### VERSION ### @@ -74,7 +82,7 @@ If you would rather set up your own private instance of CheckMyIP, then you can Install Dependencies (for example, on a FreeBSD jail) ``` -pkg install python39 py39-gssapi py39-paramiko +pkg install python39 py39-gssapi py39-paramiko py39-dnspython ``` Clone Repo and install @@ -152,4 +160,4 @@ Visit the BSD Cafe Brew page (https://brew.bsd.cafe/BSDCafe/checkmyip) and eithe Original code by [John W Kerns](https://github.com/packetsar/checkmyip) [logo]: /checkmyip_icon-100.gif -[whatismyip]: https://www.whatismyip.com/ \ No newline at end of file +[whatismyip]: https://www.whatismyip.com/ diff --git a/checkmyip.py b/checkmyip.py index bbbd0f9..7df33d3 100644 --- a/checkmyip.py +++ b/checkmyip.py @@ -21,6 +21,8 @@ import json import jinja2 import paramiko import threading +from dnslib import DNSRecord, DNSHeader, RR, TXT, QTYPE + ##### Jinja formatting for logging queries ##### @@ -43,6 +45,40 @@ j2send = """{ "sponsor": "Served by BSD Cafe, https://bsd.cafe/" }""" % version +##### DNS Server Functionality ##### +class DNSResponder: + def __init__(self, address='::', port=5553): + self.address = address + self.port = port + self.sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + self.sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) # Enables dual-stack mode + self.sock.bind((self.address, self.port)) + + def run(self): + print("DNS Server listening on port 53 for both IPv4 and IPv6") + while True: + data, addr = self.sock.recvfrom(1024) + threading.Thread(target=self.handle_query, args=(data, addr)).start() + + def handle_query(self, data, addr): + try: + request = DNSRecord.parse(data) + qname = request.q.qname + qtype = request.q.qtype + ip, port, *_ = addr # Get IP and port; ignore other details + + # Normalize IPv6 address (remove IPv4 mapping if exists) + if ip.startswith("::ffff:"): + ip = ip[7:] + + # Only respond to TXT queries for myip.bsd.cafe + if qname.matchGlob('myip.bsd.cafe') and qtype == QTYPE.TXT: + response = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q) + response.add_answer(RR(qname, QTYPE.TXT, ttl=60, rdata=TXT(ip))) + self.sock.sendto(response.pack(), addr) + except Exception as e: + print(f"Error handling DNS query: {e}") + ##### Handles all prnting to console and logging to the logfile ##### class log_management: @@ -263,6 +299,11 @@ def start(): args=(talker, talkers[talker])) thread.daemon = True thread.start() + # Start DNS server in a new thread + dns_server = DNSResponder() + dns_thread = threading.Thread(target=dns_server.run) + dns_thread.daemon = True + dns_thread.start() while True: # While loop to allow a CTRL-C interrupt when interactive try: time.sleep(1)