TCP uygulama seviyesinde nasıl kullanılır?

Bu flood’da uygulama seviyesi protokoller (HTTP, SMTP, FTP, Telnet, vb) ile TCP üzerinden istekleri karşılayan veri tabanı, cache sunucu gibi üçüncü parti sistemlerin TCP’yi nasıl kullandığını inceleyeceğiz.

Bilindiği gibi TCP ve UDP taşıyıcı katmanda bulunan protokollerdir. HTTP gibi uygulama seviyesi protokoller taşıyıcı katmanda TCP ya da UDP kullanarak işlevlerini yerine getirirler.

Uygulama seviyesindeki protokoller, iletişimin iki tarafı (istemci/sunucu) arasındaki senkronizasyonu sağlamak için iletilen paketin formatını iyi bir biçimde tanımlamaktadır. Örneğin HTTP protokolünde istemci tarafından sunucuya gönderilen pakette istek satırı HTTP metodu (GET, POST, vb) ile başlar, istek URI'ı ve protokol versiyonu (HTTP/1.0 veya HTTP/1.1) ile devam eder ve CRLF (Carriage Return, Line Feed) karakterleri ile biter. İstek satırından sonra başlık bölümü gelir.

Aşağıda www․milliyet․com․tr'ye yapılan istek Wireshark ile yakalanarak detayı gösterilmiştir.

Önceki flood’larda netcat - nc ve telnet araçları kullanarak uzak sunucuya TCP bağlantısı sağlanabileceğini göstermiştik. Şimdi yukarıda verilen bilgilerle nc kullanarak www․google․com'un ana sayfasına bir HTTP isteği yapalım.

Uygulama seviyesindeki protokollere benzer şekilde bir TCP portundan istekleri kabul eden üçüncü parti sistemler de istekleri kabul ederken ve bu isteklere cevap verirken belirli bir paket formatı belirlemişlerdir. Belirlenen paket formatı Wire Protocol olarak adlandırılır.

Wire Protocol'ü en basit olan sistemlerden biri Redis'tir. Redis tarafından kullanılan RESP - REdis Serialization Protocol https://redis.io/topics/protocol adresinde dokümante edilmiştir.

Dokümandan da görülebileceği üzere RESP'te foobar metnini serialize etmek için $6\r\nfoobar\r\n kullanılır. $6\r\n metnin uzunluğunun 6 karakter olduğunu belirtir, metin ise CRLF ile sonlandırılır foobar\r\n.

Şimdi redis-cli olmadan Redis sunucusuna TCP üzerinden bağlanıp RESP protokolünü kullanarak bir key/value ekleyelim ve sonra da sorgulayalım.

Bu noktada C#, Java ve NodeJS gibi programlama dillerinde Redis Client olarak bilinen kütüphanelerin işlevi anlaşılmış olmalıdır. Bu kütüphaneler Redis'in RESP protokolünü uygulayarak kullanıcılarına API çağrıları sağlamaktadır. Aslına bakılırsa veri tabanları, mesaj kuyrukları ve cache sunucularına erişmemizi sağlayan bütün Client Library (istemci kütüphaneleri) aynı işlevi sağlamaktadır. Kısaca sistemin sunduğu Wire Protocol'ü kullanıcıdan soyutlayarak ona API'ler verirler.

Wireshark, istemci ve sunucu arasında konumlandırılarak sunucunun sunduğu Wire Protocol'ün deşifre edilmesi amacı ile kullanılabilir. Aşağıdaki örnekte Redis'e bir key/value eklenmiş ve trafik kaydedilmiştir.

Wireshark'ın çok geniş bir protokol desteği bulunmaktadır. PostgreSQL ve MongoDB protokolleri Wireshark'ın desteklediği protokollerden sadece birkaçıdır.

Aşağıdaki örnekte PostgreSQL iletişiminden alınan TCP dump, Wireshark ile görüntülenmiş ve PostgreSQL Wire Protocol incelenmiştir.

Görüldüğü üzere birbiri ile iletişim kuran sistemlerin sağlıklı bir şekilde işleyebilmesi için uygulama seviyesinde birbirlerine gönderdikleri paketlerde belirli bir protokole uymaları gerekmektedir. Bu protokol metin formatında olabileceği gibi binary formatında da olabilir.