mirror of
https://github.com/Ground-Zerro/DomainMapper.git
synced 2025-12-10 01:47:18 +07:00
update
Много всего...
This commit is contained in:
27
README.md
27
README.md
@@ -24,8 +24,11 @@
|
|||||||
**Функции:**
|
**Функции:**
|
||||||
- Скрипт загружает списки доменных имен Antifilter - community edition, а также популярных сервисов и разрешает их в IP-адреса используя публичные DNS-сервера.
|
- Скрипт загружает списки доменных имен Antifilter - community edition, а также популярных сервисов и разрешает их в IP-адреса используя публичные DNS-сервера.
|
||||||
- Итоговый список содержит только уникальные IP-адреса исключая дубликаты, также фильтруются IP-адреса самих DNS-серверов, заглушки в виде редиректа на localhost и (по желанию) IP-адреса Cloudflare.
|
- Итоговый список содержит только уникальные IP-адреса исключая дубликаты, также фильтруются IP-адреса самих DNS-серверов, заглушки в виде редиректа на localhost и (по желанию) IP-адреса Cloudflare.
|
||||||
|
- Возможен выбор DNS сервера из установленного в системе, а также Google Public DNS, Quad9, Cloudflare DNS, OpenDNS, Cisco Umbrella, DNS.Watch, Dyn, CleanBrowsing, Alternate DNS, AdGuard DNS, Control D или все сразу.
|
||||||
|
- Разрешение DNS имени происходит используя каждый из указанных пользователем DNS серверов и не останавливается при первом же успешном получении его IP-адреса.
|
||||||
- С помощью конфигурационного файла можно настроить все параметры работы в т.ч. задать список сервисов, формат сохранения, количество потоков, имя выводного файла и другие.
|
- С помощью конфигурационного файла можно настроить все параметры работы в т.ч. задать список сервисов, формат сохранения, количество потоков, имя выводного файла и другие.
|
||||||
|
|
||||||
|
*Обратите внимание, что для эффекта от точечной маршрутизации близкого к 100% резолвить DNS имена необходимо из сети, в которой предполагается их использование при помощи DNS серверов, настроенных в роутере/хосте...*
|
||||||
|
|
||||||
|
|
||||||
**Автоматизация:**
|
**Автоматизация:**
|
||||||
@@ -34,10 +37,7 @@
|
|||||||
|
|
||||||
|
|
||||||
**Зависимости:** Для работы Domain Mapper необходимо наличие следующих библиотек Python:
|
**Зависимости:** Для работы Domain Mapper необходимо наличие следующих библиотек Python:
|
||||||
- requests
|
- requests, dnspython, ipaddress, configparser, httpx
|
||||||
- dnspython
|
|
||||||
- ipaddress
|
|
||||||
- configparser
|
|
||||||
|
|
||||||
*Не забудьте установить их перед запуском:*
|
*Не забудьте установить их перед запуском:*
|
||||||
```
|
```
|
||||||
@@ -51,22 +51,3 @@ pip3 install -r requirements.txt
|
|||||||
|
|
||||||
|
|
||||||
###### Протестировано в Ubuntu 20.04 и Windows 10/11
|
###### Протестировано в Ubuntu 20.04 и Windows 10/11
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Domain Mapper SDS (main-SDS.py)
|
|
||||||
###### Небольшой форк основного кода
|
|
||||||
|
|
||||||
|
|
||||||
**Отличия:**
|
|
||||||
- Иной подход к работе меню.
|
|
||||||
- Возможность выбора DNS серверов, которые будут использованы для проверки, в т.ч.: Системный DNS, Google, Quad9, OpenDNS, Cloudflare, CleanBrowsing, Alternate DNS, AdGuard DNS (пишите если нужно что-то еще добавить).
|
|
||||||
|
|
||||||
*В отличии от основной программы проверка DNS имени будет производиться не до первого успешного разрешения его IP-адреса, а последовательно используя каждый из указанных пользователем DNS серверов. По другому говоря - скрипт будет пытаться получить IP адрес DNS имени отдельно у каждого DNS сервера, что повышает шансы разрешить его IP в случае, например "заглушек" провайдера.*
|
|
||||||
- Список сервисов и DNS серверов исключен из кода, теперь они загружаются с Github.
|
|
||||||
|
|
||||||
*Таким образом пользователь получит актуальные данные запустив даже старую версию скрипта.*
|
|
||||||
- Автоматизация при помощи config.ini пока частичная.
|
|
||||||
- Более долгая работа т.к. DNS имя запрашивается у каждого из указанных DNS серверов.
|
|
||||||
|
|
||||||
*Можно частично компенсировать увеличением числа используемых потоков, однако будьте осторожны - не превысьте количество установленных DNS сервером запросов в секунду, чтобы не получать от него таймаут вместо разрешенного IP-адреса.*
|
|
||||||
|
|||||||
64
config.ini
64
config.ini
@@ -1,29 +1,67 @@
|
|||||||
[DomainMapper]
|
[DomainMapper]
|
||||||
# Имена сервисов, разделенные запятыми, для разрешения доменных имен в IP-адреса без запроса у пользователя
|
# Имена сервисов, разделенные запятыми, для разрешения доменных имен в IP-адреса без запроса у пользователя, если не указано (по умолчанию) - пользователю будет выведено меню выбора
|
||||||
# доступные опции: 'Antifilter community edition', 'Youtube', 'Facebook', 'Openai', 'Tik-Tok', 'Instagram', 'Twitter', 'Netflix', 'Bing', 'Adobe', 'Apple', 'Google', 'Tor-Truckers', 'Search-engines'
|
# опции:
|
||||||
# 'all' - проверить все сервисы, если не указано (по умолчанию) - пользователю будет выведено меню выбора
|
# all - проверить все сервисы
|
||||||
|
# Antifilter community edition - список заблокированных DNS имен формируемый сообществом
|
||||||
|
# Youtube
|
||||||
|
# Facebook
|
||||||
|
# Openai
|
||||||
|
# Tik-Tok
|
||||||
|
# Instagram
|
||||||
|
# Twitter
|
||||||
|
# Netflix
|
||||||
|
# Bing
|
||||||
|
# Adobe
|
||||||
|
# Apple
|
||||||
|
# Google
|
||||||
|
# Tor-Truckers - торрент трекеры
|
||||||
|
# Search-engines - поисковые системы
|
||||||
service =
|
service =
|
||||||
|
|
||||||
# Включить фильтрацию IP-адресов cloudflare и не записывать их в файл результатов
|
# DNS сервера (номер), разделенные пробелом, которые будут использоваться для разрешения доменных имен, если не указано (по умолчанию) - пользователю будет выведено меню выбора
|
||||||
# доступные опции: 'yes', 'no', если значение пусте (по умолчанию) - пользователю будет выведен запрос с подсказкой
|
# опции:
|
||||||
|
# 0 - использовать все доступные DNS серверы
|
||||||
|
# 1 - Системный DNS
|
||||||
|
# 2 - Google Public DNS
|
||||||
|
# 3 - Quad9
|
||||||
|
# 4 - Cloudflare DNS
|
||||||
|
# 5 - OpenDNS
|
||||||
|
# 6 - Cisco Umbrella
|
||||||
|
# 7 - DNS.Watch
|
||||||
|
# 8 - Dyn
|
||||||
|
# 0 - CleanBrowsing
|
||||||
|
# 10 - Alternate DNS
|
||||||
|
# 11 - AdGuard DNS
|
||||||
|
# 12 - Control D
|
||||||
|
dnsserver =
|
||||||
|
|
||||||
|
# Включить фильтрацию IP-адресов cloudflare и не записывать их в файл результатов, если не указано (по умолчанию) - пользователю будет выведен запрос с подсказкой
|
||||||
|
# опции:
|
||||||
|
# yes - исключить IP адреса cloudflare из итогового списка
|
||||||
|
# no - оставить IP адреса cloudflare в итоговом списке
|
||||||
cloudflare =
|
cloudflare =
|
||||||
|
|
||||||
# Имя выходного файла
|
# Имя конечного файла, если не указано (по умолчанию) - будет использоваться имя фала "domain-ip-resolve.txt" в каталоге со скриптом
|
||||||
# доступные опции: 'имя_файла', 'полный_путь/имя_файла', если не указано - будет использоваться имя фала "domain-ip-resolve.txt" в папке со скриптом
|
# опции:
|
||||||
|
# имя_файла - файл с указанным именем будет сохранени в каталоге со скриптом
|
||||||
|
# полный_путь/имя_файла - файл будет сохранен с указанным именем в указанной каталоге
|
||||||
filename =
|
filename =
|
||||||
|
|
||||||
# Количество потоков сканирования
|
# Количество потоков сканирования, если не указано (по умолчанию) - будет использоваться 20 потоков
|
||||||
# если не указано (по умолчанию) - будет использоваться 20 потоков
|
|
||||||
threads =
|
threads =
|
||||||
|
|
||||||
# Тип выходного файла
|
# Формат сохранения файла результатов, если не указано (по умолчанию) - пользователю будет выведен запрос с подсказкой
|
||||||
# доступные опции: 'ip' - только "IP" адрес, 'unix' - "ip rote %IP% mask/%mask% %gateway%", cidr' - "IP/маска", 'win' - "rote add %IP% mask %mask% %gateway%"
|
# опции:
|
||||||
# если не указано (по умолчанию) - пользователю будет выведен запрос с подсказкой
|
# ip - только IP адрес
|
||||||
|
# unix - ip rote %IP%/32 %gateway%
|
||||||
|
# cidr - IP/32
|
||||||
|
# win - rote add %IP% mask 255.255.255.255 %gateway%
|
||||||
filetype =
|
filetype =
|
||||||
|
|
||||||
# адрес шлюза - используется при сохранении IP-адресов в 'win' или 'unix' формате, если не указан (по умолчанию) - пользователю будет выведен запрос с подсказкой
|
# адрес шлюза - используется при сохранении IP-адресов в 'win' или 'unix' формате, если не указан (по умолчанию) - пользователю будет выведен запрос с подсказкой
|
||||||
gateway =
|
gateway =
|
||||||
|
|
||||||
# Команда для консоли после завершения скриптом всех операций, может быть полезно для автоматизации и комбинирования с другим скриптом, кодом или программой
|
# Команда для консоли после завершения скриптом всех операций, может быть полезно для автоматизации и комбинирования с другим скриптом, кодом или программой
|
||||||
# доступные опции: 'исполняемая_команда_для_консоли'
|
# опции:
|
||||||
|
# исполняемая_команда_для_консоли
|
||||||
run =
|
run =
|
||||||
|
|||||||
11
dnsdb
Normal file
11
dnsdb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Google Public DNS: 8.8.8.8 8.8.4.4
|
||||||
|
Quad9: 9.9.9.9 149.112.112.112
|
||||||
|
Cloudflare DNS: 1.1.1.1 1.0.0.1
|
||||||
|
OpenDNS: 208.67.222.222 208.67.220.220
|
||||||
|
Cisco Umbrella: 208.67.222.222 208.67.220.220
|
||||||
|
DNS.Watch: 84.200.69.80 84.200.70.40
|
||||||
|
Dyn: 216.146.35.35 216.146.36.36
|
||||||
|
CleanBrowsing: 185.228.168.9 185.228.169.9
|
||||||
|
Alternate DNS: 76.76.19.19 76.223.122.150
|
||||||
|
AdGuard DNS: 94.140.14.14 94.140.15.15
|
||||||
|
Control D: 76.76.2.0 76.76.10.0
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
Google: 8.8.8.8 8.8.4.4
|
|
||||||
Quad9: 9.9.9.9 149.112.112.112
|
|
||||||
OpenDNS: 208.67.222.222 208.67.220.220
|
|
||||||
Cloudflare: 1.1.1.1 1.0.0.1
|
|
||||||
CleanBrowsing: 185.228.168.9 185.228.169.9
|
|
||||||
Alternate DNS: 76.76.19.19 76.223.122.150
|
|
||||||
AdGuard DNS: 94.140.14.14 94.140.15.15
|
|
||||||
315
main-SDS.py
315
main-SDS.py
@@ -1,315 +0,0 @@
|
|||||||
import configparser
|
|
||||||
import ipaddress
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
||||||
|
|
||||||
import dns.resolver
|
|
||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
# Function to load URLs from external file
|
|
||||||
def load_urls(url):
|
|
||||||
try:
|
|
||||||
response = requests.get(url)
|
|
||||||
response.raise_for_status()
|
|
||||||
lines = response.text.split('\n')
|
|
||||||
urls = {}
|
|
||||||
for line in lines:
|
|
||||||
if line.strip():
|
|
||||||
service, url = line.split(': ', 1)
|
|
||||||
urls[service.strip()] = url.strip()
|
|
||||||
return urls
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Ошибка при загрузке списка платформ: {e}")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
# Function to load DNS servers from external file
|
|
||||||
def load_dns_servers(url):
|
|
||||||
try:
|
|
||||||
response = requests.get(url)
|
|
||||||
response.raise_for_status()
|
|
||||||
lines = response.text.split('\n')
|
|
||||||
dns_servers = {}
|
|
||||||
for line in lines:
|
|
||||||
if line.strip():
|
|
||||||
service, servers = line.split(': ', 1)
|
|
||||||
dns_servers[service.strip()] = servers.strip().split()
|
|
||||||
return dns_servers
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Ошибка при загрузке списка DNS серверов: {e}")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
# Load URLs and DNS servers from external files
|
|
||||||
platform_db_url = "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platformdb.txt"
|
|
||||||
dns_db_url = "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/dnsdb.txt"
|
|
||||||
urls = load_urls(platform_db_url)
|
|
||||||
dns_servers = load_dns_servers(dns_db_url)
|
|
||||||
|
|
||||||
|
|
||||||
# Function to resolve DNS
|
|
||||||
def resolve_dns_and_write(service, url, unique_ips_all_services, include_cloudflare, threads, cloudflare_ips_count,
|
|
||||||
null_ips_count, resolver_nameserver_pairs):
|
|
||||||
try:
|
|
||||||
print(f"\033[33mЗагрузка данных - {service}\033[0m")
|
|
||||||
response = requests.get(url)
|
|
||||||
response.raise_for_status()
|
|
||||||
dns_names = response.text.split('\n')
|
|
||||||
|
|
||||||
if include_cloudflare:
|
|
||||||
cloudflare_ips = get_cloudflare_ips()
|
|
||||||
else:
|
|
||||||
cloudflare_ips = set()
|
|
||||||
|
|
||||||
unique_ips_current_service = set()
|
|
||||||
|
|
||||||
print(f"\033[33mАнализ DNS имен платформы: {service}\033[0m")
|
|
||||||
|
|
||||||
with ThreadPoolExecutor(max_workers=threads) as executor:
|
|
||||||
futures = []
|
|
||||||
for nameserver_pair in resolver_nameserver_pairs:
|
|
||||||
future = executor.submit(resolve_domains_with_nameservers, dns_names, unique_ips_current_service,
|
|
||||||
unique_ips_all_services, cloudflare_ips, cloudflare_ips_count, null_ips_count,
|
|
||||||
nameserver_pair)
|
|
||||||
futures.append(future)
|
|
||||||
|
|
||||||
for future in as_completed(futures):
|
|
||||||
future.result()
|
|
||||||
|
|
||||||
print(f"\033[33mСписок IP-адресов для платформы {service} создан.\033[0m")
|
|
||||||
return '\n'.join(unique_ips_current_service) + '\n'
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Не удалось сопоставить IP адреса {service} его доменным именам.", e)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
# Function to get Cloudflare IP addresses
|
|
||||||
def get_cloudflare_ips():
|
|
||||||
try:
|
|
||||||
response = requests.get("https://www.cloudflare.com/ips-v4/")
|
|
||||||
response.raise_for_status()
|
|
||||||
cloudflare_ips = set()
|
|
||||||
|
|
||||||
cidr_blocks = re.findall(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2})', response.text)
|
|
||||||
|
|
||||||
for cidr in cidr_blocks:
|
|
||||||
ip_network = ipaddress.ip_network(cidr)
|
|
||||||
for ip in ip_network:
|
|
||||||
cloudflare_ips.add(str(ip))
|
|
||||||
|
|
||||||
return cloudflare_ips
|
|
||||||
except Exception as e:
|
|
||||||
print("Ошибка при получении IP адресов Cloudflare:", e)
|
|
||||||
return set()
|
|
||||||
|
|
||||||
|
|
||||||
# Function resolve domain using a pair of DNS servers
|
|
||||||
def resolve_domains_with_nameservers(domains, unique_ips_current_service, unique_ips_all_services, cloudflare_ips,
|
|
||||||
cloudflare_ips_count, null_ips_count, nameserver_pair):
|
|
||||||
dns_server_name, nameservers = nameserver_pair
|
|
||||||
for domain in domains:
|
|
||||||
domain = domain.strip()
|
|
||||||
if domain:
|
|
||||||
for nameserver in nameservers:
|
|
||||||
resolver = dns.resolver.Resolver()
|
|
||||||
resolver.nameservers = [nameserver]
|
|
||||||
resolver.rotate = False
|
|
||||||
resolver.timeout = 1
|
|
||||||
resolver.lifetime = 1
|
|
||||||
try:
|
|
||||||
ips = resolver.resolve(domain)
|
|
||||||
for ip in ips:
|
|
||||||
ip_address = ip.address
|
|
||||||
if ip_address in ('127.0.0.1', '0.0.0.0') or ip_address in resolver.nameservers:
|
|
||||||
null_ips_count[0] += 1
|
|
||||||
elif ip_address in cloudflare_ips:
|
|
||||||
cloudflare_ips_count[0] += 1
|
|
||||||
elif ip_address not in unique_ips_all_services:
|
|
||||||
unique_ips_current_service.add(ip_address)
|
|
||||||
unique_ips_all_services.add(ip_address)
|
|
||||||
print(f"\033[36m{domain} IP адрес: {ip_address} получен от {dns_server_name}\033[0m")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"\033[31mНе удалось разрешить {domain} через {dns_server_name}\033[0m")
|
|
||||||
|
|
||||||
|
|
||||||
# Function to read configuration file
|
|
||||||
def read_config(filename):
|
|
||||||
try:
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
with open(filename, 'r', encoding='utf-8-sig') as file:
|
|
||||||
config.read_file(file)
|
|
||||||
if 'DomainMapper' in config:
|
|
||||||
config = config['DomainMapper']
|
|
||||||
service = config.get('service') or ''
|
|
||||||
threads = int(config.get('threads') or 20)
|
|
||||||
filename = config.get('filename') or 'domain-ip-resolve.txt'
|
|
||||||
cloudflare = config.get('cloudflare') or ''
|
|
||||||
filetype = config.get('filetype') or ''
|
|
||||||
gateway = config.get('gateway') or ''
|
|
||||||
run_command = config.get('run') or ''
|
|
||||||
|
|
||||||
print("Загружена конфигурация из config.ini.")
|
|
||||||
return service, threads, filename, cloudflare, filetype, gateway, run_command
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Ошибка загрузки конфигурации: {e}")
|
|
||||||
return '', 20, 'domain-ip-resolve.txt', '', '', '', ''
|
|
||||||
|
|
||||||
|
|
||||||
def gateway_input(gateway):
|
|
||||||
if not gateway:
|
|
||||||
input_gateway = input(f"Укажите \033[32mшлюз\033[0m или \033[32mимя интерфейса\033[0m: ")
|
|
||||||
if input_gateway:
|
|
||||||
return input_gateway.strip()
|
|
||||||
else:
|
|
||||||
return gateway
|
|
||||||
|
|
||||||
|
|
||||||
# Function to check if 'service' is specified in the configuration file
|
|
||||||
def check_service_config(service):
|
|
||||||
if service:
|
|
||||||
if service.strip().lower() == "all":
|
|
||||||
return list(urls.keys())
|
|
||||||
else:
|
|
||||||
return [s.strip() for s in service.split(',')]
|
|
||||||
else:
|
|
||||||
selected_services = []
|
|
||||||
while True:
|
|
||||||
if os.name == 'nt':
|
|
||||||
os.system('cls')
|
|
||||||
else:
|
|
||||||
os.system('clear')
|
|
||||||
print("\nВыберите сервисы:")
|
|
||||||
for idx, (service, url) in enumerate(urls.items(), 1):
|
|
||||||
print(f"{idx}. {service.capitalize()}")
|
|
||||||
|
|
||||||
selection = input("\nУкажите номера сервисов через пробел и нажмите \033[32mEnter\033[0m: ")
|
|
||||||
if selection.strip():
|
|
||||||
selections = selection.split()
|
|
||||||
selected_services = [list(urls.keys())[int(sel) - 1] for sel in selections if sel.isdigit()
|
|
||||||
and 1 <= int(sel) <= len(urls)]
|
|
||||||
break
|
|
||||||
return selected_services
|
|
||||||
|
|
||||||
|
|
||||||
def check_include_cloudflare(cloudflare):
|
|
||||||
if cloudflare.lower() == 'yes':
|
|
||||||
return True
|
|
||||||
elif cloudflare.lower() == 'no':
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return input("\nИсключить IP адреса Cloudflare из итогового списка? (\033[32myes\033[0m "
|
|
||||||
"- исключить, \033[32mEnter\033[0m - оставить): ").strip().lower() == "yes"
|
|
||||||
|
|
||||||
|
|
||||||
# Function to select DNS servers
|
|
||||||
def check_dns_servers():
|
|
||||||
system_dns_servers = dns.resolver.Resolver().nameservers
|
|
||||||
selected_dns_servers = []
|
|
||||||
|
|
||||||
dns_server_options = [('Системный DNS', system_dns_servers)] + list(dns_servers.items())
|
|
||||||
|
|
||||||
while True:
|
|
||||||
if os.name == 'nt':
|
|
||||||
os.system('cls')
|
|
||||||
else:
|
|
||||||
os.system('clear')
|
|
||||||
print("\nКакие DNS сервера использовать?")
|
|
||||||
for idx, (name, servers) in enumerate(dns_server_options, 1):
|
|
||||||
print(f"{idx}. {name}: {', '.join(servers)}")
|
|
||||||
|
|
||||||
selection = input("\nУкажите номера DNS серверов через пробел и нажмите \033[32mEnter\033[0m: ")
|
|
||||||
if selection.strip():
|
|
||||||
selections = selection.split()
|
|
||||||
for sel in selections:
|
|
||||||
if sel.isdigit():
|
|
||||||
sel = int(sel)
|
|
||||||
if 1 <= sel <= len(dns_server_options):
|
|
||||||
selected_dns_servers.append((dns_server_options[sel-1][0], dns_server_options[sel-1][1]))
|
|
||||||
break
|
|
||||||
|
|
||||||
return selected_dns_servers
|
|
||||||
|
|
||||||
|
|
||||||
def process_file_format(filename, filetype, gateway):
|
|
||||||
if not filetype:
|
|
||||||
filetype = input("\nВыберите в каком формате сохранить файл: \n\033[32mwin\033[0m"
|
|
||||||
" - 'route add %IP% mask %mask% %gateway%', \033[32munix\033[0m"
|
|
||||||
" - 'ip route %IP%/%mask% %gateway%', \033[32mcidr\033[0m"
|
|
||||||
" - 'IP/mask', \033[32mEnter\033[0m - только IP: ")
|
|
||||||
|
|
||||||
if filetype.lower() in ['win', 'unix']:
|
|
||||||
gateway = gateway_input(gateway)
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(filename, 'r', encoding='utf-8-sig') as file:
|
|
||||||
ips = file.readlines()
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Ошибка чтения файла: {e}")
|
|
||||||
return
|
|
||||||
|
|
||||||
if ips:
|
|
||||||
with open(filename, 'w', encoding='utf-8-sig') as file:
|
|
||||||
for ip in ips:
|
|
||||||
if filetype.lower() == 'win':
|
|
||||||
file.write(f"route add {ip.strip()} mask 255.255.255.255 {gateway}\n")
|
|
||||||
elif filetype.lower() == 'unix':
|
|
||||||
file.write(f"ip route {ip.strip()}/32 {gateway}\n")
|
|
||||||
elif filetype.lower() == 'cidr':
|
|
||||||
try:
|
|
||||||
with open(filename, 'r', encoding='utf-8-sig') as file:
|
|
||||||
ips = file.readlines()
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Ошибка чтения файла: {e}")
|
|
||||||
return
|
|
||||||
|
|
||||||
if ips:
|
|
||||||
with open(filename, 'w', encoding='utf-8-sig') as file:
|
|
||||||
for ip in ips:
|
|
||||||
file.write(f"{ip.strip()}/32\n")
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
service, threads, filename, cloudflare, filetype, gateway, run_command = read_config('config.ini')
|
|
||||||
|
|
||||||
total_resolved_domains = 0
|
|
||||||
selected_services = check_service_config(service)
|
|
||||||
resolver_nameserver_pairs = check_dns_servers() # Get selected DNS server pairs
|
|
||||||
include_cloudflare = check_include_cloudflare(cloudflare)
|
|
||||||
|
|
||||||
unique_ips_all_services = set()
|
|
||||||
cloudflare_ips_count = [0] # To count the number of Cloudflare IPs excluded
|
|
||||||
null_ips_count = [0] # To count the number of null IPs excluded
|
|
||||||
|
|
||||||
with open(filename, 'w', encoding='utf-8-sig') as file:
|
|
||||||
for service in selected_services:
|
|
||||||
result = resolve_dns_and_write(service, urls[service], unique_ips_all_services, include_cloudflare,
|
|
||||||
threads, cloudflare_ips_count, null_ips_count, resolver_nameserver_pairs)
|
|
||||||
file.write(result)
|
|
||||||
total_resolved_domains += len(result.split('\n')) - 1
|
|
||||||
|
|
||||||
print("\nПроверка завершена.")
|
|
||||||
print(f"Использовались DNS сервера: {', '.join([f'{pair[0]} ({", ".join(pair[1])})' for pair
|
|
||||||
in resolver_nameserver_pairs])}")
|
|
||||||
if include_cloudflare:
|
|
||||||
print(f"Исключено IP-адресов Cloudflare: {cloudflare_ips_count[0]}")
|
|
||||||
print(f"Исключено IP-адресов 'заглушек' провайдера: {null_ips_count[0]}")
|
|
||||||
print(f"Разрешено IP-адресов из DNS имен сервисов: {total_resolved_domains}")
|
|
||||||
|
|
||||||
process_file_format(filename, filetype, gateway)
|
|
||||||
|
|
||||||
if run_command:
|
|
||||||
print("\nВыполнение команды после завершения скрипта...")
|
|
||||||
os.system(run_command)
|
|
||||||
else:
|
|
||||||
print("Результаты сохранены в файл:", filename)
|
|
||||||
if os.name == 'nt':
|
|
||||||
input("Нажмите \033[32mEnter\033[0m для выхода...")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
417
main.py
417
main.py
@@ -1,114 +1,16 @@
|
|||||||
import configparser
|
import asyncio
|
||||||
|
import configparser
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from asyncio import Semaphore
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
import dns.resolver
|
import dns.asyncresolver
|
||||||
import requests
|
import httpx
|
||||||
|
|
||||||
# URLs
|
|
||||||
urls = {
|
|
||||||
'Antifilter community edition': "https://community.antifilter.download/list/domains.lst",
|
|
||||||
'Youtube': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-youtube.txt",
|
|
||||||
'Facebook': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-facebook.txt",
|
|
||||||
'Openai': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-openai.txt",
|
|
||||||
'Tik-Tok': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-tiktok.txt",
|
|
||||||
'Instagram': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-instagram.txt",
|
|
||||||
'Twitter': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-twitter.txt",
|
|
||||||
'Netflix': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-netflix.txt",
|
|
||||||
'Bing': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-bing.txt",
|
|
||||||
'Adobe': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-adobe.txt",
|
|
||||||
'Apple': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-apple.txt",
|
|
||||||
'Google': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-google.txt",
|
|
||||||
'Tor-Truckers': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-ttruckers.txt",
|
|
||||||
'Search-engines': "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platforms/dns-search-engines"
|
|
||||||
".txt",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Function to resolve DNS
|
# Read configuration file
|
||||||
def resolve_dns_and_write(service, url, unique_ips_all_services, include_cloudflare, threads):
|
|
||||||
try:
|
|
||||||
print(f"Загрузка данных - {service}")
|
|
||||||
response = requests.get(url)
|
|
||||||
response.raise_for_status()
|
|
||||||
dns_names = response.text.split('\n')
|
|
||||||
|
|
||||||
resolver = dns.resolver.Resolver(configure=False)
|
|
||||||
resolver.nameservers = ['8.8.8.8', '8.8.4.4', '208.67.222.222', '208.67.220.220', '4.2.2.1', '4.2.2.2',
|
|
||||||
'149.112.112.112'] # Public DNS servers
|
|
||||||
resolver.rotate = True
|
|
||||||
resolver.timeout = 1
|
|
||||||
resolver.lifetime = 1
|
|
||||||
|
|
||||||
if include_cloudflare:
|
|
||||||
cloudflare_ips = get_cloudflare_ips()
|
|
||||||
else:
|
|
||||||
cloudflare_ips = set()
|
|
||||||
|
|
||||||
unique_ips_current_service = set() # Set to store unique IP addresses for the current service
|
|
||||||
|
|
||||||
print(f"Анализ DNS имен платформы: {service}")
|
|
||||||
|
|
||||||
with ThreadPoolExecutor(max_workers=threads) as executor:
|
|
||||||
futures = []
|
|
||||||
for domain in dns_names:
|
|
||||||
if domain.strip():
|
|
||||||
future = executor.submit(resolve_domain, resolver, domain, unique_ips_current_service,
|
|
||||||
unique_ips_all_services, cloudflare_ips)
|
|
||||||
futures.append(future)
|
|
||||||
|
|
||||||
# Дождаться завершения всех задач
|
|
||||||
for future in futures:
|
|
||||||
future.result()
|
|
||||||
|
|
||||||
print(f"Список IP-адресов для платформы {service} создан.")
|
|
||||||
return '\n'.join(unique_ips_current_service) + '\n'
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Не удалось сопоставить IP адреса {service} его доменным именам.", e)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
# Function to get Cloudflare IP addresses
|
|
||||||
def get_cloudflare_ips():
|
|
||||||
try:
|
|
||||||
response = requests.get("https://www.cloudflare.com/ips-v4/")
|
|
||||||
response.raise_for_status()
|
|
||||||
cloudflare_ips = set()
|
|
||||||
|
|
||||||
# Extract CIDR blocks from the response text using regular expressions
|
|
||||||
cidr_blocks = re.findall(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2})', response.text)
|
|
||||||
|
|
||||||
for cidr in cidr_blocks:
|
|
||||||
ip_network = ipaddress.ip_network(cidr)
|
|
||||||
for ip in ip_network:
|
|
||||||
cloudflare_ips.add(str(ip))
|
|
||||||
|
|
||||||
return cloudflare_ips
|
|
||||||
except Exception as e:
|
|
||||||
print("Ошибка при получении IP адресов Cloudflare:", e)
|
|
||||||
return set()
|
|
||||||
|
|
||||||
|
|
||||||
# Function resolve domain
|
|
||||||
def resolve_domain(resolver, domain, unique_ips_current_service, unique_ips_all_services, cloudflare_ips):
|
|
||||||
try:
|
|
||||||
ips = resolver.resolve(domain)
|
|
||||||
for ip in ips:
|
|
||||||
ip_address = ip.address
|
|
||||||
if (ip_address not in ('127.0.0.1', '0.0.0.1') and
|
|
||||||
ip_address not in resolver.nameservers and
|
|
||||||
ip_address not in cloudflare_ips and
|
|
||||||
ip_address not in unique_ips_all_services): # Check for uniqueness
|
|
||||||
unique_ips_current_service.add(ip_address)
|
|
||||||
unique_ips_all_services.add(ip_address)
|
|
||||||
print(f"\033[36m{domain} IP адрес: {ip_address}\033[0m")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"\033[31mНе удалось обработать: {domain}\033[0m - {e}")
|
|
||||||
|
|
||||||
|
|
||||||
# Function to read configuration file
|
|
||||||
def read_config(filename):
|
def read_config(filename):
|
||||||
try:
|
try:
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@@ -117,27 +19,28 @@ def read_config(filename):
|
|||||||
if 'DomainMapper' in config:
|
if 'DomainMapper' in config:
|
||||||
config = config['DomainMapper']
|
config = config['DomainMapper']
|
||||||
service = config.get('service') or ''
|
service = config.get('service') or ''
|
||||||
threads = int(config.get('threads') or 20)
|
request_limit = int(config.get('threads') or 20)
|
||||||
filename = config.get('filename') or 'domain-ip-resolve.txt'
|
filename = config.get('filename') or 'domain-ip-resolve.txt'
|
||||||
cloudflare = config.get('cloudflare') or ''
|
cloudflare = config.get('cloudflare') or ''
|
||||||
filetype = config.get('filetype') or ''
|
filetype = config.get('filetype') or ''
|
||||||
gateway = config.get('gateway') or ''
|
gateway = config.get('gateway') or ''
|
||||||
run_command = config.get('run') or ''
|
run_command = config.get('run') or ''
|
||||||
|
dns_server_indices = list(map(int, config.get('dnsserver', '').split())) if config.get('dnsserver') else []
|
||||||
|
|
||||||
print("Загружена конфигурация из config.ini.")
|
print("\033[33mЗагружена конфигурация из config.ini:\033[0m")
|
||||||
return service, threads, filename, cloudflare, filetype, gateway, run_command
|
print(f"Сервисы для проверки: {service if service else 'не указаны'}")
|
||||||
|
print(f"Использовать DNS сервер: {dns_server_indices if dns_server_indices else 'не указано'}")
|
||||||
|
print(f"Количество потоков: {request_limit}")
|
||||||
|
print(f"Фильтр Cloudflare: {'включен' if cloudflare == 'yes' else 'вЫключен' if cloudflare == 'no' else 'не указано'}")
|
||||||
|
print(f"Файл результатов: {filename}")
|
||||||
|
print(f"Формат сохранения: {'только IP' if filetype == 'ip' else 'Linux route' if filetype == 'unix' else 'CIDR-нотация' if filetype == 'cidr' else 'Windows route' if filetype == 'win' else 'не указан'}")
|
||||||
|
print(f"Шлюз для маршрутов: {gateway if gateway else 'не указан'}")
|
||||||
|
print(f"Выполнить при заврешении: {run_command if run_command else 'не указано'}")
|
||||||
|
return service, request_limit, filename, cloudflare, filetype, gateway, run_command, dns_server_indices
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Ошибка загрузки конфигурации: {e}")
|
print(f"\033[33mОшибка загрузки config.ini:\033[0m {e}\nИспользуются настройки 'по умолчанию'.")
|
||||||
service = ''
|
return '', 20, 'domain-ip-resolve.txt', '', '', '', '', []
|
||||||
threads = int(20)
|
|
||||||
filename = 'domain-ip-resolve.txt'
|
|
||||||
cloudflare = ''
|
|
||||||
filetype = ''
|
|
||||||
gateway = ''
|
|
||||||
run_command = ''
|
|
||||||
|
|
||||||
return service, threads, filename, cloudflare, filetype, gateway, run_command
|
|
||||||
|
|
||||||
|
|
||||||
def gateway_input(gateway):
|
def gateway_input(gateway):
|
||||||
@@ -149,64 +52,207 @@ def gateway_input(gateway):
|
|||||||
return gateway
|
return gateway
|
||||||
|
|
||||||
|
|
||||||
# Function to check if 'service' is specified in the configuration file
|
# Function to limit requests
|
||||||
def check_service_config(service):
|
def get_semaphore(request_limit):
|
||||||
|
return defaultdict(lambda: Semaphore(request_limit))
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize semaphore for limiting requests
|
||||||
|
def init_semaphores(request_limit):
|
||||||
|
return get_semaphore(request_limit)
|
||||||
|
|
||||||
|
|
||||||
|
async def load_urls(url):
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
response = await client.get(url)
|
||||||
|
response.raise_for_status()
|
||||||
|
text = response.text
|
||||||
|
lines = text.split('\n')
|
||||||
|
urls = {}
|
||||||
|
for line in lines:
|
||||||
|
if line.strip():
|
||||||
|
service, url = line.split(': ', 1)
|
||||||
|
urls[service.strip()] = url.strip()
|
||||||
|
return urls
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка при загрузке списка платформ: {e}")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
async def load_dns_servers(url):
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
response = await client.get(url)
|
||||||
|
response.raise_for_status()
|
||||||
|
text = response.text
|
||||||
|
lines = text.split('\n')
|
||||||
|
dns_servers = {}
|
||||||
|
for line in lines:
|
||||||
|
if line.strip():
|
||||||
|
service, servers = line.split(': ', 1)
|
||||||
|
dns_servers[service.strip()] = servers.strip().split()
|
||||||
|
return dns_servers
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка при загрузке списка DNS серверов: {e}")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
async def get_cloudflare_ips():
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
response = await client.get("https://www.cloudflare.com/ips-v4/")
|
||||||
|
response.raise_for_status()
|
||||||
|
text = response.text
|
||||||
|
cloudflare_ips = set()
|
||||||
|
cidr_blocks = re.findall(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2})', text)
|
||||||
|
for cidr in cidr_blocks:
|
||||||
|
ip_network = ipaddress.ip_network(cidr)
|
||||||
|
for ip in ip_network:
|
||||||
|
cloudflare_ips.add(str(ip))
|
||||||
|
return cloudflare_ips
|
||||||
|
except Exception as e:
|
||||||
|
print("Ошибка при получении IP адресов Cloudflare:", e)
|
||||||
|
return set()
|
||||||
|
|
||||||
|
|
||||||
|
async def resolve_domain(domain, resolver, semaphore, dns_server_name, null_ips_count, cloudflare_ips,
|
||||||
|
cloudflare_ips_count):
|
||||||
|
async with semaphore:
|
||||||
|
try:
|
||||||
|
response = await resolver.resolve(domain)
|
||||||
|
ips = [ip.address for ip in response]
|
||||||
|
for ip_address in ips:
|
||||||
|
if ip_address in ('127.0.0.1', '0.0.0.0') or ip_address in resolver.nameservers:
|
||||||
|
null_ips_count[0] += 1
|
||||||
|
elif ip_address in cloudflare_ips:
|
||||||
|
cloudflare_ips_count[0] += 1
|
||||||
|
else:
|
||||||
|
print(f"\033[36m{domain} IP адрес: {ip_address} получен от {dns_server_name}\033[0m")
|
||||||
|
return ips
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\033[31mНе удалось разрешить {domain} через {dns_server_name}\033[0m")
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
async def resolve_dns(service, url, dns_servers, cloudflare_ips, unique_ips_all_services, semaphore, null_ips_count,
|
||||||
|
cloudflare_ips_count):
|
||||||
|
try:
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
response = await client.get(url)
|
||||||
|
response.raise_for_status()
|
||||||
|
dns_names = response.text.split('\n')
|
||||||
|
|
||||||
|
print(f"\033[33mАнализ DNS имен платформы {service}...\033[0m")
|
||||||
|
|
||||||
|
tasks = []
|
||||||
|
for server_name, servers in dns_servers:
|
||||||
|
resolver = dns.asyncresolver.Resolver()
|
||||||
|
resolver.nameservers = servers
|
||||||
|
for domain in dns_names:
|
||||||
|
domain = domain.strip()
|
||||||
|
if domain:
|
||||||
|
tasks.append(resolve_domain(domain, resolver, semaphore[server_name], server_name, null_ips_count,
|
||||||
|
cloudflare_ips, cloudflare_ips_count))
|
||||||
|
|
||||||
|
results = await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
unique_ips_current_service = set()
|
||||||
|
for result in results:
|
||||||
|
for ip_address in result:
|
||||||
|
if ip_address not in unique_ips_all_services:
|
||||||
|
unique_ips_current_service.add(ip_address)
|
||||||
|
unique_ips_all_services.add(ip_address)
|
||||||
|
|
||||||
|
return '\n'.join(unique_ips_current_service) + '\n'
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Не удалось сопоставить IP адреса {service} его доменным именам.", e)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def check_service_config(service, urls):
|
||||||
if service:
|
if service:
|
||||||
if service.strip().lower() == "all":
|
if service.strip().lower() == "all":
|
||||||
return list(urls.keys()) # Select all available services
|
return list(urls.keys())
|
||||||
else:
|
else:
|
||||||
return [s.strip() for s in service.split(',')]
|
return [s.strip() for s in service.split(',')]
|
||||||
else:
|
else:
|
||||||
selected_services = []
|
selected_services = []
|
||||||
while True:
|
while True:
|
||||||
if os.name == 'nt': # Для пользователей Windows
|
print("\n\033[33mВыберите сервисы:\033[0m")
|
||||||
os.system('cls') # Очистить экран
|
print("0. Выбрать все")
|
||||||
else:
|
|
||||||
os.system('clear')
|
|
||||||
print("\nВыберите сервисы:\n")
|
|
||||||
print("0 - Отметить все")
|
|
||||||
for idx, (service, url) in enumerate(urls.items(), 1):
|
for idx, (service, url) in enumerate(urls.items(), 1):
|
||||||
checkbox = "[*]" if service in selected_services else "[ ]"
|
print(f"{idx}. {service.capitalize()}")
|
||||||
print(f"{idx}. {service.capitalize()} {checkbox}")
|
|
||||||
|
|
||||||
selection = input("\n\033[32mВведите номер сервиса\033[0m и нажмите Enter (Пустая строка "
|
selection = input("\nУкажите номера сервисов через пробел и нажмите \033[32mEnter\033[0m: ")
|
||||||
"и \033[32mEnter\033[0m для старта): ")
|
if selection.strip():
|
||||||
if selection == "0":
|
selections = selection.split()
|
||||||
selected_services = list(urls.keys())
|
if '0' in selections: # User selected all services
|
||||||
elif selection.isdigit():
|
selected_services = list(urls.keys())
|
||||||
idx = int(selection) - 1
|
break
|
||||||
if 0 <= idx < len(urls):
|
else:
|
||||||
service = list(urls.keys())[idx]
|
selected_services = [list(urls.keys())[int(sel) - 1] for sel in selections if sel.isdigit()
|
||||||
if service in selected_services:
|
and 1 <= int(sel) <= len(urls)]
|
||||||
selected_services.remove(service)
|
break
|
||||||
else:
|
|
||||||
selected_services.append(service)
|
|
||||||
elif selection == "":
|
|
||||||
break
|
|
||||||
return selected_services
|
return selected_services
|
||||||
|
|
||||||
|
|
||||||
# Function to check if to include Cloudflare IPs based on configuration or user input
|
|
||||||
def check_include_cloudflare(cloudflare):
|
def check_include_cloudflare(cloudflare):
|
||||||
if cloudflare.lower() == 'yes':
|
if cloudflare.lower() == 'yes':
|
||||||
return True
|
return True
|
||||||
elif cloudflare.lower() == 'no':
|
elif cloudflare.lower() == 'no':
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return input("Исключить IP адреса Cloudflare из итогового списка? (\033[32myes\033[0m "
|
return input("\nИсключить IP адреса Cloudflare из итогового списка? (\033[32myes\033[0m "
|
||||||
"- исключить, \033[32mEnter\033[0m - оставить): ").strip().lower() == "yes"
|
"- исключить, \033[32mEnter\033[0m - оставить): ").strip().lower() == "yes"
|
||||||
|
|
||||||
|
|
||||||
# Function to process file format
|
def check_dns_servers(dns_servers, dns_server_indices):
|
||||||
|
system_dns_servers = dns.asyncresolver.Resolver().nameservers
|
||||||
|
selected_dns_servers = []
|
||||||
|
|
||||||
|
dns_server_options = [('Системный DNS', system_dns_servers)] + list(dns_servers.items())
|
||||||
|
|
||||||
|
if dns_server_indices:
|
||||||
|
for idx in dns_server_indices:
|
||||||
|
if 0 <= idx <= len(dns_server_options):
|
||||||
|
selected_dns_servers.append((dns_server_options[idx][0], dns_server_options[idx][1]))
|
||||||
|
return selected_dns_servers
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print("\n\033[33mКакие DNS сервера использовать?\033[0m")
|
||||||
|
print("0. Выбрать все")
|
||||||
|
for idx, (name, servers) in enumerate(dns_server_options, 1):
|
||||||
|
print(f"{idx}. {name}: {', '.join(servers)}")
|
||||||
|
|
||||||
|
selection = input("\nУкажите номера DNS серверов через пробел и нажмите \033[32mEnter\033[0m: ")
|
||||||
|
if selection.strip():
|
||||||
|
selections = selection.split()
|
||||||
|
if '0' in selections: # User selected all DNS servers
|
||||||
|
selected_dns_servers = dns_server_options
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
for sel in selections:
|
||||||
|
if sel.isdigit():
|
||||||
|
sel = int(sel)
|
||||||
|
if 1 <= sel <= len(dns_server_options):
|
||||||
|
selected_dns_servers.append(
|
||||||
|
(dns_server_options[sel - 1][0], dns_server_options[sel - 1][1]))
|
||||||
|
break
|
||||||
|
|
||||||
|
return selected_dns_servers
|
||||||
|
|
||||||
|
|
||||||
def process_file_format(filename, filetype, gateway):
|
def process_file_format(filename, filetype, gateway):
|
||||||
if not filetype:
|
if not filetype:
|
||||||
filetype = input("\nВыберите в каком формате сохранить файл: \n\033[32mwin\033[0m"
|
filetype = input("\n\033[33mВ каком формате сохранить файл?\033[0m"
|
||||||
" - 'route add %IP% mask %mask% %gateway%', \033[32munix\033[0m"
|
"\n\033[32mwin\033[0m - route add IP mask MASK GATEWAY"
|
||||||
" - 'ip route %IP%/%mask% %gateway%', \033[32mcidr\033[0m"
|
"\n\033[32munix\033[0m - ip route IP/MASK GATEWAY"
|
||||||
" - 'IP/mask', \033[32mEnter\033[0m - только IP: ")
|
"\n\033[32mcidr\033[0m - IP/MASK"
|
||||||
|
"\n\033[32mПустое значение\033[0m - только IP"
|
||||||
|
"\nВаш выбор: ")
|
||||||
|
|
||||||
if filetype.lower() in ['win', 'unix']:
|
if filetype.lower() in ['win', 'unix']:
|
||||||
# Обработка файлов разных форматов
|
|
||||||
gateway = gateway_input(gateway)
|
gateway = gateway_input(gateway)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -224,7 +270,6 @@ def process_file_format(filename, filetype, gateway):
|
|||||||
elif filetype.lower() == 'unix':
|
elif filetype.lower() == 'unix':
|
||||||
file.write(f"ip route {ip.strip()}/32 {gateway}\n")
|
file.write(f"ip route {ip.strip()}/32 {gateway}\n")
|
||||||
elif filetype.lower() == 'cidr':
|
elif filetype.lower() == 'cidr':
|
||||||
# Обработка CIDR формата
|
|
||||||
try:
|
try:
|
||||||
with open(filename, 'r', encoding='utf-8-sig') as file:
|
with open(filename, 'r', encoding='utf-8-sig') as file:
|
||||||
ips = file.readlines()
|
ips = file.readlines()
|
||||||
@@ -235,47 +280,69 @@ def process_file_format(filename, filetype, gateway):
|
|||||||
if ips:
|
if ips:
|
||||||
with open(filename, 'w', encoding='utf-8-sig') as file:
|
with open(filename, 'w', encoding='utf-8-sig') as file:
|
||||||
for ip in ips:
|
for ip in ips:
|
||||||
file.write(f"{ip.strip()}/32\n") # Assuming /32 subnet mask for all IPs
|
file.write(f"{ip.strip()}/32\n")
|
||||||
else:
|
else:
|
||||||
# Сохранить только IP адреса
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def main():
|
async def main():
|
||||||
# Read parameters from the configuration file
|
# Load configuration
|
||||||
service, threads, filename, cloudflare, filetype, gateway, run_command = read_config('config.ini')
|
service, request_limit, filename, cloudflare, filetype, gateway, run_command, dns_server_indices = read_config('config.ini')
|
||||||
|
|
||||||
total_resolved_domains = 0
|
# Load URLs
|
||||||
selected_services = check_service_config(service)
|
platform_db_url = "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platformdb"
|
||||||
|
urls = await load_urls(platform_db_url)
|
||||||
|
|
||||||
# Check if to include Cloudflare IPs based on configuration or user input
|
# Get selected services from user
|
||||||
|
selected_services = check_service_config(service, urls)
|
||||||
|
|
||||||
|
# Load DNS servers
|
||||||
|
dns_db_url = "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/dnsdb"
|
||||||
|
dns_servers = await load_dns_servers(dns_db_url)
|
||||||
|
|
||||||
|
# Get selected DNS servers from config or user
|
||||||
|
selected_dns_servers = check_dns_servers(dns_servers, dns_server_indices)
|
||||||
|
|
||||||
|
# Get Cloudflare IP addresses
|
||||||
|
cloudflare_ips = await get_cloudflare_ips()
|
||||||
|
|
||||||
|
# Check if Cloudflare IPs should be included or excluded
|
||||||
include_cloudflare = check_include_cloudflare(cloudflare)
|
include_cloudflare = check_include_cloudflare(cloudflare)
|
||||||
|
|
||||||
# Set to store unique IP addresses across all services
|
|
||||||
unique_ips_all_services = set()
|
unique_ips_all_services = set()
|
||||||
|
semaphore = init_semaphores(request_limit)
|
||||||
|
null_ips_count = [0]
|
||||||
|
cloudflare_ips_count = [0]
|
||||||
|
tasks = []
|
||||||
|
|
||||||
# DNS resolution for selected services
|
for service in selected_services:
|
||||||
with open(filename, 'w', encoding='utf-8-sig') as file: # Open file for writing
|
tasks.append(resolve_dns(service, urls[service], selected_dns_servers, cloudflare_ips, unique_ips_all_services,
|
||||||
for service in selected_services:
|
semaphore, null_ips_count, cloudflare_ips_count))
|
||||||
result = resolve_dns_and_write(service, urls[service], unique_ips_all_services, include_cloudflare, threads)
|
|
||||||
file.write(result) # Write unique IPs directly to the file
|
|
||||||
total_resolved_domains += len(result.split('\n')) - 1
|
|
||||||
|
|
||||||
print("\nПроверка завершена.")
|
results = await asyncio.gather(*tasks)
|
||||||
print(f"Сопоставлено IP адресов доменам: {total_resolved_domains}")
|
|
||||||
|
with open(filename, 'w', encoding='utf-8-sig') as file:
|
||||||
|
for result in results:
|
||||||
|
file.write(result)
|
||||||
|
|
||||||
|
print("\n\033[33mПроверка завершена.\033[0m")
|
||||||
|
print(
|
||||||
|
f"Использовались DNS сервера: {', '.join([f'{pair[0]} ({', '.join(pair[1])})' for pair in selected_dns_servers])}")
|
||||||
|
if include_cloudflare:
|
||||||
|
print(f"Исключено IP-адресов Cloudflare: {cloudflare_ips_count[0]}")
|
||||||
|
print(f"Исключено IP-адресов 'заглушек': {null_ips_count[0]}")
|
||||||
|
print(f"Разрешено IP-адресов из DNS имен: {len(unique_ips_all_services)}")
|
||||||
|
|
||||||
# Asking for file format if filetype is not specified in the configuration file
|
|
||||||
process_file_format(filename, filetype, gateway)
|
process_file_format(filename, filetype, gateway)
|
||||||
|
|
||||||
# Executing the command after the program is completed, if it is specified in the configuration file
|
if run_command:
|
||||||
if run_command is not None and run_command.strip():
|
|
||||||
print("\nВыполнение команды после завершения скрипта...")
|
print("\nВыполнение команды после завершения скрипта...")
|
||||||
os.system(run_command)
|
os.system(run_command)
|
||||||
else:
|
else:
|
||||||
print("Результаты сохранены в файл:", filename)
|
print("\nРезультаты сохранены в файл:", filename)
|
||||||
if os.name == 'nt': # Для пользователей Windows при запуске из проводника
|
if os.name == 'nt':
|
||||||
input("Нажмите \033[32mEnter\033[0m для выхода...")
|
input("Нажмите \033[32mEnter\033[0m для выхода...")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
asyncio.run(main())
|
||||||
|
|||||||
@@ -2,3 +2,5 @@ requests~=2.31.0
|
|||||||
dnspython~=2.6.1
|
dnspython~=2.6.1
|
||||||
ipaddress~=1.0.23
|
ipaddress~=1.0.23
|
||||||
configparser~=7.0.0
|
configparser~=7.0.0
|
||||||
|
|
||||||
|
httpx~=0.27.0
|
||||||
4
todo.txt
4
todo.txt
@@ -1,4 +0,0 @@
|
|||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> resolvedns <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DNS <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DNS.
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>.
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|
||||||
Reference in New Issue
Block a user