Date Tags VPS

DDNS を実現するサービスはいろいろあるが、ConoHa の APIを使えば自前でDDNSっぽいことを実現できるので試してみた。

事前準備

  • ConoHa にログインする
  • APIタブから APIユーザーのパスワードを登録して API情報にある テナントID と、APIユーザー名とパスワードを書き留めておく
  • DNS タブから、事前に A Record を登録しておく。

API は https://www.conoha.jp/docs/index.html に記載されている。 流れは下記

  • 自分のホストの Global IP を取得する。
  • Identify API で アクセストークンを取得する
  • DNS API で ドメインID を取得する
  • DNS API で レコードID を取得する
  • DNS API で レコード更新 を行う

だけ。自分が管理している ドメインを example.net、更新したい レコードを target.example.net として、ずらずらとかいたスクリプトを残しておきます。

# update_conoha_dns_record.py
# -*- coding: utf-8 -*-
import json
import requests

USERNAME = "<APIユーザーのユーザー名>"
PASSWORD = "<APIユーザのパスワード>"
TENANT_ID = "<API情報に記載されているテナントID>"
TARGET_DOMAIN = "exmaple.net."   一番後ろの . を忘れずに
TARGET_RECORD = "target.example.net."  一番後ろの . を忘れずに

# Get my global IP
url = "http://ipaddr.cf/ip"
r = requests.get(url)
if r.status_code != requests.codes.ok:
    raise Exception("request failed {}".format(r.url))
my_ip = r.text

# Get access_token
url = "https://identity.tyo1.conoha.io/v2.0/tokens"
payload = {
    "auth": {
        "passwordCredentials": {
            "username": USERNAME,
            "password": PASSWORD,
        },
        "tenantId": TENANT_ID
    }
}
headers = {
    "Accept": "application/json"
}
r = requests.post(url, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
    raise Exception("request failed {}".format(r.url))
resp = r.json()
token_id = resp["access"]["token"]["id"]

# Get domain id
url = "https://dns-service.tyo1.conoha.io/v1/domains"
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "X-Auth-Token": token_id,
}
r = requests.get(url, headers=headers)
if r.status_code != requests.codes.ok:
    raise Exception("request failed {}".format(r.url))
resp = r.json()
domain_id = None
for domain in resp["domains"]:
    if domain["name"] == TARGET_DOMAIN:
        domain_id = domain["id"]
        break
else:
    raise Exception("{} is not found".format(TARGET_DOMAIN))

# Get record id
url = "https://dns-service.tyo1.conoha.io/v1/domains/{domain_id}/records".format(domain_id=domain_id)
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "X-Auth-Token": token_id,
}
r = requests.get(url, headers=headers)
if r.status_code != requests.codes.ok:
    raise Exception("request failed {}".format(r.url))
resp = r.json()
record_id = None
for record in resp["records"]:
    if record["name"] == TARGET_RECORD and record["type"] == "A":
        record_id = record["id"]
        break
else:
    raise Exception("{} is not found".format(TARGET_RECORD))

# Update record
url = "https://dns-service.tyo1.conoha.io/v1/domains/{domain_id}/records/{record_id}".format(domain_id=domain_id, record_id=record_id)
payload ={
    "name": TARGET_RECORD,
    "type": "A",
    "data": my_ip,
}
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "X-Auth-Token": token_id
}
r = requests.put(url, data=json.dumps(payload), headers=headers)
if r.status_code != requests.codes.ok:
    raise Exception("request failed {}".format(r.url))

requests パッケージを入れて

$ sudo apt-get install python3-requests
$ python update_conoha_dns_record.py