📜 ⬆️ ⬇️

Own simple DynDNS server

Recently I was approached with the question "What is the internal IP address you need to specify in the modem to forward the port to the server?". I could not answer the question, because I had not been on this server for a long time, and the qualification of the person at that end did not allow logging into the server and performing an ip address show. Then I thought about creating my own simple analogue of a DynDNS server with the ability to store the IP addresses of all client interfaces.

The server and client parts are implemented in Python. Server OS - Debian 7, client - any Linux with Python. It is assumed that you already have your own domain and your DNS server.

Server part

Bind

First, we generate the necessary keys and configure the DNS server:
dnssec-keygen -r /dev/urandom -a hmac-md5 -b 512 -n HOST dyndns.example.com. 

From the whole of the received files of the form Kdyndns.example.com.+x+y.key or Kdyndns.example.com.+x+y.private remember the zone key and add the zone ( /etc/bind/named.conf.local ):

 key "dyndns.example.com." { algorithm hmac-md5; secret "    "; }; zone "dyndns.example.com" { type master; file "/etc/bind/db.dyndns.example.com"; allow-query { any; }; allow-transfer { 127.0.0.1; }; allow-update { key dyndns.example.com.; }; }; 

')
Apache

We will use Apache with mod-wsgi. If you already have Apache installed and configured, then simply install one necessary package:
 sudo aptitude install libapache2-mod-wsgi 

We include the wsgi module:
 sudo a2enmod wsgi sudo service apache2 reload 

Create a new VirtualHost with SSL:
/ etc / apache2 / sites-available / dyndns-ssl
 <VirtualHost *:443> ServerName dyndns.example.com ServerAdmin admin@example.com DocumentRoot /var/www/tmp <Directory /> Options -FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory> <Directory /var/www/tmp> Options -Indexes -FollowSymLinks -MultiViews AllowOverride None deny from all </Directory> Alias /wsgi-scripts/ /var/www/dyndns/wsgi-scripts/ <Location /wsgi-scripts> SetHandler wsgi-script Options +ExecCGI </Location> SSLEngine on SSLCertificateFile /etc/ssl/localcerts/dyndns.example.com LogLevel info ErrorLog ${APACHE_LOG_DIR}/error_dyndns-ssl.example.com.log CustomLog ${APACHE_LOG_DIR}/access_dyndns-ssl.example.com.log combined </VirtualHost> 


And we put the main update-dyndns.wsgi in /var/www/dyndns/wsgi-scripts/ :
update-dyndns.wsgi
 import dns.query import dns.tsigkeyring import dns.update import sys import datetime from IPy import IP from cgi import parse_qs, escape import hashlib def application(environ, start_response): status = '200 OK' output = 'example.com DynDNS: ' ttl = 300 domain = 'dyndns.example.com' salt = 'YourSalt' d = parse_qs(environ['QUERY_STRING']) hostname = escape(d.get('hostname',[''])[0]) main_address = escape(environ['REMOTE_ADDR']) interfacesRaw = [i.split('_') for i in [escape(interface) for interface in d.get('interface',[])]] checkRemote = escape(d.get('checkstring',[''])[0]) checkString = hashlib.md5(salt + hostname).hexdigest() interfaces=[] for interface in interfacesRaw: try: IP(interface[1]) interfaces.append(interface) except: output += 'Following addresses are not valid: ' + ' '.join(interface) timestampStr = "Last_update_at_" + str(datetime.datetime.now().strftime("%Y-%m-%d_%H:%M")) output += timestampStr + '; Hostname: ' + hostname + '; External address: ' + main_address + '; Check string: ' + checkRemote + '; Interfaces: ' + str(interfaces) if hostname != '' and main_address != '' and checkRemote == checkString: try: keyring = dns.tsigkeyring.from_text({domain+'.' : 'YourKeyring'}) update = dns.update.Update(domain, keyring=keyring) update.replace(hostname, ttl, 'a', main_address) update.replace(hostname, ttl, 'txt', timestampStr) if interfaces != []: for interface in interfaces: str1 = interface[0] + '.' + hostname + '.' + domain + '.' str2 = interface[0] + '.' + hostname + '.' + domain + '.' update.replace(str1, ttl, 'a', interface[1]) update.replace(str2, ttl, 'txt', timestampStr) nsResponse = dns.query.tcp(update, '127.0.0.1') output += '; update OK' except: output += '; Error inserting records!\n\n' else: print 'Error in query ' + escape(environ['QUERY_STRING']) output += '; Error in input' print output output = '' response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output] 


The general principle of the script is as follows: the client is jerking a specific URL on the server dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
  dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=,  checkstring -  ,    (   salt ),        . interface     -     DNS-.      ,      A  TXT    interface.hostname.example.com  hostname.example.com . 


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
  dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=,  checkstring -  ,    (   salt ),        . interface     -     DNS-.      ,      A  TXT    interface.hostname.example.com  hostname.example.com . 


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .
dyndns.example.com/wsgi-scripts/update-dyndns.wsgi?hostname=&interface=_&checkstring=, checkstring - , ( salt ), . interface - DNS-. , A TXT interface.hostname.example.com hostname.example.com .


- cron , , , domain , myhostname salt :
update_mydyndns.py #!/usr/bin/python ################################################################## # #Configuration: domain='dyndns.example.com' myhostname='hostname-placeholder' ################################################################## import socket import fcntl import struct import sys import array import hashlib import httplib import urllib def all_interfaces(): is_64bits = sys.maxsize > 2**32 struct_size = 40 if is_64bits else 32 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) max_possible = 8 # initial value while True: bytes = max_possible * struct_size names = array.array('B', '\0' * bytes) outbytes = struct.unpack('iL', fcntl.ioctl(s.fileno(),0x8912,struct.pack('iL', bytes, names.buffer_info()[0])))[0] if outbytes == bytes: max_possible *= 2 else: break namestr = names.tostring() lst = [] for i in range(0, outbytes, struct_size): name = namestr[i:i+16].split('\0', 1)[0] ip = socket.inet_ntoa(namestr[i+20:i+24]) if name != 'lo': lst.append((name,ip)) return lst salt = 'YourSalt' checkString = hashlib.md5(salt + myhostname).hexdigest() requestData = {} requestData['hostname'] = myhostname requestData['checkstring'] = checkString requestData['interface'] = [j for j in [i[0]+'_'+i[1] for i in all_interfaces()]] requestString = urllib.urlencode(requestData,True) conn = httplib.HTTPSConnection("dyndns.example.com", 443) conn.request("GET", "/wsgi-scripts/update-dyndns.wsgi?"+requestString) r1 = conn.getresponse() print r1.status, r1.reason

( /var/www/dyndns/wsgi-scripts/ ):
get-whole-zone.wsgi import dns.query import dns.zone def application(environ, start_response): status = '200 OK' output = '' domain = 'dyndns.example.com' z = dns.zone.from_xfr(dns.query.xfr('127.0.0.1', 'dyndns.example.com')) names = z.nodes.keys() names.sort() for n in names: output += '\n' + z[n].to_text(n) response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]


PS
, Python- ( , ), . , - .

Source: https://habr.com/ru/post/188598/


All Articles