Merhaba sektördeki değerli meslektaşlarım!
Bir IT uzmanı olarak, her geçen gün yeni bir şeyler öğrenmeye ve bu öğrendiklerimi pratikle birleştirmeye bayılıyorum. Özellikle Python gibi çok yönlü bir dil, karşılaştığım birçok soruna basit ve etkili çözümler üretmeme olanak tanıyor. Bugün de sizlerle, bir IT uzmanının çantasında bulunması gereken, hem temel hem de çok faydalı bir aracı, “Python ile Basit Port Scanner Yapımı”nı konuşmak istiyorum.
Neden Bir Port Scanner’a İhtiyacımız Var?
Diyelim ki yeni bir sunucu kurdunuz veya mevcut bir sunucunun güvenlik yapılandırmasını kontrol ediyorsunuz. Bu sunucu üzerinde hangi servislerin hangi portlardan dışarıya açık olduğunu bilmek, sadece bir güvenlik denetimi değil, aynı zamanda olası ağ sorunlarını gidermek için de hayati öneme sahip. Veya bir uygulama çalışmıyor, acaba gerekli portu dinlemiyor mu, yoksa bir güvenlik duvarı mı engelliyor? İşte bu noktada bir port tarayıcı devreye giriyor.
Piyasada Nmap gibi harika ve kapsamlı araçlar var, kabul ediyorum. Ancak bazen, hızlıca bir kontrol yapmak veya Nmap’in tüm özelliklerine ihtiyaç duymadan kendi senaryomuz için özelleştirilmiş, hafif bir araç geliştirmek isteyebiliriz. Ya da en önemlisi, bir şeyin “nasıl çalıştığını” anlayarak kendi bilgimizi pekiştirmek isteyebiliriz. Benim için bu durum, geçtiğimiz günlerde kendi lab ortamımda bir servis deploy ederken doğan bir ihtiyaçla başladı. Hangi portların gerçekten erişilebilir olduğunu hızlıca görmem gerekiyordu ve bu basit script imdadıma yetişti.
Peki, Bu Port Scanner Nasıl Çalışır?
Temel olarak, bir port tarayıcı, belirtilen bir IP adresindeki belirli portlara bağlantı kurmaya çalışır. İşin özü, TCP el sıkışması (three-way handshake) prensibine dayanır. Bir port tarayıcı, hedef portlara bir SYN paketi gönderir:
- Eğer port açıksa, sunucu bir SYN-ACK paketiyle yanıt verir. Bu durumda tarayıcı, portun açık olduğunu anlar ve bağlantıyı RST (reset) paketiyle sonlandırır (tam bir bağlantı kurmaya gerek kalmadan).
- Eğer port kapalıysa, sunucu genellikle bir RST paketiyle yanıt verir.
- Eğer ortada bir güvenlik duvarı (firewall) varsa ve bu portu filtrelendiyse, herhangi bir yanıt gelmeyebilir (SYN paketine yanıt yok) veya bir ICMP Destination Unreachable mesajı gelebilir.
Python’da bu işlemi gerçekleştirmek için socket modülünü kullanırız. Özellikle socket.socket().connect_ex() metodu, bize bağlantı denemesinin sonucunu (başarılı mı başarısız mı) bir hata kodu olarak döndürdüğü için oldukça işimize yarar. 0 değeri başarılı bağlantıyı, diğer değerler ise farklı hataları (örneğin bağlantı reddi) gösterir.
Uygulama: Python ile Basit Port Scanner Kodu
Şimdi gelelim kod kısmına. Amacımız, kullanıcıdan bir hedef IP adresi ve taramak istediği port aralığını almak ve bu portları tarayarak açık olanları listelemek.
import socket
import sys
from datetime import datetime
# Hedef IP adresi
target = input("Taranacak IP adresini girin: ")
target_ip = socket.gethostbyname(target) # Host adını IP'ye çevirir
# Port aralığı
try:
start_port = int(input("Başlangıç port numarasını girin: "))
end_port = int(input("Bitiş port numarasını girin: "))
except ValueError:
print("Hata: Geçersiz port numarası girdiniz. Lütfen sayısal bir değer girin.")
sys.exit()
# Tarama başlangıç zamanı
print("-" * 50)
print(f"Hedef: {target_ip}")
print(f"Tarama Başladı: {datetime.now()}")
print("-" * 50)
# Socket timeout'unu ayarla (çok uzun beklememesi için)
socket.setdefaulttimeout(1) # 1 saniye bekleme süresi
open_ports = []
try:
for port in range(start_port, end_port + 1):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # IPv4, TCP soketi
result = sock.connect_ex((target_ip, port)) # Bağlantı denemesi yap
if result == 0:
print(f"Port {port}: Açık")
open_ports.append(port)
sock.close()
except KeyboardInterrupt:
print("\nTarama kullanıcı tarafından iptal edildi.")
sys.exit()
except socket.gaierror:
print("Host adı çözümlenemedi. Lütfen doğru bir IP adresi veya hostname girin.")
sys.exit()
except socket.error:
print("Sunucuya bağlanılamadı.")
sys.exit()
# Tarama bitiş zamanı
print("-" * 50)
print(f"Tarama Bitti: {datetime.now()}")
print("-" * 50)
if open_ports:
print("Açık Portlar:")
for p in open_ports:
print(f"- {p}")
else:
print("Belirtilen aralıkta açık port bulunamadı.")
Bu kod parçası, belirtilen IP üzerindeki her bir port için bir TCP soketi oluşturur ve bağlantı kurmaya çalışır. connect_ex() metodu bize 0 (başarılı) veya başka bir hata kodu döndürür. Böylece portun açık olup olmadığını anlarız.
Karşılaşılan Zorluklar ve Dikkat Edilmesi Gerekenler
Bu basit port tarayıcısını yazarken veya kullanırken birkaç önemli noktaya dikkat etmek gerekiyor:
- Güvenlik Duvarları (Firewallar): Yazdığımız bu basit tarayıcı, bir portun “kapalı” mı yoksa bir güvenlik duvarı tarafından “filtrelenmiş” mi olduğunu her zaman net bir şekilde ayırt edemez. Filtrelenmiş bir port, hiç yanıt vermeyebilir ve bizim tarayıcımız onu sadece “açık değil” olarak algılayabilir. Daha gelişmiş araçlar (Nmap gibi) bu ayrımı yapabilen farklı tarama teknikleri kullanır.
- Zaman Aşımı (Timeout): Her bağlantı denemesi için sonsuza kadar beklemek istemeyiz. Kodu incelerseniz,
socket.setdefaulttimeout(1)satırını göreceksiniz. Bu, bir bağlantı denemesinin en fazla 1 saniye beklemesini sağlar. Eğer hedef sunucu yanıt vermiyorsa, bu süre sonunda bağlantı denemesi başarısız sayılır. Bu değeri, ağınızın durumuna göre optimize etmeniz gerekebilir. - Performans: Büyük port aralıklarını tararken bu tek iş parçacıklı (single-threaded) script yavaş kalabilir. Binlerce portu taramak dakikalar hatta daha uzun sürebilir. Daha hızlı taramalar için çoklu iş parçacığı (multi-threading) veya asenkron programlama (asyncio) gibi teknikleri araştırmanız gerekebilir.
- Yasal ve Etik Sorumluluklar: Unutmayın, port taraması potansiyel olarak kötüye kullanılabilecek bir eylemdir. Yalnızca kendi ağlarınızda veya izniniz olan sistemlerde kullanmalısınız. İzinsiz taramalar yasa dışıdır ve etik dışıdır. Bu konuyla alakalı sorumluluk kabul edilmez!
Sonuç
Python ile bu basit port tarayıcısını yazmak, hem ağ protokollerinin temel işleyişini anlamak hem de Python’ın socket modülünün gücünü görmek açısından harika bir deneyim oldu. Belki Nmap kadar kapsamlı değil ama ihtiyacımız olan temel bilgiyi hızlıca sağlamak için son derece pratik ve öğretici bir araç.
Bu gibi basit scriptler, bir IT uzmanının problem çözme yeteneğini geliştirmesine ve mevcut araçları derinlemesine anlamasına yardımcı olur. Kendi başınıza bir şeyler inşa etmek, kütüphanelerin ve modüllerin perde arkasında neler döndüğünü daha iyi kavramanın en iyi yoludur. Siz de bu kodu alıp daha da geliştirebilir, örneğin servis tespiti (hangi portta hangi servis çalışıyor) ekleyebilir veya performansı artırmak için multi-threading kullanabilirsiniz. Unutmayın, öğrenme süreci hiç bitmiyor!
Bir sonraki blog yazımda görüşmek üzere, kodla kalın!