Cloudflareでドメイン取った
Cloudflareでドメインを取りました。 苦い経験をしたのでお◯前では二度と取りません。
Freeプランだとネームサーバーの変更ができないので、頑張ったログです。
ロリポップのIPを知る
に
ロリポップ!のドメインを検索にかけます。
赤枠のとこがIPです。
CloudflareにDNSをせってい
タイプ : A
名前 : @
IPv4アドレス : さっき確認したIP
プロキシステータス : 無効
で保存。
あとサブドメインを含めたいなら
名前を*にすればワイルドカードで設定できる。
(画像では誤ってプロキシをonにしてます。)
暗号化モードの変更
SSL/TLS▶概要▶SSL/TLS暗号化▶設定をクリック。
自動をオフにしてフルに変更します。
これで証明書云々で不具合が起きにくくなります。
ロリポップ!にドメインを追加
さっきのドメインをロリポップに追加しましょう。
アクセスして
のようなページが出れば正常です。
自動更新スクリプト
Claudeに依頼して次のようなスクリプトを作成させました。
メンテナンスなどでIPが変わっても大丈夫なように作成。
import os
import sys
import socket
import requests
import json
from typing import Optional, Dict, Any, List
from pathlib import Path
from dotenv import load_dotenv
# .envファイルをロード
dotenv_path = Path('.env')
if dotenv_path.exists():
load_dotenv(dotenv_path)
else:
print("[INFO] .envファイルが見つかりません。環境変数を使用します。")
# Cloudflare API情報
API_TOKEN = os.environ.get('CF_API_TOKEN')
ZONE_ID = os.environ.get('CF_ZONE_ID')
API_BASE_URL = 'https://api.cloudflare.com/client/v4'
# 設定情報
SOURCE_DOMAIN = os.environ.get('SOURCE_DOMAIN')
# カンマ区切りの文字列をリストに変換
TARGET_DOMAINS_STR = os.environ.get('TARGET_DOMAINS')
TARGET_DOMAINS = [domain.strip() for domain in TARGET_DOMAINS_STR.split(',')]
def get_ip_for_domain(domain: str) -> Optional[str]:
"""
指定されたドメインのIPアドレスを取得します
"""
try:
ip_address = socket.gethostbyname(domain)
print(f"[INFO] ドメイン {domain} のIPアドレスは {ip_address} です")
return ip_address
except socket.gaierror as e:
print(f"[ERROR] ドメイン {domain} のIPアドレス解決に失敗しました: {e}")
return None
def get_dns_record(zone_id: str, name: str) -> Optional[Dict[str, Any]]:
"""
Cloudflareから指定された名前のDNSレコードを取得します
"""
headers = {
'Authorization': f'Bearer {API_TOKEN}',
'Content-Type': 'application/json'
}
url = f"{API_BASE_URL}/zones/{zone_id}/dns_records"
params = {'name': name}
try:
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
data = response.json()
if data['success'] and len(data['result']) > 0:
return data['result'][0]
else:
print(f"[INFO] DNSレコード {name} は見つかりませんでした。新規作成します。")
return None
except requests.exceptions.RequestException as e:
print(f"[ERROR] DNSレコードの取得に失敗しました: {e}")
return None
def update_dns_record(zone_id: str, record_id: str, name: str, ip_address: str) -> bool:
"""
既存のDNSレコードを更新します
"""
headers = {
'Authorization': f'Bearer {API_TOKEN}',
'Content-Type': 'application/json'
}
url = f"{API_BASE_URL}/zones/{zone_id}/dns_records/{record_id}"
data = {
'type': 'A',
'name': name,
'content': ip_address,
'ttl': 1, # 自動
'proxied': False
}
try:
response = requests.put(url, headers=headers, json=data)
response.raise_for_status()
result = response.json()
if result['success']:
print(f"[SUCCESS] DNSレコード {name} を {ip_address} に更新しました")
return True
else:
print(f"[ERROR] DNSレコードの更新に失敗しました: {json.dumps(result['errors'])}")
return False
except requests.exceptions.RequestException as e:
print(f"[ERROR] DNSレコードの更新に失敗しました: {e}")
return False
def create_dns_record(zone_id: str, name: str, ip_address: str) -> bool:
"""
新しいDNSレコードを作成します
"""
headers = {
'Authorization': f'Bearer {API_TOKEN}',
'Content-Type': 'application/json'
}
url = f"{API_BASE_URL}/zones/{zone_id}/dns_records"
data = {
'type': 'A',
'name': name,
'content': ip_address,
'ttl': 1, # 自動
'proxied': False
}
try:
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
result = response.json()
if result['success']:
print(f"[SUCCESS] DNSレコード {name} を {ip_address} で作成しました")
return True
else:
print(f"[ERROR] DNSレコードの作成に失敗しました: {json.dumps(result['errors'])}")
return False
except requests.exceptions.RequestException as e:
print(f"[ERROR] DNSレコードの作成に失敗しました: {e}")
return False
def validate_environment():
"""
必要な環境変数が設定されているか確認します
"""
if not API_TOKEN:
print("[ERROR] 環境変数またはenvファイルに CF_API_TOKEN が設定されていません")
return False
if not ZONE_ID:
print("[ERROR] 環境変数またはenvファイルに CF_ZONE_ID が設定されていません")
return False
return True
def update_specific_records(source_domain, target_domains, zone_id):
"""
特定のソースドメインからIPを取得し、ターゲットドメインのDNSレコードを更新します
"""
# ソースドメインのIPアドレスを取得
ip_address = get_ip_for_domain(source_domain)
if not ip_address:
return False
success = True
# 各ターゲットドメインについてDNSレコードを更新
for target_domain in target_domains:
# 既存のDNSレコードを取得
record = get_dns_record(zone_id, target_domain)
if record:
# 既存のレコードがある場合は更新
if record['content'] == ip_address:
print(f"[INFO] DNSレコード {target_domain} は既に {ip_address} に設定されています。更新は不要です。")
continue
record_success = update_dns_record(zone_id, record['id'], target_domain, ip_address)
else:
# レコードがない場合は新規作成
record_success = create_dns_record(zone_id, target_domain, ip_address)
if not record_success:
success = False
return success
def main():
"""
メイン関数
"""
if not validate_environment():
sys.exit(1)
# 環境変数から読み込まれた設定値を使用
print(f"[INFO] ソースドメイン: {SOURCE_DOMAIN}")
print(f"[INFO] ターゲットドメイン: {', '.join(TARGET_DOMAINS)}")
# 特定のレコードを更新
success = update_specific_records(SOURCE_DOMAIN, TARGET_DOMAINS, ZONE_ID)
if not success:
print("[ERROR] 少なくとも1つのDNSレコードの更新に失敗しました")
sys.exit(1)
else:
print("[SUCCESS] すべてのDNSレコードの更新が完了しました")
if __name__ == "__main__":
main()
あとは次のような.env
ファイルを.py
ファイルと同じ場所に置く。
# Cloudflare API設定
CF_API_TOKEN=your_api_key
CF_ZONE_ID=your_zone_id
# ドメイン設定
SOURCE_DOMAIN=xxxxxx.lolipop.jp
TARGET_DOMAINS=example.org,*.example.org
これをcronに設定したり繋がらないなって思ったら実行するだけ。
以上
終わりです。最後のスクリプトがあれば便利バッチリです。
一応ロリポップ側でサポートされてないやり方ではあると思うので注意は必要ですけどね.
では。