Cloudflare Dynamic DNS のセットアップ方法

あなたが自宅のネットワークからウェブサイトを公開し、ルーターのパブリックIPアドレスを指すDNSレコードを作成した場合、パブリックIPアドレスが変更されたときにDNSレコードを更新する方法はありますか?おそらく、Cloudflareの動的DNSを設定することを検討すべきです。

インターネットサービスプロバイダ(ISP)は通常、サブスクライバに動的IPアドレスを割り当てますが、これはいつでも変更される可能性があります。その結果、DNSレコードはもはやあなたのIPアドレスを指しておらず、ウェブサイトがアクセスできなくなります。

このチュートリアルでは、Cloudflareのアプリケーションプログラミングインターフェース(API)とPowerShellを使用してDNSレコードを更新する方法について説明します。さあ、始めましょう!

前提条件

このチュートリアルを実践する予定の場合、以下は必要な要件です。

  • A computer with PowerShell 7.1 where you’ll run the Cloudflare dynamic DNS update script. This tutorial will use a Windows 10 computer.
  • A script editor of your choice. This tutorial will use Visual Studio Code v1.59.1 (recommended).
  • A domain that you already own. The example domain in this tutorial is lazyexchangeadmin.cyou.

無料のトップレベルドメイン(TLD)(.ml、.ga、.tk、.cf、および.gqなど)はCloudflareの動的DNS自動化には適用されず、このチュートリアルでは機能しません。

Sample DNS A record in Cloudflare

Cloudflare Dynamic DNSとは何ですか?

DNSレコードは本質的に静的であり、動的IPアドレスとの互換性がありません。この問題を解決するために、動的DNSを設定する必要があります。

幸いなことに、CloudflareはDNSレコードをプログラムで管理できるAPIを提供しています。Cloudflareの動的DNSを設定するには、ネットワーク内のクライアントでプロセスを実行する必要があります。このプロセスは、ネットワークの現在の公開IPアドレスを取得し、対応するDNSレコードを自動的に更新します。

以下は、CloudflareのダイナミックDNS更新フローがどのように行われるかの高レベルダイアグラムを示しています。

Cloudflare Dynamic DNS update flow

多くのダイナミックDNSクライアントが利用可能で、ほとんどはLinuxシステム向けに提供されています。たとえば、UbuntuサーバーやRaspberry PIなどです。有料または無料のサードパーティのダイナミックDNSサービスも存在します。しかし、このチュートリアルでは、PowerShell 7.1で実行されるDNS更新スクリプトを展開します。

Cloudflare APIトークンの取得

CloudflareのダイナミックDNSレコードをプログラムで更新する際、スクリプトはCloudflare APIに自分自身を認証する必要があります。その後、Cloudflareはアカウント内のDNSレコードを変更することを許可します。

Cloudflareは、その目的に十分な権限を持つAPIトークンを作成することを許可しています。そのために、Cloudflareアカウントのユーザー名とその結果として得られたAPIトークンを使用して、Cloudflare APIに認証することができます。

Cloudflare APIトークンを作成するには、次の手順に従ってください。

1. ブラウザを開き、https://dash.cloudflare.com/login/に移動し、Cloudflareアカウントにログインします。

2. Cloudflareダッシュボードにログインした後、右上隅にあるプロファイルボタンをクリックし、マイプロファイルをクリックします。

Opening your Cloudflare profile page

3. 次に、APIトークンタブリンクをクリックします。APIトークンセクションの下にあるトークンを作成ボタンをクリックします。以下の例では、まだAPIトークンを作成していないことを前提としています。

Clicking Create Token

4. APIトークンテンプレートのリストで、ゾーンDNSを編集テンプレートをクリックして使用します。このテンプレートを使用すると、アカウント内のすべてまたは選択したDNSゾーンに編集権限を持つAPIトークンを作成できます。

Selecting the Edit zone DNS API token template

5. トークンを作成ページのゾーンリソースセクションで、右端のドロップダウンボックスをクリックして、このAPIトークンのアクセスに含めるDNSゾーンを選択します。DNSゾーンを選択した後は、概要に進むをクリックしてください。

オプションで、APIトークンの有効期間を制限するには、開始日終了日TTLセクションに入力します。空白のままにしておくと、APIトークンに有効期限はありません。

Selecting the DNS Zone

6. 概要を確認し、APIが以前に選択したDNSゾーンにDNS:編集権限を持っていることを確認してください。最後に、APIトークンを作成するためにトークンを作成をクリックしてください。

Reviewing the API token permission

7. APIトークンを作成した後、トークンの値をコピーし、安全に保存してください。APIトークンをパスワードと同様に扱ってください。

Copying the API Token

8. APIトークンタブに戻り、作成したAPIトークンの存在を確認してください。

Verifying the API Token

CloudflareダイナミックDNS更新スクリプトのセットアップ

これで、CloudflareアカウントとDNSゾーンを編集するためのCloudflare APIトークンがあります。次は何ですか?APIトークンを使用して、CloudflareのダイナミックDNSレコードをプログラムで更新するスクリプトと統合する必要があります。

このチュートリアルでは、CloudflareでDNSレコードを更新するための動作するPowerShellスクリプトを提供します。

スクリプトの保存

以下の手順に従って、CloudflareのダイナミックDNS PowerShellスクリプトをクライアントコンピューターに保存します。

1. スクリプトを保存するフォルダーを決定し、まだ存在しない場合はそのフォルダーを作成します。この例では、スクリプトの場所はC:\CloudflareDDNSになります。

2. VSCodeなどのコードエディターを開き、Update-CloudflareDDNS.ps1という新しいPowerShellスクリプトファイルを作成します。スクリプトをC:\CloudflareDDNSフォルダー内に保存します。

3. 以下のスクリプトをコピーし、コードエディターに貼り付けてファイルを保存します。スクリプトが何を行うかを理解するために、インラインコメントを参照してください。

#要件 -バージョン7.1

[cmdletbinding()]
param (
    [parameter(Mandatory)]
    $Email,
    [parameter(Mandatory)]
    $Token,
    [parameter(Mandatory)]
    $Domain,
    [parameter(Mandatory)]
    $Record
)

# スクリプト全体で使用されるリクエストヘッダーを構築します。
$headers = @{
    "X-Auth-Email"  = $($Email)
    "Authorization" = "Bearer $($Token)"
    "Content-Type"  = "application/json"
}

#領域 トークンテスト
## このブロックは、APIキーが有効であることを検証します。
## そうでない場合、スクリプトは終了します。

$uri = "https://api.cloudflare.com/client/v4/user/tokens/verify"

$auth_result = Invoke-RestMethod -Method GET -Uri $uri -Headers $headers -SkipHttpErrorCheck
if (-not($auth_result.result)) {
    Write-Output "API token validation failed. Error: $($auth_result.errors.message). Terminating script."
    # スクリプトを終了する
    return
}
Write-Output "API token validation [$($Token)] success. $($auth_result.messages.message)."
#領域の終了

# ゾーンIDを取得する
## ゾーン名に基づいてドメインのゾーン識別子を取得します。 識別子が見つからない場合、スクリプトは終了します。
$uri = "https://api.cloudflare.com/client/v4/zones?name=$($Domain)"
$DnsZone = Invoke-RestMethod -Method GET -Uri $uri -Headers $headers -SkipHttpErrorCheck
if (-not($DnsZone.result)) {
    Write-Output "Search for the DNS domain [$($Domain)] return zero results. Terminating script."
    # スクリプトを終了する
    return
}
## DNSゾーンIDを保存する
$zone_id = $DnsZone.result.id
Write-Output "Domain zone [$($Domain)]: ID=$($zone_id)"
#領域の終了

# DNSレコードを取得する
## Cloudflareから既存のDNSレコードの詳細を取得します。
$uri = "https://api.cloudflare.com/client/v4/zones/$($zone_id)/dns_records?name=$($Record)"
$DnsRecord = Invoke-RestMethod -Method GET -Uri $uri -Headers $headers -SkipHttpErrorCheck
if (-not($DnsRecord.result)) {
    Write-Output "Search for the DNS record [$($Record)] return zero results. Terminating script."
    # スクリプトを終了する
    return
}
## DNSレコード内の現在のIPアドレスを保存する
$old_ip = $DnsRecord.result.content
## DNSレコードのタイプ値を保存する
$record_type = $DnsRecord.result.type
## DNSレコードのID値を保存する
$record_id = $DnsRecord.result.id
## DNSレコードのTTL値を保存する
$record_ttl = $DnsRecord.result.ttl
## DNSレコードのプロキシ値を保存する
$record_proxied = $DnsRecord.result.proxied
Write-Output "DNS record [$($Record)]: Type=$($record_type), IP=$($old_ip)"
#領域の終了

# 現在のパブリックIPアドレスを取得する
$new_ip = Invoke-RestMethod -Uri 'https://v4.ident.me'
Write-Output "Public IP Address: OLD=$($old_ip), NEW=$($new_ip)"
#領域の終了

# 動的DNSレコードを更新する
## 現在のIPアドレスをDNSレコードと比較する
## 現在のIPアドレスがDNSレコードのIPアドレスと一致しない場合、DNSレコードを更新します。
if ($new_ip -ne $old_ip) {
    Write-Output "The current IP address does not match the DNS record IP address. Attempt to update."
    ## 新しいIPアドレスでDNSレコードを更新する
    $uri = "https://api.cloudflare.com/client/v4/zones/$($zone_id)/dns_records/$($record_id)"
    $body = @{
        type    = $record_type
        name    = $Record
        content = $new_ip
        ttl     = $record_ttl
        proxied = $record_proxied
    } | ConvertTo-Json

    $Update = Invoke-RestMethod -Method PUT -Uri $uri -Headers $headers -SkipHttpErrorCheck -Body $body
    if (($Update.errors)) {
        Write-Output "DNS record update failed. Error: $($Update[0].errors.message)"
        ## スクリプトを終了する
        return
    }

    Write-Output "DNS record update successful."
    return ($Update.result)
}
else {
    Write-Output "The current IP address and DNS record IP address are the same. There's no need to update."
}
#領域の終了

スクリプトを実行します

CloudflareのダイナミックDNS更新スクリプトを保存したら、次は何ですか? スクリプトを展開する前に、その機能が動作するかどうかをテストすることが重要です。 スクリプトを実行するには、成功するために次の4つの詳細が必要です。

  • メール – これはCloudflareアカウントのメールアドレスです。
  • トークン – これは以前にCloudflareアカウントから作成したAPIトークンです。
  • ドメイン – これは更新したいDNSレコードを含むDNSドメイン名です(例:lazyexchangeadmin.cyou)。
  • レコード – これは更新したいDNSレコードです(例:demo.lazyexchangeadmin.cyou)。

スクリプトを実行するには、次の手順に従ってください。

1. 最初に、PowerShellセッションを開きます。または、VSCodeを使用している場合は、VSCode PowerShellターミナルを使用します。

2. 次に、現在のDNSレコードのIPアドレスを確認するためにDNSレコードのルックアップを実行します。 これには、以下に示すようにResolve-DnsNameコマンドレットを実行します。 -Nameパラメータとともに完全修飾ドメイン名(FQDN)を指定してください。

Resolve-DnsName -Name demo.lazyexchangeadmin.cyou

コマンドは、IPアドレスを含む検索したDNSレコードを返すはずです。

Looking up a DNS record before the Cloudflare dynamic DNS update

3. 今、以下のコマンドを実行して、Update-CloudflareDDNS.ps1 スクリプトを呼び出して、Cloudflare の DNS レコードを更新してください。スクリプトがC:\CloudflareDDNS\Update-CloudflareDDNS.ps1にあることを確認してください。

C:\CloudflareDDNS\Update-CloudflareDDNS.ps1 `
-Email '[email protected]' `
-Token 'kGW8n........eJl5a' `
-Domain 'lazyexchangeadmin.cyou' `
-Record 'demo.lazyexchangeadmin.cyou'

次に、スクリプトは以下のアクションを実行します。スクリーンショットで確認できます。

  1. API トークンを検証します。
  2. 更新する DNS レコードを含むドメインを見つけます。
  3. 更新する DNS レコードを見つけます。
  4. DNS レコードの IP アドレスを実際の外部または公開 IP アドレスと比較します。
  5. Cloudflare で DNS レコードの IP アドレスを更新します。
  6. ダイナミック DNS 更新の結果を表示します。
Running the Cloudflare dynamic DNS update script

4. Cloudflare ダッシュボードに戻り、DNS レコードが新しい IP アドレスを反映しているか確認してください。スクリーンショットには、更新スクリプトを実行した後に IP アドレスが外部 IP アドレス値に変更されたことが示されています。

Verifying the DNS record in Cloudflare

5. 最後に、ステップ 2 で行ったように別の DNS レコードのルックアップを実行して、新しい IP アドレスが既に公開されているか確認してください。

Resolve-DnsName -Name demo.lazyexchangeadmin.cyou

DNS レコードの伝播には数分、数時間、または数日かかる場合があります。この例では、Cloudflare の伝播は 1 分未満でした。

Looking up a DNS record after the Cloudflare dynamic DNS update

Cloudflare ダイナミック DNS 更新タスクのスケジューリング

現時点では、Cloudflare ダイナミック DNS レコードを更新する動作するスクリプトがありますが、毎回手動で実行することは目的ではありません。必要に応じてダイナミック DNS 更新が自動的にスケジュールされることを確認する必要があります。

使用しているオペレーティング システムに応じて、スクリプトを実行する方法は異なります。Linux の場合は cron ジョブなどです。このチュートリアルでは、Cloudflare ダイナミック DNS 更新スクリプトを5分ごとに実行する Windows スケジュール タスクを作成します。

スケジュール タスクのアクションの定義

スケジュールされたタスクにはアクションが必要であり、これは New-ScheduledTaskAction コマンドレットを実行して作成できます。この例では、アクションは PowerShell の実行可能ファイル pwsh.exe を使用して Update-CloudflareDDNS.ps1 スクリプトを実行することです。

これを行うには、新しい 管理者としての PowerShell ウィンドウを開きます。次に、PowerShell で以下のコードをコピーして実行します。 $scriptPath$Email,$Token$Domain、および $Record 変数を変更してください。

予定されたタスクのアクションプロパティを定義します
## PowerShellスクリプトのパスを入力します
$scriptPath = 'C:\CloudflareDDNS\Update-CloudflareDDNS.ps1'
## Cloudflareアカウントのメールアドレス
$Email = '[email protected]'
## Cloudflare APIトークン
$Token = 'kGW8n........eJl5a'
## DNSドメイン名
$Domain = 'lazyexchangeadmin.cyou'
## 更新するDNSレコード
$Record = 'demo.lazyexchangeadmin.cyou'

# 予定されたタスクアクションオブジェクトを作成します
$taskAction = New-ScheduledTaskAction `
    -Execute "pwsh.exe" `
    -Argument "-File $scriptPath -Email $Email -Token $Token -Domain $Domain -Record $Record"

予定されたタスクトリガーの作成

タスクが何を行うかを定義した後、次にタスクのトリガーまたはスケジュールを作成する必要があります。 New-ScheduledTaskTrigger cmdletを実行して、新しいタスクトリガーを作成します。以下のコードをコピーしてPowerShellで実行し、10年間で5分ごとに実行される新しいタスクトリガーを作成します。

# 新しい予定されたタスクトリガースケジュールを作成します
## トリガー = 10年ごとの5分ごと
$taskTrigger = New-ScheduledTaskTrigger `
-Once `
-At (Get-Date -Minute 0 -Second 0) `
-RepetitionInterval (New-TimeSpan -Minutes 5) `
-RepetitionDuration (New-TimeSpan -Days 3650)

システムに新しい予定されたタスクを登録

最終的に、新しいスケジュールされたタスクをコンピュータに登録する準備が整いました。これを行うためには、以下のコードと同じくRegister-ScheduledTaskコマンドレットを実行する必要があります。以下のコードをコピーしてPowerShellで実行し、スケジュールされたタスクを登録してください。

その結果として生成されるスケジュールされたタスクは、ローカルSYSTEMアカウントで実行されます。必要に応じて、スケジュールされたタスクを実行する異なるユーザーアカウントを割り当てることができます。

# システムでスケジュールされたタスクを登録します。
## スケジュールされたタスクの名前
$TaskName = 'Update Cloudflare Dynamic DNS'
## スケジュールされたタスクの説明
$Description = 'Update Cloudflare DDNS Entry every 5 minutes'
## スケジュールされたタスクの作成
Register-ScheduledTask `
-TaskName $TaskName `
-Description $Description `
-Action $taskAction `
-Trigger $taskTrigger `
-User 'NT AUTHORITY\SYSTEM'

以下のようにコマンドがスケジュールされたタスクを作成し、ステータスは準備完了です。この時点からスクリプトは5分間隔で実行されます。

Registering the New Scheduled Task

結論

DNSレコードを更新する際に、動的IPアドレスの変更を追跡する必要はありません。動的DNSサービスの利用料を支払う必要もありません!CloudflareでDNSゾーンを管理することで、彼らのAPIを活用してDNSレコードをプログラムで更新することができます。

このチュートリアルでは、APIコール、PowerShell 7、およびスケジュールされたタスクの組み合わせを使用して、Cloudflareの動的DNSレコードを更新する方法を学びました。これにより、Cloudflareの動的DNS更新メカニズムを一度設定し、定期的に更新を実行することができます。

CloudflareでDNSゾーンを管理して、そのAPIの恩恵を受けることを考慮していただけますか?それとも、より便利でアクセスしやすい方法があると思いますか?

Source:
https://adamtheautomator.com/cloudflare-dynamic-dns/