2020/08/04 Nginx-PHP-FPM-
前にNginxについて書いた気もするが、今回はPHPを動かせるようになるまでの手順。
環境
CentOS7
Nginx stable latest
PHP 7.4
CentOS8では手順が異なるはず。
dnfコマンドを使ってPHPのバージョンをmodule install であげられた?
試していないので分からない。。。
===================================================
Nginxのインストール
今回は、パッケージ管理のyumを使ってインストールしていく。
nginxはデフォルトのリポジトリでは存在していないため、新たに追加する。
sudo vi /etc/yum.repo.d/nginx.repo
ここに
code:/etc/yum.repo.d/nginx.repo
name=nginx stable repo
gpgcheck=1
enabled=1
module_hotfixes=true
name=nginx mainline repo
gpgcheck=1
enabled=0
module_hotfixes=true
このように保存。
今回はstableを利用するため、追加のコマンドはいりません。
一応yumのアップデートをしておく。
sudo yum update
sudo yum clean all
Nginxのインストール
sudo yum install -y nginx
これでインストール完了。
次にポートの開放とNginxを起動する。
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload
※--permanentを忘れずに。永久に設定する場合に必須のオプションとなる。
設定を忘れると、再起動時に消えてしまう。permanentオプション時はリロードも忘れずに。
余談
firewalldは内部的にはiptablesを利用しているらしい。
Cent7ではFirewalldがデフォルト。
空いているポートを表示。
sudo firewall-cmd --list-all
firewalldにはゾーンという概念がある。
これらのゾーンをNICに適用することで一元管理できる。
Nginxの起動
sudo systemctl start nginx
sudo systemctl enable nginx
ここまででNginxのインストールは完了。
Nginxのコンフィグを設定していく。
とりあえず、Nginxを落とす。
sudo systemctl stop nginx
次に設定ファイルを確認する。
デフォルトでは、「/etc/nginx/」に設定ファイルがある
まずはnginx.confの設定から。
code:/etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user $time_local "$request" ' '$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
デフォルトの設定ではこの様になっている。
一つ一つ確認する。
user nginx;
これはnginxを実行させるユーザー
workerプロセスはこのユーザーの実行権限で動作する。
worker_process;
nginxのworkerプロセスの数
CPUのコアの数以下に設定する。
worker_connections 1024;
これは1workerプロセスあたりのファイルディスクリプタの上限。
ファイルディスクリプタとは、OSでファイルを識別するための仕組みであり、
これにはOSによって上限がある。
上限の確認コマンド
cat /proc/sys/fs/file-max
これを超えないよう余裕を持った設計を行う。
もう一つnginxに追加で設定する。
worker_rlimit_nofile 80000;
これは上の上限コマンドで得た値をworkerプロセス数で割った値が上限になる。
余裕をもたせる。
worker_connections 1024;
改めてこの設定を変更する。
1接続で2ファイルディスクリプタを消費
・エフェメラルポート用のソケット
・コンテンツファイル
以上のことからworker_rlimit_nofileを超えることのないよう、2で割った値が必要になる。
実際は余裕を持たせるため、worker_rlimit_nofileから3~4で割った値に設定する。
httpコンテキスト
HTTPのモジュールで設定する部分
server_tokens off;
これはNginxのバージョンを隠すことができる。
セキュリティ上相手に情報を与えないのも一つの対策。
これはHTTPヘッダのセキュリティ設定。
iframeを禁止。
ブラウザが勝手にMIMEタイプを勝手に指定外のものに上書きしないようにする。
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options nosniff;
これはHTTPコンテキスト、Serverコンテキスト、location等好きなとこに設定する。
バーチャルドメイン
相手のアクセスしてきたドメインに合わせて返すコンテンツを変えるにはバーチャルドメインを利用する。
httpコンテキストのなかに、「/etc/nginx/conf.d/*.conf」を読み込む設定がある。
ここに細かくWebサイトごとの設定を入れる。
例
hoge.example.jp
hoge2.example.jp
http {
server{
server_name hoge.example.jp;
~設定~
}
server{
server_name hoge2.example.jp;
~設定~
}
}
serverコンテキスト
待ち受けるポートを指定
listen 80
バーチャルドメイン
server_name
ログを好きなところに出力する
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
ルートディレクトリ
root /usr/share/nginx/html;
ユーザがアクセスしてきたURIごとの設定
location / {
~設定~
}
locationは上位で指定したrootにくっつく形。
/usr/share/nginx/html + / → /usr/share/nginx/html/
Basic認証
Apacheにはmd5で暗号化したダイジェスト認証があるが、Nginxにはないらしい。
また、nginxは.htaccessが利用できないため、confに直接書く
HTTPSで通信すれば問題ないという意味なのだろうか?
設定方法
auth_basic "Basic Auth";
auth_basic_user_file ディレクトリ/.htpasswd;
.htpasswdの作成コマンド
htpasswd -c ./.htpasswd <username>
pass: <password>
PHPのインストール
PHPのバージョンは7.4をインストールする。
CentOS7ではでyumでインストールすると5系がインストールされる。
7系をインストールするにはレポジトリを追加して、指定してあげる必要がある。
EPELリポジトリの追加
yum install epel-release
次にPHPの最新バージョンを配布するREMIリポジトリの追加
REMIの公式のページから対応OS用のリポジトリを追加
JPのミラーでは理研のFTPサーバが選択できる。
リポジトリが追加できたら一度update
yum update
yum clean all
PHPのインストール
リポジトリがデフォルトで自動選択にはなっていないので手動で選ぶ
yum install --enablerepo=epel,remi,remi-php74 php php-mbstring php-pdo php-mysqlnd
上のはあくまで一例だが、拡張モジュールは仕様に合わせて選択する。
データベースを利用する人はmysqlndやマルチバイト文字はmbstringなどなど
バージョンの確認
php -v
php.ini
PHPの設定
PHPバージョンを隠す
expose_php = off
これも攻撃者に情報を与えないようにセキュリティの向上
タイムゾーン
date.timezone = "Asia/Tokyo"
セッション名
sessioon.name = PHPSESSID
デフォルト
セッションの自動開始
session.auto_start = 1
無効は0, デフォルトは0
phpのコードでsession_start();がいらなくなる。
文字コード関連の設定
default_charset = UTF-8
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.encoding_translation = Off
mbstring.http_input = pass
mbstring.http_output = pass
mbstring.detect_order = auto
メモリ
memory_limit = 64MB
これはPHP1プロセスの最大メモリ
upload_max_filesizeよりも大きく。
ファイルアップロード
upload_max_filesize 5MB
一度に送信できるファイル数
max_file_uploads = 20
POST最大
post_max_size 20MB
このあたりをチューニングする。
phpinfo();
から確認可能。
PHP-FPMのインストール
Apacheの場合はPHPをインストールするだけでモジュールを読み込むが、
Nginxの場合は、PHP-FPMを利用する。
PHP-FPMはFastCGIの一つ。
CGIとは
CGIとはこのようにプログラムを動かすための仕組み。
CGIはWebサーバからリクエストされるとプロセスを作成して実行し、破棄する。
https://gyazo.com/abf027e7e6a2209143dc602ff74f96af
FastCGIとは
CGIでは実行のたびにプロセス生成と破棄を繰り返す。
これは無駄であるため、プロセスを再利用できるようにして、効率を上げたのがFastCGI
NginxとPHP-FPMの通信方法には、TCPもしくはUNIX Socketを利用する。
ソケットのほうが動作が高速。
https://gyazo.com/ef852366fc74c45f20f48a972e50e2dc
ApacheではCGIを利用していない。
CGIではなく、モジュールを利用している。
サーバにモジュールを追加し、Apacheのプロセスに常駐させる。
https://gyazo.com/9574c0eda69a7e196773916b57464038
PHPではFastCGIであるPHP-FPMを利用する。
PHP-FPMのインストール
yum install --enablerepo=epel,remi,remi-php74 php-fpm
php-fpmの実行
systemctl start php-fpm
systemctl enable php-fpm
www.confの設定
PHP-FPMの実行ユーザとグループを設定
code:/etc/php-fpm.d/www.conf
user = nginx
group = nginx
チューニング
子プロセスの数を動的、静的に指定。
PHPのプログラムであるmemory_limitの値、搭載メモリから
pm.max_childrenを決める。
NginxとPHP-FPMの通信
今回はソケットではなく、TCPを利用する。
/etc/nginx/conf.d/hoge.confについて、
code:/etc/nginx/conf.d/hoge.conf
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
このように.phpだった場合どこに処理を投げるのかを指定する。
fastcgi_paramをデフォルトから変更することを忘れずに。
=========================================================
チューニングは正しく行えば無駄なく処理できる。
しっかりやらないといけないけどなかなか手が出せない(^o^)