Yeni bir VPS kurduğumda, ilk 45 dakikamı her zaman temel güvenlik adımlarına ayırırım. Bu süre, sunucuyu dışarıdan gelebilecek en basit ama en yaygın saldırılara karşı korumak için kritik bir penceredir. Bir sunucu, internete çıktığı an itibaren saniyeler içinde botlar tarafından taranmaya başlar ve varsayılan ayarlarla bırakılan sistemler kısa sürede hedef haline gelir.
Bu rehberde, yıllardır uyguladığım ve hem kendi yan ürünlerimde hem de müşteri projelerinde işe yaradığını gördüğüm, hızlı ve etkili bir VPS sıkılaştırma kontrol listesini paylaşacağım. Amacım, size sadece komutları vermek değil, aynı zamanda bu adımların neden önemli olduğunu, arkasındaki mantığı ve olası trade-off’ları da anlatmak.
Neden İlk 45 Dakika Çok Önemli?
Yeni bir VPS aldığımızda, genellikle varsayılan bir imajla gelir ve bu imajlar çoğu zaman güvenlik açısından “iyi niyetli” ayarlar içerir, ancak “güvenli” değildir. Root kullanıcısı için zayıf parolalar, açık SSH portları ve temel firewall kurallarının olmaması gibi durumlar sıkça karşılaştığım şeyler.
Deneyimlerime göre, bir sunucuyu internete açtıktan sonra ilk birkaç saat içinde, özellikle popüler portlar (22, 80, 443) üzerinde sürekli taramalar başlar. Kötü niyetli botlar, zayıf parolaları denemek, bilinen zafiyetleri istismar etmek için sürekli aktiftir. Bu nedenle, ilk 45 dakika içinde atacağımız adımlar, sunucumuzu bu otomatik saldırıların büyük bir kısmından koruyarak bize nefes alma alanı sağlar. Bu süre zarfında yapacağımız ayarlar, daha sonra daha kapsamlı güvenlik önlemleri almamız için sağlam bir zemin oluşturur.
Adım 1: SSH Anahtar Tabanlı Kimlik Doğrulama ve Parola İle Erişimi Kapatmak
Bir sunucuya erişimin en güvenli yollarından biri SSH anahtar çiftleri kullanmaktır. Parolalar, brute-force saldırılarına karşı savunmasızdır; anahtarlar ise çok daha güçlü bir güvenlik katmanı sunar. Ben, yeni bir sunucu kurduğumda ilk işim SSH anahtarımı yüklemek ve parola ile erişimi tamamen kapatmaktır.
Bu adımı atladığım zamanlar oldu, özellikle hızlıca bir şeyler denemem gerektiğinde. Ancak, bir keresinde parola ile açık bıraktığım bir test sunucusunun, fark etmeden bir botnet’in parçası haline geldiğini gördüm. Bu, bana zaman kazandırmak yerine daha büyük bir baş ağrısı yarattı. Bu yüzden artık asla atlamıyorum.
Öncelikle, kendi makinenizde bir SSH anahtar çiftiniz yoksa oluşturun:
ssh-keygen -t ed25519 -C "[email protected]"
Ardından, genel anahtarınızı (~/.ssh/id_ed25519.pub gibi) yeni sunucunuzdaki ~/.ssh/authorized_keys dosyasına kopyalayın. Bunu ssh-copy-id aracıyla yapabilir veya manuel olarak kopyalayabilirsiniz:
ssh-copy-id -i ~/.ssh/id_ed25519.pub mustafa@<SUNUCU_IP>
Anahtar ile giriş yapabildiğinizden emin olduktan sonra, SSH sunucu yapılandırmasını düzenleyin (/etc/ssh/sshd_config):
sudo vim /etc/ssh/sshd_config
Aşağıdaki satırları bulun ve değerlerini güncelleyin:
# Parola ile erişimi kapat
PasswordAuthentication no
# Root kullanıcısının doğrudan SSH ile giriş yapmasını engelle
PermitRootLogin no
# Kullanıcı adı ve parola yerine sadece anahtar ile giriş yapılmasını sağla
ChallengeResponseAuthentication no
Değişiklikleri kaydettikten sonra SSH servisini yeniden başlatın:
sudo systemctl restart sshd
Bu adımla, sunucunuzun kapısını sadece sizin anahtarınıza açmış olursunuz. Yanlışlıkla parolayı açık bırakmak, gelecekteki potansiyel saldırılara davetiye çıkarmaktır.
Adım 2: Temel Firewall Kurallarını Yapılandırmak (UFW veya Firewalld)
Varsayılan olarak birçok VPS’te firewall ya hiç açık değildir ya da sadece temel kurallar tanımlıdır. Bu, sunucunun tüm portlarını internete açık bırakmak demektir. Ben genellikle sadece ihtiyacım olan portları açarım. Bu, “least privilege” prensibinin network katmanındaki karşılığıdır.
Ubuntu tabanlı sistemlerde ufw (Uncomplicated Firewall) kullanmayı tercih ederim çünkü kullanımı basittir ve hızlıca temel kuralları tanımlamama olanak tanır. CentOS/RHEL tabanlı sistemlerde ise firewalld tercih ediyorum.
UFW ile Firewall Kurulumu ve Yapılandırması (Ubuntu/Debian)
İlk olarak ufw’yi yükleyin ve varsayılan politikaları ayarlayın:
sudo apt update
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
Bu komutlar, varsayılan olarak tüm gelen bağlantıları engellerken, giden bağlantılara izin verir. Şimdi, ihtiyacımız olan portları açalım. Genellikle SSH (port 22) ve bir web sunucusu (port 80 ve 443) için erişime ihtiyacımız olur:
sudo ufw allow ssh # veya sudo ufw allow 22
sudo ufw allow http # veya sudo ufw allow 80
sudo ufw allow https # veya sudo ufw allow 443
Eğer farklı bir SSH portu kullanıyorsanız (ki bu iyi bir uygulamadır, ancak ilk 45 dakikada port değiştirmek yerine öncelikle anahtar tabanlı erişimi aktif ederim), o portu açmanız gerekir: sudo ufw allow <yeni_ssh_portu>. Kuralları etkinleştirmeden önce kontrol etmek iyi bir alışkanlıktır:
sudo ufw status verbose
Her şey yolundaysa, ufw’yi etkinleştirin:
sudo ufw enable
Firewalld ile Firewall Kurulumu ve Yapılandırması (CentOS/RHEL)
firewalld genellikle bu dağıtımlarda yüklü gelir. Temel adımlar benzerdir.
sudo systemctl start firewalld
sudo systemctl enable firewalld
sudo firewall-cmd --zone=public --add-service=ssh --permanent
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload
Bu adımlar, public zonuna SSH, HTTP ve HTTPS servislerini ekler ve değişiklikleri kalıcı hale getirip firewall’u yeniden yükler. Daha sonra, firewall-cmd --list-all ile mevcut kuralları kontrol edebilirsiniz. Firewall’u doğru yapılandırmak, sunucunuzun sadece gerçekten ihtiyacı olan hizmetlere maruz kalmasını sağlar. Bir üretim ERP’sinin backend’ini geliştirirken, sadece gerekli olan API portlarını ve veritabanı portlarını açtık. Diğer her şey kapalıydı, bu da saldırı yüzeyimizi %80 oranında azalttı.
Adım 3: Güvenli Kullanıcı Oluşturma ve Root Hesabını Kısıtlama
VPS’e ilk bağlandığımda genellikle root kullanıcısıyım. Ama root kullanıcısıyla günlük işler yapmak, güvenlik açısından büyük bir risktir. Yanlış bir komut tüm sistemi bozabilir veya kötü niyetli bir saldırgan root hesabını ele geçirirse, sistemin tam kontrolünü ele geçirir. Bu yüzden, her zaman yeni bir standart kullanıcı oluşturur ve root hesabının direkt kullanımını sınırlarım.
Yeni bir kullanıcı oluşturun ve ona sudo yetkisi verin:
sudo adduser mustafa
sudo usermod -aG sudo mustafa
Şimdi, bu yeni kullanıcıyla giriş yapmayı deneyin ve sudo komutunun çalıştığından emin olun. Ardından, root kullanıcısının doğrudan SSH ile giriş yapmasını engellemek için sshd_config dosyasında daha önce yaptığımız PermitRootLogin no ayarını kontrol edin. Bu ayar, root kullanıcısının doğrudan SSH ile login olmasını engeller, ancak sudo ile root yetkisi almasına izin verir. Bu, güvenlik ve kullanılabilirlik arasında iyi bir denge sağlar.
Adım 4: Sistemi Güncel Tutmak ve Temel Güvenlik Paketlerini Kurmak
Sistem güncellemeleri, bilinen güvenlik açıklarını kapatmak için hayati öneme sahiptir. CVE (Common Vulnerabilities and Exposures) takip etmek, benim için günlük bir rutin. Kernel modüllerinden birindeki bir açığın (örneğin algif_aead modülünde geçmişte görülen bir zafiyet gibi) tüm sistemi ele geçirmeye yol açabileceğini biliyorum. Bu yüzden, sunucuyu kurar kurmaz güncellemeleri kontrol eder ve uygularım.
sudo apt update && sudo apt upgrade -y
sudo apt dist-upgrade -y
sudo apt autoremove -y
Bu komutlar, sistemdeki tüm paketleri en son sürümlerine günceller. dist-upgrade ise yeni bağımlılıkları veya değişen paketleri de ele alır. Ardından, otomatik güncellemeleri yapılandırmak, bu rutini otomatik hale getirir.
Otomatik Güvenlik Güncellemeleri
Otomatik güncellemeler, özellikle kritik güvenlik yamalarının hızlı bir şekilde uygulanmasını sağlar. Ubuntu’da unattended-upgrades paketini kullanırım:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
Bu komut, otomatik güncellemeleri etkinleştirmek için gerekli yapılandırma aracını çalıştırır. dpkg-reconfigure sırasında güvenlik güncellemelerini otomatik olarak indirip kurmayı seçmelisiniz. Genellikle bu adımı tamamladıktan sonra, bir systemd timer’ı ile bu güncellemelerin düzenli olarak çalıştığından emin olmak için /etc/apt/apt.conf.d/50unattended-upgrades dosyasını kontrol ederim. Burada, hangi tür güncellemelerin (security, proposed, updates) otomatik olarak ele alınacağını belirleyebilirsiniz. Ben sadece güvenlik güncellemelerini otomatik yapmayı tercih ederim, diğerleri için manuel kontrol sağlarım. Bu, stability ve security arasında bir trade-off kararıdır.
Adım 5: Fail2ban ile Brute-Force Koruması
SSH parolalarını kapatsak bile, SSH portumuza yapılan denemeler devam edecektir. Bu denemeler sunucu kaynaklarını tüketebilir ve log dosyalarını doldurabilir. fail2ban, bu tür kötü niyetli denemeleri tespit edip IP adreslerini geçici olarak yasaklayarak bu sorunu çözer. Kendi Android spam blocker uygulamamın backend’inde, fail2ban’in spam botlarını nasıl engellediğini bizzat deneyimledim.
fail2ban’i kurmak ve yapılandırmak oldukça basittir:
sudo apt install fail2ban -y
Kurulumdan sonra, fail2ban varsayılan olarak SSH için bir kuralı etkinleştirir. Kendi özel ayarlarınızı yapmak için /etc/fail2ban/jail.local dosyasını oluşturup düzenlemeniz gerekir. Bu dosya, /etc/fail2ban/jail.conf dosyasındaki varsayılan ayarları geçersiz kılar.
sudo vim /etc/fail2ban/jail.local
Örnek bir jail.local yapılandırması:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
Burada, bantime yasaklamanın ne kadar süreceğini (1 saat), findtime kaç başarısız denemenin ne kadar süre içinde gerçekleşmesi gerektiğini (10 dakika içinde), ve maxretry ise kaç başarısız denemeden sonra yasaklama yapılacağını (5 deneme) belirtir. Bu ayarlar, benim için yıllardır stabil ve etkili çalıştı. Daha sonra fail2ban servisini yeniden başlatın:
sudo systemctl restart fail2ban
fail2ban-client status sshd komutu ile yasaklanan IP adreslerini görebilirsiniz. Bu, bana hem proaktif bir güvenlik katmanı sağlıyor hem de log dosyalarımı gereksiz gürültüden arındırıyor.
Adım 6: Temel Denetim ve İzleme Ayarları
Bir sunucuyu güvende tutmanın son adımı, ne olduğunu bilmektir. Logları izlemek ve sistemdeki anormallikleri fark etmek, potansiyel güvenlik sorunlarını erkenden tespit etmenin anahtarıdır. İlk 45 dakika içinde, temel loglama ayarlarını kontrol eder ve auditd gibi araçların varlığını doğrularım.
Linux sistemlerde journald ve syslog servisleri, sistem olaylarını kaydeder. journalctl komutuyla logları kolayca inceleyebilirsiniz:
journalctl -u sshd -n 20 --since "1 hour ago"
journalctl -f # Gerçek zamanlı log takibi
Bu, özellikle SSH denemeleri veya diğer servis hatalarını hızlıca görmemi sağlar. Bir üretim ortamında, journald’nin rate limit özelliği sayesinde log fırtınalarının önüne geçtiğimi hatırlıyorum. Aksi takdirde diskler gereksiz yere dolarak sistemin performansını olumsuz etkileyebilirdi.
Auditd Kurulumu (İsteğe Bağlı ama Önemli)
Daha derinlemesine bir denetim için auditd kurmayı düşünürüm. Bu, özellikle dosya sistemi değişiklikleri veya yetkisiz erişim denemeleri gibi kritik olayları izlemek için güçlü bir araçtır. İlk 45 dakikada tüm kuralları ayarlamak zor olsa da, servisin çalışır durumda olduğundan emin olmak önemlidir.
sudo apt install auditd audispd-plugins -y # Debian/Ubuntu
# sudo yum install audit -y # CentOS/RHEL
sudo systemctl enable --now auditd
sudo systemctl status auditd
auditd ile belirli dosya veya dizinlerdeki değişiklikleri izleyen kurallar oluşturabilirsiniz. Örneğin, /etc dizinindeki değişiklikleri izlemek:
sudo auditctl -w /etc -p wa -k etc_changes
Bu kural, /etc dizinindeki yazma (write) veya öznitelik (attribute) değişikliklerini izler ve etc_changes anahtarı ile loglarda kolayca filtrelenebilir. Daha sonra ausearch -k etc_changes komutuyla bu logları sorgulayabilirim. Bu, özellikle birisinin sistem yapılandırmasını kurcalayıp kurcalamadığını kontrol etmek için çok değerlidir. Kendi sistemimde, sık sık auditd loglarını kontrol ederek beklenmedik değişiklikleri yakalarım.
Sonraki Adımlar ve Düşünceler
Bir sunucuyu ilk 45 dakikada güvence altına almak, bir başlangıç noktasıdır, bir son değil. Bu adımlar, sunucunuzu en temel saldırılara karşı korur ve size daha kapsamlı güvenlik önlemleri almak için zaman kazandırır. Ancak, güvenlik sürekli bir süreçtir.
Bu ilk adımlardan sonra, ben genellikle şunlara odaklanırım:
- SELinux/AppArmor Konfigürasyonu: Uygulamalarımı izole etmek ve potansiyel zararı sınırlamak için SELinux veya AppArmor profilleri oluştururum. Bu, özellikle üretim ortamlarında kritik bir adımdır ve uygulama bazında güvenlik sağlar.
- Daha Kapsamlı Firewall Kuralları: Uygulama katmanı firewall’ları (WAF) veya daha detaylı IP tabanlı kısıtlamalar eklerim.
- Log Yönetimi ve Merkezi İzleme: Birden fazla sunucum olduğunda logları merkezi bir sisteme toplar (örneğin ELK Stack veya Grafana Loki) ve anomali tespiti için alarmlar kurarım.
- Yedekleme Stratejisi: Düzenli ve güvenilir yedeklemeler, herhangi bir güvenlik ihlali veya sistem çökmesi durumunda veri kaybını önler. Kendi üretim ERP’sinde, günlük fiziksel replikasyon ve haftalık mantıksal yedeklemelerle bu riski minimize ettik.
Bu kontrol listesi, benim 20 yıllık saha tecrübelerimin damıtılmış halidir. Her yeni sunucuda bu adımları tekrar tekrar uygulayarak, birçok potansiyel sorunun önüne geçtiğimi gördüm. Bir sonraki yazıda, üretim ortamlarında kullandığım Docker Compose optimizasyonları ve disk yangınlarını nasıl önlediğimi anlatacağım.