Amazon Linux 2023 の初期設定が Amazon Linux 2 と違いすぎて戸惑ったので、その内容と対処方法のまとめ

# はじめに

[2023/03/15 に Amazon Linux 2023 (AL2023) が一般提供された](https://aws.amazon.com/jp/about-aws/whats-new/2023/03/amazon-linux-2023/) 。 これに伴い、Amazon Linux 2 (AL2) の EOL が 2025/06 と発表されたこともあり、新しいプロジェクトで AL2023 を使い始めたが、Amazon Linux 2 のつもりで利用するとかなり初期設定や使い勝手が違い、混乱する場所が多々あった。

それらの情報はすでに別のウェブサイトで多くまとめられているが、本記事では、自身が躓いた状況、および、それらの記事を参考にしつつどのように解決したのかを記載する。

# セットアップ時に遭遇した問題

## ローンチしたインスタンスにログインできない

AL2023 のインスタンスをローンチすると、いきなりログインできない問題に遭遇した。
原因は `ssh-rsa` の接続が無効化されていることであり、解決方法は以下の通り `rsa-sha2-256/512` が利用可能な ssh クライアントで接続することであった。

https://dev.classmethod.jp/articles/tsnote-ec2-rsa-sha-001/

しかし、ここで見落としていたのが作成する **キーペアの種別** である。 自分が試した ssh クライアント (Windows / rlogin 2.26.0) では **RSA方式で作成したキーペアを利用すると rsa-sha2-256 を指定しても接続できなかった。** キーペアの種別を ED25519 として作成したものを利用すれば接続できた。 普通に RSA でも接続できたという話もあるため、この件に関しては自分のクライアントが古いのが原因だとは思う。 しかし、これは言い換えるとキーペアの種別を変えることで初期設定のまま接続して問題を解消できる場合もあるということである。

キーペア作成時のデフォルトが RSA となっているため、SSH クライアントの更新ができずに初期ログインができない場合はここの種別を ED25519 に変更した鍵を用いてみると解決する可能性もある。

また、古い sha-rsa による接続を許可するには AL2023 公式で説明されている方法を実施することで接続できるようになった。

```bash:AL2023でssh-rsaを有効にするコマンド
$ sudo dnf install crypto-policies-scripts
$ sudo update-crypto-policies --set LEGACY
```

https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/ssh-host-keys-disabled.html

https://qiita.com/sugimount-a/items/78b5c02d4c286b7c266b



## パッケージマネージャの変更

大きな変更は以下の通り。 そのため、`dnf` を利用していけばよいだろう。

- AL2 では yum を利用していたが、AL2023 では dnf を利用するようになっている
    - `yum` コマンドは `dnf` へのシンボリックリンクとして有効になっている
- AL2 で利用されていた `amazon-linux-extras` コマンドは存在しない

```bash
$ ls -al /usr/bin/yum
lrwxrwxrwx. 1 root root 5 Jan 31 01:01 /usr/bin/yum -> dnf-3
```

> Q: AL2023 は AL2 のような Amazon-Linux-Extras を搭載していますか?
> A: いいえ。AL2023 には extras はありません。
> https://aws.amazon.com/jp/linux/amazon-linux-2023/faqs/

## デフォルトで利用している Python の pip では sudo を使うべきではない

インスタンスのローンチ直後は Python 3.9 が入っている。 この Python Binary は リポジトリで管理されているものであると同時に、cloud-init や dnf の実行にも用いられている。 dnf コマンドも実行は `/usr/bin/python3` を経由して実行しているようだ（シンボリックリンクを消すと dnf 自体が動作しなくなったため）。
さらに、依存関係としていくつかの Python のライブラリを dnf 経由でインストールしている。 例えば、`python-requests` が初期からインストールされている。 そのため、`requests` を含むアプリケーションを pip install しようとしたとき、依存関係解決時に `ERROR: Cannot uninstall requests 2.25.1, RECORD file not found. Hint: The package was installed by rpm.` のように、rpm でインストールされているという理由でインストールが失敗するケースがある。 ここでは `docker-compose` をインストールしようとした。

失敗するだけならよかったのだが、これを１度実行するとどうも中途半端にリソースが削除されてしまうらしく、初期から実行されている `aws` コマンドを実行するだけで以下のような問題が出るようになってしまった。

```bash
$ aws
Traceback (most recent call last):
  File "/usr/bin/aws", line 19, in <module>
    import awscli.clidriver
  File "/usr/lib/python3.9/site-packages/awscli/clidriver.py", line 21, in <module>
    import botocore.session
  File "/usr/lib/python3.9/site-packages/awscli/botocore/session.py", line 27, in <module>
    import botocore.client
  File "/usr/lib/python3.9/site-packages/awscli/botocore/client.py", line 16, in <module>
    from botocore import UNSIGNED, waiter, xform_name
  File "/usr/lib/python3.9/site-packages/awscli/botocore/waiter.py", line 17, in <module>
    from botocore.docs.docstring import WaiterDocstring
  File "/usr/lib/python3.9/site-packages/awscli/botocore/docs/__init__.py", line 15, in <module>
    from botocore.docs.service import ServiceDocumenter
  File "/usr/lib/python3.9/site-packages/awscli/botocore/docs/service.py", line 13, in <module>
    from botocore.docs.bcdoc.restdoc import DocumentStructure
  File "/usr/lib/python3.9/site-packages/awscli/botocore/docs/bcdoc/restdoc.py", line 15, in <module>
    from botocore.compat import OrderedDict
  File "/usr/lib/python3.9/site-packages/awscli/botocore/compat.py", line 31, in <module>
    from urllib3 import exceptions
ModuleNotFoundError: No module named 'urllib3'
```

これまで問題が起こっていなかった理由だが、 AL2 では yum は初期から導入されている python2 で動作していた。 python2 系はすでに EOL しているため、最初から利用するという選択肢にはなく、各サーバーで amazon-linux-extras で python3 系を導入し、その pip (pip3) を利用することで既存の python に影響を与えることなく sudo pip が実行できていた。

しかし、システムがデフォルトで利用する Python のバージョンが3系に上がったことで、3系だからOKと考え、新しいバージョンの python を入れることなく sudo pip を利用したため、dnf/yum でインストールされたコンテンツと競合してしまい、問題が起こってしまった。

解決策としては、これまでと同様にシステムで利用されている python3.9 バイナリとその関係には手を付けず、独立した Python のバイナリバージョンを持ってきて、そちらを利用するとよい。 この場合、`dnf install python3.11` および `dnf install python3.11-pip` が利用可能なので、これを利用し、`sudo pip3.11 install ...` とすれば rpm での衝突は発生しない。

ただし、これらを理解しておかないとシステム全体に影響を与える可能性があることは否定できない。 そのため、今後は pip が 必要ならば pip3.11 のようにバージョン指定の明記が必要な状態に設定し、デフォルトで導入されている python に影響を与える pip コマンドを提供しないようにしたい。

https://endy-tech.hatenablog.jp/entry/never_execute_sudo_pip

## crond と rsyslog のサービスがインストールされていない

デフォルトでは `crond` も `rsyslog` もインストールされていない。
そのため、スケジュールバッチ実行や `/var/log/messages` などを見ることができず、Amazon Linux 2 の時と比較してサーバーの利用方法が変わってしまう。

以下の記事で紹介されているように、これらのサービスが必要ならそれぞれインストールできる。

https://dev.classmethod.jp/articles/diff-al-2023-and-al-2-packages-and-services/

rsyslog はインストールせずとも `journalctl` で同様の処理ができるそうなので、そちらで対処するつもりであれば特に追加インストールは不要。

```bash
# cron をインストールして起動時に有効化
$ sudo dnf -y install cronie
$ sudo systemctl enable crond
$ sudo systemctl restart crond

# 追記参照 - もし古い AL2023 ならこちらが有効かも
# $ sudo systemctl enable cronie
# $ sudo systemctl restart cronid

# rsyslog をインストールして起動時に有効化
$ sudo dnf -y install rsyslog
$ sudo systemctl enable rsyslog
$ sudo systemctl restart rsyslog
```

### 2023/10/26 追記

現時点で cronie をインストールした後、systemctl で利用するサービスファイルが `crond.service` になっていたので上記有効化部分を修正。

```
Running transaction
  Preparing        :                                                                                                                     1/1 
  Installing       : cronie-anacron-1.5.7-1.amzn2023.0.2.x86_64                                                                          1/2 
  Running scriptlet: cronie-anacron-1.5.7-1.amzn2023.0.2.x86_64                                                                          1/2 
  Installing       : cronie-1.5.7-1.amzn2023.0.2.x86_64                                                                                  2/2 
  Running scriptlet: cronie-1.5.7-1.amzn2023.0.2.x86_64                                                                                  2/2 
Created symlink /etc/systemd/system/multi-user.target.wants/crond.service → /usr/lib/systemd/system/crond.service.
```

## visudo コマンドが vi ではなく nano で動く

visudo を実行するとなぜか nano で起動する。
この現象は Ubuntu では見たことがあったが……
名前通り vi で動かしたいので勝手に nano を起動するのはやめてほしい。

以下のように変数付きで起動することで visudo 実行のエディタを強制的に指定することで解消。 これは一時的なものではあるが、滅多に触るものでもないため、恒久化せずともこれで十分。

```
$ sudo EDITOR=vim visudo
```

https://wiki.archlinux.jp/index.php/Sudo


## SELinux のデフォルトが変更されている

AL2 では disabled だったが、AL2023 では permissive がデフォルトになっている。
挙動は permissive でも変わらないが、ちゃんと利用するなら enforce に、利用しないなら disabled にすること。


## EPEL がない

AL2 では `amazon-linux-extras install epel` が可能だったが、AL2023 では EPEL はサポートされない。

> Amazon Linux 2 features a high level of compatibility with CentOS 7. As a result, many EPEL7 packages work on Amazon Linux 2. However, AL2023 doesn't support EPEL or EPEL-like repositories.
> https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/compare-with-al2.html#epel


## remi のインストールができない or 難しい

AL2 は CentOS ベースだったので、EPELをインストールした後、CentOS 7 向けの rpm を利用することで remi リポジトリがインストールできた。
しかし、AL2023 は Fedora 34 ～ 36 および CentOS Stream 9 などをフォークして独自に管理しているリポジトリとなるので、Fedora および CentOS Stream のいずれかの方法を対象として dnf でインストールしようとしたが失敗した。

Fedora 36 のリポジトリを yum.repos.d 以下に加えるなど、いくつか試してみたのだが、うまくインストールする方法は見つけられなかった。

https://blog.remirepo.net/post/2023/04/19/Install-PHP-8.2-on-Fedora-RHEL-CentOS-Alma-Rocky-or-other-clone

現時点でも amazonlinux のリポジトリで php 8.1.16 が提供されているので、かなり新しいバージョンが提供されていることに変わりはないが、remi で直接インストールするのは難しそうである。

そのため、PHP8.2 などの新しいものを利用したい場合は docker で別途環境を用意した方が良いだろう。


# その他参考

https://www.geekfeed.co.jp/geekblog/amazonlinux2023-al2023/


https://dev.classmethod.jp/articles/amazon-linux-2023-update-package/