From e3ed8d0ad24016f4e8d335d2fe4a21d8ed1b3a6e Mon Sep 17 00:00:00 2001 From: gru Date: Tue, 20 Jan 2026 15:07:07 +0100 Subject: [PATCH] Add usr/local/bin/check_dns_restart.py --- usr/local/bin/check_dns_restart.py | 171 +++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 usr/local/bin/check_dns_restart.py diff --git a/usr/local/bin/check_dns_restart.py b/usr/local/bin/check_dns_restart.py new file mode 100644 index 0000000..2a9c16f --- /dev/null +++ b/usr/local/bin/check_dns_restart.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +""" +Skrypt sprawdzający dostępność usług DNS na portach 53, 54, 55 +i restartujący je jeśli połączenie z internetem jest dostępne +""" + +import dns.resolver +import dns.message +import dns.query +import subprocess +import sys +import logging +import socket +from datetime import datetime + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=[ + logging.FileHandler('/var/log/dns_check_restart.log'), + logging.StreamHandler() + ] +) + +DNS_PORTS = { + 53: {'service': 'dnsdist', 'name': 'dnsdist'}, + 54: {'service': 'dnsmasq', 'name': 'dnsmasq'}, + 55: {'service': 'unbound', 'name': 'unbound'} +} + +TIMEOUT = 3 + +def check_internet_connection(): + """Sprawdza czy jest dostępne połączenie z internetem używając zewnętrznych DNS""" + logging.info("Sprawdzam połączenie z internetem...") + + external_resolvers = ['8.8.8.8', '1.1.1.1', '9.9.9.9'] + + for resolver_ip in external_resolvers: + try: + resolver = dns.resolver.Resolver() + resolver.nameservers = [resolver_ip] + resolver.timeout = TIMEOUT + resolver.lifetime = TIMEOUT + + answer = resolver.resolve('google.com', 'A') + if answer: + logging.info(f"Połączenie z internetem OK (resolver: {resolver_ip})") + return True + except Exception as e: + logging.debug(f"Błąd przy sprawdzaniu z {resolver_ip}: {e}") + continue + + logging.warning("Brak połączenia z internetem") + return False + +def test_dns_port(port, server='127.0.0.1'): + """Testuje czy DNS odpowiada na danym porcie używając niskopoziomowego dns.query""" + logging.info(f"Testuję DNS na porcie {port} (serwer: {server})...") + + try: + # Tworzymy zapytanie DNS dla google.com + query = dns.message.make_query('google.com', dns.rdatatype.A) + + # Wysyłamy zapytanie UDP + response = dns.query.udp(query, server, timeout=TIMEOUT, port=port) + + # Sprawdzamy czy otrzymaliśmy odpowiedź + if response and len(response.answer) > 0: + logging.info(f"Port {port}: OK - otrzymano odpowiedź ({len(response.answer)} rekordów)") + return True + elif response: + # Otrzymaliśmy odpowiedź, ale bez answer section (może NXDOMAIN) + logging.info(f"Port {port}: OK - serwer odpowiada (rcode: {response.rcode()})") + return True + else: + logging.error(f"Port {port}: BŁĄD - brak odpowiedzi") + return False + + except dns.exception.Timeout: + logging.error(f"Port {port}: TIMEOUT - brak odpowiedzi") + return False + except socket.error as e: + logging.error(f"Port {port}: BŁĄD SOCKET - {e}") + return False + except Exception as e: + logging.error(f"Port {port}: BŁĄD - {type(e).__name__}: {e}") + return False + +def restart_service(service_name): + """Restartuje usługę systemd""" + try: + logging.info(f"Restartuję usługę {service_name}...") + result = subprocess.run( + ['systemctl', 'restart', service_name], + capture_output=True, + text=True, + timeout=30 + ) + + if result.returncode == 0: + logging.info(f"Usługa {service_name} zrestartowana pomyślnie") + return True + else: + logging.error(f"Błąd restartowania {service_name}: {result.stderr}") + return False + except subprocess.TimeoutExpired: + logging.error(f"Timeout przy restartowaniu {service_name}") + return False + except Exception as e: + logging.error(f"Wyjątek przy restartowaniu {service_name}: {e}") + return False + +def main(): + logging.info("=" * 60) + logging.info("START: DNS Health Check & Restart Script") + logging.info("=" * 60) + + if not check_internet_connection(): + logging.error("Brak połączenia z internetem - przerywam działanie skryptu") + sys.exit(1) + + results = {} + services_to_restart = [] + + for port, info in DNS_PORTS.items(): + # Wszystkie testy wykonujemy na 127.0.0.1 + is_working = test_dns_port(port, server='127.0.0.1') + + results[port] = is_working + + if not is_working: + services_to_restart.append(info['service']) + + logging.info("") + logging.info("=" * 60) + logging.info("PODSUMOWANIE TESTÓW DNS:") + for port, status in results.items(): + status_text = "✓ OK" if status else "✗ BŁĄD" + logging.info(f" Port {port} ({DNS_PORTS[port]['name']}): {status_text}") + logging.info("=" * 60) + logging.info("") + + if services_to_restart: + logging.info(f"Usługi do restartu: {', '.join(services_to_restart)}") + + for service in services_to_restart: + restart_service(service) + + logging.info("") + logging.info("Oczekuję 5 sekund na uruchomienie usług...") + import time + time.sleep(5) + + logging.info("") + logging.info("PONOWNE SPRAWDZENIE PO RESTARCIE:") + for port, info in DNS_PORTS.items(): + if info['service'] in services_to_restart: + is_working = test_dns_port(port, server='127.0.0.1') + + status_text = "✓ DZIAŁA" if is_working else "✗ NADAL NIE DZIAŁA" + logging.info(f" Port {port} ({info['name']}): {status_text}") + else: + logging.info("Wszystkie usługi DNS działają prawidłowo - brak potrzeby restartu") + + logging.info("=" * 60) + logging.info("KONIEC: DNS Health Check & Restart Script") + logging.info("=" * 60) + +if __name__ == "__main__": + main()