-
Notifications
You must be signed in to change notification settings - Fork 6
/
one_com_ddns.py
194 lines (142 loc) · 5.91 KB
/
one_com_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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
'''
#################################
## ##
## one.com DDNS Script ##
## ##
#################################
| Version | 2.4 |
+--------------+----------------+
| Last Updated | 2023-10-05 |
+--------------+----------------+
+----------------+-------------------------+
| Initial Author | Lugico <main@lugico.de> |
+----------------+-------------------------+
| Contributors | Vigge |
+----------------+-------------------------+
Note:
This script is not very fail proof.
Very few possible exceptions are handled, something as simple
as a missing internet connection will make the script behave
unexpectedly. Use with caution.
If you have any problems or suggestions, please open an issue
on github or send me an email (main@lugico.de)
'''
# YOUR ONE.COM LOGIN
USERNAME="email.address@example.com"
PASSWORD="Your Beautiful Password"
# YOUR DOMAIN ( NOT www.example.com, only example.com )"
DOMAIN="example.com"
# LIST OF SUBDOMAINS YOU WANT POINTING TO YOUR IP
SUBDOMAINS = ["myddns"]
# SUBDOMAINS = ["mutiple", "subdomains"]
# YOUR IP ADDRESS.
IP='AUTO'
# '127.0.0.1' -> IP Address
# 'AUTO' -> Automatically detect using ipify.org
# 'ARG' -> Read from commandline argument ($ python3 ddns.py 127.0.0.1)
# CHECK IF IP ADDRESS HAS CHANGED SINCE LAST SCRIPT EXECUTION?
CHECK_IP_CHANGE = True
# True = only continue when IP has changed
# False = always continue
# PATH WHERE THE LAST IP SHOULD BE SAVED INBETWEEN SCRIPT EXECUTIONS
# not needed CHECK_IP_CHANGE is false
LAST_IP_FILE = "lastip.txt"
import requests
import json
import sys
if IP == 'AUTO':
print("Fetching IP Address...")
try:
IP = requests.get("https://api.ipify.org/").text
except requests.ConnectionError:
raise SystemExit("Failed to get IP Address from ipify")
print(f"Detected IP: {IP}")
elif IP == 'ARG':
if (len(sys.argv) < 2):
raise SystemExit('No IP Address provided in commandline arguments')
else:
IP = sys.argv[1]
if CHECK_IP_CHANGE:
try:
# try to read file
with open(LAST_IP_FILE,"r") as f:
if (IP == f.read()):
# abort if ip in file is same as current
print("IP Address hasn't changed. Aborting")
exit()
except IOError:
pass
# write current ip to file
with open(LAST_IP_FILE,"w") as f:
f.write(IP)
def findBetween(haystack, needle1, needle2):
index1 = haystack.find(needle1) + len(needle1)
index2 = haystack.find(needle2, index1 + 1)
return haystack[index1 : index2]
# will create a requests session and log you into your one.com account in that session
def loginSession(USERNAME, PASSWORD, TARGET_DOMAIN=''):
print("Logging in...")
# create requests session
session = requests.session()
# get admin panel to be redirected to login page
redirectmeurl = "https://www.one.com/admin/"
try:
r = session.get(redirectmeurl)
except requests.ConnectionError:
raise SystemExit("Connection to one.com failed.")
# find url to post login credentials to from form action attribute
substrstart = '<form id="kc-form-login" class="Login-form login autofill" onsubmit="login.disabled = true; return true;" action="'
substrend = '"'
posturl = findBetween(r.text, substrstart, substrend).replace('&','&')
# post login data
logindata = {'username': USERNAME, 'password': PASSWORD, 'credentialId' : ''}
response = session.post(posturl, data=logindata)
if response.text.find("Invalid username or password.") != -1:
print("!!! - Invalid credentials. Exiting")
exit(1)
print("Login successful.")
# For accounts with multiple domains it seems to still be needed to select which target domain to operate on.
if TARGET_DOMAIN:
print("Setting active domain to: {}".format(TARGET_DOMAIN))
selectAdminDomain(session, TARGET_DOMAIN)
return session
def selectAdminDomain(session, DOMAIN):
request_str = "https://www.one.com/admin/select-admin-domain.do?domain={}".format(DOMAIN)
session.get(request_str)
# gets all DNS records on your domain.
def getCustomRecords(session, DOMAIN):
print("Getting Records")
getres = session.get("https://www.one.com/admin/api/domains/" + DOMAIN + "/dns/custom_records").text
if len(getres) == 0:
print("!!! - No records found. Exiting")
exit()
return json.loads(getres)["result"]["data"]
# finds the record id of a record from it's subdomain
def findIdBySubdomain(records, subdomain):
print("searching domain '" + subdomain + "'")
for obj in records:
if obj["attributes"]["prefix"] == subdomain:
print("Found Domain '" + subdomain + "': " + obj["id"])
return obj["id"]
return ""
# changes the IP Address of a TYPE A record. Default TTL=3800
def changeIP(session, ID, DOMAIN, SUBDOMAIN, IP, TTL=3600):
print("Changing IP on subdomain '" + SUBDOMAIN + "' - ID '" + ID + "' TO NEW IP '" + IP + "'")
tosend = {"type":"dns_service_records","id":ID,"attributes":{"type":"A","prefix":SUBDOMAIN,"content":IP,"ttl":TTL}}
dnsurl="https://www.one.com/admin/api/domains/" + DOMAIN + "/dns/custom_records/" + ID
sendheaders={'Content-Type': 'application/json'}
session.patch(dnsurl, data=json.dumps(tosend), headers=sendheaders)
print("Sent Change IP Request")
# Create login session
s = loginSession(USERNAME, PASSWORD, DOMAIN)
# get dns records
records = getCustomRecords(s, DOMAIN)
#print(records)
# loop through list of subdomains
for subdomain in SUBDOMAINS:
#change ip address
recordid = findIdBySubdomain(records, subdomain)
if recordid == "":
print("!!! - Record '" + subdomain + "' could not be found.")
continue
changeIP(s, recordid, DOMAIN, subdomain, IP, 600)