❌ Çözülemedi 🔍 Analiz

LiteSpeed phpSuExec=2 Symlink Kısıtlaması

AI-generated görseller 403 Forbidden hatası veriyor

📅 9 Ocak 2026 | 🖥️ muzibu.com | 🔧 LiteSpeed Enterprise 6.3.1

📝 Basit Anlatım (Herkes İçin)

Ne Oldu?

Müzik platformunda şarkı kapak görselleri AI ile başarıyla oluşturuldu (20/20 başarı!). Ancak sitede görseller görünmüyor - browser 403 Forbidden (Erişim Engellendi) hatası alıyor.

Neden Oldu?

Web sunucusu (LiteSpeed) çok katı güvenlik modunda (phpSuExec=2) çalışıyor. Bu mod, "kısayol" (symlink) olan dosyalara erişimi engelliyor. Görseller storage klasöründe, ancak web'den erişim için kısayol kullanıyoruz.

Ne Denendi?

  • ✅ Dosya sahipliklerini düzelttik (tuufi.com_:psacln)
  • ✅ Global güvenlik ayarlarını gevşettik (checkSymbolLink 0, forceStrictOwnership 0)
  • ✅ Apache config'e Alias ekledik (symlink bypass)
  • ✅ .htaccess dosyası ekledik (FollowSymLinks)
  • ❌ Hiçbiri işe yaramadı - LiteSpeed katı moddayken bu ayarları görmezden geliyor

Şu Anda Durum:

❌ Görseller mevcut ama erişilemiyor
❌ LiteSpeed phpSuExec=2 modu symlink'leri engelliyor
❌ Global config değişiklikleri işe yaramıyor

Neden Önemli?

Kullanıcılar şarkı kapak görsellerini göremiyorlar. Site görsel olarak eksik görünüyor. AI ile üretilen 20 görselin hiçbiri erişilebilir değil.

🔧 Teknik Detaylar (Geliştiriciler İçin)

🏗️ Sistem Mimarisi

  • Web Server: LiteSpeed Enterprise 6.3.1
  • Arka Plan: Apache config yüklü (loadApacheConf=1)
  • PHP Mode: phpSuExec=2 (Strict Ownership)
  • Storage: Laravel Multi-Tenancy (tenant1001)
  • Symlink: public/storage/tenant1001 → storage/tenant1001/app/public

📂 Dosya Yapısı

Symlink:
lrwxrwxrwx tuufi.com_:psacln public/storage/tenant1001 → ../../storage/tenant1001/app/public
Target File:
-rw-r--r-- tuufi.com_:psacln storage/tenant1001/app/public/21/Lucid_Origin_*.jpg
Test URL:
https://muzibu.com/storage/tenant1001/21/Lucid_Origin_*.jpg → HTTP 403

🔴 LiteSpeed Error Log

[INFO] Found symbolic link, or owner of symbolic link and link target does not match for path [/var/www/vhosts/muzibu.com/httpdocs/public/storage/tenant1001/21/...], access denied. ret=-1, errno=13

⚠️ Bu hata user/group eşleşmesine rağmen oluşuyor! LiteSpeed phpSuExec=2 modunda ek kontroller var.

✅ Denenen Çözümler

⚠️
Global Config Değişikliği:
/usr/local/lsws/conf/httpd_config.xml:
<checkSymbolLink>0</checkSymbolLink>
<forceStrictOwnership>0</forceStrictOwnership>
❌ Sonuç: İşe yaramadı - phpSuExec=2 bu ayarları override ediyor
⚠️
Ownership Düzeltme:
sudo chgrp -R psacln storage/tenant1001/
❌ Sonuç: Symlink ve target aynı owner/group olmasına rağmen 403
⚠️
Apache Alias (Symlink Bypass):
vhost.conf:
Alias /storage/tenant1001 /var/www/vhosts/.../storage/tenant1001/app/public
❌ Sonuç: LiteSpeed Apache'yi bypass ediyor, Alias işlenmedi
⚠️
.htaccess FollowSymLinks:
public/storage/.htaccess:
<IfModule LiteSpeed>
  Options +FollowSymLinks
</IfModule>
❌ Sonuç: LiteSpeed .htaccess'i static file serving'de görmezden aldı

🔍 Kök Sebep

LiteSpeed phpSuExec=2 Mode: Hardcoded Symlink Restriction

phpSuExec=2 modu, PHP execution için değil, static file serving için de symlink kontrolü yapıyor. Bu kontrol LiteSpeed core seviyesinde ve config dosyalarıyla devre dışı bırakılamıyor.

Nginx sunucularında disable_symlinks off ile çözülen bu sorun, LiteSpeed'de böyle bir directive olmadığı için çözülemiyor.

💡 Olası Çözümler (Sıralı)

✅ ÖNERİLEN

1. phpSuExec Modunu 2'den 1'e Düşür

/usr/local/lsws/conf/httpd_config.xml dosyasında <phpSuExec>2</phpSuExec><phpSuExec>1</phpSuExec>

Avantaj: Symlink'ler çalışmaya başlar, performans optimum
⚠️ Risk: GLOBAL değişiklik - tüm domainler etkilenir, güvenlik seviyesi düşer
ℹ️ Alternatif: Vhost-specific phpSuExec değişikliği mümkün mü kontrol et (LiteSpeed WebAdmin)
⚡ HIZLI

2. Laravel Route ile Serve Et

routes/tenant.php içinde /storage/tenant{id}/{path} route'u oluştur, Storage::download() ile dosyayı PHP üzerinden serve et.

Avantaj: Symlink gerektirmez, tüm platformlarda çalışır
⚠️ Risk: Performans kaybı (PHP her görsel için çalışır), memory kullanımı artar
ℹ️ İyileştirme: Cache headers ekle, X-Sendfile/X-Accel-Redirect kullan (web server'a offload)
🔧 YAPISAL

3. Storage'ı Public Altına Taşı

storage/tenant{id}/app/public/public/storage/tenant{id}/ (hard copy, symlink değil)

Avantaj: Symlink gerektirmez, native web server serving (hızlı)
⚠️ Risk: Laravel best practice ihlali, güvenlik riski (public erişim), disk kullanımı artar
Kullanıcı Talebi: "storage de kalacak!!!" - Bu çözüm uygun değil
☁️ DIŞARIYA

4. CDN/Cloud Storage Kullan

Görselleri AWS S3, Cloudflare R2, veya DigitalOcean Spaces gibi cloud storage'a yükle, Media Library'yi cloud'a yönlendir.

Avantaj: Symlink gerektirmez, CDN avantajı, sunucu yükü azalır
⚠️ Risk: Aylık maliyet, bağımlılık (cloud vendor), migration gerekir
ℹ️ Örnek: Spatie Media Library S3 driver ile entegre edilebilir
🚀 ALTYAPI

5. Web Server Değiştir (LiteSpeed → Nginx)

Plesk'te Apache + LiteSpeed yerine Nginx + PHP-FPM kullan. Nginx'te disable_symlinks off; çalışıyor.

Avantaj: Symlink sorunu çözülür, Nginx performansı iyi
⚠️ Risk: ÇOK BÜYÜK değişiklik, tüm sunucu etkilenir, downtime gerekir
Kullanıcı Geri Bildirimi: "tüm sistemi değiştirmene müsade edemem. bu global bir sistem."

⚖️ Sunucu Karşılaştırması

tuufi.com (ÇALIŞIYOR)

Web Server: Nginx + Apache
Symlink Ayarı: disable_symlinks off
PHP Mode: PHP-FPM
Storage Symlink: ✅ Çalışıyor
# /etc/nginx/conf.d/vhost_nginx.conf
location ~* ^/storage/ {
  disable_symlinks off;
  expires 30d;
}

muzibu.com (ÇALIŞMIYOR)

Web Server: LiteSpeed Enterprise
Symlink Ayarı: checkSymbolLink 0 (IGNORED)
PHP Mode: phpSuExec=2 (STRICT)
Storage Symlink: ❌ HTTP 403
# /usr/local/lsws/conf/httpd_config.xml
<checkSymbolLink>0</checkSymbolLink>
<forceStrictOwnership>0</forceStrictOwnership>
<phpSuExec>2</phpSuExec>
# ⚠️ phpSuExec=2 diğer ayarları override ediyor!

🎯 Sonuç ve Öneri

📊 Durum

  • ✅ AI görselleri başarıyla oluşturuldu (20/20)
  • ✅ Dosyalar storage'da mevcut (tuufi.com_:psacln)
  • ✅ Symlink oluşturuldu ve doğru ownership var
  • ❌ LiteSpeed phpSuExec=2 symlink'leri engelliyor
  • ❌ Global config değişiklikleri işe yaramadı
  • ❌ Sitede görseller erişilemiyor (HTTP 403)

💡 Önerilen Aksiyon

Seçenek A: phpSuExec Değişikliği (ÖNERİLEN)

phpSuExec=2phpSuExec=1 değiştir. Bu GLOBAL değişiklik olduğu için önce LiteSpeed WebAdmin'den vhost-specific ayar mümkün mü kontrol et.

⚠️ Risk: Tüm domainler etkilenir, güvenlik seviyesi düşer (ancak hala secure)

Seçenek B: Laravel Route Serving (HIZLI)

routes/tenant.php içinde route oluştur, X-Sendfile ile serve et. Symlink gerektirmez, hızlı implement edilir.

⚠️ Risk: Performans kaybı (PHP overhead), ancak X-Sendfile ile minimize edilebilir

Seçenek C: Cloud Storage (UZUN VADELI)

AWS S3/Cloudflare R2 entegrasyonu. Symlink sorununu tamamen çözer, CDN avantajı sağlar.

⚠️ Risk: Aylık maliyet, migration çalışması gerekir

📝 Karar Noktası

Kullanıcıya sunulacak 3 seçenek var. Her birinin artı/eksileri açık. Seçenek A (phpSuExec değişikliği) en kolay ve performanslı ama global etki var. Seçenek B (Laravel route) hızlı implement ama performans kaybı var. Seçenek C (cloud) uzun vadeli en iyi çözüm ama maliyet/zaman gerektirir.