Teknoloji

Linux VPS’te Kullanıcı, Grup ve sudo Yetki Tasarımı

Linux VPS’te Kullanıcı, Grup ve sudo Yetkilerini Planlayın

Birden fazla projenin çalıştığı Linux VPS üzerinde erişimi kişi, proje ve işleme göre tasarlayın. Bu rehberde hesaplar, dosya izinleri, ACL ve sudo yetki tasarımı aynı uygulanabilir örnekte buluşur.

Linux VPS üzerinde birden fazla proje, ajans yapısı veya ürün ekibi yönetiyorsanız, CPU, RAM ve disk kapasitesi kadar kullanıcı, grup ve sudo mimarinizi de planlamalısınız. Kaynak ihtiyaçlarını belirlerken şu soruyu da yanıtlayın: “Bu sunucuya kim, neye, hangi yetkiyle erişecek?”

Yanlış yapılandırılmış sudo, herkesin paylaştığı tek bir kullanıcı hesabı ve projeler arası karışan dosya izinleri; işlemleri kişilere bağlamayı zorlaştırabilir, yanlışlıkla dosya veya log silinmesine ve üretim ortamında gereğinden fazla ayrıcalık kullanılmasına yol açabilir.

Bu yazıda, Linux VPS’inizde çoklu proje ve ekipler için tekrar kullanılabilir bir yetki tasarımı kurmanıza yardımcı olacağız. Kullanıcı ve grup modelini, komut bazlı sudoers kurallarını ve geliştirme–staging–canlı ortam ayrımlarının yetkilere nasıl yansıtılabileceğini ele alacağız. Kullanıcı, grup ve dizin yönetimi için adım adım örnekler sunacağız; bunlar her sistemde doğrudan uygulanabilecek eksiksiz bir kurulum değildir. Örnekleri uygulamadan önce kullandığınız dağıtımın araçlarını, mevcut hesapları ve servis kullanıcılarını dikkate alarak uyarlamanız gerekir.

Eğer henüz temel güvenlik sertleştirme adımlarını atmadıysanız, bu yazıyı VPS güvenlik sertleştirme kontrol listemiz ve yeni VPS’te ilk 24 saatte yapılması gereken ayarlar ile birlikte değerlendirmenizi öneririz.

Kavramlar: Kullanıcı, Grup ve sudo Arasındaki İlişki

POSIX izin modeli hızlı özet

Linux’ta dosya ve dizin izinlerinin temelinde POSIX modeli vardır. Her dosya için üç ana başlık bulunur:

  • Sahip (user): Dosyanın sahibi kullanıcı.
  • Grup (group): Dosyanın ait olduğu grup; bu, sahibinin birincil grubuyla aynı olmak zorunda değildir.
  • Diğerleri (others): Sahip ve grup dışındaki herkes.

Her biri için okunabilir (r), yazılabilir (w) ve çalıştırılabilir (x) bitleri (ve bunların sayısal karşılığı olan 4, 2, 1) vardır. Bu konuyu detaylı anlamak istiyorsanız, ayrıca Linux dosya izinleri ve güvenli ayarlar yazımıza da göz atabilirsiniz.

Kullanıcı türleri: root, sistem kullanıcıları ve normal kullanıcılar

Yetki tasarımı yaparken üç ana kullanıcı türünü bilmek gerekir:

  • root: Linux yetenekleri, namespace ve ek güvenlik politikalarının bağlamında en geniş yönetim ayrıcalıklarına sahip hesap. Günlük paylaşılan oturum hesabı olarak kullanmayın.
  • Servis hesapları: uygulama süreçlerinin kimliği. nologin bir kabuk girişini reddeder; hesabın süreç çalıştıramayacağı anlamına gelmez.
  • Kişisel hesaplar: insanlara ayrı SSH ve denetlenebilir görev erişimi verir; otomasyon kimliklerinden ayrı tutulur.

Günlük yönetimde, insanlara ortak bir doğrudan root oturumu kullandırmak yerine kişisel hesaplar verin. Kişisel normal kullanıcı + sudo ile gerektiğinde kontrollü ayrıcalık yükseltmesine izin verirsiniz.

sudo neden doğrudan root yerine tercih edilmeli?

sudo, belirli kullanıcılara belirli komutları, belirli kullanıcı kimlikleriyle (çoğu zaman root) çalıştırma izni veren bir mekanizmadır. Avantajları:

  • sudo üzerinden başlatılan komutlar, yapılandırmaya bağlı olarak loglanır; kayıtlar dağıtıma göre /var/log/auth.log, /var/log/secure veya journal içinde bulunabilir. sudo ile açılan bir kabuğun içindeki her komut, olağan komut kaydıyla ayrı ayrı izlenmez.
  • Kullanıcı bazlı ince ayarlı yetki verebilirsiniz.
  • Parola doğrulaması ek bir kontrol sağlayabilir; NOPASSWD ise bu doğrulamayı kaldırır, başlı başına ek güvenlik sağlamaz.
  • Doğrudan root parolasını paylaşmak zorunda kalmazsınız.

Çoklu proje ve çok ekipli yapılarda ortak root oturumları, işlemlerin sorumlusunu belirlemeyi zorlaştırır. Kişisel hesaplara dayalı, sudo merkezli bir model bu ayrımı destekler.

Çoklu Proje ve Ekipler İçin Mantıksal Model

Hedef: En az ayrıcalık ve izlenebilirlik

Başarılı bir yetki tasarımının üç temel hedefi vardır:

  • Least privilege (en az ayrıcalık): Her kullanıcı sadece işini yapmaya yetecek kadar hakka sahip olsun.
  • Separation of duties (görev ayrımı): Geliştirici, operasyon, müşteri veya içerik ekibi aynı yetki seviyesinde olmasın.
  • Auditability (izlenebilirlik): Hangi komutu kimin, ne zaman çalıştırdığını görebilin.

Basit bir örnek düşünelim: Aynı VPS’te üç proje barınıyor:

  • Kurumsal web sitesi (marketing ekibi ve ajans erişiyor).
  • E-ticaret sitesi (backend & frontend ekipleri, operasyon).
  • İç dashboard (sadece iç ekip, kritik veriler).

Bu üç projenin hem kod tabanı hem de verileri birbirinden olabildiğince izole olmalı. Aynı zamanda, ortak görevler (örneğin sunucu güncelleme, log yönetimi) için rol bazlı erişimlere de ihtiyaç var.

Proje bazlı gruplar

İyi bir başlangıç noktası şudur: Her proje için en az bir grup tanımlayın. Örneğin:

  • proj_corporate
  • proj_shop
  • proj_dashboard

Bu gruplar, ilgili projenin kod dizinlerine ve loglarına erişme hakkını belirler. Örnek dizin yapısı:

  • /var/www/corporate (grup: proj_corporate)
  • /var/www/shop (grup: proj_shop)
  • /var/www/dashboard (grup: proj_dashboard)

Kod sahipliği için ayrı bir dağıtım hesabı, çalışan uygulama için ayrı servis hesabı kullanın. Aşağıdaki tam örnekte bunlar deploy_shop ve svc_shop. Tüm projeleri aynı servis kimliğiyle çalıştırmak, proje grupları ayrı olsa bile uygulamalar arasında dosya erişim sınırı kurmaz. Kodu değiştirebilen/deploy edebilen kişinin, bu kodun çalışma zamanı hesabının eriştiği verileri de etkileyebileceğini hesaba katın.

Rol bazlı gruplar

Rol ihtiyaçlarını da adlandırın. Aşağıdaki genel rol etiketleri tek başına izin uygulamaz; çalıştırılabilir örnekte proje kapsamlı shop_read ve shop_ops grupları kullanılır:

  • role_dev: Geliştiriciler.
  • role_ops: Sistem & DevOps ekibi.
  • role_ro: Sadece log okuma, konfigürasyon görüntüleme yetkisi olanlar.

Hedef erişim politikasını “proje + rol” olarak modelleyebilirsiniz; ancak Linux grup üyelikleri kendiliğinden bir kesişim koşulu oluşturmaz. Bir gruptan gelen yazma iznini role_ro üyeliği geri almaz. Aşağıdakiler hedef politikalardır; bunları uygulamak için proje kapsamlı okuma/yazma grupları veya uygun ACL’ler ve ayrıca komut kapsamlı sudo kuralları gerekir. Örnek:

  • alice: shop kod yazarı ve log okuyucusu.
  • bob: shop için kod/log okuyucusu; yazıcı gruba alınmaz.
  • carol: shop operasyon grubu ve okuma grubu; servis yetkisi dosya yazma yetkisine otomatik dönüşmez.

Umask ve varsayılan izinler

Dizinlerde işbirliği için setgid, izin modu ve gerektiğinde ACL birlikte kullanılır. Aşağıdaki kabuk ayarı yalnız mevcut oturumun yeni dosyaları içindir; tam dizin kurulumunu hesapları oluşturduktan sonra uygulayın.

Setgid ve grup sahipliği için tam komutlar, gerekli hesaplarla birlikte aşağıdaki kurulum bölümünde verilir. Kod dosyaları ile dizinlerin modlarını ayrı değerlendirin.

Varsayılan ACL olmayan bir yerde, uygulama dosyayı 0666 ile oluşturursa umask 0002 sonucu 0664, umask 0007 sonucu 0660 olur. Umask izin eklemez; mevcut dosyaları değiştirmez. Aşağıdaki komut yalnız mevcut kabuk ve çocuklarını etkiler. Tüm sunucunun /etc/profile.d politikasını bu örnek için değiştirmeyin. Servislerde kendi UMask= ayarını ve varsayılan ACL etkisini ayrıca inceleyin.

umask 0007

Dizinlerdeki setgid yeni nesnelerin grup sahipliğini devralmasını sağlar; kendi başına yazma hakkı sağlamaz. Normal dosyalar topluca çalıştırılabilir yapılmaz. ACL’de svc_shop ve shop_read için kod okuma/geçiş hakkı vardır; proj_shop yazabilir. mask, adlandırılmış kullanıcı/grup ve sahip grup girdilerinin etkin üst sınırıdır. chmod g=... bu maskeyi de değiştirebilir; yalnız grup satırını okuyarak sonuç çıkarmayın.

Varsayılan ACL bulunan dizinde yeni dosyanın izinleri ACL ve uygulamanın istediği oluşturma modu üzerinden hesaplanır. Örneğin uygulama 0600 isterse okuyucu ACL’sinin etkin hakkı kapanabilir. Kopyalama, arşiv açma, editörün geçici dosyayı yeniden adlandırması veya dağıtım araçları izin/ACL’leri korumayabilir. Örnekte install sonrasında index dosyasının ACL’si bu yüzden açıkça kuruluyor. Her gerçek dağıtımın sonunda etkin izinleri yeniden sınayın.

POSIX ACL kılavuzu oluşturma ve erişim denetimi kurallarını açıklar.

Adım Adım: Kullanıcı ve Grup Oluşturma Pratiği

Gerekli Hesapları ve Proje Gruplarını Oluşturun

Tek shop projesi üzerinden yazar, okuyucu, proje operasyonu, dağıtım ve çalışma zamanı kimliklerini ayıralım. Aynı modeli corporate/dashboard ve staging için ayrı adlar ve üyeliklerle çoğaltabilirsiniz.

Aşağıdaki tekrarlanabilir örnek Ubuntu 24.04 üzerinde Bash/POSIX kabuk, shadow kullanıcı araçları, sudo ve acl paketini varsayar. Ayrı bir test sunucusunda başlayın; mevcut hesap ve proje ağacına topluca uygulamayın. Komutları yönetici/root yetkisiyle çalıştırın. Hesaplar ve /srv/shop yeni olmalıdır; örnek mevcut adlarda durur. İnsan hesaplarının SSH anahtarlarını, parola/PAM politikasını ve kurtarma erişimini ayrıca hazırlayın. Hesap oluşturmak girişin hazır olduğu anlamına gelmez.

#!/bin/sh
set -eu
for account in alice bob carol deploy_shop svc_shop; do
    if getent passwd "$account" >/dev/null; then
        printf 'Account already exists: %s\n' "$account" >&2
        exit 1
    fi
done
for team in proj_shop shop_read shop_ops; do
    if getent group "$team" >/dev/null; then
        printf 'Group already exists: %s\n' "$team" >&2
        exit 1
    fi
done
groupadd proj_shop
groupadd shop_read
groupadd shop_ops
useradd -m -U -s /bin/bash alice
useradd -m -U -s /bin/bash bob
useradd -m -U -s /bin/bash carol
useradd -r -M -U -d /nonexistent -s /usr/sbin/nologin deploy_shop
useradd -r -M -U -d /nonexistent -s /usr/sbin/nologin svc_shop
usermod -aG proj_shop,shop_read alice
usermod -aG shop_read bob
usermod -aG shop_ops,shop_read carol

Komutlar kişisel hesapları ve giriş yapmayan iki sistem hesabını oluşturur. İnsanların ilk girişini ve gerekli sudo parola politikasını ayrı oturumda doğrulayın; komut satırına açık parola yazmayın.

getent passwd alice bob carol deploy_shop svc_shop

usermod -aG mevcut supplementary grupları koruyarak ekler. -a olmadan -G liste dışındaki üyelikleri kaldırır. Değişikliklerin yeni oturuma yansıdığını kontrol edin.

id alice
id bob
id carol

Bu noktada:

  • alice: proj_shop ile kod/shared yazarı; shop_read ile log okuyucusu.
  • bob: yalnız shop_read; kod ve log okur, shared içeriğine erişmez.
  • carol: shop_ops ile belirli servis işlemleri, shop_read ile okuma; otomatik kod yazma yetkisi yoktur.
  • deploy_shop: kod sahibi ve sınırlı yerel bakım görevinin hedefi. svc_shop: ayrı çalışma zamanı kimliği; kodu okuyabilir, değiştiremez.

Elbette gerçek hayatta daha fazla proje ve rol olabilir, ancak mantık aynı kalır.

Proje dizini izinleri

Aşağıdaki örnek yeni ve boş bir proje ağacı içindir. Dizinler ve normal dosyalar farklı modlarla kurulur. Mevcut ağaçta recursive chmod/chown yerine sahipliği, ACL’leri, özel dosyaları, symlinkleri ve uygulamanın yazdığı alanları önce envanterleyin.

Aşağıdaki tam kurulum /srv/shop/prod/app, shared ve logs dizinlerini ayırır. Üst dizinlerde geçiş izni vardır; proje içeriğinin sınırı yaprak dizinlerde uygulanır. Kod sahibi dağıtım hesabıdır; uygulamanın değişebilir verileri ayrı tutulur. Sentetik index.html yalnız alıştırma içindir.

#!/bin/sh
set -eu
if [ -e /srv/shop ] || [ -L /srv/shop ]; then
    printf '%s\n' '/srv/shop already exists; review it instead of overwriting permissions.' >&2
    exit 1
fi
install -d -o root -g root -m 0755 /srv/shop /srv/shop/prod
install -d -o deploy_shop -g proj_shop -m 2770 /srv/shop/prod/app
install -d -o svc_shop -g proj_shop -m 2770 /srv/shop/prod/shared
install -d -o svc_shop -g shop_read -m 2750 /srv/shop/prod/logs

setfacl -m u:svc_shop:rx,g:shop_read:rx,m::rwx /srv/shop/prod/app
setfacl -d -m u::rwx,u:svc_shop:rx,g::rwx,g:shop_read:rx,m::rwx,o::--- /srv/shop/prod/app
setfacl -m u:svc_shop:rwx,m::rwx /srv/shop/prod/shared
setfacl -d -m u::rwx,u:svc_shop:rwx,g::rwx,m::rwx,o::--- /srv/shop/prod/shared
setfacl -d -m u::rwx,g::rx,m::rx,o::--- /srv/shop/prod/logs

install -o deploy_shop -g proj_shop -m 0660 /dev/null /srv/shop/prod/app/index.html
printf '%s\n' '<!doctype html><title>Shop preview</title><p>Synthetic tutorial page.</p>' > /srv/shop/prod/app/index.html
setfacl -m u:svc_shop:r,g:shop_read:r,m::rw /srv/shop/prod/app/index.html

Yönetici oturumundan sentetik örneği doğrulayın. İlk iki okuma başarılı olmalı; son iki yazma denemesi reddedilmelidir. Beklenmeyen başarıyı, geniş bir başka grup/sudo/ACL yetkisi bulunabileceğine dair bulgu olarak ele alın.

getfacl -p /srv/shop/prod/app /srv/shop/prod/app/index.html
sudo -u bob -- cat /srv/shop/prod/app/index.html
sudo -u svc_shop -- cat /srv/shop/prod/app/index.html
sudo -u bob -- touch /srv/shop/prod/app/bob-must-not-write
sudo -u svc_shop -- touch /srv/shop/prod/app/runtime-must-not-write

Grup ekleme/çıkarma mevcut süreçlerin supplementary group listesini geriye dönük değiştirmez. Erişim verirken yeni oturumla doğrulayın; erişim iptalinde açık oturumları, çalışan süreçleri, kullanıcıya ait dosyaları ve diğer sırları da değerlendirin. id bob hesap veritabanını sorgular; eski bir oturumun içindeki id farklı grup kümesi gösterebilir. Bir okuyucuyu yazıcı grubuna da eklerseniz okuma rolü yazma iznini geri almaz.

Home dizinleri ve paylaşım stratejisi

Geliştiricilerin kişisel ~/ dizinlerini izole tutmak ve proje dosyalarını kişisel home dizinlerinden ayrı, örneğin /var/www altında konumlandırmak iyi bir pratiktir. Böylece:

  • Proje ağacını kişisel home dizininden ayırmak, hesap kaldırılırken proje verisini korumayı kolaylaştırır. Silmeden önce dosya sahipliklerini, saklanacak veriyi ve kullanılan aracın silme davranışını inceleyin.
  • Yedekleme ve geri yükleme planında proje kodunu, kalıcı veriyi, yapılandırmayı ve gerekli sırları ayrı değerlendirin.

Yedeklemeyi tasarlarken, bu yapıyı object storage’a otomatik yedek alma stratejileri ile birleştirmeniz uzun vadede işinizi çok kolaylaştırır.

sudoers Tasarımı: Komut Bazlı Yetki Paylaşımı

sudoers dosyasına bakış

sudo kuralları /etc/sudoers dosyasında ve buradan dahil edilen ek dosyalarda tanımlanır; /etc/sudoers.d/ dizininin yapılandırmaya dahil edildiğini doğrulayın. Asla sudoers dosyasını doğrudan bir editörle düzenlemeyin; her zaman visudo kullanın. Bu komut, düzenlenen kurallar için sözdizimi denetimi sağlar.

/etc/sudoers.d ile modüler yapı

Karmaşık yapılarda, tek bir büyük /etc/sudoers dosyası yerine, proje veya rol bazlı dosyalar oluşturmak işleri çok daha okunabilir hale getirir:

  • /etc/sudoers.d/proj_shop
  • /etc/sudoers.d/proj_corporate
  • /etc/sudoers.d/role_ops_global

Ortam politikasını her proje dosyasında tekrarlamak yerine merkezi olarak tanımlayın. Aşağıdaki ayarı mevcut Defaults kurallarıyla birlikte değerlendirin:

Defaults    env_reset

Bu ayar, sudo ile çalıştırılan komutların ortamını sınırlandırmaya yardımcı olur; tüm ortam değişkenlerinin koşulsuz silindiği veya ortam kaynaklı tüm risklerin giderildiği anlamına gelmez.

Alias kullanarak okunabilirlik

Root olarak geliştiricinin değiştirdiği build/deploy/migration kodunu çalıştırmayın. Sınırlı RunAs örneği için aşağıdaki dosyayı shop-check adıyla kaydedin. Yalnız sabit bir dosyanın SHA-256 değerini hesaplar; dağıtım yapmaz, dosyanın güvenilirliğini kanıtlamaz. Gerçek dağıtımın artifact doğrulaması, atomik geçişi ve geri dönüşü ayrıca tasarlanmalıdır.

#!/bin/sh
set -eu
if [ "$#" -ne 0 ]; then
    printf '%s\n' 'No arguments are accepted.' >&2
    exit 2
fi
exec /usr/bin/sha256sum -- /srv/shop/prod/app/index.html

İçeriğini gözden geçirdikten sonra yönetici/root olarak kurun. Dosya ve bütün üst dizinler yetki verilen kullanıcının değiştiremeyeceği sahiplik ve izinlerle korunmalıdır:

install -d -o root -g root -m 0755 /usr/local/libexec
install -o root -g root -m 0755 ./shop-check /usr/local/libexec/shop-check
visudo -f /etc/sudoers.d/shop

Aşağıdaki dosya tek bir proje için geçerlidir. shop_ops proje kapsamlı bir gruptur; genel bir role_ops adının proje üyeliğiyle otomatik kesiştiği varsayılmaz. Gerçek komut yollarını doğrulayın ve dosya adında nokta/tilde kullanmayın:

User_Alias SHOP_DEVS = %proj_shop
User_Alias SHOP_OPS = %shop_ops
Cmnd_Alias SHOP_VERIFY = /usr/local/libexec/shop-check ""
Cmnd_Alias SHOP_RESTART = /usr/bin/systemctl restart shop.service
Cmnd_Alias SHOP_LOGS = /usr/bin/journalctl --no-pager --unit shop.service --lines 100

SHOP_DEVS ALL=(deploy_shop) NOPASSWD: SHOP_VERIFY
SHOP_OPS ALL=(root) SHOP_RESTART, SHOP_LOGS
  • proj_shop üyeleri yalnız bu kuraldan shop-check görevini deploy_shop olarak çalıştırma hakkı alır. Sondaki "" argüman verilmesini engeller; argüman yazmamak genel olarak tüm argümanları serbest bırakır.
  • shop_ops yalnız tam yazılan restart/log komutlarını root olarak çalıştırabilir. Komut argümanlarında wildcard yoktur; fazladan birim veya seçenek izin kapsamına girmez.
  • --no-pager etkileşimli pager riskini azaltır; log içerikleri yine hassas olabilir. Satır sayısı sınırı ve birim seçimi veri erişim politikasının yerine geçmez.
  • NOPASSWD yalnız sınırlı nonroot görev içindir. Servis işlemleri varsayılan kimlik doğrulamasını kullanır; geçerli önbellek ve başka kurallar nedeniyle her çağrıda yeni parola sorulacağı garanti değildir.
  • Diğer sudoers dosyaları, polkit kuralları, grup/ACL izinleri ve servis davranışı toplam yetkiyi etkiler. Bu parça bütün kullanıcıların başka root yolu olmadığına dair kanıt değildir.

sudoers kılavuzundaki argüman, RunAs ve include kuralları bu sınırları belirler.

Tam yapılandırmayı denetleyin; tek dosyadaki sözdizimi başarısı diğer dosyalardaki çakışmaları veya geniş yetkileri göstermeyebilir. Aşağıdaki -l kontrolleri komutu çalıştırmaz. İlk iki yetki sorgusu izinli, son sorgu reddedilmiş olmalıdır:

chown root:root /etc/sudoers.d/shop
chmod 0440 /etc/sudoers.d/shop
visudo -c
sudo -l -U alice -u deploy_shop /usr/local/libexec/shop-check
sudo -l -U carol /usr/bin/systemctl restart shop.service
sudo -l -U bob /usr/bin/systemctl restart shop.service

Ardından alice oturumunda sudo -u deploy_shop /usr/local/libexec/shop-check çalışmalı; aynı komuta ek argüman veya -u root verilmesi reddedilmelidir. Komutun kendi davranışını ve dosya izinlerini de sınayın; visudo bunları kanıtlamaz.

Proje Servisi ve Paylaşılan Servis Arasındaki Sınır

Servis yeniden başlatma yetkisi, o servisin tüm projelerini etkiler. Ortak nginx, PHP-FPM veya Supervisor birimini yeniden başlatmak proje izolasyonu değildir. Gerçek proje kapsamı için ayrı birim ve çalışma kimliği gerekir; ortak bağımlılıkların etkisini ayrıca inceleyin. Birim, drop-in, ExecStartPre/ExecStart/ExecReload zinciri, script ve kritik ayarların üst dizinleri de yetki verilen kullanıcıların yazmasına kapalı olmalıdır. systemd komutlarındaki +/! gibi önekler kimlik sınırını değiştirebilir.

Aşağıdaki isteğe bağlı shop.service, yalnız izole alıştırmada sentetik sayfayı localhost üzerinde gösterir. Python http.server üretim sunucusu olarak önerilmez. Bu isteğe bağlı bölüm için hedefte /usr/bin/python3 çalıştırılabilir dosyasının ve http.server modülünün mevcut olduğunu önce doğrulayın; en küçük sunucu imajlarında bunlar eksik olabilir. Gerekirse test sunucusuna dağıtımın desteklenen Python 3 paketlerini kurun. Gerçek uygulamanız için doğru sunucuyu, bağımlılıkları, erişim sınırlarını ve sağlık/geri dönüş kontrollerini ayrıca kurun. Buradaki yetki örneğini üretim mimarisi diye kullanmayın.

[Unit]
Description=Shop static preview for an isolated tutorial
After=network.target

[Service]
Type=simple
User=svc_shop
Group=svc_shop
WorkingDirectory=/srv/shop/prod/app
ExecStart=/usr/bin/python3 -m http.server 18080 --bind 127.0.0.1 --directory /srv/shop/prod/app
UMask=0027
NoNewPrivileges=yes
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=strict
ReadOnlyPaths=/srv/shop/prod/app
ReadWritePaths=/srv/shop/prod/shared /srv/shop/prod/logs

[Install]
WantedBy=multi-user.target

Dosyayı root:root ve 0644 ile /etc/systemd/system/shop.service olarak kurun. systemd-analyze verify /etc/systemd/system/shop.service çıktısındaki tüm uyarı/hataları inceleyip giderin; varsayılan çıkış kodu tek başına yeterli değildir. Ardından yalnız test sunucusunda systemctl daemon-reload ve systemctl start shop.service ile başlatıp gerçek süreç kimliğini, okuma/yazmayı ve localhost yanıtını kontrol edin. Sözdizimi denetimi servis çalıştığı anlamına gelmez. Type=simple nedeniyle başarılı bir start sonucu da Python’un çalıştığını veya HTTP yanıtı verdiğini tek başına kanıtlamaz. ProtectSystem=strict ve yazılabilir istisnalar Unix izinlerinin yerine geçmez; PrivateTmp özel geçici yazma alanı da sağlar. ReadWritePaths listesi bütün dosya sisteminin mutlak sınırı gibi okunmamalıdır.

systemd.exec belgesi User, UMask ve dosya sistemi sınırlamalarını ayrıntılandırır. Sözdizimi ve eşdeğer süreç izinlerini denetlemek, çalışan servisi doğrulamanın yerine geçmez; servis başlatma, SSH bağlantısı ve üretim yükü kabul testlerini ayrıca yapın.

Parola Doğrulaması ve NOPASSWD

Güvenlik–kullanılabilirlik dengesini, komut seviyesinde kurabilirsiniz:

  • Kapsamı dar ve güvenlik incelemesi yapılmış otomasyon komutları için NOPASSWD düşünülebilir. Sık kullanılması veya bir dosya temizleme script’i olması, komutu tek başına düşük riskli yapmaz.
  • Kritik etkileşimli işlemlerde (örn. firewall restart, kullanıcı yönetimi) parola doğrulamasını koruyun; bu doğrulama, verilen yetkinin kapsamını daraltmanın yerine geçmez.

Örneğimizde SHOP_VERIFY nonroot ve NOPASSWD, SHOP_RESTART ise varsayılan doğrulamalıdır. Firewall veya kullanıcı yönetimini bu proje rolüne eklemeyin; bunlar ayrı yönetici sorumluluğudur.

sudo -l
sudo -k

sudo -k önbelleği geçersiz kılar; NOPASSWD kurallarını kaldırmaz. Kimlik doğrulaması, verilen komutun kapsamını daraltmanın yerine geçmez. Gerçek parola/MFA davranışı mevcut PAM ve sudo politikanızla ayrıca sınanmalıdır.

root erişimini tamamen mi kapatmalı?

Pratikte çoğu prod ortamda SSH ile doğrudan root girişi kapatılmalı, fakat sudo ile root olma ihtimali (örneğin acil durumlar için ops ekibinde) korunmalıdır. Bunun detaylarını, hem bu mimariyle uyumlu hem de daha geniş kapsamlı şekilde VPS sunucu güvenliği rehberimizde anlattık.

SSH, Anahtar Yönetimi ve sudo Modelinin Birlikte Çalışması

Parola yerine SSH anahtarı

Zayıf SSH doğrulaması hesabın ele geçirilmesi riskini artırır; gereğinden geniş sudo izinleri de etkisini büyütür. Kişisel anahtar politikasını ve gereken ek doğrulamayı birlikte tasarlayın. Aşağıdaki yalnız anahtarlı örneği mevcut MFA gereksinimlerini kaldırmak için kullanmayın. Ayrıntılar için SSH anahtar yönetimi ve yetki paylaşımı rehberimize bakabilirsiniz.

Genel yaklaşım şu olmalı:

  • Her ekip üyesi için ayrı bir Linux kullanıcısı oluşturun (alice, bob, carol vb.).
  • Her kullanıcının kendi SSH anahtarını ~/.ssh/authorized_keys içine ekleyin.
  • SSH üzerinde PasswordAuthentication no ve PermitRootLogin no ayarlarını yapmadan önce kişisel hesabınızla anahtarlı girişi ve gerekli sudo erişimini ayrı bir oturumda doğrulayın. Değişiklik sırasında mevcut yönetim oturumunu açık tutun ve çalışır bir konsol/kurtarma erişimi bulundurun.
  • sudo izinlerini az önce anlattığımız şekilde, roller ve projelere göre tanımlayın.

Bu iki ayar tek başına yalnızca anahtarlı giriş politikasını göstermez: parola ile klavye-etkileşimli doğrulama ayrı yöntemlerdir. Ubuntu 24.04/OpenSSH örneğinde, yalnız public key isteniyorsa etkin politika şu değerleri birlikte sağlamalıdır:

PubkeyAuthentication yes
AuthenticationMethods publickey
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no

Bu parça ayrı bir MFA politikası değildir; mevcut anahtar+ikinci faktör zorunluluğunu bununla değiştirmeyin. PAM hesap ve oturum kontrollerini kapatmanız gerekmez. Satırları dosya sonuna körlemesine eklemeyin: Include dosyaları ve kullanıcı/adres ile eşleşen Match blokları etkin değerleri değiştirebilir. Önce mevcut dosyaları yedekleyin; hedef sürümün kılavuzuna göre sshd -t ile doğrulayın, sshd -T ve bağlantıya uygun -C parametreleriyle her ilgili kullanıcı/kaynak için etkin politikayı inceleyin. Yalnız başarılı kontrolden sonra dağıtımın servis veya socket yöntemini uygulayın. Yönetim oturumunu ve konsol erişimini koruyarak ikinci bir oturumda anahtarlı giriş, sudo ve beklenen reddetme davranışını sınayın; sözdizimi denetimi gerçek bağlantı testi değildir.

Bu model, ortak root parolasını herkese dağıtma ihtiyacını ortadan kaldırır. Bir ekip üyesi ayrıldığında kişisel hesabının erişimini ve anahtarlarını kaldırmanın yanında açık oturumlarını, otomasyon erişimlerini ve bildiği ortak sırları da gözden geçirin. Hesabı silmek tek başına bütün erişim yollarının kapandığını göstermez.

Çoklu ortamlar: dev, staging, prod

SaaS veya e-ticaret projeleri için erişim politikasını şu üç ortam üzerinden planlayabilirsiniz:

  • Geliştirme (dev)
  • Test/Staging
  • Üretim (prod)

Bu ortamları farklı VPS’lerde tuttuğunuz senaryolarda, kullanıcı–grup–sudo modelinde tutarlı bir isimlendirme kullanmak yönetimi kolaylaştırabilir. Ancak aynı adları kullanmak aynı erişimleri vermek anlamına gelmez; grup üyeliklerini, dosya izinlerini ve sudo kurallarını her ortamın ihtiyacına göre ayrı belirleyin. Örneğin:

  • Dev ortamında geliştiricilere daha geniş sudo hakkı verilebilir.
  • Prod ortamında geliştiriciler sadece deploy script’lerini çalıştırabilir, servis restart ve sistem ayarları yalnızca ops ekibine açık olabilir.

Tipik Senaryolar İçin Örnek Mimariler

Senaryo 1: Ajansın çoklu müşteri siteleri

Bir dijital ajans olduğunuzu ve DCHost üzerinde onlarca müşteri sitesini aynı VPS havuzunda yönettiğinizi düşünün. Her müşteri için ayrı bir proje grubu oluşturabilirsiniz:

  • proj_markaA, proj_markaB, proj_markaC…

Ajans içi ekip rolleri:

  • role_wp_dev (WordPress geliştiriciler)
  • role_frontend
  • role_ops (sunucu yöneten az sayıdaki kişi)

Bir geliştirici hem proj_markaA hem proj_markaB’de çalışıyorsa, iki proje grubuna da eklenir. Bu senaryoda sudoers kuralları, role_ops dışındaki geliştiricilerin sudo yetkisini yalnızca ilgili projelerin belirli deploy veya cache temizleme script’leriyle sınırlandıracak şekilde tanımlanır. Daha kapsamlı ajans senaryosu için ajanslar için panel erişim yönetimi rehberimiz de iyi bir tamamlayıcı olacaktır.

Senaryo 2: Ürün şirketinde backend, frontend ve DevOps ayrımı

Örnek ürün şirketimizde şu ekiplerin bulunduğunu varsayalım:

  • Backend ekibi
  • Frontend ekibi
  • DevOps/SRE ekibi

Burada strateji:

  • Backend ekibi: API kod dizinlerine yazabilir ve belirli log dizinlerini okuyabilir. Deploy ve migration işlemleri, yalnızca gereken dosya ve veritabanı izinlerine sahip sınırlı bir servis hesabıyla yürütülür; sudo gerekiyorsa hedef hesap ve izinli komutlar ayrıca sınırlandırılır.
  • Frontend ekibi: Sadece frontend build/deploy script’lerini çalıştırabilir, sunucu yapılandırmasına dokunamaz.
  • DevOps ekibi: Servis restart, firewall, sistem güncelleme gibi görevler için daha geniş sudo yetkisine sahip olur.

Veritabanı yetkisi ayrıca tasarlanır. mysql/psql gibi etkileşimli istemcileri veya genel dump araçlarını sınırsız argümanlarla root sudo listesine koymayın: araçların shell, dosya ve bağlantı yetenekleri OS sınırını genişletebilir. Yedekleme için ayrı sınırlı OS hesabı, doğru veritabanı rolü, hedef dosya izinleri ve saklama politikası gerekir. Örnek bir bağlantı servisi gerçek sisteminizde önceden tanımlanmışsa, kendi hesabından şöyle çağrılabilir:

umask 0077
pg_dump --dbname=service=shop_backup --format=custom --file="$HOME/shop.dump"

Bu komut root gerektirdiği varsayımıyla verilmez; shop_backup bağlantı servisi burada oluşturulmuş değildir. TLS, kimlik doğrulama, veritabanı/şema/tablo yetkileri, çıktı kapasitesi ve geri yükleme testi ayrı önkoşullardır. Bir rolün adı ona yetki vermez; bir veritabanı dump’ı bütün kümenin rol/tablespace nesnelerini yedeklemez. Dump/restore işlemini kendi test ortamınızda ayrıca doğrulayın.

Script’ler ve çalıştırıldıkları hesaplar da bu yetki sınırlarına uyuyorsa, backend veya frontend ekibinin yanlışlıkla tüm sunucuyu etkileyen bir işlem yapma riski azaltılabilir.

Senaryo 3: Dış hizmet sağlayıcı veya freelance geliştirici

Dışarıdan destek aldığınız bir freelance geliştiriciye “geçici” ama kontrollü erişim vermek istiyorsanız:

  • Sadece ilgili projeye ait gruba ekleyin (ör. proj_shop).
  • role_dev veya role_ro gibi rol adlarını gerçek dosya ve sudo izinleriyle destekleyin. Salt okunur erişim isteniyorsa kullanıcının proje grubu üzerinden yazma izni almadığını da doğrulayın; rol adı diğer izinleri geri almaz.
  • sudo tarafında, sadece belirli script’leri çalıştırmasına izin veren minimal bir tanım ekleyin.
  • İş bittiğinde erişimi iptal edin; kullanıcıyı silmeden önce proje dosyalarını, sahipliklerini ve saklanacak logları belirleyin. Silme işleminin bu verileri koruyacağını varsaymayın.

İptalde yalnız parolayı kilitlemek yeterli değildir. Anahtarları/sertifikaları ve CI erişimini iptal edin, açık süreçleri/oturumları yetkili operasyonla sonlandırın, ortak sırları döndürün ve kalan dosya sahipliklerini denetleyin. Hesap/süreç sonlandırması gerçek iş yüklerini etkileyebileceğinden bakım planıyla uygulanır.

Bu yaklaşım ortak root parolası paylaşmayı gerektirmez. Kişisel hesaplar, erişim ve sudo kayıtları uygun biçimde tutulup korunduğunda işlemleri kişilere bağlamayı kolaylaştırır.

Güvenlik Boyutu: Hangi Hatalardan Özellikle Kaçınmalısınız?

“Herkes için tek kullanıcı” modeli

Kaçınılması gereken bir anti-pattern, tüm ekibin ubuntu, admin veya benzeri tek bir kullanıcıyı, paylaşılan bir SSH anahtarıyla kullanması. Bu modelde:

  • Kimin ne yaptığını loglardan bile ayırt edemezsiniz.
  • Bir kişi ayrıldığında anahtarı değiştirmek zorundasınız; herkesi etkileyen operasyonel yük.
  • sudoers üzerinden kişiye özel yetki tanımı yapamazsınız.

Bu modelden bir an önce uzaklaşmak gerekir. DCHost olarak yeni açılan VPS’lerde, ilk 24 saatte mutlaka kişisel kullanıcılar ve sudo modelinin devreye alınmasını öneriyoruz.

Tüm geliştiricilere sınırsız sudo yetkisi dağıtmak

Tüm geliştiricilere aşağıdaki gibi geniş bir yetki vermekten kaçının:

%dev ALL=(ALL:ALL) ALL

Bu kural, dev grubunun tüm üyelerine tam root yetkisi verir. Prod ortamda bunu yapmak güvenlik ve operasyonel riskleri artırır. Bunun yerine:

  • Hangi komutların gerçekten gerektiğini belirleyin.
  • Bu komutları Cmnd_Alias ile gruplayın.
  • Sadece bu alias’lara izin verin.

sudo ile ortam değişkeni manipülasyonu

Sudo ile çalıştırılan programların ortamını ve komut arama yollarını da değerlendirin. Aşağıdaki ayarlar politika örnekleridir; mevcut dağıtım ayarlarını ve uygulama gereksinimlerini inceleyerek kullanın:

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults    env_reset

secure_path komut arama yolunu, env_reset ise izin verilen ortamı sınırlandırmaya yardımcı olur. Etkin env_keep, SETENV ve diğer kuralları da inceleyin. Bu ayarlar, kullanıcının değiştirebildiği bir script’i veya tehlikeli komut argümanlarını güvenli hâle getirmez; tam yollar ve güvenilir bağımlılıklar kullanın.

DCHost VPS Üzerinde Bu Mimariyi Nasıl Konumlandırabilirsiniz?

Planlama adımı: Yalnızca kaynak değil, yetki de tasarlanmalı

Linux VPS planlarken vCPU, RAM ve disk gereksinimlerinin yanında şu üç soruyu da yanıtlamanızı öneririz:

  • Bu VPS’te kaç ayrı proje olacak?
  • Bu projelere kimler, hangi rollerle erişecek?
  • Hangi rollere hangi sudo komutları gerçekten gerekli?

Bu soruları netleştirmek, kullanıcı–grup–sudo mimarisini ilk günden ihtiyaçlarınıza göre kurmanıza ve büyüme sırasında gereken değişiklikleri planlamanıza yardımcı olur.

Önerilen ilk kurulum akışı

DCHost üzerinde yeni bir Linux VPS açtığınızda pratik bir akış şöyle olabilir:

  1. İlk erişim için sağlanan yönetici hesabıyla SSH bağlantısı kurun; bu hesap root veya sudo yetkili bir kullanıcı olabilir.
  2. Sistem güncellemesi ve temel güvenlik hazırlıklarını yapın; erişimi değiştirecek SSH ayarlarını aşağıdaki doğrulama adımlarından sonra uygulayın.
  3. Kendi kişisel yönetici kullanıcınızı oluşturun, SSH anahtarını tanımlayın ve gerekli sudo yetkisini verin.
  4. Mevcut yönetici oturumunu açık tutarak ayrı bir SSH oturumunda yeni kullanıcının anahtarla girişini ve sudo erişimini doğrulayın. Çalışır konsol/kurtarma erişimi ve yapılandırma yedeği bulundurun. Yukarıdaki SSH bölümüne göre sözdizimini ve etkin politikayı denetleyin; mevcut MFA gereksinimlerini koruyarak doğrudan root girişini ve seçtiğiniz politikaya aykırı doğrulama yöntemlerini kapatın. Değişiklikten sonra mevcut oturumu kapatmadan yeni bağlantıyla giriş, sudo ve beklenen reddetme davranışını yeniden doğrulayın.
  5. Proje gruplarını (proj_*) ve rol gruplarını (role_*) oluşturun.
  6. Kullanıcıları bu gruplara yerleştirin, proje dizinlerini ve izinlerini ayarlayın.
  7. /etc/sudoers.d altında proje/rol bazlı sudo kurallarını visudo ile düzenleyin; sözdizimini doğrulayın ve ilgili kullanıcılarla izin verilen ve reddedilmesi gereken işlemleri kontrol edin.

Bu adımların bir kısmı, daha önce hazırladığımız VPS sunucu güvenliği için pratik yaklaşımlar rehberimizle de bire bir uyumludur.

Sonuç: Yetki Modelini İhtiyaçlara Göre Kurun ve Gözden Geçirin

Linux VPS’inizde kullanıcı, grup ve sudo mimarisini ihtiyaçlarınıza göre kurmak, erişim sınırlarını netleştirir ve operasyonel sorumlulukları ayırmayı kolaylaştırır. Hangi dosyayı kimin değiştirdiğini ve hangi komutu kimin çalıştırdığını izleyebilmek, üretim ortamında olayları açıklamaya yardımcı olabilir. Ancak kullanıcı, grup ve sudo tasarımı tek başına eksiksiz bir işlem geçmişi sağlamaz; dosya değişiklikleri ve sudo dışındaki işlemler için ayrıca uygun denetim kayıtları gerekir.

Bu modelin temel prensipleri; proje bazlı gruplar, rol bazlı gruplar, minimal ve denetlenebilir sudo yetkileri, SSH anahtar kullanımı ve root erişiminin sıkı kontrolüdür. Siz de çoklu proje, ajans yapısı veya SaaS ürünleri yönetiyorsanız, bu yazıdaki modeli kendi senaryonuza uyarlayarak başlayabilirsiniz.

Yeni bir Linux VPS planlıyorsanız, ekibinizin rol dağılımını ve projelerinizin erişim ihtiyaçlarını belgeleyerek başlayın. Kullanıcı, grup ve sudo tasarımını bu ihtiyaçlara göre kurmak ve düzenli olarak gözden geçirmek, güvenlik ve operasyon risklerini azaltmaya yardımcı olur.

Son adım olarak, bu yazıyı VPS izleme ve uyarı kurulum rehberi ile tamamlayarak sistem kaynaklarınızı izleyebilirsiniz. Yetki modelini ise erişim kuralları, grup üyelikleri ve denetim kayıtları üzerinden ayrıca düzenli olarak gözden geçirin.

Sıkça Sorulan Sorular

Ortak hesap ve paylaşılan SSH anahtarı, işlemleri kişilere bağlamayı zorlaştırır ve bir kişi ayrıldığında tüm ekibi etkileyen anahtar değişiklikleri gerektirebilir. Her ekip üyesine kişisel hesap verin; dosya ve sudo izinlerini ihtiyaçlarına göre tanımlayın. Kişisel hesaplar tek başına eksiksiz işlem geçmişi sağlamaz; uygun denetim kayıtları da gerekir.

Gereken komutları belirleyip Cmnd_Alias ile gruplayın ve yalnız ilgili kullanıcılara veya gruplara izin verin. Kuralları visudo ile düzenleyin; diğer etkin kuralları ve izinlerin sınırlarını kontrol edin. Root olarak çalışacak script ve bağımlılıkları yetki verilen kullanıcılar değiştirememelidir. Kullanıcının değiştirebildiği kodu, build ve migration işlemlerini sınırlı bir servis hesabıyla çalıştırın. Yeniden başlatma izninde servis birimlerini, drop-in dosyalarını ve ayrıcalıklı başlangıç bağımlılıklarını da koruyun. Paylaşılan bir servisin yeniden başlatılması diğer projeleri de etkiler.

Proje bazlı erişim grupları oluşturun ve rol ihtiyaçlarını ayrıca belirleyin. Linux grup üyelikleri otomatik olarak proje–rol kesişimi oluşturmaz; role_ro üyeliği başka bir grubun verdiği yazma iznini kaldırmaz. Okuma ve yazma erişimini proje kapsamlı gruplar veya uygun ACL’lerle, sudo erişimini ise komut bazlı kurallarla uygulayın. Aynı servis hesabıyla çalışan projeler, yalnızca ayrı proje grupları kullanıldığı için birbirinden izole olmaz.

Zayıf SSH doğrulaması hesabın ele geçirilmesi riskini artırırken, gereğinden geniş sudo izinleri ele geçirilen hesabın etkisini büyütür. Kişisel hesapları, uygun SSH anahtar politikasını ve komut düzeyinde sınırlı sudo izinlerini birlikte tasarlayın. Yalnız anahtarlı giriş için PasswordAuthentication no tek başına yeterli değildir; etkin doğrulama politikasını inceleyin. Mevcut MFA gereksinimlerini koruyun ve erişimi kapatmadan önce ayrı oturumda giriş ile sudo erişimini doğrulayın.

Sonradan düzenlenebilir; ancak ilk kurulumda proje, ekip ve komut ihtiyaçlarını belirlemek daha düzenli bir başlangıç sağlar. Mevcut sunucuda hesapları, servis kullanıcılarını, dosya sahipliklerini ve etkin sudo kurallarını birlikte inceleyin. Yazıdaki boş dizin örneklerini mevcut proje ağacına doğrudan uygulamayın; alt dosya ve dizin izinlerini ayrıca değerlendirin. Değişiklikleri yedek, geri dönüş planı ve test ortamıyla hazırlayın; erişim modelini ihtiyaçlar değiştikçe gözden geçirin.
↑