Merge pull request #3 from meemo/master

Cleanup, display IP addresses with leading zeros, switch Windows build system to Nuitka
This commit is contained in:
Austin Burk authored and GitHub committed 2022-02-08 13:36:35 -05:00
commit 985f381643
6 files changed
+85 -75

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
+8
View File
@@ -0,0 +1,8 @@
.idea/
__pycache__/
sudomemoDNS.build/
sudomemoDNS.dist/
sudomemoDNS.onefile-build/
sudomemoDNS.exe
+22 -18
View File
@@ -15,19 +15,21 @@ Run the .exe provided in this release. You may have to click past a warning from
## Running on anything else:
Required packages (installable with pip): `requests`, `dnslib`
Required packages are installable with the following command:
Required Python version: 3+, tested with 3.6
sudo python3 -m pip install -r requirements.txt
sudo <name of your python binary> sudomemoDNS.py
Required Python version: 3.6+, tested with 3.9.9
sudo python3 sudomemoDNS.py
Note: `python3` is assumed to be the name of your python binary, if it is not then it will need to be substituted with the name and/or path of your binary.
## What you'll see when it starts up
The following will display when you start it up:
+===============================+
| Sudomemo DNS Server |
| Version 1.2 |
| Version 1.2.1 |
+===============================+
== Welcome to sudomemoDNS! ==
@@ -40,24 +42,26 @@ The following will display when you start it up:
Then, put these settings in for DNS on your console:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Primary DNS: XXX.XXX.XXX.XXX (NOTE: This value will be unique when you run the program)
Secondary DNS: 8.8.8.8
Secondary DNS: 008.008.008.008
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
== Getting Help ==
Need help? Visit our Discord server or check out https://support.sudomemo.net
When entering your DNS settings, if the Primary DNS is displayed like this (this is an example):
192.168.1.7
then you can enter it as follows:
192.168.001.007
## Building on Windows
Install dnslib, requests, and pyinstaller via pip, then modify the paths in the spec file to where sudomemoDNS and the sudomemoDNS icon is stored.
- Install Python 3.6+ (preferably 3.9). Make sure to install the x86 version for 32 bit targets.
Then, run the following as an administrator:
- Install all requirements via the following command as an administrator
pyinstaller.exe sudomemoDNS_v1.2.spec
```
python -m pip install -r requirements.txt nuitka zstandard
```
- Run the following (answer yes to any prompts):
```shell
python -m nuitka --standalone --onefile --windows-icon-from-ico=sudomemoDNS_icon.ico -o sudomemoDNS.exe sudomemoDNS.py
```
- Run `sudomemoDNS.exe`
+2
View File
@@ -0,0 +1,2 @@
requests
dnslib
+51 -25
View File
@@ -1,16 +1,18 @@
# sudomemoDNS
from datetime import datetime
from json import loads
from socket import socket, AF_INET, SOCK_DGRAM, gethostbyname
from sys import platform
from time import sleep
from dnslib import DNSLabel, QTYPE, RD, RR
from dnslib import A, AAAA, CNAME, MX, NS, SOA, TXT
from dnslib import DNSLabel, QTYPE, RD, RR
from dnslib.server import DNSServer
from requests import get
from requests.exceptions import RequestException
from requests.exceptions import Timeout
import socket
import requests
import json
import sys
def get_platform():
platforms = {
@@ -19,15 +21,24 @@ def get_platform():
'darwin': 'macOS',
'win32': 'Windows'
}
if sys.platform not in platforms:
return sys.platform
if platform not in platforms:
return platform
return platforms[sys.platform]
return platforms[platform]
SUDOMEMODNS_VERSION = "1.2.1"
# Adds preceding zeros to IP addresses
# e.g `1.1.1.1` becomes `001.001.001.001`
def format_ip(address):
octets = str(address).split(".")
return f"{int(octets[0]):03d}.{int(octets[1]):03d}.{int(octets[2]):03d}.{int(octets[3]):03d}"
SUDOMEMODNS_VERSION = "1.2"
def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s = socket(AF_INET, SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
@@ -38,25 +49,27 @@ def get_ip():
s.close()
return IP
EPOCH = datetime(1970, 1, 1)
SERIAL = int((datetime.utcnow() - EPOCH).total_seconds())
MY_IP = get_ip()
print("+===============================+")
print("| Sudomemo DNS Server |")
print("| Version " + SUDOMEMODNS_VERSION + " |")
print(f"| Version {SUDOMEMODNS_VERSION} |")
print("+===============================+\n")
print("== Welcome to sudomemoDNS! ==")
print("This server will allow you to connect to Sudomemo when your Internet Service Provider does not work with custom DNS.\n")
print(
"This server will allow you to connect to Sudomemo when your Internet Service Provider does not work with custom DNS.\n")
print("== How To Use ==")
print("First, make sure that your console is connected to the same network as this computer.\n")
print("Then, put these settings in for DNS on your console:")
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("Primary DNS: ",MY_IP)
print("Secondary DNS: 8.8.8.8")
print(f"Primary DNS: {format_ip(MY_IP)}")
print("Secondary DNS: 008.008.008.008")
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
print("== Getting Help ==")
@@ -74,24 +87,32 @@ TYPE_LOOKUP = {
TXT: QTYPE.TXT,
}
# Can't seem to turn off DNSLogger with a None type so let's just null it out with a dummy function
class SudomemoDNSLogger(object):
def log_recv(self, handler, data):
pass
def log_send(self, handler, data):
pass
def log_request(self, handler, request):
print("[INFO] Received DNS request from console at " + handler.client_address[0])
def log_reply(self, handler, reply):
print("[INFO] Sent response to console at " + handler.client_address[0])
def log_error(self, handler, e):
print("[ERROR] Invalid DNS request from " + handler.client_address[0])
def log_truncated(self, handler, reply):
pass
def log_data(self, dnsobj):
pass
class Record:
def __init__(self, rdata_type, *args, rtype=None, rname=None, ttl=None, **kwargs):
if isinstance(rdata_type, RD):
@@ -144,15 +165,16 @@ class Record:
ZONES = {}
try:
get_zones = requests.get("https://www.sudomemo.net/api/dns_zones.json", headers={'User-Agent': 'SudomemoDNS/' + SUDOMEMODNS_VERSION + ' (' + get_platform() + ')'})
except requests.exceptions.Timeout:
get_zones = get("https://www.sudomemo.net/api/dns_zones.json",
headers={'User-Agent': 'SudomemoDNS/' + SUDOMEMODNS_VERSION + ' (' + get_platform() + ')'})
except Timeout:
print("[ERROR] Unable to load DNS data: Connection to Sudomemo timed out. Are you connected to the Internet?")
except requests.exceptions.RequestException as e:
except RequestException as e:
print("[ERROR] Unable load DNS data.")
print("[ERROR] Exception: ", e)
sys.exit(1)
exit(1)
try:
zones = json.loads(get_zones.text)
zones = loads(get_zones.text)
except ValueError as e:
print("[ERROR] Unable load DNS data: Invalid response from server. Check that you can visit sudomemo.net")
@@ -160,10 +182,11 @@ for zone in zones:
if zone["type"] == "a":
ZONES[zone["name"]] = [Record(A, zone["value"])]
elif zone["type"] == "p":
ZONES[zone["name"]] = [ Record(A, socket.gethostbyname(zone["value"])) ]
ZONES[zone["name"]] = [Record(A, gethostbyname(zone["value"]))]
print("[INFO] DNS information loaded successfully.")
class Resolver:
def __init__(self):
self.zones = {DNSLabel(k): v for k, v in ZONES.items()}
@@ -171,6 +194,7 @@ class Resolver:
def resolve(self, request, handler):
reply = request.reply()
zone = self.zones.get(request.q.qname)
if zone is not None:
for zone_records in zone:
rr = zone_records.try_rr(request.q)
@@ -204,18 +228,20 @@ elif get_platform() == 'macOS':
print("[INFO] If you aren't seeing any requests, check that this is the case first with lsof -i:53 (requires lsof)")
print("[INFO] To run as root, prefix the command with 'sudo'")
elif get_platform() == 'Windows':
print("[INFO] Please note that you may have to allow this application through the firewall. If so, a popup will appear in a moment.")
print("[INFO] If you are not seeing any requests, make sure you have allowed this application through the firewall. If you have already done so, disregard this message.")
print(
"[INFO] Please note that you may have to allow this application through the firewall. If so, a popup will appear in a moment.")
print(
"[INFO] If you are not seeing any requests, make sure you have allowed this application through the firewall. If you have already done so, disregard this message.")
try:
servers = [
DNSServer(resolver=resolver, port=53, address=MY_IP, tcp=True, logger=dnsLogger),
DNSServer(resolver=resolver, port=53, address=MY_IP, tcp=False, logger=dnsLogger),
DNSServer(resolver=resolver, port=53, address=MY_IP, tcp=False, logger=dnsLogger)
]
except PermissionError:
print("[ERROR] Permission error: Check that you are running this as an administrator or root")
sys.exit(1)
exit(1)
print("[INFO] sudomemoDNS is ready. Now waiting for DNS requests from your console...")
-32
View File
@@ -1,32 +0,0 @@
# -*- mode: python -*-
block_cipher = None
a = Analysis(['sudomemoDNS.py'],
pathex=['C:\\PATH\\TO\\SUDOMEMODNS'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='sudomemoDNS_v1.2',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=True , icon='C:\\PATH\\TO\\SUDOMEMODNS\\ICON.ico')