Snyk をオンプレミス環境と接続する Snyk Broker の紹介と設定例


## はじめに
この記事は、Qiita エンジニアフェスタ 2022 [**「Snykを使って開発者セキュリティに関する記事を投稿しよう！」**](https://qiita.com/official-events/786b978e4a1a28fad312) の参加記事です。

https://qiita.com/official-events/786b978e4a1a28fad312

Snyk Broker に関する日本語情報がまだ少ないの気がするので、書き留めます。

## Snyk Broker とは
Snyk Broker (以下、Broker) は snyk.io と Git リポジトリ間のアクセスをプロキシするためのツールです。

https://docs.snyk.io/features/snyk-broker

対応する Git リポジトリには以下のようなものがあります。

* GitHub Enterprise Server
* GitHub.com
* Bitbucket Server
* GitLab
* Azure Repos

またオンプレミス環境の Jira Data Center や Jfrog Artifactory、コンテナレジストリなどでも使用できます。

:::note info
Snyk Broker は Enterprise plan で利用可能です。Free plan では利用できません。
:::

Broker clinet はユーザーのオンプレミス環境に配置し、Snyk の Broker Server と HTTPS で接続されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/90efb689-4e0d-b2ba-3d31-caf33cb64d4e.png)


Broker を使用すると以下のようなメリットあります。特にエンタープライズユーザーにおいては Snyk を利用するにあたっての使いやすさやセキュリティの向上に繋がります。

* オンプレミスに配置された Git リポジトリ等へのアクセス
* アクセストークンなどの機密データをユーザー NW 内に保持
* ネットワークが制限された環境へアクセス

3 点目について補足します。GitHub Enterprise Cloud などを使用している場合、クラウド環境へのアクセスに IP アドレスベースのアクセス制限を設定しているユーザーも多いと思います。しかし Snyk の IP アドレスレンジは変動するため、ホワイトリストとして登録することができません。

**How can we whitelist Snyk IP addresses?**
https://support.snyk.io/hc/en-us/articles/360002153077-How-can-we-whitelist-Snyk-IP-addresses-

> Outbound requests destined for Snyk are routed over a content delivery network (CDN) which rotates IP addresses and entire IP ranges on an ongoing basis. 

このような環境では接続先がクラウドサービスであっても Broker を使用するメリットがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/545231e7-adac-39bc-0ca7-ee09fd2d40a3.png)


## 使い方
Broker client 単体では Snyk Open Source と Snyk IaC を実行できます。Snyk Code および Snyk Container を Broker 経由で利用したい場合は、それぞれ Code Agent および Container Registry Agent も導入する必要があります。Broker Clinet, Code Agent, Container Registry Agent はコンテナイメージとして提供されます。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/65e394ba-ef5b-0c3b-0883-9d6687acecf5.png)

:::note info
Code Agent は 2022年6月現在ではベータ版として提供されています。
:::

### Docker Compose の例
以下は Docker Compose で Broker client および Code Agent を起動する例です。GitHub Enterprise Cloud に接続し、Snyk Open Source および Snyk Code 使用することを前提としています。

```compose.yaml
services:
  broker:
    image: snyk/broker:github-enterprise
    ports:
      - 8000:8000
    environment:
      - BROKER_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      - GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      - GITHUB=github.com
      - GITHUB_API=api.github.com
      - GITHUB_GRAPHQL=api.github.com
      - PORT=8000
      - BROKER_CLIENT_URL=http://my.broker.client:8000
      - GIT_CLIENT_URL=http://code-agent:3000
      - ACCEPT=/private/accept.json
      - HTTPS_PROXY=http://my.proxy.address:8080
      - HTTP_PROXY=http://my.proxy.address:8080
      - NO_PROXY=code-agent
    restart: always
    networks:
      broker_link:
    volumes:
      - type: bind
        source: "./private"
        target: "/private"
        read_only: true

  code-agent:
    image: snyk/code-agent:latest
    ports:
      - 3000:3000
    environment:
      - PORT=3000
      - SNYK_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      - HTTPS_PROXY=http://my.proxy.address:8080
      - HTTP_PROXY=http://my.proxy.address:8080
    restart: always
    networks:
      borker_link:

networks:
  broker_link:
```

コンテナを起動 (`docker compose up -d`) し、ログを確認します。Broker clinet が Broker server に正常に接続されていれば、以下のようなメッセージが出力されています。

```
"msg":"successfully established a websocket connection to the broker server"
```

Code Agent は起動メッセージが出力されていればひとまず OK です。

```
"msg":"Application started"
```

あとは Snyk の Web UI から GitHub Enterprise Integration の設定にアクセスし、Connected to GitHub Enterprise と表示されていれば完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/254085e9-3076-f3a4-546f-79fba14c96ce.png)


**参考:** Kubernetes 環境で実行したい場合は Helm Chart も公開されています。

https://github.com/snyk/snyk-broker-helm

## スキャンの実行
Web UI で Add project から GitHub Enterprise を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/f5bbc0bd-d0ef-0204-5d51-615387668eed.png)

GitHub Organiozation やリポジトリを選択し、Import を開始できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/518c2138-ace0-6a17-ffe8-cd66627f2fec.png)

:::note info
nodejs-goof は snyk-labs で公開されているデモ用の脆弱な Node.js アプリケーションです。
:::

Import が成功することを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/a2ff5df0-644c-17b5-e493-ec563dc4bbed.png)

Import が成功した場合、Log からは特に Broker 経由の Import であることは確認できませんでした。
(Broker の通信で問題が発生した場合は確認できます。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/254fae71-9689-80a6-ea52-4995a52e56ef.png)

Broker client, Code Agent のログでは対象のリポジトリがインポートできたことを確認できます。

**Code Agent のログ出力例**

```
"msg":"Fetching repo"
"msg":"Cloned repo"
"msg":"Uploaded repo"
```

## 設定の補足
### コンテナイメージ
Broker client の コンテナイメージは接続する SCM ごとに用意されています。GitHub の場合、`snyk/broker:github-com` と `snyk/broker:github-enterprise` が用意されています。サポートにも確認した結果、GitHub Enterprise Cloud を利用するケースでは `snyk/broker:github-enterprise` を使用しています。

```yaml
services:
  broker:
    image: snyk/broker:github-enterprise
```

### アクセストークン
以下のトークンが必要です。

* `BROKER_TOKEN` (for Broker)

  GitHub Enterprise 用の Broker Token を取得するには CSM またはサポートに連絡する必要があります。Token は Snyk Organizations の Settings から確認できます。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/9977d713-54a9-4b35-323e-03117644e78d.png)

* `GITHUB_TOKEN` (for Broker)

  Scope に `repo` の Full Control, `read:org` and `admin:repo_hook` を設定した Personal Access Token を取得します

* `SNYK_TOKEN` (for Code Agent)
  
  Snyk アカウントから API Toekn を取得します

詳細はドキュメントを参照してください。

https://docs.snyk.io/features/snyk-broker/snyk-broker-set-up-examples/setup-broker-with-github-enterprise

https://docs.snyk.io/features/snyk-broker/snyk-broker-code-agent#set-up-code-agent

### Code Agent 利用時の Broker client の設定
Code Agent の構成とは別途、**Broker clinet** の構成に以下のような設定を追加する必要があります。

`GIT_CLIENT_URL` には Code Agent コンテナとポートを指定します。

```yaml
    environment:
      - GIT_CLIENT_URL=http://code-agent:3000
```

Broker および Code Agent 経由で Snyk Code を利用した場合、デフォルトで Snyk の Web UI ではコードスニペットが表示されません。

**Snyk Code のコードスニペットの例 (nodejs-goof のスキャン結果より)**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/e0b00eb2-cd9c-dac5-3e0d-28449e5c748e.png)

コードスニペットの表示を有効にするには必要なルールを記載した `accpet.json` を用意し、コンテナにマウントします。`accpet.json` のパスは環境変数 `ACCEPT` で指定します。

```yaml
    environment:
      - ACCEPT=/private/accept.json
    volumes:
      - type: bind
        source: "./private"
        target: "/private"
        read_only: true
```

`accept.json` は Broker client が Git リポジトリ内のどのファイルにアクセスをすることができるかを定義します。Snyk Open Source を想定した accept.json のサンプルは GitHub に公開されています。こちらに Code Agent のドキュメント通りの定義を追加します。

**accept.json.sample**

https://github.com/snyk/broker/blob/master/client-templates/github-enterprise/accept.json.sample

**Enable code snippets**

https://docs.snyk.io/features/snyk-broker/snyk-broker-code-agent#enable-code-snippets

```diff:accpet.json
+	{
+      "//": "needed to load code snippets",
+      "method": "GET",
+      "path": "/repos/:name/:repo/contents/:path",
+      "origin": "https://${GITHUB_TOKEN}@${GITHUB_API}"
+    }
```

Borker client および Code Agent は同一ネットワーク内を使用する必要があります。共通の Bridge ネットワークを作成し、接続します。

```yaml
    networks:
      broker_link:
```

### プロキシ
borker.snyk.io への接続に企業内のプロキシサーバーを経由する場合は、環境変数 `HTTP_PROXY` および `HTTPS_PROXY` を利用できます。Broker client → Code Agent の通信はプロキシをバイパスする必要があります。`NO_PROXY` 設定をお忘れなく。

```yaml
    environment:
      - HTTPS_PROXY=http://my.proxy.address:8080
      - HTTP_PROXY=http://my.proxy.address:8080
      - NO_PROXY=code-agent
```

以上です。
参考になれば幸いです。