Загрузка данных
import os
import sys
import ctypes
import subprocess
import json
import socket
import customtkinter as ctk
# Имя файла конфига
CONFIG_FILE = "dns_config.json"
class FerrariDNS(ctk.CTk):
def __init__(self):
super().__init__()
self.title("Ferrari Private DNS")
self.geometry("450x500")
ctk.set_appearance_mode("dark")
# Загружаем настройки или ставим дефолт
self.config = self.load_config()
# UI Элементы
self.label = ctk.CTkLabel(self, text="PRIVATE DNS SETTINGS", font=("Arial", 20, "bold"))
self.label.pack(pady=20)
self.dns_input = ctk.CTkEntry(self, width=350)
self.dns_input.pack(pady=10)
self.dns_input.insert(0, self.config.get("dns_url", "https://dns.comss.one/dns-query"))
self.status_label = ctk.CTkLabel(self, text=f"Статус: {self.config.get('status', 'Ожидание')}", text_color="gray")
self.status_label.pack(pady=5)
self.btn_on = ctk.CTkButton(self, text="ВКЛЮЧИТЬ", fg_color="green", command=self.activate)
self.btn_on.pack(pady=10)
self.btn_off = ctk.CTkButton(self, text="СБРОСИТЬ (АВТО)", fg_color="#d32f2f", command=self.reset)
self.btn_off.pack(pady=10)
self.auto_run_var = ctk.BooleanVar(value=self.config.get("auto_run", False))
self.check_auto = ctk.CTkCheckBox(self, text="Автозагрузка при старте", variable=self.auto_run_var, command=self.toggle_autorun)
self.check_auto.pack(pady=20)
def load_config(self):
if os.path.exists(CONFIG_FILE):
try:
with open(CONFIG_FILE, "r") as f:
return json.load(f)
except:
pass
return {"dns_url": "https://dns.comss.one/dns-query", "status": "Отключено", "auto_run": False}
def save_config(self, status):
config_data = {
"dns_url": self.dns_input.get(),
"status": status,
"auto_run": self.auto_run_var.get()
}
with open(CONFIG_FILE, "w") as f:
json.dump(config_data, f)
def get_active_adapter(self):
# Находим имя активного сетевого адаптера через PowerShell
try:
cmd = 'powershell "(Get-NetAdapter | Where-Object {$_.Status -eq \'Up\'} | Select-Object -First 1).Name"'
adapter = subprocess.check_output(cmd, shell=True).decode('cp866').strip()
return adapter if adapter else "Wi-Fi"
except:
return "Wi-Fi"
def activate(self):
url = self.dns_input.get()
adapter = self.get_active_adapter()
self.status_label.configure(text="Настройка...", text_color="yellow")
try:
# Извлекаем хост для резолва IP
host = url.replace("https://", "").split("/")[0]
ip = socket.gethostbyname(host)
# Команды настройки
commands = [
f'powershell Set-DnsClientServerAddress -InterfaceAlias "{adapter}" -ServerAddresses {ip}',
f'powershell Add-DnsClientDohServerAddress -ServerAddress {ip} -DohTemplate "{url}" -AllowFallbackToUdp $false',
f'powershell Set-DnsClient -InterfaceAlias "{adapter}" -UseDnsOverHttps Only',
'ipconfig /flushdns'
]
for cmd in commands:
subprocess.run(cmd, shell=True, check=True)
self.status_label.configure(text="Статус: АКТИВНО (Шифрование)", text_color="green")
self.save_config("Активно")
except Exception as e:
self.status_label.configure(text=f"Ошибка: {str(e)}", text_color="red")
def reset(self):
adapter = self.get_active_adapter()
try:
subprocess.run(f'powershell Set-DnsClientServerAddress -InterfaceAlias "{adapter}" -ResetServerAddresses', shell=True)
subprocess.run(f'powershell Set-DnsClient -InterfaceAlias "{adapter}" -UseDnsOverHttps Prohibit', shell=True)
subprocess.run('ipconfig /flushdns', shell=True)
self.status_label.configure(text="Статус: Сброшено (Авто)", text_color="white")
self.save_config("Отключено")
except:
self.status_label.configure(text="Ошибка сброса", text_color="red")
def toggle_autorun(self):
# Путь к текущему скрипту или EXE
path = os.path.realpath(sys.argv[0])
key = r"Software\Microsoft\Windows\CurrentVersion\Run"
if self.auto_run_var.get():
subprocess.run(f'reg add "HKEY_CURRENT_USER\{key}" /v "FerrariDNS" /t REG_SZ /d "{path}" /f', shell=True)
else:
subprocess.run(f'reg delete "HKEY_CURRENT_USER\{key}" /v "FerrariDNS" /f', shell=True)
self.save_config(self.config.get("status", "Отключено"))
if __name__ == "__main__":
# Проверка на права админа
if not ctypes.windll.shell32.IsUserAnAdmin():
# Если не админ — перезапускаем сами себя с правами
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, f'"{__file__}"', None, 1)
else:
app = FerrariDNS()
app.mainloop()