Jak Poradzić Sobie ze Zmiennym IP Publicznym: Automatyczna aktualizacja Rekordu DNS na Cloudflare

Wstęp

Wiele domowych i małych firmowych sieci korzysta z dynamicznych adresów IP przyznawanych przez dostawcę usług internetowych (ISP). Oznacza to, że publiczny adres IP może się zmieniać w czasie. Dla użytkowników, którzy chcą uzyskać zdalny dostęp do swoich zasobów lub hostować usługi, zmienne IP może stanowić problem. W tym artykule pokażemy, jak automatycznie aktualizować rekord DNS na Cloudflare, aby zawsze wskazywał aktualny publiczny adres IP, wykorzystując Pythona i crontab w systemie openSUSE.

Krok 1: Instalacja Niezbędnych Narzędzi

Na początek upewnij się, że masz zainstalowane narzędzia niezbędne do wykonania zadań w systemie openSUSE.

Sprawdzenie i Instalacja Cron

Cron to narzędzie do planowania zadań, które jest standardem w systemach Unix/Linux. Aby sprawdzić, czy cron jest zainstalowany i działa, użyj poniższych poleceń:

sudo systemctl status cron

Jeśli cron nie jest zainstalowany, zainstaluj go za pomocą:

sudo zypper install cron

Następnie uruchom cron i ustaw go, aby uruchamiał się przy starcie systemu:

sudo systemctl start cron
sudo systemctl enable cron

Sprawdzenie Ścieżki do Pythona i Skryptu

Upewnij się, że znasz pełną ścieżkę do interpretera Pythona i skryptu. Możesz to sprawdzić za pomocą:

which python3

To zazwyczaj zwróci coś w stylu /usr/bin/python3.

Aby uzyskać pełną ścieżkę do skryptu, przejdź do katalogu, w którym jest on umieszczony i użyj komendy:

pwd

Krok 2: Skrypt do Aktualizacji Rekordu DNS na Cloudflare

Poniżej znajduje się skrypt w Pythonie, który sprawdzi bieżący publiczny adres IP hosta i zaktualizuje odpowiedni rekord A na Cloudflare, jeśli adres IP się zmienił.


# 
# Autor: lesinski.it
# Kod pochodzi ze strony lesinski.it
# Artykuł opisuje, jak poradzić sobie ze zmiennym IP publicznym i aktualizować rekord DNS na Cloudflare.
#

import requests

# Cloudflare API endpoint and token
CLOUDFLARE_API_URL = "https://api.cloudflare.com/client/v4"
CLOUDFLARE_API_TOKEN = "YOUR_CLOUDFLARE_API_TOKEN"

# Zone ID and Record Name for the DNS record to update
ZONE_ID = "YOUR_ZONE_ID"
RECORD_NAME = "YOUR_RECORD_NAME"  # e.g., "type host for domain host.example.com"

def get_public_ip():
    """Fetch the current public IP address."""
    try:
        response = requests.get("https://api.ipify.org?format=json")
        response.raise_for_status()
        ip = response.json()["ip"]
        return ip
    except requests.RequestException as e:
        print(f"Error fetching public IP: {e}")
        return None

def get_record_id(zone_id, record_name):
    """Retrieve the DNS record ID for the given record name."""
    url = f"{CLOUDFLARE_API_URL}/zones/{zone_id}/dns_records"
    headers = {
        "Authorization": f"Bearer {CLOUDFLARE_API_TOKEN}",
        "Content-Type": "application/json"
    }
    try:
        response = requests.get(url, headers=headers, params={"type": "A", "name": record_name})
        response.raise_for_status()
        records = response.json()["result"]
        for record in records:
            if record["name"] == record_name:
                return record["id"]
        print(f"No record found for {record_name}")
        return None
    except requests.RequestException as e:
        print(f"Error fetching DNS record ID: {e}")
        return None

def update_cloudflare_dns(zone_id, record_id, ip_address):
    """Update the A record in Cloudflare with the new IP address."""
    headers = {
        "Authorization": f"Bearer {CLOUDFLARE_API_TOKEN}",
        "Content-Type": "application/json"
    }
    url = f"{CLOUDFLARE_API_URL}/zones/{zone_id}/dns_records/{record_id}"

    try:
        # Fetch the current DNS record details
        record_response = requests.get(url, headers=headers)
        record_response.raise_for_status()
        record_data = record_response.json()["result"]

        # Check if the IP address needs updating
        if record_data["content"] == ip_address:
            print(f"IP address {ip_address} is already set. No update needed.")
            return

        # Update the DNS record
        update_data = {
            "type": "A",
            "name": RECORD_NAME,
            "content": ip_address,
            "ttl": 120  # TTL in seconds
        }
        update_response = requests.put(url, headers=headers, json=update_data)
        update_response.raise_for_status()
        print(f"Successfully updated DNS record to IP: {ip_address}")

    except requests.RequestException as e:
        print(f"Error updating Cloudflare DNS record: {e}")

if __name__ == "__main__":
    ip = get_public_ip()
    if ip:
        record_id = get_record_id(ZONE_ID, RECORD_NAME)
        if record_id:
            update_cloudflare_dns(ZONE_ID, record_id, ip)

Instrukcje:

  1. Zainstaluj bibliotekę requests:
    pip install requests
  2. Zaktualizuj skrypt, wprowadzając swoje dane:
    • CLOUDFLARE_API_TOKEN: Twój token API z Cloudflare.
    • ZONE_ID: Identyfikator strefy (zone ID) dla domeny.
    • RECORD_NAME: Nazwa rekordu DNS, który chcesz zaktualizować (np. "host" dla doemny host.example.com).

Krok 3: Ustawienie Zadania Cron do Uruchamiania Skryptu Co 5 Minut

Teraz, gdy skrypt jest gotowy, możemy użyć crontab do jego regularnego uruchamiania.

  1. Otwórz crontab dla bieżącego użytkownika:
    crontab -e
  2. Dodaj nową linię do pliku crontab, która uruchomi skrypt co 5 minut. Upewnij się, że podajesz pełne ścieżki do Pythona i skryptu:
    */5 * * * * /usr/bin/python3 /home/user/scripts/cloudflare_update.py
    Jeśli chcesz przekierować wyjście do pliku logu, aby łatwiej debugować ewentualne problemy, dodaj >> i 2>&1:
    */5 * * * * /usr/bin/python3 /home/user/scripts/cloudflare_update.py >> /home/user/scripts/cloudflare_update.log 2>&1

    Wyjaśnienie 2>&1:

    • 2> oznacza przekierowanie standardowego strumienia błędów (stderr).
    • &1 oznacza do miejsca, do którego obecnie jest kierowany standardowy strumień wyjścia (stdout).

    Więc 2>&1 oznacza przekierowanie stderr do stdout, co sprawia, że zarówno normalne wyjścia, jak i błędy będą zapisane w cloudflare_update.log.

  3. Zapisz zmiany i zamknij edytor:
    • W nano: Naciśnij CTRL + O, potem Enter, a następnie CTRL + X.
    • W vim: Naciśnij Esc, a następnie :wq i Enter.
  4. Zweryfikuj wpisy w crontab:
    crontab -l

Podsumowanie

Dynamiczne adresy IP mogą stanowić wyzwanie, szczególnie jeśli polegasz na stałym adresie do zdalnego dostępu lub hostowania usług. Dzięki powyższym krokom, możesz skonfigurować automatyczną aktualizację rekordu DNS na Cloudflare, aby zawsze wskazywał na aktualny publiczny adres IP Twojego hosta. Skrypt w Pythonie, wsparty przez crontab, to proste i skuteczne rozwiązanie na zmieniające się IP publiczne.

Jeśli masz pytania lub napotkasz problemy podczas konfigurowania tego rozwiązania, śmiało pytaj!

We use cookies
Strona internetowa zbiera informację na potrzeby analizy ruchu odwiedzających (Google Analytics). Czy zgadzasz się na przetwarzanie danych?