curl -fsSL 'https://file.surtr.nl/opscript/bunny.sh' -o bunny.sh && chmod +x bunny.sh && sudo ./bunny.sh
#!/usr/bin/env python3
import requests
import sys
# === 全局配置 ===
API_KEY = None
BASE_URL = "https://api.bunny.net"
def api_request(method, endpoint, data=None):
url = f"{BASE_URL}{endpoint}"
headers = {"AccessKey": API_KEY, "Content-Type": "application/json"}
response = requests.request(method, url, headers=headers, json=data)
if response.status_code >= 400:
print(f"\n❌ 请求失败 {response.status_code}: {response.text}\n")
return None
if response.text:
return response.json()
return None
# =====================
# 区域管理
# =====================
def list_zones():
zones = api_request("GET", "/dnszone")
if not zones:
return
print("\n=== DNS 区域列表 ===")
for zone in zones["Items"]:
print(f"- {zone['Domain']} (ID: {zone['Id']})")
print()
return zones
def add_zone():
domain = input("请输入要添加的域名 (例如 example.com): ").strip()
ttl = input("请输入默认 TTL (秒, 默认 300): ").strip()
ttl = int(ttl) if ttl.isdigit() else 300
data = {
"Domain": domain,
"Ttl": ttl
}
zone = api_request("POST", "/dnszone", data)
if zone:
print(f"\n✅ 已添加区域: {zone['Domain']} (ID: {zone['Id']})\n")
def delete_zone():
zone_id = input("请输入要删除的 Zone ID: ").strip()
confirm = input(f"确认删除 Zone {zone_id}? (y/n): ").lower()
if confirm == "y":
api_request("DELETE", f"/dnszone/{zone_id}")
print(f"\n✅ 已删除 Zone {zone_id}\n")
else:
print("❌ 操作已取消\n")
# =====================
# 记录管理
# =====================
def list_records(zone_id):
records = api_request("GET", f"/dnszone/{zone_id}/records")
if not records:
return
print(f"\n=== 区域 {zone_id} 的记录 ===")
for r in records["Items"]:
print(f"- {r['Type']} {r['Name']} -> {r['Value']} (ID: {r['Id']})")
print()
def add_record(zone_id):
print("""
请选择记录类型:
1. A
2. AAAA
3. CNAME
4. MX
5. TXT
6. NS
7. Redirect
8. 其他
""")
type_map = {
"1": 1, # A
"2": 28, # AAAA
"3": 5, # CNAME
"4": 15, # MX
"5": 16, # TXT
"6": 2, # NS
"7": 301, # Redirect (假设 Bunny 使用 301 类型)
}
choice = input("请选择类型: ").strip()
record_type = type_map.get(choice, None)
if not record_type:
try:
record_type = int(input("请输入记录类型代码 (数字): ").strip())
except ValueError:
print("❌ 类型无效")
return
name = input("请输入记录名 (例如 www 或 @): ").strip()
value = input("请输入记录值 (IP / 域名 / 文本等): ").strip()
ttl = input("请输入 TTL (秒, 默认 300): ").strip()
ttl = int(ttl) if ttl.isdigit() else 300
priority = None
if record_type == 15: # MX
priority = input("请输入优先级 (默认 10): ").strip()
priority = int(priority) if priority.isdigit() else 10
data = {
"Type": record_type,
"Name": name,
"Value": value,
"Ttl": ttl
}
if priority is not None:
data["Priority"] = priority
rec = api_request("POST", f"/dnszone/{zone_id}/records", data)
if rec:
print(f"\n✅ 已添加记录: {rec['Type']} {rec['Name']} -> {rec['Value']}\n")
def update_record(zone_id):
record_id = input("请输入要更新的记录ID: ").strip()
value = input("请输入新的记录值: ").strip()
ttl = input("请输入 TTL (秒, 默认 300): ").strip()
ttl = int(ttl) if ttl.isdigit() else 300
data = {"Value": value, "Ttl": ttl}
rec = api_request("POST", f"/dnszone/{zone_id}/records/{record_id}", data)
if rec:
print(f"\n✅ 已更新记录: {rec['Name']} -> {rec['Value']}\n")
def delete_record(zone_id):
record_id = input("请输入要删除的记录ID: ").strip()
confirm = input(f"确认删除记录 ID {record_id}? (y/n): ").lower()
if confirm == "y":
api_request("DELETE", f"/dnszone/{zone_id}/records/{record_id}")
print(f"\n✅ 已删除记录 ID {record_id}\n")
else:
print("❌ 操作已取消\n")
# =====================
# 菜单
# =====================
def menu():
while True:
print("""
=== Bunny DNS 管理菜单 ===
1. 查看 DNS 区域
2. 添加 DNS 区域
3. 删除 DNS 区域
4. 查看记录
5. 添加记录
6. 更新记录
7. 删除记录
0. 退出
""")
choice = input("请选择操作: ").strip()
if choice == "1":
list_zones()
elif choice == "2":
add_zone()
elif choice == "3":
delete_zone()
elif choice == "4":
zone_id = input("请输入 Zone ID: ").strip()
list_records(zone_id)
elif choice == "5":
zone_id = input("请输入 Zone ID: ").strip()
add_record(zone_id)
elif choice == "6":
zone_id = input("请输入 Zone ID: ").strip()
update_record(zone_id)
elif choice == "7":
zone_id = input("请输入 Zone ID: ").strip()
delete_record(zone_id)
elif choice == "0":
print("退出程序。")
sys.exit(0)
else:
print("❌ 无效输入,请重新选择。")
if __name__ == "__main__":
global API_KEY
API_KEY = input("请输入 Bunny API Key: ").strip()
if not API_KEY:
print("❌ 必须提供 API Key 才能使用。")
sys.exit(1)
menu()
功能
-
添加 DNS 区域:输入域名 + TTL 即可(API 会创建 Zone)
-
菜单更新:
1. 查看 DNS 区域 2. 添加 DNS 区域 3. 删除 DNS 区域 4. 查看记录 5. 添加记录 6. 更新记录 7. 删除记录 0. 退出
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
