📌 Hızlı Özet & Temel Çıkarım:
Ucuz bir Ubuntu VPS’i ayağa kaldırıp root + parola ile bırakmak, internetteki botların birkaç saat içinde deneme listesine girmesi demektir. Bu rehber; erişimizi kaybetmeden ed25519 anahtar, sshd sıkılaştırma, UFW ve Fail2ban adımlarını sırayla uygular. Hedef kitle: ders projesi, küçük SaaS, robotik yer istasyonu backend’i — enterprise SIEM değil.


Altın kural: ikinci oturum açık kalsın

Sıkılaştırma sırasında en pahalı hata, PasswordAuthentication no yazıp kendi anahtarınızı sunucuya koymadan sshd restart etmektir. Prosedür:

  1. Mevcut SSH oturumunu kapatmayın.
  2. İkinci bir terminalde yeni ayarlarla bağlanmayı deneyin.
  3. İkinci oturum başarılıysa ancak o zaman birinciden çıkın.

Cloud panel / VNC konsolu olan sağlayıcılarda (Hetzner, DigitalOcean, AWS) acil kurtarma yolu bilin; yoksa adımları daha da yavaş uygulayın.


1) Kullanıcı ve anahtar

Yerelde:

ssh-keygen -t ed25519 -a 100 -C "abdullah@pusula-ops"
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@SUNUCU_IP

Sunucuda deploy (veya kendi sudo kullanıcınız) oluşturduysanız:

adduser deploy
usermod -aG sudo deploy
mkdir -p /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
# authorized_keys içine public key
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh

Windows istemcideseniz OpenSSH ile aynı ed25519 anahtarı kullanın; eski RSA 1024 / parola dosyalarını yeni sunucuya taşımayın.


2) sshd_config: önce drop-in, sonra reload

Ubuntu 22.04/24.04’te tüm dosyayı ezmek yerine:

/etc/ssh/sshd_config.d/99-hardening.conf

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
X11Forwarding no
AllowTcpForwarding no
PermitTunnel no
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers deploy
# İsteğe bağlı: Port 2222

Kontrol ve uygula:

sudo sshd -t
sudo systemctl reload ssh
# veya: sudo systemctl reload sshd

AllowTcpForwarding no yer istasyonu tüneli kullanıyorsanız yes bırakın veya belirli kullanıcılara Match bloğu açın. Kör kopyalama, kendi reverse tunnel’ınızı kırar.

AllowUsers listesinde CI deploy kullanıcısı varsa ekleyin; unutursanız pipeline SSH’de kalır.


3) UFW: önce allow, sonra enable

sudo apt update
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
# Port değiştirdiyseniz:
# sudo ufw allow 2222/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

SSH portunu değiştirip UFW’de hâlâ 22 bırakmak klasik self-lockout’tur. Sırayı unutmayın: UFW’de yeni portu aç → sshd portunu değiştir → reload → yeni porttan bağlan → eski kuralı sil.

WireGuard veya Cloudflare Tunnel kullanıyorsanız 80/443 dışında neredeyse hiçbir şeyi dünyaya açmayabilirsiniz; o mimari ayrı bir yazının konusu.


4) Fail2ban: gürültüyü kes

sudo apt install -y fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

/etc/fail2ban/jail.d/sshd.local:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 4
findtime = 10m
bantime = 1h
backend = systemd
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Ofis / yurt NAT’ı arkasından sık yanlış parola deniyorsanız (hâlâ parola açıksa) kendi IP’nizi banlarsınız. Anahtar zorunluysa bu risk düşer; yine de ignoreip ile sabit çıkış IP’nizi ekleyebilirsiniz:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.50

5) Güncelleme ve otomatik güvenlik yamaları

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

/etc/apt/apt.conf.d/50unattended-upgrades içinde güvenlik kökenlerinin açık olduğundan emin olun. Kernel güncellemesi reboot ister; ayda bir bakım penceresi planlayın. “Hiç reboot yok” edge VPS’lerde technical debt biriktirir.


6) Doğrulama checklist (15 dakika)

Başka bir ağdan (telefon hotspot):

ssh -v deploy@SUNUCU_IP

Beklenenler:

  • root@ ile giriş reddedilir.
  • Parola sorulmaz (yanlış yapılandırmada password prompt = fail).
  • sudo ufw status yalnızca ihtiyacınız olan portlar.
  • sudo fail2ban-client status sshd jail aktif.
  • grep -R "" /etc/ssh/sshd_config* içinde PasswordAuthentication yes kalmamış.

Bonus: ssh-audit ile algoritma setine bakın; zayıf host key / cipher varsa temizleyin. İlk kurulumda ed25519 host key üretmek çoğu VPS imajında zaten vardır.


Sık yapılan yanlışlar (kısaca)

  • Sadece port değiştirmek: Botlar tüm portları tarar; anahtar zorunluluğu olmadan anlamı sınırlıdır.
  • fail2ban kurup jail enable etmemek: Paket yüklü ≠ koruma aktif.
  • authorized_keys izinlerini 777 yapmak: sshd çoğu zaman sessizce key’i ignore eder; “anahtar çalışmıyor” sanırsınız.
  • Tek admin anahtarı, yedek yok: Laptop gidince sunucu kalır. İkinci ed25519’u parola korumalı USB / password manager’da tutun.
  • FTP / eski panel portlarını açık unutmak: SSH’yi kilitleyip 21’i açık bırakmak.

Küçük takım için ek pratikler

  • Deploy için ayrı Linux kullanıcısı; günlük iş için ayrı.
  • Ansible veya tek bir harden.sh ile yeniden kurulabilir hale getirin (VPS recreate sık olur).
  • Cloudflare Proxy arkasındaki origin IP’yi sızdırmayın; SSH’yi mümkünse yalnızca kendi IP’nize veya Tailscale/WireGuard’a açın.
  • Last-Session / runbook’a kurtarma adımlarını yazın: panel konsolu, ek anahtar yolu, UFW disable komutu.

Log’a bakmayı alışkanlık yapın

Sıkılaştırma bir kerelik checklist değildir. Haftada beş dakika:

sudo journalctl -u ssh -S today --no-pager | tail
sudo fail2ban-client status sshd
last -a | head

Anlamlı sinyaller: bilmediğiniz ülkeden başarılı login, peş peşe ban sonrası aynı subnet’ten devam, Accepted publickey satırında tanımadığınız key comment. Agent forwarding (ssh -A) açık makineden jump yapıyorsanız, compromised laptop’un başka sunuculara sıçrama riskini bilin; günlük iş için forwarding kapalı kalsın.

authorized_keys içine from="203.0.113.0/24" veya command= kısıtları eklemek ileri seviye ama etkili bir katmandır. CI deploy anahtarına yalnızca git pull && systemctl reload ... benzeri tek komut vermek, o anahtarın çalınması halinde hasarı sınırlar. Her anahtara full shell vermek “kolay”dır; kolaylık burada maliyetli borçtur.


Zaman senkronu ve hostname

Fail2ban ve audit için saat doğru olmalıdır. timedatectl ile NTP açık mı bakın; kaymış saat, log korelasyonunu ve TLS sertifika kontrollerini bozar. Hostname’i vps-1 gibi jenerik bırakmak birden fazla sunucuda log karışıklığı yaratır — usv-grafana-fra gibi işlev + bölge taşıyan isimler runbook’u sadeleştirir. Motd’ye “bu makine X servisini taşır, acil: panel URL” yazmak da gece yarısı yanlış sunucuya bağlanma riskini azaltır; özellikle takımda herkesin aynı ssh config Host alias’larını kullanmadığı dönemlerde.


Ne zaman yeterli, ne zaman üstüne çıkmalı?

Tek VPS + blog / API + 2–3 kişi: bu rehber + düzenli update yeterlidir.
Birden fazla sunucu, müşteri verisi, ödeme: merkezi identity (SSO), bastion, audit log ve secret manager ekleyin. SSH hardening tabanı aynı kalır; üzerine Zero Trust (Cloudflare Access vb.) binersiniz.


Son söz

SSH sıkılaştırma tiyatro değil, bot gürültüsünü ve kaba kuvveti kesen temel hijyendir. Sıra önemli: anahtar çalışıyor → root/parola kapalı → firewall → fail2ban → unattended upgrades. Adımları atlayıp “port 2222 yaptım güvenliyim” demek, telemetride checksum kontrol etmeden “paket geldi” demeye benzer. VPS’iniz öğrenci bütçesinde olsa da internet aynı internettir.