Dynamická DNS – DDNS u Wedosu

Vyřešeno169 zhlédnutíDNS
1

Zdravím,

nejde o dotaz, ale o sdílení nalezeného/vytvořeného řešení problému. Kupodivu na internetu toho moc dohledat nelze….a to ani na stránkách Wedosu. Takže bych chtěl sdílet své řešení a ušetřit ostatním čas hledání.

Návod je vytvořený a otestovaný na domácím serveru běžící na OS Ubuntu server 18.04.2 LTS. U Wedosu mám tedy jen zaregistrovanou doménu a využívám výpočetní výkon domácího železa.

Internet zná tato řešení změny DNS, bohužel pro mě nefungovaly:

  • https://www.funnyvoid.com/dynamicke-dns-na-vps-od-wedosu-cz.html – skript mi fungoval pouze pro subdomény, věnoval jsem mu hodně pozornosti – drive.example.com ano, ale pro example.com už ne.
  • https://www.abclinuxu.cz/blog/soban/2016/3/ddns-u-wedosu – kód na podobný způsob, ale podle popisu fungování mi to nesedělo
  • https://gist.github.com/hroncok/166305c39fd8e80609d1 – zde jsem se inspiroval a kód upravil pro svoji potřebu. Originál slouží pro jiný účel.

Upravený kód našeho řešení:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Script for Wedos DDNS 
==============================
This script uses Wedos WAPI for modifiing saved IP adress DNS record to actual IP of running device.
Script finds userfull in case you internet provider change your IP adress in random times and you want automatically watch and apply changes.
 MANUAL
1)Set up your WEDOS API (Czech): http://kb.wedos.com/wapi/aktivace-nastaveni.html
2)Set your credentials few lines bellow.
3)Run this daily by cron.
This was tested on Python 3 only and requires requests.
  Modified version by:
Copyright (c) 2020 Marek Vach <mvach@email.cz>
 Original software by:
Copyright (c) 2015 Miro Hrončok <miro@hroncok.cz>
https://gist.github.com/hroncok/166305c39fd8e80609d1
 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Provided license texts might have their own copyrights and restrictions
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
 import datetime
import hashlib
import json
import socket
 import requests
 import urllib.request
 # Change these!
LOGIN = 'user@example.com' #CASE SENSITIVE!
PASSWORD = 'passW0rd!' # by Wedos requirments must contain at least one upper case and one special symbol
DOMAIN = 'example.com' # 'example.com' - must be already existing A record!
 # Keep this
API = 'https://api.wedos.com/wapi/json'
  def get_auth(login=LOGIN, password=PASSWORD):
    passhash = hashlib.sha1(password.encode('utf8')).hexdigest()
    phrase = login + passhash + datetime.datetime.now().strftime('%H')
    return hashlib.sha1(phrase.encode('utf8')).hexdigest()
  def request(command, data, login=LOGIN, auth=get_auth(), url=API):
    d = {'request': {'user': login, 'auth': auth, 'command': command, 'data': data}}
    r = requests.post(url, data={'request': json.dumps(d)})
    data = r.json()
    if data['response']['result'] != 'OK':
        raise Exception('Response from WEDOS was {}'.format(data['response']['result']))
    return data
  def dns_rows_list(domain=DOMAIN):
    return request('dns-rows-list', locals())
  def dns_row_update(row_id, ttl, rdata, domain=DOMAIN):
    return request('dns-row-update', locals())
  def dns_domain_commit(name=DOMAIN):
    return request('dns-domain-commit', locals())
  def find_A_record():
    data = dns_rows_list()
     for row in data['response']['data']['row']:
        if row['rdtype'] == 'A' and row['name'] == '':
            return row['ID'], row['ttl']
     raise Exception('Cannot find A record for the domain')
  def update_A_record(ip, domain=DOMAIN):
    dns_row_update(*find_A_record(), rdata=ip)
    dns_domain_commit()
    print('Updated {} to {}'.format(domain, ip))
 def get_current_device_public_ip():
    ident_me_find_ip = urllib.request.urlopen('https://ident.me').read().decode('utf8')
    return ident_me_find_ip
 def compare_ip_of_dns_record_and_local_device_and_make_changes(domain=DOMAIN):
    dns_ip = socket.gethostbyname(domain)
    local_device_ip = get_current_device_public_ip()
     if dns_ip != local_device_ip:
        update_A_record(local_device_ip, domain)
    else:
        print('IP addresses match')
  compare_ip_of_dns_record_and_local_device_and_make_changes()

Manuál:

  1. Nastavte a aktivujte si WAPI dle návodu http://kb.wedos.com/wapi/aktivace-nastaveni.html
  2. Upravte v kódu wedos-updatedns.py řádky LOGIN, PASSWORD, DOMAIN
  3. Nastavte soubor jako spustitelný
  4. Vytvořte cron úlohu (automatické spouštění) pro daný skript.

Nastevení souboru jako spustitelý:

sudo chmod +x /var/www/ddns/wedos-updatedns.py

Odzkoušet funkčnost skriptu ručně můžete příkazem:

./var/www/ddns/wedos-updatedns.py

Vytvoření cron úlohy:

sudo crontab -e

a na konec přidejte 2 řádky, celý soubor u mě vypadá takto:

# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
 @reboot   var/www/ddns/wedos-updatedns.py
0 * * * * var/www/ddns/wedos-updatedns.py

První řádek spouští skript po restartu PC. Druhý spouští skript každou hodinu.

Tak snad vám návod a trocha mého kódování pomůže neztratit kupu času. Komu návod pomůže, budu rád, když zanechá poděkování.

Role: Zákazník
Otázka je uzamčena pro nové odpovědi.
Vybral nejlepší odpověď
1

A ještě jeden dobrý tip. U nastavování WAPI musíte zvolit povolený rozsah IP adres. A jelikož se tu bavíme o dynamických IP adresách, tak budete potřebovat znát rozsahy IP podle poskytovatelů. To naleznete zde:

Rozsah IPv4 adres přidělených pro Českou republiku

Jak to zapsat naleznete v návodu od Wedosu k WAPi.

Role: Zákazník
publikoval nový komentář

Vidím trošku problém v definování adres/subnetů ze kterých lze požadavky API odesílat. V dokumentaci je zapis takovy, ze lze zapsat pouze posledni oktet adres: https://kb.wedos.com/cs/wapi-api-rozhrani/zakladni-informace-wapi-api-rozhrani/wapi-zakladni-informace/

Bohuzel nektere rozsahy dle https://www.nirsoft.net/countryip/cz.html nebo vami zminovane tomasbenda.cz jsou i vetsi. Netusite jak by slo do povolenych adres zapsat takovy subnet: „89.102.0.0“ mimochodem „89.102..“ nefunguje. „89.102.0.“ ale uz ano. Jedna se o UPC – tech rozsahu maji vice..

Zkuste s jednou tečkou, v daném příkladu používáte tečky 2 a možná proto Vám to nejde.

Já mám subnet „78.44.“, též UPC a zatím ke spokojenosti.

Ty jo to přiznám, že fakt koukám 🙂 Můžu se zeptat co je to vaše železo na kterém vám běží váš server? Je to Raspberry? Měl byste návod jak to vše poladit (Ubuntu, Gunicorn, Nginx ?). Chci dělat Django aplikace v Pythonu. Váš způsob se mi zdá příliš náročný, ale zajímavý. Proč jste nešel do VPS? Děkuji, Jirka

Prohlížíte 1 ze 1 odpovědí, klikněte zde pro zobrazení všech odpovědí.

Categories