Find own ipv6 address and loop updates
parent
67a5b82d9b
commit
4d78196461
|
@ -3,5 +3,9 @@ RUN pip install --no-cache-dir --upgrade pip
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY src/ ./
|
COPY src/ ./
|
||||||
RUN pip install --no-cache-dir --requirement requirements.txt
|
|
||||||
|
ARG APK_BUILD_DEPS=".build-deps gcc musl-dev linux-headers"
|
||||||
|
RUN apk add --no-cache --virtual $APK_BUILD_DEPS\
|
||||||
|
&& pip install --no-cache-dir --requirement requirements.txt \
|
||||||
|
&& apk del $APK_BUILD_DEPS
|
||||||
CMD [ "python", "ddns_update.py" ]
|
CMD [ "python", "ddns_update.py" ]
|
||||||
|
|
|
@ -5,4 +5,8 @@ services:
|
||||||
container_name: strato-ddns
|
container_name: strato-ddns
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
|
network_mode: host
|
||||||
restart: always
|
restart: always
|
||||||
|
environment:
|
||||||
|
- DDNS_HOST=my.host.name
|
||||||
|
- DDNS_KEY=secret
|
||||||
|
|
|
@ -5,15 +5,54 @@ import requests
|
||||||
from requests.exceptions import RequestException
|
from requests.exceptions import RequestException
|
||||||
import click
|
import click
|
||||||
from os import environ
|
from os import environ
|
||||||
|
from netifaces import interfaces, ifaddresses, AF_INET6
|
||||||
|
from ipaddress import ip_address
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
log = logging.getLogger("ddns updater")
|
log = logging.getLogger("ddns updater")
|
||||||
|
|
||||||
|
|
||||||
|
def get_global_address(address_family):
|
||||||
|
for interface in interfaces():
|
||||||
|
if_addresses = ifaddresses(interface)
|
||||||
|
if address_family in if_addresses:
|
||||||
|
for address in if_addresses[address_family]:
|
||||||
|
addr = ip_address(address["addr"].split("%")[0])
|
||||||
|
if addr.is_global:
|
||||||
|
return addr
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_global_ipv6():
|
||||||
|
return get_global_address(AF_INET6)
|
||||||
|
|
||||||
|
|
||||||
def response_successful(response_text):
|
def response_successful(response_text):
|
||||||
return response_text.startswith("good") or response_text.startswith("nochg")
|
return response_text.startswith("good") or response_text.startswith("nochg")
|
||||||
|
|
||||||
|
|
||||||
|
def ddns_update(host, key, ip):
|
||||||
|
url = f"https://dyndns.strato.com/nic/update?hostname={host}&myip={ip}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.get(url, auth=(host, key), timeout=3)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
if not response_successful(response.text):
|
||||||
|
raise RequestException("update failed")
|
||||||
|
|
||||||
|
except RequestException as error:
|
||||||
|
log.debug(response.text.strip())
|
||||||
|
log.error(error)
|
||||||
|
return False
|
||||||
|
|
||||||
|
log.debug(response.text.strip())
|
||||||
|
log.info("update successful")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.option(
|
@click.option(
|
||||||
"--host",
|
"--host",
|
||||||
|
@ -27,30 +66,17 @@ def response_successful(response_text):
|
||||||
default=lambda: environ.get("DDNS_KEY", None),
|
default=lambda: environ.get("DDNS_KEY", None),
|
||||||
help="The ddns authorization key",
|
help="The ddns authorization key",
|
||||||
)
|
)
|
||||||
@click.option(
|
def loop_ddns_update(host, key):
|
||||||
"--ip",
|
last_ip = None
|
||||||
required=True,
|
while True:
|
||||||
default=lambda: environ.get("DDNS_IP", None),
|
current_ip = get_global_ipv6()
|
||||||
help="The hosts new ip address in ipv4 or ipv6 format",
|
if current_ip != last_ip:
|
||||||
)
|
if ddns_update(host, key, current_ip):
|
||||||
def ddns_update(host, key, ip):
|
last_ip = current_ip
|
||||||
url = f"https://dyndns.strato.com/nic/update?hostname={host}&myip={ip}"
|
else:
|
||||||
|
log.debug("skipped update, ip address unchanged")
|
||||||
try:
|
sleep(5)
|
||||||
response = requests.get(url, auth=(host, key), timeout=3)
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
if not response_successful(response.text):
|
|
||||||
raise RequestException("update failed")
|
|
||||||
|
|
||||||
except RequestException as error:
|
|
||||||
log.debug(response.text.strip())
|
|
||||||
log.error(error)
|
|
||||||
return
|
|
||||||
|
|
||||||
log.debug(response.text.strip())
|
|
||||||
log.info("update successful")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
ddns_update()
|
loop_ddns_update()
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
Click==7.0
|
Click==7.0
|
||||||
requests==2.23.0
|
requests==2.23.0
|
||||||
|
netifaces==0.10.9
|
||||||
|
ipaddress==1.0.23
|
||||||
|
|
Loading…
Reference in New Issue