AWX on Almalinux 9 で receptor がエラー状態になる


# 概要

AlmaLinux 9 上の AWX ( [run in Docker](https://github.com/ansible/awx/blob/devel/tools/docker-compose/README.md) ) 環境を再構築したところ、 receptor がエラー状態になるという事象が発生しました。
OpenSSL 3.0 で 秘密鍵・公開鍵の形式が変わったためのエラーで、回避策として `-traditional` オプションをつけて鍵を作り直す必要がありました。（回避策です）
その手順について備忘録的にまとめておきます。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310495/58913b99-a2a7-304e-44d6-efbbbae2ffb4.png)

# 環境

- OS : AlmaLinux 9.0 (Emerald Puma)
- AWX : AWX 21.3.0  ( run in Docker 環境 )
- OpenSSL : OpenSSL 3.0.1

# エラー内容

上図の通り、 AWX コンソールの　管理＞インスタンス画面で、receptor のステータスがエラーになります。
receptor リンクをクリックすると、ステータスの詳細が確認できます。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310495/a073ed09-00b5-d3fe-3354-2406e6f55cc1.png)

エラーメッセージ：
`Remote error: ERROR: could not load signing key file: unknown block type PRIVATE KEY`

秘密鍵が読み込めなかったというエラーのようです。

この時、 `docker ps` コマンドではコンテナが stopしているなどの異常は見られません。
また、 receptor コンテナのログにもエラーは見られませんでした。
唯一、 awx コンテナのログに同じエラーが出力されています。

```shell-session
tools_awx_1         | 2022-07-20 11:54:33,599 WARNING  [ef95b864] awx.main.tasks.system Execution node attempting to rejoin as instance receptor-2.
tools_awx_1         | 2022-07-20 11:54:33,615 WARNING  [ef95b864] awx.main.tasks.system Execution node attempting to rejoin as instance receptor-1.
tools_awx_1         | ERROR 2022/07/20 11:54:33 could not load signing key file: unknown block type PRIVATE KEY
tools_awx_1         | 2022-07-20 11:54:33,643 INFO     [ef95b864] awx.main.tasks.system Failed to find capacity of new or lost execution node receptor-2, errors:
tools_awx_1         | Remote error: ERROR: could not load signing key file: unknown block type PRIVATE KEY
tools_awx_1         | ERROR 2022/07/20 11:54:33 could not load signing key file: unknown block type PRIVATE KEY
tools_awx_1         | 2022-07-20 11:54:33,656 INFO     [ef95b864] awx.main.tasks.system Failed to find capacity of new or lost execution node receptor-1, errors:
tools_awx_1         | Remote error: ERROR: could not load signing key file: unknown block type PRIVATE KEY
```

# 対応

エラーメッセージに基づき検索を行い、下記の Issue を見つけました。（そのまんまです）
[Communication with receptor fails: could not load signing key file: unknown block type PRIVATE KEY #12266](https://github.com/ansible/awx/issues/12266)

回避方法としては、以下の２つの **どちらか** です。

1. openssl コマンドでキーペアを再作成し、置き換える
1. awx ( run in docker ) の main.yml を修正し、キーペアを再作成させる

上記それぞれについて記載します。

# 1. OpenSSL コマンドでキーペアを再作成し、置き換える

receptor が利用しているキーペアは以下の場所にあります。
`work_private_key.pem`、 `work_public_key.pem` の２つです。
( awx は git clone した際にできたディレクトリで、_sources 以下は、導入時の `make docker-compose-build` 実行後に作成されます）

```shell
# cd awx/tools/docker-compose/_sources/receptor/
# ls
receptor-awx-1.conf  receptor-hop.conf  receptor-worker-1.conf  receptor-worker-2.conf  
work_private_key.pem  work_public_key.pem
```

該当のキーペアを削除し、OpenSSL コマンドを利用してキーペアを再作成します。
その際に、`-traditional` オプションをつけます。

```shell
# openssl genrsa -traditional -out work_private_key.pem 4096
# openssl rsa -traditional -in work_private_key.pem -pubout -out work_public_key.pem
writing RSA key
```

キーペア再作成後に、AWX を起動すれば解消します。

# 2.main.yml を修正してキーペアを再作成させる

AWX 起動コマンド実行時 ( run in docker の場合、 `make docker-compose` 実行時 ) に、 
該当のキーペアが存在しなければ、自動的に再作成されます。
そのキーペア作成部分に `-traditional` をつける、という方法です。

修正対象のファイルは sources ロールの tasks 以下のファイルです。

`awx/tools/docker-compose/ansible/roles/sources/tasks/main.yml`

このファイル内に、キーファイルの作成部分があります。 (下の内容はすでに `-traditional` をつけた後の状態です)

```yml:awx/tools/docker-compose/ansible/roles/sources/tasks/main.yml 抜粋
- name: Generate Private RSA key for signing work
  command: openssl genrsa -traditional -out {{ work_sign_private_keyfile }} {{ receptor_rsa_bits }}
  args:
    creates: "{{ work_sign_private_keyfile }}"

- name: Generate public RSA key for signing work
  command: openssl rsa -traditional -in {{ work_sign_private_keyfile }} -out {{ work_sign_public_keyfile }} -outform PEM -pubout
  args:
    creates: "{{ work_sign_public_keyfile }}"
```

上記の通り `-traditional` を付与した後、 1. で記載したキーペアを削除します。

:::note warn
注
command モジュールの args に creates が入っているため、ファイルが存在すると task が OK となりキーペアは再作成されません
:::

キーペア削除後、 AWX を起動します。その際、 該当のタスクが changed となり再作成されたことがわかります。

```shell-session
# make docker-compose

...(略)...

TASK [sources : Generate Private RSA key for signing work] **********************************************************************************************************************************************
changed: [localhost]

TASK [sources : Generate public RSA key for signing work] ***********************************************************************************************************************************************
changed: [localhost]

...(略)...

```

起動後、receptor のステータスを見ると問題なく稼働していることがわかります。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310495/4f75d675-7452-ddc0-c644-6c6ed36536c1.png)


# （参考）鍵の形式に関して

OpenSSL に深入りする知識はありませんが、[ウィキペディア](https://ja.wikipedia.org/wiki/PKCS)の力をお借りして
今回のキーペアについて、少し補足します。

`-traditional` のあり、なしで、 秘密鍵の形式が異なります。

`-traditional` あり
```
-----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEAqldsq5yT3Lxwq6/Cs/qAvgeBzLYqTgUv6Kg21Q2uVh6+Ew0s
```

こちらは、 PKCS#1 形式で、
RSA暗号鍵、公開鍵および秘密鍵のフォーマットの最初の規定で、暗号化されていません。

`-traditional` なし
```
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDICJZ6UA8EuLOB
```
こちらは、 PKCS#8 形式で、秘密鍵情報構文の標準だそうです。
PKCS#8 については、暗号化されるパターンもあり、
暗号化されている場合は、 `BEGIN ENCRYPTED PRIVATE KEY` となるそうです。

# 終わりに

今回、OpenSSL については深入りしませんでしたが、`-traditional` をつけて、古い形式にしている以上、
望ましい状態ではないと思います。（ そのため、今回の対応はあくまで回避策です。）
OpenSSL 関連は、[こちら](https://heartbeats.jp/hbblog/2021/09/openssl3.html)の記載がわかりやすいと思いました。
AWX はバージョンアップが早いのですぐにこのような回避策は不要になると思いますが、参考になれば幸いです。

# 参考情報

■ Communication with receptor fails: could not load signing key file: unknown block type PRIVATE KEY #12266
https://github.com/ansible/awx/issues/12266

■ OpenSSL 3.0のTLS証明書用プライベート鍵生成方法
https://heartbeats.jp/hbblog/2021/09/openssl3.html

■ ウィキペディア PKCS
https://ja.wikipedia.org/wiki/PKCS

---