Oracle Autonomous Linuxをハックする Part 3

# 前回の続き
前回から続いた内容なので、連続した段落番号をつけている。

* [Oracle Autonomous Linuxをハックする Part 1](https://qiita.com/yamada-hakase/items/3b29b49703d2c807349b)
* [Oracle Autonomous Linuxをハックする Part 2](https://qiita.com/yamada-hakase/items/b735ec62ddcb38eb19f5)

# 6. Oracle Autonomous Linux固有のal-configを調べる


これまでの調査で大まかなことが分かったので、Oracle Autonomous Linux固有のal-configを調べてみよう。

### 6-1. al-configパッケージの調査

al-configに含まれるファイルを調べる。

```shell-session
# rpm -qf `which al-config`
al-config-1.0-1.0.28.el7.noarch

# rpm -ql al-config
/etc/al-config/al.conf
/etc/al-config/yum-cron.conf
/etc/logrotate.d/al-config
/etc/profile.d/al.sh
/etc/rsyslog.d/al-exploit-alert.conf
/etc/yum.repos.d/al-al7.repo
/usr/lib/al-config
/usr/lib/al-config/activate_known_exploit_detection.sh
/usr/lib/al-config/add_cron_job.sh
/usr/lib/al-config/functions
/usr/lib/al-config/ksplice_access_key
/usr/lib/al-config/pre_config.sh
/usr/lib/systemd/system-preset/84-al.preset
/usr/lib/systemd/system/al-config.service
/usr/sbin/al-config
/usr/sbin/al-exploit-alert
/usr/sbin/al-notify
/usr/sbin/al-start
/usr/sbin/al-update
/usr/share/licenses/al-config-1.0
/usr/share/licenses/al-config-1.0/LICENSE
/usr/share/selinux/packages/omprog_exploit_detection.pp
/var/lib/al-config
```

上記から推測できることは以下のとおり。

1. RPMパッケージ名のサフィックスがnoarchなので、スクリプトやテキストファイルなど非実行形式ファイル
2. 次の2つは設定ファイル

　　/etc/al-config/al.conf
　　/etc/al-config/yum-cron.conf

3.al-configサービスのユニットファイル

　　/usr/lib/systemd/system/al-config.service

4.logrotateの定義があるので、ログファイルを出力している

　　/etc/logrotate.d/al-config

5.コマンド類
　　/usr/sbin/al-*

6.Kspliceのエクスプロイト検出に対応したSELinuxポリシーモジュール

　　/usr/share/selinux/packages/omprog_exploit_detection.pp

### 6-2. al-configの更新履歴

al-configがOracle Autonomous Linuxのコアコンポーネントであることがわかった。毎回ソース解析は面倒なので、手早く更新履歴を知るには`rpm -q --changelog`が便利だ。これを見れば大まかな機能変更がわかる。

```shell-session
$  rpm -q --changelog al-config |head -n 15
* Wed Oct 16 2019 Frank Deng <frank.deng@oracle.com> - 1.0-1.0.30.el7
- Update AL only ksplice access key [Orabug: 30420716] (Frank Deng)  [Orabug: 30420716]
- Display ksplice first in summary (Frank Deng)

* Tue Sep 24 2019 Frank Deng <frank.deng@oracle.com> - 1.0-1.0.29.el7
- Fixes for ACL-67 - Send notification once topic OCID is configured. - Do not
  report 'needs-restaring' status be default. - Print welcome message for opc
  user login. - Fix exploit alert message. (Frank Deng)

* Fri Sep 13 2019 Frank Deng <frank.deng@oracle.com> - 1.0-1.0.28.el7
- Add license url (Frank Deng)
- Add disclaimer (Frank Deng)
```

### 6-3. al-configのライセンス

al-configのライセンスを調べると「UPL」。

```shell-session
$ rpm -qi al-config
Name        : al-config
Version     : 1.0
Release     : 1.0.30.el7
Architecture: noarch
Install Date: Sat 19 Oct 2019 03:46:13 PM JST
Group       : Development/Tools
Size        : 36822
License     : UPL ★
```

聞き慣れないので調べてみると、こちら「[The Universal Permissive License (UPL)](https://www.oracle.com/downloads/licenses/upl-license.html)」に条文を発見。どうやらApache系のライセンスでOSSライセンスの一つ。Commercialじゃなくてよかった。

### 6-4. al-config.serviceサービス


al-config.serviceサービスでは/usr/sbin/al-startを起動している。

```shell:/usr/lib/systemd/system/al-config.serviceの一部
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/al-start
```

この中で注目は★の2箇所。それぞれについてコードを見てみよう。

```shell:/usr/sbin/al-startの一部
# pre config
/usr/lib/al-config/pre_config.sh　★

# activate know exploit detection
/usr/lib/al-config/activate_known_exploit_detection.sh

# add cron job if the cron job doesn't exit
/usr/lib/al-config/add_cron_job.sh　★
```
pre_config.shでは、yum-cronの自動起動やkspliceのcronジョブを無効化している。

```shell:/usr/lib/al-config/pre_config.shの一部
# Stop and disable yum-cron systemd service, then yum-cron con jobs won't actually run
systemctl stop yum-cron.service &>/dev/null
# yum-cron is pre set to disable by default
systemctl preset yum-cron.service &>/dev/null

# Disable ksplice cron jobs by commenting out the cron job entries.
for cron in /etc/cron.d/uptrack /etc/cron.d/ksplice; do
    if [ -f "$cron" ]; then
        sed -i '/^[0-9]/s/^/# /g' $cron
    fi
done
```

add_cron_job.shでは、al-updateを実行するcronジョブを追加している。cronの起動時間は$RANDOMを利用してランダムな値を設定している。

```shell:/usr/lib/al-config/add_cron_job.sh
if [ ! -f "$al_cron_job_file" -o $force -eq 1 ]; then
    # Add AL auto update cron job
    cat > $al_cron_job_file <<CRON
# Daily cron job for AL updates
$(($RANDOM%60)) $(($RANDOM%24)) * * * root /usr/sbin/al-update &>/dev/null
CRON
    log "Created cron job file $al_cron_job_file ."
fi
```

`rpm -q --scripts`で、al-configパッケージをインストールしたときに実行するスクリプトを確認する。pre_config.shは、こちらでも実行している。

```shell-session
# rpm -q --scripts al-config
```

```shell:%postinstallセクションの内容
postinstall scriptlet (using /bin/sh):
# install or upgrade
/usr/lib/al-config/pre_config.sh ★
/usr/sbin/semodule -i /usr/share/selinux/packages/omprog_exploit_detection.pp ★

if [ $1 -eq 1 ] ; then
        # Initial installation
        systemctl preset al-config.service >/dev/null 2>&1 || :
fi
```

### 6-5. al-configの主要コマンド

実行可能スクリプトの行数をカウントする。行数が多いal-configやal-notify、al-updateあたりが、いろいろやっていそうだ。

```shell-session
# ls /usr/sbin/al-* |xargs wc -l
  227 /usr/sbin/al-config
   56 /usr/sbin/al-exploit-alert
  143 /usr/sbin/al-notify
   42 /usr/sbin/al-start
  309 /usr/sbin/al-update
  777 total
```

それぞれの機能を説明すると以下のとおり。

| スクリプト | 処理内容 |
|:--|:--|
| al-config  | Notificationsの設定|
| al-exploit-alert | ksplice-known-exploit-detectionで検出した内容を/var/log/al.logに出力 |
| al-notify | Notificationsのメッセージ通知 |
| al-start | al-configの初期設定。既存のyum-cronやkspliceジョブの無効化など  |
| al-update | Kspliceによるパッチ適用とRPMパッケージのアップデート  |

それぞれの呼び出し関係は以下のとおり。
![al-config-diagram1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/8eb67b85-4391-b2b9-d600-febf6eef9fbb.png)


al-updateの冒頭を見ると、このスクリプトが実行することが書かれている。メールで送られてきたレポートと一致している。

```shell:/usr/sbin/al-update
# al-update:
# - ksplice upgrade
# - yum-cron - yum upgrade
# - report exploit attemp(s) if detected
# - report ksplice show
# - report needs-restarting
# - send notification if needed
```

<font color="red">注意：</font>
al-config-1.0-1.0.29以降では`needs-restarting`は実行されなくなった。実行するには、以下のパラメータをyesに変更する必要がある。

```:/etc/al-config/al.conf
report_needs_restarting=no
```


al-updateのコードを調べると、下記2つの原因も判明する。

* Kspliceは「cronジョブ無効化」「自動適用しない設定」だが自動適用されている
* yum-cronは「cronジョブあり」「適用無効化」だが自動適用されている

Kspliceはal-updateから実行しているので、既存のcronジョブや設定ファイルとは関係なく実行される。

```shell:/usr/sbin/al-updateのksplice部分
if command -v ksplice &>/dev/null; then
    echo "Running 'ksplice -y all upgrade'." | tee -a $out_file
    ksplice -y all upgrade 2>&1 | tee -a $out_file
    ret=${PIPESTATUS[0]}

else
    echo "Running 'uptrack-upgrade -y'." | tee -a $out_file
    uptrack-upgrade -y | tee -a $out_file
    ret=${PIPESTATUS[0]}
fi
```

続いてyum-cron。引数に設定ファイル/etc/al-config/yum-cron.confを指定している。

```shell:/usr/sbin/al-updateのyum-cron部分
echo "Running 'yum-cron' with update cmd: default." | tee -a $out_file
yum-cron $yum_cron_config_file 2>&1 | tee -a $out_file
```

```shell:/usr/lib/al-config/functions
config_dir=/etc/al-config　★
# AL config
config_file=$config_dir/al.conf
# OCI config: topic OCID etc.
oci_config_file=$config_dir/oci.conf
# OCI SDK/CLI config
oci_cli_config_file=$config_dir/oci_cli.conf
# OCI API private key
oci_api_key_file=$config_dir/oci_api_key.pem
# Yum-cron config
yum_cron_config_file=$config_dir/yum-cron.conf　★
```

設定ファイルは`apply_updates = yes`になっているので`yum update`が実行される。これでkspliceとyum-cronが実行できた理由が分かった。

```shell-session
# grep apply_update /etc/al-config/yum-cron.conf
apply_updates = yes
```

### 6-6. al-configの設定ファイル

残りの設定ファイルが`/etc/al-config/oci.conf`だ。Notificationsで設定した値が格納されている。

```shell:/etc/al-config/oci.conf
# This file is a bourne shell snippet, and is sourced by the
# script al-notify for configuration.

# OCI notification service topic OCID
topic="ocid1.onstopic.oc1.phx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

### 6-7. al-configのログファイル

ログファイルにはNotificationsで送信する内容や、Notificationsによるメールの送信情報が出力されている。メールが送信されないときは、ERRORが無いか確認してみよう。

なお、メールが送信されるのは、Kspliceパッチを適用したときやRPMパッケージアップデートが実施させたときだ。何も変更が無く、エラーも無いときはメールは送信されない。

```shell:/var/log/al.log
+------------------------------------------------------------------------+
|  Needs-restarting status                                               |
+------------------------------------------------------------------------+
Running 'needs-restarting'.
--------------------------------------------------------------------------
Running 'needs-restarting --services'.
--------------------------------------------------------------------------
Running 'needs-restarting --reboothint'.
No core libraries or services have been updated.
Reboot is probably not necessary.
2019-10-03 12:29:12,755 - al-notify[INFO]: Publishing message 'AL: Status update
 on instance autolinux7-2'
2019-10-03 12:29:12,757 - al-notify[DEBUG]: Running OCI CLI with instance princi
pal auth.
2019-10-03 12:29:14,552 - al-notify[DEBUG]: ServiceError:
{
    "code": "NotAuthorizedOrNotFound",
    "message": "Resource Id: ocid1.onstopic.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx not found",
    "opc-request-id": "E5FF4BC3C68F4E19A78E753963D7F3ED/6817D51C37DAA55194292EAA
47A70945/D6CCC5F93B6CCFEFA15C267966BB6091",
    "status": 404
}
2019-10-03 12:29:14,554 - al-notify[ERROR]: Failed to publish message 'AL: Statu
s update on instance autolinux' ★メールが送信できずにエラーになっている
```

### 6-8. 管理コンソール（OS Management Service）

<font color="red">[OS Management Service](https://docs.cloud.oracle.com/iaas/os-management/index.html)の正式リリースで、対象はOracle Autonomous LinuxではなくOracle Linux 6 / 7 / 8であることが判明。誤解させるようなことを書かないで欲しい。＞Oracle</font>

**Oracle Autonomous Linux:** 毎日に自動的にアップデートを適用。DMZに配置するようなサーバーに適している。
**OS Management Service:** インスタンスのアップデート管理をグループ単位で実現。管理者による制御なのでパッチ適用をコントロールしたいエンタープライズ向け。

以下は初回公開時の文面。

Oracle Autonomous Linuxを紹介しているブログでは、管理コンソールに「OS Management」というリンクが追加されている。セキュリティ・アップデートのステータスを確認できるだけで無く、メニューからアップデートを実行できるようだ。

[In an Industry First, Oracle Brings Autonomous Operation to Linux](https://blogs.oracle.com/cloud-infrastructure/in-an-industry-first%2c-oracle-brings-autonomous-operation-to-linux)
![al-config-console1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/4a1a98b4-548e-6319-f39d-3edc058077b4.png)
# 7. まとめ

**Oracle Autonomous Linuxの特徴**

* Oracle Autonomous LinuxはOracle Linux 7をベースとしている
* Kspliceパッチが自動適用される
* RPMパッケージが自動アップデートされる（yum-cron）
* Kspliceパッチを適用したときや、yum-cronでパッケージをアップデートしたとき、Notificationsサービスを利用してメールが自動送信される
*  Oracle Autonomous Linux専用に用意されたYumリポジトリは、アップデート高速化のためにパッケージ数を制限している（推測モード）

**Oracle Autonomous Linux固有の機能を支える仕組み**

* Oracle Autonomous Linux固有の機能はal-configパッケージで提供している
* Kspliceやyum-cronの実行は、既存の仕組みは利用しないでal-configのスクリプトを利用している
* al-configパッケージに含まれるコマンドのなかで、もっとも中心的なのはal-updateである

# 9. 今後に向けて
ファーストバージョンということもあり、現時点で大きな魅力は感じない。だけれど今回のOracle OpenWorld 2019では「CPUコアやメモリの柔軟な変更」「ストレージ・サイズや性能の柔軟な変更」などOracle Cloud Infrastructureのロードマップが発表された。

これらの機能と組み合わせることで、よりAutonomous（自立）になっていくのだろう。今後に期待といったところか。

Red Hat社は、何年も前から**[Red Hat Insights](https://www.redhat.com/ja/technologies/management/insights)**を提供していることを忘れてはならない。以前は追加オプションだったが、RHEL8以降はサブスクリプションに含まれるのだ。