Какво е LVE-stats 2 и защо е важен?
Това е компонент на CloudLinux OS, който събира детайлна статистика за ресурсите, които използват хостинг акаунтите (CPU, RAM, IO и др.).
📌 Защо е нужно да го използваме?
Старата система за статистика:
- Записва данните твърде грубо – на интервали от 1 час
- Не улавя внезапни пикови натоварвания
- Не показва кой процес точно е претоварил акаунта
- Показва неточни нотификации за грешки
✅ Какво е по-доброто в LVE-stats 2:
- По-точна статистика, на много по-кратки интервали
- 100% CPU = 1 ядро, не всички ядра
- Снимки (“snapshots”) на процесите при проблеми
- Поддръжка за MySQL и PostgreSQL
- По-добри и лесни за четене графики
- Може да се добавят персонализирани плъгини
⚙️ Инсталиране / Ъпдейт / Връщане към стара версия
➕ Инсталиране:
yum install lve-stats
🔄 Ъпдейт:
yum update lve-stats
При първото стартиране старите настройки се прехвърлят автоматично. Пълната миграция на данни може да отнеме от 2 до 8 часа.
⬅️ Връщане към стара версия:
yum downgrade lve-stats
Ако имаш проблем, можеш да се свържеш със съпорта: https://cloudlinux.zendesk.com
🛠️ Конфигурация
Главният файл с настройки се намира тук:
/etc/sysconfig/lvestats2
В него може да настроиш:
- Какъв тип база данни се използва (sqlite, MySQL, PostgreSQL)
- Потребителско име/парола за връзка с БД
- Колко време да се пази историята (по подразбиране – 30 дни)
- Интервали за запазване на статистика (по подразбиране – на 5 сек.)
- Да се включват/изключват snapshots
- Да се използват UID-и по-големи от 109 (ако сървърът го поддържа)
📬 Имейл нотификации
Можеш да изпращаш имейли:
- до администратора
- до реселъри
- до крайни потребители
Включително за:
- Прекалено ползване на CPU, RAM, IO, IOPS, процеси и т.н.
Настройва се в:
/etc/sysconfig/lvestats.config/StatsNotifier.cfg
Там можеш да укажеш:
- Колко грешки трябва да има, за да се изпрати имейл
- През какъв интервал да се изпращат (например на 12 часа)
- От кого да идва имейлът и какъв да е subject-а
🔍 Съхраняване на “snapshots” при проблеми
Когато някой акаунт претовари ресурси, LVE-stats 2 може да направи моментна снимка (snapshot) на:
- Процесите, които работят в този момент
- Активните SQL заявки (ако има)
Тези настройки се управляват тук:
/etc/sysconfig/lvestats.config/SnapshotSaver.cfg
🔐 Примерна настройка с MySQL
- Инсталирай MySQL/MariaDB (ако не е наличен)
yum install mariadb mariadb-server
systemctl start mariadb
systemctl enable mariadb
- Създай база данни и потребител:
CREATE DATABASE db_lvestats2;
CREATE USER ‘lvestats2’@’localhost’ IDENTIFIED BY ‘парола’;
GRANT ALL PRIVILEGES ON db_lvestats2.* TO ‘lvestats2’@’localhost’;
FLUSH PRIVILEGES;
- Настрой lvestats2:
Отвори файла: /etc/sysconfig/lvestats2
Промени:
db_type = mysql
connect_string = lvestats2:парола@localhost/db_lvestats2
- Създай таблиците:
/usr/sbin/lve-create-db
- Рестартирай услугата:
service lvestats restart
- (по избор) Създай втори потребител с достъп само за четене, ако искаш други потребители да могат да виждат статистиката без да могат да я променят.
📧 Съобщения с кодиране UTF-8
Ако използваш имейл шаблони с кирилица, добави в конфигурацията:
NOTIFY_CHARSET_EMAIL=utf-8
🧪 Команден инструмент (CLI)
Можеш да управляваш LVE-stats 2 и от конзолата с cloudlinux-config и lveinfo, lvechart, lve-read-snapshot.
📈 В бъдеще очакваме:
- Нотификации и за други контролни панели, не само cPanel
- Автоматично увеличаване/намаляване на лимити според натоварването
- Реселър лимити с аналитика
- Автоматични реакции при продължително натоварване – напр. предупреждение или временно спиране
⚙️ Настройка на LVE-stats2 с MySQL
1. Инсталиране на MySQL сървър
Ако MySQL не е инсталиран:
За CloudLinux OS 6:
bash
КопиранеРедактиране
yum install mysql mysql-server
service mysqld start
chkconfig mysqld on
За CloudLinux OS 7:
yum install mariadb mariadb-server
systemctl start mariadb.service
systemctl enable mariadb.service
2. Създаване на база данни и потребител
Влезте в MySQL с командата:
mysql
След това въведете следните команди:
CREATE DATABASE db_lvestats2;
CREATE USER ‘lvestats2’@’localhost’ IDENTIFIED BY ‘lvestats2_passwd’;
GRANT ALL PRIVILEGES ON db_lvestats2.* TO ‘lvestats2’@’localhost’;
FLUSH PRIVILEGES;
Можете да използвате свои имена и пароли.
3. Конфигурация на LVE-stats2
- Спрете услугата:
service lvestats stop
- Отворете файла /etc/sysconfig/lvestats2 и задайте:
db_type = mysql
connect_string = lvestats2:lvestats2_passwd@localhost/db_lvestats2
- Инициализирайте базата:
/usr/sbin/lve-create-db
- Рестартирайте услугата:
service lvestats restart
4. Сигурен достъп само за четене
Създайте потребител с права само за четене:
CREATE USER ‘lvestats2_read’@’localhost’ IDENTIFIED BY ‘lvestats2_read_passwd’;
GRANT SELECT ON db_lvestats2.* TO ‘lvestats2_read’@’localhost’;
FLUSH PRIVILEGES;
Сигурност:
- Направете основния файл достъпен само за root:
chmod 600 /etc/sysconfig/lvestats2
- Копирайте го и създайте версия с read-only достъп:
cp /etc/sysconfig/lvestats2 /etc/sysconfig/lvestats2.readonly
chmod 644 /etc/sysconfig/lvestats2.readonly
5. Пароли със специални символи
Ако паролата съдържа символи като @, $, и т.н., трябва да ги „кодирате“:
Пример:
echo -n ‘[You_P@$$]:’ | perl -MURI::Escape -ne ‘print uri_escape($_).”\n”‘
Ще получите нещо като:
%5BYou_P%40%24%24%5D%3A
И тогава connect_string ще изглежда така:
connect_string=lvestats2:%5BYou_P%40%24%24%5D%3A@localhost/db_lvestats2
🐘 Настройка на LVE-stats2 с PostgreSQL
1. Инсталиране на PostgreSQL
За CloudLinux OS 6:
yum install postgresql-server postgresql
service postgresql initdb
service postgresql start
chkconfig postgresql on
За CloudLinux OS 7:
yum install postgresql-server postgresql
postgresql-setup initdb
systemctl start postgresql
systemctl enable postgresql
Промяна в конфигурацията
Редактирайте /var/lib/pgsql/data/pg_hba.conf и добавете:
host dblvestat all 127.0.0.1/32 password
host dblvestat all ::1/128 password
Рестартирайте PostgreSQL:
service postgresql restart
2. Създаване на база и потребител
Стартирайте PostgreSQL:
sudo -u postgres psql postgres
Създайте база и потребител:
CREATE DATABASE dblvestat;
CREATE USER lvestat WITH password ‘passw’;
GRANT ALL privileges ON DATABASE dblvestat TO lvestat;
\q
3. Настройка на LVE-stats2
Спрете услугата:
service lvestats stop
Редактирайте /etc/sysconfig/lvestats2:
db_type = postgresql
connect_string = lvestat:passw@localhost/dblvestat
Инициализация:
/usr/sbin/lve-create-db
Рестартирайте:
service lvestats restart
📬 Персонализиране на имейл нотификациите
Файлове с шаблони се намират в:
/usr/share/lve/emails/en_US/
Имената са:
- admin_notify.txt / .html
- reseller_notify.txt / .html
- user_notify.txt
За персонализация:
- Копирайте шаблоните в:
/etc/cl.emails.d/ваш_език/
- Добавете персонализиран Subject в началото на .txt файла:
Subject: Пример за персонализирана тема
Здравейте {{TONAME}},
…
- Рестартирайте услугата:
service lvestats restart
- Ако искате да преведете думи като “Administrator”, “12 hours” и т.н., създайте файл:
/usr/share/lve/emails/bg_BG/locale_defines.json
Съдържание:
{
“NOTIFY_FROM_SUBJECT”: “Изчерпани ресурси на хостинг акаунт”,
“PERIOD”: {
“days”: “дни”, “hours”: “часа”, “minutes”: “минути”, “seconds”: “секунди”
},
“TONAME”: {
“admin”: “Администратор”, “reseller”: “Реселър”, “customer”: “Клиент”
}
}
Създаване на плъгин за LVE-stats2 (CloudLinux)
Системата LVE-stats2 в CloudLinux е направена така, че позволява добавяне на персонализирани плъгини. Те могат да събират данни, да ги анализират, записват или изпращат нотификации – точно както ти трябва.
🔧 Как работи плъгин системата?
CloudLinux търси плъгини в папка (по подразбиране това е /usr/share/lve-stats/plugins). Всички файлове трябва да са Python скриптове (с .py разширение). Всеки плъгин трябва да има метод execute() — това е “работната” част, която се изпълнява периодично (на всеки 5 секунди по подразбиране).
Може да се зададе:
- order: редът, в който се изпълнява плъгинът;
- period: през колко секунди да се пуска;
- timeout: колко секунди да изчака, преди да се прекъсне изпълнението.
📁 Типове плъгини
Най-често се използват 4 вида:
- Collector – събира информация (напр. CPU, размер на файл);
- Analyzer – анализира събраните данни;
- Persistor – записва данните (в лог, база и т.н.);
- Notifier – праща известия (имейл, лог и пр.).
🧪 Пример: Плъгин, който следи размера на даден файл
Идеята е да следим размер на файл, да го записваме в лог, ако се е променил, и да пращаме имейл с текущия размер на всеки X часа. Това се реализира чрез няколко малки плъгина:
📥 1. Collector – събира текущия размер на файла
Проверява дали файлът съществува, взима размера му и го записва в споделена променлива, която другите плъгини ще използват. Конфигурацията (кой файл се следи) се чете от .cfg файл.
🔍 2. Analyzer – проверява дали размерът се е променил
Сравнява текущия размер със стария. Ако е различен, отбелязва го в променлива, за да може saver-ът да знае, че има какво да записва.
💾 3. Saver – записва информацията в лог
Тук се записва промяната на размера в лог файл (който също е зададен в конфигурация). Записва се само при промяна. Също така при спиране на сървиса (напр. рестарт) се записва “TERMINATE” съобщение – полезно за диагностика.
📧 4. Notifier – праща имейл
Плъгинът праща имейл на всеки определен период, независимо дали има промяна. Имейлът съдържа името на файла и текущия му размер. Използват се стойности от конфигурационен .cfg файл: подател, получател, тема, честота.
🧠 Как си комуникират?
Всички плъгини работят със споделена променлива (речник), в която се записва информация като: име на файл, размер, флаг дали да се запише лог, и т.н.
📌 Важно
- Всеки плъгин трябва да се добави ръчно в папката с плъгини (можеш да направиш symlink).
След всяка промяна/добавяне на плъгин – рестартирай lvestats:
service lvestats restart
- Ако нещо не работи – погледни лог файла: /var/log/lve-stats
🧰 Именуване и конфигурация
Имената на плъгините и техните .cfg файлове трябва да съвпадат. Например:
- Файл: FSize_watcher_collector.py
- Конфигурация: /etc/sysconfig/lvestats.config/FSize_watcher_collector.cfg
💌 Имейл нотификации (персонализиране)
Можеш да създадеш собствен HTML и текстов шаблон за имейли в:
/etc/cl.emails.d/bg_BG/
И да използваш файл locale_defines.json, за да преведеш “Administrator”, “days”, “hours” и т.н.
📄 Файлът /var/lve/info
Това е системен файл, който се обновява на всеки 5 секунди. Панелите (като cPanel) го ползват, за да показват на потребителите моментната им натовареност. Стойностите никога не надвишават лимитите.
Отстраняване на проблеми с LVE-stats
Ако нещо не работи с lvestats, най-доброто място да провериш какво се случва е:
- /var/log/lve-stats.log – там се записват грешки, предупреждения и traceback-и.
- За да видиш имейлите, изпратени от LVE-статистиката, направи следното:
- В конфигурационния файл /etc/sysconfig/lvestats2 сложи logging_level=debug
- След това рестартирай услугата с: service lvestats restart
🔒 Какво е CageFS?
CageFS е виртуална файлова система, която “изолира” всеки потребител в собствена среда (наричана клетка). Това означава, че:
- Потребителят не може да вижда други потребители, техните файлове или процеси
- Няма достъп до важни конфигурационни файлове на сървъра (като Apache)
- Може да използва само разрешени и безопасни програми
- Всичко работи нормално – няма нужда от промени по скриптовете на потребителя
Работи със:
- Apache (с suexec, suPHP и т.н.)
- LiteSpeed
- Cron задачи
- SSH
- Всички PAM базирани услуги
⚠️ mod_php не се поддържа и MPM ITK изисква пачове.
💾 Минимални изисквания за CageFS:
- CloudLinux OS 6 или 7
- Поне 7 GB свободно място
- За всеки потребител ще трябват още няколко MB за конфигурации
📥 Инсталиране на CageFS
Инсталирай пакета:
yum install cagefs
Инициализирай клетката (ще създаде скелетната структура):
/usr/sbin/cagefsctl –init
Ако нямаш достатъчно място в /usr/share, можеш да преместиш скелета в /home:
mkdir /home/cagefs-skeleton
ln -s /home/cagefs-skeleton /usr/share/cagefs-skeleton
Същото важи и за /var/cagefs – можеш да го преместиш, ако не стига място или ако искаш по-добър контрол над квотите.
👥 Управление на потребители
Можеш да активираш CageFS по два начина:
- Включен за всички (по подразбиране)
- Изключен за всички, включваш ръчно само за тези, които искаш
Команди:
# Включи за всички:
cagefsctl –enable-all
# Изключи за всички:
cagefsctl –disable-all
# Включи за конкретен потребител:
cagefsctl –enable username
# Изключи потребител:
cagefsctl –disable username
🔁 Обновяване на CageFS
Ако правиш промени (напр. в php.ini или добавяш нови програми), винаги изпълнявай:
cagefsctl –update
🚫 Изключване на файлове и потребители
- За да скриеш файлове от клетката:
- Добави ги в: /etc/cagefs/custom.black.list
- После изпълни: cagefsctl –force-update
- За да изключиш потребител от CageFS:
- Напиши потребителското име в файл в /etc/cagefs/exclude/
- После: cagefsctl –user-status username
🗂️ Шаблони и допълнителни файлове
CageFS използва шаблон, който се намира в /usr/share/cagefs-skeleton. Там се копират нужните файлове, които потребителите ще виждат в клетката.
Можеш да добавяш допълнителни пътища чрез .cfg файлове в /etc/cagefs/conf.d, например:
[mail]
comment=Mail tools
paths=/bin/mail, /usr/sbin/sendmail
След добавяне, изпълни:
cagefsctl –update
🧩 Специални случаи
- mount points – CageFS може да монтира директории за всички или само за конкретни потребители
- виртуални директории на потребител – чрез файл virt.mp, можеш да зададеш специфични пътища за всеки потребител
- сплит по UID – полезно, ако имаш потребители с еднакви UID
- домашна директория – CageFS се грижи тя да изглежда еднакво вътре и извън клетката
- /dev/shm изолация – отделен shared memory за всеки потребител
- лога – използва /var/log/cagefs.log
🧹 Деинсталиране на CageFS
Изключи и изчисти всичко:
/usr/sbin/cagefsctl –remove-all
- Изтрий пакета:
yum remove cagefs
📁 Скриване на съдържание на директория във CageFS
Ако искаш потребителите в CageFS да виждат дадена папка като празна (въпреки че не е), можеш да направиш следното:
Пример: да скриеш /var/www
Създай файл с име custom.empty със съдържание:
/var/www
- Запази го в: /etc/cagefs/empty.dirs
Изпълни:
cagefsctl –remount-all
Така всички потребители ще виждат /var/www като празна директория, дори ако вътре има папки като html, icons и т.н.
🏠 Домашни директории в по-сложна структура
Ако потребителските папки не са стандартно в /home/потребител, а примерно в /home/потребител/data, тогава CageFS трябва да знае как да ги обработи безопасно.
Създай файл:
/etc/cagefs/cagefs.base.home.dirs
и вътре напиши:
^/home/
^/var/www/users/
Ако не го направиш, може потребителите да виждат директории на други потребители – което не искаме.
👥 Споделена структура между потребители
Ако имаш няколко потребителя с достъп до обща структура (пример: сайт с няколко dev потребителя), можеш да направиш това с:
mount_basedir=1
^/var/www/vhosts/[^/]+
Така всеки потребител ще вижда структурата на целия сайт, но според разрешенията му.
Не забравяй да изпълниш:
cagefsctl –remount-all
🐘 PostgreSQL и CageFS
За CloudLinux OS 7: Просто добави реда:
/var/run/postgresql
в /etc/cagefs/cagefs.mp и изпълни:
cagefsctl –remount-all
За CloudLinux OS 6: Трябва да редактираш /etc/sysconfig/postgres, да махнеш коментара от SOCK_DIR, после:
cagefsctl –reconfigure-cagefs
service postgresql restart
Ако използваш cPanel – трябва да редактираш и cron скрипта tmpwatch.
🔐 Филтриране на команди (proxyexec filters)
Искаш да забраниш определени параметри при изпълнение на команди? Например да ограничиш sendmail да не се ползва с опасни флагове?
Пример: Създай файл /etc/cagefs/filters/sendmail.json с:
{
“default”: {
“deny”: [“-be”, “-bem”],
“restrict_path”: [“-C”, “-D”],
“strict_options”: true
}
}
С strict_options: true се анализират всички параметри отделно, дори когато са събрани (напр. -bem).
🚀 Изпълнение на скрипт извън CageFS
Пример 1: Скрипт с нормални права
- Имаш скрипт /my/scripts/superbinary
В /etc/cagefs/custom.proxy.commands напиши:
MYSUPERBINARY=/my/scripts/superbinary
Обнови с:
cagefsctl –force-update
- Скриптът ще се изпълнява извън CageFS!
Пример 2: Скрипт с root права (⚠️ внимателно!)
В /etc/cagefs/custom.proxy.commands:
MYSUPERBINARY=root:/my/scripts/superbinary
Сега скриптът ще се изпълнява като root. Внимавай – това може да е опасно!
Пример 3: Ограничаване на аргументи със собствен wrapper
Копирай стандартния wrapper:
cp /usr/share/cagefs/safeprograms/cagefs.proxy.program /usr/share/cagefs/safeprograms/cagefs.proxy.mysuperbinary
В него добави:
if [[ $1 == “/etc/passwd” ]]; then
echo “Not allowed”
exit 1
fi
Обнови:
cagefsctl –force-update
🧪 Собствени /etc файлове за потребители
Ако искаш да дадеш персонализиран /etc/hosts файл на конкретен потребител:
Създай:
/etc/cagefs/custom.etc/USERNAME/hosts
Изпълни:
cagefsctl –update-etc USERNAME
📦 Преместване на cagefs-skeleton
Ако искаш да го преместиш:
mkdir /home/cagefs-skeleton
ln -s /home/cagefs-skeleton /usr/share/cagefs-skeleton
cagefsctl –init
♻️ /tmp и почистване на PHP сесии
- Всеки потребител има свой .cagefs/tmp
- Почистването става веднъж на ден от cron (по подразбиране след 30 дни)
Можеш да го пуснеш ръчно:
cagefsctl –tmpwatch
- За PHP сесии:
- CageFS чете session.gc_maxlifetime и session.save_path
- Ако има няколко версии на PHP – се използва най-краткия gc_maxlifetime
- Скриптът чисти sess_* файлове в CageFS-а, не извън него
За cPanel и Plesk има специални настройки и cron задачи, които вече се поддържат автоматично от CageFS (ако версията е нова).
🧾 Syslog и CageFS
По подразбиране, вътре в CageFS потребителите имат достъп до /dev/log. Това е нужно, за да могат cron задачи или други процеси, стартирани от потребителя, да записват в системните логове.
Ако не искаш това:
Изтрий файла:
/etc/rsyslog.d/schroot.conf
Рестартирай rsyslog:
systemctl restart rsyslog
🚫 Изключване на mount точки от LVE namespace
Когато нещо е монтирано в системата, се вижда и от всички LVE среди. Ако искаш да изключиш конкретни mount точки от LVE:
Създай файл:
/etc/container/exclude_mounts.conf
Пример съдържание:
^/dir1/
^/dir2$
Изпълни:
lvectl start
За да приложиш към съществуващи LVE, изпълни:
lvectl destroy all
lvectl apply all
Така тези mount точки ще бъдат изключени от новите и съществуващи LVE.
🔒 Изолиране на /dev/shm (shared memory) в CageFS
По подразбиране /dev/shm е споделена между всички потребители. За по-добра сигурност можеш да я направиш индивидуална за всеки потребител.
Активиране:
sed -i -e ‘/^\/dev\/shm/d’ /etc/cagefs/cagefs.mp
echo ‘mode=0777’ > /etc/cagefs/dev.shm.options
cagefsctl –remount-all
Можеш да зададеш и лимит на паметта:
1MB:
echo ‘mode=0777,size=1m’ > /etc/cagefs/dev.shm.options
50% от PMEM лимита:
echo ‘mode=0777,size=50%’ > /etc/cagefs/dev.shm.options
Деактивиране:
rm -f /etc/cagefs/dev.shm.options
echo ‘/dev/shm’ >> /etc/cagefs/cagefs.mp
cagefsctl –remount-all
Важно: mode=0777 е задължителен. Това не е рисково, защото /dev/shm е отделен за всеки потребител.
🚫 Блокиране на процеси, които не могат да влязат в CageFS
Ако даден процес не може да влезе в CageFS (поради грешка), по подразбиране той все пак се изпълнява извън CageFS. Това може да е риск.
За да го забраниш (и процесът да се провали при грешка):
touch /etc/cagefs/fail.on.error
cagefsctl –remount-all
За да го върнеш към стандартно поведение:
rm -f /etc/cagefs/fail.on.error
cagefsctl –remount-all
Интеграция на CageFS с контролни панели
CageFS се интегрира директно с популярни хостинг контролни панели като:
- cPanel
- Plesk
- ISPmanager
Тази интеграция позволява:
- Инициализация и настройка на CageFS
- Управление на потребители (включване/изключване от CageFS)
- Обновяване на CageFS скелета (файлова структура)
- Смяна на режима на работа (всички потребители или само избрани)
⚙️ cPanel
CageFS User Manager (в WHM)
- Намира се в Plugins секцията.
- Има две основни секции:
- Enabled users – потребители с активиран CageFS
- Disabled users – потребители без CageFS
👉 Какво можеш да правиш:
- Включване/изключване на потребител:
Избери потребител и натисни Toggle. - Обновяване на CageFS скелета:
Натисни Update CageFS Skeleton.
CloudLinux Manager (в WHM)
- Отиваш на Users таб → колоната „CageFS“ → натисни бутона Toggle за желания потребител.
- За обновяване на скелета → Options > CageFS → Update.
📦 Plesk
Вградено в CloudLinux Manager за Plesk.
👉 Стъпки:
- Отиваш на Users таб → Toggle бутона до потребителя.
- За обновяване: Options > CageFS > Update
🛠 ISPmanager
CageFS идва с плъгин за ISPmanager.
👉 Стъпки:
- Отиди на редакция на потребител
- В таба Permission отбележи „CageFS User Mode“ → натисни OK.
Може да се управлява и глобално чрез CageFS менюто в интерфейса на ISPmanager.
MySQL Governor — какво представлява и как работи
MySQL Governor е инструмент, който ти позволява да наблюдаваш и ограничаваш използването на MySQL/MariaDB ресурси в споделена хостинг среда. Той следи използването на ресурси за всеки отделен MySQL процес (тема/нишка) и може да прилага ограничения при нужда.
✅ Какво точно прави:
- Следи CPU натоварване, четене/писане на диска, и брой активни връзки към базата данни.
- Може да ограничи потребители, които прекаляват с ресурсите.
- Поставя тежките SQL заявки в LVE контейнер, където вече има зададени лимити.
⚙️ Режими на работа
| Режим | Какво прави |
| off | Само наблюдава използването, без да прилага ограничения. |
| abusers | Ако даден потребител надвиши лимитите – заявките му се изпълняват в LVE. |
⚠️ Внимание: Режимът „All“ е отписан и няма да се поддържа след 1 септември 2021.
🧮 Видове лимити, които можеш да зададеш
| Тип | Какво контролира |
| CPU % | Колко процесор се използва (пример: 150% = 1.5 ядра). |
| READ | Колко байта са прочетени от диска (не кеширани). |
| WRITE | Колко байта са записани на диска (не кеширани). |
| Connections | Максимален брой едновременни MySQL връзки (по подразбиране: 30). |
📌 Можеш да зададеш различни стойности за различни периоди:
1 секунда, 5 секунди, 1 минута, 5 минути – идеята е да се позволят временни пикове, но да се ограничи дългосрочната злоупотреба.
🔄 Как работи заедно с LVE
- Преди да изпълни SQL заявка, MySQL Governor проверява:
- Кой е потребителят
- Дали е преминал зададените лимити
- Ако има нарушение → заявката се поставя в LVE контейнера на този потребител → прилагат се CPU и други лимити.
Така реално се управляват ресурсите, без да се нарушава работата на сървъра.
💡 Разлики между CPU/IO графиките на LVE и MySQL Governor
- Синя линия (Database): реална употреба на CPU/IO, измерена от MySQL Governor
- Зелена линия (LVE): същото, но само когато заявките са в LVE — т.е. по-ниски стойности, защото не всички заявки се насочват там
❓Как MySQL Governor ограничава IO без директно блокиране?
- Няма директно ограничаване на IO.
- Вместо това: ако се надвишат зададените IO лимити → заявките се вкарват в LVE → прилага се CPU лимит, а тъй като всяко IO използва и CPU, то и IO индиректно се намалява.
📈 На практика, това значи, че ако някой прави тежки заявки, те ще започнат да се „задушават“ чрез CPU лимита, което ще забави и самите операции с базата.
Инсталация на MySQL Governor
🔔 Важно преди да започнеш:
- Направи пълен бекъп на базата (включително system tables)
- MariaDB 10.4 НЕ се поддържа от cPanel
- Не се поддържа ъпгрейд от MySQL 8 → MariaDB 10.x
🔧 Стъпки за инсталиране:
Изтрий стари пакети (ако има):
yum remove db-governor db-governor-mysql
Инсталирай MySQL Governor:
yum install governor-mysql
Избери версия на съществуващата MySQL/MariaDB:
/usr/share/lve/dbgovernor/mysqlgovernor.py –mysql-version=mysql57 # или mariadb105, percona56 и т.н.
Инсталирай:
/usr/share/lve/dbgovernor/mysqlgovernor.py –install
👉 Пример с автоматично потвърждение (не препоръчително за първи път):
/usr/share/lve/dbgovernor/mysqlgovernor.py –install –yes
📦 Поддържани версии:
| Тип | Версии |
| MySQL | mysql55, mysql56, mysql57, mysql80 |
| MariaDB | mariadb55 → mariadb114 (до v11.4) |
| Percona | percona56 |
✅ Инсталация на чисто (без MySQL):
Можеш да избереш версия още при инсталация:
/usr/share/lve/dbgovernor/mysqlgovernor.py –mysql-version=mysql80
/usr/share/lve/dbgovernor/mysqlgovernor.py –install
🔼 Ъпгрейд на база данни
⚠️ Важно: Ъпгрейд от MySQL 8 → MariaDB НЕ се поддържа! Ще счупи базата!
Избери нова версия:
/usr/share/lve/dbgovernor/mysqlgovernor.py –mysql-version=mariadb106
Инсталирай новата версия:
/usr/share/lve/dbgovernor/mysqlgovernor.py –install
📌 Направи пълен бекъп преди ъпгрейд.
❌ Деинсталация:
/usr/share/lve/dbgovernor/mysqlgovernor.py –delete
Това ще върне оригиналния MySQL от CloudLinux репото.
Конфигурация
Файлът за конфигурация е:
/etc/container/mysql-governor.xml
➡ Препоръчително е да използваш CLI инструмента dbctl за промени.
След промяна:
service db_governor restart
🔁 Режими на работа (Modes of Operation)
| Режим | Описание |
| abusers | (препоръчителен) Поставя заявките на потребителите в LVE само ако надвишат лимитите |
| off | Само мониторинг – не прилага лимити |
| all | ❌ (депрекиран) – винаги изпълнява заявките в LVE |
| single | ❌ (депрекиран) – всички нарушители в един LVE ID=3 |
| on | ❌ стар синоним на single |
🔔 all режимът е премахнат от нови инсталации от 1 септември 2021.
🚦 Лимити
📊 Могат да се зададат 4 нива:
- current – текущ максимум
- short – 5 сек.
- mid – 60 сек.
- long – 300 сек.
🔧 Пример (CPU):
<limit name=”cpu” current=”150″ short=”120″ mid=”100″ long=”80″/>
💡 Принципи при настройка:
- current и short могат да са над LVE лимитите
- mid и long трябва да са равни или по-ниски от LVE лимитите
- По този начин се избягват “блокиращи” SQL заявки
📄 Допълнителни лимити:
- read, write – байтове от диск (не кеширани)
- slow – бавни заявки (напр. <limit name=”slow” current=”30″/> за 30 секунди)
📂 Log файлове
| Файл | Описание |
| /var/log/dbgovernor-error.log | Всички грешки |
| /var/log/dbgovernor-restrict.log | Записи при прилагане на лимити |
| /var/log/dbgovernor-kill.log | Бавни заявки, които са убити |
🗺️ Свързване на потребител с база
Файл:
/etc/container/dbuser-map
Формат:
dbuser1 user1 502
🔁 Обновяване на мапа:
/usr/share/lve/dbgovernor/mysqlgovernor.py –dbupdate
▶️ Старт и стоп на Governor:
service db_governor start
service db_governor stop
🔄 Смяна на версия на MySQL/MariaDB
⚠️ ЗАДЪЛЖИТЕЛНО бекъп преди ъпгрейд:
/usr/share/lve/dbgovernor/mysqlgovernor.py –mysql-version=mariadb105
/usr/share/lve/dbgovernor/mysqlgovernor.py –install
📌 Поддържани версии:
- mysql55, mysql56, mysql57, mysql80
- mariadb10x (до mariadb114)
- percona56
🔒 PrivateDevices поддръжка (на CloudLinux 7/8)
CloudLinux 7:
- Увери се, че systemd е поне 219-78.2
Вкарай в mysqld.service:
PrivateDevices=true
CloudLinux 8:
Вкарай:
PrivateDevices=true
DeviceAllow=/dev/lve
BindPaths=/dev/lve
🛡️ Backup преди инсталация
/usr/share/lve/dbgovernor/scripts/mysql_backup.sh
За cPanel, изключи мониторинга преди:
whmapi1 configureservice service=mysql enabled=1 monitored=0
и включи след това:
whmapi1 configureservice service=mysql enabled=1 monitored=1
Подобрения в пресмятането на CPU (MySQL Governor 1.2-81+)
- По-точно изчисление на CPU използването от потребителите.
- Подобрен dbtop отчита правилно моментите, когато даден потребител трябва да бъде ограничен.
- Намалява риска един потребител да източи всички ресурси.
🔧 Включено по подразбиране. Може да се изключи с:
dbctl –lve-improved-accuracy off
📊 Разлика в графиките (CPU/IO от базата и LVE)
| Цвят | Източник | Какво показва |
| 🟦 Син | MySQL Governor | Реално CPU/IO от заявките към базата |
| 🟩 Зелен | lve-stats | CPU/IO от LVE (ако заявките вече са пратени в LVE) |
💡 Заявките се пращат в LVE само ако има надвишаване на лимитите, затова графиките могат да се различават.
🧠 Как работи ограничаването на IO реално?
- IO не се ограничава директно.
- При надвишаване на лимит – заявките се пускат в LVE.
- А там CPU лимита води и до ограничаване на IO индиректно (защото IO причинява CPU натоварване).
❗ Troubleshooting съвети:
1. 🛠 MariaDB LimitNOFILE
Добави лимита:
mkdir -p /etc/systemd/system/mariadb.service.d/
cat <<EOF > /etc/systemd/system/mariadb.service.d/limits.conf
[Service]
LimitNOFILE=99999
EOF
2. ❌ Can’t connect to MySQL (Plesk/DirectAdmin)
След смяна на root парола:
/usr/share/lve/dbgovernor/mysqlgovernor.py –update-config-auth
3. ❓ Липсваща библиотека (libgovernor_stubs.so и др.)
Провери библиотеката:
yum provides ‘*/libexample_stubs.so’
Ако е в Python пакет:
pip install mysqlclient –force –no-cache-dir
- Или премахни референцията с patchelf:
patchelf –remove-needed libexample_stubs.so path/to/your_binary.so
❗ Известни ограничения
📌 I/O LVE лимити не работят за SQL заявки
- SQL заявките, които се пускат през MySQL Governor в LVE, не се ограничават от I/O лимити, само от CPU.
- Причината е, че при предишни опити да се ограничи паметта за MySQL заявките, това водело до OOM и повреда на бази.
- CPU лимитите косвено ограничават и I/O.
🛠 PHP Selector: изисквания и работа
📦 Изисквания
- CageFS трябва да е инсталиран и инициализиран.
- Alt-PHP пакети трябва да са инсталирани (yum groupinstall alt-php)
- mod_suexec трябва да е наличен.
- Поддържани PHP режими: suPHP, mod_fcgid, CGI (suexec), LiteSpeed
- System PHP не трябва да е alt-php (трябва да е ea-php при cPanel)
✅ Поддържани версии
Alt-PHP 5.1–8.4 работят под CloudLinux 6–9.
🛠 Инсталация (cPanel пример)
yum install cagefs
yum groupinstall alt-php
yum install mod_suexec
cagefsctl –init
След това в WHM:
- Проверяваш PHP handler
- Уверяваш се, че системният PHP не е alt-php
- Активираш CageFS за потребителите
- Включваш PHP Selector в Feature Manager
⚙️ Поддръжка на LiteSpeed
- Автоматично разпознаване на CloudLinux OS.
- Ако е с нестандартен път: ln -s /custom/lsws /usr/local/lsws
- Ключови настройки:
- CloudLinux OS: CageFS
- PHP suEXEC: Yes
- Път до PHP: /usr/local/bin/lsphp или /var/www/cgi-bin/…
🧼 Деактивиране или ресет на PHP Selector
# Ресетва версиите на PHP за всички потребители:
cagefsctl –cl-selector-reset-versions
# Ресетва модулите към дефолт:
cagefsctl –cl-selector-reset-modules
👉 Използвай внимателно – може да спре сайтове на клиенти.
⚙️ Глобално деактивиране на PHP разширения
- Не трий .ini файла.
- Просто закоментирай extension= директивата.
- При ъпдейт на alt-php няма да се включи отново автоматично.
Конфигурация и използване на PHP Selector
⚙️ 1. Настройка на подразбираща се PHP версия и разширения
- Конфигурационен файл: /etc/cl.selector/defaults.cfg
Пример:
[global]
selector=enabled
[versions]
php=7.4
[php7.4]
modules=json,phar,mbstring
За нулиране на разширения към дефолт за PHP 8.4:
selectorctl –reset-user-extensions –version=8.4 –user=username
🧾 2. Индивидуални php.ini файлове
- Път вътре в CageFS:
/etc/cl.php.d/alt-phpXX/alt_php.ini
За ръчно добавяне на стойност:
echo “upload_tmp_dir=/tmp” >> /etc/cl.php.d/alt-php72/custom.ini
🔁 3. Подмяна на глобален php.ini само за отделни потребители
Постави файл в:
/etc/cagefs/custom.etc/USER_NAME/php.ini
След това:
cagefsctl –update-etc USER_NAME
⚠️ Забележка: При SuPHP или LSAPI трябва да укажеш SuPHP_ConfigPath или lsapi_phprc в Apache конфигурацията или .htaccess.
🐘 4. Управление на интерпретатори
Показване на наличните версии:
selectorctl –list –interpreter=php
Задаване на версия за потребител:
selectorctl –user=username –interpreter=php –set-user-current=8.2
🧩 5. PHP разширения
Промяна на behavior така, че избрани модули в Selector да важат за всички alt-php версии:
echo “php.d.location = selector” > /etc/cl.selector/symlinks.rules
selectorctl –apply-symlinks-rules
- За връщане към стандартно поведение – изтрий този файл.
🎞 6. FFmpeg
- Не се поддържа в CloudLinux 8.
При CloudLinux 7 – инсталирай от nux-dextop репо:
yum install alt-php*ffmpeg
selectorctl –enable-extensions=ffmpeg –user=username –version=7.4
⚙️ 7. Конфигуриране на alt-php72-zts (Thread-safe версия)
Увери се, че си инсталирал правилния RPM:
yum install alt-php72-zts
- Промени /etc/cl.selector/selector.conf с пътищата до zts-php и zts-php-cgi.
Препрати php.d.all към правилната php.d.all.zts директория:
ln -fsn php.d.all.zts php.d.all
🧪 8. Собствени PHP опции през Selector
Разрешените за промяна опции са в:
/etc/cl.selector/php.conf
Пример:
Directive = memory_limit
Type = value
Comment = Limits memory per script
Можеш да редактираш стойности чрез:
selectorctl –set-option=user=username –version=8.1 –option=memory_limit –value=512M
💡 Полезни команди за админ
# Принудително обновяване на alt-php ini файлове:
cagefsctl –rebuild-alt-php-ini
# Обновяване конфигурацията на Selector:
cagefsctl –setup-cl-selector
# Показване текуща PHP версия за потребител:
selectorctl –user=username –interpreter=php –user-current
Чеклист за управление на PHP Selector (CloudLinux)
📦 Инсталация на PHP Selector без CageFS (единичен потребител)
yum groupinstall alt-php
yum install cagefs lvemanager
selectorctl –setup-without-cagefs USER
🔁 Връщане към CageFS режим:
cagefsctl –init
selectorctl –revert-to-cagefs
🔍 Проверка на PHP версия за потребител:
selectorctl –interpreter=php –user-summary –user=USERNAME
📌 Изход:
- e – версията е активна
- d – по подразбиране
- s – избрана от потребителя
🧱 Файлове и директории, създавани за всеки потребител:
| Път | Значение |
| /etc/cl.selector | Symlinks към PHP bin файлове |
| /usr/selector/php | Native PHP bin |
| /etc/cl.php.d/alt-php* | Активирани модули |
| /home/user/.cl.selector/alt_phpXX.cfg | Настройки за конкретна PHP версия |
| /opt/alt/phpXX/etc/php.d.all/ | Модули на alt-PHP |
| /opt/alt/phpXX/usr/lib64/php/modules/ | Компилирани .so файлове |
🛠️ Компилиране на собствен PHP модул
cd /path/to/extension
/opt/alt/phpXX/usr/bin/phpize
./configure –with-php-config=/opt/alt/phpXX/usr/bin/php-config
make
cp modules/*.so /opt/alt/phpXX/usr/lib64/php/modules/
echo “extension=yourmodule.so” > /opt/alt/phpXX/etc/php.d.all/yourmodule.ini
cagefsctl –setup-cl-selector
🚀 Добавяне на твоя PHP версия (пример: 5.1)
mkdir -p /opt/alt/php51/{etc/php.d.all,usr/bin,usr/sbin,usr/lib/php/modules}
# Копирай нужните bin/ini/moudles файлове
ln -s /etc/cl.php.d/alt-php51 /opt/alt/php51/etc/php.d
# Добави в конфигурацията:
echo “php 5.1 5.1.2 /opt/alt/php51/usr/bin/php-cgi” >> /etc/cl.selector/selector.conf
echo “php-cli 5.1 5.1.2 /opt/alt/php51/usr/bin/php” >> /etc/cl.selector/selector.conf
echo “php-fpm 5.1 5.1.2 /opt/alt/php51/usr/sbin/php-fpm” >> /etc/cl.selector/selector.conf
# Регистрирай:
cagefsctl –setup-cl-selector
📁 Файлове при –setup-without-cagefs
- .cl.selector/ – главна конфигурационна директория в home на user
- *.cfg – потребителски конфигурации на версии
- .cl.selector/php → symlink към избрания php-cgi
- .cl.selector/php.ini → към избрания ini
- .bashrc получава:
PATH=$HOME/.cl.selector/selector.path:$HOME/.cl.selector:$PATH
💡 Съвет за миграции
- Когато местиш акаунти между сървъри, .cl.selector директорията запазва настройките (версии, модули, php.ini).
- Ако тя липсва, се използват стойностите от /etc/cl.selector/defaults.cfg.
🔧 Настройване на глобални php.ini опции за всички Alt-PHP версии
🗂️ Файл: /etc/cl.selector/global_php.ini
[Global PHP Settings]
date.timezone = Europe/Sofia
memory_limit = 256M
error_log = /var/log/php_errors.log
- Работи само с CageFS 6.0-33+ и LVE Manager 2.0-11.2+.
- Не поддържа секции – само име = стойност.
✅ Прилагане на промените
Промени без date.timezone и error_log:
/usr/sbin/cagefsctl –setup-cl-selector
Промени включително date.timezone и error_log:
selectorctl –apply-global-php-ini
# или
cagefsctl –apply-global-php-ini
Само конкретна опция:
selectorctl –apply-global-php-ini date.timezone
selectorctl –apply-global-php-ini error_log
⚙️ Полезни selectorctl команди (управление през CLI)
| Цел | Команда |
| Покажи всички версии | selectorctl –summary |
| Покажи с native PHP | selectorctl –summary –show-native-version |
| Задай default версия | selectorctl –set-current=7.4 |
| Изключи версия | selectorctl –disable-alternative=8.1 |
| Включи версия | selectorctl –enable-alternative=8.1 |
| Списък с разширения | selectorctl –list-extensions –version=7.4 |
| Активирай разширения глобално | selectorctl –version=7.4 –enable-extensions=pdo,json,mbstring |
| Деактивирай разширения | selectorctl –version=7.4 –disable-extensions=pdo,json |
| Смени разширения | selectorctl –version=7.4 –replace-extensions=gd,zip,mysql |
| Избор на PHP за user | selectorctl –set-user-current=7.4 –user=username |
| Списък разширения за user | selectorctl –list-user-extensions –user=username –version=7.4 |
| Активирай за user | selectorctl –enable-user-extensions=curl,json –user=username –version=7.4 |
| Рестартирай към default | selectorctl –reset-user-extensions –user=username –version=7.4 |
🧠 Пример: Подаване на custom php.ini опции с base64
OPTIONS=$(echo memory_limit:128M | base64 -w 0)
selectorctl –user=username –version=7.4 –replace-options=$OPTIONS –base64
Можеш да комбинираш няколко:
OPTIONS=`echo disable_functions:exec,system|base64 -w 0`,`echo post_max_size:64M|base64 -w 0`
selectorctl –user=username –version=7.4 –replace-options=$OPTIONS –base64
Python Selector – Обобщение
✅ Изисквания
- Контролен панел: cPanel или DirectAdmin (без Plesk)
- Уеб сървър: Apache, LiteSpeed или Apache + Nginx (реверсен прокси)
- mod_passenger: необходимо за Python Selector
- CageFS: силно препоръчително
🔧 Поддържани версии на Python:
- Python 2.7 до 3.12 (включително)
- Работи на CloudLinux 6, 7, 8 и 9
🛠️ Инсталация (за cPanel)
# 1. Инсталирай всички alt-Python пакети
yum groupinstall alt-python
# 2. Инсталирай необходимите зависимости
yum install lvemanager lve-utils alt-python-virtualenv
# 3. Инсталирай mod_passenger (за CloudLinux 7 и 8)
# CloudLinux 7: Избираш една от двете
yum install ea-ruby24-mod_passenger
# или
yum install ea-ruby27-mod_passenger
# CloudLinux 8: Само това
yum install ea-ruby27-mod_passenger
✅ След това:
- Увери се, че Python App е видим в CloudLinux Manager > Options tab.
- Разреши компилаторен достъп от WHM ➝ Security Center > Compiler Access
- После:
cagefsctl –force-update
🛠️ Инсталация (за DirectAdmin)
yum groupinstall alt-python
yum install lve-utils lvemanager alt-python-virtualenv alt-mod-passenger
cagefsctl –force-update
🧑💻 Къде потребителят вижда Python Selector?
В контролния панел (cPanel/DirectAdmin), потребителят ще има опция “Python App” за създаване и управление на виртуални среди и приложения с Python + uWSGI.
Какво може да прави?
- Избира Python версия (2.7 до 3.12)
- Създава виртуална среда
- Инсталира Python пакети (pip)
- Управлява wsgi файлове и настройки на app
💎 Ruby Selector – Обобщение
✅ Изисквания
- Работи само с cPanel
- Използва mod_passenger като сървър
🔧 Поддържани Ruby версии
- alt-ruby версии (напр. 2.5, 2.6, 2.7)
🛠️ Инсталация на Ruby Selector
yum groupinstall alt-ruby
⚠️ След инсталация:
- Увери се, че опцията “Ruby App” не е скрита в CloudLinux Manager (Options tab).
- Разреши достъп до компилаторите:
cagefsctl –force-update
👩🔧 Добра практика
👉 Винаги използвай cagefsctl –force-update след промени (нов потребител, инсталиране на нови езици, активиране на модул и т.н.)
Node.js Selector в CloudLinux OS
✅ Изисквания
- Контролен панел: cPanel или DirectAdmin (не поддържа Plesk)
- Web сървър: Apache или LiteSpeed
- mod_passenger: използва се за хостване на Node.js апликации
- CloudLinux OS 6, 7, 8, 9
- CageFS препоръчително
❗ Лимитации
- Работи само с CommonJS модули
- Не поддържа ECMAScript модули (ESM), но можеш да обвиеш app.js със CJS файл:
// app_wrapper.cjs
(() => import(‘./app.js’))();
🛠️ Инсталация (cPanel)
# 1. Инсталирай Node.js пакети:
yum groupinstall alt-nodejs
# 2. Инсталирай LVE + Passenger:
yum install lvemanager lve-utils
# 3. Инсталирай подходящ Passenger модул:
# CloudLinux 7 (избери един):
yum install ea-ruby24-mod_passenger
# или
yum install ea-ruby27-mod_passenger
# CloudLinux 8 (само този):
yum install ea-ruby27-mod_passenger
# 4. (Препоръчително) Инсталирай CageFS:
yum install cagefs
🔧 Ако получиш грешка ENOMEM npm ERR! errno -12, увеличи:
WHM → Server Configuration → Tweak Settings → System → Max cPanel process memory
После рестартирай cPanel:
# CloudLinux 7:
systemctl restart cpanel.service
# CloudLinux 6:
service cpanel restart
💎 Ruby Selector
✅ Изисквания
- Работи само с cPanel
- Изисква mod_passenger
- Използва се за Ruby приложения (като Redmine)
🛠️ Инсталация
# 1. Инсталирай Ruby пакети:
yum groupinstall alt-ruby
# 2. Увери се, че Ruby App е активиран в LVE Manager > Options
# 3. Активирай компилатори за gcc/make:
cagefsctl –force-update
⚙️ Управление на иконите за крайния потребител
🧩 Скриване на иконата на Ruby Selector
В LVE Manager > Options Tab можеш да махнеш отметката до Hide Ruby App in web-interface.
💻 Или чрез CLI:
cloudlinux-config set –json –data ‘{“options”:{“uiSettings”:{“hideRubyApp”:true}}}’
✅ За да покажеш иконата отново:
cloudlinux-config set –json –data ‘{“options”:{“uiSettings”:{“hideRubyApp”:false}}}’
📌 В cPanel ➝ WHM ➝ Feature Manager можеш да я включиш или изключиш за конкретни “feature lists”, но първо трябва да бъде видима глобално от LVE Manager.
🛠️ Пример: Деплой на Redmine с Ruby Selector
Ако искаш да деплойнеш Redmine:
- Версия 2.6.0 или по-нова
- Използваш Ruby Selector с модул ea-ruby2X-mod_passenger
- Следвай официалния гайд на CloudLinux за конкретната версия
Бонус: Бърз Bash скрипт за инсталация на всички Selectors
#!/bin/bash
echo “Инсталирам CloudLinux Selectors…”
# Python Selector
yum groupinstall -y alt-python
yum install -y lvemanager lve-utils alt-python-virtualenv
# Ruby Selector
yum groupinstall -y alt-ruby
# Node.js Selector
yum groupinstall -y alt-nodejs
yum install -y cagefs
# Passenger (само ако не е CL6)
OS_MAJOR=$(awk -F. ‘{print $1}’ /etc/redhat-release | grep -oE ‘[0-9]+’)
if [[ “$OS_MAJOR” -ge 7 ]]; then
yum install -y ea-ruby27-mod_passenger
else
yum install -y ea-ruby24-mod_passenger
fi
# Финално обновление на CageFS
cagefsctl –force-update
echo “Инсталацията е завършена.”
Node.js Deployment on CloudLinux
CloudLinux OS offers two powerful remote methods for Node.js development and deployment:
✅ Supported Use Cases:
- Remote IDE development (IntelliJ IDEA/WebStorm)
- Control via cloudlinux-selector CLI
- Deployment over SSH with syncing tools (e.g., rsync, SFTP)
📦 Approach 1: Remote usage of Node.js Interpreters (from IDE)
🧰 Prerequisites
- CloudLinux with alt-nodejs packages installed
- Node.js app directory created on the server
- Access to SSH and proper permissions
- IntelliJ/WebStorm + Node.js Remote Interpreter plugin
- (Optional but ideal): Passenger not needed for local dev
🛠️ Steps
1. Install alt-nodejs on the server
yum groupinstall alt-nodejs
2. Create the application
Option A: via UI (LVE Manager → Node.js App)
Option B: via CLI:
cloudlinux-selector create –interpreter=nodejs \
–json \
–app-root=/home/USERNAME/APPNAME \
–app-uri=/APPNAME \
–app-mode=development \
–version=18 \
–domain=example.com
3. Configure IntelliJ/WebStorm
- Install Node.js Remote Interpreter plugin
- Go to: Preferences → Languages & Frameworks → Node.js and NPM
- Set up a remote interpreter via SSH (your user account on the server)
- In Run > Edit Configurations, create a new Node.js config:
- JavaScript file: app.js
- Interpreter path: /opt/alt/nodejs18/usr/bin/node
- Port: 3003 or as used in app
4. Sync code
Set Path Mappings:
Local: ~/Projects/my-node-app
Remote: /home/USERNAME/APPNAME
You can sync via:
- Deployments (WebStorm built-in)
- rsync
- SFTP
5. Install dependencies on server
cd /home/USERNAME/APPNAME
npm install
Alternatively, use WebStorm UI → Run NPM Install
6. Run & Debug
From IntelliJ/WebStorm:
- Use Run or Debug to launch app
- Access app via http://example.com:3003
📁 Approach 2: Remote usage of cloudlinux-selector CLI
This lets you manage apps via terminal commands directly.
🔧 Useful CLI commands:
Restart app:
cloudlinux-selector restart –interpreter=nodejs –user=USERNAME –app-root=/home/USERNAME/APPNAME
Install packages:
cloudlinux-selector run –interpreter=nodejs –user=USERNAME \
–app-root=/home/USERNAME/APPNAME \
–command=”npm install”
Change Node.js version:
cloudlinux-selector set-version –interpreter=nodejs –user=USERNAME \
–app-root=/home/USERNAME/APPNAME \
–version=18
💡 You can bind these commands into WebStorm → Preferences → Remote SSH External Tools for easy one-click use.
🛠️ Troubleshooting & Debugging
💥 Debug errors during development
Enable detailed app errors in .htaccess:
PassengerAppEnv development
PassengerFriendlyErrorPages on
This shows detailed error stack traces in the browser — perfect for development. For production, comment them out.
⚠️ Known Issues
❗ Out Of Memory Errors
If you see errors like:
ENOMEM npm ERR! errno -12
Or:
Out of memory: wasm memory
✅ Solutions:
1. Increase memory limit (WHM → Tweak Settings)
whmapi1 set_tweaksetting key=maxmem value=51200
/usr/local/cpanel/scripts/restartsrv_cpsrvd
💡 Sometimes full server reboot may be required due to cPanel bug (CPANEL-43590).
2. User-specific override
Edit /etc/security/limits.conf:
username hard as unlimited
Then edit user’s .bashrc:
ulimit -S -v unlimited
🧠 Quick Reference: cloudlinux-selector Node.js CLI
| Task | Command |
| Create app | cloudlinux-selector create –interpreter=nodejs … |
| Restart app | cloudlinux-selector restart –interpreter=nodejs … |
| Install NPM packages | cloudlinux-selector run –interpreter=nodejs –command=”npm install” |
| Change Node.js version | cloudlinux-selector set-version –version=18 … |
Какво е mod_lsapi PRO и защо да го използваме?
mod_lsapi PRO е модул за Apache уеб сървър, създаден от LiteSpeed Technologies. Той изпълнява PHP скриптове, подобно на други технологии като mod_php, php-fpm или mod_suphp – но го прави по-бързо, с по-малко използвана памет и по-добра защита.
📌 Как работи?
- Apache получава PHP заявка и я прехвърля към mod_lsapi.
- mod_lsapi използва библиотека liblsapi, за да прати заявката към процеса lsphp.
- lsphp стартира нов процес (child), който изпълнява заявката.
- След това данните се връщат обратно към уеб сървъра.
🧠 Какво е lsphp?
lsphp = PHP + LSAPI
LSAPI е специален интерфейс, създаден за бърза комуникация между LiteSpeed уеб сървър и PHP. Сега чрез mod_lsapi PRO можем да използваме същата технология и в Apache.
✅ Предимства на mod_lsapi PRO:
- Много по-бързо изпълнение на PHP
- По-ниска консумация на ресурси (RAM)
- Поддръжка на opcode кеширане (за още по-бърз PHP)
- Много добра съвместимост с хостинг панели като cPanel, Plesk и DirectAdmin
🛑 Какво НЕ е съвместимо с mod_lsapi?
- mod_ruid2 (трябва да е изключен)
- mod_itk (трябва да е изключен)
- php-fpm (не може да се използва заедно, тъй като и двете са PHP изпълнители)
🔐 Препоръчителни настройки за максимална сигурност:
- Активиран CageFS (ограничава достъпа на потребителите)
- Използване на LVE контейнери
- Инсталирани mod_hostinglimits и mod_suexec
- Използване на PHP Selector (CloudLinux) или ea-php (за cPanel)
🔧 Инсталиране на mod_lsapi PRO
Инсталацията зависи от използвания контролен панел:
📦 cPanel (с EasyApache 4)
Инсталирай нужните пакети:
yum install liblsapi liblsapi-devel
yum install ea-apache24-mod_lsapi
Активирай lsapi:
/usr/bin/switch_mod_lsapi –setup
Рестартирай Apache:
service httpd restart
Сега можеш да управляваш PHP изпълнителя през MultiPHP Manager.
📦 Plesk
Инсталирай нужните пакети:
yum install liblsapi liblsapi-devel
yum install mod_lsapi
Активирай lsapi:
/usr/bin/switch_mod_lsapi –setup
Рестартирай Apache:
service httpd restart
След това можеш да използваш alt-php LSPHPXY през Plesk панела.
📦 DirectAdmin
Инсталирай нужните пакети:
yum install liblsapi liblsapi-devel
С custombuild:
cd /usr/local/directadmin/custombuild
./build update
./build set php1_mode lsphp
./build php n
./build apache
Рестартирай Apache:
service httpd restart
Готово – всички домейни с php1_mode ще използват lsphp.
📦 Без контролен панел
Изтрий или преименувай php.conf, ако съществува:
mv /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.conf.NO
Инсталирай пакетите:
yum install liblsapi liblsapi-devel
yum install mod_lsapi
Активирай lsapi:
/usr/bin/switch_mod_lsapi –setup
Рестартирай Apache:
service httpd restart
🔁 Ако ползваш алтернативен Apache (httpd24):
yum install httpd24-mod_lsapi
/opt/rh/httpd24/root/usr/bin/switch_mod_lsapi –setup
service httpd24-httpd restart
❌ Деинсталиране на mod_lsapi PRO
🧼 cPanel:
/usr/bin/switch_mod_lsapi –uninstall
yum erase liblsapi liblsapi-devel ea-apache24-mod_lsapi
service httpd restart
🧼 Plesk:
/usr/bin/switch_mod_lsapi –uninstall
yum erase liblsapi liblsapi-devel mod_lsapi
service httpd restart
🧼 DirectAdmin:
cd /usr/local/directadmin/custombuild
./build update
./build set php1_release mod_php
./build php n
./build apache
service httpd restart
🧼 Без контролен панел:
/usr/bin/switch_mod_lsapi –uninstall
yum erase liblsapi liblsapi-devel mod_lsapi
rm /etc/httpd/conf.d/mod_lsapi.conf
service httpd restart
📌 За httpd24, използвай същите стъпки, но с httpd24-mod_lsapi и service httpd24 restart.
🛠️ Конфигурация на mod_lsapi PRO (по лесен и разбираем начин)
За да може mod_lsapi PRO да работи коректно с Apache, трябва да го настроим правилно чрез отделен конфигурационен файл — lsapi.conf.
🔌 Задължителна настройка: Зареждане на модула
Увери се, че в lsapi.conf модулът е зареден. Това става чрез следния ред:
LoadModule lsapi_module modules/mod_lsapi.so
Ако този ред е закоментиран (с # отпред), премахни коментара.
✅ Активиране на обработката на PHP заявки
Добави тази директива:
lsapi_engine On
Това казва на Apache да използва mod_lsapi, за да обработва заявки.
📄 Обработка на PHP файлове
Следващата стъпка е да кажеш на Apache кои файлове да се обработват чрез lsapi:
AddType application/x-httpd-lsphp .php
Това означава: “Всеки .php файл ще се обработва чрез lsapi”.
📌 Важно! Ако има друг PHP хендлър активен (например php.conf), го деактивирай или преименувай, за да не пречи.
🧩 Пример за цял lsapi.conf файл:
LoadModule lsapi_module modules/mod_lsapi.so
<IfModule lsapi_module>
lsapi_engine On
AddType application/x-httpd-lsphp .php
lsapi_backend_connect_timeout 100000
lsapi_backend_connect_tries 10
lsapi_backend_children 20
lsapi_backend_pgrp_max_idle 30
lsapi_backend_max_process_time 300
lsapi_debug Off
</IfModule>
📌 Увери се, че lsapi.conf се зарежда от Apache чрез Include директива (например в httpd.conf или друга конфигурация).
🔄 Използване на различни LVE ID за един и същи потребител
От версия 1.1-79 mod_lsapi поддържа използване на алтернативни LVE ID-та за различни сайтове на един и същ потребител.
🧾 Пример:
Имаш потребител user1 с UID 1001. Това автоматично създава LVE ID 1001.
Сега ще създадем допълнителна LVE с ID 11001 с различни лимити:
lvectl set 11001 –speed=50% –pmem=512M –io=2048 –ep=10 –nproc=50
🧰 Apache конфигурация с два сайта (две LVE зони):
<VirtualHost 10.0.0.1:80>
ServerName user1.example.com
DocumentRoot /home/user1/public_html
<IfModule hostinglimits_module>
<Directory “/home/user1/public_html”>
LVEId 11001
</Directory>
</IfModule>
<IfModule lsapi_module>
lsapi_user_group user1 user1
lsapi_per_user Off
</IfModule>
</VirtualHost>
<VirtualHost 10.0.0.1:80>
ServerName sub.user1.example.com
DocumentRoot /home/user1/subsite
<IfModule hostinglimits_module>
<Directory “/home/user1/subsite”>
LVEId 1001
</Directory>
</IfModule>
<IfModule lsapi_module>
lsapi_user_group user1 user1
lsapi_per_user Off
</IfModule>
</VirtualHost>
💡 Какво правим тук?
- Имаме два сайта под потребител user1.
- Всеки сайт използва различен LVE ID с различни лимити.
- Настройката lsapi_per_user Off е важна — тя позволява на всеки сайт да използва отделен lsphp процес (по-ефективно при различни натоварвания).
⚙️ Основни настройки на mod_lsapi PRO
🔌 lsapi_engine
- Синтаксис: lsapi_engine On/Off
- По подразбиране: Off
- Какво прави: Включва или изключва mod_lsapi. Трябва да е включено (On), за да работи модула.
📂 lsapi_socket_path
- Синтаксис: lsapi_socket_path /път/до/сокет
- По подразбиране: /var/mod_lsapi
- Какво прави: Указва къде да се съхраняват socket файловете на lsphp.
⏱️ lsapi_poll_timeout
- Синтаксис: lsapi_poll_timeout 300
- По подразбиране: 300 (секунди)
- Какво прави: Колко време Apache чака отговор от lsphp. Може да се използва за ограничаване на дълги заявки.
👤 lsapi_per_user
- Синтаксис: lsapi_per_user On/Off
- По подразбиране: Off
- Какво прави: Когато е включено, lsphp процесите се стартират по потребител (акаунт), а не по виртуален хост. Това позволява споделяне на ресурси между сайтове на един и същ потребител.
📤 lsapi_output_buffering
- По подразбиране: On
- Какво прави: Включва или изключва буфериране на изхода (output buffering) – полезно е за по-добра производителност.
🚫 lsapi_disable_reject_mode
- По подразбиране: Off (т.е. REJECT mode е активен)
- Какво прави: Когато всички процеси на lsphp са заети, нови заявки се отхвърлят (код 507) или чакат на опашка. Включването на тази опция деактивира REJECT режима и позволява чакане.
🔁 lsapi_terminate_backends_on_exit
- По подразбиране: On
- Какво прави: Когато Apache се рестартира, всички lsphp процеси също се спират. Ако е Off, те остават активни (което е полезно, ако се използва opcache).
🧟 lsapi_avoid_zombies
- По подразбиране: Off
- Какво прави: Предотвратява създаването на зомби-процеси.
🌐 lsapi_use_req_hostname
- По подразбиране: Off
- Какво прави: Използва хостнейма от заявката вместо от конфигурацията на виртуалния хост. Полезно за динамични хостове (примерно с mod_lua).
🛠️ lsapi_sentry
- По подразбиране: On
- Какво прави: Изпраща грешки от mod_lsapi към сървъра на Sentry (логовете също се пазят в /var/log/mod_lsapi).
🐞 lsapi_debug
- По подразбиране: Off
- Какво прави: Активира допълнителна информация в логовете за дебъгване.
🧰 Фина настройка на LSPHP backend
🌱 lsapi_set_env
- Какво прави: Добавя нова среда (env) променлива към lsphp процесите.
- Пример: lsapi_set_env TMP “/var/tmp”
🛣️ lsapi_set_env_path
- Какво прави: Променя PATH променливата (път до изпълними файлове). Не може да се прави с lsapi_set_env поради съображения за сигурност.
👶 lsapi_backend_children
- По подразбиране: Равен на броя на EP (entry processes)
- Какво прави: Указва колко паралелни lsphp процеса могат да работят. Пример: ако имаш EP=20, тогава LSAPI_CHILDREN=21.
🔁 lsapi_backend_connect_tries
- По подразбиране: 20
- Какво прави: Колко пъти Apache ще пробва да се свърже с lsphp преди да откаже.
⏳ lsapi_backend_connect_timeout
- По подразбиране: 500000 (в микросекунди)
- Какво прави: Колко време се изчаква lsphp да стартира, ако не е активен.
⏱️ lsapi_backend_max_process_time
- По подразбиране: 300 секунди
- Какво прави: Колко дълго може да работи даден lsphp процес преди да бъде прекратен (за предпазване от зависвания).
💤 lsapi_backend_pgrp_max_idle
- По подразбиране: 30 секунди
- Какво прави: Ако няма заявки за повече от тази стойност, процесът се спира автоматично. 0 = никога не спира.
📜 lsapi_backend_use_own_log
- По подразбиране: Off
- Какво прави: Ако е включено, логовете на lsphp се записват в отделен файл, а не в Apache логовете.
🧾 lsapi_backend_common_own_log
- По подразбиране: Off
- Какво прави: Когато е включено заедно с горната опция, всички сайтове използват един общ лог файл. Ако е изключено – всеки сайт има свой лог.
💥 lsapi_backend_coredump
- По подразбиране: Off
- Какво прави: Ако е включено, при срив на lsphp ще се създаде core dump файл – за подробен анализ.
🔔 lsapi_backend_accept_notify
- По подразбиране: On
- Какво прави: Позволява на lsphp да получава известия за нови заявки – несъвместимо с PHP 4.4.
🔄 lsapi_backend_pgrp_max_reqs
- По подразбиране: 0 (неограничен брой заявки)
- Какво прави: Колко заявки да обслужи един backend процес преди да бъде рестартиран.
💣 lsapi_backend_pgrp_max_crashes
- По подразбиране: 0 (неограничен брой сривове)
- Какво прави: Колко пъти даден процес може да се срине, преди да се рестартира backend процеса.
🪵 lsapi_backend_loglevel_info
- По подразбиране: Off
- Какво прави: Определя дали PHP предупреждения и съобщения ще се записват като LOG_INFO или само като LOG_WARNING.
Управление на памет и процеси
🔥 lsapi_backend_oom_score_adj
- Какво прави: Помага да определите колко “жертвен” да е lsphp процесът, ако сървърът остане без памет. По-големи стойности означават по-голям шанс процесът да бъде убит.
- Стойности: от -1000 до 1000 (по подразбиране: 0)
- Полезно при: предотвратяване на сривове при претоварване.
🧪 lsapi_server_tweak
- По подразбиране: Off
- Какво прави: Позволява някои настройки (като lsapi_set_env) да се използват директно във виртуални хостове. Включете го, ако искате по-фина настройка на отделни сайтове.
🏊♂️ Режим на connection pool (споделени връзки)
🔗 lsapi_with_connection_pool
- По подразбиране: Off
- Какво прави: Активира режим на споделени връзки между Apache и lsphp (по-добра производителност при много заявки).
⌛ lsapi_backend_max_idle
- По подразбиране: 300 секунди
- Какво прави: Определя колко дълго lsphp процес остава активен, ако няма заявки. Само при включен connection pool режим.
🔁 lsapi_backend_max_reqs
- По подразбиране: 10,000
- Какво прави: Колко заявки ще обслужи lsphp процес преди да се затвори (в pool режим).
❄️ Поддръжка на CRIU (замразяване на процеси)
🧊 lsapi_criu
- По подразбиране: Off
- Какво прави: Активира функция за “замразяване” на lsphp процеси с помощта на CRIU — ускорява зареждането при следваща заявка.
🧩 lsapi_criu_socket_path
- По подразбиране: /var/run/criu/criu_service.socket
- Какво прави: Път до сокета, по който Apache и CRIU комуникират.
🗂️ lsapi_criu_imgs_dir_path
- По подразбиране: /var/mod_lsapi/
- Какво прави: Къде се съхраняват “замразените” снимки (snapshots) на PHP процесите.
🧮 lsapi_backend_initial_start
- По подразбиране: 0 (деактивирано)
- Какво прави: Колко заявки да получи даден виртуален хост преди да се включи “замразяването” на процеси.
🔁 lsapi_criu_use_shm
- По подразбиране: Off
- Какво прави: Определя как се броят заявките: чрез памет (shm) или чрез сигнали.
🕓 lsapi_backend_semtimedwait
- По подразбиране: On
- Какво прави: Използва семафори за ускоряване на старта на lsphp — по-бързо и по-ефективно.
🧹 lsapi_reset_criu_on_apache_restart
- По подразбиране: Off
- Какво прави: Ако е On – при рестарт на Apache, всички “замразени” образи на процеси се изтриват.
🐞 lsapi_criu_debug
- По подразбиране: Off
- Какво прави: Включва детайлни логове за CRIU (полезно при диагностика).
🧩 Управление на PHP конфигурация
📄 lsapi_process_phpini
- По подразбиране: Off
- Какво прави: Активира/деактивира обработката на директиви като phpini_*.
📁 lsapi_phpini
- Какво прави: Позволява задаване на конкретен php.ini файл, дори в .htaccess. Работи само ако горната опция е включена.
📌 lsapi_phprc
- По подразбиране: No
- Опции:
- No – няма PHPRC.
- Env – взема от околната среда (env).
- Auto – от DocumentRoot или $HOME.
- DocRoot – винаги от DocumentRoot.
- Какво прави: Определя откъде да се зареди php.ini файл.
🧊 lsapi_tmpdir
- По подразбиране: /tmp
- Какво прави: Директория за временно съхранение на заявки (upload-и и др.).
🔧 lsapi_enable_user_ini
- По подразбиране: Off
- Какво прави: Активира .user.ini файловете, подобно на suphp или php-fpm.
🏠 lsapi_user_ini_homedir
- По подразбиране: Off
- Какво прави: Ако .user.ini е активиран, тази настройка решава дали да се търси и в началната директория на потребителя.
✅ lsapi_keep_http200
- По подразбиране: Off
- Какво прави: Определя дали да се запази оригиналният HTTP статус от PHP, както при mod_php.
Поведение и сигурност
🔧 Поведение като mod_php
- lsapi_mod_php_behaviour On
Позволява ползване на php_value, php_flag и подобни директиви в .htaccess и конфигурационните файлове, сякаш използвате mod_php.
🔐 Сигурност
- lsapi_use_suexec On
Изпълнява PHP скриптовете от името на потребителя, както при suEXEC. Препоръчва се. - lsapi_user_group [user] [group]
Изрично задава кой потребител и група да изпълняват PHP заявката. - lsapi_uid_gid [uid] [gid]
Същото, но със системни ID-та вместо имена. - lsapi_use_default_uid On
Ако не е зададен UID/GID, използва UID на Apache. Ако е Off и няма зададен UID – връща грешка 503. - lsapi_target_perm On
Проверява дали PHP скриптът е собственост на същия потребител, който го изпълнява. Ако не – връща грешка 503. Повишава сигурността. - lsapi_paranoid On
Проверява правата върху PHP файловете. Полезно за защита. - lsapi_check_document_root On
Проверява дали DocumentRoot е собственост на правилния потребител. - lsapi_disable_forced_pwd_var On
Спира добавянето на променливата PWD в средата. Полезно при по-строги политики.
📦 HTTP заявки и буфериране
- lsapi_max_resend_buffer 200
Определя до колко KB може да се буферира POST заявка, която се изпраща повторно.
🐞 Отстраняване на проблеми (Troubleshooting)
Проблемите с mod_lsapi се виждат в логовете:
- Apache error_log – системни грешки
- sulsphp_log – логове от самия lsphp
⚠️ Чести проблеми и решения:
| Проблема | Обяснение | Решение |
| connect to lsphp failed: 111 Connection refused | Няма достатъчно памет за LVE | Увеличете pmem или vmem лимита за UID |
| ReceiveLSHeader: nothing to read | Процесът е бил убит (може би от Apache или CSF/LFD) | Задайте lsapi_terminate_backends_on_exit Off и игнорирайте lsphp в CSF |
| Own id for script file… | Скриптът не е собственост на потребителя | Изключете lsapi_target_perm (НЕ се препоръчва в продукция) |
| Could not determine uid/gid | Липсва UID/GID в виртуалния хост | Уверете се, че lsapi_use_default_uid On е зададено |
| Reached max children process limit | Надхвърлен лимитът на активни lsphp процеси | Увеличете lsapi_backend_children или EP/NPROC лимитите |
| fork() failed или Cannot allocate memory | Недостатъчно памет за нов процес | Увеличете PMEM или намалете броя на процесите |
| connect to lsphp failed: 13 | mod_ruid2 е активен | Деактивирайте mod_ruid2 – не е съвместим с mod_lsapi |
| backend rejected | Всички работещи процеси са заети | Задайте lsapi_disable_reject_mode On за да изчаква заявката |
mod_lsapi и нестандартни конфигурации
✅ Apache използва различен потребител (не apache или nobody)
Ако вашият Apache работи под друг потребител (примерно webuser), трябва да прекомпилирате sulsphp, за да го съобразите със сигурността:
yum install liblsapi liblsapi-devel
cd ~
wget https://repo.cloudlinux.com/cloudlinux/sources/da/mod_lsapi.tar.gz
tar zxvf mod_lsapi.tar.gz
cd mod-lsapi-0.1-XX
cmake -DHTTPD_USER=<ИМЕ_НА_ПОЛЗВАТЕЛ> .
make
make install
➡️ Това ще инсталира:
- Модула: /usr/lib/apache/mod_lsapi.so
- Скрипта: /usr/sbin/sulsphp
Забележка: От версия 1.1-80 нататък, mod_lsapi автоматично разчита потребителя от Apache конфигурацията, така че ръчната компилация вече не е задължителна.
🧒 PHP изпълняван от потребители с UID под 99
Ако искате mod_lsapi да работи с потребители с UID < 99:
cmake -DUID_MIN=80 -DGID_MIN=80 .
Това позволява на по-ниски системни UID-ове да използват mod_lsapi.
⚙️ Apache бинарен файл е нестандартен (примерно httpd.worker)
cmake -DPARENT_NAME=”httpd.worker” .
❗ WHMCS статус страница не се зарежда (при cPanel)
Решение:
useradd userstat
Добавете това в края на файла /usr/local/apache/conf/conf.d/lsapi.conf:
<Directory /usr/local/apache/htdocs/>
lsapi_user_group userstat userstat
</Directory>
След това рестартирайте Apache:
service httpd restart
❌ PHP страница връща 503 грешка със Suhosin или APC
Suhosin – препоръчителни настройки:
Добавете това в php.ini:
[suhosin]
suhosin.simulation = Off
suhosin.cookie.max_vars = 16384
…
suhosin.get.max_vars = 16384
…
suhosin.post.max_vars = 16384
APC – препоръчителни настройки:
[apc]
apc.shm_segments = 1
apc.shm_size = 32
Паметта за споделен сегмент трябва да е поне 32MB.
💥 Как да активирате core dump при срив на lsphp
- Във lsapi.conf:
lsapi_backend_coredump On
- В системата:
sysctl -w ‘kernel.core_uses_pid=1’
sysctl -w ‘kernel.core_pattern=core.%p’
- В /etc/security/limits.conf:
user1 soft core unlimited
user1 hard core unlimited
- В apachectl добавете:
ulimit -c unlimited
- Рестартирайте Apache по “студен” начин:
service httpd stop
sleep 2
killall lsphp
service httpd start
🔍 Проверка дали core dump е разрешен:
cat /proc/$(pgrep -f lsphp | head -1)/limits | grep ‘Max core file size’
🧊 CRIU – “замразяване” на lsphp процеси
CRIU (Checkpoint/Restore In Userspace) позволява да “замразите” работещ lsphp процес и после да го “размразите” по-късно, за по-бързо стартиране на PHP скриптове.
🧪 Активиране:
- Инсталира се автоматично с mod_lsapi.
- Активирайте и стартирайте CRIU:
systemctl enable criu
systemctl start criu
- В lsapi.conf добавете:
lsapi_criu On
lsapi_criu_socket_path /var/run/criu/criu_service.socket
lsapi_backend_semtimedwait On
lsapi_backend_initial_start 15
lsapi_criu_use_shm Off
- Рестартирайте Apache:
service httpd restart
📝 CRIU ще замразява lsphp след 15 заявки (или каквото сте задали в lsapi_backend_initial_start).
🧹 Изчистване на CRIU изображения
Добавете в lsapi.conf:
lsapi_reset_criu_on_apache_restart On
Това ще изтрие “замразените” образи при всяко рестартиране на Apache.
Можете също да изтриете само за определен виртуален хост:
touch ~/mod_lsapi_reset_me_mysite.com
❗ Не работи, ако lsapi_per_user е включено (On).
Какво е NGINX LSAPI Module?
NGINX LSAPI Module е допълнителен модул за уеб сървъра NGINX, който му позволява да работи директно с lsphp – бърз и лек PHP обработващ процес, използван и от LiteSpeed сървъра.
С него получаваме по-добра производителност, по-малко натоварване на паметта и по-добра стабилност спрямо други технологии като PHP-FPM.
🧠 Как работи?
- NGINX получава PHP заявка и я предава на NGINX LSAPI модула;
- Той използва liblsapi, за да прати заявката към lsphp процеса;
- lsphp създава дъщерен процес, който изпълнява скрипта и връща отговора обратно към NGINX;
- Ако няма заявки за известно време (lsapi_backend_pgrp_max_idle), процесът се затваря;
- Ако няма активни lsphp процеси, се стартира нов;
- lsphp процесите могат да обслужват заявки едновременно.
🧩 Какво е lsphp?
Това е PHP, компилиран с LSAPI – интерфейс за оптимална комуникация между уеб сървър (в случая NGINX) и PHP.
📋 Изисквания и препоръки
- Препоръчително е да използвате:
- LVE лимити – за контрол над ресурсите;
- CageFS – за изолирана и по-сигурна среда;
- PHP Selector (alt-php) – за избор на PHP версии за всеки потребител;
- ea-php (ако сте с cPanel).
🛠️ Инсталация (само за cPanel засега)
- Инсталирайте пакета:
yum install ea-nginx-mod-lsapi –enablerepo=cl-ea4-testing
- Рестартирайте NGINX:
service nginx restart
- Използвайте Apache2MaxWebserver, за да конвертирате .htaccess файлове в подходящи NGINX конфигурации автоматично.
❌ Деинсталиране
Ако искате да го премахнете:
yum erase ea-nginx-mod-lsapi
service nginx restart
⚙️ Конфигурация
Ако използвате Apache2MaxWebserver – няма нужда от ръчна настройка.
Ако конфигурирате ръчно, ето какво трябва да направите:
- Уверете се, че модулът е зареден – трябва да съществува файл с това съдържание:
load_module “/usr/lib64/nginx/modules/ngx_http_lsapi_module.so”;
- Добавете път към модулите в nginx.conf:
include /usr/share/nginx/modules/*.conf;
- Добавете следната конфигурация, за да обработва PHP:
server {
listen 80;
server_name testlsapi.com;
root /home/testlsapi/public_html;
location ~ \.php$ {
lsapi_engine on;
lsapi_handler application/x-httpd-lsphp;
lsapi_user testlsapi;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
📌 Забележка: Деактивирайте други PHP хендлъри като php-fpm, за да не пречат.
🛠️ Основни настройки на NGINX LSAPI Module
| Настройка | Какво прави | Примерна стойност |
| lsapi_engine | Включва или изключва модула за даден сайт или глобално. | lsapi_engine on; |
| lsapi_sock_path | Път до сокетите на lsphp (комуникационни файлове). | /var/ngx_lsapi |
| lsapi_per_user | Всеки потребител има отделен lsphp процес (вместо всеки сайт). | lsapi_per_user on; |
| lsapi_disable_reject_mode | Ако всички lsphp процеси са заети: вместо отказ → чакане. | lsapi_disable_reject_mode on; |
| lsapi_terminate_backends_on_exit | При рестарт на nginx – да се убият ли lsphp процесите. | lsapi_terminate_backends_on_exit on; |
| lsapi_avoid_zombies | Предпазва от „зомби“ процеси (висящи и неизчистени). | lsapi_avoid_zombies on; |
🔁 Стартиране и логове
| Настройка | Какво прави | Примерна стойност |
| lsapi_starter_sock | Местоположение на сокета за стартиращия процес. | /var/run/lsapi-starter.sock; |
| lsapi_starter_log | Път до лог файл за стартиране на lsphp. | /var/log/lsapi-starter.log; |
| lsapi_log | Лог за самия модул (ако е компилиран със специална поддръжка). | /var/log/lsapi.log; |
🧪 Среда и път
| Настройка | Какво прави | Примерна стойност |
| lsapi_set_env | Задава среда за PHP. | lsapi_set_env TMP “/var/tmp”; |
| lsapi_set_env_path | Променя PATH променливата. | lsapi_set_env_path /custom/bin:/usr/bin; |
⚖️ Управление на ресурси и процеси
| Настройка | Какво прави | Стойност (примерна) |
| lsapi_backend_children | Колко lsphp процеса могат да работят едновременно. | 300 |
| lsapi_backend_connect_tries | Колко пъти да опитва връзка с lsphp. | 20 |
| lsapi_backend_max_process_time | Максимално време за работа на процес. | 300 секунди |
| lsapi_backend_pgrp_max_idle | Колко време да чака нова заявка преди да се затвори. | 30 секунди |
| lsapi_backend_pgrp_max_crashes | Брой сривове преди да се рестартира процесът. | 300 |
| lsapi_backend_pgrp_max_reqs | Брой заявки преди рестарт. | 0 – безкрайно |
📝 Логове
| Настройка | Какво прави | Стойност |
| lsapi_backend_use_own_log | Използва отделни логове за PHP процесите. | on |
| lsapi_backend_common_own_log | Един общ лог за всички сайтове. | on |
| lsapi_backend_loglevel_info | Да се записват ли предупреждения на ниво info. | on |
| lsapi_dump_debug_info | Включва debug логване. | on |
🔒 Безопасност и поведение
| Настройка | Какво прави | Стойност |
| lsapi_backend_oom_score_adj | Колко лесно да бъде убит процесът при изчерпана памет (по-висока стойност = по-лесно). | 1000 (по-рисково) |
| lsapi_backend_accept_notify | Нотификация за lsphp готовност. | on |
| lsapi_backend_coredump | Позволява генериране на core dump при срив. | on |
| lsapi_pwd_disabled | Да не се добавя PWD в средата. | on |
🧩 Връзка с PHP
| Настройка | Какво прави | Пример |
| lsapi_handler | Задава какъв тип заявки (.php) да се обработват от lsapi. | lsapi_handler application/x-httpd-lsphp; |
📘 Примерен конфигурационен блок за nginx:
server {
listen 80;
server_name example.com;
root /home/example/public_html;
location ~ \.php$ {
lsapi_engine on;
lsapi_handler application/x-httpd-lsphp;
lsapi_user example;
lsapi_per_user on;
lsapi_backend_children 50;
lsapi_disable_reject_mode on;
}
}
Connection Pool Mode (Режим с пул от връзки)
| Настройка | Какво прави | Пример |
| lsapi_with_connection_pool | Включва/изключва режим с пул от връзки. По-бърза обработка. | lsapi_with_connection_pool on; |
| lsapi_backend_max_idle | Колко време lsphp процес да чака нова заявка преди да се изключи. | lsapi_backend_max_idle 300; |
| lsapi_backend_max_reqs | Максимален брой заявки, които един процес ще обработи преди да се рестартира. | lsapi_backend_max_reqs 20000; |
| lsapi_pool_size | Размер на пула (брой връзки) за всеки виртуален хост. | lsapi_pool_size 20; |
❄️ CRIU – Замразяване на PHP процеси
Позволява “замразяване” на lsphp процеси и възстановяване при нужда (за по-бърз старт).
| Настройка | Какво прави | Пример |
| lsapi_criu | Активира CRIU функцията. | lsapi_criu on; |
| lsapi_criu_socket_path | Път до сокета на criu услугата. | /var/run/criu/criu_service.socket; |
| lsapi_criu_imgs_dir_path | Къде да се пазят “замразените” PHP изображения. | /var/ngx_lsapi/criu; |
| lsapi_backend_initial_start | След колко заявки да се замрази процеса. 0 = изключено. | 15 |
| lsapi_reset_criu_on_restart | Изчиства CRIU изображения при рестарт на NGINX. | on |
| lsapi_criu_use_shm | Метод за отчитане на заявки – чрез памет или сигнали. | signals |
| lsapi_criu_debug | Включва debug логване за CRIU. | off |
📄 PHP конфигурация – php.ini и .user.ini
| Настройка | Какво прави | Пример |
| lsapi_process_phpini | Позволява настройките от php.ini да се използват. | on |
| lsapi_phpini | Пълен път до php.ini файл, който да се използва. | /home/user/public_html/php.ini |
| lsapi_phprc | Автоматично откриване на php.ini (по DocumentRoot, $HOME и т.н.). | Auto, DocRoot, Env, No |
| lsapi_tmpdir | Директория за временни файлове. | /usr/tmp |
| lsapi_enable_user_ini | Разрешава използването на .user.ini. | on |
| lsapi_user_ini_homedir | Разрешава .user.ini и в home директорията. | on |
| lsapi_mod_php_behaviour | Активира поддръжка на php_flag, php_value директиви. | on |
| lsapi_param | Задава PHP конфигурации чрез nginx. | lsapi_param PHP_ADMIN_VALUE “memory_limit=1024M”; |
🔐 Сигурност и потребители
| Настройка | Какво прави | Пример |
| lsapi_use_suexec | Разрешава изпълнение като конкретен потребител. | on |
| lsapi_user | Потребител и група, под които ще се изпълнява PHP. | lsapi_user user1 user1; |
| lsapi_paranoid | Проверява дали PHP скриптовете имат коректни права. | on |
| lsapi_check_owner | Проверява дали PHP скриптът е собственост на текущия потребител. | on |
✅ Примерна секция за сайт с включен LSAPI и CRIU
server {
listen 80;
server_name example.com;
root /home/example/public_html;
location ~ \.php$ {
lsapi_engine on;
lsapi_handler application/x-httpd-lsphp;
lsapi_user example;
lsapi_per_user on;
lsapi_backend_children 50;
lsapi_disable_reject_mode on;
lsapi_criu on;
lsapi_backend_initial_start 20;
lsapi_criu_imgs_dir_path /var/ngx_lsapi/criu;
}
}
Допълнителни настройки за сигурност (проверка на собственост)
Тези опции добавят още проверки, за да се уверим, че PHP скриптовете са стартирани само от техния собственик:
| Настройка | Какво прави | Пример | По подразбиране |
| lsapi_check_owner | Проверява дали PHP скриптът е собственост на потребителя. | lsapi_check_owner on; | off |
| lsapi_check_document_root | Проверява дали DOCUMENT_ROOT принадлежи на правилния потребител. | lsapi_check_document_root on; | off |
| lsapi_check_script | Проверява собствеността на PHP файла преди да се изпрати към lsphp. | lsapi_check_script on; | on |
🔐 Тези опции се препоръчват в споделени хостинг среди за по-добра защита.
👥 Ръчно задаване на UID и GID
lsapi_uid_gid 1001 1001;
С тази настройка можеш ръчно да зададеш под какъв потребител и група да работи lsphp, ако не се ползва lsapi_user.
🛠️ Отстраняване на проблеми – Логове
Ако нещо не работи, ще намериш полезна информация в следните лог файлове:
- /var/log/nginx/error.log – стандартен nginx лог
- /var/log/sulsphp.log – специфичен за LSAPI и lsphp
Най-чести проблеми и решения:
| Проблема | Решение |
| Connection refused | Увеличи pmem/vmem лимити за потребителя или броя на процесите (lsapi_backend_children). |
| ReceiveLSHeader: nothing to read from backend socket | lsphp процес е убит – възможно от рестарт на nginx или lfd. Настрой lsapi_terminate_backends_on_exit off; |
| file is writable by others | Провери правата на /usr/local/bin/lsphp: chmod 755 |
| 507 HTTP error | Всички lsphp процеси са заети. Активирай опцията lsapi_disable_reject_mode on; |
| Signal: 11, core dump: 0 | Настрой php.ini (APC/Suhosin). Активирай core dump логика (виж по-долу). |
❄️ CRIU поддръжка (замразяване на PHP процеси)
CRIU (Checkpoint/Restore In Userspace) позволява да се “замразят” lsphp процесите и при нужда да се възстановят отново, без да стартират отначало – това ускорява отварянето на PHP страници.
✅ Примерни настройки:
lsapi_criu on;
lsapi_criu_socket_path /var/run/criu/criu_service.socket;
lsapi_criu_imgs_dir_path /var/nginx-mod-lsapi/;
lsapi_backend_initial_start 15;
lsapi_criu_use_shm off;
lsapi_criu_debug off;
Как работи:
- При първите 15 заявки се събира информация (според lsapi_backend_initial_start).
- След това CRIU създава snapshot (образ) на lsphp.
- Следващия път процесът се “размразява” и стартира моментално.
- Образите остават дори при рестарт на nginx, но се изтриват при рестарт на сървъра, освен ако не е указано друго.
🧼 Почистване на изображения:
Автоматично при рестарт на nginx:
lsapi_reset_criu_on_restart on;
- Ръчно (ако си сменил php.ini):
Изтрий съдържанието на lsapi_criu_imgs_dir_path.
⚠️ Важно:
Ако използваш PrivateTmp=true в nginx.service, CRIU няма да работи. Смени го с PrivateTmp=false.
Как да изключим PrivateTmp за nginx (необходимо за CRIU)
За да може CRIU да работи с lsphp, трябва да деактивираме PrivateTmp в nginx услугата. Има два начина:
✅ Метод 1: Копиране на пълната nginx услуга
- Копираш съществуващия nginx.service файл:
cp /usr/lib/systemd/system/nginx.service /etc/systemd/system/nginx.service
- Отвори го с редактор (например nano) и промени:
PrivateTmp=false
- Презареди systemd:
systemctl daemon-reload
✅ Метод 2 (препоръчителен): Създай малък override
bash
КопиранеРедактиране
mkdir -p /etc/systemd/system/nginx.service.d
echo “[Service]” > /etc/systemd/system/nginx.service.d/nopt.conf
echo “PrivateTmp=false” >> /etc/systemd/system/nginx.service.d/nopt.conf
systemctl daemon-reload
❄️ Активиране на CRIU за lsphp процеси
CRIU е инсталиран автоматично с NGINX LSAPI модула. За да го активираш:
systemctl enable criu
systemctl start criu
След това редактирай lsapi.conf и добави:
lsapi_criu on;
lsapi_criu_socket_path /var/run/criu/criu_service.socket;
lsapi_backend_initial_start 15;
lsapi_criu_use_shm off;
lsapi_criu_debug off;
След това рестартирай nginx:
service nginx restart
🧼 Изчистване на CRIU изображения
Когато CRIU “замрази” lsphp, създава файлове. Ако искаш да ги изчистиш:
🌍 Глобално при рестарт на nginx
В lsapi.conf добави:
lsapi_reset_criu_on_restart on;
Работи само ако lsapi_terminate_backends_on_exit е on.
👤 За конкретен потребител (ръчно)
- Отиди в папката със CRIU файлове (например /var/ngx_lsapi/criu/).
- Създай файл:
touch /var/ngx_lsapi/criu/lsapi_user_reset.criu_imgs
🔐 Глобално нулиране през файл
mkdir -p /usr/share/criu/mod_lsapi
chown nginx:nginx /usr/share/criu/mod_lsapi
chmod 700 /usr/share/criu/mod_lsapi
touch /usr/share/criu/mod_lsapi/lsphp.criu.reset
🧑 Нулиране от самия потребител
- Потребителят създава файл в домашната директория:
touch ~/mod_lsapi_reset_me_my.domain.com
my.domain.com трябва да съвпада с server_name от nginx конфигурацията.
⚠️ Важно: Това няма да работи, ако lsapi_per_user е on.
🛡️ Интеграции за сигурност и LVE
🧱 pam_lve.so – добавяне на LVE при вход (ssh, su, cron и т.н.)
- Инсталирай:
yum install pam_lve
- Добави ред към нужния PAM конфигурационен файл (пример: /etc/pam.d/sshd):
session required pam_lve.so 500 1 wheel,other
- 500 – минимален UID за LVE
- 1 – включва CageFS
- wheel,other – групи, изключени от LVE (напр. root потребители)
⚠️ Не го добавяй в /etc/pam.d/sudo! Това може да счупи някои функции като Node.js/PHP Selector.
🔐 pam_sulve – защита срещу “влизане като root в LVE”
Това предотвратява влизане като root от потребител вътре в LVE.
Провери дали е активен:
grep pam_sulve.so /etc/pam.d/*
🔄 Изпълнение на команди в LVE – LVE Wrappers
Инсталирай:
yum install lve-wrappers
✅ Изпълнение на команда от текущия потребител:
lve_wrapper make install
✅ Изпълнение в конкретен LVE от root:
lve_suwrapper 1000 /etc/init.d/postgresql start
Какво е MPM ITK?
MPM ITK е специален модул за Apache, който позволява всяка заявка (request) да се изпълнява под отделен потребител. Това увеличава сигурността и контрола върху ресурсите.
📦 Вградено в CloudLinux OS
Ако ползваш Apache от CloudLinux OS (httpd RPM), MPM ITK вече е вграден и не е нужно да го добавяш ръчно.
🛠️ Ако искаш да билднеш свой собствен Apache
Изтегли пачовете:
wget https://repo.cloudlinux.com/cloudlinux/sources/da/cl-apache-patches.tar.gz
Разархивирай архива:
tar -zxvf cl-apache-patches.tar.gz
Използвай следния patch файл:
apache2.2-mpm-itk-seculrelve12.patch
- Прилагаш го към твоя Apache source преди компилиране.
❌ Изключи mod_hostinglimits
MPM ITK вече има вградена функционалност за LVE лимити, така че mod_hostinglimits трябва да бъде изключен, когато използваш MPM ITK.
🧩 Apache директиви, които можеш да използваш с ITK и CloudLinux:
| Директива | Описание |
| AssignUserID | Определя под кой потребител/група ще се изпълнява заявката. Също така се използва за задаване на LVE ID. |
| LVEErrorCodeITK | Определя какъв HTTP код да се върне при грешка с LVE лимит (по подразбиране: 508). |
| LVERetryAfterITK | Връща HTTP заглавка Retry-After, когато възникне грешка 508. |
| LVEId | Пренаписва LVE ID (ако искаш да използваш различен от този, определен от AssignUserID). |
| LVEUser | Използва конкретен потребител за определяне на LVE ID, вместо този, зададен в AssignUserID. |
Какво е mod_hostinglimits?
Това е модул за Apache, който позволява ограничаване на ресурсите (CPU, RAM, процеси и др.) на базата на LVE за всеки потребител. Работи отлично с PHP и CGI скриптове.
🧠 Как работи?
Модулът определя кой потребител стои зад даден уебсайт и го поставя в LVE среда – т.е. вътре в собствения му „ресурсен балон“.
Открива потребителя чрез:
- SuexecUserGroup – ако ползваш mod_suexec
- suPHP_UserGroup – ако ползваш mod_suphp
- AssignUserID – ако ползваш MPM ITK
- RUidGid – ако ползваш mod_ruid2
Ако искаш, можеш ръчно да зададеш потребител или LVE ID с:
- LVEUser
- LVEId (вътре в <Directory> блок)
⚠️ Не работи с mod_fcgid и mod_cgid
🔧 Примерна конфигурация:
LoadModule hostinglimits_module modules/mod_hostinglimits.so
<IfModule mod_hostinglimits.c>
AllowedHandlers cgi-script php5-script php4-script
SecureLinks On
</IfModule>
🛡️ Важни директиви
| Директива | Какво прави |
| SecureLinks On | Забранява достъп до файлове, които не са собственост на потребителя (предпазва от symlink атаки) |
| AllowedHandlers | Определя кои типове файлове да попадат под LVE контрол (пример: PHP, CGI) |
| DenyHandlers | Обратно – забранява LVE за конкретни handler-и |
| LVEId | Принудително задава LVE ID за дадена директория |
| LVEUser | Принудително задава потребител за LVE в дадена директория |
| LVEErrorCode | Променя кода, който се връща при грешка за изчерпани ресурси (по подразбиране: 508) |
| LVERetryAfter | Връща заглавка “Retry-After”, ако сайтът е блокиран поради лимити |
| LVESitesDebug | Включва допълнително логване за избрани домейни |
| LVEUse429 | Вместо 508, връща грешка 429 „Too Many Requests“ |
📊 Логване на LVE ID в access_log
Можеш да добавиш LVE ID към всеки Apache лог ред така:
LogFormat “%h %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-Agent}i\” req for lve \”%{LVE_ID}y\”” combined
Така ще виждаш в логовете кой потребител какво натоварване създава.
🛠️ Инсталация
cPanel:
- Вградено в EasyApache 4
- Увери се, че имаш lve-stats и lve-utils инсталирани
DirectAdmin:
yum install liblve-devel
cd /usr/local/directadmin/custombuild
./build update
./build set cloudlinux yes
./build apache
./build rewrite_confs
Plesk, ISPmanager, InterWorx:
yum install mod_hostinglimits
Стандартна инсталация (ако Apache не е част от контролен панел):
yum install mod_hostinglimits
Или компилираш ръчно:
wget https://repo.cloudlinux.com/cloudlinux/sources/mod_hostinglimits.tar.gz
yum install cmake
tar -zxvf mod_hostinglimits*.tar.gz
cd mod_hostinglimits*
cmake .
make
make install
⚠️ Съвети за сигурност
- Използвай SecureLinks On – това е мощна защита срещу symlink атаки.
- Не забравяй, че mod_hostinglimits не е съвместим с mod_fcgid.
- AllowedHandlers с * може да доведе до излишно натоварване, така че ограничавай го при нужда.
CloudLinux cPanel/WHM JSON API – Управление на LVE
Използва се за:
- Промяна на лимити (CPU, IO и др.) за потребители, пакети и реселъри
- Извиква се чрез URL с токен и параметри
Примери:
# Задаване лимити на потребител с UID 500
https://IP:2087/cpsess_TOKEN/cgi/CloudLinux.cgi?cgiaction=jsonhandler&command=lvectl&handler=set&lveid=500&speed=30%&io=2048
# Лимити по потребителско име:
handler=set-user&lveid=username
📌 Speed може да е в: %, MHz, GHz
🔒 mod_proctitle – Проследяване на активни заявки в Apache
- Показва URL и тип заявки за всеки Apache процес
- Много полезно за диагностика на натоварване
🔧 Инсталация:
# EasyApache 4:
yum install ea-apache24-mod_proctitle
service httpd restart
👀 Преглед на активни заявки: Скрипт чете от /dev/shm/apache_title_shm_* и показва URL за всеки процес/нишка.
🧩 alt-suexec – suEXEC с различни root директории
Ако сайтовете ти не са в /var/www, а например в /home, трябва:
yum install alt-suexec
switch_suexec -sUSE_HOME
Това инсталира suEXEC, който знае къде са директориите на сайтовете ти.
🔄 mod_hostinglimits – Контрол на ресурсите чрез Apache
- Работи заедно със suEXEC, suPHP, ITK и други модули
- Слага всяка заявка в LVE според потребителя
Примерна конфигурация:
<IfModule mod_hostinglimits.c>
SecureLinks On
AllowedHandlers cgi-script %php%
</IfModule>
Опции:
- LVEUser / LVEId – пренасочват LVE ID ръчно
- LVEErrorCode – променя кода при изчерпани ресурси (508/429)
- LVESitesDebug – логове за избрани сайтове
🌀 CRIU – Замразяване на PHP процеси (Freezing)
- Позволява lsphp да бъде „замразен“ и стартиран по-бързо
- Работи с lsapi_criu директиви
Включване:
systemctl enable criu
systemctl start criu
# В lsapi.conf:
lsapi_criu on;
lsapi_backend_initial_start 15;
⚙️ LVE PAM module – Ограничения при ssh, su, crontab и др.
yum install pam_lve
И добавяш в /etc/pam.d/sshd:
session required pam_lve.so 500 1 wheel
🚨 Внимавай – грешна настройка може да заключи SSH достъп
🧰 LVE Wrappers – Стартиране на програми в LVE ръчно
yum install lve-wrappers
# Стартиране на команда в LVE на текущия потребител:
lve_wrapper make install
# Стартиране на команда в LVE с конкретен ID:
lve_suwrapper 1001 /etc/init.d/postgresql start
🌐 Nginx LSAPI модул
Алтернатива на PHP-FPM за Nginx. Много по-бърз и стабилен.
Инсталация (cPanel):
yum install ea-nginx-mod-lsapi –enablerepo=cl-ea4-testing
service nginx restart
Конфигурация:
location ~ \.php$ {
lsapi_engine on;
lsapi_handler application/x-httpd-lsphp;
lsapi_user testuser;
}
🧪 mod_suexec – Суид модул за Apache
- Важно за сигурно изпълнение на PHP/CGI скриптове
- CloudLinux добавя поддръжка за CageFS
- Изисква се от PHP Selector и mod_hostinglimits
🛠️ Какво още можеш да правиш:
| Действие | Метод | Пример |
| Задаване лимити на потребител | set-user | &lveid=username&speed=30% |
| Лимити за реселър | set-reseller | &lveid=res1 |
| Лимити за пакет | package-set | &lveid=res_pack1 |
| Изтриване на потребител | delete-user | &lveid=username |
mod_suexec – Quick Reference for CloudLinux
🔹 What It Does
Runs CGI/SSI (and often PHP via wrappers) under specific user/group IDs instead of the webserver (like apache or nobody), providing per-user security isolation.
📌 Directive: SuexecUserGroup
<VirtualHost *:80>
ServerName example.com
DocumentRoot /home/user/public_html
SuexecUserGroup user group
</VirtualHost>
- 🔐 Required when using mod_suexec for secure PHP execution
- 📦 Automatically handled by control panels (cPanel, DirectAdmin, Plesk)
- 🛠️ If no control panel: manually add per vhost
📦 Installation by Environment
| Control Panel | Action | Notes |
| cPanel (EA4) | yum install ea-apache24-mod_suexec | Must yum remove ea-apache24-mod_ruid2 first |
| Plesk | Pre-integrated | No action needed |
| DirectAdmin | Pre-integrated | No action needed |
| No Control Panel | Default in CloudLinux-provided Apache | No action unless custom Apache used |
🌀 If using CageFS + PHP Selector:
Always run:
cagefsctl –force-update
❗ Conflicts to Avoid
- ❌ mod_suexec conflicts with mod_ruid2
- Must uninstall ea-apache24-mod_ruid2 if present
- 💥 If both are active, Apache startup will fail or suexec will silently not work
🔧 Verification Tips
Check if mod_suexec is loaded:
httpd -M | grep suexec
Check suexec binary config:
/usr/sbin/suexec -V
You’ll see something like:
-D AP_DOC_ROOT=”/home”
-D AP_UID_MIN=500
-D AP_GID_MIN=100
🧰 Troubleshooting Checklist
| Symptom | Fix |
| Apache won’t start after adding SuexecUserGroup | mod_suexec might be missing or conflicting |
| PHP runs as apache/nobody | SuexecUserGroup missing or misconfigured |
| .php files download instead of executing | PHP handler not configured properly for mod_suexec (e.g., LSAPI, suphp) |
| CageFS not applying correctly | Run cagefsctl –force-update |