HOME | 2026-10-22 (Thu) Today's Access : 213 Total : 1402852. Since 10 Sep. 2019

ラズパイで作る自宅WEBサーバ:nginx編
第4回 PHPインストール
2026.10.21

---------------------------------------------------------------------------------------------
CVE-2026-109618/109619 重大なリモートコード実行の脆弱性対応
PHP 8.5.12、8.4.27、8.3.36、および8.2.35では、認証なしでリモートコード実行を可能にする2つの重大な脆弱性が修正されています。 PHPユーザーは直ちにアップデートすることを強くお勧めします。
例) ubuntuサーバ:php8.3.6 → 8.3.36
$ sudo apt update
$ sudo apt install -y software-properties-common
$ sudo add-apt-repository -y ppa:ondrej/php
$ sudo apt update
$ sudo apt-get -y install php8.3 php8.3-cgi .... ← 必要なモジュールを列記してください

今回の問題は、Apache系WEBサーバで利用されるmod_phpに関連しており、本シリーズで取り上げている nginx では、 mod_php は使用していません。
---------------------------------------------------------------------------------------------

今回は、自宅WEBサーバに、PHPをインストールします。

利用できるパッケージのバージョンを確認します
$ apt-cache show php
Package: php
Architecture: all
Version: 2:8.3+93ubuntu2

インストール可能なコンポーネントを検索します
$ apt-cache search php | grep php8.3 | more

適時必要なPHPモジュールをインストールします
$ sudo apt-get -y install php8.3 php8.3-cgi php8.3-cli php8.3-common php8.3-curl php8.3-gd php8.3-ldap php8.3-mysql php8.3-mbstring php8.3-imap php8.3-xml

インストール済みの拡張モジュールを確認します
$ php -m

●PHP-FPMのインストール
NginxのようなWebサーバーは単独ではPHPコードを実行できません。 そこでPHP-FPM(FastCGI Process Manager)がWebサーバーと連携し、FastCGIというプロトコルを介してPHPスクリプトの実行を橋渡しします。

PHP-FPMの主な役割と仕組み
- プロセス管理(プーリング): あらかじめ待機状態のPHPプロセス(ワーカー)を複数プール(待機)させておきます。 リクエストが来るとこの待機中のプロセスに割り当てるため、プロセスの起動・終了にかかるオーバーヘッドを削減し、高負荷時でもサーバーの負荷を低く抑えます。
- リソース最適化: アクセス数に応じて動的・静的にプロセス数を調整できるため、メモリやCPUを効率的に利用できます。

$ sudo apt install php8.3-fpm

PHP-FPMサービスの確認
$ sudo systemctl --type=service | grep -i fpm
php8.3-fpm.service   loaded active running The PHP 8.3 FastCGI Process Manager

$ sudo systemctl status php8.3-fpm
〇 php8.3-fpm.service - The PHP 8.3 FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php8.3-fpm.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-07-31 06:19:36 JST; 2min 13s ago

●PHP-FPM設定ファイルの編集
PHP-FPMプロセスを実行できるユーザおよびグループが Nginx のシステムユーザ(www-data)になっているか確認します
$ sudo vi /etc/php/8.3/fpm/pool.d/www.conf
[www]                              # プールの名前
user = www-data                    # プールを実行するユーザー名
group = www-data                   # プールを実行するグループ名
listen = /run/php/php8.3-fpm.sock  # リッスンソケットのパス
listen.owner = www-data            # ソケットファイルの所有者
listen.group = www-data            # ソケットファイルのグループ
pm = dynamic                       # 動的にプロセス数を調整
pm.max_children = 5                # 最大ワーカープロセス数
pm.start_servers = 2               # 起動時のワーカープロセス数
pm.min_spare_servers = 1           # 最小アイドルワーカープロセス数
pm.max_spare_servers = 3           # 最大アイドルワーカープロセス数
;request_terminate_timeout = 0     # 単一リクエスト処理のタイムアウト(初期値:無効)
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/php8.3-fpm.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M

取り合えず初期設定のまま使用します。設定を変更した場合
$ sudo systemctl restart php8.3-fpm

nginx 設定ファイルに、serverセクションを追加し、locationディレクティブを編集します。
$ sudo vi /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
}

http {
    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    access_log /var/log/nginx/access.log;

    gzip on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    # サーバー情報の隠匿設定
    more_clear_headers 'Server';
    more_clear_headers 'X-Powered-By';
    more_set_headers 'Server: Apache/2.4.1';

    server {
        listen 80;
        server_name example.com;
        root    /example/www;

        location ~ \.php$ {
            try_files $uri = 404;
            fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
            client_max_body_size 50M;
            client_body_buffer_size 128k;
        }

        location = /custom_404.html {
            internal; # 外部からの直接アクセス拒否
        }
        location = /custom_50x.html {
            internal;
        }
    }
}
リクエストボディの最大サイズ設定
client_max_body_size 50M;
client_body_buffer_size 128k;
client_max_body_sizeはアップロードなどのリクエストボディの最大サイズを定義し(デフォルト1MB),これを超えると413エラーになります。 client_body_buffer_sizeはメモリ上で処理するバッファサイズ(デフォルト16k〜64k)です。これを超えたデータは一時ファイルに書き込まれます。

$ sudo nginx -t
$ sudo systemctl restart nginx

動作確認のために、PHPの環境変数を表示するスクリプトを作成します
$ vi /example/www/index.php
<?php phpinfo(); ?>

ブラウザから
http://example.com/index.php

PHP-FPM経由で参照される設定ファイルは /etc/php/8.3/fpm/php.ini であることがわかります

●存在しないファイルにアクセスした際のプロキシ抑止
try_files $uri = 404;
try_files ディレクティブは、存在しないファイルへのリクエストがプロキシされないように指定しています。

ブラウザから存在しないURLにアクセスします。
http://example.com/test.php

nginxに用意されているエラーページでは、WEBサーバとそのバージョンが表示されてしまいます。

nginx 設定ファイルでサーバーを偽装しているので、ヘッダー情報では隠蔽されています。
$ curl -I http://example.com/test.php
HTTP/1.1 404 Not Found
Date: Sat, 19 Sep 2026 07:04:13 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Server: Apache/2.4.1

カスタムエラーページへのリダイレクトを設定します。

$ sudo vi /etc/nginx/nginx.conf
http {
    .....................

    # エラー発生時にリダイレクトさせるHTMLのパス
    error_page 404 /custom_404.html;
    error_page 500 502 503 504 /custom_50x.html;

    server {
カスタムエラーページを作成します。

$ sudo vi /example/www/custom_404.html
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
</body>
</html>

再度、アクセスしてみます。
http://example.com/test.php


サーバ内部エラー用にもファイルを作成します。
$ sudo vi /example/www/custom_50x.html
<html>
<head><title>500/501/503/504</title></head>
<body>
<center><h1>Internal Server Error</h1></center>
</body>
</html>

補足:サーバ・エラーの種類
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout

●めちゃくちゃなURIでアクセスされた場合の別対処
エラーを通知する代わりに、存在しないファイルへのアクセス要求をすべてトップページの index.php へ飛ばす例です。
    server {
        ......................................
        location / {
            # 全てのリクエストを /index.php に集約
            try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
            try_files $uri $uri/ /index.php;
            include        fastcgi_params;
            fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            client_max_body_size 50M;
            client_body_buffer_size 128k;
        }
優先順位として正規表現が優先され、存在しないPHPファイルが指定されたときは、index.php に置き換えられます。 htmlファイルなどが指定されると、前方一致により、index.phpに置き換えられます。

デフォルトのフォールバックは、画像専用の location(例: location ~* \.(jpg|png)$)を書かなくても、標準の location / や全体設定が静的ファイルをそのまま処理します。

$is_argsと$argsは、URLのクエリ文字列(GETパラメータ)を転送先やリダイレクト先に引き継ぐために組み合わせて使用する変数です。
$is_argsはクエリがある場合に「?」になり、ない場合は空文字になります。
$argsには実際のパラメータの中身が入ります。

●リクエストURIの書換え

rewriteは、Webサーバーへのアクセス時に、リクエストされたURLを指定した正規表現に基づいて別のURLに動的に書き換える機能です。

ここでは、一例としてブラウザに
http://example.com/123
と打ち込むと、nginx サーバ側で下記のように書き換えてみます。
http://example.com/members/index.php?id=123&sid=abcde

rewriteディレクティブで、正規表現を使ってリクエストURLを別のURLに書き換ます。
$ sudo vi /etc/nginx/nginx.conf
server {
    listen 80;
    server_name example.com;
    root    /example/www;

    location ~ /([0-9)]+) {
        rewrite ^/([0-9)]+)$ /members/index.php?id=$1&sid=abcde;
    }

    location ~ \.php$ {
        try_files $uri = 404;
        fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        client_max_body_size 50M;
        client_body_buffer_size 128k;
    }
}

受け側のPHPファイルを作成します。

$ mkdir -p /example/www/members
$ vi /example/www/members/index.php
<?php
    echo "Welcome to Member's Page<br />\n";
    echo 'SERVER_NAME = '.$_SERVER['SERVER_NAME']."<br />\n";
    echo 'SERVER_ADDR = '.$_SERVER['SERVER_ADDR']."<br />\n";
    echo 'REMOTE_ADDR = '.$_SERVER['REMOTE_ADDR']."<br />\n";
    echo 'REQUEST:id  = '.$_REQUEST['id']."<br />\n";
    echo 'REQUEST:sid = '.$_REQUEST['sid']."<br />\n";
?>
ブラウザからアクセスします
http://example.com/123


locationディレクティブの優先順位
前方一致より正規表現が優先されます
同じ優先順位の場合、上から順に評価し、マッチしたものが使われます
^~修飾子にマッチした場合は、それ以降のlocationディレクティブは評価されません
修飾子説明(上から優先度が高い)
=完全一致
~正規表現(大文字小文字を区別)
~*正規表現(大文字小文字を区別しない)
なし前方一致
^~前方一致

●設定ファイル php.ini の編集

設定ファイル php.ini は動作環境によって参照されるファイルが異なります。
コマンドラインで参照される php.ini は下記の通りです。

$ php --ini | grep php.ini
Configuration File (php.ini) Path: /etc/php/8.3/cli
Loaded Configuration File: /etc/php/8.3/cli/php.ini

$ sudo vi /etc/php/8.3/fpm/php.ini
default_charset = "UTF-8"              ← デフォルト文字コード
mbstring.language = Japanese           ← デフォルトの言語
date.timezone = Asia/Tokyo             ← タイムゾーンの設定
expose_php = Off                       ← HTTPレスポンスによるPHPバージョン非表示

;mbstring.internal_encoding =          ← PHP5.6以降で非推奨
;mbstring.http_input =                 ← PHP5.6以降で非推奨
;mbstring.http_output =                ← PHP5.6以降で非推奨

log_errors = On                        ← エラーログをファイルに残す
error_log = /var/log/php_errors.log    ← エラーログの場所
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off                  ← エラー非表示
display_startup_errors = Off          ← PHP起動時エラー非表示

session.name = PHPSESSID
session.use_trans_sid = 0
session.use_cookies = 1
Debian系OSでは、拡張モジュールの設定は、php.ini では行いません。(php.ini で extension の指定は必要ありません)

●NGINX Rift(CVE-2026-42945)
NGINX Riftは、NGINXの書き換え(rewrite)モジュールに18年前から存在していた深刻なヒープバッファオーバーフローの脆弱性です。

影響を受けるバージョン:
 NGINX Open Source: 0.6.27 から 1.30.0 まで

発生条件:
1.疑問符(?)を含む置換文字列を使用する rewrite ディレクティブがある。
2.その後に、$1や$2といった名前のない正規表現キャプチャ(未命名キャプチャ)を使用する rewrite、if、または set ディレクティブが同じスコープ内で続く。

◎NGINX Rift(CVE-2026-42945)の脆弱性に該当しない例
location ~ /([0-9)]+) {
    rewrite ^/([0-9)]+)$ /example.com/index.php?id=$1;  # この1行で完結していれば安全
}
NGINX Riftの脆弱性は、「疑問符(?)を含む置換」が行われた後に、同じスコープ内で「別の名前のない正規表現キャプチャ($1など)」が処理されることで、 内部のバッファ計算にズレが生じて発生します。 この例では、1つの rewrite ディレクティブの中で正規表現のキャプチャ($1)とクエリパラメータ(?)の付与を完結させています。 この処理の後に、さらに未命名のキャプチャを呼び出すような別の rewrite、set、if ディレクティブが続いていないため、 脆弱性のトリガーは引き起こされません。

×具体的に危険な記述
本脆弱性のトリガーは、「①疑問符(?)を含む置換」が行われた後に、同じスコープ内で「②名前のないキャプチャ($1、$2など)をさらに処理する」 という組み合わせです。
location ~ ^/api/(.*)$ {
    # ① 疑問符(?)を含む置換を行う
    rewrite ^/api/(.*)$ /internal?migrated=true;
    
    # ② 直後に、同じスコープ内で名前のないキャプチャ($1)を set に渡している
    set $original_endpoint $1; 
}
rewrite で ? を含む処理をしたことでNGINX内部の状態フラグが変化し、その状態のまま直後の set で $1 を処理しようとすると、 メモリのサイズ計算が狂ってヒープオーバーフローが発生します。

◎安全なコード(回避策)
location ~ ^/api/(?.*)$ {  # (?...) で名付けを行う
    rewrite ^/api/.*$ /internal?migrated=true;
    set $original_endpoint $endpoint; # 名前付き変数に変えたため安全
}
【参考文献】
・入門 - Nginx + PHP-FPM の仕組み

Raspberry Piはイギリスのラズベリーパイ財団により開発されたシングルボードコンピュータです。
2026.08.27 番外編 DNSトランスファー
2026.09.06 第0回 nginx を始めよう
2026.09.14 第1回 Ubuntu Server 設定
2026.09.24 第2回 DNS設定
2026.10.08 第3回 Nginxインストール
2026.10.21 第4回 PHPインストール

KEYESTUDIO Micro:bit V2ロボットスターターキット (マイクロビットなし) MakecodeとPython用
動き、光と音の使い方、障害物の検知と回避方法、線をたどり、IRリモコンとアプリでコントロールする方法を学びます。

Maqueen Lite V5 micro:bit ロボットキット STEM用(ライントレース&障害物回避)
Maqueen Lite V5 STEMロボットは、事前調整済みのライントレースアルゴリズム、耐衝撃モーター、開封即使用可能な設計で、ストレスを解消します。

たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」 「一念発起して何かを始めても、いつも三日坊主で終わってしまう」 「色んなことを先延ばしにしたまま、時間だけが過ぎていく」 そこで本書では、そんな著者が独自に開発した、 まったく新しい目標達成メソッド「100日デザイン」について、 その知識と技術を、余すところなくご紹介します。

まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。 ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。

今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。

ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。 29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!

【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。 基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。

Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説! 500以上のサンプルを掲載。実行結果も確認。 全24章の包括的なチュートリアル。

ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS… 全WEB媒体で効果バツグン! カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術

小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。

Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード

電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)

Copyright © 2011-2027 Sarako Tsukiyono All rights reserved®.