Bu araç sayesinde onlarca domaininizi tek seferde yönetebilir, DNS kayıtlarınızı toplu olarak ekleyebilir veya güncelleyebilirsiniz.
### Aracın Özellikleri:
1. 🌐 **Domain Yönetimi**:
- Tüm domainlerinizi (zone) listeleme
- Domain nameserver bilgilerini görüntüleme
- Nameserver bilgilerini CSV veya TXT dosyasına aktarma
2. 📝 **DNS Kayıt Yönetimi**:
- Domain için tüm DNS kayıtlarını listeleme
- Tüm domainlere aynı anda root (@) ve www A kaydı ekleme
- Tüm domainlere aynı anda subdomain A kaydı ekleme
- MX kayıtları (mail sunucusu) ekleme
- Özel DNS kayıtları ekleme (A, CNAME, TXT, MX, vb.)
- Tüm A kayıtlarını toplu olarak güncelleme
- DNS kayıtlarını CSV dosyasına aktarma
- CSV dosyasından DNS kayıtlarını içe aktarma
3. 🔒 **Güvenlik Duvarı Kuralları**:
- Toplu IP kısıtlaması ekleme
4. ⚡ **Paralel İşlem Desteği**:
- Çok sayıda domain üzerinde eş zamanlı işlem yapabilme
### Kurulum ve Kullanım:
1. Python 3.x kurulu olmalıdır
2. Gerekli kütüphaneleri yükleyin: `pip install requests`
3. Kodun başındaki Cloudflare API bilgilerinizi güncelleyin
4. Scripti çalıştırın: `python cloudflare_manager.py`
### Güvenlik Notu: Paylaştığım koddaki API anahtarını kendi API anahtarınızla değiştirmeyi unutmayın! Kod açık kaynaklıdır, dilediğiniz gibi geliştirip kullanabilirsiniz. Sorularınız veya önerileriniz için yorum bırakabilirsiniz. İyi kullanımlar!
#!/usr/bin/env python3
import os
import requests
import json
import csv
import sys
import threading
import concurrent.futures
CLOUDFLARE_EMAIL = 'mail_adresiniz'
CLOUDFLARE_API_KEY = 'cloudfare_apikey'
ORIGIN_CA_KEY = 'v1.32443424...' #gereksiz
CF_API_URL = 'https://api.cloudflare.com/client/v4'
headers = {
'X-Auth-Email': CLOUDFLARE_EMAIL,
'X-Auth-Key': CLOUDFLARE_API_KEY,
'Content-Type': 'application/json'
}
def list_zones():
try:
response = requests.get(f'{CF_API_URL}/zones?status=active&per_page=50', headers=headers)
data = response.json()
if not data['success']:
print(f"Hata: {data['errors']}")
return None
print(f"Toplam domain sayısı: {len(data['result'])}")
zones = []
for zone in data['result']:
print(f"Domain: {zone['name']}, ID: {zone['id']}")
zones.append(zone)
return zones
except Exception as e:
print(f"Alan adları listelenirken hata: {e}")
return None
def get_nameservers(zone_id):
try:
response = requests.get(f'{CF_API_URL}/zones/{zone_id}', headers=headers)
data = response.json()
if not data['success']:
print(f"Hata: {data['errors']}")
return None
return data['result']['name_servers']
except Exception as e:
print(f"Nameserver bilgileri alınırken hata: {e}")
return None
def export_nameservers_to_csv(zones, filename="domain_nameservers.csv"):
if not zones:
print("Domain bulunamadı!")
return
nameserver_info = []
def process_zone(zone):
nameservers = get_nameservers(zone['id'])
if nameservers:
return {
'domain': zone['name'],
'nameservers': ', '.join(nameservers)
}
return None
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = executor.map(process_zone, zones)
for result in results:
if result:
nameserver_info.append(result)
try:
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['domain', 'nameservers']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for info in nameserver_info:
writer.writerow(info)
print(f"\nTüm nameserver bilgileri {filename} dosyasına aktarıldı.")
return filename
except Exception as e:
print(f"CSV dosyası oluşturulurken hata: {e}")
return None
def export_nameservers_to_txt(zones, filename="domain_nameservers.txt"):
if not zones:
print("Domain bulunamadı!")
return
try:
with open(filename, 'w', encoding='utf-8') as txtfile:
txtfile.write("Domain Nameserver Bilgileri\n")
txtfile.write("=========================\n\n")
def process_zone(zone):
nameservers = get_nameservers(zone['id'])
result = f"Domain: {zone['name']}\n"
if nameservers:
result += f"Nameservers: {', '.join(nameservers)}\n\n"
else:
result += "Nameserver bilgisi alınamadı!\n\n"
return result
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = executor.map(process_zone, zones)
for result in results:
txtfile.write(result)
print(f"\nTüm nameserver bilgileri {filename} dosyasına aktarıldı.")
return filename
except Exception as e:
print(f"TXT dosyası oluşturulurken hata: {e}")
return None
def get_dns_records(zone_id):
try:
response = requests.get(f'{CF_API_URL}/zones/{zone_id}/dns_records?per_page=100', headers=headers)
data = response.json()
if not data['success']:
print(f"Hata: {data['errors']}")
return None
print(f"Toplam DNS kaydı sayısı: {len(data['result'])}")
for record in data['result']:
print(f"Tür: {record['type']}, Ad: {record['name']}, İçerik: {record['content']}, Proxy: {record['proxied']}")
return data['result']
except Exception as e:
print(f"DNS kayıtları listelenirken hata: {e}")
return None
def create_dns_record(zone_id, record_type, name, content, ttl=1, proxied=True, priority=None):
data = {
'type': record_type,
'name': name,
'content': content,
'ttl': ttl,
'proxied': proxied
}
if record_type == "MX" and priority is not None:
data['priority'] = priority
try:
response = requests.post(
f'{CF_API_URL}/zones/{zone_id}/dns_records',
headers=headers,
json=data
)
result = response.json()
if not result['success']:
print(f"Hata: {result['errors']}")
return None
print(f"DNS kaydı eklendi: {result['result']['name']}")
return result['result']
except Exception as e:
print(f"DNS kaydı oluşturulurken hata: {e}")
return None
def add_root_and_www_a_records(zones, ip_address, proxied=True):
if not zones:
print("Domain bulunamadı!")
return
results = []
def process_zone(zone):
zone_results = []
root_result = create_dns_record(
zone_id=zone['id'],
record_type="A",
name="@",
content=ip_address,
proxied=proxied
)
zone_results.append({
'domain': zone['name'],
'record': '@',
'result': 'Başarılı' if root_result else 'Başarısız'
})
www_result = create_dns_record(
zone_id=zone['id'],
record_type="A",
name="www",
content=ip_address,
proxied=proxied
)
zone_results.append({
'domain': zone['name'],
'record': 'www',
'result': 'Başarılı' if www_result else 'Başarısız'
})
return zone_results
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = [executor.submit(process_zone, zone) for zone in zones]
for future in concurrent.futures.as_completed(futures):
results.extend(future.result())
print("\nİşlem sonuçları:")
for r in results:
print(f"{r['domain']} ({r['record']}): {r['result']}")
return results
def add_mx_records(zones, mail_server_prefix="mail", priority=10, proxied=False, mail_ip=None):
if not zones:
print("Domain bulunamadı!")
return
if not mail_ip:
mail_ip = input(f"Tüm {mail_server_prefix} subdomainleri için IP adresi: ")
results = []
def process_zone(zone):
zone_results = []
mail_server = f"{mail_server_prefix}.{zone['name']}"
data = {
'type': "MX",
'name': "@",
'content': mail_server,
'ttl': 1,
'proxied': proxied,
'priority': priority
}
try:
response = requests.post(
f'{CF_API_URL}/zones/{zone["id"]}/dns_records',
headers=headers,
json=data
)
result = response.json()
if not result['success']:
print(f"Hata: {result['errors']}")
result = None
else:
print(f"MX kaydı eklendi: {result['result']['name']}")
result = result['result']
except Exception as e:
print(f"MX kaydı oluşturulurken hata: {e}")
result = None
mail_a_result = create_dns_record(
zone_id=zone['id'],
record_type="A",
name=mail_server_prefix,
content=mail_ip,
ttl=1,
proxied=proxied
)
zone_results.append({
'domain': zone['name'],
'record': 'MX',
'result': 'Başarılı' if result else 'Başarısız'
})
return zone_results
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = [executor.submit(process_zone, zone) for zone in zones]
for future in concurrent.futures.as_completed(futures):
results.extend(future.result())
print("\nİşlem sonuçları:")
for r in results:
print(f"{r['domain']} ({r['record']}): {r['result']}")
return results
def add_subdomain_to_domains(zones, subdomain, ip_address, proxied=True):
if not zones:
print("Domain bulunamadı!")
return
results = []
def process_zone(zone):
result = create_dns_record(
zone_id=zone['id'],
record_type="A",
name=subdomain,
content=ip_address,
proxied=proxied
)
return {
'domain': zone['name'],
'record': subdomain,
'result': 'Başarılı' if result else 'Başarısız'
}
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(process_zone, zones))
print("\nİşlem sonuçları:")
for r in results:
print(f"{r['domain']} ({r['record']}): {r['result']}")
return results
def add_record_to_domains(zones, record_type, name, content, proxied=True):
if not zones:
print("Domain bulunamadı!")
return
results = []
def process_zone(zone):
result = create_dns_record(
zone_id=zone['id'],
record_type=record_type,
name=name,
content=content,
proxied=proxied
)
return {
'domain': zone['name'],
'result': 'Başarılı' if result else 'Başarısız'
}
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(process_zone, zones))
print("\nİşlem sonuçları:")
for r in results:
print(f"{r['domain']}: {r['result']}")
return results
def update_dns_record(zone_id, record_id, record_type, name, content, ttl=1, proxied=True):
data = {
'type': record_type,
'name': name,
'content': content,
'ttl': ttl,
'proxied': proxied
}
try:
response = requests.put(
f'{CF_API_URL}/zones/{zone_id}/dns_records/{record_id}',
headers=headers,
json=data
)
result = response.json()
if not result['success']:
print(f"Hata: {result['errors']}")
return None
print(f"DNS kaydı güncellendi: {result['result']['name']}")
return result['result']
except Exception as e:
print(f"DNS kaydı güncellenirken hata: {e}")
return None
def bulk_update_a_records(zones, new_ip):
if not zones:
print("Domain bulunamadı!")
return
results = []
def process_zone(zone):
zone_results = []
records = get_dns_records(zone['id'])
if not records:
return []
a_records = [r for r in records if r['type'] == 'A']
for record in a_records:
result = update_dns_record(
zone_id=zone['id'],
record_id=record['id'],
record_type='A',
name=record['name'],
content=new_ip,
proxied=record['proxied']
)
zone_results.append({
'domain': zone['name'],
'record': record['name'],
'result': 'Başarılı' if result else 'Başarısız'
})
return zone_results
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = [executor.submit(process_zone, zone) for zone in zones]
for future in concurrent.futures.as_completed(futures):
results.extend(future.result())
print("\nGüncelleme sonuçları:")
for r in results:
print(f"{r['domain']} ({r['record']}): {r['result']}")
return results
def export_dns_records_to_csv(zones, filename="dns_records.csv"):
if not zones:
print("Domain bulunamadı!")
return
all_records = []
def process_zone(zone):
zone_records = []
records = get_dns_records(zone['id'])
if not records:
return []
for record in records:
zone_records.append({
'domain': zone['name'],
'type': record['type'],
'name': record['name'],
'content': record['content'],
'proxied': record['proxied'],
'ttl': record['ttl'],
'id': record['id'],
'zone_id': zone['id']
})
return zone_records
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = [executor.submit(process_zone, zone) for zone in zones]
for future in concurrent.futures.as_completed(futures):
all_records.extend(future.result())
try:
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['domain', 'type', 'name', 'content', 'proxied', 'ttl', 'id', 'zone_id']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for record in all_records:
writer.writerow(record)
print(f"\nTüm DNS kayıtları {filename} dosyasına aktarıldı.")
return filename
except Exception as e:
print(f"CSV dosyası oluşturulurken hata: {e}")
return None
def import_dns_records_from_csv(filename="dns_records.csv"):
try:
with open(filename, 'r', newline='', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile)
records = list(reader)
results = []
def process_record(record):
try:
proxied = record['proxied'].lower() == 'true'
result = create_dns_record(
zone_id=record['zone_id'],
record_type=record['type'],
name=record['name'],
content=record['content'],
ttl=int(record['ttl']),
proxied=proxied
)
return {
'domain': record['domain'],
'record': record['name'],
'result': 'Başarılı' if result else 'Başarısız'
}
except Exception as e:
return {
'domain': record['domain'],
'record': record['name'],
'result': f'Hata: {str(e)}'
}
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(process_record, records))
print("\nİçe aktarma sonuçları:")
for r in results:
print(f"{r['domain']} ({r['record']}): {r['result']}")
return results
except Exception as e:
print(f"CSV dosyası okunurken hata: {e}")
return None
def create_firewall_rule(zone_id, name, action="block", expression="", paused=False):
data = {
'filter': {
'expression': expression
},
'action': action,
'description': name,
'paused': paused
}
try:
response = requests.post(
f'{CF_API_URL}/zones/{zone_id}/firewall/rules',
headers=headers,
json=data
)
result = response.json()
if not result['success']:
print(f"Hata: {result['errors']}")
return None
print(f"Güvenlik duvarı kuralı oluşturuldu: {name}")
return result['result']
except Exception as e:
print(f"Güvenlik duvarı kuralı oluşturulurken hata: {e}")
return None
def add_ip_restriction(zones, rule_name, allowed_ips):
if not zones:
print("Domain bulunamadı!")
return
ip_list = " or ".join([f"ip.src eq {ip}" for ip in allowed_ips])
expression = f"not ({ip_list})"
results = []
def process_zone(zone):
result = create_firewall_rule(
zone_id=zone['id'],
name=rule_name,
action="block",
expression=expression
)
return {
'domain': zone['name'],
'result': 'Başarılı' if result else 'Başarısız'
}
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(process_zone, zones))
print("\nIP kısıtlaması sonuçları:")
for r in results:
print(f"{r['domain']}: {r['result']}")
return results
def select_domains(all_zones):
print("\nDomain seçim modu:")
print("1. Tüm domainler")
print("2. Tek domain")
print("3. Çoklu domain seçimi")
choice = input("\nSeçiminiz (1-3): ")
if choice == "1":
return all_zones
elif choice == "2":
if all_zones and len(all_zones) > 0:
print("\nİşlem yapmak istediğiniz domainin numarasını seçin:")
for i, zone in enumerate(all_zones):
print(f"{i+1}. {zone['name']}")
try:
zone_index = int(input("\nSeçiminiz: ")) - 1
if 0 <= zone_index < len(all_zones):
return [all_zones[zone_index]]
else:
print("Geçersiz numara!")
return None
except ValueError:
print("Lütfen bir numara girin!")
return None
elif choice == "3":
if all_zones and len(all_zones) > 0:
print("\nİşlem yapmak istediğiniz domainlerin numaralarını virgülle ayırarak girin:")
for i, zone in enumerate(all_zones):
print(f"{i+1}. {zone['name']}")
try:
indices = input("\nSeçimleriniz (örn: 1,3,5): ").split(',')
selected_zones = []
for idx in indices:
zone_index = int(idx.strip()) - 1
if 0 <= zone_index < len(all_zones):
selected_zones.append(all_zones[zone_index])
else:
print(f"Geçersiz numara: {idx}")
if selected_zones:
return selected_zones
else:
print("Geçerli domain seçilmedi!")
return None
except ValueError:
print("Lütfen geçerli numaralar girin!")
return None
print("Geçersiz seçim!")
return None
def display_menu():
print("\nCloudflare API Yönetim Aracı")
print("---------------------------")
print("1. Domainleri listele")
print("2. Domain için DNS kayıtları listele")
print("3. Root (@) ve www A kaydı ekle")
print("4. Belirli bir subdomain A kaydı ekle")
print("5. MX kaydı ekle (mail.domain.com)")
print("6. Aynı DNS kaydı ekle")
print("7. A kayıtlarını güncelle")
print("8. DNS kayıtlarını CSV'ye aktar")
print("9. CSV'den DNS kayıtlarını içe aktar")
print("10. IP kısıtlaması ekle")
print("11. Nameserver bilgilerini CSV'ye aktar")
print("12. Nameserver bilgilerini TXT'ye aktar")
print("0. Çıkış")
choice = input("\nSeçiminiz (0-12): ")
return choice
def main():
all_zones = list_zones()
while True:
choice = display_menu()
if choice == "1":
list_zones()
elif choice == "2":
if all_zones and len(all_zones) > 0:
print("\nDNS kayıtlarını görmek istediğiniz domainin numarasını seçin:")
for i, zone in enumerate(all_zones):
print(f"{i+1}. {zone['name']}")
try:
zone_index = int(input("\nSeçiminiz: ")) - 1
if 0 <= zone_index < len(all_zones):
get_dns_records(all_zones[zone_index]['id'])
else:
print("Geçersiz numara!")
except ValueError:
print("Lütfen bir numara girin!")
elif choice == "3":
selected_zones = select_domains(all_zones)
if selected_zones:
ip_address = input("Eklenecek IP adresi: ")
proxied = input("Proxy kullanılsın mı? (e/h): ").lower() == 'e'
add_root_and_www_a_records(selected_zones, ip_address, proxied)
elif choice == "4":
selected_zones = select_domains(all_zones)
if selected_zones:
subdomain = input("Eklenecek subdomain adı: ")
ip_address = input(f"{subdomain} için IP adresi: ")
proxied = input("Proxy kullanılsın mı? (e/h): ").lower() == 'e'
add_subdomain_to_domains(selected_zones, subdomain, ip_address, proxied)
elif choice == "5":
selected_zones = select_domains(all_zones)
if selected_zones:
mail_prefix = input("Mail sunucusu öneki (varsayılan: mail): ") or "mail"
priority = int(input("MX önceliği (varsayılan: 10): ") or "10")
proxied = input("Proxy kullanılsın mı? (e/h): ").lower() == 'e'
add_mx_records(selected_zones, mail_prefix, priority, proxied)
elif choice == "6":
selected_zones = select_domains(all_zones)
if selected_zones:
record_type = input("Kayıt türü (A, CNAME, TXT, MX, vb.): ").upper()
name = input("Kayıt adı (@ root için): ")
content = input("İçerik (IP adresi veya hedef): ")
proxied = input("Proxy kullanılsın mı? (e/h): ").lower() == 'e'
add_record_to_domains(selected_zones, record_type, name, content, proxied)
elif choice == "7":
selected_zones = select_domains(all_zones)
if selected_zones:
new_ip = input("A kayıtları için yeni IP adresi: ")
bulk_update_a_records(selected_zones, new_ip)
elif choice == "8":
selected_zones = select_domains(all_zones)
if selected_zones:
filename = input("CSV dosya adı (varsayılan: dns_records.csv): ") or "dns_records.csv"
export_dns_records_to_csv(selected_zones, filename)
elif choice == "9":
filename = input("İçe aktarılacak CSV dosya adı: ")
if os.path.exists(filename):
import_dns_records_from_csv(filename)
else:
print(f"Hata: {filename} dosyası bulunamadı!")
elif choice == "10":
selected_zones = select_domains(all_zones)
if selected_zones:
rule_name = input("Kural adı: ")
allowed_ips = input("İzin verilen IP'ler (virgülle ayırın): ").split(',')
allowed_ips = [ip.strip() for ip in allowed_ips]
add_ip_restriction(selected_zones, rule_name, allowed_ips)
elif choice == "11":
selected_zones = select_domains(all_zones)
if selected_zones:
filename = input("CSV dosya adı (varsayılan: domain_nameservers.csv): ") or "domain_nameservers.csv"
export_nameservers_to_csv(selected_zones, filename)
elif choice == "12":
selected_zones = select_domains(all_zones)
if selected_zones:
filename = input("TXT dosya adı (varsayılan: domain_nameservers.txt): ") or "domain_nameservers.txt"
export_nameservers_to_txt(selected_zones, filename)
elif choice == "0":
print("Programdan çıkılıyor...")
sys.exit(0)
else:
print("Geçersiz seçim!")
input("\nDevam etmek için Enter tuşuna basın...")
if __name__ == "__main__":
main()