Last active
October 13, 2015 12:37
-
-
Save overplumbum/4196574 to your computer and use it in GitHub Desktop.
Update Yandex DNS A record with host IP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
curl -sL https://gist.github.com/overplumbum/4196574/raw/install.sh > tmp.sh && sudo sh tmp.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
if [ "$USER" != root ]; then | |
echo "root access required:" | |
exit 1 | |
fi | |
while true; do | |
read -p "What IP address you want to use? (external,internal) " kind | |
if [ "$kind" = external ]; then | |
export interface="" | |
break | |
elif [ "$kind" = internal ]; then | |
ifs=$(ifconfig -s | cut -d ' ' -f 1 | grep -vxE 'Iface|lo') | |
read -p "What interface IP to use: $ifs: " interface | |
export interface=$interface | |
echo $ifs | grep -Fw "$interface" >/dev/null && break | |
fi | |
echo "invalid value, try again" | |
done | |
read -p "Main domain name (e.g. domain.ru, not zzz.domain.ru): " domain | |
read -p "Sub-domain name (e.g. zzz for zzz.domain.ru): " subdomain | |
read -p "Yandex DNS Token (please auth & open https://pddimp.yandex.ru/get_token.xml?domain_name=$domain in browser): " token | |
echo -n "$token" > /etc/yandex-dns-token | |
chmod go-rwx /etc/yandex-dns-token | |
curl -L -s https://gist.github.com/overplumbum/4196574/raw/yandex-dns.py > /usr/local/bin/yandex-dns-update | |
chmod +x /usr/local/bin/yandex-dns-update | |
cmd="/usr/local/bin/yandex-dns-update --domain $domain --interface='$interface' --subdomain $subdomain --token \$(cat /etc/yandex-dns-token) --keep" | |
echo "@reboot www-data $cmd >/dev/null" > /etc/cron.d/yandexdns | |
sh -c "$cmd" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
import argparse | |
import json | |
import os | |
import re | |
import sys | |
import time | |
from urllib import urlencode | |
from urllib2 import urlopen | |
import xml.etree.ElementTree as ET | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--domain', required=True) | |
parser.add_argument('--subdomain', required=True) | |
parser.add_argument('--token', required=True) | |
parser.add_argument('--keep', action='store_true') | |
parser.add_argument('--force', action='store_true') | |
parser.add_argument('--interface', default='') | |
args = parser.parse_args() | |
storage = '/var/lib/yandex-dns.json' | |
if os.path.exists(storage): | |
stored_data = json.load(open(storage, 'r')) | |
else: | |
stored_data = {} | |
store_key = args.domain + '|' + args.subdomain + '|' + args.interface | |
if not args.interface: | |
ip = urlopen('http://checkip.dyndns.com/').read().strip() | |
ip = re.search(r'\d+\.\d+\.\d+\.\d+', ip).group(0) | |
else: | |
import socket | |
import fcntl | |
import struct | |
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
ip = socket.inet_ntoa(fcntl.ioctl( | |
s.fileno(), | |
0x8915, # SIOCGIFADDR | |
struct.pack('256s', args.interface[:15]) | |
)[20:24]) | |
print 'detected ip', ip | |
if not args.force and ip == stored_data.get(store_key): | |
print 'not changed' | |
sys.exit(0) | |
# http://api.yandex.ru/pdd/doc/api-pdd/reference/api-dns.xml | |
base_params = { | |
'token': args.token, | |
'domain': args.domain, | |
} | |
def get_sub_id(): | |
data = urlopen('https://pddimp.yandex.ru/nsapi/get_domain_records.xml?' + urlencode(base_params)).read() | |
root = ET.fromstring(data) | |
node = root.find("domains/domain/response/record[@subdomain='" + args.subdomain + "']") | |
if not node is None: | |
return node.attrib['id'] | |
sub_id = get_sub_id() | |
if not sub_id: | |
print 'sub-domain not found, adding' | |
params = base_params.copy() | |
params.update({ | |
'subdomain': args.subdomain, | |
'ttl': 900, | |
'content': ip, | |
}) | |
data = urlopen('https://pddimp.yandex.ru/nsapi/add_a_record.xml?' + urlencode(params)).read() | |
root = ET.fromstring(data) | |
error = root.findtext('domains/error') | |
assert error == 'ok', error | |
print "added" | |
time.sleep(1) | |
sub_id = get_sub_id() | |
assert sub_id | |
print 'dns listing ok' | |
params = base_params.copy() | |
params.update({ | |
'subdomain': args.subdomain, | |
'record_id': str(sub_id), | |
'ttl': 900, | |
'content': ip, | |
}) | |
data = urlopen('https://pddimp.yandex.ru/nsapi/edit_a_record.xml?' + urlencode(params)).read() | |
root = ET.fromstring(data) | |
error = root.findtext('domains/error') | |
assert error == 'ok', error | |
print 'dns update ok' | |
stored_data[store_key] = ip | |
json.dump(stored_data, open(storage, 'w'), indent=4) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment