お声がけをいただいて、連載が始まったわけですが、編集部からのオーダーが「インフラセキュリティ」と言うことで、ちょっとだけ迷いました。
インフラもセキュリティもなんでもそうですが、共通して言えることは「『あたりまえ』の積み重ねが被害を減らす」と言うところだからです。
ただ、ここで言う『あたりまえ』は「セキュリティをやってる人から見た『あたりまえ』」であり、そうでない人から見たら「そうなの?」と言うことも多々あります。
本連載では、「これ」と言うことが発生したときに、その内容について解説を試みると言うことは普通にやるとして、そう言う『あたりまえ』的な内容についても紐解いていくような試みをして行こうと思います。
と言うことで、最初は、「脆弱性対策のためにパッケージを入れ替える」と言うところに触れて行きます。
1.ソフトウェアの脆弱性とその修正
バグのないソフトウェアはないと言うくらいに、ソフトウェアにはさまざまなバグが存在します。実装時に混入するものもあれば、仕様そのものにバグがあると言うこともあり得ます。バグのうち、外部の第三者による不正利用やサービス妨害、情報窃取に繋がりうるものを脆弱性と呼ぶことが多いです。経済産業省告示第二百三十五号[1]には、より具体的な脆弱性の定義がなされています。
例外はあるものの、ソフトウェアの脆弱性が見つかったときには、多くの場合その対応策がリリースされます。その対応策はパターンがいくつかあります。場合によっては「パッチ適用」と言う言葉を見ることがあります。本来のパッチ適用は、プログラムファイル中のバグに該当する部分を直接書き換えたり、メモリ上のデータを書き換えたりと言う、手芸のパッチワークになぞらえた行為を指しますが、このような行為は作業者に相応のスキルを要求することもあり、言葉どおりのパッチ適用を行うような脆弱性対応は少ないと言えます。
(1)ソフトウェアのバージョンアップ
たとえば、FooBarと言うソフトウェアのバージョン1.0.0に脆弱性が見つかった場合、そのソフトウェアの開発者は、次のバージョンで脆弱性対応を行います。バージョン番号の付け方にもよりますが、たとえば1.0.1と言うバージョンで脆弱性対応が行われます。
ソフトウェアのバージョンアップによる脆弱性対応を行う場合には、オープンソースソフトウェア(OSS)やフリーソフトウェア(FSW)の場合にはコンパイルなどの作業を伴うことが多いため、通常の運用管理を考えた場合には少し手間がかかる対応となります。
(2)ソフトウェア以外の部分での対応
ソフトウェアをバージョンアップできないような環境の場合には、脆弱性の影響を最小限に抑えるような対応を行うことがあります。
たとえば、ソフトウェアにリモートからの不正侵入を許すような脆弱性が見つかった場合には、不正侵入を許すようなパターンの電文を通さないようにしたり、リモートからの電文が届かないようなフィルタをネットワーク機器で行うと言うことが考えられます。また、信頼できる通信相手のみ、当該ソフトウェアの提供するサービスを利用すると言うことも対策の1つになります。
(3)ソフトウェアパッケージの入れ替え
これは、すでに導入済みのソフトウェアパッケージを、脆弱性を修正したソフトウェアパッケージに入れ替えることを指します。ソフトウェアのバージョンアップと異なるのは、大抵の場合ユーザが明示的にコンパイルなどの作業を指示することなく、ソフトウェアの入れ替えが行われる点です。
(4)攻撃の監視
(1)~(3)のいずれも行えない場合、攻撃を行った際の挙動を把握して、そのような挙動が発生しているかどうかをシステムの運用監視中で見定め、もしそのような挙動を確認した場合には、システム停止やそのような挙動を発生させた通信先との通信を遮断するなどの対応を取ります。
ただし、このような対応は、根本的に攻撃による被害をなくすことはありません。対策を取れない場合の次善の策と言えます。
2.通常のソフトウェア脆弱性対処とOSごとの対処
ソフトウェアに脆弱性が発見された際には、1(1)~(4)のいずれかの対応を行うか、対策を行うまでの間システムを停止させるなどの措置が取られます。
しかし、システムを停止させた場合、停止期間中にそのシステムを利用することは当然できませんし、システムの稼働がビジネスに直結するような場合には、動かしていることによる収益を見込むことは当然できません。このため、可能な限り早く脆弱性を修正し、システムに存在する脆弱性をなくすことが求められます。
とは言え、脆弱性修正を行うための手段のうち、1(1)と同(3)については、稼働しているソフトウェアに何らかの手が入る、と言っても良いでしょう。
以下、OSSやFSWの脆弱性が見つかった場合の対処について、1(1)と同(3)を取り上げ、利害得失の観点から比較を行ってみることにします。
(1)バージョンアップ
OSSやFSWの場合、バージョンアップ=ソースコードのコンパイルと言うことになります。
- (A)利点
- (a)既知の脆弱性による影響をなくすことが可能
- (b)バージョンアップにより提供される新しい機能を利用可能になる
- (B)欠点
- (a)脆弱性修正以外に出てくる影響を見極めるためには、Changelogやソースコードをきちんと読み解く必要がある
- (b)コンパイルを行う際の環境構築や入れ替えにスキルが必要
- (c)入れ替えに伴う他のソフトウェアへの影響確認が大変
- (d)依存関係の解決が大変になることがある
ソースコードをコンパイルするには、相応のスキルを必要とします。
単なるコマンド1つの入れ替えで済めば良いのですが、脆弱性対応を行う必要があるような場合には、コマンド1つ入れ替えて済むと言うものではありません。
とくに、ライブラリの入れ替えなどを伴う場合には、入れ替えた後の動作をきちんと行えるかどうかについても確認が必要になりますし、複数のソフトウェアと連携して動くソフトウェアの入れ替えの場合には、依存関係の解決なども視野に入れた作業が必要になります。
(2)パッケージ入れ替え
ここでのパッケージは、RPMパッケージやDEBパッケージのことを指します。
- (A)利点
- (a)既知の脆弱性による影響をなくすことが可能
- (b)バージョンアップではないため、パッケージ入れ替えに伴う確認は、最小限の動作確認で済む
- (c)依存関係の解決は、パッケージマネージャに任せることが可能
- (B)欠点
- (a)コンパイル済みのバイナリ+設定ファイルと言う組み合わせが提供されるため、パッケージ入れ替えで何が差し替わるかをきちんと確認する必要がある
- (b)ソフトウェアをパッケージではなくソースコードからのコンパイルを行って導入している場合には、すでに入っているソフトウェアを消去するか無効にする必要がある
- (c)バージョンアップするわけではないため、脆弱性対応は行えるが、バージョンアップを行うことで使用可能になるような機能は使えない
RPMパッケージやDEBパッケージは、オフィシャルなものはパッケージを作成する基になるソフトウェアバージョンはかわりません。最近のLinuxディストリビューションでは普通にこのような考え方でパッケージは作られています。
これは、ソフトウェアを入れ替えることで発生する手間を、入れ替えるソフトウェアのベースバージョンを固定することで最小限に留められる効果があります。最新の機能を使いたいと言う方々には不満があるかもしれないことですが、エンタープライズ用途では、構成を決め打ちにしてシステム開発を行い、実際の運用時にはソフトウェアのバージョンは固定にしつつ、出て来た問題を潰していくと言う手法がよく採られます。
運用上、パッケージを使うことの最大の利点は「依存関係の解決をパッケージマネージャに任せることができる」と言う点に尽きます。
筆者もシステム運用の経験は山のようにありますが、ソースコードからのコンパイルを行う場合に、依存関係の解決を行うために別のソフトウェアを入れ……と言う依存関係解決地獄に陥ったことが何度となくあります。そして、このような依存関係を解決していくうちに、本来の目的である安定したシステム稼働ができなくなって行く、と言うことも普通に発生します。
パッケージマネージャに任せることで、このようなトラブル発生を最小限に抑えることが可能になります。可能であれば、自前でコンパイルしなければならないようなソフトウェアであっても、パッケージ化しておくことで、インストールと除去が容易になります。
3.パッケージのバージョンアップ時に差異が出てくる部分の例
以下に、Debian GNU/LinuxにおけるOpenSSLの脆弱性対応前と対応後のパッケージ差異を示します。
Debian GNU/Linuxでは、パッケージのコンパイル時に「ベースとなるソフトウェアの取得」+「パッチ適用」を行うのですが、適用されるパッチがどのように異なるかを見ることによって、どう言う差異が発生してるのかがわかります。
具体的には、Heartbleed Bugが出る前後にリリースされたOpenSSLパッケージのソースコードアーカイブopenssl_1.0.1e-2+deb7u4.debian.tar.gz(2014年2月リリース、以下u4)とopenssl_1.0.1e-2+deb7u7.debian.tar.gz(2014年4月リリース、以下u7)の間に含まれるパッチとその内容の差を確認することで、どのような影響があるのかを推し量ることが可能になります。
(1)どんなパッチファイルが増えたか? &差分のあるファイルは?
上記u4のアーカイブファイルとu7のアーカイブファイルをそれぞれ展開すると、どちらもdebianと言うディレクトリが作成されます。パッチファイルはさらにその下にあるpatchesディレクトリに配置されます。
u4になくu7にあるパッチファイルは以下の4つであり、変更されるファイルはseriesと言うファイルになります。ただし、seriesファイルは当該ディレクトリにあるファイル一覧なので、何が変わったのかについては、実質的には追加されているファイル4つを見れば良いことになります[2]。お手軽に見るのであれば、debianディレクトリ直下のchangelogを見ると、どんな修正がどのファイルを用いて行われているかが書かれています(書かれていないものもありますが……)。
- CVE-2010-5298.patch
- CVE-2014-0076.patch
- CVE-2014-0160.patch
- CVE-2014-XXXX-Extension-checking-fixes.patch
以下、u4とu7のパッチディレクトリにあるファイルのハッシュを取ったリストについて、diffを取った結果を示します。
(2)Heartbleed Bugの修正を見る
2014年4月に発表され、世界中が大騒ぎになったOpenSSLのバグ、Heartbleed Bugについて、u7では修正されています。
実際には、OpenSSL-1.0.1e-2+deb7u5で修正されたものが、u7でも引き継がれたとするのが正しい表現ですが、u7でも修正内容を追いかけることは容易です。
以下がHeartbleed Bugの修正に関するchangelog中の記述になります。
ファイルCVE-2014-0160.patchに修正がまとめられている旨が書かれています。
CVE-2014-0160.patchの行数は、diff形式で112行なのですが、内容は大変読みやすく書かれています。パッチ自体は、実質2つのソースコードに対する修正+CHANGESへの追加を含みます。
内容を見ていると、「本当に急いで作ったパッチなんだな」と言うことを推し量れるのですが、それ以上にパッチ前の内容が「とりあえず動くように作ったんだな」と言うように見えます。
(3)新しいパッケージは機能拡張を含まず、バグ/脆弱性修正を含む
(2)でパッケージの内容を少し紐解きましたが、特定のバージョンのソフトウェアをベースに作られるパッケージは、新しくなっても新機能を取り込むことはありません。しかし、新しいバージョンで行われた脆弱性修正は、パッケージの基にしているバージョンに適用させるような形での移植が行われます。
このような形の移植は、脆弱性修正やバグ修正など、ソフトウェアの本来の機能を阻害する要因を除去することを意図して行われます。このため、APIの変更や機能の変更をはじめとして、バグ修正以上にソフトウェアの動作への影響を及ぼすようなことは原則行いません。
パッケージ入れ替えを行った場合でも、基本的な動作確認は実施されるべきと言う向きはあり、それは当然とも言えるのですが、緊急の脆弱性修正など「入れ替えることを優先する」ような場合には、まずパッケージの入れ替えを行い、不具合などが発生したら古いパッケージに入れ替え直すことを考えるくらいでも良いでしょう。
サービス妨害などはまだマシなほうで、脆弱性の種類によっては、情報漏えいなども普通に発生することが考えられます。Heartbleed Bugの場合は、メモリの内容が漏えいすると言う深刻な脆弱性だったため、脆弱性を含むOpenSSLパッケージを使っていることがわかった場合には、即刻パッケージを入れ替えて様子を見るくらいの対応が適切だったとも言えます。
このあたりは、脆弱性の種類や影響によって対応を決めるのが理想ですが、ある程度以上の危険度や影響が考えられる脆弱性の場合には、即アクションを取れるように事前の取り決めをしておくのも良いでしょう。
4.むすび
今回は、「脆弱性修正」と「パッケージの利用」を主眼に置いて説明を行いましたが、今回の内容をまとめると、以下の3点に集約されます。但し、OSSやFSWでないものについては、ソースコードに施された具体的な修正内容を確認できないことも多いため、更新履歴を確認したり、動作確認を行ったりという話は必要になってきます。
- 脆弱性修正のためにソフトウェアパッケージの利用を行うことで、入れ替えに伴う手間を最小化できる
- ソフトウェアパッケージの入れ替えは、バージョンアップと違って機能追加などの影響はない
- パッケージに含まれる修正は、ソースコードパッケージに含まれるパッチを見ることで明らかに出来る
中身をわかって入れ替えを行うのがベストではあるのですが、そのための時間がない! と言う場合も多いため、とりあえず脆弱性の影響を最小限にするためのパッケージ入れ替えを行い、後で中をきっちり見ると言うのも悪くない選択です。