VPNサーバのパブリックIPをDNSに登録する 〜Raspberry Pi上で定期実行〜

弊社オフィスではVPN環境を構築していますが、固定IPを取得していないため、パブリックIPが変わるたびにVPNの接続先を変更しなければならず面倒です。

そこで、定期的にIPアドレスを取得し、DNSに登録するようにしています。
ここでは、Raspberry Pi 上でAWS SDK for Python (Boto 3) を用いて定期実行させる手順をまとめます。

AWS SDK for Python のインストールおよび設定

DNSはAWSのRoute53で管理しており、その操作のためにSDKを導入します。
なお、Raspberry PiにはPython (2.7系) がデフォルトでインストールされているため、そのまま用います。

$ sudo pip install boto3

続いて、Credentialを設定します。YOUR_KEYおよびYOUR_SECRETは環境に合わせて設定してください。
(Route53へのアクセス権限があれば問題ありません)

$ vi ~/.aws/credentials
[default]
aws_access_key_id = YOUR_KEY
aws_secret_access_key = YOUR_SECRET

DNS更新

DNS更新にはchange_resource_record_setsメソッドを使用します。
詳細は、公式ドキュメント を参照してください。

パブリックIPの取得

パブリックIPは、httpbin.org にアクセスして取得します。
レスポンスとしては以下のようなものが返ってきます。

$ curl http://httpbin.org/ip
{
    "origin": "xxx.xxx.xxx.xxx"
}

スクリプト

以上を踏まえて、スクリプトを書いていきます。
DOMAINおよびHOSTは環境に合わせて書き換えてください。下記ではhoge.example.comを登録する例としています。

# -*- coding: utf-8 -*-

import json
import urllib2

import boto3

DOMAIN = 'hoge'
HOST = 'example.com'
TTL = 300

# パブリックIPアドレスの取得
response = urllib2.urlopen('http://httpbin.org/ip')
ip_address = json.loads(response.read())['origin']

# AWS SDK Client
client = boto3.client('route53')

# hosted_zone_idの取得
hosted_zones = client.list_hosted_zones()['HostedZones']
hosted_zone_id = filter(lambda h: h['Name'] == HOST + '.', hosted_zones)[0]['Id']

# 更新内容
change_batch = {
    'Changes': [
        {
            'Action': 'UPSERT',
            'ResourceRecordSet': {
                'Name': DOMAIN + '.' + HOST + '.',
                'Type': 'A',
                'TTL': TTL,
                'ResourceRecords': [
                    {'Value': ip_address}
                ]
            }
        }
    ]
}

# 更新
client.change_resource_record_sets(
    HostedZoneId = hosted_zone_id,
    ChangeBatch = change_batch
)

あとは、上記のスクリプトをcronに登録するなどして、定期実行させれば完了です。

著者紹介
阪神タイガースと天下一品が好きなエンジニア。