前回「OCIでKspliceを使う Part1」の続き。
本題に入る前に
唐突だが
「カーネルをアップデートすると、既存のアプリケーションの動作が不安だ」
と思っている人もいるのではないだろうか。
「まったくの杞憂である」と声を大にして言いたい。
なぜならばカーネルはハードウェアやOSプロセスを管理するものであって、(ユーザ空間で稼働する)アプリケーションの動作には直接関係しないからだ。
アプリケーションの動作にもっとも影響するのはglibcをはじめとするコアライブラリ群である。
だからこそOracle LinuxはUEKとRHCKという、まったくベースバージョンの異なるLinuxカーネルを使っているにもかかわらず、ユーザ空間アプリケーションのABI(Application Binary Interface)互換性を保っているのだ。
長年実積のあるテクノロジーだし、技術的にもアプリケーションの動作に直接影響しないので、不安がらずに使って欲しい。とはいえソフトウェアなので「Kspliceのバグによる障害は100%無い」とは言い切れないのだが...。
Kspliceのコマンドを使いこなす
前回はUptrackクライアントを使ってアップデートを適用した。そこからの話を続けたい。
適用済みのアップデートを確認する
現在適用済みのKspliceのアップデートを確認する。Installed updates:
以下に適用されているアップデートが表示される。各行先頭の[xxxxxxxx]
という記号はアップデートごとに割り当てられているIDで、このIDを使ってアップデートを個別に適用できる。
# uptrack-show
Installed updates:
[jqu0nve5] Add support for runtime configuration of target LIO inquiry strings.
[q5v4oo0p] Denial-of-service in the Infiniband core driver when allocating protection domains.
★中略
[oehos3cn] Known exploit detection.
[s8jh2mwf] Known exploit detection for CVE-2017-7308.
[dcgq70uq] Known exploit detection for CVE-2018-14634.
Effective kernel version is 4.14.35-1844.4.5.2.el7uek
適用したアップデートを削除する
適用したアップデートは動的に削除することもできる。-y
オプションを付けると最後の質問が表示されず、そのまま実行される。
# uptrack-remove --all
The following steps will be taken:
Remove [dcgq70uq] Known exploit detection for CVE-2018-14634.
Remove [s8jh2mwf] Known exploit detection for CVE-2017-7308.
Remove [oehos3cn] Known exploit detection.
★中略★
Remove [jqu0nve5] Add support for runtime configuration of target LIO inquiry strings.
Go ahead [y/N]?★yかNを入力
アップデートを削除したので、カーネルバージョンは元に戻っている。
# uptrack-uname -r
4.14.35-1844.3.2.el7uek.x86_64
# uname -r
4.14.35-1844.3.2.el7uek.x86_64
個別のアップデートを適用する
いままでは適用可能なアップデートをすべて適用してきたが、uptrack-install
を使うと個別にアップデートを適用できる。また前述のuptrack-remove
では個別削除できる。
# uptrack-install jqu0nve5 -y
The following steps will be taken:
Install [jqu0nve5] Add support for runtime configuration of target LIO inquiry strings.
Installing [jqu0nve5] Add support for runtime configuration of target LIO inquiry strings.
Effective kernel version is 4.14.35-1844.3.2.el7uek
念のために確認すると、個別に適用したアップデートが表示された。
# uptrack-show
Installed updates:
[jqu0nve5] Add support for runtime configuration of target LIO inquiry strings.
Effective kernel version is 4.14.35-1844.3.2.el7uek
設定ファイルを調べる
Part1ではKspliceの設定ファイルの中身を見たが、今回はパラメータの意味を説明する。
/etc/uptrack/uptrack.confの内容
こちらがデフォルトの設定ファイルの中身である。インストール環境によって少し違いがあるかもしれない。
$ grep -v -e '^\s*#' -e '^\s*$' /etc/uptrack/uptrack.conf
--ここから下が出力--
[Auth]
accesskey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(意図的に伏せ字)
[Network]
https_proxy =
gconf_proxy_lookup = no
update_repo_url=https://oraclecloud-updates-ksplice.oracle.com/update-repository
user_update_repo_url=https://oraclecloud-updates-ksplice.oracle.com/ksplice/request
[Settings]
install_on_reboot = yes
autoinstall = no
重要なパラメータ
この中でも重要なパラメータは以下の通り。マニュアル以外にも、パラメータファイル内にコメントで説明が書かれている。
パラメータ | デフォルト値 | 説明 |
---|---|---|
https_proxy | なし | Internetへのアクセス経路にプロキシがあるときには指定する。ポート8080のプロキシを指定するなら次のように指定する。https_proxy = http://proxy.example.com:8080/
|
autoinstall | no | 利用できるようになったアップデートを自動的に適用する。ただしKspliceのクライアントは自動的にアップデートされないので、yum-cron等で自動アップデートすることを推奨 |
install_on_reboot | yes | リブート時に前回適用した分までのアップデートを適用する。 |
upgrade_on_reboot | no | リブート時に適用可能なすべてのアップデートを適用する。install_on_reboot とは排他の関係で、upgrade_on_reboot = yes にするならば、install_on_reboot はno もしくはコメントアウトする。 |
下記のデフォルト値であれば「自動適用はしないが、手動でインストールしたものはリブート時に自動適用する」ということになる。
install_on_reboot = yes
autoinstall = no
自動適用するときには、install_on_reboot = yes
とupgrade_on_reboot = yes
のどちらでもよいが、ブートシーケンスの最中でトラブルがあるとイヤなので次のようにしたい。さらにコンサバに行くならばinstall_on_reboot = no
にして、起動してから次のcronが実行されるまでアップデートが適用されない状態にする。cronの話は後ほど。
install_on_reboot = yes
autoinstall = yes
アップデートを自動適用する
アップデートを自動適用するにはautoinstall = yes
に変更する。デーモン系のプログラムでパラメータを変更したときには、設定を反映するために再起動などが必要だ。しかしKspliceではcronやブート時に利用しているだけなので再起動は不要である。これから、その内容を見ていくことにする。
cronの設定を確認する
cronの設定を確認する。uptrackパッケージに含まれているcron関連のファイルを確認する。2つのファイルがあることが分かる。
$ rpm -ql uptrack | grep cron
/etc/cron.d/uptrack
/usr/lib/uptrack/regenerate-crontab
cronの起動ファイルを確認すると毎時1分と31分にuptrack-upgrade
を実行している。他を調べると毎時3分と33分というサーバもあった。
$ grep -v -e '^\s*#' /etc/cron.d/uptrack ★当然catでもOK
--ここから下が出力--
1,31 * * * * root export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && [ -x /usr/sbin/uptrack-upgrade ] && /usr/sbin/uptrack-upgrade --cron
cronの詳細は下記資料を参考のこと。
rpmに含まれているもう一つのファイル/usr/lib/uptrack/regenerate-crontab
を見ると、ランダムの数字を生成しているようだ。
$ head -n 15 /usr/lib/uptrack/regenerate-crontab
--ここから下が出力--
#!/bin/sh
cronfile=/etc/cron.d/uptrack
# Run at a random time within 20 minutes of each half hour.
randfirst=$(($(od -An -N2 -d /dev/urandom) % 20))
randsecond=$(($randfirst + 30))
if [ -e "$cronfile" ] && \
! echo 5f8ac9a8816940c1e309b2e3e5bf725c '' "$cronfile" | md5sum -c --status; then
およその推測がついたのでrpmのpostinstall
セクションを見てみる。このセクションにはインストール終了後に実行するスクリプトが書かれている。20行目付近に/usr/lib/uptrack/regenerate-crontab
を発見。これまでのことをまとめると、インストール時にランダムの値を生成して30分間隔で実行するように設定している。
$ rpm -q --scripts uptrack
--ここから下が出力--
postinstall scriptlet (using /bin/sh):
if [ $1 -eq 1 ] ; then
# Initial installation
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
/sbin/chkconfig --del uptrack >/dev/null 2>&1 || :
/sbin/chkconfig --del uptrack-late >/dev/null 2>&1 || :
/bin/systemctl mask uptrack-late.service >/dev/null 2>&1 || :
/bin/systemctl enable uptrack.service >/dev/null 2>&1 || :
/bin/systemctl enable uptrack-prefetch.service >/dev/null 2>&1 || :
fi
★中略★
cronfile=/etc/cron.d/uptrack
if ! [ -e "$cronfile" ] || grep -q '^\*/30' "$cronfile"; then
/usr/lib/uptrack/regenerate-crontab ★ここで実行している
fi
アップデートの自動インストールを有効化する
すでに説明したようにautoinstall = yes
に変更する。
# cp -p /etc/uptrack/uptrack.conf /etc/uptrack/uptrack.conf-`date +%Y%m%d`
# sed -i -e "s/^autoinstall = no/autoinstall = yes/" /etc/uptrack/uptrack.conf
しばらく放置してから確認する。kspliceのログ/var/log/uptrack.log
を確認すると、cronの設定通りに毎時1分と31分に実行されていることが分かる。
$ grep "Invoked by" /var/log/uptrack.log
--ここから下が出力--
2019-05-20 22:31:02,183 DEBUG Invoked by the cron job.
2019-05-20 23:01:02,144 DEBUG Invoked by the cron job.
2019-05-20 23:31:02,077 DEBUG Invoked by the cron job.
2019-05-21 00:01:02,063 DEBUG Invoked by the cron job.
念のためcronのログファイル/var/log/cron
を確認する。すると02:01:01にuptrack-upgrade
コマンドと、02:12:01にksplice
コマンドが実行されている。後者のksplice
コマンドは拡張クライアントのコマンドである。想定外の事態が発生したので「拡張クライアントも実行されるかもしれない」問題編へ。
# tail -n 8 /var/log/cron
May 21 02:01:01 testweb01 CROND[17215]: (root) CMD (export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && [ -x /usr/sbin/uptrack-upgrade ] && /usr/sbin/uptrack-upgrade --cron) ★この行
May 21 02:01:01 testweb01 run-parts(/etc/cron.hourly)[17214]: starting 0anacron
May 21 02:01:01 testweb01 run-parts(/etc/cron.hourly)[17228]: finished 0anacron
May 21 02:01:01 testweb01 anacron[17226]: Anacron started on 2019-05-21
May 21 02:01:01 testweb01 anacron[17226]: Normal exit (0 jobs run)
May 21 02:10:01 testweb01 CROND[17297]: (root) CMD (/usr/lib64/sa/sa1 1 1)
May 21 02:12:01 testweb01 CROND[17318]: (root) CMD (export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && [ -x /usr/bin/ksplice ] && (/usr/bin/ksplice --cron user upgrade; /usr/bin/ksplice --cron xen upgrade)) ★この行
拡張クライアントも実行される?
cronのファイルを調べるとuptrack
に加えてksplice
もある。
# ls -l /etc/cron.d
total 16
-rw-r--r--. 1 root root 128 Nov 20 02:22 0hourly
-rw-r--r--. 1 root root 818 May 16 01:21 ksplice ★これ
-rw-r--r--. 1 root root 108 Oct 31 2018 raid-check
-rw-------. 1 root root 235 Aug 25 2018 sysstat
-rw-r--r--. 1 root root 747 Apr 2 10:42 uptrack
cronファイル/etc/cron.d/ksplice
がどのrpmに属しているか調べると、拡張クライアントのksplice-tools
に含まれている。
# rpm -qf /etc/cron.d/ksplice
ksplice-tools-1.0.38-1.el7.x86_64
実行される時間を確認すると、毎時12分と42分で/var/log/cron
のログ通り。
# grep -v -e '^\s*#' /etc/cron.d/ksplice ★当然catでもOK
--ここから下が出力--
12,42 * * * * root export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && [ -x /usr/bin/ksplice ] && (/usr/bin/ksplice --cron user upgrade; /usr/bin/ksplice --cron xen upgrade)
本題では無いので詳細は省略するけれど、/etc/cron.d/ksplice
の内容を実行しても、カーネルにアップデートは適用されなかった。あらためて/etc/cron.d/ksplice
の内容をよく見ると、ユーザ空間のアップデートを適用するコマンドだった。ユーザ空間のアップデートは無効になっているので、cronジョブが実行されても何も影響は無いということらしい。フー。
/usr/bin/ksplice --cron user upgrade
エクスプロイト実行検出機能
2019年4月からは、既知の脆弱性を突いた攻撃があったとき、それをロギングする機能が追加された。詳しくは以下のブログを見ていただくとして、設定手順を紹介する。
- ksplice-known-exploit-detectionをイントールする。
# yum install -y ksplice-known-exploit-detection
2.uptrck.confの末尾に以下の2行を追加する。
[Known-Exploit-Detection]
enabled = yes
3.追加したパラメータを有効化するためにkspliceを実行する。
# ksplice kernel upgrade
4.有効になると、以下のようにカーネルパラメータが設定される。
# cat /proc/sys/kernel/known_exploit_detection
1
5.既知の脆弱性に対する攻撃があったときは、kspliceで適用したパッチで防御するとともに、/var/log/messagesには以下のように攻撃の痕跡が表示される。
Apr 02 13:36:16 ol-7-sys log-known-exploit[22360]: exploit attempt detected; id=CVE-2017-101234 pid=22358 uid=1001 comm=a.out lost=0
いくつか補足事項
Kspliceクライアントのアップデートも検討する
これまでアップデートが自動適用する方法を説明してきたが、kspliceクライアント自身は更新しない。そのため自動適用するときは、yum-cronなどでuptrack*
やksplice*
に該当するパッケージを自動でアップデートすることも検討する。
yum updateでカーネルをアップデートする必要はあるか?
Yes.
Kspliceを有効にすると停止時間ゼロでアップデートを適用できる。しかし再起動するときには、再び累積のアップデートを適用する必要がある。数が増えるほど時間がかかり、また複雑性も増加する。
そのためOSを再起動しなくてもyum update
でカーネルも定期的にアップデートすることが推奨されている。そして何かのメンテナンスタイミングで再起動すれば、新しいカーネルが利用される。
Kspliceがセットアップされている環境ではyum update kernel*
に時間がかかる
Part1の冒頭で少し触れたが、Kspliceが設定されている環境でyum update kernel*
を実行すると、内部的にinitrdやinitramfsが再作成される。これは非Ksplice環境では起きない動作だ。
アップデートの最中にtop
コマンドでプロセスを確認すると、dracut
やgzip
、cpio
などが活発に動作し、initrdやinitramfsが再作成されていることがわかる。
Ksplice 30日トライアル
OCIでは追加のサポート契約なしにKspliceを利用できるが、オンプレミスなど他の環境では利用できない。30日トライアルが提供されているので、興味のあるかたは検討してはどうだろう。
https://ksplice.oracle.com/try/trial
コマンド・リファレンス
Ksplice Uptrackクライアントのコマンド・リファレンスは以下のマニュアルを参照のこと。
マニュアルを補足すると、Kspliceを無効化するには以下のように空ファイルを作成する。するとuptrack-upgradeを実行してもアップデートはできず、また再起動時にもアップデートは適用されない。当然cronジョブも実行されない。
# touch /etc/uptrack/disable
まとめ
Part1
- Kspliceを使うと、再起動しなくても新しいカーネルアップデートを適用できる
- Oracle Cloud Infrastructure Compute/Databaseでは、デフォルトでKspliceを利用できる
- KspliceはUEKとRHCKの両方で利用できる
- 操作コマンドには、uptrackクライアントと拡張クライアントという2種類のコマンドがある
- 拡張クライアントを使うとglibcとopensslも対象にできる
- Oracle Linux以外にCentOSやRHEL、Ubuntuでも利用できる。OCIの場合は追加料金不要
Part2
- アップデートは手動で適用することも、自動で適用することもできる
- 適用したアップデートは削除できる
- アップデートの適用と削除は個別IDごとに指定できる
- 自動適用を有効にするとcronジョブで30分間隔で実行される
- 設定ファイルは
/etc/uptrack/uptrack.conf
のみ - 拡張クライアントがインストールされていても、ユーザー空間アップデート用の設定を追加しない限り、適用されることは無い
- Ksplice環境ではinitrdやinitramfs再作成されるので、カーネルアップデート時に時間がかかる
おわりに
一通り読んでみていかがだろうか。正直なところマニュアル以外の情報が少なく、最初は取っつきにくさもあった。だけれど仕組みやコマンド体系を理解すれば、シンプルなのでは無いだろうか。まあライブ・パッチング自体の仕組みは高度な実装だが利用者には関係ないことだ。
また今回は紹介していないが、拡張クライアントやSNMPプラグインなどさまざまな機能がある。興味があればそれらも調べて欲しい。