У меня есть сервер Apache, внутри которого будет работать несколько субдоменов, например:
www.example.com
api.example.com
панель инструментов.example.com
клиент.example.com
Я установил Apache 2.4.41 и PHP-FPM 7.4 на Ubuntu 20.04, выполнив следующие команды:
sudo apt установить apache2
sudo apt установить php libapache2-mod-php
судо a2dismod php7.4
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo apt установить php-fpm
sudo apt установить libapache2-mod-fcgid
sudo a2enconf php7.4-fpm
sudo a2enmod прокси
sudo a2enmod proxy_fcgi
Я только что сделал это, ничего более, PHP-FPM работает нормально в соответствии с phpinfo().
По умолчанию сайт 000 по умолчанию включен на Apache, и я могу получить к нему доступ через IP. При создании файла PHP и HTML в каталоге /var/www/html я могу получить доступ к этим файлам (PHP и HTML) в обычном режиме, например: http://EXAMPLE-IP/file.php
Но при создании поддомена и попытке доступа к любому файлу PHP возникает ошибка Не указан входной файл. всегда отображается. В журнале apache отображается следующее сообщение:
AH01071: Ошибка «Невозможно открыть основной скрипт: /var/www/html/subdomain.example.com/index.php (Нет такого файла или каталога)»
AH01071: ошибка «Невозможно открыть основной скрипт: /var/www/html/subdomain.example.com/index-2.php (нет такого файла или каталога)»
Но HTML-файлы внутри поддомена всегда отображаются корректно.
Это мой настроенный VirtualHost:
000-default.conf
<VirtualHost *:80>
ServerAdmin example@example.com
DocumentRoot /var/www/html
LogLevel notice core:info
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ErrorLog syslog:local1
Header append X-FRAME-OPTIONS "SAMEORIGIN"
</VirtualHost>
<VirtualHost *:80>
ServerName MY-PUBLIC-IP
Redirect 403 /
ErrorDocument 403 "The operation had an error."
DocumentRoot /var/www/html
</VirtualHost>
Это поддомен (один из нескольких):
субдомен.example.com
<VirtualHost *:80>
ServerAdmin example@example.com
ServerName subdomain.example.com
ServerAlias subdomain.example.com
DocumentRoot /var/www/html/subdomain.example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Header append X-FRAME-OPTIONS "SAMEORIGIN"
RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /ssl-location/my-cert.crt
SSLCertificateKeyFile /ssl-location/my-cert.key
SSLCertificateChainFile /ssl-location/my-cert-intermediary.crt
Protocols h2 http/1.1
# HSTS (mod_headers is required) (15768000 seconds = 6 months)
Header always set Strict-Transport-Security "max-age=31536000"
Header append X-FRAME-OPTIONS "SAMEORIGIN"
<Directory /var/www/subdomain.example.com>
Options None
AllowOverride None
Require all granted
</Directory>
ServerAdmin example@example.com
ServerName subdomain.example.com
ServerAlias subdomain.example.com
DocumentRoot /var/www/html/subdomain.example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Из соображений безопасности, рекомендованных документацией OWASP, я установил в php.ini значение doc_root = /var/www/html/, но если я изменю его на doc_root = /var/www/html/subdomain.example.com, файлы PHP работают на моем поддомене, и /var/www/htm файлов больше нет.
Как динамически настроить doc_root для этих поддоменов в PHP-FPM без необходимости иметь выделенный физический сервер для каждого поддомена?
Примечание. Это мой файл конфигурации Apache FPM:
conf-enabled/php7.4-fpm.conf
# Перенаправление на локальный php-fpm, если mod_php недоступен
<ЕслиМодуль !mod_php7.c>
<IfModule proxy_fcgi_module>
# Включить заголовки авторизации http
<IfModule setenvif_module>
SetEnvIfNoCase ^Авторизация$ "(.+)" HTTP_AUTHORIZATION=$1
</ЕслиМодуль>
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "прокси:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
</FilesMatch>
<FilesMatch ".+\.phps$">
# Запретить доступ к необработанным источникам php по умолчанию
# Для повторного включения рекомендуется разрешить доступ к файлам
# только в определенном виртуальном хосте или каталоге
Требовать все отказано
</FilesMatch>
# Запретить доступ к файлам без имени файла (например, '.php')
<FilesMatch "^\.ph(ar|p|ps|tml)$">
Требовать все отказано
</FilesMatch>
</ЕслиМодуль>
</ЕслиМодуль>