前回、Raspberry Pi でサーバーを建てたのはいいのだけれども、
うちはグローバル IP アドレスがちょくちょく変わるので、 cron でなんとかしてみる。
前回の記事
Raspberry Pi 2 を入手したので、いろいろやってみる
このままでもいいけども、IP アドレスが変わってアクセスできなくなるのは困るので、
cron とかを使って、 IP アドレスを監視し、変わっていたら変更を適用させます。
とりあえず、cron で 10 分おきくらいでタスクを実行させてみます。
crontab -e
できたら、これは使わないほうがいい*1](#f-28b15ce5 "http://d.hatena.ne.jp/ozuma/20120711/1342014448")([タイプミスしたら悲しいことになる)らしいけど、
これ1回だけなので。
nano が開くので、以下の項目を追加
*/10 * * * * /home/mikazuki/task/hoge.sh
これで、10 分おきに hoge.sh を実行してくれます。
次に、IP アドレスの監視部分。
ほしいのは、グローバル IP アドレスなので、 http://httpbin.org/ip を使うことにしました。
下のようなものが帰ってきます。
{ "origin": "111.111.111.111" }
これで、グローバル IP アドレスが入手出来ました。
次は、これを DNS のレコードに適用させます。
私は、ConoHa の DNS を使っているので、API を使ってやってみることにしました。 Designate とか言うやつらしいですね。便利な時代です。
それで、上までの作業をまとめたのが ↓
#!/usr/bin/python # -*- coding: utf-8 -*- import json import pycurl from StringIO import StringIO # ConoHa APIユーザー API_USER = "hoge" # ConoHa APIパスワード API_PASSWD = "fuga" # ConoHa テナントID TENANT_ID = "foobar" # 更新対象のドメイン DOMAINS = ["example.com", "www.example.com"] # 更新対象のレコード RECORDS = ["A"] # 以下定数 CONOHA_DNS_SERVICE = 'https://dns-service.tyo1.conoha.io' token = "" ipaddress = "" # # ネットワークまわり # # method # 0 : GET # 1 : POST # 3 : PUT # def network(endpoint, method = 0, headers = [], contents = []): buffer = StringIO() curl = pycurl.Curl() curl.setopt(pycurl.URL, endpoint) curl.setopt(pycurl.HTTPHEADER, headers) if method == 1: curl.setopt(pycurl.POST, 1) curl.setopt(pycurl.POSTFIELDS, json.dumps(contents)) if method == 3: curl.setopt(pycurl.CUSTOMREQUEST, 'PUT') curl.setopt(pycurl.POSTFIELDS, json.dumps(contents)) curl.setopt(pycurl.WRITEFUNCTION, buffer.write) curl.perform() curl.close() return buffer.getvalue() # -------------------------------------------------------- # # 初期化 # def initialize(): global token options = {"auth": {"passwordCredentials": {"username": API_USER, "password": API_PASSWD}, "tenantId": TENANT_ID}} response = json.loads(network('https://identity.tyo1.conoha.io/v2.0/tokens', 1, ['Accept: application/json'], options)) token = response["access"]["token"]["id"] # -------------------------------------------------------- # # グローバルIPアドレスを拾ってくる # def get_global_ip(): global ipaddress response = json.loads(network('http://httpbin.org/ip')) ipaddress = response['origin'] # -------------------------------------------------------- # # レコードの更新 # def update_record(record): if record['data'] == ipaddress: return options = {"name": record["name"], "type": record["type"], "data": ipaddress} response = json.loads(network(CONOHA_DNS_SERVICE + '/v1/domains/' + str(record['domain_id']) + '/records/' + str(record['id']), 3, ['Accept: application/json', 'X-Auth-Token: ' + str(token), 'Content-Type: application/json'], options)) if response['data'] == ipaddress: print "ok" # -------------------------------------------------------- # # ConoHa の DNS に登録されているものを列挙したり # def select_domains(): response = json.loads(network(CONOHA_DNS_SERVICE + '/v1/domains', 0, ['Accept: application/json', 'X-Auth-Token: ' + str(token)])) for domain in response["domains"]: records = json.loads(network(CONOHA_DNS_SERVICE + '/v1/domains/' + str(domain['id']) + '/records', 0, ['Accept: application/json', 'X-Auth-Token: ' + str(token)])) for record in records["records"]: if not record['type'] in RECORDS: continue if record['name'][:-1] in DOMAINS: update_record(record) # -------------------------------------------------------- # # Main # def main(): initialize() get_global_ip() select_domains() main()
あまり時間がなかったので、あれだけども(;・∀・)
前の IP アドレスとかは保存してないので、すごく無駄な処理がある気がするけど、
多分そのうち直すと思います。
ちなみに、はじめから pycurl ははいってないので、 pip で入れる必要があります。
# pip の導入
とりあえず、これで目的を達成することはできました。
ではでは。