Dynamic DNS: hoe doen jullie het?

Heb je problemen met het instellen van je netwerk, bedraad of draadloos, dan kan je hier altijd terecht!
Gebruikersavatar
silentkiller
Premium Member
Premium Member
Berichten: 480
Lid geworden op: 24 jun 2008, 13:36
Locatie: Limburg
Uitgedeelde bedankjes: 32 keer
Bedankt: 67 keer

Bericht

tl;dr : Hoe implementeren jullie DDNS? DuckDNS is te onbetrouwbaar
De beste optie lijkt me momenteel om via een API call een A record up2date te houden in DirectAdmin bij vimexx
Nadeel: als ik mijn domein switch naar een andere provider die geen gebruik maakt van DirectAdmin, moet ik weer op zoek naar een andere oplossing

Hoe implementeren jullie DDNS? Liefst zonder afhankelijk te zijn van teveel derde partijen.
CDNs genre cloudflare vind ik geen optie, ik wil mijn trafiek niet unecnrypted door een server van een derde partij.


---
Om mijn thuis IPv4 adres te kunnen bereiken, gebruik ik Dynamic DNS.
Daarvoor draait er een component in een docker container op mijn thuisservertje welke een DuckDNS record up to date houdt.

Op mijn eigen domein heb ik een CNAME record dat point naar het DuckDNS record.

Eigenlijk heeft dat altijd goed gewerkt, ik gebruikte het vroeger enkel voor mijn VPN verbinding welke ik zelden gebruik.

Sinds ik home assistant heb draaien, wordt het veel meer gebruikt. Zowel door mij als mijn vrouw.
Letsencrypt heeft soms moeite om het certificaat te vernieuwen, alsook krijg ik soms een 'a server with the specified hostname could not be found'

Na wat googlen kwam ik hier terecht

DuckDNS geeft regelmatig problemen, dat is de oorzaak van mijn instabiliteit.
Gebruikersavatar
7zp
Plus Member
Plus Member
Berichten: 128
Lid geworden op: 30 jun 2008, 22:49
Uitgedeelde bedankjes: 14 keer
Bedankt: 12 keer

Bericht

Bij welke DNS providers staat uw domein momenteel? Mss hebben die een API?
Hey MinisForum GK41 (OPNsense), Netgear R7800 (OpenWrt), TP-Link C6 (OpenWrt)
Linux Mint 22, AMD 5700x, 64GB DDR4 3200MHz, Nvidia RTX 4060Ti 8GB
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16751
Lid geworden op: 18 feb 2003, 21:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 472 keer
Bedankt: 661 keer
Recent bedankt: 4 keer

Bericht

Ik heb m'n domein bij bNamed.net, en die hebben een API.
Ik run gewoon elke 30 min dit powershell script:

Code: Selecteer alles

$ip = Invoke-RestMethod -Uri 'https://api.ipify.org?format=json'
$current = [System.Net.Dns]::GetHostAddresses('home.example.org')

if ($ip.ip -ne $current.ipaddresstostring) {
    $Cred = New-Object PSCredential('home.example.org',('P@ssw0rd' | ConvertTo-SecureString -AsPlainText -Force))
    $out = Invoke-Webrequest -Uri ('http://www.bnamed.net/dyn/dyn.asp?myip=' + $ip.ip) -Credential $Cred -UseBasicParsing
    Write-EventLog -LogName Application -Source 'IPUpdater' -EntryType SuccessAudit -Message ($out.content + ': ' + $ip.ip) -EventId 1
    return $out.content
} else {
    Write-EventLog -LogName Application -Source 'IPUpdater' -EntryType Information -Message ('no update' + ': ' + $ip.ip) -EventId 0
    return "no update"
}
streulma
Elite Poster
Elite Poster
Berichten: 922
Lid geworden op: 06 aug 2011, 14:39
Uitgedeelde bedankjes: 12 keer
Bedankt: 58 keer

Bericht

no-ip met cname in domein.
Je moet het wel iedere maand herbevestigen.
Zeer tevreden van.
Gebruikersavatar
Sinna
Elite Poster
Elite Poster
Berichten: 3073
Lid geworden op: 14 nov 2008, 07:22
Twitter: KrSi78
Locatie: Brugge
Uitgedeelde bedankjes: 286 keer
Bedankt: 194 keer
Recent bedankt: 2 keer

Bericht

@streulma: en valt Let's Encrypt niet over die CNAME?
Computer(k)nul
Gebruikersavatar
devilkin
Administrator
Administrator
Berichten: 6410
Lid geworden op: 17 mei 2006, 18:10
Uitgedeelde bedankjes: 737 keer
Bedankt: 474 keer
Recent bedankt: 11 keer

Bericht

Ddclient naar cloudflare
Telenet All-Internet -- using CV8560E & OPNsense on PCEngines APU2E4
Proximus & Mobile Vikings -- Using OnePlus 8 Pro (ROM: Stock)
streulma
Elite Poster
Elite Poster
Berichten: 922
Lid geworden op: 06 aug 2011, 14:39
Uitgedeelde bedankjes: 12 keer
Bedankt: 58 keer

Bericht

Sinna schreef: 5 maanden geleden @streulma: en valt Let's Encrypt niet over die CNAME?
Dat weet ik nu niet meer want zit bij Tadaam die geen ddns ondersteund.
Daar doe ik het omgekeerd vpn naar VPS server en van daar poorten open zetten of services doorsluizen.
Gebruikersavatar
silentkiller
Premium Member
Premium Member
Berichten: 480
Lid geworden op: 24 jun 2008, 13:36
Locatie: Limburg
Uitgedeelde bedankjes: 32 keer
Bedankt: 67 keer

Bericht

Thanks already!

Vimexx ondersteunt een API call (feitelijk ondersteunt DirectAdmin bij vimexx data) -> cfr openingspost moet ik het dan herbekijken mocht ik mijn domein daar weghalen. Dit lijkt wel de beste optie..

no-ip is ook een optie, letsencrypt valt niet over die cname (is momenteel ook zo in mijn huidige setup met duckdns)
Gebruikersavatar
devilkin
Administrator
Administrator
Berichten: 6410
Lid geworden op: 17 mei 2006, 18:10
Uitgedeelde bedankjes: 737 keer
Bedankt: 474 keer
Recent bedankt: 11 keer

Bericht

Als je je domein wilt laten staan kan je nog altijd bvb de pure dns hosting (name servers) verwijzen naar een dienst zoals cloudflare, en de rest laten staan.

Kan je hun API gebruiken puur voor records te updaten.
Telenet All-Internet -- using CV8560E & OPNsense on PCEngines APU2E4
Proximus & Mobile Vikings -- Using OnePlus 8 Pro (ROM: Stock)
Mantis
Member
Member
Berichten: 75
Lid geworden op: 28 apr 2007, 10:54
Uitgedeelde bedankjes: 1 keer
Bedankt: 6 keer

Bericht

silentkiller schreef: 5 maanden geleden Hoe implementeren jullie DDNS? Liefst zonder afhankelijk te zijn van teveel derde partijen.
CDNs genre cloudflare vind ik geen optie, ik wil mijn trafiek niet unecnrypted door een server van een derde partij.
Je kan ook puur de DNS functionaliteit van Cloudflare gebruiken zonder tunneling/CDN.
Aangezien je Home Assistant draait, zou je dan dit kunnen gebruiken https://www.home-assistant.io/integrations/cloudflare/
Gebruikersavatar
silentkiller
Premium Member
Premium Member
Berichten: 480
Lid geworden op: 24 jun 2008, 13:36
Locatie: Limburg
Uitgedeelde bedankjes: 32 keer
Bedankt: 67 keer

Bericht

bon, ik wil mijn DNS records niet graag weg moven van vimexx.
Alles qua mail en DNSSEC staat goed, mogelijks doen ze daar ooit aanpassingen aan die ik dan zelf moet opvolgen, vandaar.

Ik heb een script gemaakt om het A DNS record aan te passen. Vergelijking van het publieke IP gebeurt met het A record uitgegeven door de nameservers zelf. Alternatief is de raw dump vanuit direct admin analyseren (waarschijnlijk niet, maar kans bestaat dat deze veranderd bij direct admin upgrades. Vandaar de keuze voor de eerste NS te queryen)
Nadeel: als het aangepast wordt in directadmin, duur het tot 30min tot het gepropageerd wordt over de 3 nameservers van vimexx. Gezien mijn publieke IP bijna niet wijzigt, kan ik daar wel mee leven.

Voor mensen die ook klant zijn bij vimexx en graag gebruik maken van python, hieronder het script.
Ik ben geen developer maar ik denk dat het wel zal dienen, 't draait hier in een docker container elke 10min:

Code: Selecteer alles

### Update DNS record via Direct Admin API using CMD_API_DNS_CONTROL
### Create a login key with only access to CMD_API_DNS_CONTROL in the direct admin environment: <your domain> -> Advanced features -> Login keys
###
### The script checks the A record return by the first NS. If it doesn't match, the A record is updated in Direct Admin to the new public IP address
### Disadvandtage: updates in direct admin don't reflect immediately on the nameservers
### Another option is to replace the NS query by a CMD_API_DNS_CONTROL to query the DNS database but it can only return a raw dump which need to be processed
###
### Config ###
DA_URL = "https://webxxxx.zxcs.be:2222/CMD_API_DNS_CONTROL"
DA_USER = "uXXXXXXXXXXXXXX" # Username to login to directadmin
DA_LOGINKEY = "generate_in_direct_admin" #Loginkey created in direct admin
DA_DOMAIN = "domein.be"
DA_A_RECORD = "dyndns" # FQDN = <DA_A_RECORD>.<DA_DOMAIN> -> dyndns.domein.be
IPV4_IP_URL = "https://api.ipify.org" # Used to retrieve the public IPv4 address
DEBUG = False
###

import requests
import dns.resolver

print("Checking DynDNS for " + DA_A_RECORD + "." + DA_DOMAIN)
dnsresolver = dns.resolver.Resolver()
####Find name server for domain
dnsresponseNS = dnsresolver.resolve(DA_DOMAIN, 'NS')
if not dnsresponseNS: raise Exception('failed to retrieve the nameservers for the domain')
nameservers = [ns.to_text() for ns in dnsresponseNS]
if DEBUG: print("Returned nameserver(s) for domain:")
if DEBUG: print("   ", *nameservers)

### Find IP of first nameserver
dnsresponseNS1 = dnsresolver.resolve(nameservers[0], 'A')
if not dnsresponseNS1: raise Exception('failed to retrieve IP address of the nameserver')
ns1ip = [ns1.to_text() for ns1 in dnsresponseNS1]
if DEBUG: print("IP of the first returned domain server: ")
if DEBUG: print("   ", *ns1ip)


### Use IP of first nameserver to check the DNS record
dnsresolver.nameservers = ns1ip
responseIpOnNameServer = dnsresolver.resolve(DA_A_RECORD + "." + DA_DOMAIN)
if not responseIpOnNameServer: raise Exception('failed to retrieve IPv4 address on the domain NS')
ipOnNameServer = responseIpOnNameServer[0].to_text()
if DEBUG: print("IP of A record on NS: ")
if DEBUG: print("   " + ipOnNameServer)

## Call to the internet to find the current IPv4
session = requests.Session()
responseIpOnInternet = session.get(IPV4_IP_URL)
if not responseIpOnInternet.status_code == 200: raise Exception('failed to retrieve IPv4 address')
ipOninternet = responseIpOnInternet.text
if DEBUG: print("Public IP retrieved from " + IPV4_IP_URL + ":")
if DEBUG: print("   " + ipOninternet)

if not ipOnNameServer == ipOninternet:
    print("Updating DNS record, IP's do not match..")
    postData = {
      "domain": DA_DOMAIN,
      "action": "edit",
      "type": "A",
      "ttl": "60",
      "arecs0": "name=" + DA_A_RECORD,
      "name": DA_A_RECORD,
      "value": ipOninternet,
      "json": "yes"
    }
    session = requests.Session()
    session.auth = (DA_USER, DA_LOGINKEY)
    response = session.post(DA_URL, postData)

    if DEBUG: print(response)
    if not response.status_code == 200: raise Exception('Dailed to update IP address in A record')
    print("Record updated..")
    print(response.text)
else:
    print("Nothing to do..")