65 лет полету человека в космос! Хостинг и домены со скидкой
до 22.04.2026 Подробнее
Выберите продукт

HTACCESS‑практики на виртуальном хостинге: закрываем .env/.git и запрещаем exec в uploads

На виртуальном хостинге .htaccess — главный инструмент быстрой защиты. Разберём, как закрыть .env и .git от внешнего доступа, отключить листинг каталогов через Options -Indexes и запретить выполнение PHP в uploads. Дадим готовые фрагменты и объясним, где их безопасно размещать.
HTACCESS‑практики на виртуальном хостинге: закрываем .env/.git и запрещаем exec в uploads

Если сайт живёт на виртуальном хостинге, у вас, как правило, нет доступа к конфигурации веб‑сервера на уровне vhost, но почти всегда доступен .htaccess. От него напрямую зависят безопасность и предсказуемость поведения приложений (WordPress, Laravel, Yii и т.д.). Ниже — рабочие практики «защиты по умолчанию»: закрываем .env и .git, отключаем индексирование каталогов, запрещаем исполнение PHP в uploads, разбираем подводные камни и совместимость Apache 2.4/2.2.

Почему именно .env, .git и uploads

Три самых частых источника проблем на виртуальном хостинге:

  • .env — файл с секретами (пароли к БД, ключи API). Если он доступен по HTTP — это мгновенная компрометация проекта.
  • .git — служебный каталог системы контроля версий; при публичном доступе злоумышленник может восстановить исходники и историю коммитов.
  • uploads — каталог с загружаемыми пользователями файлами (медиа). Сюда часто пытаются подсунуть web‑shell под видом картинки: задача — запретить исполнение любых скриптов тут.

Критерий успеха: попытки обратиться к .env, .git или любым «php» в uploads должны давать 403/404 и не раскрывать содержимого. Плюс отключён листинг каталогов.

Что можно и чего нельзя в .htaccess на виртуальном хостинге

В разных тарифах AllowOverride может отличаться. Где‑то можно менять Options и использовать mod_rewrite, где‑то нет. Если сомневаетесь, включайте защиту по слоям: FilesMatch с Require all denied (Apache 2.4) и резервно правила на mod_rewrite, чтобы блокировать каталоги вроде .git. В Apache 2.4 используется директива Require, в старых конфигурациях 2.2 — Deny/Allow. Мы дадим обе версии, обернув их в <IfModule>. Если у вас свой сервер на VDS, лучше уносить эти правила в конфиг vhost — см. разбор в статье почему конфиг vhost предпочтительнее .htaccess.

Схема слоёв защиты .htaccess на виртуальном хостинге

Базовый каркас .htaccess в корне сайта

Ниже — минимальный набор, который стоит держать первым делом. Он выключает листинг каталогов (Options -Indexes), запрещает доступ к .env, скрытым файлам/служебным каталогам, блокирует бэкапы и защищает служебные .ht*.

# 1) Общая гигиена: без индексации каталогов, без контент-неготиации по имени
Options -Indexes
Options -MultiViews

# 2) Защитить служебные .ht* (включая .htaccess, .htpasswd)
<FilesMatch "^\.ht">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# 3) Закрыть .env (включая вариации вроде .env.local)
<FilesMatch "^\.env(\..*)?$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# 4) Блокировать общие артефакты: composer.* и различные бэкапы
<FilesMatch "^(composer\.(json|lock)|package(-lock)?\.json|yarn\.lock|pnpm-lock\.yaml|.*\.(bak|old|swp|swo|tmp|sql|sqlite|zip|tar|gz))$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# 5) Разрешить .well-known (ACME) при блокировке скрытых путей
# Важно: сначала разрешаем исключение, потом общую блокировку
<IfModule mod_rewrite.c>
  RewriteEngine On
  # Разрешить доступ к .well-known
  RewriteRule ^\.well-known/ - [L]
  # Запретить доступ к скрытым файлам и каталогам (начинаются с точки)
  RewriteRule (^|/)\.[^/]+ - [F]
</IfModule>

# 6) Специально блокируем .git (каталог и любые обращения внутрь)
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule (^|/)\.git - [F]
</IfModule>

Пояснения:

  • Options -Indexes — при запросе каталога без index.php|html сервер не отдаст список файлов.
  • Options -MultiViews — отключаем «умную» подстановку по части имени файла, чтобы исключить неожиданные совпадения и утечки.
  • <FilesMatch> удобен для точечного запрета файлов по имени/паттерну.
  • mod_rewrite пригодится для блокировки каталогов типа .git, на которые <FilesMatch> не всегда сработает.
  • Исключение .well-known нужно для ACME и других политик. Если вы выпускаете сертификаты, держите его открытым. Для выпуска можно использовать наши SSL-сертификаты.

Запрещаем выполнение PHP/CGI в uploads

Самая уязвимая точка — каталог загрузок. Название может отличаться: uploads (WordPress), storage, userfiles, assets и т.д. Принцип: внутри этого каталога вообще не должны исполняться сценарии. Даже если злоумышленник загрузил image.php, доступ к нему должен дать 403.

Создайте отдельный .htaccess в каталоге uploads (или аналогичном) со следующим содержимым:

# Отключаем индексирование и выполнение CGI
Options -Indexes
Options -ExecCGI

# Снимаем обработчики с расширений, чтобы ничего не исполнялось
RemoveHandler .php .phtml .php3 .php4 .php5 .php7 .php8 .phar .pl .py .cgi

# Универсальный запрет на доступ к любым «php-подобным» файлам
<FilesMatch "\.(php|php[0-9]|phtml|phpt|phar)$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# На случай двоичного исполнения через CGI или другие обработчики
<FilesMatch "\.(pl|py|cgi|asp|aspx|jsp)$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# Часто злоумышленники прячут код в .php.xxx или image.jpg.php
<IfModule mod_rewrite.c>
  RewriteEngine On
  # Если внутри имени встречается .php где угодно — запрещаем
  RewriteCond %{REQUEST_URI} \.php [NC]
  RewriteRule . - [F]
</IfModule>

Проверка на «двойные расширения» и маскировку

Вредонос может называться avatar.jpg.php или f0o.phar.jpg. Проверка по окончанию строки не всегда спасает, поэтому добавили правило на любую подстроку .php в запросе. Если ваш движок генерирует легитимные ссылки с таким шаблоном (редко), сузьте правило под свои реалии, но лучше разберитесь, почему так происходит. Кстати, директивы php_flag и php_value из .htaccess не работают с PHP‑FPM — пользуйтесь настройкой PHP через user.ini.

Совместимость с Apache 2.4 и 2.2

Современные площадки используют Apache 2.4 и директиву Require. На старых конфигурациях в ходу Deny/Allow. Мы применяем условные блоки:

<IfModule mod_authz_core.c>
  Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
  Order allow,deny
  Deny from all
</IfModule>

Такой шаблон годится для <Files>/<FilesMatch> и не зависит от того, как обрабатывается PHP (mod_php, FPM через proxy_fcgi и т.п.).

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Где размещать фрагменты и как не сломать движок

  • Базовые правила (защита .env/.git, Options -Indexes, блок бэкапов) — в корневом .htaccess сайта и раньше любых «магистральных» правил CMS.
  • Правила для uploads — отдельный .htaccess внутри каталога загрузок. Не мешайте их с общими rewrite‑правилами движка — так проще сопровождать.
  • Если у вас WordPress, блок для uploads кладите в wp-content/uploads/.htaccess. Кэш‑плагины могут генерировать свои директивы — держите «безопасность» сверху файла.
  • Если движок сам создаёт .htaccess, наши секции размещайте вне подписанных блоков CMS, чтобы обновления не затирали защиту.

Фильтр на «скрытые» и служебные пути: тонкости

Типичная ловушка — слишком агрессивная блокировка всех путей, начинающихся с точки. Держите исключение для .well-known выше общего запрета. Если вы используете дополнительные интеграции, которые опираются на .well-known (Webfinger, security.txt, Apple/Android‑ассоциации), они продолжат работать.

Проверка конфигурации curl -I для .env, .git и uploads

Блокируем доступ к служебным каталогам проекта

Если вы развернули PHP‑фреймворк в корне веб‑директории (а не в стиле «public/»), стоит заблокировать доступ к vendor, config, storage и прочим внутренностям. Делать это нужно, понимая логику вашего приложения.

# Аккуратно запрещаем прямой доступ к vendor и другим служебным папкам
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule ^vendor/ - [F]
  RewriteRule ^(config|storage|database|resources|tests)/ - [F]
</IfModule>

Важно: некоторые приложения сами роутят запросы в эти каталоги (например, для отдачи публичных ассетов из подкаталога resources). В таких случаях не применяйте «широкие» запреты без учёта реального роутинга. Если у вас есть доступ к конфигам сервера (см. статью про vhost вместо .htaccess), лучше ограничивайте доступ на уровне vhost.

Дополнительные защитные приёмы для uploads

  • Можно отдавать потенциально опасные расширения как текст, но надёжнее возвращать 403, а не «раскрывать» содержимое.
  • Периодически чистите «подозрительные» расширения в uploads: .php, .phar, .phtml, .cgi, .pl. Лучше не допускать их появления вовсе (валидируйте расширения при загрузке).
  • Проверяйте реальный MIME, а не только расширение. Даже при правильной валидации .htaccess‑блок в uploads обязателен.

Проверка конфигурации: быстрый чеклист

После правок — проверяем заголовки ответов и коды статусов. Подставьте ваш домен и выполните:

curl -I https://example.tld/.env
curl -I https://example.tld/.git/config
curl -I https://example.tld/.htaccess
curl -I https://example.tld/wp-content/uploads/test.php
curl -I https://example.tld/wp-content/uploads/avatar.jpg.php
curl -I https://example.tld/.well-known/acme-challenge/test

Ожидаемое поведение:

  • /.env, /.git/*, /.ht*, любые *.php в uploads — 403 (или 404 при «искусственном 404»).
  • /.well-known/* — 200, если ресурс существует (не блокируем ACME и другие политики).
  • Запрос каталога без index при включённом Options -Indexes — 403.
FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Типичные ошибки и как их избежать

  • Ставить защитные блоки после «главного» rewrite CMS. На внутренних перезапросах правила могут не сработать. Держите безопасность сверху.
  • Полагаться только на php_flag engine Off. В PHP‑FPM это не работает из .htaccess. Используйте FilesMatch, RemoveHandler, Options -ExecCGI, mod_rewrite.
  • Блокировать все скрытые пути без исключений. Обязательно белый список для .well-known.
  • Оставлять uploads без отдельного .htaccess. Даже если корневой .htaccess «закрыл всё», локальные правила в каталоге загрузок — последний рубеж.
  • Забывать про «двойные расширения». Проверяйте не только окончание имени, но и наличие подстроки .php в любом месте пути.

Минимальный «комбо»-пример для быстрого старта

Если хотите быстро закрыть основные риски в корне сайта, используйте этот компактный блок. Он объединяет ключевые приёмы: deny для .env/.git, защита .ht*, выключение индексации, запрет на скрытые пути с исключением для .well-known.

Options -Indexes
Options -MultiViews

# Служебные .ht*
<FilesMatch "^\.ht">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# .env и артефакты сборки/бэкапы
<FilesMatch "^(\.env(\..*)?|composer\.(json|lock)|package(-lock)?\.json|.*\.(bak|old|swp|swo|tmp|sql|sqlite|zip|tar|gz))$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>

# Разрешаем .well-known, остальное «скрытое» запрещаем
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule ^\.well-known/ - [L]
  RewriteRule (^|/)\.[^/]+ - [F]
  RewriteRule (^|/)\.git - [F]
</IfModule>

И не забудьте отдельный .htaccess внутри каталога uploads с запретом выполнения, как показано выше.

Нюансы производительности

.htaccess обрабатывается на каждый запрос, но безопасность важнее. Если у вас высокая нагрузка, оптимизируйте порядок правил: сначала разрешения (например, для .well-known), затем самые «часто совпадающие» запреты, и в конце — крупные регулярки. Для обычного сайта накладные расходы микроскопические по сравнению с риском утечки .env.

Контроль качества: чек‑лист админа

  • .env/.git/.ht* недоступны извне.
  • Листинг каталогов выключен (Options -Indexes).
  • В uploads запрещено исполнение любых сценариев, включая маскировку через двойные расширения.
  • .well-known доступен.
  • Защита не мешает статическим файлам и роутингу приложения.

Итоги

.htaccess — «брандмауэр ближнего боя» на виртуальном хостинге. Он не заменяет обновления CMS и плагинов, бэкапы и мониторинг, но снимает самые болезненные риски: утечки .env, раскрытие .git и запуск шеллов из uploads. Включайте защиту слоями: deny через FilesMatch, запреты на каталоги через mod_rewrite и здравую валидацию загрузок. Если только запускаете проект — начните с базовой гигиены и при необходимости масштабируйтесь на VDS.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...