- 現在の状態
- GitLabのFIPSコンプライアンス
- GitLab における FIPS 検証
- FIPS準拠のGitLabインストール
- FIPSパフォーマンス・ベンチマーク
- FIPS対応開発環境の構築
- Omnibus FIPSパッケージ
- Runner
- FIPS の検証
- FIPSビルドの作成方法
FIPS準拠
FIPSとは「Federal Information Processing Standard」の略で、「暗号モジュール」(CM) に対する一定のセキュリティ慣行を定義した文書です。これは、米国連邦機関に製品を販売するベンダーが一定のセキュリティ・フロアを満たすことを保証することを目的としています。
現在のFIPS標準は2つあります:140-2と140-3です。GitLabでは通常FIPS 140-2を指します。
現在の状態
GitLab はこのドキュメントで指定されたビルドの FIPS 140-2 コンプライアンスを完了しています。FIPS140-2認証はカスタマーアシュアランスパッケージ、特にコミュニティパッケージでご覧いただけます。
GitLabのFIPSコンプライアンス
準拠するためには、すべてのコンポーネント(GitLab自体、Gitalyなど)が準拠し、それらのコンポーネント間の通信、それらによって使用されるストレージも準拠する必要があります。準拠できない機能は、FIPSモードが有効なときに無効にしなければなりません。
利用される暗号モジュール
暗号モジュール名 | CMVP番号 | インスタンスタイプ | 使用ソフトウェアコンポーネント |
---|---|---|---|
Ubuntu 20.04 AWSカーネル暗号API暗号モジュール | 4132 | EC2 | Linuxカーネル |
Ubuntu 20.04 OpenSSL暗号モジュール | 3966 | EC2 | Gitaly、Rails(Puma/Sidekiq) |
Ubuntu 20.04 Libgcrypt暗号モジュール | 3902 | EC2インスタンス |
gpg ,sshd
|
Amazon Linux 2 カーネル暗号 API 暗号モジュール | 3709 | EKSノード | Linuxカーネル |
Amazon Linux 2 OpenSSL 暗号モジュール | 3553 | EKSノード | NGINX |
RedHat Enterprise Linux 8 OpenSSL 暗号モジュール | 4271 | EKSノード | UBIコンテナ:Workhorse、Pages、コンテナレジストリ、Rails (Puma/Sidekiq)、セキュリティアナライザ |
RedHat Enterprise Linux 8 Libgcrypt 暗号モジュール | 3784 | EKSノード | UBIコンテナ:GitLab Shell、gpg
|
対応オペレーションシステム
対応するハイブリッド・プラットフォームは以下の通りです:
- Omnibus GitLab: Ubuntu 20.04 LTS
- クラウドネイティブGitLab:Amazon Linux 2(EKS)
FIPSモードでサポートされていない機能
FIPSモードが有効な場合、一部のGitLab機能は動作しない可能性があります。以下の機能はFIPSモードでは動作しないことが知られています。しかし、ここに挙げられていない機能でもFIPSモードで正しく動作しないものがあるかもしれません:
- 認証が必要なリポジトリ内のイメージをスキャンするコンテナスキャンのサポート。
- Code Qualityは、FIPS準拠モードでのオペレーションをサポートしていません。
- Gradleの依存関係スキャンのサポート。
- Dynamic Application Security Testing(DAST)アナライザの縮小セットをサポートします。プロキシベースのアナライザは現在 FIPS モードでは利用できませんが、ブラウザベースの DAST、DAST API、DAST API Fuzzing イメージは利用できます。
- Yarnプロジェクトのための脆弱性ソリューション。
- 静的アプリケーション・セキュリティ・テスト(SAST)FIPS準拠モードでオペレーションする場合、アナライザーの縮小セットをサポートします。
- 現在、高度な検索機能は FIPS モードには含まれていません。FIPS に準拠するためには、この機能を有効にしてはなりません。
- Gravatar または Libravatar ベースのプロフィール画像はFIPS 準拠ではありません。
さらに、これらのパッケージリポジトリはFIPSモードでは無効になります:
GitLab における FIPS 検証
FIPS準拠とは異なり、FIPSバリデーションは認定監査役による正式な準拠宣言です。監査に合格するために必要な要件は、FIPS準拠と同じです。
FIPS検証済みモジュールのリストは、NIST(米国国立標準技術研究所)の暗号モジュール検証プログラムで見ることができます。
FIPS準拠のGitLabインストール
このガイドは、FIPSに準拠したGitLabの本番インスタンスを実行する必要がある公開ユーザーまたはGitLabチームメンバー向けのものです。このガイドでは、OmnibusとクラウドネイティブGitLabインストールの両方の要素を使用したハイブリッドデプロイの概要を説明します。
前提条件
- Amazon Web Servicesアカウント。最初のターゲット環境はAWS上で動作しており、他のFIPS準拠のAWSリソースを使用しています。
- GitLab 用に Ubuntu 20.04 マシンを実行する能力。私たちの最初のターゲット環境はハイブリッドアーキテクチャを使用しています。
FIPS対応クラスターのセットアップ
GitLab Environment Toolkitを使って、開発とテストのための FIPS 対応クラスターを立ち上げることができます。前提条件のところで述べたように、この説明ではAmazon Web Services(AWS) を使います。これは最初のターゲット環境だからです。
環境のセットアップ
開始するには、AWSアカウントは、AWS MarketplaceコンソールでFIPS対応のAmazon Machine Image(AMI) をサブスクライブする必要があります。
この例では、Canonical Group Limited
によるUbuntu Pro 20.04 FIPS LTS
AMI がアカウントに追加されていることを想定しています。このオペレーティングシステムは、Amazon EC2で実行される仮想マシンに使用されます。
Omnibus
FIPS対応のGitLabクラスターを手に入れる最もシンプルな方法は、Omnibusリファレンスアーキテクチャを使うことです。詳しくはGETクイックスタートガイドをご覧ください。以下の手順はクイックスタートに基づいており、クラウド・ネイティブ・ハイブリッドのインストールにも必要です。
Terraformを使用します:FIPS AMI を使う
GitLabチームメンバーはこの内部ハンドブックページでFIPS AMIの使い方を見ることができます:https://internal.gitlab.com/handbook/engineering/fedramp-compliance/get-configure/#terraform---use-fips-ami
AnsibleFIPS Omnibus ビルドの指定
標準のOmnibus GitLabリリースは独自のOpenSSLライブラリをビルドしますが、これはFIPSバリデーションされていません。しかし、Omnibusのナイトリービルドでは、オペレーティングシステムのOpenSSLライブラリとリンクするOmnibusパッケージを作成します。このパッケージを使用するには、Ansiblevars.yml
のgitlab_edition
とgitlab_repo_script_url
フィールドを更新します。
GitLabチームのメンバーは、このAnsibleの内部ハンドブックページ(AWS) で詳細を見ることができます:https://internal.gitlab.com/handbook/engineering/fedramp-compliance/get-configure/#ansible-aws
クラウドネイティブハイブリッド
Cloud Native Hybridインストールでは、OmnibusとCloud Native GitLab(CNG) イメージの両方を使用します。これまでの説明でOmnibusの部分はカバーしましたが、CNGでFIPSを有効にするにはさらに2つのステップが必要です:
- カスタムAmazon Elastic Kubernetes Service(EKS) AMIを使います。
- RedHatのUniversal Base Image(UBI) でビルドしたGitLabコンテナを使用します。
カスタム EKS AMI のビルド
AmazonはまだFIPS対応のAMIを公開していないため、Packerを使って自分でAMIを構築する必要があります。
Amazonは以下のGitリポジトリでカスタムEKS AMIに関する情報を公開しています:
このGitHubプルリクエストでは、Kubernetes v1.21用のFIPSを有効にしたAmazon Linux 2 EKS AMIを作成できます。イメージをビルドするには
- Packerをインストールします。
-
以下を実行してください:
git clone https://github.com/awslabs/amazon-eks-ami cd amazon-eks-ami git fetch origin pull/898/head:fips-ami git checkout fips-ami AWS_DEFAULT_REGION=us-east-1 make 1.21-fips # Be sure to set the region accordingly
異なるバージョンのKubernetesを使用している場合は、make
コマンドとMakefile
を適宜調整してください。
AMIのビルドが完了すると、以下のようなメッセージとともに新しいAMIが作成されるはずです:
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
us-west-2: ami-0a25e760cd00b027e
この例では、AMI ID はami-0a25e760cd00b027e
です。
FIPS を有効にした RHEL ベースのシステムをビルドすることは可能ですが、Packer のビルドが完了しない未解決の問題があります。
これは、特定のバージョンのイメージに基づいてカスタム AMI をビルドするため、最新のセキュリティパッチやアップグレードに対応するためには、定期的にカスタム AMI を再構築する必要があります。
Terraformを使用します:カスタム EKS AMI の使用
GitLabチームメンバーは、カスタムEKS AMIの使い方についてこの内部ハンドブックページでより詳しい情報を見ることができます:https://internal.gitlab.com/handbook/engineering/fedramp-compliance/get-configure/#terraform---use-a-custom-eks-ami
Ansible:UBI イメージを使う
CNGは、デプロイするコンテナイメージを管理するためにHelm Chartを使用します。UBI ベースのコンテナを使用するには、Ansiblevars.yml
を編集してカスタム Chart 変数を使用します:
all:
vars:
...
gitlab_charts_custom_config_file: '/path/to/gitlab-environment-toolkit/ansible/environments/gitlab-10k/inventory/charts.yml'
ここで、上記で指定した場所にcharts.yml
を作成し、-fips
サフィックス付きのタグを指定します。
詳細については、FIPSに関するChartのドキュメントを参照してください。
リリースタグを使うこともできますが、各コンポーネントが独自のバージョン管理スキームを使っている可能性があるため、バージョン管理が厄介です。例えば、GitLab v15.2:
global:
image:
tagSuffix: -fips
certificates:
image:
tag: 20211220-r0
kubectl:
image:
tag: 1.18.20
gitlab:
gitaly:
image:
tag: v15.2.0
gitlab-exporter:
image:
tag: 11.17.1
gitlab-shell:
image:
tag: v14.9.0
gitlab-mailroom:
image:
tag: v15.2.0
gitlab-pages:
image:
tag: v1.61.0
migrations:
image:
tag: v15.2.0
sidekiq:
image:
tag: v15.2.0
toolbox:
image:
tag: v15.2.0
webservice:
image:
tag: v15.2.0
workhorse:
tag: v15.2.0
FIPSパフォーマンス・ベンチマーク
品質エンジニアリングイネーブルメントチームは、FIPS対応環境がFIPS非対応環境と比較して優れているかどうかを確認することで、これらの取り組みを支援します。
テストでは、Gitaly SSLなどいくつかの場所で影響が見られますが、顧客に影響を与えるほど大きなものではありません。
FIPSパフォーマンス・ベンチマークに関する詳細は、以下のイシューをご覧ください:
FIPS対応開発環境の構築
最も簡単な方法は、Red Hat Enterprise Linux 8 を実行する仮想マシンをセットアップすることです。
Red Hat は開発者に無償のライセンスを提供し、Red Hat 開発者ポータルから CD イメージをダウンロードすることを許可しています。登録が必要です。
仮想マシンのセットアップが完了したら、RHEL 用の高度な手順も含め、GDK のインストール手順に従います。RedHat が提供する Go コンパイラやその他のシステム依存関係を使用することが不可欠なため、依存関係の管理にはasdf
を使用しないことに注意してください。
FIPS モードの有効化
GDKとその依存関係がインストールされたら、このコマンドを(rootで)実行し、仮想マシンを再起動します:
fips-mode-setup --enable
このコマンドを実行することで、GDKが有効になったかどうかを確認できます:
fips-mode-setup --check
この環境では、OpenSSL は FIPS 標準で禁止されている暗号オペレーションの実行を拒否します。これにより、FIPS 関連のバグを再現し、修正を検証することができます。
仮想マシン内でウェブブラウザを開き、GitLabインスタンスにサインインできるはずです。
このコマンドを実行し、仮想マシンを再起動すれば FIPS モードを再び無効にすることができます:
fips-mode-setup --disable
コード内のFIPS 有効化の検出
Ruby コード内でGitlab::FIPS
にクエリを発行し、インスタンスが FIPS に対応しているかどうかを調べることができます:
def default_min_key_size(name)
if Gitlab::FIPS.enabled?
Gitlab::SSHPublicKey.supported_sizes(name).select(&:positive?).min || -1
else
0
end
end
Omnibus FIPSパッケージ
GitLabには、FIPSに準拠してビルドされたOmnibus GitLabのビルド専用のリポジトリ(gitlab/gitlab-fips
)があります。これらのGitLabビルドは、Omnibus組み込みバージョンのOpenSSLではなく、システムのOpenSSLを使うようにコンパイルされています。これらのパッケージは
- RHEL 8 (および互換)
- AmazonLinux 2
- Ubuntu
これらはGitLab Environment Toolkit (GET)によって消費されます。
FIPS ビルドの作成方法のセクションを参照してください。
毎晩の Omnibus FIPS ビルド
ディストリビューションチームは、テスト目的で使用できる夜間のFIPS Omnibusビルドを作成しました。これらは決して本番環境で使用しないでください。
Runner
FIPS 準拠の GitLab Runner のインストールに関するドキュメントを参照してください。
FIPS の検証
以下のセクションでは、FIPS が有効になっているかどうかを確認する方法について説明します。
カーネル
$ cat /proc/sys/crypto/fips_enabled
1
Ruby (Omnibusイメージ)
$ /opt/gitlab/embedded/bin/irb
irb(main):001:0> require 'openssl'; OpenSSL.fips_mode
=> true
Ruby(CNGイメージ)
$ irb
irb(main):001:0> require 'openssl'; OpenSSL.fips_mode
=> true
Go
Googleは、OpenSSLからフォークされたFIPSバリデーションモジュールであるBoringSSLを静的にリンクできるように、Goコンパイラのdev.boringcrypto
ブランチ 。ただし、BoringSSLは公開用ではありません。
私たちはgolang-fips
、 dev.boringcrypto
ブランチのフォーク を使って、OpenSSL をdlopen
経由で動的にリンクする Go プログラムをビルドしています。これにはいくつかの利点があります:
- FIPSで検証されたシステムOpenSSLを使うのは簡単です。
- これはRed Hat の go-toolset パッケージで使用されているソースコードです。
- go-toolset とは異なり、このフォークは最新の Go リリースに対応しているようです。
ただし、これを動作させるには、CGO_ENABLED=1
を使ってcgo を有効にする必要があります。Cコードに呼び出すとパフォーマンスが低下します。
Linux x86 でgolang-fips
を使ってコンパイルされたプロジェクトは、OpenSSL を使用する暗号化ルーチンを自動的にビルドします。boringcrypto
ビルド・タグは自動的に存在しますが、実際には追加のビルド・タグは必要ありません。これらの暗号化フックを無効にする特定のビルド・タグがあります。
指定したバイナリがOpenSSLを使用しているかどうかは、go tool nm
、Cfunc__goboringcrypto
という名前のシンボルを探すことで確認できます。例えば
$ go tool nm nginx-ingress-controller | grep Cfunc__goboringcrypto | tail
2a0b650 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_SHA384_Final
2a0b658 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_SHA384_Init
2a0b660 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_SHA384_Update
2a0b668 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_SHA512_Final
2a0b670 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_SHA512_Init
2a0b678 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_SHA512_Update
2a0b680 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_internal_ECDSA_sign
2a0b688 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_internal_ECDSA_verify
2a0b690 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_internal_ERR_error_string_n
2a0b698 D crypto/internal/boring._cgo_71ae3cd1ca33_Cfunc__goboringcrypto_internal_ERR_get_error
さらに、LabKitにはFIPSが有効かどうかをチェックするルーチンが含まれています。
FIPSビルドの作成方法
多くのGitLabプロジェクト(例:Gitaly、GitLab Pages)は、FIPS_MODE=1 make
を使ってFIPSバイナリをローカルにビルドすることを標準としています。
Omnibus
OmnibusのFIPSビルドは、USE_SYSTEM_SSL
環境変数がtrue
に設定されると開始されます。この環境変数が設定されると、Omnibusレシピの依存関係であるcurl
、NGINX、libgit2がシステムのOpenSSLに対してリンクされます。OpenSSL は Omnibus のビルドには含まれません。
Omnibus ビルドは、golang-fips
コンパイラ](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/blob/master/docker/snippets/go_fips)を使用するコンテナイメージ[を使用して作成されます。例えば、このジョブはRHEL 8 用のパッケージのビルドに使用されるregistry.gitlab.com/gitlab-org/gitlab-omnibus-builder/centos_8_fips:3.3.1
イメージを作成しました。
別の Linux ディストリビューション用の新しい FIPS ビルドの追加
まず、目的の Linux ディストリビューション用の Omnibus Builder イメージがあることを確認する必要があります。Omnibus パッケージのビルドに使用されるイメージはOmnibus Builder イメージで作成されます。
このマージリクエストをレビューしてください。新しいイメージを追加するには
- サフィックスが
_fips
の CI ジョブを追加します (例:ubuntu_18.04_fips
)。 -
Dockerfile
がSnippets.new.populate
の代わりにSnippets.new(fips: fips).populate
を使っていることを確認してください。
この画像にタグを付けたら、Omnibus GitLabに新しいCIジョブを追加します。
クラウドネイティブGitLab(CNG)
Cloud Native GitLab CIパイプラインはいくつかのベースイメージを使ってイメージを生成します:
UBI イメージには、RHEL で使われているものと同じ OpenSSL パッケージが同梱されています。これにより、RHEL を必要とせずに FIPS 準拠のバイナリをビルドすることができます。RHEL 8.2 にはFIPS 検証済みの OpenSSL が同梱されていますが、8.5 では FIPS 検証のためのレビューが行われています。
このマージリクエストはCNG イメージ用の FIPS パイプラインを導入します。FIPS 用にタグ付けされたイメージには-fips
という接尾辞が付きます。例えば、webservice
コンテナには以下のタグがあります:
master
master-ubi8
master-fips
FIPSパイプラインによるマージリクエストのテスト
パッケージと QA をトリガーできるマージリクエストは、FIPS パッケージとリファレンスアーキテクチャのテストパイプラインをトリガーできます。トリガーに使用されるベースイメージはUbuntu 20.04 FIPSです:
- まだトリガーされていない場合は、
e2e:package-and-test
ジョブをトリガーします。 -
gitlab-omnibus-mirror
子パイプラインで、手動でTrigger:package:fips
をトリガーします。 - パッケージジョブが完了したら、手動で
RAT:FIPS
ジョブをトリガします。