2026/10/22

PHP / OS 更新チートシート(Amazon Linux 2023 / Apache + PHP-FPM)

- 対象環境:Amazon Linux 2023、PHP は AL2023 標準パッケージ(`php8.x*`)、Web サーバは Apache(`httpd`)+ PHP-FPM
- コマンド中の `php8.4` は、使用している PHP のバージョンに読み替える

---

## 1. PHP の更新

> AL2023 の dnf コマンドには `--releasever=latest` を付ける。付けないと、OS のリリースバージョンが固定されているため新しいパッケージが見えない。

### 1-1. 現状確認

```bash
# PHP バージョン(CLI / FPM の両方)
php -v
php-fpm -v

# インストール済み PHP パッケージ
rpm -qa | grep php
```

### 1-2. 未適用の修正版・セキュリティアドバイザリの確認

```bash
# 1) キャッシュを捨てて、最新の情報を取り直す(古いキャッシュだと新しいパッケージが見えない)
sudo dnf clean metadata

# 2) インストール済みの PHP パッケージに更新があるか(何も出なければ更新なし)
sudo dnf list --upgrades 'php8.4*' --releasever=latest

# 3) PHP 関連の未適用アドバイザリ(ALAS)
sudo dnf updateinfo list --security --releasever=latest | grep -i php

# 4) 特定の CVE に対応するアドバイザリがあるか(例:CVE-2026-109618)
sudo dnf updateinfo list --releasever=latest --cve CVE-2026-109618
```

- 1):2)〜4) の出力に表示される「メタデータの期限切れの最終確認」の日時が古い場合は、1) をやり直す
- 2):`dnf list available` はインストールしていないパッケージしか表示しないので、更新の確認には `dnf list --upgrades` を使う

**AWS 側の対応状況の確認先**

php.net で修正版が出ても、AL2023 のパッケージに反映されるまでは時間差がある(通常数日)。

| 確認したいこと | 確認先 |
|---|---|
| 特定の CVE の対応状況(パッケージごと) | `https://explore.alas.aws.amazon.com/<CVE番号>.html`    例:https://explore.alas.aws.amazon.com/CVE-2026-109618.html |
| AL2023 のセキュリティアドバイザリ一覧 | https://alas.aws.amazon.com/alas2023.html |

CVE ページの「Status」の見方:

| Status | 意味 | 対応 |
|---|---|---|
| Pending Fix | 影響あり、修正版を準備中 | 回避策を入れて、修正版が出るのを待つ |
| Fixed | 修正版を公開済み(ALAS 番号と公開日が載る) | 1-3 以降で更新する |
| No Fix Planned | 修正版は出ない予定(サポート終了のバージョンなど) | サポートされているバージョンへ移行する |
| Not Affected | 影響なし | 対応不要 |

PHP 本体の情報(脆弱性の内容、修正版のバージョン、回避策):

- PHP 公式のお知らせ:https://www.php.net/
- PHP のセキュリティアドバイザリ(技術的な詳細):https://github.com/php/php-src/security/advisories

### 1-3. バックアップ

- EC2 コンソールから **AMI またはスナップショットを取得**(切り戻し用)
- 複数台ある場合は、1台で更新・動作確認してから残りに展開する

### 1-4. 更新

```bash
# インストール済みの PHP 関連パッケージをすべて最新に(一覧を確認してから y)
sudo dnf upgrade --releasever=latest 'php8.4*'
```

- インストール済みの php8.4 関連パッケージ(拡張モジュールを含む)だけが最新版に置き換わる。パッケージの追加や削除はされない

### 1-5. 設定ファイルの競合を確認

```bash
# 何も出なければ競合なし
sudo find /etc/php* /etc/php-fpm* /etc/httpd -name '*.rpmnew' 2>/dev/null
```

- `/etc/php.ini`、`/etc/php.d/*.ini`、`/etc/php-fpm.d/www.conf` などの変更は上書きされない
- `*.rpmnew` が出た場合は、既存の設定との差分を確認する

### 1-6. サービスの再起動

```bash
sudo systemctl restart php-fpm   # 必須:PHP 本体の反映
sudo apachectl configtest        # 推奨:httpd の設定に問題がないか(Syntax OK を確認)
sudo systemctl reload httpd      # 推奨:httpd 用の設定ファイルの反映(接続は切れない)
```

PHP パッケージの更新では、次の2種類のファイルが置き換わるため、それぞれ反映する。

| 置き換わるもの | 反映方法 |
|---|---|
| PHP 本体(PHP-FPM で動いている) | `php-fpm` の再起動 |
| httpd 用の設定ファイル(`/etc/httpd/conf.d/php.conf` など。`.php` へのリクエストを PHP-FPM に渡す設定) | `configtest` で確認してから、httpd の `reload` |

### 1-7. 更新後の確認

```bash
# バージョン
php -v ; php-fpm -v
rpm -qa | grep php8.4

# サービスの状態
systemctl status php-fpm --no-pager   # active (running)、起動時刻が更新後になっているか
systemctl status httpd --no-pager     # active (running) か(reload では起動時刻は変わらない)

# 未適用の PHP アドバイザリが残っていないか(何も出なければ OK)
sudo dnf updateinfo list --security --releasever=latest | grep -i php

# エラーログ
sudo tail -n 50 /var/log/php-fpm/error.log
sudo tail -n 50 /var/log/httpd/error_log
```

- ブラウザで各サイトの主な画面を確認する(ログイン、DB 参照、画像やファイルのアップロードなど、使用している拡張モジュールに関わる処理)

### 1-8. 定期確認(新しい修正が出ていないか)

```bash
sudo dnf clean metadata
sudo dnf list --upgrades 'php8.4*' --releasever=latest
sudo dnf updateinfo list --security --releasever=latest | grep -i php
```

- 更新が表示されたら、1-3〜1-7 を行う
- 修正待ちの CVE がある場合は、1-2 の CVE ページで Status が「Fixed」になったかも確認する

---

## 2. OS 全体の更新

### 2-1. リリースバージョンの固定状況の確認

AL2023 のリポジトリには日付付きのバージョン(例:`2023.10.20260120`)があり、各サーバーは**起動に使った AMI のバージョンに固定**される。

- 普通の `dnf upgrade` は、固定されたバージョンの範囲内でしか更新しない
- 新しいバージョンのパッケージを入れるには `--releasever=latest`(または特定の日付)を指定する
- 自分でバージョンを進めないと、セキュリティ修正も入らない(構築時のバージョンのまま取り残される)

```bash
# 今固定されているリリースのバージョン
rpm -q system-release

# 新しいリリースがあるか(出力にリリースノートの URL も表示される)
sudo dnf check-release-update

# 未適用のアドバイザリ件数
sudo dnf updateinfo summary --releasever=latest
```

- AL2023 のリリースノート:https://docs.aws.amazon.com/linux/al2023/release-notes/relnotes.html

### 2-2. 事前準備

**バックアップ**

- EC2 コンソールから AMI またはスナップショットを取得する
- 可能であれば、本番の AMI から検証用のインスタンスを起動して先に試す

```bash
# /etc 全体のバックアップ(更新後の比較用)
sudo tar czf /root/etc-backup-$(date +%Y%m%d).tar.gz /etc
```

**変更した設定ファイルの確認**

パッケージに含まれるファイルを、インストール時の状態と比べて、内容を変更したものを洗い出す(全パッケージを調べるため数分かかる)。

```bash
# 1) 内容を変更した「設定ファイル」(更新しても基本的に変更は残る)
sudo rpm -Va 2>/dev/null | grep '^..5' | awk '$2=="c"'

# 2) 内容を変更した「設定ファイル以外」(更新で上書きされて変更が消える → 要対応)
sudo rpm -Va 2>/dev/null | grep '^..5' | awk '$2!="c"'
```

出力の例と見方:

```
S.5....T.  c /etc/httpd/conf/httpd.conf     ← 1) に出る:設定ファイル
S.5....T.    /usr/lib/systemd/system/xxx.service   ← 2) に出る:設定ファイル以外
│ │    │   │
│ │    │   └ "c" があれば設定ファイル(なければ空欄)
│ │    └ T:更新日時が変わっている
│ └ 5:内容が変わっている(grep '^..5' でこれを含む行だけに絞っている)
└ S:サイズが変わっている
```

- 先頭の9文字は、インストール時から変わった項目を表す(変わっていない項目は `.`)
- `rpm -Va`:インストール済みの全パッケージ(`-a`)のファイルを検証(`-V`)する
- 2) に出たファイルは、更新前に変更内容を控えておくか、上書きされない場所(systemd なら `/etc/systemd/system/`)に移しておく

更新時の設定ファイルの扱い:

| 設定の種類 | 更新時の動き |
|---|---|
| 自分で新しく作ったファイル(例:`/etc/httpd/conf.d/サイト名.conf`) | 影響なし |
| パッケージ付属の設定ファイルを編集したもの | 基本的に残る。新しい標準設定は `*.rpmnew` として置かれる |
| 同上だが、パッケージ側が「上書き」指定にしているもの(少数) | 新しいものに置き換わり、元のファイルは `*.rpmsave` として退避される |
| パッケージ付属の、編集していない設定ファイル | 新しいバージョンのものに黙って置き換わる |
| 設定ファイル以外を直接編集したもの(例:`/usr/lib/systemd/system/*.service`) | 上書きされて変更が消える |
| サービスの自動起動設定、ユーザー、cron、`/var/www` のデータなど | 影響なし |

- `/usr/lib/systemd/system/` 配下などを直接編集している場合は、更新前に `sudo systemctl edit サービス名` で `/etc/systemd/system/` 側の上書き設定に移しておく

### 2-3. 更新

```bash
# OS 全体を最新リリースに更新(一覧を確認してから y)
sudo dnf upgrade --releasever=latest
#   特定のバージョンに揃えたい場合は日付を指定する
#   sudo dnf upgrade --releasever=2023.12.20261016

# 再起動が必要か確認して、必要なら再起動
sudo dnf needs-restarting -r
sudo reboot
```

- 更新の中で `system-release` パッケージも新しくなり、固定先がそのバージョンに進む

### 2-4. 更新後の確認

```bash
# 固定先が進んだか
rpm -q system-release            # 新しい日付になっていれば OK
sudo dnf check-release-update    # 新しいリリースが表示されなければ最新

# 設定ファイルの競合(.rpmnew:新しい標準設定 / .rpmsave:元の設定が退避されたもの)
sudo find /etc \( -name '*.rpmnew' -o -name '*.rpmsave' \) 2>/dev/null

# 退避された設定がある場合は差分を確認して、必要な変更を戻す
sudo diff /etc/xxx.conf.rpmsave /etc/xxx.conf

# 起動に失敗しているサービスがないか
systemctl --failed
sudo apachectl configtest
systemctl status php-fpm --no-pager
systemctl status httpd --no-pager
```

- 1-7 と同様に、エラーログとブラウザでの動作を確認する

### 2-5. 定期的な更新の運用

- 固定先を定期的に進める(`sudo dnf upgrade --releasever=latest`)。SSM Patch Manager で自動化するのもおすすめ
- `/etc/dnf/vars/releasever` に `latest` と書くと、常に最新のリポジトリを見るようになる(ただし勝手にリリースが進むので、検証環境と本番環境でバージョンを揃えたい場合は、毎回 `--releasever` を明示的に指定する運用にする)
- 新しいサーバーを構築するときは、パッケージをインストールする前に `sudo dnf upgrade --releasever=latest` で最新リリースに上げておく(AMI 作成時点のバージョンに固定されているため)

---

## おまけ:作業ログの記録

```bash
# プロンプトに日時を表示する(コマンドごとの時刻がログに残る。このログイン中だけ有効)
export PS1='[\D{%F %T}] \u@\h:\w\$ '

# 記録開始(入力したコマンドと出力をファイルに記録。-a:追記 / -f:すぐ書き込む)
script -a -f ~/worklog_$(date +%Y%m%d_%H%M).log

# 記録終了
exit
```

0 件のコメント:

コメントを投稿

人気の投稿