# Kurulum Kılavuzu

## Sistem Gereksinimleri

### Desteklenen İşletim Sistemleri

WHost dar ve bilinçli olarak modern bir OS matrisini destekler. Bunların
dışındaki her sürüm, installer başlarken, hiçbir şey kurmadan reddedilir —
tüm gerekçe için bkz. [Desteklenen OS](supported-os.md).

| OS | Sürüm | Durum |
|----|-------|-------|
| Ubuntu | 24.04 LTS (Noble) | Tam Desteklenir |
| Ubuntu | 22.04 LTS (Jammy) | Tam Desteklenir — Python 3.12 deadsnakes PPA'dan; nginx ModSecurity bağlayıcısı doğrulanmış kaynaktan derlenir |
| Debian | 12 (Bookworm) | **1.0 hattında kurulamaz** — Python 3.12 paketi yok; kurulum aracı reddeder. Çoklu-ABI build ile geri gelir |
| AlmaLinux | 9 | Tam Desteklenir |
| Rocky Linux | 9 | Tam Desteklenir |
| CentOS Stream | 9 | Tam Desteklenir |

> **Doğrulama:** Kurulum aracı **Ubuntu 24.04**, **Ubuntu 22.04** ve
> **AlmaLinux 9.8** yüklü temiz sunucularda uçtan uca çalıştırıldı. Bu
> koşumların gerektirdiği düzeltmeler (`agent/requirements.txt`, Python 3.12
> kurulumu, fail2ban günlük dosyası, web sunucusuna derlenen indirmeler için
> pinli özetler ve installer'la gelen imza anahtarları, servislerin
> installer'ın yazdığı yapılandırmayla yeniden başlatılması) yayımlanan
> deponun taşıdığı installer'ın parçasıdır. Rocky Linux 9 ve CentOS Stream 9,
> installer'da AlmaLinux 9 ile aynı yoldan geçer; üçünde de installer
> SELinux'u Enforcing'den Permissive'e çevirir — bkz.
> [RHEL ailesinde SELinux](#rhel-ailesinde-selinux). **Debian 12** bu sürümde
> kurulamaz — desteklenen OS sayfasındaki *Agent Python çalışma zamanı*
> bölümüne bakın.

> **Desteklenmeyenler:** bunların dışındaki her sürüm — aralarında Debian 11
> ve 13, AlmaLinux, Rocky Linux ve CentOS Stream'in 8 ve 10 sürümleri, Red Hat
> Enterprise Linux'un kendisi ve 22.04 ile 24.04 dışındaki her Ubuntu sürümü.
> Installer, desteklenen sürümleri sayan bir hata mesajıyla durur.

### Minimum Donanım

Beta süresince desteklenen her sistem bu boyuttaki sunucularda kuruldu ve test edildi; daha küçük sunucular test edilmedi.

- **CPU:** 2 vCPU
- **RAM:** 4 GB
- **Disk:** 40 GB (kurulumdan hemen sonra işletim sistemi ve WHost birlikte 8,4–11 GB yer kapladı)
- **Ağ:** Statik IP adresi

Üretim için daha fazlasını planlayın: 4+ vCPU, 8+ GB RAM ve barındıracağınız hesaplara göre boyutlandırılmış SSD depolama.

### Ön Koşullar

- Temiz OS kurulumu (mevcut web sunucusu, veritabanı veya mail sunucusu olmamalı)
- Root erişimi (sudo veya root kullanıcı)
- Paket indirmeleri için internet bağlantısı
- Kurulum deposunu indirmek için `git` (installer diğer araçlarını kendisi kurar)
- Sunucu için tam nitelikli bir hostname (örneğin `srv1.example.com`); sistemde zaten ayarlı olmalı ya da `--hostname` ile verilmelidir. Bulut imajları çoğunlukla `ubuntu-4gb-hel1-3` gibi tek etiketli bir adla açılır; installer böyle bir adda hiçbir şey kurmadan durur (bkz. [Hostname](#hostname))

---

## Hızlı Kurulum

```bash
# Installer'ı indir ve çalıştır
cd /tmp
git clone https://wisecp.com/files/whost/whost.git
cd whost/installer
bash install.sh --hostname=srv1.example.com
```

`hostname -f` zaten tam nitelikli bir ad yazıyorsa `--hostname` verilmeyebilir.

Installer otomatik olarak şunları yapar:
- İşletim sisteminizi tespit eder
- Sunucunun hostname'ini ayarlar (bkz. [Hostname](#hostname))
- Gerekli tüm servisleri kurar ve yapılandırır
- API kimlik bilgileri ve yönetici parolası üretir
- Bu sürümün web panelini indirir ve imzasını doğrular
- WHost Agent'ı başlatır

---

## Doğrulanan İndirmeler

Installer'ın web sunucusuna derlediği ya da kural kümesi olarak yüklediği her şey TLS üzerinden alınır ve kullanılmadan önce `installer/lib/` içinde gelen upstream anahtarlarıyla (`nginx-release-keys.pub`, `owasp-modsecurity-signing-key.pub`, `owasp-crs-signing-key.pub`) ayrık bir imzaya karşı denetlenir. ModSecurity-nginx bağlayıcısı ve OWASP Core Rule Set ayrıca pinli bir SHA-256 taşır. nginx kaynak arşivi — yalnız dağıtımın ModSecurity modül paketi göndermediği yerde gerekir, örneğin Ubuntu 22.04 — installer'ın listelediği nginx sürümleri için (1.18.0, 1.22.1, 1.24.0) pinli bir SHA-256 taşır; başka bir sürümde yalnız imzasıyla denetlenir. Kontrolü geçemeyen bağlayıcı ya da nginx kaynağı derlenmez: modül dışarıda kalır ve installer bunu çıktısında söyler. Kontrolü geçemeyen kural kümesi kurulumu durdurur.

Her PHP sürecinin yüklediği ionCube Loader, ionCube'un indirme sunucusundan tek bir adlandırılmış sürüm (15.5.1) olarak alınır ve arşivi installer'ın o sürüm ve makinenin mimarisi (x86_64, aarch64) için pinlediği SHA-256 ile eşleşirse açılır; kontrolü geçemeyen arşiv ya da başarısız indirme kurulumu durdurur.

## Panel Arşivi

Web paneli, deponun yanında ayrı ve imzalı bir arşiv olarak yayımlanır: `whost-panel-<sürüm>.tar.gz`. Installer frontend adımında bu arşivi `.asc` imzası ve `.sha256` dosyasıyla birlikte indirir; sürüm imzasını `installer/lib/whost-release.pub` içindeki açık anahtarla, `.sha256` dosyası varsa SHA-256 özetini de doğrular; imzası olmayan ya da bir kontrolü geçemeyen arşivi açmaz.

Arşivin nereden geldiğini iki değişken belirler:

| Değişken | Etkisi |
|---|---|
| `WHOST_PANEL_URL` | Başka bir adresten, örneğin bir yansıdan indirir. `.asc` dosyası orada da arşivin yanında yayımlanmış olmalıdır; `.sha256` dosyası varsa o da denetlenir. |
| `WHOST_PANEL_ARCHIVE` | İndirmek yerine yerel bir kopyayı kullanır; dışarıya erişimi olmayan sunucular içindir. `.asc` dosyasını (isteğe bağlı `.sha256` ile) yanında tutun; aynı kontroller uygulanır. İki değişken birlikte verilirse yerel kopya kullanılır. |

```bash
WHOST_PANEL_ARCHIVE=/root/whost-panel-VERSION.tar.gz bash install.sh
```

`VERSION` yerine kurduğunuz sürümü yazın; `bash install.sh --help` bunu ilk satırında gösterir.

Arşiv indirilemez ya da doğrulanamazsa installer paneli kurmaz ve bunu çıktısında söyler (`Panel archive could not be fetched or verified - the panel is NOT installed`, ardından beklediği dosya adı). Kapanış denetimi de eksik panel sayfasını bildirir ve koşum, tamamlanma ekranı yerine hatayla biter. Arşivi sağlayıp `bash install.sh` komutunu yeniden çalıştırın; panel yerindeyse indirme atlanır.

---

## Özel Kurulum

### Komut Satırı Seçenekleri

```bash
bash install.sh [OPTIONS]
```

| Seçenek | Açıklama | Varsayılan |
|---------|----------|------------|
| `--webserver=TYPE` | Web sunucusu: `nginx_apache` ya da `nginx` (aşağıya bakın) | `nginx_apache` |
| `--php-versions=LIST` | Virgülle ayrılmış PHP sürümleri | `5.6,8.2,8.3,8.4` |
| `--php-default=VER` | Varsayılan PHP sürümü | `8.4` |
| `--hostname=FQDN` | Sunucu hostname'i, tam nitelikli; sistem hostname'i olarak ayarlanır, ayrıca self-signed sertifikanın konusu ve aşağıdaki varsayılanların tabanıdır. Bkz. [Hostname](#hostname) | sistemin adı (`hostname -f`); o ad tam nitelikli değilse zorunludur |
| `--nameservers=NS1,NS2` | Yeni DNS zone'larına yazılan nameserver'lar | `ns1.<hostname>,ns2.<hostname>` |
| `--mail-hostname=HOST` | Mail sunucusu hostname'i | `mail.<hostname>` |
| `--ssl-email=EMAIL` | Let's Encrypt bildirimleri için e-posta adresi | ayarlı değil |
| `--timezone=TZ` | Sunucu saat dilimi, örn. `Europe/Istanbul` | otomatik algılanır, bilinmiyorsa `UTC` |
| `--no-dns` | PowerDNS kurulumunu atla | DNS aktif |
| `--no-mail` | Postfix/Dovecot kurulumunu atla (Roundcube ve Rspamd de atlanır) | Mail aktif |
| `--no-ftp` | Pure-FTPd kurulumunu atla | FTP aktif |
| `--no-firewall` | Güvenlik duvarı yapılandırmasını atla | Güvenlik duvarı aktif |
| `--no-fail2ban` | Fail2Ban kurulumunu atla | Fail2Ban aktif |
| `--no-modsecurity` | ModSecurity (OWASP WAF) kurulumunu atla | ModSecurity `detection_only` modunda kurulur (kaydeder, engellemez) |
| `--help` | Yardım mesajını göster | - |

**Web sunucusu ve panel.** `nginx_apache` (varsayılan) ya da `nginx` ile paneli nginx sunar: `https://<hostname>/admin/`. Installer `apache`, `openlitespeed` ve `litespeed` değerlerini hiçbir şeyi değiştirmeden reddeder ve desteklenen iki modu söyler. Siteleri OpenLiteSpeed ya da LiteSpeed Enterprise üzerinde barındırmak için varsayılanla kurun ve yönetici panelindeki **Eklentiler** bölümünden geçiş yapın; LiteSpeed Enterprise sunucusunun kendisi orada etkinleştirildiğinde indirilir.

### Örnekler

```bash
# Sadece Nginx, PHP 8.3 ve 8.4 ile
bash install.sh --webserver=nginx --php-versions=8.3,8.4 --php-default=8.4

# Tüm servisler, PHP 7.4'ten 8.5'e
bash install.sh --php-versions=7.4,8.0,8.1,8.2,8.3,8.4,8.5

# Minimal kurulum (DNS, mail, FTP yok)
bash install.sh --no-dns --no-mail --no-ftp

# Kendi nameserver'ları, hostname ve Let's Encrypt iletişim adresi ile
bash install.sh --hostname=srv1.example.com --nameservers=ns1.example.com,ns2.example.com --ssl-email=admin@example.com
```

### Hostname

Panelin kurulduğu ad; self-signed sertifikanın konusu, varsayılan nameserver'ların (`ns1.<hostname>`) ve mail hostname'inin (`mail.<hostname>`) tabanı, DKIM alan adı ve panelin e-posta gönderdiği adresin alan adı olur (SMTP relay yapılandırılmadığı sürece `whost@<hostname>`). Bu yüzden tam nitelikli olmak zorundadır: harf, rakam ve tireden oluşan en az iki etiket, son etiket tümüyle sayısal olamaz. Tek etiketli bir ad (`ubuntu-4gb-hel1-3`, `localhost`) ya da bir IP adresi reddedilir ve installer hiçbir şey kurmadan durur:

```
[ERROR] 2026-09-26 09:14:03 Server hostname "ubuntu-4gb-hel1-3" is not a fully qualified domain name.
[ERROR] 2026-09-26 09:14:03 Run the installer with --hostname=<fqdn>, for example: --hostname=srv1.example.com
```

Installer sistemin de bu ada yanıt vermesini sağlar: `hostnamectl set-hostname <fqdn>` çalıştırır ve `/etc/hosts` dosyasının `127.0.1.1` satırını bu ada çevirir (tam olarak bir satır bırakılır; dosyada yoksa eklenir). Böylece `hostname -f` panelin adını yazar; mail sunucusu ve agent da bu adı okur. `/etc/hosts` dosyası cloud-init tarafından yönetilen bulut imajlarında değişiklik yeniden başlatmalardan sonra da yerinde kalır. Adı zaten taşıyan bir sunucuda koşum hiçbir şeyi değiştirmez.

Ada genel DNS'te bir A kaydı verin. Kurulum A kaydı olmadan da tamamlanır, ancak yerel mail sunucusu her gönderen adresinin alan adını denetler: ad çözülmediği sürece panelin bu sunucu üzerinden gönderdiği e-postalar (bildirimler, parola sıfırlama, e-postayla gelen giriş kodları) `450 4.1.8 Sender address rejected: Domain not found` yanıtıyla geri çevrilir ve agent logu bildirimi `email=failed` olarak kaydeder.

### RHEL ailesinde SELinux

WHost henüz bir SELinux politikası taşımıyor. SELinux **Enforcing** iken — AlmaLinux, Rocky Linux ve CentOS Stream kendi kurulum ortamlarından kurulduğunda varsayılan budur — nginx agent'a bağlanamayabilir (panelin API'si `502` döner) ya da PHP sitelerini 8080'deki Apache'ye iletemeyebilir, fail2ban hesap günlüklerini okuyamayabilir ve açılışta `quotaon` reddedilir. Bu yüzden installer, SELinux'u uygulayan bir sunucuyu hiçbir şey kurmadan önce **Permissive**'e çevirir: çalışan sistemde (`setenforce 0`) ve `/etc/selinux/config`'te (`SELINUX=permissive`), böylece kip yeniden başlatmadan sonra da geçerli kalır. Bunu ekrana, `/var/log/whost/install.log`'a ve kapanış özetine yazar:

```
[WARN] 2026-10-01 10:02:11 SELinux switched from Enforcing to Permissive: the running system and /etc/selinux/config
```

Permissive kipte SELinux dosyaları etiketlemeye ve reddedeceği işlemleri günlüğe yazmaya (`/var/log/audit/audit.log`'daki AVC kayıtları) devam eder, ama hiçbir şeyi reddetmez. Zaten Permissive olan (bazı bulut imajları böyle gelir) ya da SELinux'u kapalı bir sunucuya dokunulmaz. Kurulum başarısız olup geri alınırsa önceki kip geri konur. WHost'un SELinux enforcing ile çalışması beta sonrasına planlandı; o zamana kadar sunucuyu Permissive tutun (`getenforce` geçerli kipi yazar).

> **PHP 5.6 notu:** PHP 5.6, eski müşteri scriptlerini desteklemek için
> varsayılan sürüm listesine dahildir. Ubuntu'da sorunsuz kurulur
> (`ondrej/php` PPA'sı); RHEL ailesi 9'da Remi reposu artık PHP 5.6 paketlerini
> yayınlamamaktadır ve installer bir uyarı ile bunu atlar
> (`PHP 5.6 unavailable on RHEL 9+ (Remi dropped EOL series) — skipping`).
> Modern hesaplar OS'ten bağımsız olarak PHP 8.4 (varsayılan) kullanır.

---

## Kurulum Sonrası

### Kurulumu Doğrula

```bash
# Servis durumunu kontrol et
systemctl status whost-agent

# Agent'ın yanıt verdiğini doğrula (yalnız 127.0.0.1'de dinler)
curl -k https://127.0.0.1:2000/health
```

Yanıt `{"status":"ok","version":"<sürüm>"}` biçimindedir.

Agent ağacı `/opt/whost/agent` root'a aittir ve diğer kullanıcılara kapalıdır (`0750` dizin, `0640` dosya); kiracı kabukları agent'ın kaynak kodunu veya derlenmiş modüllerini okuyamaz. `stat -c '%a' /opt/whost/agent` çıktısı `750` olmalıdır.

### Yönetici Paneline Erişim

Yerleşik yönetici paneli şu adresten erişilebilir:

```
https://<SERVER_HOSTNAME>/admin/
```

Panel sunucunun IP adresinden de yanıt verir. Güvenilir bir sertifika kurulana kadar tarayıcı self-signed sertifika için uyarır (bkz. Sorun Giderme altında *SSL Sertifikası Sorunları*).

Kullanıcı adı `admin` ve kurulum aracının sonunda ekrana basılan yönetici parolasıyla giriş yapın; kurulum aracı bastığı değeri ayrıca `/etc/whost/admin_password` dosyasında saklar (yalnız root okuyabilir). API anahtarları yönetici panelinde **Ayarlar → API Erişimi** üzerinden yönetilir.

Kurulum aracı `/etc/whost/agent.conf` dosyasına `license:` bloğu yazmaz ve lisans seçeneği almaz; bu yüzden agent anahtarsız, `NOT_ACTIVATED` durumunda başlar. İlk ekran olağan giriş formudur: kurulum aracının yazdırdığı yönetici parolası kabul edildiğinde panel lisans sayfasında açılır; sayfa etkin bir lisans olmadığını söyler ve anahtar formunu taşır. Anahtarı gönderen bu girişin oturumudur; bir anahtar kabul edilene kadar bu oturum panelde başka hiçbir şeyi açmaz. Aktivasyon, lisans servisine giden HTTPS üzerinden yapılır, lisansı bu sunucunun genel IP adresine ve donanımına bağlar ve verilen kimlik bilgilerini `agent.conf` dosyasına kaydeder; ardından lisans sayfası etkin lisansı gösterir ve panelin geri kalanı açılır. Sonrasında lisans **Ayarlar → Lisans** üzerinden yönetilir. İlk giriş adımları için [yönetici kullanıcı kılavuzuna](admin-user-guide.md) bakın.

**Sunucuyu aynı anahtarla yeniden kurmak.** Lisans servisi bir anahtarı, onu aktive eden kuruluma kayıtlı tutar; kayıt, yalnız o kurulumun `agent.conf` dosyasında duran kimlik bilgileriyle birlikte yaşar. Yeniden kurulumdan sonra bu kimlik bilgileri artık yoktur ve aktivasyon formu "Bu lisans anahtarı zaten bir kuruluma kayıtlı" yanıtını verir. Lisansı lisans sağlayıcınızda yeniden düzenletin (reissue; WISECP'den alınan lisanslarda wisecp.com'daki hizmet yönetim ekranı), ardından anahtarı forma yeniden girin. Reissue, sonrasında lisans servisine ulaşan ilk isteğe verilir: önceki kurulum hâlâ çalışıyorsa reissue'dan önce onun agent'ını durdurun (`systemctl stop whost-agent`); aksi hâlde yeni kimlik bilgilerini bir sonraki denetiminde o alır ve yeni sunucu yine reddedilir. Reissue sırasında çalışmaya devam eden bir kurulumun bir şey yapması gerekmez — bir sonraki denetimi yeni kimlik bilgilerini kendiliğinden uygular.

Yeni bir kurulum yönetici girişlerini her adresten kabul eder: CAPTCHA yapılandırılmamıştır ve admin IP beyaz listesi boştur; giriş formunu yalnız web sunucusunun istek limiti, agent'ın kilitleme mekanizması ve `whost-agent` fail2ban jail'i korur. İlk girişten sonra **Ayarlar → Güvenlik** sayfasını açıp **Admin Panel IP Beyaz Listesi** ile **CAPTCHA Koruması**'nı ayarlayın; installer'ın kapanış çıktısı da aynı şeyi söyler.

---

### Disk kotası

Hesap başına disk limitleri `/` üzerindeki dosya sistemi kotasıyla uygulanır. Kök dosya sistemi ext4 ise installer bağlama seçeneklerine `usrquota,grpquota` ekler, `aquota.*` dosyalarını oluşturur, kotayı açar, ardından **gerçekten etkin olup olmadığını denetler** ve sonucu çıktısında söyler. Kök XFS ise hiçbir şeyi değiştirmez, yalnız `uquota` bağlama seçeneğinin gerektiğini çıktısında hatırlatır (yeniden başlatma gerekebilir) ve ardından aynı denetimi yapar; başka bir dosya sisteminde kotayı bir uyarıyla atlar.

Kota `quota_v2` çekirdek modülünü ister. Ubuntu bulut imajlarının açıldığı çekirdeğin temel modül paketi bu modülü içermez. Modül yoksa installer `linux-modules-extra-<çalışan çekirdek>` paketini, `linux-image-virtual` meta paketini kullanan imajlarda ayrıca `linux-image-extra-virtual` paketini kurar; böylece sonraki çekirdek güncellemeleri de modülü getirir. İkinci paket generic çekirdek imajına bağımlıdır; bu yüzden çekirdek firmware paketlerini (diskte yaklaşık 0,7 GB) ve varsa daha yeni bir çekirdeği de kurar; o çekirdek bir sonraki yeniden başlatmada devreye girer. Yalnız çalışan çekirdeğin modüllerini kurmak daha az yer tutardı, ama bir sonraki çekirdek güncellemesi kotayı sessizce kapatırdı.

Installer `Disk quota is NOT active on /` yazıyorsa panel her planın disk limitini kaydedip göstermeye devam eder, ama hiçbir şey onu uygulamaz; agent her uygulama denemesinde günlüğe hata yazar. ext4'te installer bu durumda kota bağlama seçeneklerini `/etc/fstab` dosyasından geri çıkarır ve `aquota.*` dosyalarını siler; böylece sunucu her açılışta başarısız bir `quotaon.service` ile gelmez. ext4'te kotayı sonradan açmak için:

1. Dağıtımınızın `fs/quota/quota_v2` modülünü sağlayan çekirdek modül paketini kurun (Ubuntu: `apt-get install linux-modules-extra-$(uname -r) linux-image-extra-virtual`), ardından `modprobe quota_v2` çalıştırın.
2. `/etc/fstab` dosyasındaki `/` satırının seçeneklerine `usrquota,grpquota` ekleyin; sonra `mount -o remount /`, `quotacheck -cugm /` ve `quotaon -v /` çalıştırın.
3. `quotaon -p /` ile doğrulayın; kullanıcı ve grup kotası `on` görünmelidir.

Limitler yalnız `/` üzerinde uygulanır: agent her hesabın limitini kök dosya sistemine yazar; `/home` dizini ayrı bir dosya sisteminde olan sunucuda limitler uygulanmaz.

## Servis Yönetimi

```bash
# WHost Agent
systemctl start whost-agent
systemctl stop whost-agent
systemctl restart whost-agent
systemctl status whost-agent

# Logları görüntüle (ajan agent.log'a yazar; journal yalnız birimin başlama / durma olaylarını tutar)
tail -f /var/log/whost/agent.log
```

Ubuntu'da `unattended-upgrades` güvenlik güncellemelerini her gün kurar; ardından `needrestart`, güncellenen bir kütüphaneyi kullanan servisleri yeniden başlatır — WHost Agent da bunların arasındadır. Panel ve API bu yeniden başlatma süresince (küçük bir sunucuda yaklaşık 15–20 saniye) yanıt vermez; agent geri geldiğinde dosyalarını denetler ve lisansını yeniden doğrular. Installer bu dağıtım varsayılanını olduğu gibi bırakır: eski kütüphaneyle çalışmaya devam eden bir servis düzeltmeyi almış olmaz.

---

## Güvenlik Duvarı

Installer aşağıdaki portları açar, gerisini reddeder: Ubuntu'da UFW'nin gelen trafik politikasını reddet olarak ayarlar; RHEL ailesinde aşağıdaki servisleri firewalld'nin varsayılan bölgesine ekler (bölge listelemediği her şeyi reddeder) ve o bölgenin varsayılan olarak açtığı `cockpit` servisini kaldırır. Liste `--no-dns`, `--no-mail` ya da `--no-ftp` seçeneklerinden bağımsız olarak aynıdır; `--no-firewall` verilirse güvenlik duvarına dokunulmaz.

| Port | Protokol | Servis |
|------|----------|--------|
| 22 | TCP | SSH |
| 80 | TCP | HTTP |
| 443 | TCP | HTTPS |
| 21 | TCP | FTP |
| 30000–30100 | TCP | FTP pasif veri aralığı |
| 25 | TCP | SMTP |
| 465, 587 | TCP | SMTP gönderimi (implicit TLS / STARTTLS) |
| 110, 995 | TCP | POP3 / POP3S |
| 143, 993 | TCP | IMAP / IMAPS |
| 53 | TCP + UDP | DNS |
| 2000 | TCP, yalnız loopback | WHost Agent — `127.0.0.1`'e bağlıdır, firewall'da **açılmaz**; panel ve `/api/v1/` web sunucusu üzerinden 443'ten sunulur |

### Manuel Port Yönetimi

```bash
# Ubuntu (UFW) — örnek: ek bir servis portu
ufw allow 8443/tcp

# AlmaLinux / Rocky Linux / CentOS Stream (firewalld)
firewall-cmd --permanent --add-port=8443/tcp
firewall-cmd --reload

# 2000/tcp açılmaz: agent yalnız loopback'te dinler; panel dahil her
# istemci ona https://<host>/api/v1/ üzerinden ulaşır.
```

---

## Sorun Giderme

### Agent başlamıyor

```bash
# Konfigürasyon dosyasının yüklendiğini kontrol et (PYTHONPATH servis birimindeki gibi)
PYTHONPATH=/opt/whost/agent /opt/whost/venv/bin/python -c "from whost_agent.config import load_config; load_config()"

# Port erişilebilirliğini kontrol et
ss -tlnp | grep 2000

# Birimin başlama/durma olayları; agent'ın kendi çıktısı agent.log'a gider
journalctl -u whost-agent --no-pager -n 50
tail -50 /var/log/whost/agent.log
```

Agent log'unda `ModuleNotFoundError: No module named 'paramiko'` görünüyorsa,
venv'de bağımlılıklar eksiktir — `pip install`'i yeniden çalıştır:

```bash
/opt/whost/venv/bin/python -m pip install --require-hashes -r /opt/whost/agent/requirements.lock
systemctl restart whost-agent
```

### SSL Sertifikası Sorunları

Installer hostname için kendinden imzalı bir sertifikayı
`/etc/whost/ssl/cert.pem`, anahtarını `/etc/whost/ssl/key.pem` konumunda,
ona ihtiyaç duyan herhangi bir adımdan **önce** oluşturur. Panelin nginx
sitesi, Postfix, Dovecot ve agent'ın loopback dinleyicisi bu çifti
kullanır. Yollar panelin nginx yapılandırmasında ve agent'ın servis
biriminde sabittir; bu yüzden `/etc/whost/agent.conf` içindeki
`server.ssl_cert` ve `server.ssl_key` anahtarları sunulan sertifikayı
değiştirmez. Güvenilir bir sertifika kullanmak için iki dosyayı yerinde
değiştirin (anahtar yalnız root tarafından okunabilir kalsın), ardından
onları okuyan servisleri yeniden yükleyin:

```bash
systemctl reload nginx postfix dovecot
systemctl restart whost-agent
```

Pure-FTPd kendi self-signed sertifikasını kullanır
(Ubuntu'da `/etc/ssl/private/pure-ftpd.pem`, RHEL ailesinde
`/etc/pki/pure-ftpd/pure-ftpd.pem`).

### Multi-OS Spesifik Sorunlar

#### Ubuntu'da `Unable to locate package php<version>-fpm`

PHP paketleri `ondrej/php` PPA'sından gelir; installer istenen sürüm
yapılandırılmış kaynaklarda yoksa bu PPA'yı ekler. PPA eklenemezse
installer o noktada durmaz; paket kurulumunda bu mesajla durur. PPA'nın
tanımlı olduğunu kontrol edin (`grep -rl ondrej /etc/apt/sources.list.d/`),
ardından installer'ı yeniden çalıştırın.

#### AlmaLinux, Rocky Linux ya da CentOS Stream'de panelin API'si `502` dönüyor

Giriş sayfası açılıyor ama her giriş başarısız oluyor ve nginx hata
günlüğünde `connect() to 127.0.0.1:2000 failed (13: Permission denied)`
görünüyor: SELinux enforcing (kurulumdan sonra geri çevrilmiş bir
sunucu). Şimdi ve sonraki açılış için Permissive'e çevirin (bkz.
[RHEL ailesinde SELinux](#rhel-ailesinde-selinux)):

```bash
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
```

#### Installer başlamadan `git: command not found`

Hızlı kurulum depoyu `git` ile indirir; installer diğer temel araçlarını
(`curl`, `wget`, `tar`, `unzip` ve diğerleri) sonra kendisi kurar. git
içermeyen bir imajda önce onu kurun:

```bash
dnf install -y git        # AlmaLinux, Rocky Linux, CentOS Stream
apt-get install -y git    # Ubuntu
```

#### RHEL ailesinde Nginx, Apache 404 sayfasını döndürüyor

RHEL'de `mod_ssl`, `/etc/httpd/conf.d/ssl.conf` dosyasına
`Listen 443 https` bırakır ve bu portu Nginx'ten çalar. Installer,
`nginx_apache` modunda bu listen direktifini devre dışı bırakır. Eğer
yanlış sayfayı görüyorsan, doğrula:

```bash
grep -i '^Listen 443\|^#Listen 443' /etc/httpd/conf.d/ssl.conf
ss -tlnp | grep ':443 '
```

`^Listen 443` satırı yorumlanmış olmalı; `:443` portu `httpd` değil
`nginx`'e ait olmalı. Gerekirse her iki servisi yeniden başlat:

```bash
systemctl restart httpd nginx
```

#### Hesap oluşturmada `nginx: [emerg] Invalid input: IncludeOptional`

ModSecurity v3 (nginx bağlayıcısı) yalnız `Include`'u kabul eder,
`IncludeOptional`'ı değil; bir `Include` deseni de en az bir dosyayla
eşleşmelidir. Installer `/etc/modsecurity/modsecurity.conf` dosyasına
`Include /etc/modsecurity/custom/*.conf` satırını, desen her zaman
eşleşsin diye de bir yer tutucu dosya
(`/etc/modsecurity/custom/00-placeholder.conf`) yazar. Hata manuel bir
düzenlemeden sonra çıkıyorsa `IncludeOptional`'ı `Include` ile değiştirin
ve `/etc/modsecurity/custom/` içinde en az bir `.conf` dosyası bırakın.

### Geri Alma (Rollback)

Bir adım başarısız olduğunda installer durur ve kendisini durduran komutu hem çıktısında hem de transcript'te adıyla yazar:

```
[ERROR] <date> <time> Installer stopped: "<command>" exited with <code> (transcript: /var/log/whost/install.log)
```

Nedeni giderin ve `bash install.sh` komutunu aynı seçeneklerle yeniden çalıştırın. İkinci koşum adımlardan yeniden geçer ve kurulumu tamamlar: paket kurulumları ve yapılandırma dosyaları aynı sonucu verir, phpMyAdmin, Roundcube ve yerinde duran panel olduğu gibi bırakılır; yönetici parolası, API anahtarı ve secret'ı ile servis veritabanı parolaları yeniden üretilir — kapanış ekranı yeni değerleri basar. Kullanımdaki bir sunucuda installer'ı yeniden çalıştırmayın: `agent.conf` dosyasını baştan yazar, bu da lisans kimlik bilgilerini ve panelden kaydedilen ayarları siler; Ubuntu'da ayrıca barındırma hesaplarının PHP-FPM havuzlarını kaldırır.

Hatanın neredeyse her zaman oluştuğu yer olan installer'ın kendi adım fonksiyonlarının içindeki bir hata, önceden koşmuş adımları geri almaz; yalnız `install.sh` içindeki üst düzey bir komutun hatası kayıtlı geri alma adımlarını çalıştırır (o ana kadar kurulan servisleri durdurur, installer'ın oluşturduğu veritabanlarını siler, `/opt/whost`'u, panel ağacını ve ModSecurity, phpMyAdmin ve Roundcube ağaçlarını kaldırır). Yarım kalmış bir kurulumu elle kaldırmak için (geç aşamada duran bir koşum aşağıdaki Kaldırma bölümünde listelenen dosyaları da yazmış olabilir):

```bash
systemctl stop whost-agent
rm -rf /opt/whost
rm -rf /etc/whost
rm -f /etc/systemd/system/whost-agent.service
systemctl daemon-reload
```

---

## Kaldırma

Varsayılan bir kurulum (`--webserver=nginx_apache`, Ubuntu 24.04), agent'ın ilk açılışında yazdıkları dahil, aşağıdaki dosyaları bırakır. WHost'a ait olanları kaldırın; servis paketlerini (nginx, Apache, MariaDB, PowerDNS, Postfix, Dovecot, Pure-FTPd, Rspamd, PHP) ve verilerini, servisleri de kaldırmayı düşünmüyorsanız yerinde bırakın.

```bash
# WHost unit'lerini durdur ve devre dışı bırak
systemctl disable --now whost-agent whost-policyd whost-http-ban.path whost-http-ban-apply
rm -f /etc/systemd/system/whost-agent.service /etc/systemd/system/whost-policyd.service \
      /etc/systemd/system/whost-http-ban.path /etc/systemd/system/whost-http-ban-apply.service
rm -f /etc/systemd/system/php*-fpm.service.d/whost-limits.conf
systemctl daemon-reload

# WHost ağaçları: agent + venv + paketlenmiş Node.js runtime'ları, config + hesaplar, panel, durum, yedekler + metrikler, loglar
rm -rf /opt/whost /etc/whost /var/www/whost /var/lib/whost /var/whost /var/log/whost

# WHost'un eklediği web sunucusu parçaları (ardından nginx ve Apache'yi yeniden yükleyin ya da paketleri kaldırın)
rm -f /etc/nginx/sites-enabled/whost-panel.conf /etc/nginx/sites-available/whost-panel.conf \
      /etc/nginx/snippets/whost-panel-locations.conf /etc/nginx/snippets/whost-security-headers.conf \
      /etc/nginx/conf.d/whost-panel-ratelimit.conf /etc/nginx/conf.d/whost-banlist.conf \
      /etc/nginx/conf.d/whost-cloudflare-realip.conf /etc/nginx/conf.d/whost-modsecurity.conf
rm -f /etc/apache2/conf-enabled/whost-status.conf /etc/apache2/conf-available/whost-status.conf \
      /etc/apache2/conf-enabled/whost-banlist.conf
rm -rf /etc/modsecurity            # ModSecurity yapılandırması, OWASP CRS kopyası, hesap bazlı kurallar

# phpMyAdmin ve Roundcube: upstream arşivlerinden açılır, panel sitesi üzerinden sunulur
rm -rf /usr/share/phpmyadmin /etc/phpmyadmin /var/lib/phpmyadmin /usr/share/roundcube /var/lib/roundcube
rm -f /etc/nginx/snippets/phpmyadmin.conf /etc/nginx/snippets/roundcube.conf

# PHP drop-in'leri, log rotation, fail2ban, SSH ve Dovecot drop-in'leri
rm -f /etc/php/*/fpm/conf.d/99-whost-opcache.ini
rm -f /etc/logrotate.d/whost /etc/logrotate.d/whost-accounts /etc/logrotate.d/modsecurity
rm -f /etc/fail2ban/filter.d/whost-agent.conf /etc/fail2ban/filter.d/whost-web-scan.conf \
      /etc/fail2ban/action.d/whost-http-deny.conf /etc/fail2ban/action.d/whost-nginx-deny.conf
rm -f /usr/local/sbin/whost-http-ban
rm -rf /var/lib/fail2ban/whost-http-ban
rm -f /etc/ssh/sshd_config.d/10-whost-accounts.conf /etc/ssh/sshd_config.d/60-whost-hardening.conf
rm -f /etc/dovecot/conf.d/95-whost-quota.conf

# Çekirdek ayarları (ptrace kısıtı, swap ayarı); çalışan değerler bir sonraki yeniden başlatmada geri döner
rm -f /etc/sysctl.d/99-whost-ptrace.conf /etc/sysctl.d/99-whost-perf.conf
```

Servisleri de kaldırmıyorsanız yerinde kalır: `/etc/fail2ban/jail.local` (installer'ın jail'leri, `[whost-agent]` dahil) ve `/etc/fail2ban/fail2ban.local`, ionCube loader (`/usr/local/ioncube`, `/etc/php/*/mods-available/00-ioncube.ini` ve `conf.d` bağları), `/etc/mysql/mariadb.conf.d/` içindeki MariaDB drop-in'leri `99-whost.cnf` (yalnız loopback) ve `99-whost-tuning.cnf` (RAM'e göre boyutlanmış) ile `/var/lib/mysql-files`, `/root/.my.cnf` içindeki MariaDB root girişi, MariaDB veritabanları `powerdns`, `pureftpd`, `roundcubemail`, `vmail` ve kullanıcıları (`powerdns`, `pureftpd`, `roundcube`, `vmail`), `vmail` kullanıcısı ve grubu ile `whost-noshell` / `whost-sso` grupları, UFW kuralları (`ufw status numbered`), `/etc/fstab`'daki `usrquota,grpquota` bağlama seçenekleri ile `/aquota.user` ve `/aquota.group`, kota adımının imajda eksik olduğu için kurduğu çekirdek modül paketleri (`linux-modules-extra-*`, `linux-image-extra-virtual`), installer'ın eklediği APT kaynakları (`ondrej/php`, `deadsnakes`, `rspamd`).

---

**Geliştirici: [WISECP LLC.](https://wisecp.com)**
**İletişim:** hello@wisecp.com
