Доступен — Локальные цифровые продукты
HCA · Studio
TR Контакты ↗
Заметка 03 · Сервер

Половина .htaccess, которая не работает в OpenLiteSpeed

Говорят, что OpenLiteSpeed поддерживает синтаксис .htaccess из Apache — но лишь частично. Напишете неподдерживаемый блок — сообщения об ошибке не будет; страница вернёт 403, а рабочие правила в том же файле перестанут применяться.

Сервер
OpenLiteSpeed / CyberPanel
Симптом
Тихий 403
Последствие
Файл целиком недействителен
Короткий ответ

OpenLiteSpeed надёжно обрабатывает в .htaccess только правила перезаписи. Директивы <Files>, <FilesMatch>, <IfModule> и Header ведут себя не как в Apache; файл с ними в большинстве установок даёт 403, и правила перезаписи в том же файле тоже перестают применяться. Заголовки безопасности, времена кэширования и ограничения доступа к файлам задаются в конфигурации виртуального хоста.

Отличие от Apache

OpenLiteSpeed предлагает совместимость с Apache как слой совместимости; сам движок — не Apache. На практике это значит, что распространённые правила перезаписи работают, а большинство прочих директив либо игнорируется, либо считается ошибкой конфигурации.

Проблема в том, что это поведение тихое. В Apache плохая конфигурация обычно даёт 500 и понятную строку в журнале. В OpenLiteSpeed вы часто видите только 403 — и в журнале может не быть строки, объясняющей причину.

Хуже: когда ошибка относится к блоку, недействительным может стать весь файл. Совершенно рабочее перенаправление на HTTPS в начале файла тоже перестаёт работать. Это самая частая причина жалобы «написал правило, и ничего не происходит».

Что работает

# HTTPS и хост без www за один переход
RewriteEngine On
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]

# index.html -> адрес каталога (убирает дубли URL)
RewriteCond %{THE_REQUEST} \s/+(([^\s?]*/)?)index\.html[\s?] [NC]
RewriteRule ^ https://example.com/%1 [R=301,L]

RewriteEngine, RewriteCond, RewriteRule и их флаги (R, L, NC, QSA) работают ожидаемо. Правила постоянных ссылок WordPress относятся к этой категории — поэтому WordPress на OpenLiteSpeed работает без проблем.

Что ломается

# ✗ Заголовки безопасности — в .htaccess не работают
<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set Strict-Transport-Security "max-age=31536000"
</IfModule>

# ✗ Ограничение доступа к файлу — даёт 403 и обнуляет файл
<Files "wp-config.php">
  Require all denied
</Files>

# ✗ Правила по расширению
<FilesMatch "\.(env|log|bak|sql)$">
  Require all denied
</FilesMatch>

# ✗ Времена кэширования
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/webp "access plus 1 year"
</IfModule>

Опасность не только в том, что они не работают. Добавленные в .htaccess, они могут утянуть за собой рабочие правила. Однажды перенаправление сайта на HTTPS тихо перестаёт работать, и никто не понимает почему.

Как распознать симптом

  • Корень сайта или конкретная папка неожиданно отдаёт 403 Forbidden при корректных правах доступа.
  • Написанное вами перенаправление вообще не срабатывает — будто файл не читается.
  • После добавления правила сломалось другое, ранее рабочее.
mv .htaccess .htaccess.test
curl -sI https://example.com/ | head -1
# 403 ушёл? Причина была внутри файла.
mv .htaccess.test .htaccess

Затем делите файл пополам, чтобы сузить проблемный блок. Почти всегда это оказывается строка <IfModule>, <Files> или Header.

Правильное место: vhost

Всё, что не помещается в .htaccess, идёт в конфигурацию виртуального хоста. В CyberPanel это vhost.conf сайта, редактируемый из панели.

context / {
  extraHeaders            <<<END_extraHeaders
X-Content-Type-Options nosniff
X-Frame-Options SAMEORIGIN
Referrer-Policy strict-origin-when-cross-origin
Strict-Transport-Security max-age=31536000; includeSubDomains
  END_extraHeaders
}

expires {
  enableExpires           1
  expiresByType           image/webp=A31536000, text/css=A31536000, application/javascript=A31536000, text/html=A300
}

Обратите внимание на text/html=A300: HTML не следует кэшировать надолго. На статическом сайте кэшировать ресурсы на год, обновляя HTML каждые несколько минут, — верный баланс.

Для ограничения доступа к файлам используйте перезапись — она в .htaccess работает:

RewriteRule ^(.*/)?\.(env|git|htaccess|htpasswd)$ - [F,L]
RewriteRule \.(log|bak|sql|sql\.gz|tar\.gz|zip)$ - [F,L]

Флаг [F] возвращает 403 и не требует блочного синтаксиса, поэтому в OpenLiteSpeed работает чисто.

Ловушка статических файлов

Ещё одна деталь, важная для безопасности: OpenLiteSpeed может отдавать статические файлы, не пропуская их через правила перезаписи. Хорошо для производительности, но с неожиданным следствием — ваши резервные копии могут остаться незащищёнными.

# Рискованная привычка
cp wp-config.php wp-config.php.bak
cp index.html index.html.20260902.bak

Пока эти файлы лежат в корне сайта, их адреса можно угадать и скачать — а так как .bak не обрабатывается как PHP, содержимое отображается простым текстом. Включая пароль от базы данных.

mkdir -p /home/example.com/code-backups
cp /home/example.com/public_html/wp-config.php \
   /home/example.com/code-backups/wp-config.php.20260902

Веб-сервер эту папку не видит вовсе, и правило доступа не требуется.

Итог

В OpenLiteSpeed используйте .htaccess только как файл перезаписи. Заголовки, кэширование и файловые блоки относятся к конфигурации vhost; запреты доступа пишутся правилами перезаписи с флагом [F].

И всегда проверяйте сайт после изменения правил: на этом сервере ошибки не шумят, они тихо перестают работать.

Быстрая справка
Работает
RewriteEngine, RewriteCond, RewriteRule и флаги (R, L, NC, QSA, F)
Не работает
, , , Header, ExpiresByType
Риск
Неподдерживаемый блок может обнулить рабочие правила в том же файле
Симптом
Необъяснимый 403 или никогда не применяющееся перенаправление
Заголовки
Задаются в блоке extraHeaders в vhost
Кэширование
Блок expires в vhost — HTML коротко (A300), ресурсы долго (A31536000)
Запрет файлов
RewriteRule ... - [F,L], а не
Резервные копии
Хранить вне корня сайта — .bak скачиваются простым текстом
Частые вопросы

Об OpenLiteSpeed и .htaccess.

Поддерживает ли OpenLiteSpeed .htaccess?

Частично. Правила перезаписи (RewriteEngine, RewriteCond, RewriteRule) работают надёжно, поэтому WordPress устанавливается без проблем. Но блочные директивы вроде Header, IfModule, Files и FilesMatch ведут себя не как в Apache и в большинстве установок дают 403.

Сайт отдаёт необъяснимый 403 — с чего начать?

Временно переименуйте .htaccess и проверьте сайт. Если 403 исчез, причина внутри файла. Затем делите файл пополам; виновником почти всегда оказывается блок IfModule, Files или Header. Так как такой блок может обнулить весь файл, рабочие перенаправления в нём тоже перестают действовать.

Где задавать заголовки безопасности в OpenLiteSpeed?

В конфигурации виртуального хоста, в блоке context под extraHeaders. В CyberPanel конфигурацию vhost можно править из панели. Строки Header, написанные в .htaccess, не работают и могут сломать файл.

Как запретить доступ по расширению файла?

Используйте правило перезаписи с флагом F вместо FilesMatch: RewriteRule \.(log|bak|sql)$ - [F,L]. Оно не требует блочного синтаксиса и работает чисто. Тем не менее безопаснее всего держать чувствительные резервные копии вне корня сайта.

Доступность и смета

Виден в локальном поиске.
Убедителен в продукте.