استخراج بيانات الاتصال (WHOIS & DNS): بناء أداة لجمع معلومات السيرفرات


مرحباً أيها المطورون! اليوم، سنبني أداة قوية لاستخراج معلومات خوادم الإنترنت باستخدام بروتوكولات WHOIS و DNS.

مقدمة: فهم WHOIS و DNS

تُعد بروتوكولات WHOIS و DNS أدوات أساسية لأي شخص يعمل في مجال الشبكات أو أمن المعلومات أو حتى تطوير الويب. يتيح لك WHOIS الاستعلام عن معلومات تسجيل النطاق مثل مالك النطاق، تواريخ الإنشاء والانتهاء، وخوادم الأسماء (Nameservers). بينما يوفر نظام أسماء النطاقات (DNS) معلومات حول كيفية ترجمة أسماء النطاقات إلى عناوين IP، وتحديد خوادم البريد (MX)، وغيرها من السجلات الهامة التي تكشف الكثير عن البنية التحتية للموقع. سنقوم في هذا الدرس ببناء أداة بايثون بسيطة لجمع هذه المعلومات بطريقة منظمة.

الخطوة 1: استيراد المكتبات الضرورية

للبدء، نحتاج إلى مكتبات بايثون التي تسمح لنا بالتفاعل مع خدمات WHOIS و DNS. سنستخدم مكتبة python-whois لمعلومات WHOIS ومكتبة dnspython لسجلات DNS. إذا لم تكن مثبتة لديك، يمكنك تثبيتها باستخدام pip: pip install python-whois dnspython
import whois          # لاستخراج معلومات WHOIS عن النطاقات
import dns.resolver   # لاستخراج سجلات DNS (مثل A, MX, NS)
import socket         # للحصول على عنوان IP الأساسي من اسم النطاق
في هذا الجزء، قمنا باستيراد المكتبات اللازمة. whois سيمكننا من إجراء استعلامات WHOIS، وdns.resolver سيتعامل مع استعلامات DNS المتنوعة، وsocket هو مكتبة بايثون مدمجة يمكن أن تساعد في بعض عمليات تحويل أسماء المضيفين.

الخطوة 2: استخراج معلومات WHOIS

الآن، لنقم بإنشاء دالة تستقبل اسم النطاق وتُرجع معلومات WHOIS الخاصة به. هذه المعلومات تشمل عادةً المالك، المسجل، تاريخ الإنشاء، تاريخ الانتهاء، وخوادم الأسماء.
def get_whois_info(domain):
    """تستخرج معلومات WHOIS لنطاق معين."""
    print(f"\n[*] استخراج معلومات WHOIS لـ: {domain}")
    try:
        w = whois.whois(domain)
        return w
    except Exception as e:
        print(f"[-] خطأ في استخراج WHOIS: {e}")
        return None
الدالة get_whois_info تستخدم whois.whois(domain) لمحاولة جلب البيانات. لقد أضفنا كتلة try-except للتعامل مع أي أخطاء محتملة قد تحدث أثناء الاستعلام، مثل عدم وجود النطاق أو مشاكل في الاتصال بالخادم.

الخطوة 3: استخراج سجلات DNS

بعد ذلك، سنبني دالة لجلب سجلات DNS المختلفة (مثل A، MX، NS، TXT). هذه السجلات توفر رؤى حول كيفية توجيه حركة المرور للموقع، خوادم البريد، وخوادم الأسماء المستخدمة.
def get_dns_records(domain, record_type):
    """تستخرج سجلات DNS لنوع معين (مثل 'A', 'MX', 'NS', 'TXT')."""
    records = []
    try:
        answers = dns.resolver.resolve(domain, record_type)
        for rdata in answers:
            records.append(str(rdata))
    except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.Timeout):
        # معالجة الأخطاء الشائعة مثل عدم وجود النطاق أو عدم وجود سجلات لهذا النوع
        pass
    except Exception as e:
        print(f"[-] خطأ في استخراج سجلات DNS من نوع {record_type}: {e}")
    return records
تأخذ الدالة get_dns_records النطاق ونوع السجل (مثل 'A' لعنوان IP، 'MX' لخادم البريد) وتقوم بإجراء استعلام DNS. نجمع النتائج في قائمة ونعيدها. تم تضمين معالجة الأخطاء للتعامل مع الحالات التي لا توجد فيها سجلات أو يكون النطاق غير موجود.

الخطوة 4: دمج الوظائف وبناء الأداة

الآن حان الوقت لربط كل شيء معًا في سكربت واحد يمكن للمستخدم تشغيله. سنطلب من المستخدم إدخال اسم نطاق ثم نعرض جميع المعلومات التي جمعناها.
def main():
    domain = input("أدخل اسم النطاق (مثال: google.com): ")
    if not domain:
        print("[-] لم يتم إدخال نطاق. الخروج.")
        return

    # الحصول على معلومات WHOIS
    whois_info = get_whois_info(domain)
    if whois_info:
        print("\n=== معلومات WHOIS ===")
        # عرض بعض معلومات WHOIS الرئيسية
        print(f"المسجل: {whois_info.registrar}")
        print(f"تاريخ الإنشاء: {whois_info.creation_date}")
        print(f"تاريخ الانتهاء: {whois_info.expiration_date}")
        print(f"خوادم الأسماء (Nameservers): {', '.join(whois_info.nameservers) if whois_info.nameservers else 'غير متوفر'}")
        # يمكنك طباعة 'whois_info' بالكامل لرؤية جميع البيانات

    # الحصول على سجلات DNS
    print("\n=== سجلات DNS ===")

    print("[*] سجلات A (عناوين IP):")
    a_records = get_dns_records(domain, 'A')
    if a_records: 
        for record in a_records: print(f"  - {record}")
    else: print("  لا توجد سجلات A.")

    print("\n[*] سجلات MX (خوادم البريد):")
    mx_records = get_dns_records(domain, 'MX')
    if mx_records:
        for record in mx_records: print(f"  - {record}")
    else: print("  لا توجد سجلات MX.")

    print("\n[*] سجلات NS (خوادم الأسماء المعتمدة):")
    ns_records = get_dns_records(domain, 'NS')
    if ns_records:
        for record in ns_records: print(f"  - {record}")
    else: print("  لا توجد سجلات NS.")

    print("\n[*] سجلات TXT (النصوص):")
    txt_records = get_dns_records(domain, 'TXT')
    if txt_records:
        for record in txt_records: print(f"  - {record}")
    else: print("  لا توجد سجلات TXT.")

if __name__ == "__main__":
    main()
في الدالة main، نطلب من المستخدم إدخال النطاق، ثم نستدعي الدالتين get_whois_info و get_dns_records لأنواع سجلات DNS المختلفة. يتم تنسيق الإخراج ليكون واضحًا وسهل القراءة.
ملاحظة تقنية: قد تحتاج بعض استعلامات WHOIS إلى المرور عبر وكلاء (proxies) أو استخدام خدمات API مدفوعة لتجاوز قيود معدل الاستعلام (rate limits) المفروضة من قبل بعض المسجلين أو registries، خاصة عند إجراء عدد كبير من الاستعلامات. مكتبة python-whois تتعامل بشكل جيد مع معظم الحالات الافتراضية.

الكود النهائي الكامل

هذا هو السكربت الكامل الذي يمكنك تشغيله لجمع معلومات الخوادم.
import whois
import dns.resolver
import socket

def get_whois_info(domain):
    """تستخرج معلومات WHOIS لنطاق معين."""
    print(f"\n[*] استخراج معلومات WHOIS لـ: {domain}")
    try:
        w = whois.whois(domain)
        return w
    except Exception as e:
        print(f"[-] خطأ في استخراج WHOIS: {e}")
        return None

def get_dns_records(domain, record_type):
    """تستخرج سجلات DNS لنوع معين (مثل 'A', 'MX', 'NS', 'TXT')."""
    records = []
    try:
        answers = dns.resolver.resolve(domain, record_type)
        for rdata in answers:
            records.append(str(rdata))
    except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.Timeout):
        # معالجة الأخطاء الشائعة مثل عدم وجود النطاق أو عدم وجود سجلات لهذا النوع
        pass
    except Exception as e:
        print(f"[-] خطأ في استخراج سجلات DNS من نوع {record_type}: {e}")
    return records

def main():
    domain = input("أدخل اسم النطاق (مثال: google.com): ")
    if not domain:
        print("[-] لم يتم إدخال نطاق. الخروج.")
        return

    # الحصول على معلومات WHOIS
    whois_info = get_whois_info(domain)
    if whois_info:
        print("\n=== معلومات WHOIS ===")
        print(f"المسجل: {whois_info.registrar}")
        print(f"تاريخ الإنشاء: {whois_info.creation_date}")
        print(f"تاريخ الانتهاء: {whois_info.expiration_date}")
        print(f"خوادم الأسماء (Nameservers): {', '.join(whois_info.nameservers) if whois_info.nameservers else 'غير متوفر'}")

    # الحصول على سجلات DNS
    print("\n=== سجلات DNS ===")

    print("[*] سجلات A (عناوين IP):")
    a_records = get_dns_records(domain, 'A')
    if a_records: 
        for record in a_records: print(f"  - {record}")
    else: print("  لا توجد سجلات A.")

    print("\n[*] سجلات MX (خوادم البريد):")
    mx_records = get_dns_records(domain, 'MX')
    if mx_records:
        for record in mx_records: print(f"  - {record}")
    else: print("  لا توجد سجلات MX.")

    print("\n[*] سجلات NS (خوادم الأسماء المعتمدة):")
    ns_records = get_dns_records(domain, 'NS')
    if ns_records:
        for record in ns_records: print(f"  - {record}")
    else: print("  لا توجد سجلات NS.")

    print("\n[*] سجلات TXT (النصوص):")
    txt_records = get_dns_records(domain, 'TXT')
    if txt_records:
        for record in txt_records: print(f"  - {record}")
    else: print("  لا توجد سجلات TXT.")

if __name__ == "__main__":
    main()

النتيجة المتوقعة

عند تشغيل السكربت وإدخال نطاق مثل example.com، ستحصل على إخراج مشابه لما يلي (البيانات الفعلية ستختلف): `` أدخل اسم النطاق (مثال: google.com): example.com [*] استخراج معلومات WHOIS لـ: example.com === معلومات WHOIS === المسجل: IANA تاريخ الإنشاء: 1995-08-14 04:00:00 تاريخ الانتهاء: غير متوفر خوادم الأسماء (Nameservers): A.IANA-SERVERS.NET, B.IANA-SERVERS.NET === سجلات DNS === [*] سجلات A (عناوين IP): - 93.184.216.34 [*] سجلات MX (خوادم البريد): لا توجد سجلات MX. [*] سجلات NS (خوادم الأسماء المعتمدة): - a.iana-servers.net. - b.iana-servers.net. [*] سجلات TXT (النصوص): لا توجد سجلات TXT. `` ستزودك هذه الأداة بمعلومات قيمة حول أي نطاق، مما يساعدك في فهم البنية التحتية للخادم والاتصالات المرتبطة به. يمكنك توسيعها لجمع المزيد من أنواع السجلات أو دمجها مع أدوات أخرى لتحليل أعمق!