$ Python ve Scapy ile Kendi Traceroute Aracınızı Yazın
Bir web sitesine bağlanmaya çalıştığınızda verilerinizin hangi yollardan geçtiğini hiç merak ettiniz mi? traceroute (veya Windows'ta tracert), bir ağ paketinin hedef sunucuya ulaşana kadar geçtiği her bir "atlama noktasını" (hop) keşfeden temel bir ağ teşhis aracıdır. Bu makalede, bu aracın arkasındaki mantığı anlayacak ve Python'un güçlü scapy kütüphanesi ile kendi versiyonumuzu yazacağız.
Traceroute Nasıl Çalışır? (TTL Mantığı)
Traceroute'un çalışma prensibi, IP paketlerindeki TTL (Time To Live) alanını akıllıca kullanmaya dayanır. TTL, bir paketin ağda ne kadar süre "yaşayabileceğini" belirten bir sayaçtır. Bir paket bir yönlendiriciye (router) her uğradığında, yönlendirici paketin TTL değerini 1 azaltır. TTL değeri 0'a ulaştığında, yönlendirici paketi yok eder ve paketin gönderildiği kaynağa bir "Zaman Aşımı" (Time Exceeded) ICMP hata mesajı gönderir.
Traceroute tam olarak bunu yapar: Hedefe giden yoldaki her yönlendiriciden bu hata mesajını kasıtlı olarak tetikler. Bunu, TTL değerini 1'den başlatarak ve her adımda bir artırarak yapar. Böylece, sırayla her yönlendiricinin kimliğini (IP adresini) öğrenir.
Gerekli Kütüphane: Scapy
Bu işlemi düşük seviyeli soketlerle yapmak karmaşık olabilir. Scapy, ağ paketlerini oluşturma, gönderme, alma ve analiz etme işlemlerini inanılmaz derecede basitleştiren güçlü bir kütüphanedir. Kurulumu için:
pip install scapy
Örnek Python Traceroute Kodu
Aşağıdaki betik, bir hedef alan adı alır ve o hedefe giden yolu maksimum 30 atlama noktasına kadar keşfeder. Her adımda gönderdiği pakete bir yanıt alamazsa, o adımı `*` olarak işaretler.
Not: Bu betiğin ICMP paketleri gönderebilmesi için yönetici (root veya Administrator) yetkileriyle çalıştırılması gerekebilir.
from scapy.all import *
import sys
def trace_route(hostname):
"""
Scapy kullanarak belirtilen hedefe giden ağ yolunu keşfeder.
"""
print(f"'{hostname}' için traceroute başlatılıyor (maksimum 30 hop)...")
# TTL değerini 1'den başlatıp 30'a kadar döngüye al
for i in range(1, 31):
# Hedefe ICMP "echo-request" paketi gönder, TTL değerini ayarla
# IP() katmanı TTL'i yönetir, ICMP() ise ping isteğidir.
pkt = IP(dst=hostname, ttl=i) / ICMP()
# Paketi gönder ve bir cevap bekle (timeout=2 saniye)
# sr1 fonksiyonu, bir paket gönderip ilk cevabı alan fonksiyondur.
reply = sr1(pkt, verbose=0, timeout=2)
if reply is None:
# 2 saniye içinde cevap gelmedi
print(f"{i}\t* * * Zaman aşımı")
elif reply.type == 11 and reply.code == 0:
# TTL zaman aşımına uğradı, bu bir yönlendirici demek.
# reply.src, ICMP hata mesajını gönderen yönlendiricinin IP adresidir.
print(f"{i}\t{reply.src}")
elif reply.type == 0:
# ICMP "echo-reply" aldık, hedefe ulaştık demek.
print(f"{i}\t{reply.src} (Hedefe ulaşıldı!)")
break
else:
# Beklenmedik bir durum
print(f"{i}\tBeklenmedik cevap: Tip={reply.type}, Kod={reply.code}")
if __name__ == '__main__':
# Komut satırından bir hedef alın, verilmezse varsayılanı kullanın
target = "virtualscrap.com"
if len(sys.argv) > 1:
target = sys.argv[1]
trace_route(target)