JFrog Japan Blog

DevOpsを加速する、JFrog日本法人メンバーによるブログです。

JFrog ArtifactoryやXrayといった自社ツールはもちろん、CI/CDやコンテナ技術(DockerやKubernetes)などDevOpsの一般的な内容も扱います。その他、日本でのDevOps事例紹介やお楽しみコンテンツも掲載予定です。 JFrogならではの面白くて役に立つブログを目指しますので、お楽しみに!

GradleでJFrog Artifactory越しに依存解決する #MavenCentral #JCenter

1月ももう終わりますが、あけましておめでとうございます。デベロッパーアドボケイトのよこなです。

JFrog Artifactoryは自分たちのアーティファクト(バイナリファイル)を保管する以外に、外部レジストリ(Maven Central, Docker Hubなど)からライブラリのアーティファクトを取得する際の仲介役としても使えます。Artifactoryを経由することで、一度取得したことのあるアーティファクトを保存しキャッシュとして活用できる他、様々なメリットがあります。

このエントリではGradleを使って依存解決する方法を紹介します。
Artifactoryを導入するなら依存解決以外にも活用するのがオススメ(本音)ですが、まずはここから始めてみるパターンも大いにアリだと思う(これもまた本音)ので、依存解決だけにフォーカスして書いていきます。おそらく、JCenterを使い続けたい方にはぴったりの内容かなと思います (参考: Bintray、JCenter、GoCenter、ChartCenterのサービス終了) 。
公式Wikiもあるものの、細かいことまで書かれているので「結局どうしたらいいの」となった方に贈る記事です!

手順

Artifactoryを利用できる状態にする

既にお使いのArtifactoryがあればそちらをお使いいただき、なくて試してみたい場合は無料なのでお気軽に登録してみてください。 jfrog.com

リモートリポジトリを作成する

Artifactoryで使えるリポジトリには種類がある中、依存解決に利用するのは「リモートリポジトリ」です。
今回はリモートリポジトリだけ作りますが、この手順も既にお持ちのものがあればスキップしてください。

f:id:ihcomega:20220128165045p:plain
リモートリポジトリ作成

右上のメニューからGradle用のリモートリポジトリを作成します。リポジトリの名前は xxx-gradle-maven-remote xxx-gradle-remote (xxxはアプリケーションやプロジェクトの名前) など、パッケージ・リポジトリの種類が分かる形がオススメです。
URLは次の値を入れてください。

使うリポジトリ URL
Maven Central https://repo.maven.apache.org/maven2
Google https://maven.google.com
JCenter https://jcenter.bintray.com

ビルドスクリプト (build.gradle) を更新する

Artifactoryを使っていない場合、次のような記述でリポジトリを指定しますよね。例えば次のような記述だと、基本的にはMaven Central -> Googleの順でアーティファクトを探しにいって依存解決します*1

buildscript {
    repositories {
        mavenCentral()
        google()
    }
}

ここでArtifactoryを使う場合、記述はこうなります。なお、紹介している設定ファイルはArtifactoryからダウンロードできます(後述)。

repositories {
  maven {
    url "${artifactory_url}"
    credentials {
      username = "${artifactory_user}"
      password = "${artifactory_password}"
    }
  }
}

変数は gradle.propertiesなどを使って埋め込んでください。

変数
artifactory_url https://yyy.jfrog.io/artifactory/xxx-gradle-maven-remote形式のURL
(https://【ArtifactoryのURL※ご自身で設定したサーバーIDを含むもの】/artifactory/【リモートリポジトリ名】)
artifactory_user Artifactoryのユーザー
artifactory_password ArtifactoryのパスワードまたはAPI Key

設定はこれだけ!あとはいつものとおり依存解決 (gradle buildとかgradle assemble) すればArtifactoryを経由するようになります。ということで最低限必要なのはここまでで、残りは補足やお役立ち情報です。

Artifactoryから設定ファイル (build.gradlegradle.properties) をダウンロードする

上記の設定ファイルは自分で記述しなくてもダウンロード可能ですが、現状だと依存解決以外に必要な設定もまとめて入ってくる形になっています。記述量はさほど多くないので、必要なものだけ取り入れてシンプルさを保つために自分で書いてしまうのも手だと思います。

f:id:ihcomega:20220128173548p:plain
「Artifacts」ビューで右上の「Set Me Up」を選択する

f:id:ihcomega:20220128182407p:plain
リモートリポジトリを選択する + ダウンロードする設定ファイルにクレデンシャル情報を含めたい場合はパスワードを入力する

f:id:ihcomega:20220128182454p:plain
「Generate Settings」をクリックする

f:id:ihcomega:20220128173755p:plain
ファイルのダウンロードまたはテキストのコピーをして使う

不要な設定に要注意

Artifactoryからダウンロードされるファイル、またウェブ上にある古い記事には artifactory.resolve.repotitories という設定が含まれている場合があります。実は冗長な設定で不要なので削除していただいても動作します *2

f:id:ihcomega:20220128181612p:plain

複数の外部リポジトリを使う

1つのリモートリポジトリに設定できる外部リポジトリは1つです。しかし、依存解決にMaven CentralもGoogleもJCenterも使いたいケースも多々あるでしょう。その場合は必要な数だけリモートリポジトリを作って、「バーチャルリポジトリ」でまとめます *3
バーチャルリポジトリは複数のリポジトリを束ねて仮想的に1つのリポジトリに見せる機能です。要はインタフェースの役割を果たしてくれ、ユーザーはその裏側にあるリポジトリの構成を意識せずに使うことができます。

こちらは右上のメニューでバーチャルリポジトリ作成を選べます。名前は xxxxxx-virtual とし、まとめたいリポジトリをすべて選択すればOKです。このとき、UI上でリポジトリが並ぶ順番に応じて依存解決先が決まります。

  • example-gradle-remote-mavencentral (Maven Centralにアクセスするリモートリポジトリ)
  • example-gradle-remote-google (GoogleのMavenリポジトリにアクセスするリモートリポジトリ)
    の2つを用いた次の例ではMaven Central -> Googleの順に優先されるというわけです (リポジトリ名長くて切れちゃってますが)。

f:id:ihcomega:20220128180355p:plain
バーチャルリポジトリを使って複数のリモートリポジトリをまとねる

以上です〜!これで取得したライブラリのアーティファクトがArtifactoryにたまっていきます。冒頭で説明したとおりキャッシュの役割を果たすので時間短縮が期待できたり、JFrog Xrayを使ってセキュリティスキャンができたり、便利なことも多いのでぜひ試してみてください!

*1:参考: Declaring repositories, 第60章 ビルドロジックの体系化など

*2:サービス上で不要な記述が「Set Me Up」から消えるよう社内でフィードバック中なので、将来のアップデートで直ります

*3:ビルドスクリプトに全リモートリポジトリを羅列することも可能ですが、リポジトリに変更があったときのメンテナンスが楽なのでバーチャルリポジトリの利用がオススメです

JFrog 製品と Apache Log4j 2 の脆弱性に関して

(このブログは GENERAL: JFrog Services Are Not Affected by Vulnerability CVE-2021-44228 の日本語訳および補足です)

On 10 December 2021, a RCE (remote code execution) exploit was exposed on several versions of the Apache Log4j 2 utility. Affected code exists in log4j core libraries: log4j-core-*.jar, versions 2.0 to 2.14.1.

2021年12月10日 Apache Log4j 2 ユーティリティのいくつかのバージョンで、RCE(リモートコード実行)の脆弱性が公開されました。 影響を受けるコードは log4j コアライブラリ: log4j-core-*.jar のバージョン2.0~2.14.1 です。

Following internal research and validation by the JFrog Security and R&D teams, we can confirm that JFrog services are not affected by this vulnerability (CVE-2021-44228). First, we have validated that JFrog services are not configured to implement the log4j-core package. Additionally, we can confirm that the JDK version used in JFrog services (e.g. Artifactory) contains default protection against remote class loading via JNDI objects. Therefore, no action is required by JFrog customers regarding this issue for JFrog solutions.

JFrog セキュリティチームと R&D チームによる内部調査と検証の結果、JFrog のサービスがこの脆弱性(CVE-2021-44228)の影響を受けていないことが確認できました。まず、JFrog のサービスが log4j-core パッケージを利用するように設定されていないことを確認しました。さらに JFrog サービス(Artifactory など)で使用されている JDK のバージョンには JNDI オブジェクトを介したリモートでのクラス読み込みに対するデフォルトの保護機能が含まれていることを確認しています。したがって、この問題に関して JFrog のお客様が特別に何か対処する必要はありません。

JFrog Security and Xray product teams have updated the Xray database with CVE information regarding this vulnerability, and this information will be available for Xray customers to assist in detection and remediation across customer portfolios.

JFrog Security と JFrog Xray製品チームは、この脆弱性に関する CVE 情報をすでに Xray データベースに更新済みです。つまり JFrog Xray をご利用のお客様は、すぐにアプリケーション全体でこの脆弱性の検出および修正の支援を受けることが可能です。

※ JFrog Xray に関して詳細を知りたい方は下記ウェビナー及びプレゼン資料を参照ください。

www.youtube.com

speakerdeck.com

JFrog has examined and validated that none of the following products reference the vulnerable libraries:

Artifactory 6.x and 7.x, and the accompanying Access service

Distribution

Mission Control

Insights

JFrog は以下の製品が脆弱性のあるライブラリを参照していないことを調査・確認しました。

  • JFrog Artifactory 6.x および 7.x、ならびに付随する Access サービス
  • JFrog Distribution
  • JFrog Mission Control
  • JFrog Insights

(訳注)JFrog Xray がリストにないのは JFrog Xray は Go で実装されているためです!

【Google Cloud Build & JFrog Artifactory + Xray + CLI】Dockerイメージを自動でビルド・保存・セキュリティスキャンする

こんにちは、デベロッパーアドボケイトのよこなです。もう9月ですね。な〜つのお〜わ〜り〜

ソースコードだけじゃなくてアーティファクトを専用リポジトリで保存しましょう!
という話をよくするのですが、最近はもはやおまじないであっという間に「ソースコード→デプロイ」の過程を終えられる便利ツールが増えていますよね。「アーティファクトを取っておくと言っても、コマンド叩いたらサーバーまで行っちゃうんだけど…」と思われる方もいらっしゃるかもしれません。

この記事ではGCPとJFrog Platformを組み合わせた例を使って、アーティファクトの保管・セキュリティスキャンを行います。

☝やりたいこと

f:id:ihcomega:20210904124728p:plain

  1. Dockerで動くアプリケーションをビルドする
  2. アーティファクトをJFrog Artifactoryに保存する
  3. Artifactory上のアーティファクトにセキュリティスキャンをかけ、問題ない場合のみビルドを正常終了させる

この流れをCloud Build (CI/CDツール) 上で実現します。デプロイするところまで書こうかと思ったのですが、上記だけで超大作になったため別記事にします。
記事が長いので身構えるかもしれませんが、動かしたいアプリもない、クラウド環境もない、JFrogサーバーもないというゼロからの状態で始めて丁寧に説明しているからなのでご安心を。実際は既存で使っているものをカスタマイズすることになると思うのでもうちょっと気楽にお試し頂けるかと思います。
例えば既にCloud Buildでコンテナイメージのデプロイをしている場合はちょっとステップを追加するだけで脆弱性のスキャンができるようになります!必要に応じ読み飛ばしながらご活用ください🐸

☝Frogに関する前提知識

  • JFrog Artifactory: アーティファクト(今回はDockerイメージ)を保存するためのリポジトリ。
  • JFrog Xray: いわゆるSCAツール。Artifactoryと連携し、アーティファクトが依存するOSSに脆弱性やライセンス違反がないかをスキャンする。

☝コンテナ化されたアプリケーションを用意する

今回デプロイするアプリケーションはこちらです。JavaとSpring bootというフレームワークで作りました。アプリの作り方は詳細割愛しますが、Springの公式ドキュメントを参考にしました。
github.com

実行・アクセスすると Hello Docker World! と返せるだけのシンプル・サンプルアプリケーションです。
f:id:ihcomega:20210903165717p:plain

☝JFrog Artifactory上にDockerイメージ用のリポジトリを作成する

JFrog SaaS版の利用を開始する

jfrog.com

ここから登録してJFrog Platformが使える状態にしてください。
Name Your Environment*欄はお好きな値を指定していただけばOKです(既存の別のサーバーと重複はNG)。それがURLになり、後々Cloud Build側の設定にも使います。

リポジトリを作成する

アカウント作成して初回ログイン(これ以降、admin権限があるユーザーを使ってください)をしたら、そのままリポジトリも用意しちゃいましょう。

  • リモートリポジトリ
  • ローカルリポジトリ
  • バーチャルリポジトリ

の3つを作成します。以前は別々に作成する必要があったのですが、最近まとめて3つ作れるようになったので結構楽ちんです。

f:id:ihcomega:20210903130807p:plain
最初のログイン後表示される画面で「Docker」を選択する

f:id:ihcomega:20210903131037p:plainf:id:ihcomega:20210903131104p:plain
プロジェクト名を入れてリポジトリを作成する

今回は雑(サンプルとしては分かりやすいとも言う)ですが、springという名前を指定しました。spring-docker-local, spring-docker-remote, spring-dockerという3つのリポジトリが爆誕します。

リポジトリをXrayでスキャンできるよう設定する

スキャンには時間がかかるので、予めインデックスを追加しておくことでいざスキャンの命令が来たときに素早く結果を返せるようにしておきます。

f:id:ihcomega:20210903154145p:plain

リポジトリの設定画面からローカル・リモートリポジトリに対してEnable Indexing in Xrayを有効にする設定を入れてあげればOKです。ローカルとリモートを束ねる存在であるバーチャルリポジトリには設定不要です(そもそも設定項目がありません)。

f:id:ihcomega:20210903154554p:plainf:id:ihcomega:20210903154557p:plain
ローカルもリモートも似た画面で設定する

☝Cloud Buildでビルドできるようにする

Google Cloud上にプロジェクトを作成(手順)済みの状態で始めましょう。今回の例では「My First Project」を作りました。

ビルドを定義する設定ファイルcloudbuild.yamlを作成する

さて、ビルドの準備を進めていきますが、基本的には公式ドキュメントが詳しいし分かりやすいです。
cloud.google.com

サンプルアプリケーションのプロジェクトルートにcloudbuild.yaml (Cloud Build上で自動で実行したいことを書き連ねていく設定ファイル)を追加します。完成形はGitHub上のファイルをご確認ください。
では、まずはDockerイメージをビルドしてタグをうつところまで。

steps:
  - name: 'gcr.io/cloud-builders/docker'
    entrypoint: 'bash'
    args:
    - '-c'
    - |-
      docker build --build-arg JAR_FILE==build/libs/*.jar -t gcr.io/$PROJECT_ID/spring-boot-docker .
      docker tag gcr.io/$PROJECT_ID/spring-boot-docker:latest ${_JFROG_PLATFORM_URL}/spring-docker/spring-boot-docker:latest

公式ドキュメントと異なるのはentrypointを指定してbash -cでコマンドをまるごと渡せるようにしているところです。これで、ひとつのステップで2行コマンドを実行できます(参考: bash スクリプトの実行)。
コマンド内の$PROJECT_IDはプロジェクトIDに置換される変数で、Cloud Buildが標準で提供しているものです。一方、${_JFROG_PLATFORM_URL}は独自で設定する環境変数です。値の設定方法は後ほど見せますが、ここではArtifactoryのURLをCI実行時に埋め込むようにしています。

ここまで出来たらgcloudコマンドが使えるようCloud SDKをインストール(手順)して、プロジェクトルートで次のコマンドを実行すればCloud Buildを動かすことができます。

gcloud builds submit

結果はそのままターミナルで確認できますが、Cloud Buildのコンソールにて「履歴」を見ることも可能です。

f:id:ihcomega:20210903054042p:plain
コンソール上で確認できるビルド履歴

ビルドのトリガーを設定し、自動でビルドが実行されるようにする

先に設定ファイルを書ききってもいいですが、いったん何らかのイベントをきっかけにCloud Build上で自動ビルドが走るように設定しちゃいましょう。ローカルでコマンドを打たなくて良いので動作確認も楽になります。

今回はspring-boot-dockerリポジトリのmainブランチに変更が入ったらビルドするという設定にします。Cloud Buildのコンソールで「トリガー」ページを開きます。

f:id:ihcomega:20210903054345p:plain

先に最終形をお見せするとこんな感じです。

f:id:ihcomega:20210903123638p:plain

GitHubと初めて連携する場合、リポジトリを指定するところでGitHubとの行き来が発生します。認証を行い、使うリポジトリにGoogle Cloud Buildのツールを入れましょう。

f:id:ihcomega:20210903130158p:plain

また、変数をセットするのもポイントですね。今回は次の2つを設定しておいてください(参考: 変換値の置換)。

変数名
_JFROG_PLATFORM_URL JFrog Platform登録時に指定したサーバー名を含むURL(xxx.jfrog.io)
_JFROG_PLATFORM_USER JFrog Platformのログインユーザー(メアド)

f:id:ihcomega:20210903134041p:plain

☝Cloud BuildからArtifactoryへDockerイメージを保存する

Cloud Build上でさっきビルドしたイメージをArtifactoryへ保存するための設定をしていきます。

JFrog PlatformのAPI KEYをCloud Key Management Serviceで暗号化する

まずはJFrog Platformで認証するためのAPI KEYを発行し、クリップボードにコピーしてローカルで使えるようにします。

f:id:ihcomega:20210903133112p:plainf:id:ihcomega:20210903133122p:plain
右上のメニューからプロフィールページへ行くと発行できる

続いて、今取得したAPI KEYを暗号化します。そうすることで、cloudbuild.ymlに(暗号化した)値を直接書いて安全に使うことができるようになります。

公式ドキュメントを参考にしつつ、暗号化するための鍵を作る2ステップを実施します。

gcloud kms keyrings create [KEYRING-NAME] --location=global
gcloud kms keys create [KEY-NAME] --location=global --keyring=[KEYRING-NAME] --purpose=encryption

[KEYRING-NAME](Keyring = 簡単に言うと鍵のグループ)と[KEY-NAME](Key = 鍵)は自分で決めます。サンプルではそれぞれspring-docker-keyring, key-exampleとしました。これらの値はこの後cloudbuild.yamlでも使います。

これで鍵が作成されたので、それを使って暗号化します。さっきクリップボードにコピーしたAPI_KEYをローカルの環境変数$RT_API_KEYに設定した上で、次のコマンドを実行します。3つ目のコマンドを実行すると返ってくる値こそが暗号化したAPI KEYなので、控えておいてください(まぁ紛失してもまたコマンドを実行すればOKです)。

echo $RT_API_KEY | gcloud kms encrypt --plaintext-file=- --ciphertext-file=- --location=global --keyring=[KEYRING-NAME] --key=[KEY-NAME] | base64

暗号化した値を復号できるよう設定する

暗号化した鍵はビルド実行時に復号したいので、Cloud Buildに復号の許可を与えます。Cloud Buildのコンソールより「設定」画面で変更してください。
f:id:ihcomega:20210903140608p:plain

おそらくこのときに「APIを有効にしてね」という別画面が立ち上がると思うので、画面に従って設定しましょう。

f:id:ihcomega:20210903145443p:plainf:id:ihcomega:20210903145451p:plain
KMS APIを有効にする

設定ファイルで暗号化したAPI KEYを使えるよう追記する

ようやく準備が整ったので、cloudbuild.yamlに追記します。まずはファイルの末尾に暗号化したAPI KEYを追記しましょう。[]で覆われた値は上の手順にある鍵発行・暗号化時に得たものに差し替えてください。

secrets:
  - kmsKeyName: projects/dark-hall-324609/locations/global/keyRings/[KEYRING-NAME]/cryptoKeys/[KEY-NAME]
    secretEnv:
      APIKEY: '[暗号化されたAPI KEY]'

つまり私のサンプルバージョンだとこんな感じになります。

secrets:
  - kmsKeyName: projects/dark-hall-324609/locations/global/keyRings/spring-docker-keyring/cryptoKeys/key-example
    secretEnv:
      APIKEY: 'CiQAy/L6lVzsfbJqvTbOInV71GDrfUnHFPMbclD7a45xkGgsXlkScwAbTXpQ7gUCXwLhVYLC9BaGcGx7KmaSjuIaErsNQ7CacG/Jetll1xpDc/ITCAr+WrCZqYSktGWyvmE4zSBct9cMWPdVgPnoc1mmOst9iiD1S8G9QeCu8xY9XFYJq/T5K+Cu5lchGtAfWRNB8c1QA58/Qk4='

JFrog CLIを使ってDockerイメージをArtifactoryへ保存する

続いて、ArtifactoryへにDockerイメージを保存するためのステップを追加します。やっとこの記事の肝にたどり着きました…。

ググるとGoogle Cloud Blog - News, Features and Announcementsっていう公式の記事もあるんですが、

  • 最新のJFrog CLIのバージョンがv2になっていること
  • かつてCLIのイメージを取得する先であったbintrayはサービス終了していること
    をふまえると、次のような記述が良いでしょう。
  - name: 'releases-docker.jfrog.io/jfrog/jfrog-cli-v2'
    entrypoint: 'bash'
    args:
    - '-c'
    - |-
      apk add docker-cli
      jfrog c add my-jfrog-server --url=https://${_JFROG_PLATFORM_URL}/ --user=${_JFROG_PLATFORM_USER} --password=$$APIKEY
      jfrog rt dp ${_JFROG_PLATFORM_URL}/spring-docker/spring-boot-docker:latest spring-docker --build-name=spring-boot-docker-build --build-number=${BUILD_ID} --server-id=my-jfrog-server
      jfrog rt bce spring-boot-docker-build ${BUILD_ID}
      jfrog rt bp spring-boot-docker-build ${BUILD_ID}

jfrog-cli-v2イメージを使用することでCLIを有効にし、jfrogコマンドが使えるようにします。

CLIの使い方はやりたいことに応じてご確認いただくのが1番ですが、今回使っているコマンドについては説明します。
www.jfrog.com

apk add docker-cli

(当然これはJFrog CLIじゃないですが、準備として必要なので補足します)

  • Cloud Build上ではCLIもコンテナで動いているわけですが、そのコンテナからDockerイメージをプッシュするためにDockerクライアントが必要です。
  • Alpine(CLIのDockerコンテナで動いている軽量のLinux)にapkというパッケージマネージャーでDockerクライアントをインストールしておきます。

jfrog c add

  • cconfigのことです。この記事の上の方で作ったJFrogのサーバーを指定し、認証しておきます。
  • CLIにおいてJFrogのサーバーを一意に識別するため、my-jfrog-serverという名前をここでつけています。

jfrog rt dp

  • rtはArtifactoryを操作するコマンド、dpdocker-pushの略です。直前に設定したmy-jfrog-serverという名前でサーバーを指定し、そこに対してdocker pushしています。
  • この作業でspring-boot-docker-buildという名の「ビルド」という塊を作っているのですが、この後セキュリティスキャンをする際もこのビルドに対して操作を行います。
  • spring-dockerは前半で作成したバーチャルリポジトリの名前で、プッシュ先として指定しています。バーチャルリポジトリに対してプッシュするとアーティファクトはローカルリポジトリに保存されます*1
  • ビルドを識別するためにIDを振る必要があるので、今回はCloud Buildが標準で提供してくれている変数$BUILD_IDを使いました。シーケンシャルな番号を振るとかでも良いです。

jfrog rt bce

  • bcebuild-collect-env の略で、次のステップ (jfrog rt bp) を実行する前の準備としてbuild info (アーティファクトの詳細や依存関係、サーバーの環境変数などビルドの付加情報) を収集します。

jfrog rt bp

  • bpbuild-publishを意味しており、これを実行するとビルド実行時のbuild infoがArtifactory上に一緒に保存されます。

上記の設定を反映してGitHubにプッシュすると、トリガーの設定がうまく行っていればCloud Buildが実行されるはずです。

f:id:ihcomega:20210903143759p:plain
ArtifactoryのBuildsに行が増えていればイメージの保存成功

f:id:ihcomega:20210903144119p:plain
build info

ビルドをXrayでスキャンできるよう設定する

作成したビルドにもXrayのインデックスを追加しておきましょう。AdminメニューのXray SettingsでIndexed Resourcesを開き、Buildタブで操作します。

f:id:ihcomega:20210903161241p:plainf:id:ihcomega:20210903161238p:plain
Xray設定画面からスキャンしたいビルドを追加する

Manage Indexをクリック後に開く画面でspring-boot-docker-buildを追加すれば完了です。
f:id:ihcomega:20210903161632p:plain

☝JFrog Xrayでスキャンする

無事ビルドを作成できたのでXrayを使ってスキャンします。無料版では脆弱性のスキャンのみが使えるので、やっていきましょう。

その前にXray用語をごく簡単に紹介します。

  • ルール: チェックのレベルを定義します。「どの緊急度まで検知するか」「検知したら誰にどうやって通知するか」「検知した場合、そのアーティファクトの利用を許可するか」などを決めます。CVSSのスコアにも対応しています。
  • ポリシー: ルールを束ねてスキャンの方針を示すようなものです。後述のウォッチと紐付けて使います。
  • ウォッチ: ポリシーをどのビルド, リポジトリ*2に適用するかを定義します。

ということでルール, ポリシー, ウォッチを用意します。

f:id:ihcomega:20210903152038p:plain
adminメニューのXray設定画面を開く

ポリシー・ルールを追加する

f:id:ihcomega:20210903152127p:plain
ポリシーの作成画面からRuleを作成していく

ルールの作成画面はこのように細かい決まりを定められます。今回は例として

  • 緊急度がHigh以上なら検知する
  • 検知をしたらCIでのビルドを失敗させる(Fail Buildにチェックを入れるとそうなります)
    という設定を入れてみます。

f:id:ihcomega:20210903152424p:plainf:id:ihcomega:20210903152431p:plain
実現したいことをルールで表現する

ルールが追加できたらポリシーを保存しましょう。

f:id:ihcomega:20210903152924p:plain

ちなみに、なぜ1つのポリシーに複数のルールが設定できるのかについてはユースケースの例を挙げると分かりやすいかもしれません。
例えば「緊急度がHigh以上ならビルドを失敗させたいけど、Medium以下ならとりあえずメールで通知してほしい」場合は、今行った設定に加えて、Mediumならばメール通知するというルールを足してあげればOKです。

ウォッチを作成する

ポリシーを作った画面で隣のWatchesタブから操作できます。

f:id:ihcomega:20210903161717p:plain

ウォッチはポリシーとビルドを紐付けるものです。どのリポジトリのどのビルドに対しどのポリシーでXrayスキャンを行うかここで指定してください。

f:id:ihcomega:20210903161925p:plain

それぞれプラスボタンを押して、追加画面でポチポチ選択していきます。

f:id:ihcomega:20210903162108p:plainf:id:ihcomega:20210903162101p:plainf:id:ihcomega:20210903162104p:plain
リポジトリ、ビルド、ポリシーを追加する

f:id:ihcomega:20210903162706p:plain
無事追加できたら設定完了

JFrog CLIを使って保存したDockerイメージにセキュリティスキャンを行う

Xrayが準備万端になったので、cloudbuild.yamlにスキャンするためのコマンドをbpコマンドの後に追記しましょう。

jfrog rt bs spring-boot-docker-build ${BUILD_ID}

bsbinary-scanのことで、これがIDで特定したビルドに対しスキャンを行うための記述です。

結果

ついに全ての設定が完了しました!!!GitHubへ変更を反映させるとまたCloud Buildが走ります。

f:id:ihcomega:20210903164407p:plain

Xrayをオンにしたらビルドがコケるようになりました(1番上の行)。サンプルで使ったアプリケーションはベースイメージで大量の脆弱性が見つかってしまったんです…。

Cloud Buildの実行結果を見たらJSON形式で詳細が確認できます。
f:id:ihcomega:20210903164843p:plain

JFrog Platformにアクセスすればよりリッチに詳細を見ることもできます。

f:id:ihcomega:20210903165103p:plainf:id:ihcomega:20210903165059p:plain

☝終わりに

今回はGCP系のツールでやってみましたが、別のプラットフォーム、CI/CDツールでも同様のことが出来ます。オフィシャルにインテグレーションがサポートされている場合は公式ドキュメントが見つかるはずですが、英語しかなかったり最新バージョンを追従できていなかったりすることもあるので、JFrog関連で気になることや不明点があったらぜひご連絡ください〜!ブログのコメント欄でもOKです◎

文中に出てこなかった参考文献

*1:つまり、ここでローカルリポジトリを指定しても同じことが実現できるのですが、基本的にバーチャルリポジトリを使うようにすると便利です。詳細は別の機会に…

*2:「リリースバンドル」にも適用できるのですが、今日は登場していない概念なので割愛しました

デブサミ2021夏でDevSecOpsを始めるためのヒントをお伝えしました #devsumi

こんにちは、JFrogデベロッパーアドボケイトのよこなです。毎日地獄のように暑いですが皆さんバテていませんか…。

7月30日に行われたDevelopers Summit 2021 SummerにてJFrogはプラチナスポンサーをさせていただきました。

スポンサーセッションとしてDevSecOpsの話をしたので、簡単に振り返ってみます!といってもプレゼンの動画も公開される予定ですし、基本的に資料はそれだけ見てもなんとなく分かるように作ってありますし(本人はいつもそのつもり…)、ポイントと所感だけ。
speakerdeck.com

セッションでお伝えした内容は次のような感じです。

  • DevOps復習: コラボレーションにより顧客に価値を届け続けることを目指す
  • DevSecOpsの考え方ではDevとOpsに加えSec(セキュリティ)も協力する
    • セキュリティといっても色々あるが、DevSecOpsでは主にソフトウェアのセキュリティを扱う
    • 開発ライフサイクル(≒CI/CD)に自動で行うセキュリティチェックを組み込むのを目指すと分かりやすい
  • ソフトウェアのセキュリティとして取り組めることにも種類があるが、動的・静的なチェックともに(できる/必要なところから)行うと良い
  • 関心の向きがちな自分の書いたコードのみならず、依存するOSSの脆弱性にも対策を講じる必要がある
    • OSSの脆弱性を放置したことによるインシデント(個人情報の流出など)は実際に事例がある
    • CI/CDを活用し、自動で早めかつ定期的なチェックを行う
  • 効率良いセキュリティチェックのためにもバイナリ・リポジトリマネージャーでアーティファクトを管理する
    • アーティファクトは依存解決が済んでおり、リリースする対象となる
    • 自らビルドして作成したアーティファクト・ライブラリなど外から取得したアーティファクトの両方を管理しておく
    • セキュリティチェックが出来る以外にも管理のメリットは多数ある
  • ツール追加で自動のセキュリティチェックを当たり前にするとともに、効率化により出来た時間は思考や判断が必要な作業に割く
  • どこから始めるかは組織次第だが、まずは普段の悩みや隣の人との雑談など身近なところからやっていきたい
    • DevOpsやDevSecOpsなどが定着していない(させづらい)組織ではセキュリティというポイントを使って周りを巻き込むのも手である
    • 自分が楽に、幸せになるところからやればそれが組織にとってプラスになる

三行に出来たら良かったんですが…結構長くなりました。これが40分程度のセッションのまとめです。
純粋にセキュリティやっていき💪な方はぜひ参考にしていただけたら嬉しいですし、終盤で話したように「周りを巻き込むためのタネ」とするのもアリだと思います。結果として何かが良くなるのであれば!
実際DevSecOpsはとても関心が高く、JFrogにコンタクト取って下さるかたも、セキュリティきっかけで興味を持ったという方がたくさんいらっしゃいますよ!

さて、ソフトウェアエンジニアだった頃の私がこうしたセキュリティに対する取り組みを理解していたかというと…足りていなかったように思います。
どちらかというとマーケティングとか自分の担当システムの使い手といった方々とのコラボを重視していた私ですが、運用やセキュリティとのそれについては今振り返ればもっと出来たことがありました。単純に知識不足が原因な気がします。
言い訳ではないですが、担当以外のことって難しいし時間も足りないし、ちゃんと分かってコラボレーションのため積極的に動くのは簡単なことではないですよね。「もやもやを抱えて仕事しているけど自分にはどうしようもない」「やる気はあるが何をどう変えたらいいか分からない」という方に日々出会うのも本当によく分かります😢
だからこそデベロッパーアドボケイトとなった今、忙しい中クイックに大事なことを知るための話をしたり、スーパーマンじゃないエンジニア(←まさに私のような)にも出来ることをお伝えしたりと、過去の学びからなるべく有益なネタを見つけようと思う今日この頃です。
ぜひ皆さんの悩みや取り組みなども教えて下さいね。

最後に、デブサミの運営、参加者、スピーカーの皆様、お疲れさまでした。そして、ありがとうございました。


ちょうど次のウェビナーがDevSecOpsに関するツールについてなのでよければぜひ!スピーカーは同僚の三宅です◎
leap.jfrog.com

JFrog Artifactoryを使ってDocker Hubのdownload rate limit (ダウンロード回数の制限) を回避する

Docker Hubのdownload rate limitとは?

blog.jfrog.co.jp

以前この記事で詳しく紹介した(翻訳ですが…)とおり、みんな大好きDocker Hubを無料で使っていると次のような利用制限がかかります。

ダウンロードの制限
イメージのプルが制限され、匿名ユーザーは6時間あたり100回、無料アカウントだと6時間あたり200回までとなります。

今日はダウンロードの際、JFrog Artifactory(クラウド版)をプロキシとして間に挟むことでこの回数をなるべく消費せずにDockerイメージを取得する方法を見ていきます。他のメリット含め、詳細は先ほど紹介した記事をご覧ください!

https://cdn-ak.f.st-hatena.com/images/fotolife/i/ihcomega/20200915/20200915055858.png

Artifactoryの設定をする

Artifactoryのアカウントを作成する

jfrog.com

ここからクラウド版の無料アカウントを作成します。もちろん有料アカウントをお持ちの方はそちらをお使いいただけます。
サーバー名(Server Name)はお好きなものを指定してください。 <サーバー名>.jfrog.ioにアクセスすればJFrog Platformが使えるようになります。なお、既に他のサーバーで使われている名前は指定できません。

リモートリポジトリを作成する

リポジトリにはいくつか種類がありますが、Docker Hubのように別のリポジトリと接続するときはリモートリポジトリを使います。

f:id:ihcomega:20210705164604p:plain
「New Remote Repository」をクリックする

f:id:ihcomega:20210705165425p:plain
パッケージの種類として「Docker」を選択する

f:id:ihcomega:20210705165457p:plain
リポジトリ作成に必要な情報を入力する

  • リポジトリ名は何でも良いですが、<特徴(アプリ名、サービス名など)>-<パッケージの種類>-<リポジトリの種類>とするのが分かりやすくてオススメです。ここでは example-docker-remoteとしました
  • URLにはイメージの取得先としてDocker Hub https://registry-1.docker.io/ を指定します(デフォルトで入力されています)。
  • Docker Hubにログインした状態でイメージを取得するには、ログイン情報も入力します

Save & Finishをクリックするとリポジトリが作成され、次のような画面が表示されます。ログインなどの操作をコマンドラインで行うのに便利です。

f:id:ihcomega:20210705184940p:plain
作成したリポジトリを操作するためのヒント

Dockerイメージをpullする

例としてGradleのイメージを取得することとします。普通にDocker Hubからダウンロードする場合、 docker pull gradleとやる操作です。
Artifactoryを介してDocker Hubにアクセスできるよう、まずはログインします(Docker for Mac / Windowsを使っている場合はsudoが要りません)。 *1

sudo docker login <サーバー名>.jfrog.io

続いて、必要なイメージをArtifactory経由でpullします。 *2

docker pull <サーバー名>.jfrog.io/example-docker-remote/gradle:latest

これで初回のみDocker Hubへアクセスしますが、1度コンテナイメージを取得したらArtifactoryにキャッシュされるので、2回目以降はそこから取得するようになります。
取得済みのアーティファクトはArtifactoryのUI上でも確認することができます。

f:id:ihcomega:20210705173910p:plain

ちなみに

自分のダウンロード回数の確認

残り何回ダウンロードできるかは Download rate limit | Docker Documentation に記載されている方法で調べることが可能です。

f:id:ihcomega:20210705160759p:plain
ダウンロード回数の上限と残り (あと92/200)

リモートリポジトリへの操作のコマンド確認

上で紹介したリポジトリ作成直後に表示されるコマンドは、後からも確認できます。ArtifactsのビューでSet Me Upをクリックしてください。

f:id:ihcomega:20210705185059p:plain
右上の「Set Me Up」をクリックする

すると、さっきみたいな画面がまた表示されます。

f:id:ihcomega:20210705185115p:plain

バーチャルリポジトリの利用

今回はリモートリポジトリ経由での操作を紹介しましたが、リモートリポジトリと紐付いたバーチャルリポジトリを使うことも可能です。
バーチャルリポジトリって何?という記事はまた書く予定がありますのでそちらにて!


以上、この簡単なステップだけでDocker Hubの制限に悩まされることも減るはずです。無料でお気軽に始められるのでぜひお試しあれ😋

*1:Artifactoryのバージョンが古い場合、リポジトリにログインする必要があるかもしれません。その場合は docker login <サーバー名>-example-docker-remote.jfrog.io を試してみてください

*2:Artifactoryのバージョンによっては docker pull <サーバー名>-example-docker-remote.jfrog.io/gradle とする必要があります