こんにちは。CTOの冨田です。 春になったかと思えば寒くなったり、不安定な天気が続きますね。 Windowsでシステム開発をする場合、Linux仮想マシンやWindows Subsystem for Linux (以下WSL)を利用することも多いでしょう。 WindowsのcmdやPowerShellはバージョンが上がるごとに使いやすくなっていますが、Linuxに慣れた開発者にとっては学習コストが高く感じられます。
kippでは安全なサービスを提供し、情報漏洩を防止するため、従業員の端末の管理やセキュリティ対策にも力をいれています。 現在はMicrosoft Defender for Endpoint (以下MDE)の導入を進めています。 MDEはWindows OS標準添付のセキュリティ機能として知られるMicrosoft Defenderの集中管理バージョンです。 通常のMicrosoft DefenderはWindows固有の機能ですが、MDEはWindowsのほかAndroid、iOS、Linux、macOSでもサポートされている点が優れています。 さらにLinux環境でもソフトウェアインベントリや操作履歴の一部が取得できます。 MDEをすべての環境にインストールし、すべての環境のマルウェア対策を一元管理したいと考えました。
MDEは上述のようにLinuxとmacOSにもインストールできるため現在の従業員の環境をすべてカバーしていると想定していました。 しかし実際にはWSL2上のLinuxはサポートされていません。 WSL2がLinuxをゲストOSとしてのみ動作させることを想定しているため、必要な一部機能が省略されているからです。 今回はいくつかのハックを組み合わせて、通常省略されている機能を復活させ、MDEを動作させることに成功しました。
なお、Microsoft社の公式見解は見つけられませんでしたが、MDEはWSL2のサポートを想定して設計されていないように見受けます。 最悪の場合、ハックを導入したためにベンダー標準の状態で使うよりも脆弱な状態に陥るリスクさえあります。 MDEの導入と安定していてサポートされたWSL2環境のどちらを取るべきか、各自が吟味するべきです。
どうしてMDEが動作しないのか
MDEを動作させるためには、まずサポートしないとされている原因を把握します。 本記事ではホスト環境としてWindows 10を、WSL2のゲストディストリビューションとしてUbuntu 20.04を使います。 サンプルもすべてUbuntu 20.04を利用しています。 Windows 11では一部動作しない恐れがあります。
インストールガイドによれば、適切な準備をしてsudo apt-get install mdatp
を実行すればインストールが完了するとしています。
しかしWSL2の環境で実行するとmdatpのパッケージは展開されるものの、post install scriptsの実行に失敗し、中途半端な状態になってしまいます。
エラーメッセージをよく見ると、systemd
がないためにエラーが起きているとわかります。
systemdは最近の多くのLinux distributionで利用されているinitシステムですが、標準のWSL2環境には存在しません。 スクリプトを動かしたりGCCなどLinuxの開発環境を使う程度であれば必要ないため、省略されているのでしょう。 しかしmdatpのみならずデーモンプログラムやサーバを動かそうとすると、systemdを要求されるケースがあります。
systemdを導入する
systemdはいくつかの方法で導入できますが、現在一番簡単で信頼性が高いのはwsl-distrodを使う方法でしょう。 wsl-distrodは既存のWSL2 distributionに影響を与えず、linuxcontainers.orgから新しいイメージを展開するオプションがあるので、非破壊的に導入できます。 導入方法自体もとても簡単です。 Windows上でexeファイルをひとつ実行し、CLIインタフェースでいくつかの質問に答えるだけです。 いくつかの導入方法がありますので、上のリンクから公式情報を確認してください。
導入に成功すると、ps -aux
等で全プロセスを表示したときPID1で/usr/lib/systemd/systemd
が動作していることを確認できます。
auditを有効にする
systemdが動いている状態でmdatp
のインストールを再試行すると、audit
がサポートされていないというエラーに変わりました。
Error - audit support not in kernel Cannot open netlink audit socket
auditd
を調べると、この機能はパッケージマネージャなどでインストールできるものではなく、カーネル設定で有効にしなければならないと分かります。
さらに調べると、WSL2カーネルをビルドし上書きする方法が見つかりました。
この記事のなかで.config
ファイルを編集していますが、これはカーネルのビルドオプションを指定するファイルです。
このファイルでCONFIG_AUDIT=y
を指定すればaudit機能が有効になりそうです。
実際に手順に沿ってビルドするとカーネルイメージ(bzImage)が出力されます。
Linuxカーネル全体をビルドする作業なので、マシンスペックによりますが30分程度かかります。
このbzImageを一旦Windowsのファイルシステムに待避し、C:\Windows\System32\lxss\tools
にあるkernel
というファイルを置き換えます。
WSL2で起動するすべてのdistributionのカーネルが置きかわるようです。
実際にこの手順を行ったあと、mdatpを再インストールすると今度は成功しました。
systemctl status auditd
で確認するとauditdも動作しています。
さらにMDEのインストール手順を最後まで進めると、無事テストウイルスファイルに対して検疫が発動することを確認できました。
カーネル生成の自動化
この導入手順では通常のWSL2環境にくらべてsystemdの導入、カーネルのカスタムコンパイルという2つの余計なことをしています。 余計なことをした部分は通常よりインセキュアになっていると考えるべきです。
リスクを詳しく分析すると、systemdやdistrodに脆弱性がある場合と、カーネルに脆弱性がある場合に特に深刻な影響を受けるとわかります。 systemdとdistrodは配布されているものをそのまま利用しているのでそれぞれの脆弱性情報を確認しパッチを適用すればよいでしょう。
しかしカーネルについてはオリジナルのものを使っているため、通常配布されているバイナリを利用できません。
WSL2にはwsl --update
というカーネルファイルを更新する機能が実装されていますが、この更新を利用するとauditdが利用できなくなるでしょう。
かわりに自分達で常に最新のカーネルをビルドし、利用するプロセスを確立する必要があります。
今回はGitHub Actionsを使って定期的な自動ビルドを実装しました。 kipp-corp/wsl2-kernel-with-auditはシンプルなworkflowだけが定義されているリポジトリです。 ビルドスクリプトが上のビルド方法をGitHub Actions上で実行する定義になります。 実行結果はActionsの履歴から確認でき、ビルド成果物のカーネルファイルもダウンロードできます。
LinuxカーネルやWSL2カーネルの脆弱性情報を確認し、更新が必要なときここからダウンロードして利用できます。 新しいメンバーが増える時でも秘伝のタレを伝授するかわりに公開された信頼できるソースを提示できます。
最後に
今回は実験的な試みとして、WSL2上のUbuntuでMDEを動かしてみた過程をまとめました。 また長期的に運用する上で課題となりうる部分を検討し、自動化まで達成しました。
kippはアプリケーション開発に留まらず、コンピュータサイエンスやセキュリティの幅広い知識をお持ちの開発者と一緒に働きたいと考えています。
情報管理やセキュリティの取り組みに関心をお持ちの方はpeople@kipp-corp.com
までぜひお気軽にご連絡ください。