Geçen gece sunucumda ciddi bir trafik vardı. Nedenini anlamak için biraz araştırma yaptım. WordPress siteme birisi şifre deneyerek (bruteforce) giriş yapmaya çalışıyordu. Klasik sözlük saldırısı yapıyordu ve bu yöntemle şifremi tahmin etme şansı hiç yoktu. Bana bir zararı var mıydı? Tek bir saldırı olduğu için çok da önemli değildi…
Bu yazıda anlatılanları denemek için: Hemen buradan bir hesap açarbilir, 55 saniyede bulut sunucunuzun kurulumunu tamamlar ve 2 ay boyunca ücretsiz kullanırsınız…
Peki ya birden fazla kişi, eş zamanlı olarak saldırsaydı? Bunun cevabını vermeden önce saldırı anında sunucumun verilerine bakalım dilerseniz:
Yukarıdaki tabloya baktığımızda, saldırı anında işlemci gücüm %1 – %2 seviyesinden %40 seviyesine kadar çıkmış. %50’yi bile zorladığı olmuş. Tek bir saldırı neredeyse sunucumun yarı zamanını çalmaya yetmiş.
Aynı şekilde apache bağlantı sayısına da bakarsak, eş zamanlı olarak dört ayrı bağlantı kurduğunu görmekteyiz saldırganın. Bu sayı size az gelmesin çünkü anlık olarak açtığı bağlantı sayısı dört. Bunu bir dakika için düşünürsek, yüzlerce / binlerce bağlantı isteği anlamına gelir.
Ağ hareketliliğine bakarsak, durumun ciddiyetini daha iyi kavrayabiliriz. Normal seyrinde anlık 25KB/s olan bağlantı hacmim, saldırı anında anlık 400KB/s seviyesine kadar gelmiş. Koca sunucunun trafiği bir anda 16 katına çıkmış.
Güvenlik zafiyeti olmamasına karşın, bu kadar kaynağın heba edilmesi hoş değil. Tamam belki bir ömür şifreme ulaşamayacak ama sunucumu da yormasını istemedim. Bunu engelleyecek bir eklenti var mı diye bakınmaya başladım. Bir kaç seçenek çıktı önüme. Örneğin, http://www.scelik.net/wp-admin olan yönetim paneli giriş sayfamın adresini sanal olarak değiştirmek… Ya da 3 defa hatalı şifre girilmesi durumunda, asla oturum açmasına müsade etmemek.
Bunların hepsi bir seçenek. Ama işlevsel olarak hayalkırıklığı. Çünkü sitemi güvenleştirmeye değil, kaynaklarımı kurtarmaya çalışıyorum. Sitem zaten güvenli. Şifrem sağlam. Tahmin edilmesi imkansız. Saldırı yöntemi bile artık eskilerde kalmış kullanışsız bir yöntem. Tüm bunlara rağmen, işlemci gücümün yarısını yemiş bile…
Bana kökten bir çözüm (bir kaç hatalı denemeden sonra, saldırganı komple sunucudan uzak tutacak) lazımdı ve mevcut eklentiler arasında kafama göre bir çözüm bulamadım. Kendi eklentimi yazmaya karar verdim.
Öncelikle sistemimde hali hazırda çalışan bir firewall ve sistem günlüklerini periyodik olarak tarayan bir servis çalışmaktaydı. Eğer ben sistem günlüklerine saldırgan ile ilgili kayıt açabilirsem, servis bunu farkedip, doğrudan firewall üzerinden saldırganı engelleyebilirdi.
Ortaya şöyle bir eklenti çıktı:
/* Plugin Name: Secure WP with Fail2Ban Version: 1.0 Description: Stop WP bruteforce login attempts with Fail2Ban. Author: Sertaç ÇELİK Author URI: https://www.scelik.net */ function get_user_ip() { $RemoteAddress = $_SERVER['REMOTE_ADDR']; if (!empty($_SERVER['X_FORWARDED_FOR'])) { $X_FORWARDED_FOR = explode(',', $_SERVER['X_FORWARDED_FOR']); if (!empty($X_FORWARDED_FOR)) { $RemoteAddress = trim($X_FORWARDED_FOR[0]); } } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $HTTP_X_FORWARDED_FOR= explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); if (!empty($HTTP_X_FORWARDED_FOR)) { $RemoteAddress = trim($HTTP_X_FORWARDED_FOR[0]); } } return preg_replace('/[^0-9a-f:\., ]/si', '', $RemoteAddress); } function secure_wp_with_fail2ban() { openlog('SWPWF2B', LOG_PID, LOG_AUTHPRIV); syslog(LOG_INFO, "WordPress login failed. Server: [".$_SERVER['SERVER_NAME']."] - Client: [".get_user_ip()."]"); closelog(); } add_action( 'wp_login_failed', 'secure_wp_with_fail2ban' );
Yazmış olduğum eklenti sayesinde artık sunucumun /var/log/secure günlüğünde bir satır bilgi yer almaya başladı:
Bu satırda hangi site için, kim tarafından başarısız bir oturum açma girişimi yapılmış, bunun bilgisi yer alıyordu. Artık sistemimde çalışan Fail2Ban servisi bu bilgiye erişebilecekti. Geriye sadece bu satırı nasıl yorumlaması gerektiğini anlatmak kalıyordu…
Öncelikle /etc/fail2ban/filter.d dizini içerisinde wordpress.conf isimli bir dosya oluşturdum. İçeriği şu şekilde oldu:
# Fail2Ban filter for unsuccesfull WordPress authentication attempts # [INCLUDES] before = common.conf [Definition] # Aug 30 17:12:30 mail SWPWF2B[19859]: WordPress login failed. Server: [www.scelik.net] - Client: [176.40.200.88] failregex = .* WordPress login failed\. .* Client: \[\] ignoreregex =
Buradaki regex ifadesine baktığınızda, /var/log/secure dosyasında oluşturduğum bilgi satırlarını yakalayacak şekilde düzenlendiğini farkedersiniz. Bir şey, bir şey sonrasına WordPress login failed. yazısı, sonrasına bir şey, bir şey sonrasına Client: yazısı ve köşeli parantez içerisinde saldırgan ipsi. Ardından /etc/fail2ban dizini içerisinde bulunan jail.local dosyasına şu satırları ekledim:
[vesta-wordpress] enabled = true filter = wordpress action = vesta[name=WEB] logpath = /var/log/secure maxretry = 3
Normalde bu kısımda, bir action tanımlayıp, saldırgan ipsini doğrudan firewall üzerinden yasaklamam gerekiyordu. Ama sunucu yönetim panelimden de takip edebilmek için, ben bu işi Vesta‘ya devrettim. Böylece sadece arkaplanda yasaklanmak yerine, aynı zamanda sunucu panelimde de bir girdi olarak gözükecekti.
Fail2Ban servisini yeniden başlattım ve saldırılar bıçak gibi kesildi. Kulağı tersten gösterseydim, bu kadar zahmete girmeseydim ne olacaktı? Saldırgan asla başarılı bir şekilde oturum açamayacaktı ama sunucumu meşgul etmeye devam edecekti. Binlerce, milyonlarca istek oluşturacaktı… Ben ne yaptım? Hiç bir servise erişmesine (Web Sunucusu, Veritabanı Sunucusu, Php Betikleri) müsade etmeden, doğrudan ağ kartı üzerinden yasakladım.
İşlemleri bitirip, Fail2Ban servisini yeniden başlatmam takriben 04:30 gibi bir zamana denk geldi. Grafiklerden de göreceğiniz gibi, saldırı namına eser kalmadı. Bilgisayarını açık bırakıp, sabaha kullanıcı adımı ve şifremi ele geçireceğini sanan dangalak da, eline üçün birini almış oldu. Uyandığında artık oynar durur elindekiyle… :)
Neden Vesta’ya devrettiğime gelirsek de, tamamen estetik kaygılar yüzünden. :) O da şöyle gözüktü…
Artık sürekli komut satırına girmek zorunda kalmıyor, sunucu panelimden tüm saldırıları ve yasaklı ipleri izleyebiliyor, gerektiğinde yasaklamaları görsel olarak kaldırabiliyorum. Bu şekilde binlerce site bile barındırsam, tek bir günlük dosyasına girdi oluşturuluyor, hangi site saldırı alıyor görebiliyorum.
Saldırgan ise, tek bir siteden değil, tüm sunucudan uzaklaştırılıyor. Böylece başka bir siteye zıplayıp, onu da mıncıklamasını önlenmiş oluyorum. Biraz zahmetli oldu ama değdi.
Siz de kendinizi geliştirmek ve/veya bulut sunucuların avantajlarından faydalanmak isterseniz: hemen buradan bir hesap açabilir, 55 saniyede yeni sunucunuzun keyfini, 2 ay ücretsiz deneyerek, sürebilirsiniz…
Hi,
I know you a little mad at VestaCP team, but
how can I contact you vie e-mail?
Merhaba Sertaç,
Yazıların keyifli, devamını mutlaka getirmelisin.
Sorum şöyle: WordPress için TR’de önereceğin bir hosting firması var mı? Zamanında çok dert olunca yurtdışına taşıdım ama TR’den de hızlı bir şekilde ulaşılan bir hosting arayışım var. Fiyatlar da ya çok ucuz ya da çok uçuk oluyor; mesela hostpoint php7 versiyonunu yayına sundu ama burada 5.6 yükleyebilir miyiz diye sormaktan bıktım :)
İyi çalışmalar