Ubuntu VPS Güvenliği: Adım Adım Sunucu Sıkılaştırma Rehberi
Yeni açılmış bir VPS, internete bağlandığı ilk dakikadan itibaren otomatik tarama botlarının hedefindedir. Müdahale ettiğimiz vakalarda saldırıların büyük bölümü sofistike tekniklerle değil; parola ile açık bırakılmış SSH, güncellenmemiş paketler ve internete gereksiz yere açılmış servis portları üzerinden gerçekleşiyor. İyi haber şu: VPS güvenliği için atılması gereken temel adımlar bellidir, sıralıdır ve bir öğleden sonrada uygulanabilir.
Bu rehberde Ubuntu 22.04/24.04 üzerinde çalışan bir VPS'i sıfırdan sıkılaştırmayı adım adım anlatıyoruz. Komutların tamamını root ya da sudo yetkili bir kullanıcı ile çalıştırabilirsiniz. Sunucunuzun mevcut durumunu bilmiyorsanız, önce ücretsiz sunucu güvenlik kontrolü ile nereden başlamanız gerektiğini görebilirsiniz.
1. İlk Oturum: Güncelleme ve Yeni Kullanıcı
Sunucuya ilk bağlandığınızda yapılacak ilk iş paket listesini ve sistemi güncellemektir:
apt update && apt upgrade -y
Bu komut paket deposu listesini yeniler ve kurulu tüm paketleri en güncel sürüme çeker; bilinen açıkların çoğu bu adımla kapanır.
Root ile çalışmaya devam etmek yerine sudo yetkili ayrı bir kullanıcı oluşturun:
adduser yonetici
usermod -aG sudo yonetici
İlk komut yeni kullanıcıyı oluşturur, ikincisi bu kullanıcıya sudo grubunu ekleyerek yönetici yetkisi verir. Bundan sonraki tüm işlemleri bu kullanıcı ile yapacak, root hesabını tamamen kapatacağız.
2. SSH Anahtarı ile Giriş ve Root'un Kapatılması
Parola tabanlı SSH girişi, VPS'lere yönelik en yaygın saldırı yüzeyidir. Botlar gün boyu yaygın kullanıcı adı/parola kombinasyonlarını dener. Çözüm, parolayı devreden çıkarıp yalnızca SSH anahtarı ile giriş kabul etmektir.
Önce kendi bilgisayarınızda (sunucuda değil) bir anahtar çifti üretin:
ssh-keygen -t ed25519 -C "yonetici@vps"
Bu komut modern ve hızlı ed25519 algoritmasıyla bir özel/açık anahtar çifti oluşturur. Ardından açık anahtarı sunucuya kopyalayın:
ssh-copy-id yonetici@SUNUCU_IP
Komut, açık anahtarınızı sunucudaki ~/.ssh/authorized_keys dosyasına ekler. Anahtarla girebildiğinizi ayrı bir terminalde test ettikten sonra SSH yapılandırmasını sıkılaştırın:
sudo nano /etc/ssh/sshd_config
Dosyada şu satırları ayarlayın:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
Bu ayarlar sırasıyla root girişini kapatır, parola ile girişi tamamen devre dışı bırakır, anahtar tabanlı girişi zorunlu kılar ve oturum başına deneme sayısını sınırlar. Ubuntu'da /etc/ssh/sshd_config.d/ altındaki ek dosyaların bu ayarları ezebileceğini unutmayın; 50-cloud-init.conf gibi dosyalarda PasswordAuthentication yes satırı varsa onu da düzeltin. Sonra servisi yeniden başlatın:
sudo systemctl restart ssh
Mevcut oturumunuzu kapatmadan yeni bir terminalde anahtarla giriş yapabildiğinizi mutlaka doğrulayın; aksi hâlde kendinizi sunucudan kilitleyebilirsiniz.
SSH portunu değiştirmek (örneğin 22 yerine 10022) zorunlu bir güvenlik önlemi değildir; ancak log gürültüsünü ve otomatik bot trafiğini ciddi biçimde azalttığı için önerdiğimiz bir adımdır. Port değiştirirseniz güvenlik duvarı kuralınızı da buna göre açmayı unutmayın.
3. UFW ile Güvenlik Duvarı
Varsayılan kural basittir: dışarıya her şey kapalı, yalnızca gerçekten sunduğunuz servisler açık. Ubuntu'nun UFW aracı bunu birkaç komutla sağlar:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
İlk iki komut varsayılan politikayı belirler: gelen tüm trafik reddedilir, giden trafiğe izin verilir. Sonraki üç komut SSH, HTTP ve HTTPS portlarını açar; ufw enable ise duvarı etkinleştirir. SSH portunu değiştirdiyseniz 22 yerine kendi portunuzu yazın.
Durumu her zaman şu komutla kontrol edebilirsiniz:
sudo ufw status verbose
Kritik nokta: veritabanı (3306, 5432), Redis (6379), Node.js uygulama portları (3000, 3300 vb.) gibi servislerin UFW'de açık olmaması gerekir. Müdahale ettiğimiz vakalarda cryptominer bulaşmalarının önemli bir kısmı, internete gereksiz yere açılmış bir uygulama portu üzerinden gerçekleşmişti; bu senaryonun detaylarını sitem hacklendi, ne yapmalıyım yazımızda anlattık.
4. fail2ban ile Kaba Kuvvet Koruması
UFW portları yönetir; fail2ban ise açık bıraktığınız portlara yönelik deneme-yanılma saldırılarını engeller. Log dosyalarını izler, art arda başarısız giriş yapan IP'leri belirlediğiniz süre boyunca yasaklar:
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
İlk komut paketi kurar, ikincisi servisi hem hemen başlatır hem de açılışta otomatik başlamasını sağlar. Varsayılan ayarları ezmek için /etc/fail2ban/jail.local dosyası oluşturun:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
Bu yapılandırma, 10 dakika içinde 5 başarısız deneme yapan IP'yi 1 saat yasaklar ve SSH jail'ini etkinleştirir. Yasaklanan IP'leri görmek için:
sudo fail2ban-client status sshd
fail2ban'ın jail mantığını, parametre ayarlarını ve sık yapılan hataları ayrı bir rehberde detaylandırdık: fail2ban kurulumu ve yapılandırması.
5. Otomatik Güvenlik Güncellemeleri
Güvenlik yamalarını elle takip etmek sürdürülebilir değildir. Ubuntu'nun unattended-upgrades paketi güvenlik güncellemelerini otomatik uygular:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
İkinci komut, açılan ekranda "Yes" seçtiğinizde otomatik güncellemeleri etkinleştiren yapılandırmayı yazar. Ayarların aktif olduğunu doğrulamak için:
cat /etc/apt/apt.conf.d/20auto-upgrades
Dosyada Unattended-Upgrade "1" satırını görüyorsanız güvenlik yamaları artık otomatik iniyor demektir. Çekirdek güncellemeleri sonrası yeniden başlatma gerektiren durumları /var/run/reboot-required dosyasından takip edebilir, bakım pencerenizde planlı reboot yapabilirsiniz.
6. Uygulamaları Localhost'a Alın, Önüne Reverse Proxy Koyun
En sık gördüğümüz mimari hata: Node.js, Python veya benzeri bir uygulamanın 0.0.0.0:3000 gibi bir adreste doğrudan internete açılması. Bu durumda uygulama, web sunucusunun ve WAF katmanının tüm korumalarını baypas ederek dış dünyaya çıplak şekilde sunulmuş olur.
Doğru mimari şudur: uygulama yalnızca 127.0.0.1 üzerinde dinler, internete ise sadece Nginx veya Apache gibi bir reverse proxy açılır.
# Yanlış: her arayüzden erişilebilir
node server.js --host 0.0.0.0 --port 3000
# Doğru: yalnızca localhost dinler
node server.js --host 127.0.0.1 --port 3000
Nginx tarafında minimal bir reverse proxy bloğu:
server {
listen 443 ssl;
server_name ornek.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Bu yapılandırma, gelen HTTPS trafiğini localhost'taki uygulamaya iletir; uygulamanın kendisi dışarıdan hiçbir zaman doğrudan erişilebilir olmaz. Hangi servislerin hangi arayüzü dinlediğini görmek için:
sudo ss -tlnp
Çıktıda 0.0.0.0: veya [::]: ile başlayan ve 22/80/443 dışında kalan her satır sorgulanmalıdır. Bu tek komut, sunucunuzun gerçek saldırı yüzeyini gösterir. Sunucunuzda hangi portların gereksiz açık olduğundan emin değilseniz VPS güvenliği hizmetimiz kapsamında bu analizi sizin için yapıyoruz.
7. Yedekleme: Sunucunun Dışına ve Test Edilmiş
Güvenlik önlemleri riski azaltır ama sıfırlamaz. Ele geçirilmiş bir sunucuda en değerli varlığınız temiz ve güncel bir yedektir. Üç kural:
| Kural | Neden |
|---|---|
| Yedek sunucunun dışında dursun | Sunucu ele geçirilirse yereldeki yedek de ele geçirilmiş sayılır |
| Otomatik ve zamanlanmış olsun | Elle alınan yedek unutulur |
| Düzenli geri dönüş testi yapılsın | Açılmayan yedek, yedek değildir |
Basit bir örnek: veritabanı ve web dizinini arşivleyip başka bir konuma gönderen günlük cron işi:
#!/bin/bash
tar czf /tmp/site-$(date +%F).tar.gz /var/www/site
mysqldump --all-databases | gzip > /tmp/db-$(date +%F).sql.gz
rsync -a /tmp/*-$(date +%F)* yedek@yedeksunucu:/backups/
Betik web dizinini ve tüm veritabanlarını sıkıştırır, ardından rsync ile harici yedek sunucusuna aktarır. Object storage (S3 uyumlu) hedefler için rclone da iyi bir alternatiftir. Kritik nokta yöntem değil, disiplindir: yedeğin çalıştığını ancak geri döndüğünüzde anlarsınız, o gün ilk kez denemeyin.
8. İzleme: Sorunu Müşterinizden Önce Görün
Sıkılaştırılmış bir sunucu bile izlenmezse, bir sorun çıktığında bunu genellikle en kötü yoldan öğrenirsiniz. Asgari izleme seti şunları kapsamalı:
- Kaynak takibi: CPU, RAM, disk doluluğu. Açıklanamayan sürekli yüksek CPU, çoğu zaman bir cryptominer belirtisidir; bu senaryoyu sunucuda yüksek CPU ve cryptominer temizliği yazısında ayrıntılı işledik.
- Servis ve site erişilebilirliği: HTTP durum kodu ve sertifika süresi kontrolü yapan harici bir uptime izleyici.
- Giriş denetimi: Başarılı SSH girişlerinin takibi.
lastkomutu son oturumları,sudo lastbbaşarısız denemeleri listeler.
Anlık durum için birkaç temel komut:
htop # işlemci ve bellek kullanımını canlı gösterir
df -h # disk doluluk oranlarını listeler
sudo ss -tlnp # dinleyen portları ve sahibi süreçleri gösterir
journalctl -p err -S today # bugünkü hata seviyesindeki logları döker
Bu kontrolleri düzenli yapacak vaktiniz yoksa, bakım ve izleme hizmetimiz kapsamında sunucularınızı 7/24 izliyor, anormallikte sizden önce müdahale ediyoruz.
9. Gereksiz Servisleri ve Paketleri Kaldırın
Her kurulu servis potansiyel bir saldırı yüzeyidir. Kullanmadığınız bir FTP sunucusu, unutulmuş bir mail servisi ya da denemek için kurulup bırakılan bir veritabanı, sizin işinize yaramazken saldırgana kapı olabilir. Önce neyin çalıştığını görün:
systemctl list-units --type=service --state=running
Komut, o an çalışan tüm servisleri listeler. Bu listedeki her satır için "buna gerçekten ihtiyacım var mı?" sorusunu sorun. Gereksiz bulduğunuz servisi durdurup devre dışı bırakın:
sudo systemctl disable --now servis-adi
sudo apt purge paket-adi -y
İlk komut servisi hem durdurur hem açılışta başlamasını engeller; ikincisi paketi yapılandırma dosyalarıyla birlikte kaldırır. Tipik adaylar: kullanılmayan vsftpd, telnet, rpcbind, denemelik kurulmuş veritabanları ve artık ihtiyaç duyulmayan dil çalışma ortamları. Kural basit: kurulu olmayan yazılımın açığı da olmaz.
Aynı mantık zamanlanmış görevler için de geçerli. sudo ls /etc/cron.d/ /etc/cron.daily/ çıktısındaki her girdinin ne yaptığını bildiğinizden emin olun; sahiplenilmemiş cron görevleri hem güvenlik hem kararlılık riskidir.
Sıkılaştırma Kontrol Listesi
Tüm adımları özetleyen hızlı liste:
- Sistem güncellendi,
unattended-upgradesaktif - Sudo yetkili kullanıcı oluşturuldu
- SSH yalnızca anahtarla, root ve parola girişi kapalı
- UFW aktif; yalnızca SSH, 80 ve 443 açık
- fail2ban kurulu, sshd jail'i etkin
- Uygulamalar 127.0.0.1'de, önlerinde reverse proxy var
- Yedekler sunucu dışında ve geri dönüş testi yapılmış
- Kaynak, uptime ve giriş izlemesi çalışıyor
- Gereksiz servisler ve paketler kaldırıldı
Sıralamanın da bir mantığı var: önce kimlik (SSH), sonra sınır (UFW ve fail2ban), sonra iç mimari (localhost + reverse proxy), en sonda süreklilik (yedek, izleme, güncelleme). Adımları bu sırayla uygularsanız her katman bir sonrakini anlamlı kılar; örneğin fail2ban, parola girişi zaten kapalı bir SSH'ın üzerinde çok daha az iş yapar ama yine de log gürültüsünü keser ve diğer servisleri korur.
Bu listeyi eksiksiz uygulayan bir Ubuntu VPS, otomatik saldırıların ezici çoğunluğuna karşı korunmuş olur. Daha derin bir sıkılaştırma — kernel parametreleri, AppArmor profilleri, denetim logları (auditd), dosya bütünlük kontrolü — isteyen kurumsal senaryolar için Linux sunucu sıkılaştırma hizmetimize göz atabilirsiniz. Sunucunuz şu anda saldırı altındaysa ya da ele geçirildiğinden şüpheleniyorsanız bu rehberi değil, acil müdahale sayfamızı kullanın.
Sık Sorulan Sorular
SSH portunu değiştirmek tek başına yeterli mi?
Hayır. Port değişikliği yalnızca otomatik bot gürültüsünü azaltır; hedefli bir tarama farklı portlardaki SSH'ı saniyeler içinde bulur. Asıl koruma anahtar tabanlı giriş, kapalı root hesabı ve fail2ban'dır. Port değişikliğini bu önlemlerin üzerine bir katman olarak düşünün.
Sağlayıcımın panelindeki firewall varken UFW kurmama gerek var mı?
İkisini birlikte kullanmanızı öneriyoruz. Sağlayıcı firewall'u sunucuya trafik ulaşmadan filtreler, UFW ise sunucu içinde ikinci bir savunma hattı oluşturur. Panelde yanlışlıkla açılan bir kural ya da sonradan kurulan bir servisin açtığı port, UFW sayesinde yine kapalı kalır.
VPS'imin zaten ele geçirilip geçirilmediğini nasıl anlarım?
Hızlı kontroller: sudo ss -tlnp ile tanımadığınız dinleyen portlar, crontab -l ve /etc/cron.* dizinlerinde bilinmeyen görevler, top çıktısında sürekli yüksek CPU tüketen tanımsız süreçler, ~/.ssh/authorized_keys içinde size ait olmayan anahtarlar. Şüpheli bulgu varsa sıkılaştırmadan önce temizlik gerekir; kirli bir sistemin üzerine alınan önlem güven vermez.
Bu adımları uyguladım, sunucum artık tamamen güvenli mi?
"Tamamen güvenli" sunucu yoktur; bu rehber saldırı yüzeyini asgariye indirir ve otomatik saldırıları büyük oranda etkisiz kılar. Güvenlik süreklilik ister: güncellemelerin takibi, logların izlenmesi ve uygulama katmanındaki (CMS, framework, eklentiler) açıkların yönetimi devam eden işlerdir.
Sunucunuzun bu listeye göre nerede durduğunu merak ediyorsanız, ücretsiz sunucu güvenlik kontrolü ile mevcut açıklarınızı raporluyoruz. WhatsApp hattımız 7/24 açık; sıkılaştırmayı sizin yerinize yapmamızı isterseniz VPS güvenliği sayfasından bize ulaşabilirsiniz.