モグラ先生:こんにちは!今日は、Cloudflare DDNS を最新の方法でラクに運用するトンネルを掘るよ。昔ながらの「グローバルAPIキー方式」はもう古い!今はAPIトークンとsystemd timerでスマート管理する時代だね✨
はじめに|Cloudflare DDNSを最新仕様で運用しよう
今まで「グローバルAPIキー+cron」で更新していた人、多いですよね?
でもそれ、もう時代遅れかも知れません。
- Cloudflare公式推奨は最小権限の「APIトークン」!
- Linux界隈ではcronよりsystemd timerが推され中!
- PythonもPEP 668対応が必要になってきました!
モグラ先生:つまり、「今風」に掘り直すと運用が安全・快適になるってことだね🐾
CloudflareでAPIトークンを作成しよう 🔑
必須キーワード:「Edit zone DNS」のトークン
- Cloudflareダッシュボードへログイン
- My Profile → API Tokens → Create Token
- テンプレートから「Edit zone DNS」を選ぶ
- 対象ゾーン(ドメイン)を限定して発行!
モグラ先生:昔のグローバルAPIキーは、落としたら全権喪失。怖いよね💦トークンなら安心!
Zone IDとRecord IDをAPIでゲットする🧭
bashスクリプト例:
CF_API="https://api.cloudflare.com/client/v4"
TOKEN="YOUR_BEARER"
DOMAIN="example.com"
FQDN="home.example.com"
ZONE_ID=$(curl -s -H "Authorization: Bearer $TOKEN" "$CF_API/zones?name=$DOMAIN" | jq -r '.result[0].id')
REC_ID=$(curl -s -H "Authorization: Bearer $TOKEN" "$CF_API/zones/$ZONE_ID/dns_records?type=A&name=$FQDN" | jq -r '.result[0].id')
モグラ先生:「手動で探す」とかもう卒業しよう。API叩いてサクッと掘り出そう!⛏️
PythonスクリプトでDNSを更新しよう 🐍
Pythonコード例:(update_dns.py)
import os
import requests
import re
from datetime import datetime
import configparser
# 現在のスクリプトのディレクトリを取得
current_directory = os.path.dirname(os.path.abspath(__file__))
# 設定ファイルを読み込む
config = configparser.ConfigParser()
config_file = os.path.join(current_directory, 'config.ini')
config.read(config_file)
# 設定値の取得
MY_DOMAIN = config['DEFAULT']['MY_DOMAIN']
ZONE_ID = config['DEFAULT']['ZONE_ID']
RECORD_ID = config['DEFAULT']['RECORD_ID']
AUTH_EMAIL = config['DEFAULT']['AUTH_EMAIL']
API_TOKEN = config['DEFAULT']['API_TOKEN']
# IPアドレス取得サービスのリスト
services = [
"https://api.ipify.org/",
"https://checkip.amazonaws.com/",
"https://ipv4.icanhazip.com/",
"https://4.icanhazip.com/"
]
def get_ip_address(url):
"""
指定されたURLからIPアドレスを取得します。
"""
try:
response = requests.get(url)
response.raise_for_status()
return response.text.strip()
except requests.RequestException:
return None
def is_valid_ip(ip_address):
"""
IPアドレスが正しい形式かどうかをチェックします。
"""
pattern = r"^([0-9]{1,3}\.){3}[0-9]{1,3}$"
return re.match(pattern, ip_address) is not None
# IPアドレスを取得するループ
ip_address = None
for service in services:
ip_address = get_ip_address(service)
if ip_address and is_valid_ip(ip_address):
break
if ip_address is None:
raise Exception("有効なIPアドレスを取得できませんでした。")
# 今日の日付を取得
current_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# CloudFlare APIによるAレコードの更新
update_url = f"https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/dns_records/{RECORD_ID}"
headers = {
'Content-Type': 'application/json',
'X-Auth-Email': AUTH_EMAIL,
'Authorization': f'Bearer {API_TOKEN}'
}
data = {
"content": ip_address,
"name": MY_DOMAIN,
"proxied": False,
"type": "A",
"comment": f"DDNS record updated on {current_datetime}"
}
response = requests.put(update_url, headers=headers, json=data)
response.raise_for_status() # エラーが発生した場合、例外を発生させます
print("IPアドレスが更新されました。")
print('response',response)
設定ファイルの例:(config.ini)
[DEFAULT]
MY_DOMAIN=XXXXX
ZONE_ID=YYYYY
RECORD_ID=ZZZZZ
[email protected]
API_TOKEN=AABBCCDD
5️⃣ Python仮想環境(venv)で安全に運用 🐚
python3 -m venv ~/cf-ddns
~/cf-ddns/bin/pip install requests
PEP 668対応で、グローバルpip汚染を防ぎましょう。
モグラ先生:今どき
sudo pip install
は時限爆弾だから絶対やめようね💣
6️⃣ systemd-timerで自動更新!⏰
.serviceファイル
[Unit]
Description=Update Cloudflare DDNS
After=network-online.target
[Service]
Type=oneshot
ExecStart=/home/pi/cf-ddns/bin/python /home/pi/update_ddns.py
.timerファイル
[Unit]
Description=Run Cloudflare DDNS every 5min
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
AccuracySec=30s
Persistent=true
Unit=cf-ddns.service
[Install]
WantedBy=timers.target
ポイント!
Persistent=true
にすると、シャットダウン中の実行漏れもリカバー!systemctl list-timers
で次回予定も確認できる!
sudo systemctl daemon-reload
sudo systemctl enable --now cf-ddns.timer
systemctl list-timers | grep cf-ddns
モグラ先生:「cronと違って、再起動後も自動で走る」のがsystemd-timer最大のメリットだよ!
7️⃣ 代替案:ddclient 3.11以上を使う手もある🚏
もし「Pythonスクリプトめんどい!」なら、ddclientでもいけます。
以下でインストール。初期設定ウィザードは適当でOK。
apt install ddclient
ddclient設定例:
#================= 一般設定 =================
daemon=300
syslog=yes
pid=/var/run/ddclient.pid
ssl=yes
#================= IP 取得設定 ==============
usev4=webv4, webv4=ipify-ipv4
usev6=webv6, webv6=ident-me-ipv6
#================= Cloudflare 本体 ==========
protocol=cloudflare, \
zone=hoge.com, \
ttl=1, \
login=token, \
password=<API_TOKEN> \
XXX.hoge.com
- loginには「token」と明示!
- passwordにAPIトークン直書き!
【まとめ】Cloudflare DDNSを最新運用にアップグレードしよう⛏️✨
- APIトークン+systemd-timerで安全・スマートなDDNS運用が可能!
- グローバルAPIキーやcronは卒業して、今風のやり方へ!
- Python仮想環境(venv)運用で依存管理もバッチリ!
これでCloudflare DDNS運用は一段とラクに!
次回はこの仕組みをDocker化してさらに掘り進める予定だよ〜🐾
モグラ先生:最後まで読んでくれてありがと〜!他の記事もぜひ掘りに来てね🪹✨