mirror of
https://github.com/Ground-Zerro/DomainMapper.git
synced 2025-12-10 01:47:18 +07:00
new
Добавлена возможность объединить IP-адреса в подсеть до /24 (255.255.255.0)
This commit is contained in:
@@ -45,6 +45,13 @@ dnsserver =
|
||||
# no - оставить IP адреса cloudflare в итоговом списке
|
||||
cloudflare =
|
||||
|
||||
# Сгруппировать подсети
|
||||
# опции:
|
||||
# пустое значение - пользователю будет выведено меню выбора
|
||||
# yes - группировка подсетей до /24 (255.255.255.0)
|
||||
# no - оставить как есть
|
||||
subnet =
|
||||
|
||||
# Имя конечного файла
|
||||
# опции:
|
||||
# пустое значение - "domain-ip-resolve.txt" в каталоге со скриптом
|
||||
|
||||
172
main.py
172
main.py
@@ -13,6 +13,7 @@ from colorama import init
|
||||
|
||||
# Цвета
|
||||
init(autoreset=True)
|
||||
|
||||
def yellow(text):
|
||||
return f"{Fore.YELLOW}{text}{Style.RESET_ALL}"
|
||||
|
||||
@@ -31,7 +32,6 @@ def magneta(text):
|
||||
def blue(text):
|
||||
return f"{Fore.BLUE}{text}{Style.RESET_ALL}"
|
||||
|
||||
|
||||
# Читаем конфигурацию
|
||||
def read_config(filename):
|
||||
try:
|
||||
@@ -49,6 +49,7 @@ def read_config(filename):
|
||||
run_command = config.get('run') or ''
|
||||
dns_server_indices = list(map(int, config.get('dnsserver', '').split())) if config.get('dnsserver') else []
|
||||
mk_list_name = config.get('listname') or ''
|
||||
subnet = config.get('subnet') or ''
|
||||
|
||||
print(f"{yellow('Загружена конфигурация из config.ini:')}")
|
||||
print(f"{Style.BRIGHT}Сервисы для проверки:{Style.RESET_ALL} {service if service else 'спросить у пользователя'}")
|
||||
@@ -59,19 +60,19 @@ def read_config(filename):
|
||||
print(f"{Style.BRIGHT}Формат сохранения:{Style.RESET_ALL} {'только IP' if filetype == 'ip' else 'Linux route' if filetype == 'unix' else 'CIDR-нотация' if filetype == 'cidr' else 'Windows route' if filetype == 'win' else 'CLI Mikrotik firewall' if filetype == 'mikrotik' else 'open vpn' if filetype == 'ovpn' else 'спросить у пользователя'}")
|
||||
print(f"{Style.BRIGHT}Шлюз/Имя интерфейса для маршрутов:{Style.RESET_ALL} {gateway if gateway else 'спросить у пользователя'}")
|
||||
print(f"{Style.BRIGHT}Имя списка для Mikrotik firewall:{Style.RESET_ALL} {mk_list_name if mk_list_name else 'спросить у пользователя'}")
|
||||
print(f"{Style.BRIGHT}Группировка IP-адресов в подсети:{Style.RESET_ALL} {'включена' if subnet == 'yes' else 'выключена' if subnet == 'no' else 'спросить у пользователя'}")
|
||||
print(f"{Style.BRIGHT}Выполнить по завершению:{Style.RESET_ALL} {run_command if run_command else 'не указано'}")
|
||||
return service, request_limit, filename, cloudflare, filetype, gateway, run_command, dns_server_indices, mk_list_name
|
||||
return service, request_limit, filename, cloudflare, filetype, gateway, run_command, dns_server_indices, mk_list_name, subnet
|
||||
|
||||
except Exception as e:
|
||||
print(f"{yellow('Ошибка загрузки config.ini:')} {e}\n{Style.BRIGHT}Используются настройки 'по умолчанию'.{Style.RESET_ALL}")
|
||||
return '', 20, 'domain-ip-resolve.txt', '', '', '', '', [], ''
|
||||
return '', 20, 'domain-ip-resolve.txt', '', '', '', '', [], '', ''
|
||||
|
||||
|
||||
def gateway_input(gateway):
|
||||
if not gateway:
|
||||
input_gateway = input(f"Укажите {green('шлюз')} или {green('имя интерфейса')}: ")
|
||||
if input_gateway:
|
||||
return input_gateway.strip()
|
||||
return input_gateway.strip() if input_gateway else None
|
||||
else:
|
||||
return gateway
|
||||
|
||||
@@ -285,102 +286,119 @@ def check_dns_servers(dns_servers, dns_server_indices):
|
||||
return selected_dns_servers
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Для microtik ввод комментария comment для firewall
|
||||
def mk_list_name_input(mk_list_name):
|
||||
if not mk_list_name:
|
||||
input_mk_list_name = input(f"Введите {green('LIST_NAME')} для firewall: ")
|
||||
if input_mk_list_name:
|
||||
return input_mk_list_name.strip()
|
||||
input_mk_list_name = input(f"Введите {green('LIST_NAME')} для Mikrotik firewall: ")
|
||||
return input_mk_list_name.strip() if input_mk_list_name else None
|
||||
else:
|
||||
return mk_list_name
|
||||
|
||||
|
||||
# Для mikrotik собираем в кучку сервисы
|
||||
# Для mikrotik уплотняем имена сервисов
|
||||
def mk_comment(selected_service):
|
||||
return ",".join(["".join(word.title() for word in s.split()) for s in selected_service])
|
||||
|
||||
|
||||
# Выбор формата сохранения списка разрешенных DNS имен
|
||||
def process_file_format(filename, filetype, gateway, selected_service, mk_list_name):
|
||||
def subnetting(subnet):
|
||||
if subnet.lower() == 'yes':
|
||||
return "24", "255.255.255.0"
|
||||
elif subnet.lower() == 'no':
|
||||
return "32", "255.255.255.255"
|
||||
else:
|
||||
choice = input(f"\n{yellow('Сгруппировать IP-адреса в подсети?')} ({green('yes')} - да, {green('Enter')} - нет): ").strip().lower()
|
||||
if choice == "yes":
|
||||
return "24", "255.255.255.0"
|
||||
else:
|
||||
return "32", "255.255.255.255"
|
||||
|
||||
|
||||
def group_ips_in_subnets(filename):
|
||||
try:
|
||||
with open(filename, 'r', encoding='utf-8-sig') as file:
|
||||
ips = {line.strip() for line in file if line.strip()} # Собираем уникальные IP адреса
|
||||
|
||||
# Преобразование всех IP в их подсети /24
|
||||
subnet_ips = set()
|
||||
for ip in ips:
|
||||
try:
|
||||
# Преобразуем IP в сеть /24 (маска 255.255.255.0)
|
||||
network = ipaddress.ip_network(f"{ip}/24", strict=False)
|
||||
subnet_ips.add(str(network.network_address))
|
||||
except ValueError as e:
|
||||
print(f"{red('Ошибка в IP адресе:')} {ip} - {e}")
|
||||
|
||||
# Перезаписываем файл с уникальными подсетями
|
||||
with open(filename, 'w', encoding='utf-8-sig') as file:
|
||||
for subnet in subnet_ips:
|
||||
file.write(subnet + '\n')
|
||||
|
||||
print("IP-адреса сгруппированы...")
|
||||
|
||||
except Exception as e:
|
||||
print(f"{red('Ошибка при обработке файла:')} {e}")
|
||||
|
||||
|
||||
# Выбор формата сохранения списка разрешенных DNS имен
|
||||
def process_file_format(filename, filetype, gateway, selected_service, mk_list_name, submask):
|
||||
def read_file(filename):
|
||||
try:
|
||||
with open(filename, 'r', encoding='utf-8-sig') as file:
|
||||
return file.readlines()
|
||||
except Exception as e:
|
||||
print(f"Ошибка чтения файла: {e}")
|
||||
return None
|
||||
|
||||
def write_file(filename, ips, formatter):
|
||||
with open(filename, 'w', encoding='utf-8-sig') as file:
|
||||
for ip in ips:
|
||||
file.write(formatter(ip.strip()) + '\n')
|
||||
|
||||
# Определение маски подсети для отображения пользователю
|
||||
display_submask = "255.255.255.0" if submask == "24" else "255.255.255.255"
|
||||
|
||||
if not filetype:
|
||||
filetype = input(f"""
|
||||
{yellow('В каком формате сохранить файл?')}
|
||||
{green('win')} - route add {cyan('IP')} mask 255.255.255.255 {cyan('GATEWAY')}
|
||||
{green('unix')} - ip route {cyan('IP')}/32 {cyan('GATEWAY')}
|
||||
{green('cidr')} - {cyan('IP')}/32
|
||||
{green('mikrotik')} - /ip/firewall/address-list add list={cyan("LIST_NAME")} comment="{mk_comment(selected_service)}" address={cyan("IP")}/32
|
||||
{green('ovpn')} - push "route {cyan('IP')} 255.255.255.255"
|
||||
{green('win')} - route add {cyan('IP')} mask {cyan(display_submask)} {cyan('GATEWAY')}
|
||||
{green('unix')} - ip route {cyan('IP')}/{cyan(submask)} {cyan('GATEWAY')}
|
||||
{green('cidr')} - {cyan('IP')}/{cyan(submask)}
|
||||
{green('mikrotik')} - /ip/firewall/address-list add list={cyan("LIST_NAME")} comment="{mk_comment(selected_service)}" address={cyan("IP")}/{cyan(submask)}
|
||||
{green('ovpn')} - push "route {cyan('IP')} {cyan(display_submask)}"
|
||||
{green('Enter')} - {cyan('IP')}
|
||||
Ваш выбор: """)
|
||||
|
||||
ips = read_file(filename)
|
||||
if not ips:
|
||||
return
|
||||
|
||||
# Если формат требует указания шлюза, запрашиваем его
|
||||
if filetype.lower() in ['win', 'unix']:
|
||||
gateway = gateway_input(gateway)
|
||||
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
|
||||
# Если выбран формат Mikrotik, запрашиваем mk_list_name
|
||||
if filetype.lower() == 'mikrotik':
|
||||
mk_list_name = mk_list_name_input(mk_list_name) # Сохраняем значение mk_list_name после ввода
|
||||
|
||||
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
|
||||
formatters = {
|
||||
'win': lambda ip: f"route add {ip} mask {display_submask} {gateway}",
|
||||
'unix': lambda ip: f"ip route {ip}{submask} {gateway}",
|
||||
'cidr': lambda ip: f"{ip}{submask}",
|
||||
'ovpn': lambda ip: f'push "route {ip} {display_submask}"',
|
||||
'mikrotik': lambda ip: f'/ip/firewall/address-list add list={mk_list_name} '
|
||||
f'comment="{mk_comment(selected_service)}" address={ip}/{submask}'
|
||||
}
|
||||
|
||||
if ips:
|
||||
with open(filename, 'w', encoding='utf-8-sig') as file:
|
||||
for ip in ips:
|
||||
file.write(f"{ip.strip()}/32\n")
|
||||
if filetype.lower() in formatters:
|
||||
write_file(filename, ips, formatters[filetype.lower()])
|
||||
|
||||
elif filetype.lower() == 'ovpn':
|
||||
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'push "route {ip.strip()} 255.255.255.255"\n')
|
||||
|
||||
elif filetype.lower() == 'mikrotik':
|
||||
mk_list_name = mk_list_name_input(mk_list_name)
|
||||
|
||||
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/firewall/address-list add list={mk_list_name} comment="{mk_comment(selected_service)}" address={ip.strip()}/32{chr(10)}')
|
||||
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
# Ну чо, погнали?!
|
||||
async def main():
|
||||
# Инициализация настроек из config.ini
|
||||
service, request_limit, filename, cloudflare, filetype, gateway, run_command, dns_server_indices, mk_list_name = read_config('config.ini')
|
||||
service, request_limit, filename, cloudflare, filetype, gateway, run_command, dns_server_indices, mk_list_name, subnet = read_config('config.ini')
|
||||
|
||||
# Load URLs
|
||||
platform_db_url = "https://raw.githubusercontent.com/Ground-Zerro/DomainMapper/main/platformdb"
|
||||
@@ -443,7 +461,12 @@ async def main():
|
||||
print(f"{Style.BRIGHT}Исключено IP-адресов 'заглушек':{Style.RESET_ALL} {null_ips_count[0]}")
|
||||
print(f"{Style.BRIGHT}Разрешено IP-адресов из DNS имен:{Style.RESET_ALL} {len(unique_ips_all_services)}")
|
||||
|
||||
process_file_format(filename, filetype, gateway, selected_services, mk_list_name)
|
||||
# Группировка IP-адресов в подсети
|
||||
submask, _ = subnetting(subnet)
|
||||
if submask == "24":
|
||||
group_ips_in_subnets(filename)
|
||||
|
||||
process_file_format(filename, filetype, gateway, selected_services, mk_list_name, submask)
|
||||
|
||||
if run_command:
|
||||
print("\nВыполнение команды после завершения скрипта...")
|
||||
@@ -453,5 +476,6 @@ async def main():
|
||||
if os.name == 'nt':
|
||||
input(f"Нажмите {green('Enter')} для выхода...")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
Reference in New Issue
Block a user