-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathddns.py
129 lines (101 loc) · 4.6 KB
/
ddns.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import json, socket, os, sys, ipaddress
from requests import Session, get
from hashlib import sha1
from datetime import datetime
from requests_toolbelt.adapters.host_header_ssl import HostHeaderSSLAdapter
def get_ipv4_address_for(site_url):
addrs = socket.getaddrinfo(site_url, 443)
ipv4_addrs = [addr[4][0] for addr in addrs if addr[0] == socket.AF_INET]
return ipv4_addrs[0]
def simple_request(s, username, auth_token, domain, command, additional_data=None):
data = {
"user": username,
"auth": auth_token,
"command": command
}
data["data"] = {"domain": domain}
if additional_data != None:
data["data"].update(additional_data)
#WAPI chce json v kolonce data 2x zabalený do {request: }
single_wrapped_string_request = json.dumps({"request": data})
double_wrapped_request = {"request": single_wrapped_string_request}
wapi_ipv4_address = get_ipv4_address_for("api.wedos.com")
response = s.post(f"https://{wapi_ipv4_address}/wapi/json", data=double_wrapped_request)
#Koukám jestli vše prošlo, padám pokud ne.
if response.json()["response"]["code"] != 1000:
print("Je to rozbitý!")
print(data)
print(response.json()["response"]["result"])
raise RuntimeError("Wedos API se něco nelíbí")
else:
print(f"{command} succeeded")
return response
def change_row(s, username, auth_token, id, rdata, domain):
additional_data = {
"row_id": id,
"ttl": 1800,
"rdata": rdata
}
return simple_request(s, username, auth_token, domain, "dns-row-update", additional_data)
# Jaká byla naše adresa naposled?
if os.path.exists("current_ip"):
with open("current_ip", "r") as current_ip_file:
current_ip_lines = current_ip_file.readlines()
if current_ip_lines:
current_ip = current_ip_lines[0]
else:
current_ip = "0.0.0.0"
else:
current_ip = "0.0.0.0"
global_ip_resp = get("https://ipinfo.io")
# Did we got even a 200?
if global_ip_resp.status_code != 200:
print(f"Non 200 response during global ip retrieval with status {global_ip_resp.status_code} and text {global_ip_resp.text}.")
if global_ip_resp.status_code == 503: # Speciální případ kdy se podělá cdn týpků, kde zjišťujeme ip. Já nechci číst maily o pádu aplikace v takovym případě.
sys.exit(0)
else:
sys.exit(1)
actual_ip = global_ip_resp.json()["ip"]
# Did they send something reasonable back?
try:
addr = ipaddress.ip_address(actual_ip)
# It should be a global one, otherwise it has no reason to exist in the global DNS data.
if not addr.is_global:
print(f"The address {addr} is not a global one.")
sys.exit(2)
except ValueError:
print(f"The returned data {actual_ip} do not comprise an IPv4 address.")
sys.exit(3)
# Pokud se změnila ip, dohodni s WAPI změnu
if actual_ip != current_ip:
# Seženu potřebné proměnné prostředí
username = os.environ.get("WAPI_USERNAME")
password = os.environ.get("WAPI_PASSWORD")
domain = os.environ.get("WEDOS_DOMAIN")
# poskládám autntizační token podle kuchařky od Wedosu
auththingy = sha1()
auththingy.update(username.encode("ascii"))
auththingy.update(sha1(password.encode("ascii")).hexdigest().encode("ascii"))
auththingy.update(str(datetime.now().hour).encode("ascii"))
auth_token = auththingy.hexdigest()
# Tvorba sezení pro requests s oním SSL adaptérem umožňujícím funkčnost SSL i při adresování pomocí IP
s = Session()
s.mount('https://', HostHeaderSSLAdapter())
s.headers = {"host": "api.wedos.com"}
response = simple_request(s, username, auth_token, domain, "dns-rows-list")
rows = response.json()["response"]["data"]["row"]
# Tady se prochází záznamy a kouká se který měnit
# V if řádku je filtrování podle jména a typu záznamu
# Pod tím se pak volá funkce co sestrojí požadavek pro úpravu. Zajímavá proměnná je actual_ip
for row in rows:
if row["name"] == "" and row["rdtype"] == "A":
change_row(s, username, auth_token, row["ID"], actual_ip, domain)
if row["name"] == "*" and row["rdtype"] == "A":
change_row(s, username, auth_token, row["ID"], actual_ip, domain)
# Nakonec požadavek o uložení změn.
simple_request(s, username, auth_token, domain, "dns-domain-commit", {"name": domain})
#Zapíšu si naši novou ip do souboru
with open("current_ip", "w") as current_ip_file:
current_ip_file.write(actual_ip)
else:
print("The ip is the same as the last time")