Amazon Linux 2 のセキュリティアップデート後に Nginx が動かなくなった件と amazon-linux-extras disable のメモ

# 概要

[Amazon Linux 2 Security Advisories](https://alas.aws.amazon.com/alas2.html) に記載された、Date Updated: 2022-12-06 の更新に関して

1. 複数台の EC2 インスタンスで `sudo yum -y update --security` を実行
2. `needs-restarting -r` で再起動が必要と確認できたので、再起動
3. なぜか 1台だけ Nginx が起動不能

\# まだサーバーレスじゃないの？というお叱りを覚悟でメモを残す

# 応急処置

Nginx 起動時のエラーメッセージ

:::note alert
nginx: [emerg] module "/usr/lib64/nginx/modules/ngx_http_geoip_module.so" version 1020000 instead of 1022000 in /usr/share/nginx/modules/mod-http-geoip.conf:1
:::

以下の記事に書かれているとおりに、`sudo yum -y remove nginx-mod-http-geoip` で不正なバージョンのモジュールを削除してから Nginx を再起動し、応急処置に成功

- 参考: [AL2 Nginxをアップデートするとエラーを吐いて起動しない - でんとタッチ](https://b.ictes.jp/uncategorized/103/)

# 調査

## インストール済み Nginx パッケージ

問題のインスタンスで `yum list installed nginx*` を実行した結果は以下のとおり

```:問題のインスタンス
yum list installed nginx*

nginx.x86_64                       1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
nginx-all-modules.noarch           1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
nginx-core.x86_64                  1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
nginx-filesystem.noarch            1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
nginx-mod-http-geoip.x86_64        1:1.20.0-2.amzn2.0.4  @amzn2extra-nginx1 # <- これ！
nginx-mod-http-image-filter.x86_64 1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
nginx-mod-http-perl.x86_64         1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
nginx-mod-http-xslt-filter.x86_64  1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
nginx-mod-mail.x86_64              1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
nginx-mod-stream.x86_64            1:1.22.0-1.amzn2.0.1  @amzn2extra-nginx1
```

`nginx-mod-http-geoip` だけバージョンが `1.20.0` で、他の `1.22.0` と合わないバージョンに更新されてしまったらしい（エラーメッセージの `version 1020000 instead of 1022000` の部分）

幸い GeoIP を使っていなかったので、問題のパッケージを削除することで Nginx を起動することができた

他のインスタンスでなぜ問題が発生しないのかを確認すると、どれも Nginx のバージョンが `1.12.x` だった

```:正常なインスタンス
yum list installed nginx*

nginx.x86_64                       1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
nginx-all-modules.noarch           1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
nginx-filesystem.noarch            1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
nginx-mod-http-geoip.x86_64        1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
nginx-mod-http-image-filter.x86_64 1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
nginx-mod-http-perl.x86_64         1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
nginx-mod-http-xslt-filter.x86_64  1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
nginx-mod-mail.x86_64              1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
nginx-mod-stream.x86_64            1:1.12.2-2.amzn2.0.2      @amzn2extra-nginx1.12
```

## インストール済み Yum リポジトリ

リポジトリリストを見ると、なぜか問題のインスタンスだけ `amzn2extra-nginx1/2/x86_64` がインストールされていたために、Nginx が 1.2x に更新されてしまったらしい

```:問題のインスタンス
yum repolist amzn2extra-nginx*

リポジトリー ID                 リポジトリー名                      状態
amzn2extra-nginx1/2/x86_64    Amazon Extras repo for nginx1     82 # <- これ！
amzn2extra-nginx1.12/2/x86_64 Amazon Extras repo for nginx1.12  36

```

```:正常なインスタンス
yum repolist amzn2extra-nginx*

リポジトリー ID                 リポジトリー名                      状態
amzn2extra-nginx1.12/2/x86_64 Amazon Extras repo for nginx1.12  36
```

全インスタンスの構築・運用に同じ Ansible Playbook を使っているはずなのに、なぜ 1 台だけリポジトリが増えてしまったかは不明 (？)

```yaml:playbook.yml
- name: Enable amazon2 extra yum repository for nginx
  ansible.builtin.command: amazon-linux-extras enable nginx1.12
  changed_when: false

- name: Install Nginx
  ansible.builtin.yum:
    name:
      - nginx
    state: present
```

# 暫定処置

## リポジトリ（トピック）の削除

リポジトリ `amzn2extra-nginx1/2/x86_64` が残ったままでは今後もセキュリティ更新で同様の事故が起きる可能性があるので、暫定処置として問題のリポジトリを削除する

amazon-linux-extras コマンドでインストールしたリポジトリ（トピック）なので、削除にも同コマンドを使用することで不整合の発生を防ぐ

[Amazon Linux - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/amazon-linux-ami-basics.html#extras-library) などを見る限り、`sudo amazon-linux-extras disable` にトピックの ID を指定すれば削除できるらしい

`yum repolist` で表示された「リポジトリー ID」を使って以下を実行しても削除できない（エラーも表示されない）

```shell:失敗
sudo amazon-linux-extras disable amzn2extra-nginx1/2/x86_64
```

`amazon-linux-extras` コマンドで表示されるリスト内のトピック名 `nginx1` を指定して削除する

```shell:成功
sudo amazon-linux-extras disable nginx1
```

# 恒久処置

トピック `nginx1.12` はすでにサポートが終了しているので、今後は `nginx1` を使用する必要がある

古いトピックとパッケージの削除、新しいトピック `nginx1` と Nginx 1.22 のインストールを Ansible Playbook で実行する

```yaml:playbook.yml
# Nginx 1.12 をアンインストール
- name: Uninstall old nginx
  ansible.builtin.shell: if nginx -v 2>&1 | grep '1\.12'; then yum -y remove nginx*; fi
  changed_when: false

# 古いトピック nginx1.12 を amazon-linux-extras コマンドで無効化
- name: Disable old nginx repository with amazon-linux-extras command
  ansible.builtin.command: amazon-linux-extras disable nginx1.12
  changed_when: false

# 新しいトピック nginx1 を amazon-linux-extras コマンドで有効化
- name: Enable nginx repository with amazon-linux-extras command
  ansible.builtin.command: amazon-linux-extras enable nginx1
  changed_when: false

# Nginx 1.22 を yum でインストール
- name: Install nginx
  ansible.builtin.yum:
    name:
      - nginx-1.22.0
    state: present
    update_cache: yes

# Nginx サービスの開始と自動起動設定
- name: Enable and start nginx service
  ansible.builtin.service:
    name: nginx
    enabled: yes
    state: started
```

古い 9 つのパッケージが削除され、以下の 5 つのパッケージがインストールされた

```
===============================================================================
 Package            アーキテクチャー      バージョン             リポジトリー
===============================================================================
インストール中:
 nginx              x86_64             1:1.22.0-1.amzn2.0.2   amzn2extra-nginx1
依存性関連でのインストールをします:
 nginx-core         x86_64             1:1.22.0-1.amzn2.0.2   amzn2extra-nginx1
 nginx-filesystem   noarch             1:1.22.0-1.amzn2.0.2   amzn2extra-nginx1
 openssl11-libs     x86_64             1:1.1.1g-12.amzn2.0.9  amzn2-core
 openssl11-pkcs11   x86_64             0.4.10-6.amzn2.0.1     amzn2-core
```

# 参考リンク

- [AL2 Nginxをアップデートするとエラーを吐いて起動しない - でんとタッチ](https://b.ictes.jp/uncategorized/103/)
- [Amazon Linux - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/amazon-linux-ami-basics.html#extras-library)