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:
- Zainstaluj bibliotekę
requests
:pip install requests
- 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 doemnyhost.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.
- Otwórz crontab dla bieżącego użytkownika:
crontab -e
- 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:
Jeśli chcesz przekierować wyjście do pliku logu, aby łatwiej debugować ewentualne problemy, dodaj*/5 * * * * /usr/bin/python3 /home/user/scripts/cloudflare_update.py
>>
i2>&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 wcloudflare_update.log
. - Zapisz zmiany i zamknij edytor:
- W
nano
: NaciśnijCTRL + O
, potemEnter
, a następnieCTRL + X
. - W
vim
: NaciśnijEsc
, a następnie:wq
iEnter
.
- W
- 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!