Python
Python3
SoftLayer

SoftLayerのDNSサービスをDDNS的に使う

More than 1 year has passed since last update.

SoftLayerは、IBMの子会社 SoftLayer社によって提供されているクラウドサービス。SoftLayerの会員になると、DNSサーバーサービスが無料で使えるようになります。
また、SoftLayerは、非常に豊富なAPIによりユーザーに「ガラス張り」状態でインターフェース提供をしているので、これを組み合わせると、SoftLayerに会員登録(無料)をしておくだけでDDNSサービスが使い放題、ってわけです。

CentOS 6 (現時点 6.6) + Python3.4で構築していますので、それを連携します。

大まかな構成手順

  1. SoftLayer社に会員登録する。control.softlayer.com にてログオンし、User画面にて ユーザーIDとAPIキーを控えておきます。
  2. CentOS 6 にPython 3.4をインストール。wgetでソースを引っ張ってきてコンパイルするとpip 3.4も一緒に導入されます。(hint: ldconfig)
  3. SoftLayer Python Clientを導入。
pip3.4 install softlayer

4.Python3 のスクリプトを書いて、crontab -e で登録。この部分を情報連携します。

グローバルIPアドレスを引っ張ってきてSoftLayer DNSを更新するスクリプト

まずは、グローバルIPの取得をrequestsで。

python3
#!/usr/local/bin/python3.4

import requests
import SoftLayer
import syslog

# グローバルIPアドレスをipinfoからゲット。ipsに文字列として代入。
ipr = requests.get('http://ipinfo.io/json')
ips = ipr.json()['ip']

SoftLayerにログオン。この時に控えておいたSoftLayerのユーザー名とAPIキーを入れ込みます。
このあたりのフローからは、下記マニュアルを要チェック。
https://softlayer-api-python-client.readthedocs.org/en/latest/

python3
# ユーザー名、APIキーでSoftLayerにログオン。DNSマネージャをインスタンス化
slClient = SoftLayer.Client(username='username', api_key='__YOUR_User_API_Key__Total_64_Digits__')
manDNS = SoftLayer.managers.dns.DNSManager(slClient)

manDNSとしてインスタンス化したDNSManagerのメソッド群を使用して、SoftLayerのDNSサービスを突っついていきます。まずは、SoftLayer DNSサービスに登録しているDNSゾーンの一覧を取得します。IPアドレスを更新したいのがwww.domainname.infoとすると、domainname.infoの部分です。
これをやるのが、list_zones() です。dictのlistが返ってきます。参考として返り値の出方も入れておきます。帰り値のうち、のちのち使うのはzoneのIDです。

python3
lz = manDNS.list_zones()

>>> type(lz)
<class 'list'>
>>> len(lz)
1
>>> type(lz[0])
<class 'dict'>
>>> lz[0]
{'updateDate': '2014-12-19T17:56:49+09:00', 'id': 1234567, 'name': 'domainname.info', 'serial': 2014121901}

zoneID = lz[0]['id']

>>> type(zoneID)
<class 'int'>
>>> print(zoneID)
1234567

次に、ゾーン中のレコードを引っ張ってきます。www.domainname.info とすると wwwの部分ですね。
get_records(zone_id, ttl=None, data=None, host=None, record_type=None)を使います。

python3
lrec = manDNS.get_records(zoneID, host='www')

>>> type(lrec)
<class 'list'>
>>> len(lrec)
1

# このDictを、SoftLayer APIでは「レコード」と称します。
record_in = lrec[0]

>>> type(record_in)
<class 'dict'>
>>> record_in
{'host': 'www', 'retry': '', 'id': 98765432, 'expire': '', 'minimum': '', 'type': 'a', 'domainId': 1234567, 'mxPriority': '', 'ttl': 900, 'data': '1.2.34.56', 'refresh': ''}

recordID = record_in['id']

>>> type(recordID)
<class 'int'>
>>> print(recordID)
98765432

このrecordIDを控えておけば、上記のlist_zones(), get_records()をすっとばせます。日頃の運用で仕掛けるpythonスクリプトでは、こうしてしまいます。

python3
#!/usr/local/bin/python3.4

import requests
import SoftLayer
import syslog

ipr = requests.get('http://ipinfo.io/json')
ips = ipr.json()['ip']

slClient = SoftLayer.Client(username='username', api_key='__YOUR_User_API_Key__Total_64_Digits__')
manDNS = SoftLayer.managers.dns.DNSManager(slClient)

recordID = 98765432
record_in = manDNS.record.getObject(id=recordID)
ipsl_in = record_in['data']

record_in が、ホスト名 www のAレコードということになります。このrecord_indata 値を、新しいグローバルIPアドレスに書き換えて、SoftLayer DNSに登録すればいいのです。

python3
if ips != ipsl_in:
        record_in['data'] = ips
        manDNS.edit_record(record_in)
        syslog.syslog(syslog.LOG_INFO, "UpdateSLDNS: Updated")