Sunucuya ilk kez erişildiğinde genellikle root kullanıcı ile giriş yapılır. Ancak güvenlik ve operasyonel sürdürülebilirlik açısından, root kullanıcısının günlük işlemlerde doğrudan kullanılması önerilmez. Bu nedenle ilk adım olarak, yetkilendirilmiş ayrı bir kullanıcı oluşturulur ve yönetim yetkileri bu kullanıcıya devredilir.
Yüklenecek yazılımların en güncel adreslerini ve sürümlerini kontrol eder. Sunucunun hangi yazılımın nerede olduğunu bilmesini sağlar.
sudo apt update
sudo apt upgrade -yRoot olarak sunucuya giriş yaptıktan sonra, aşağıdaki komut ile yeni bir kullanıcı oluşturulur. Root kullanıcısını izole ederek, sistemde yapılacak işlemler için daha güvenli ve kontrollü bir kullanıcı alanı oluşturmak.
sudo adduser masterOluşturulan kullanıcının sistem üzerinde yönetimsel işlemler yapabilmesi için sudo yetkisi verilmesi gerekir. Bu işlem, kullanıcının root yetkisi gerektiren komutları kontrollü şekilde çalıştırabilmesini sağlar.
usermod -aG sudo masterBu işlemler kendi bilgisayarının terminalinde gerçekleştirilir. Amaç, sunucuya parola yerine SSH anahtarı ile güvenli erişim sağlamaktır.
Bu komut ile sunucuya bağlanmak için kullanılacak bir SSH anahtarı oluşturulur. Oluşturulan anahtar, kullanıcıya özel dijital bir kimlik görevi görür ve parola kullanımını ortadan kaldırır.
-f parametresi ile anahtara özel bir isim verilirssh-keygen -t ed25519 -C "example@gmail.com" -f ~/.ssh/special_vps_keyOluşturulan public anahtar bu komut ile sunucuya aktarılır. Bu işlem sonrasında sunucu, ilgili anahtarı tanır ve bu anahtarla yapılan SSH bağlantılarına izin verir.
authorized_keys dosyasına eklenirssh-copy-id -i ~/.ssh/special_vps_key.pub master@111.111.111.111Bu dosya, SSH bağlantıları için istemci tarafında kullanılan yapılandırma dosyasıdır. Tanımlanan her Host girdisi, bir sunucuya ait bağlantı ayarlarını içerir.
nano ~/.ssh/configBu yapılandırma ile sunucuya kısa bir isim atanmış olur. Artık terminalde yalnızca ssh myserver komutu kullanılarak bağlantı sağlanabilir.
Host myserver sunucuya verilen kısa isimdirHostName sunucunun IP adresini belirtirUser bağlantı kurulacak kullanıcıyı tanımlarIdentityFile kullanılacak SSH anahtarının yolunu belirtirAddKeysToAgent yes anahtarın SSH agent’a eklenmesini sağlarUseKeychain yes anahtar parolasının macOS Keychain’de saklanmasını sağlarHost myserver
HostName 111.111.111.111
User master
IdentityFile ~/.ssh/myserver_vps_key
AddKeysToAgent yes
UseKeychain yesBu aşama, sunucu güvenliğinin en kritik adımıdır. İşlemler, sunucuya SSH anahtarı ile giriş yapıldıktan sonra sunucu içerisinde gerçekleştirilir. Yapılacak hatalar sunucuya erişimi tamamen engelleyebileceği için adımlar dikkatle uygulanmalıdır.
Bu dosya, sunucunun dış dünyaya açılan kapısı olan SSH servisinin ana yapılandırma dosyasıdır. Burada yapılan değişiklikler, kimlerin ve hangi yöntemlerle sunucuya bağlanabileceğini belirler. Aşağıdaki kısımları bulun ve düzenleyin. Bu ayarlar sayesinde brute-force (şifre deneme) saldırıları etkisiz hale getirilmiş olur.
PermitRootLogin no Root kullanıcısının dışarıdan doğrudan SSH ile giriş yapmasını tamamen engeller.PasswordAuthentication no Parola ile SSH girişini kapatır. Artık sadece yetkilendirilmiş SSH anahtarına sahip cihazlar sunucuya erişebilir.sudo nano /etc/ssh/sshd_configYapılan değişikliklerin aktif hale gelmesi için SSH servisi yeniden başlatılır. Bu işlemden sonra sunucu, yalnızca SSH anahtarı ile bağlantı kabul eder.
sudo systemctl restart sshBu aşamada sunucunun dış dünyaya açık olan ağ kapıları (portlar) kontrol altına alınır. UFW (Uncomplicated Firewall), yalnızca izin verilen servislerin sunucuya erişebilmesini sağlar ve yetkisiz tüm bağlantıları engeller.
Sunucuya uzaktan erişim sağlayabilmek için SSH portunun açık olması gerekir. Güvenlik duvarı aktif edilmeden önce bu kural mutlaka eklenmelidir. Aksi halde sunucuya erişim tamamen kaybedilebilir.
sudo ufw allow sshBu kurallar, web sitelerinin 80 (HTTP) ve 443 (HTTPS) portları üzerinden dış dünyaya yayın yapabilmesini sağlar. Ziyaretçilerin siteye erişebilmesi için bu portların açık olması zorunludur.
sudo ufw allow http
sudo ufw allow httpsTanımlanan tüm kurallar yürürlüğe girer ve güvenlik duvarı aktif hale gelir. Bu aşamadan sonra sunucu, yalnızca izin verilen portlardan gelen bağlantılara cevap verir.
sudo ufw enableBu komut ile güvenlik duvarının aktif olup olmadığı ve hangi portların açık olduğu kontrol edilir. Durumun Active olarak görünmesi, yapılandırmanın başarılı olduğunu gösterir.
sudo ufw statusBu aşamada sunucuya web servislerini yayınlayacak olan Nginx kurulumu gerçekleştirilir. Kurulum öncesinde paket listesi güncellenir, ardından Nginx yüklenir ve gerekli durumlarda sistem yeniden başlatılır.
Dünyanın en hızlı web sunucu yazılımlarından biri olan Nginx’i kurar. -y takısı kurulum sırasında çıkan onay sorularına otomatik olarak “evet” yanıtını verir.
sudo apt install nginx -yÖzellikle Pending kernel upgrade gibi kritik sistem güncellemeleri yapıldığında, sunucunun en yeni çekirdek sürümüyle açılması için gereklidir. Bu komutu yazınca bağlantın kopar; yaklaşık 1 dakika bekledikten sonra ssh myserver komutu ile tekrar bağlanabilirsin.
sudo rebootNginx’in hatasız bir şekilde active (running) durumda olduğunu doğrular. Eğer her şey yolundaysa, sunucu IP adresini tarayıcıya yazdığında Nginx’in varsayılan karşılama sayfası görüntülenir.
sudo systemctl status nginxBu aşamada Nginx ile birlikte gelen varsayılan (default) yapılandırmalar ve örnek dosyalar sistemden kaldırılır. Amaç, sunucuda yalnızca bizim tanımlayacağımız kuralların ve projelerin çalışmasını sağlamaktır.
Nginx’in kurulumla birlikte gelen varsayılan site ayarlarını hem arşiv klasöründen hem de aktif yayın dizininden kaldırır. Bu sayede sunucunun eski veya gereksiz kurallarla çakışmasının önüne geçilir.
sudo rm /etc/nginx/sites-available/default
sudo rm /etc/nginx/sites-enabled/defaultNginx ile gelen Welcome to nginx sayfasını içeren web dizinini tamamen siler. Artık sunucuda otomatik yayınlanan hiçbir varsayılan içerik kalmaz.
sudo rm -rf /var/www/htmlYapılan tüm temizlik işlemlerinin Nginx tarafından uygulanabilmesi için servis yeniden başlatılır. Bu işlemden sonra Nginx yalnızca bizim tanımlayacağımız yeni site konfigürasyonlarını bekler durumda olur.
sudo systemctl restart nginxBu aşamada sunucuda çalışacak tüm Frontend ve Backend projeleri için merkezi, düzenli ve güvenli bir çalışma alanı oluşturulur. Amaç; projeleri sistem dosyalarından ayırmak, yetki karmaşasını önlemek ve uzun vadede sürdürülebilir bir sunucu yapısı kurmaktır.
Tüm projelerin yer alacağı ana klasör güvenli bölge olan /var/www altında hiyerarşik şekilde oluşturulur. Bu dizin, sunucudaki tüm uygulamaların merkezi çalışma alanı olacaktır.
sudo mkdir -p /var/www/appsOluşturulan proje dizininin sahipliği master kullanıcısına devredilir. Böylece npm install , git clone veya dosya düzenleme gibi işlemler sırasında sürekli sudo kullanma ihtiyacı ortadan kalkar.
sudo chown -R master:master /var/www/appsBundan sonraki tüm Frontend ve Backend projeler bu dizin altında, kendilerine ait alt klasörler içerisinde konumlandırılır. Sunucu üzerinde yapılan tüm geliştirme ve dağıtım işlemleri bu çalışma alanı üzerinden yürütülür.
cd /var/www/appsBu aşamada sunucu üzerinde yapılacak tüm kod değişikliklerinin kime ait olduğunun net bir şekilde kayıt altına alınması sağlanır. Git konfigürasyonu, özellikle GitHub / GitLab entegrasyonlarında logların temiz ve profesyonel görünmesi açısından kritiktir.
Sistemde Git’in yüklü olup olmadığını kontrol eder. Ubuntu 24.04 ile genellikle varsayılan olarak gelir, ancak kontrol etmek en güvenli yaklaşımdır.
git --versionSunucu üzerinde yapılacak tüm commit işlemlerinin senin adınla imzalanmasını sağlar.
git config --global user.name "Sezer Gec"Git kayıtlarında (logs) görünecek olan resmi e-posta adresini ayarlar. Bu bilgi GitHub / GitLab gibi platformlarla birebir eşleşmelidir.
git config --global user.email "example@gmail.com"Bu aşamada Node.js sürümlerini profesyonel şekilde yönetmek için NVM kurulumu yapılır. Ardından Node.js v24 kurulup, uygulamaların arka planda kararlı çalışmasını sağlayacak PM2 yapılandırılır.
Node.js sürümlerini yönetmek için önerilen en sağlıklı yöntemdir. Resmi NVM projesinin önerdiği betik kullanılır.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bashTerminali kapatıp açmaya gerek kalmadan NVM komutlarını mevcut oturumda kullanılabilir hale getirir.
. "$HOME/.nvm/nvm.sh"Güncel ana sürüm olan Node.js v24.x ve beraberinde gelen modern npm v11.x sisteme dahil edilir.
nvm install 24
node -v
npm -vNode.js uygulamalarını arka planda, otomatik yeniden başlatma ve loglama özellikleriyle yöneten süreç yöneticisidir. NVM kullanıldığı için sudo gerekmez.
npm install -g pm2Sunucu her yeniden başladığında PM2 süreçlerinin otomatik ayağa kalkması için işletim sistemine gerekli yetki tanımlanır. Komut sonrası terminalin verdiği sudo env PATH=... ile başlayan satır çalıştırılır.
pm2 startupBu komut, npm start ile uygulamanı PM2 altında çalıştırır, example-project ismiyle listede görünmesini sağlar ve uygulamanın arka planda sürekli çalışmasını yönetir. pm2 save ile mevcut süreçler kaydedilerek sunucu yeniden başlasa bile otomatik başlatılmaları sağlanır.
pm2 start npm --name "example-project" -- start
pm2 saveBu aşamada Nginx üzerinde uygulamaya özel bir host (server block) tanımlanır. Amaç, dış dünyadan gelen HTTP isteklerini doğrudan backend uygulamanın portuna açmak yerine, Nginx üzerinden güvenli ve kontrollü şekilde yönlendirmektir. Bu yapı production ortamları için temel bir gerekliliktir.
Nginx’in yapılandırma şablonlarının bulunduğu sites-available dizininde, sunucuya gelen tanınmayan domain isteklerini sessizce kapatacak bir dosya oluşturulur. Bu dosya, bilinmeyen veya hatalı domainlerden gelen tüm istekleri yakalayarak güvenliği artırır.
sudo nano /etc/nginx/sites-available/000-catch-allBu yapılandırma ile Nginx, default server olarak çalışır ve IP veya tanınmayan domainlerden gelen HTTP (Port 80) isteklerini sessizce kapatır. Bu sayede uygulaman yalnızca kendi domainin üzerinden erişilebilir olur.
server {
listen 80 default_server;
server_name _;
return 444;
}Oluşturulan konfigürasyon dosyası,sites-enabled dizinine sembolik link ile bağlanır. Nginx yalnızca bu dizindeki dosyaları aktif olarak çalıştırır. Bu yaklaşım, konfigürasyonu silmeden hızlıca yayından kaldırabilmeyi sağlar.
sudo ln -s /etc/nginx/sites-available/000-catch-all /etc/nginx/sites-enabled/Nginx’in yapılandırma şablonlarının bulunduğu sites-available dizininde projeye özel bir dosya oluşturulur. Bu dosya, ilgili domain veya servis için tüm davranışların tanımlandığı ana merkezdir.
sudo nano /etc/nginx/sites-available/example-siteBu yapılandırma ile Nginx, dışarıdan gelen HTTP (Port 80) isteklerini, arka planda çalışan Node.js uygulamasına (Port 3000) yönlendirir.
server {
listen 80;
server_name example.com;
}Oluşturulan konfigürasyon dosyası,sites-enabled dizinine sembolik link ile bağlanır. Nginx yalnızca bu dizindeki dosyaları aktif olarak çalıştırır. Bu yaklaşım, konfigürasyonu silmeden hızlıca yayından kaldırabilmeyi sağlar.
sudo ln -s /etc/nginx/sites-available/example-site /etc/nginx/sites-enabled/Bu yapı, tüm uygulamalarında kullanılacak global proxy ve güvenlik ayarlarını içerir. Klasör oluşturularak merkezi bir config dosyası hazırlanır ve tüm Nginx hostlarında include edilerek kullanılabilir. Bu sayede uygulaman HTTP üzerinden çalışsa bile HTTPS yönlendirmesi, proxy ayarları ve güvenlik header’ları otomatik uygulanır.
sudo mkdir -p /etc/nginx/config
sudo nano /etc/nginx/config/proxy_settings.confOluşturulan proxy_settings.conf dosyası, uygulamalarında kullanılacak tüm global proxy ve güvenlik ayarlarını içerir. Bu dosya sayesinde uygulaman HTTPS üzerinden güvenli bir şekilde çalışır, HTTP istekleri otomatik olarak yönlendirilir ve SSL ile proxy trafiği merkezi olarak yönetilir.
proxy_http_version 1.1;
# Header ayarları
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Origin $http_origin;
proxy_set_header Content-Type $content_type;
# Cache ve güvenlik
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
# Ek güvenlik header'ları
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;Yapılandırma dosyasında yazım veya sözdizimi hatası olup olmadığı nginx -t komutu ile kontrol edilir. Test başarılıysa Nginx servisi yeniden başlatılarak yeni ayarlar aktif hale getirilir.
sudo nginx -t
sudo systemctl restart nginxBu aşamada Let’s Encrypt tarafından sağlanan ücretsiz SSL sertifikası kullanılarak API servisleri HTTPS üzerinden güvenli hale getirilir. Certbot, Nginx yapılandırmasını otomatik olarak algılar ve sertifika yenileme süreçlerini arka planda yönetir. Mobil uygulamalar ve production ortamlar için HTTPS zorunlu kabul edilir.
SSL sertifikalarını otomatik olarak alıp yenileyen Certbot aracı ve Nginx entegrasyon paketi sisteme kurulur. Bu paket sayesinde manuel sertifika ve konfigürasyon işlemlerine gerek kalmaz.
sudo apt update
sudo apt install certbot python3-certbot-nginx -yBu komut sadece Let’s Encrypt üzerinden SSL sertifikası üretir ve dosyalarını /etc/letsencrypt/live/example.com/ altına kaydeder. Nginx’e hiçbir değişiklik yapmaz, otomatik deploy veya server block eklemez.
sudo certbot certonly --manual -d example.comBu yapı, uygulamanı güvenli bir şekilde HTTPS üzerinden çalıştırır. HTTP isteklerini HTTPS’e yönlendirir ve SSL sertifikaları ile proxy ayarlarını yönetir.
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://localhost:3000;
include /etc/nginx/config/proxy_settings.conf;
}
}
Sertifikaların otomatik yenilenme mekanizmasının doğru çalışıp çalışmadığını test eder. Gerçek yenileme yapmaz, sadece simülasyon çalıştırır. Böylece ileride sertifika süresi dolduğunda sorun yaşamazsın.
sudo certbot renew --dry-runSertifikanın, nginx veya Let’s Encrypt dizinlerinde nerelerde kullanıldığını ve ayarlandığını görmek için kullanılır. Özellikle nginx’de otomatik ekleme yapıldıysa veya eski sertifikalar kaldıysa bunu tespit etmeye yarar.
sudo grep -R "example.com" /etc/nginx /etc/letsencrypt -nSertifikaların otomatik yenilenme mekanizmasının doğru çalışıp çalışmadığını test eder. Gerçek yenileme yapmaz, sadece simülasyon çalıştırır. Böylece ileride sertifika süresi dolduğunda sorun yaşamazsın.
sudo certbot delete --cert-name example.com --non-interactive
sudo nginx -t
sudo systemctl reload nginx