Dockerがマルウェア判定された原因と解決方法

こんにちは。エンジニアのKennieです！
少し前に、macOS環境のDocker Desktopバージョン4.32から4.36において、Dockerがマルウェアと誤判定され、ゴミ箱への移動を促される問題が発生しました。今回は、その原因と解決方法を詳しく解説します。

https://docs.docker.com/desktop/cert-revoke-solution/?_gl=1*2h8wz5*_gcl_au*NTQzMDQ0ODUyLjE3NDEzMTg4MDY.*_ga*MTE4OTAyNzM2Ni4xNzQxMzE4ODA2*_ga_XJWPQMJYHQ*MTc0MTMxODgwNS4xLjEuMTc0MTMxODgwNi41OS4wLjA.#install-a-patch-if-you-have-version-432---436

## 問題の原因

多くのユーザーがこの問題に直面し、`com.docker.vmnetd` と `com.docker.socket` の[証明書に不具合](https://github.com/docker/for-mac/issues/7527)が発生していました。この証明書の不具合は、macOSセキュリティ機能であるGatekeeperによって引き起こされた可能性があります！

### Gatekeeperによる証明書の取り消し

GatekeeperはmacOSのセキュリティ機能で、アプリケーションのマルウェアを検証し、定期的にバックグラウンドでセキュリティアップデートを行い、再検証を実施します。アプリケーションが不正なものと判定されると、その証明書は無効化され、「取り消しチケット（revocation ticket）」が発行されます。

今回、Dockerに含まれるファイルがマルウェアと誤判定されたことにより、取り消しチケットが発行され、アプリケーションの証明書が無効化された可能性があります。その結果、Dockerの起動が阻止され、「コンピュータが破損する可能性があります」といった通知が表示されたと考えられます。

### 証明書の確認

自分の環境でも影響を受けているか確認することにしました。

**1. `check.sh.txt`ファイルを、以下のページからダウンロードします。**

https://github.com/docker/for-mac/issues/7527

**2. ダウンロードしたファイルの名前を`check.sh`に変更します。**
**3. ダウンロードしたスクリプトファイルに実行権限を付与するために、ターミナルで以下のコマンドを実行します。**

```bash
chmod +x check.sh
```

**注意:** インターネットからダウンロードしたシェルスクリプトをそのまま実行するのは危険なので、必ず内容を確認してから実行してください。

**4. 以下のコマンドを実行して、証明書の状態をチェックします。**

`com.docker.vmnetd`と`com.docker.socket`の証明書の確認を行います。下記は、Dockerをすでに再インストールした後の環境で行っているものなので、成功した例として`is signed with a correct certificate`がスクリプトの結果として表示されます。

`com.docker.vmnetd`の証明書の確認

```bash
$ ./check.sh /Library/PrivilegedHelperTools/com.docker.vmnetd
-----------------------------------------------------------------
Certificate details for com.docker.socket:
 serial=3EC22E699630083A
 subject=UID=9BNSXJN65R
 CN=Developer ID Application: Docker Inc (9BNSXJN65R)
 OU=9BNSXJN65R
 O=Docker Inc
 C=US
 issuer=CN=Developer ID Certification Authority
 OU=Apple Certification Authority
 O=Apple Inc.
 C=US
 notBefore=Oct  2 16:46:37 2024 GMT
 notAfter=Feb  1 22:12:15 2027 GMT
-----------------------------------------------------------------

com.docker.socket is signed with a correct certificate
```

`com.docker.socket`の証明書の確認

```bash
$ sudo ./check.sh /Library/PrivilegedHelperTools/com.docker.socket
-----------------------------------------------------------------
Certificate details for com.docker.vmnetd:
 serial=3EC22E699630083A
 subject=UID=9BNSXJN65R
 CN=Developer ID Application: Docker Inc (9BNSXJN65R)
 OU=9BNSXJN65R
 O=Docker Inc
 C=US
 issuer=CN=Developer ID Certification Authority
 OU=Apple Certification Authority
 O=Apple Inc.
 C=US
 notBefore=Oct  2 16:46:37 2024 GMT
 notAfter=Feb  1 22:12:15 2027 GMT
-----------------------------------------------------------------

com.docker.vmnetd is signed with a correct certificate
```

スクリプトを実行した結果が`is signed with a correct certificate`でなければ、証明書に不具合があることになります。

Dockerを再インストールする前に、自分の環境でスクリプトを実行した結果では、証明書に不具合があることを確認できました。

## 解決方法

マルウェアと誤判定を受けないように修正され、有効な証明書を保持するDockerの新しいバージョンがリリースされたため、Dockerを再インストールしました。

その前に、Dockerを完全にパソコンから削除する必要がありました。

Dockerを完全に削除するには、まずアプリケーションフォルダにある`Docker.app`を削除します。これにより、DockerのGUIアプリケーションが削除されます。

関連する設定ファイルやシステムコンポーネントは残っているため、以下のコマンドを実行して、Dockerに関連する設定やデーモンを完全に削除します。

```bash
rm -rf ~/.docker
sudo rm -f /Library/LaunchDaemons/com.docker.socket.plist
sudo rm -f /Library/LaunchDaemons/com.docker.vmnetd.plist
sudo rm -f /Library/PrivilegedHelperTools/com.docker.socket
sudo rm -f /Library/PrivilegedHelperTools/com.docker.vmnetd
```

Dockerの削除が完了したら、[公式サイト](https://docs.docker.com/desktop/setup/install/mac-install/)から4.37.2のバージョンをインストールして解決しました。

## あとがき

突然ポップアップが表示され、「コンピュータが破損します」と書かれていて驚きましたが、公式の手順に従ってDockerを再インストールすることで問題が解決してよかったです。

## 参考にしたもの

https://docs.docker.com/desktop/cert-revoke-solution/?_gl=1*2h8wz5*_gcl_au*NTQzMDQ0ODUyLjE3NDEzMTg4MDY.*_ga*MTE4OTAyNzM2Ni4xNzQxMzE4ODA2*_ga_XJWPQMJYHQ*MTc0MTMxODgwNS4xLjEuMTc0MTMxODgwNi41OS4wLjA.#install-a-patch-if-you-have-version-432---436

https://github.com/docker/for-mac/issues/7527

https://github.com/docker/for-mac/issues/7531#issuecomment-2580595610

https://support.apple.com/ja-jp/guide/security/sec469d47bd8/web