最近、Apache 2.4をローカルマシンにPHP 5.4.8 with PHP-FPMを使用して)インストールしました。
すべてがかなりスムーズに進みました(しばらくすると...)が、奇妙なエラーがまだあります。
次のように、ApacheをPHP-FPM用に構成しました。
_<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1
</VirtualHost>
_
これは機能します。たとえば、_http://localhost/info.php
_を呼び出すと、正しいphpinfo()
を取得します(これは単なるテストファイルです)。
ただし、ディレクトリを呼び出すと、本文_File not found.
_の404が返され、エラーログに表示されます。
_[Tue Nov 20 21:27:25.191625 2012] [proxy_fcgi:error] [pid 28997] [client ::1:57204] AH01071: Got error 'Primary script unknown\n'
_
私は今mod_rewriteでプロキシをやってみました:
_<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>
_
しかし問題は次のとおりです:_http://localhost/
_では自動的に_http://localhost/index.php
_が要求されるため、常にリダイレクトされます。
_DirectoryIndex index.php index.html
_
わかりましたので、「まずプロキシに渡すファイルがあるかどうかを確認します。
_<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>
_
これで完全な書き換えは機能しなくなりました...
今私はこの解決策を持っています:
_<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
RewriteEngine on
RewriteCond /Users/apfelbox/WebServer/%{REQUEST_FILENAME} -f
RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>
_
最初に、PHP-FPMに渡すファイルがあることを確認し(fullおよびabsoluteパスを使用)、次に書き換えを行います。
これは、サブディレクトリ内でURLの書き換えを使用している場合は機能しません。また、_http://localhost/index.php/test/
_などのURLの場合は失敗します。そのため、正方形に戻ります。
何か案は?
Apacheドキュメントを何時間も検索して読んだ後、プールを使用できるようにするソリューションを思いつきました。また、URLに.phpファイルが含まれている場合でも、.htaccessのRewriteディレクティブが機能するようにしています。
<VirtualHost ...>
...
# This is to forward all PHP to php-fpm.
<FilesMatch \.php$>
SetHandler "proxy:unix:/path/to/socket.sock|fcgi://unique-domain-name-string/"
</FilesMatch>
# Set some proxy properties (the string "unique-domain-name-string" should match
# the one set in the FilesMatch directive.
<Proxy fcgi://unique-domain-name-string>
ProxySet connectiontimeout=5 timeout=240
</Proxy>
# If the php file doesn't exist, disable the proxy handler.
# This will allow .htaccess rewrite rules to work and
# the client will see the default 404 page of Apache
RewriteCond %{REQUEST_FILENAME} \.php$
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-f
RewriteRule (.*) - [H=text/html]
</VirtualHost>
Apacheのドキュメントに従って、SetHandlerプロキシパラメータにはApache HTTP Server 2.4.10が必要です。
この解決策があなたにも役立つことを願っています。
あなたがする必要があるすべては設定することです:
ProxyErrorOverride on
また、次の方法で顧客ページを設定することを忘れないでください。
ErrorDocument 404 /path/to/error_page_file
さらに別のソリューション(Apache> = 2.4.10が必要)-vhost内:
# define worker
<Proxy "unix:/var/run/php5-fpm-wp.bbox.nuxwin.com.sock|fcgi://domain.tld" retry=0>
ProxySet connectiontimeout=5 timeout=7200
</Proxy>
<If "%{REQUEST_FILENAME} =~ /\.php$/ && -f %{REQUEST_FILENAME}">
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
SetHandler proxy:fcgi://domain.tld
</If>
したがって、ここではPHPのfcgiハンドラーは、ファイルが存在し、その名前がPHPファイル拡張子と一致する場合にのみ設定されます。
BTW:ProxyErrorOverrideをOnに設定するアイデアがある場合、これは本当に悪いアイデアであることに注意してください。このディレクティブを使用しても問題は発生します。たとえば、PHPアプリケーションがHTTPコード(503など)を送信すると、予期しない結果が発生します。デフォルトのエラーハンドラはすべてのケースに関係し、PHP APIを提供します。これは本当に悪い動作です。
これは私が持っているものです。大丈夫そうです。私はサブディレクトリにDrupalを置き、その書き換え作業、ディレクトリインデックス作業、PATH_INFO作業を行います。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$
RewriteCond %2 -f
RewriteRule . fcgi://127.0.0.1:9000/%1 [L,P]
RewriteOptions Inherit
私は書き換えなしでこのようなことをしようとしましたが( "If"など)、何も動作しませんでした。
編集:これを共有ホスティングプロバイダーとして実装する場合、セキュリティ上の問題になる可能性があることに注意してください。これにより、ユーザーはPHPスクリプトを任意のfcgiプロキシに渡すことができます。ユーザーごとに個別のプールがある場合、特権の昇格攻撃が可能になります。
これを解決する最良の方法は、mod_proxy、mod_rewrite、およびphp-fpmのデバッグログをオンにすることです。 Apache 2.4では、特定のモジュールのみのデバッグログをオンにできるようになりました。 http://httpd.Apache.org/docs/current/mod/core.html#loglevel モジュールごとおよびディレクトリごとの構成は、Apache HTTPサーバー2.3.6以降で使用できます
多分あなたはディレクトリでダブルスラッシュを取得していますか?
これが私が使っているもので、うまくいきます:
<LocationMatch ^(.*\.php)$>
ProxyPass fcgi://127.0.0.1:9000/home/DOMAINUSER/public_html$1
</LocationMatch>
この問題の処理で遭遇したことの1つは、次の組み合わせを使用する場合です。
chroot = /path/to/site
chdir = /
Fpmプール構成では、ProxyPass
ディレクティブに絶対パスを渡さないでください。
ProxyPass fcgi://127.0.0.1:9020/$1
ただし、そのポートのプールがchrootされている場合は-のみ-です。
問題が関連しているかどうかはわかりませんが、ここでは部分的に機能する解決策を見つけました:
トリックは?を追加しているようです。 .htaccess RewriteRuleのchar、たとえば次を使用:
RewriteRule ^(.*)$ index.php?/$1 [L,NS]
の代わりに:
RewriteRule ^(.*)$ index.php/$1 [L,NS]
問題の原因は、Apache 2.4.25のmod_rewriteの変更にあるようです。 Apache trace1ログレベルを使用して、index.php/$ 1が渡された後に$ 1をphp-fpmに渡す「ループ」を観察しました。 $ 1は「AH01071:Got error 'Primary script unknown\n'」エラーを生成します。
この小さな一口が誰かが彼らの問題を解決するのを助けることを願っています。
Mod_rewriteを必要としない@FrancescoAの回答のわずかに変更されたバージョン
<IfModule proxy_fcgi_module>
<FilesMatch \.php$>
<If "-f '%{REQUEST_FILENAME}'">
SetHandler "proxy:unix:/path/to/socket.sock|fcgi://unique-domain-name-string/"
</If>
</FilesMatch>
<Proxy fcgi://unique-domain-name-string>
ProxySet connectiontimeout=5 timeout=240
</Proxy>
</IfModule>
Linodeにはこのテーマに関する素晴らしいチュートリアルがあります
基本的に、phpスクリプトをキャッチしてfast-cgiに渡すサーバー全体のハンドラーをセットアップします。
私のサーバー(centos 7.3.16 docker)でも同じ問題に直面しています。 php-fpmログを追跡した後、sys libが見つからないことがわかりました。 WARNING: [pool www] child 15081 said into stderr: "php-fpm: pool www: symbol lookup error: /lib64/libnsssysinit.so: undefined symbol: PR_GetEnvSecure"
それから、nsprを再インストールし、機能します。何らかの方法を試しても解決策が見つからない場合は、これを試してみてください。 yum -y install/reinstall nspr
これはWordpress 5.1.1以降およびPHP 7.3、FastCGI、プロキシ、MariaDB/MySQLとも一緒に動作します。サーバー上で2回チェックされます。チャーム。
CentOS/Fedora/Red Hatで初めて
Sudo yum remove php*
Sudo yum --enablerepo=extras install epel-release
Sudo yum install php-fpm php-mysql php-Gd php-imap php-mbstring
Sudo grep -E '(proxy.so|fcgi)' /etc/httpd/conf.modules.d/00-proxy.conf
Sudo mv /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.conf_bak
このファイルを編集します。
Sudo nano /etc/php-fpm.d/www.conf
これを貼り付けます:
[www]
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses on a
; specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = 127.0.0.1:9000
listen = /run/php-fcgi.sock
Sudo ll /run/php-fcgi.sock
Srw-rw-rw-を与える必要があります。
または、Debian/Ubuntuでの設定方法
チュートリアル:
Sudo apt purge 'php*' or Sudo apt-get purge 'php*'
Sudo add-apt-repository ppa:ondrej/php
Sudo apt-get update
Sudo apt install php7.3 php7.3-fpm php-mysql php-mbstring php-Gd php-imap libapache2-mod-security2 modsecurity-crs
systemctl status php7.3-fpm
systemctl stop php7.3-fpm.service
Sudo a2dismod php7.0 php7.1 php7.2 mpm_event mpm_worker
Sudo a2enmod mpm_prefork
Sudo a2enmod php7.3
Sudo systemctl restart Apache2 (httpd in CentOS)
問題は、Ondrejリポジトリのphp 7.3がmpm_preforkモードでのみ機能することです。彼はgitリポジトリを持っているので、ネットで見つけて彼に尋ねることができます。mpm_workerとmpm_eventのphp 7.3を作成しますか。 Debianファミリーディストリビューションの残りの構成は以下のとおりです。
Sudo apt --assume-yes install php7.3-fpm
Sudo systemctl stop php7.3-fpm.service
Sudo rm /var/log/php7.0-fpm.log
Sudo mkdir /var/log/php7.3-fpm/
Sudo touch /var/log/php7.3-fpm/error.log
Sudo mkdir /var/log/php7.3/
Sudo touch /var/log/php7.3/error.log
Sudo mkdir /var/tmp/php7.3/
Sudo > /etc/php/7.3/fpm/php.ini
Sudo > /etc/php/7.3/fpm/php-fpm.conf
Sudo rm /etc/php/7.3/fpm/pool.d/www.conf
Sudo touch /etc/php/7.3/fpm/pool.d/example.com.conf
Sudo useradd --comment "PHP" --Shell "/usr/sbin/nologin" --system --user-group php
Sudo nano /etc/php/7.3/fpm/php.ini
ペースト
[PHP]
date.timezone = Europe/Prague
display_errors = Off
error_log = /var/log/php7.3/error.log
error_reporting = 32767
log_errors = On
register_argc_argv = Off
session.gc_probability = 0
short_open_tag = Off
upload_tmp_dir = /var/tmp/php7.3/
Sudo nano /etc/php/7.3/fpm/php-fpm.conf
ペースト
[global]
error_log = /var/log/php7.3-fpm/error.log
include = /etc/php/7.3/fpm/pool.d/*.conf
Sudo nano /etc/php/7.3/fpm/pool.d/example.com.conf
ペースト
[example.com]
group = php
listen = 127.0.0.1:9000
pm = ondemand
pm.max_children = 5
pm.max_requests = 200
pm.process_idle_timeout = 10s
user = php
Sudo nano /etc/logrotate.d/php7.3-fpm
これをtxtファイルにコピーします:
/var/log/php7.3-fpm.log {
rotate 12
weekly
missingok
notifempty
compress
delaycompress
postrotate
/usr/lib/php/php7.3-fpm-reopenlogs
endscript
}
それを削除してから、上記の代わりに貼り付けます。
/var/log/php7.3/*.log /var/log/php7.3-fpm/*.log
{
copytruncate
maxage 365
missingok
monthly
notifempty
rotate 12
}
ディレクティブを追加
Sudo nano /etc/Apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
ServerAdmin [email protected]
DocumentRoot /var/www/html/example.com/public_html
DirectoryIndex index.php index.htm index.html index.xht index.xhtml
LogLevel info warn
ErrorLog ${Apache_LOG_DIR}/error.log
CustomLog ${Apache_LOG_DIR}/access.log combined
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
<files readme.html>
order allow,deny
deny from all
</files>
RewriteEngine on
RewriteCond %{SERVER_NAME} =example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/example.com/public_html
<Directory /var/www/html/example.com/public_html>
Options Indexes FollowSymLinks Includes IncludesNOEXEC SymLinksIfOwnerMatch
AllowOverride None
</Directory>
</VirtualHost>
次に、サイトを有効にします。
Sudo a2ensite /etc/Apache2/sites-available/example.com.conf
次に、SSLサイトを編集します(この場合、Let's Encryptのcertbotは、SSL証明書構成の最初にインストールおよび構成されています)。
Sudo nano /etc/Apache2/sites-available/example.com-le-ssl.conf
<IfModule mod_ssl.c>
#headers for security man in the middle attack find how to enable this mod in Google
LoadModule headers_module modules/mod_headers.so
<VirtualHost *:443>
Header always set Strict-Transport-Security "max-age=15768000"
SSLEngine On
ServerName example.com
ServerAdmin [email protected]
DocumentRoot /var/www/html/example.com/public_html
<Directory /var/www/html/example.com/public_html>
Options Indexes FollowSymLinks Includes IncludesNOEXEC SymLinksIfOwnerMatch
AllowOverride All
Require all granted
DirectoryIndex index.php
RewriteEngine On
<FilesMatch ^/(.*\.php(/.*)?)$>
SetHandler "fcgi://example.com:9000/var/www/html/example.com/public_html"
</FilesMatch>
</Directory>
# Log file locations
#LogLevel info ssl:warn
LogLevel debug
ErrorLog ${Apache_LOG_DIR}/error.log
CustomLog ${Apache_LOG_DIR}/access.log combined
# modern configuration
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-Apache.conf
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
#SSLCipherSuite HIGH:!aNULL:!MD5
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM$
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
<files readme.html>
order allow,deny
deny from all
</files>
</VirtualHost>
#Stapling OCSP for Let's Encrypt certs.
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
</IfModule>
Sudo a2enmod proxy proxy_fcgi setenvif
Sudo systemctl reload Apache2.service
Sudo chown --recursive root:adm /etc/php/
Sudo chmod --recursive 0770 /etc/php/
Sudo chown --recursive php:adm /var/log/php7.3/
Sudo chown --recursive php:adm /var/log/php7.3-fpm/
Sudo chmod --recursive 0770 /var/log/php7.3/
Sudo chmod --recursive 0770 /var/log/php7.3-fpm/
Sudo chown --recursive php:php /var/tmp/php7.3/
Sudo chmod --recursive 0770 /var/tmp/php7.3/
Sudo a2enconf php7.3-fpm
Sudo systemctl enable php7.3-fpm.service
Sudo systemctl start php7.3-fpm.service
Debian/Ubuntuのファイアウォールにポート9000を追加することを忘れないでください
Sudo ufw allow 9000/tcp
Sudo ufw status
CentoOS/Fedora/Red Hatの場合
Sudo firewall-cmd --zone=public --add-port=9000/tcp --permanent
Sudo firewall-cmd --reload
Sudo firewall-cmd --list-all
Sudo firewall-cmd --state
drupalインスタンスに対してphp-fpm + Apache 2.4.6に切り替えた後もエラーが発生します
しかし、私はmpm event modを使用しています
挿入するだけ
DirectoryIndex index.php
は私のために働く
私の仮想ホスト設定は以下のようになります
<VirtualHost *:8080>
ServerAdmin webmaster@localhost
ServerName sever.com
DocumentRoot /var/www/html/webroot
ErrorLog logs/web-error_log
CustomLog logs/web-access_log common
<IfModule mpm_event_module>
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/webroot/$1
</IfModule>
<Directory /var/www/html/webroot>
Options FollowSymlinks
DirectoryIndex index.php
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
ありがとう
drupalのデフォルトの.htaccessファイルを修正する必要はありません