CentOSでRHEL用のoval定義を使って残存脆弱性あるか調べたい

## ことの発端

RedHatとかCentOSとかUbuntuとかは提供元が独自のパッチを適用してメンテナンスしてくれているのでたとえば php-5.4.16 とかいう一見もうサポート切れに見えるソフトだって詳しくrpm -qとかでバージョンを見ればphp-5.4.16-48.el7とかいう枝番号(RHEL系用語ではrelease番号でしたっけ)が付いててつまりは脆弱性が出ないようにパッチをバックポートしてくれているわけなんで見た目のバージョンが上がっていなくても脆弱性は対処されてるなんてことはqiitaにお越しのみなさまは当然の常識であるように認識いただけているとおもいますが

そのあたりの知識もないくせに高飛車なセキュリティ部門が突然おいおまえのところの使ってるソフトは脆弱性残存してるぞEOLになってるぞ即刻対応しないと懲戒もありうるぞ2週間だけまってやるありがたく思えとか鬼の首を取ったようにいってきやがる事例があるとのことでこのへんの枝番号まで考慮した上で残存脆弱性を調べてなにいってんだおまえバックポートされてるから安全なんだよ誤検出なんだよってエビダンスちがうエビデンスつけて言い返すことができるんですよダンナしかもOS標準のパッケージなんで追加のオゼゼは一銭もかかんないんっすよってことで同じような被害を受けている同志の方向けに情報を記したく候

2023/10/19 [対応ツール oval-rhel2centos](https://github.com/YuppyJP/oval-rhel2centos) 作ってGitHubに置いたのでもしよかったら使って

### いいたいこと
OpenSCAPというツールがLinux系のパッケージにあるんでそれインストールしてもらって、脆弱性パターンファイルに相当するoval.xmlを入手して食わせればOK

#### Ubuntu使いのみなさま
https://ubuntu.com/security/oval にあるとおりなので割愛
いちおう引用しておくと以下でできるreport.htmlを読めばOK
oscapコマンドがエラーになる人は sudo apt install -y libopenscap8 しておけばいいんじゃないかな
```bash
$ wget https://security-metadata.canonical.com/oval/com.ubuntu.$(lsb_release -cs).usn.oval.xml.bz2
$ bunzip2 com.ubuntu.$(lsb_release -cs).usn.oval.xml.bz2
$ oscap oval eval --report report.html com.ubuntu.$(lsb_release -cs).usn.oval.xml
```

#### RHEL使いのみなさま
https://access.redhat.com/ja/articles/6970229 にあるとおりなので割愛…したいんだけど微妙に不親切かも
要はUbuntuとほとんど同じでoval.xmlの入手元がちがうだけ
oscapコマンドがエラーになる人はsudo yum install -y openscap-utils しておくとよさげ
```bash
$ wget https://www.redhat.com/security/data/oval/v2/RHEL7/rhel-7.oval.xml.bz2 または
$ wget https://www.redhat.com/security/data/oval/v2/RHEL8/rhel-8.oval.xml.bz2
$ bunzip2 rhel-?.oval.xml.bz2
$ oscap oval eval --report report.html rhel-?.oval.xml
```

#### CentOS使いのみなさま
実は**これが今回の主題** なんですけどCentOS用のoval.xmlは実は誰も作ってないのよ昔はmitre.orgがメンテしてくれてたんだけどcisecurity.orgに移管された前後くらいからロクにメンテナンスされてないんで最新の脆弱性対応状況わかんないんだわ
じゃあどうするかって上にRHELのやつあるんだからそのまま使えば良いじゃん互換あるんでしょやってみよっと
あれ？どのチェックもfalseになる、つまり何も脆弱性ないってことになってる？どうしよう助けてウワーン

…というところでforums.centos.orgでもserverfault.comでも力尽きてる人が多いのでそうじゃないよ **ちゃんと使えるよ** ってことを広めたくて今回の記事を書くことにした次第

なおココに書いた情報が通用しなくなることも十分有りうるのであくまで現時点でのやり方ってことであしからず

### 落ち着いてRHELとCentOSの違いを改めて確認

* 名前が違う(Red Hat Enterprise Linux / CentOS (CentOS Stream))
  * redhat-release パッケージが centos-release (7)または centos-linux-release (8) または centos-stream-release (8 Stream)に変わっている
  * /etc/redhat-release が実ファイルか /etc/centos-releaseへのリンクかが違う、中身のフォーマットも違う
* パッケージの提供元が違う
    * パッケージの署名者が違う=keyidが違う

このあたり対処すれば良いってことっす

もとのrhel用oval.xmlってそれぞれどうなってるんだっけ、ってのはgrepで確認できる
RHELのkeyidは https://access.redhat.com/security/team/key に書いてあるとおり 199e2f91fd431d51 っすね
このあたりの確認を一応しておくとこんな感じ
```bash
$ grep redhat-release rhel-7.oval.xml
 <red-def:filepath>/etc/redhat-release</red-def:filepath>
 <red-def:name operation="pattern match">^redhat-release</red-def:name>
 <red-def:name operation="pattern match">^redhat-release</red-def:name>
$ grep redhat-release rhel-8.oval.xml
 <red-def:filepath>/etc/redhat-release</red-def:filepath>
 <red-def:name operation="pattern match">^redhat-release</red-def:name>
 <red-def:name operation="pattern match">^redhat-release-coreos</red-def:name>
 <red-def:name operation="pattern match">^redhat-release</red-def:name>
$ grep 199e2f91fd431d51 rhel-7.oval.xml
 <red-def:signature_keyid operation="equals">199e2f91fd431d51</red-def:signature_keyid>
$ grep 199e2f91fd431d51 rhel-8.oval.xml
 <red-def:signature_keyid operation="equals">199e2f91fd431d51</red-def:signature_keyid>
```

ところでredhat-release が centos-releaseになるのは自明だからヨシ！としてkeyidってどう調べるんでしょ、ってなるけどシステムに入ってるrpmがどういう署名されてるか調べればいいわけなので
/var/cache/yum/x86_64/7/updates/packages/ とか  /var/cache/PackageKit/8/metadata/baseos-8-x86_64/packages/ あたりにたまってそうなrpmファイルがあるとおもうのでそいつに rpm -qiかけてみるといいかも
```
(CentOS 7)
Signature   : RSA/SHA256, 2020年04月04日 06時20分44秒, Key ID 24c6a8a7f4a80eb5
(CentOS 8, CentOS 8 Stream)
Signature   : RSA/SHA256, 2023年10月05日 06時45分38秒, Key ID 05b555b38483c65d
```
ほら。これで材料揃った


### GitHubにあげました
2023/10/19補記
以下いろいろ書いていましたがRHEL側のメンテによってpatchだと対象行が許容範囲これちゃうとメンドウなので [対応ツール oval-rhel2centos](https://github.com/YuppyJP/oval-rhel2centos) をつくりました
xsltprocで食わせると変換してくれます

#### CentOS 7 用の修正
そんなわけでまずはCentOS 7用
可搬性あげようと思ったらxml真面目に解析して置換えとかsedとか使うべきなのかもですが
ひとまずpatch形式で行くとこんな感じ

第一ブロックはkeyid置換え
第二ブロックはredhat-releaseをcentos-releaseに置換え
なお中身のフォーマット的に「7.x」みたいなのをRHELは想定しているっぽいけどCentOSは「7」としか書かないからマッチのパターンも少しいじってる

```
--- rhel-7.oval.xml     2023-10-13 10:50:45.000000000 +0900
+++ centos-7.oval.xml      2023-10-14 00:23:45.660599003 +0900
@@ -239949,7 +239949,7 @@
  <red-def:evr datatype="evr_string" operation="less than">0:4.10.6-3.el7</red-def:evr>
 </red-def:rpminfo_state>
 <red-def:rpminfo_state id="oval:com.redhat.rhba:ste:20150364002" version="641">
- <red-def:signature_keyid operation="equals">199e2f91fd431d51</red-def:signature_keyid>
+ <red-def:signature_keyid operation="equals">24c6a8a7f4a80eb5</red-def:signature_keyid>
 </red-def:rpminfo_state>
 <red-def:rpminfo_state id="oval:com.redhat.rhba:ste:20150364003" version="641">
  <red-def:arch datatype="string" operation="pattern match">i686|ppc|ppc64|s390|s390x|x86_64</red-def:arch>
@@ -239968,11 +239968,11 @@
  <red-def:evr datatype="evr_string" operation="less than">0:3.16.2.3-9.el7</red-def:evr>
 </red-def:rpminfo_state>
 <red-def:rpmverifyfile_state id="oval:com.redhat.rhba:ste:20150364007" version="641">
- <red-def:name operation="pattern match">^redhat-release</red-def:name>
- <red-def:version operation="pattern match">^7[^\d]</red-def:version>
+ <red-def:name operation="pattern match">^centos-release</red-def:name>
+ <red-def:version operation="pattern match">^7[^\d]?</red-def:version>
 </red-def:rpmverifyfile_state>
 <red-def:rpmverifyfile_state id="oval:com.redhat.rhba:ste:20150364008" version="641">
- <red-def:name operation="pattern match">^redhat-release</red-def:name>
+ <red-def:name operation="pattern match">^centos-release</red-def:name>
 </red-def:rpmverifyfile_state>
 <red-def:rpminfo_state id="oval:com.redhat.rhba:ste:20150386001" version="642">
  <red-def:arch datatype="string" operation="pattern match">ppc64|s390x|x86_64</red-def:arch>
```

このパッチあててcentos-7.oval.xml生成してそいつでチェックすると
```
$ oscap oval eval --verbose INFO --verbose-log-file log.txt --report report.html centos-7.oval.xml
Definition oval:com.redhat.rhsa:def:20235691: true
Definition oval:com.redhat.rhsa:def:20235622: true
Definition oval:com.redhat.rhsa:def:20235621: false
Definition oval:com.redhat.rhsa:def:20235616: false
Definition oval:com.redhat.rhsa:def:20235615: true
:
```
うんうんちゃんとfalseだけにもならずtrueだけにもならずちゃんと動いてそう


#### CentOS8, CentOS 8 Stream 用の修正
続いてCentOS 8, CentOS 8 Stream用
こっちは素直
```
diff -u rhel-8.oval.xml centos-8.oval.xml
--- rhel-8.oval.xml     2023-10-13 10:50:48.000000000 +0900
+++ centos-8.oval.xml   2023-10-13 23:25:57.725936467 +0900
@@ -255141,10 +255141,10 @@
  <red-def:evr datatype="evr_string" operation="less than">0:18.5-1.el8.4</red-def:evr>
 </red-def:rpminfo_state>
 <red-def:rpminfo_state id="oval:com.redhat.rhba:ste:20191992002" version="635">
- <red-def:signature_keyid operation="equals">199e2f91fd431d51</red-def:signature_keyid>
+ <red-def:signature_keyid operation="equals">05b555b38483c65d</red-def:signature_keyid>
 </red-def:rpminfo_state>
 <red-def:rpmverifyfile_state id="oval:com.redhat.rhba:ste:20191992003" version="635">
- <red-def:name operation="pattern match">^redhat-release</red-def:name>
+ <red-def:name operation="pattern match">^centos-(?:linux|stream)-release</red-def:name>
  <red-def:version operation="pattern match">^8[^\d]?</red-def:version>
 </red-def:rpmverifyfile_state>
 <red-def:rpmverifyfile_state id="oval:com.redhat.rhba:ste:20191992004" version="635">
@@ -255152,7 +255152,7 @@
  <red-def:version operation="pattern match">^4[\d]+?[^\d]</red-def:version>
 </red-def:rpmverifyfile_state>
 <red-def:rpmverifyfile_state id="oval:com.redhat.rhba:ste:20191992005" version="635">
- <red-def:name operation="pattern match">^redhat-release</red-def:name>
+ <red-def:name operation="pattern match">^centos-(?:linux|stream)-release</red-def:name>
 </red-def:rpmverifyfile_state>
 <red-def:rpminfo_state id="oval:com.redhat.rhba:ste:20193384001" version="638">
  <red-def:arch datatype="string" operation="pattern match">aarch64|i686|ppc64le|s390x|x86_64</red-def:arch>
```
このパッチあててcentos-8.oval.xml生成してチェックすると
```
$ oscap oval eval --verbose INFO --verbose-log-file log.txt --report report.html centos-8.oval.xml
Definition oval:com.redhat.rhsa:def:20235683: false
Definition oval:com.redhat.rhsa:def:20235537: true
Definition oval:com.redhat.rhsa:def:20235474: true
Definition oval:com.redhat.rhsa:def:20235463: false
Definition oval:com.redhat.rhsa:def:20235460: false
:
```
こっちもいけそうね


#### 余談
--verbose INFO --verbose-log-file log.txt をつけて実行するとlog.txt内にどのテストがどういう結果だったからどういう判定しましたってログが残るので追いかけることができるのでなんか動作おかしいなって場合はそれ見ると良いかも

### 変更履歴
2023/10/19 CentOS 8 のStreamじゃないやつにも一応対応(正規表現変更)、GitHubにツールおいたのでリンク追加