FIPS 준수

FIPS는 “연방 정보 처리 표준(Federal Information Processing Standard)”의 약자로, “암호 모듈”(CM)의 특정 보안 관행을 정의하는 문서입니다. 이는 미국 연방 기관에 제품을 판매하는 공급업체가 일정 수준의 보안을 충족하도록 보장하는 것을 목표로 합니다.

경고:
FIPS 준수 인스턴스를 GitLab에서 구축할 수 있지만 모든 기능이 포함되지 않습니다.
FIPS 준수 인스턴스는 FIPS 설치 지침을 정확히 따르도록 구성해야 합니다.

현재 두 가지 FIPS 표준: 140-2140-3입니다. GitLab에서는 일반적으로 FIPS 140-2를 의미합니다.

현재 상태

GitLab은 이 문서에 명시된 빌드에 대해 FIPS 140-2 준수를 완료했습니다. 우리의 FIPS 140-2 인증서는 고객 보증 패키지에서 찾을 수 있으며, 특히 커뮤니티 패키지에 있습니다.

GitLab의 FIPS 준수

준수를 위해 모든 구성 요소(GitLab 자체, Gitaly 등)는 준수해야 하며, 이러한 구성 요소 간의 통신 및 이들이 사용하는 모든 저장소도 포함되어야 합니다. 기능이 준수로 가져올 수 없는 경우, FIPS 모드가 활성화되면 해당 기능은 비활성화되어야 합니다. FIPS 준수 암호화는 암호화 작업이 FIPS 검증된 모듈을 활용함을 의미합니다.

활용한 암호화 모듈

다음 목록은 참고용으로만 제공되며 동적으로 업데이트되지 않습니다. 아래 모듈에 대한 최신 CMVP 인증서가 적용됩니다.

암호화 모듈 이름 CMVP 번호 인스턴스 유형 사용된 소프트웨어 구성 요소
Ubuntu 20.04 AWS Kernel Crypto API 암호화 모듈 4366 EC2 (Omnibus) Linux kernel
Ubuntu 20.04 OpenSSL 암호화 모듈 4292 EC2 (Omnibus) Gitaly, Rails (Puma/Sidekiq)
Ubuntu 20.04 Libgcrypt 암호화 모듈 3902 EC2 (Omnibus) gpg, sshd
Amazon Linux 2 Kernel Crypto API 암호화 모듈 4593 EKS nodes Linux kernel
Amazon Linux 2 OpenSSL 암호화 모듈 4548 EKS nodes EKS
Red Hat Enterprise Linux 8 OpenSSL 암호화 모듈 4642 GitLab Helm chart UBI containers: Workhorse, Pages, container registry, Rails (Puma/Sidekiq), Security Analyzers, gitlab-sshd
Red Hat Enterprise Linux 8 Libgcrypt 암호화 모듈 4438 GitLab Helm chart UBI containers: GitLab Shell, gpg

지원되는 운영 체제

지원되는 하이브리드 플랫폼은 다음과 같습니다:

  • Omnibus GitLab: Ubuntu 20.04 LTS
  • Cloud Native GitLab: Amazon Linux 2 (EKS)

FIPS 모드에서 지원되지 않는 기능

FIPS 모드가 활성화되면 일부 GitLab 기능이 제대로 작동하지 않을 수 있습니다. FIPS 모드에서 작동하지 않는 것으로 알려진 기능은 다음과 같습니다. 그러나 이곳에 나열되지 않은 추가 기능도 FIPS 모드에서 제대로 작동하지 않을 수 있습니다:

또한, FIPS 모드에서는 다음 패키지 리포지토리가 비활성화됩니다:

GitLab의 FIPS 준수 및 FIPS 검증

GitLab은 FIPS 준수 소프트웨어 릴리즈에서 암호화 이진 파일(예: OpenSSL)을 포크하거나 수정하지 않고 대신 기존의 FIPS 검증된 암호화 소프트웨어(모듈)를 사용합니다. 따라서 GitLab은 NIST 암호화 모듈 검증 프로그램(CMVP) 독립 실험실 테스트를 통해 소프트웨어를 제출할 필요가 없습니다. 대신, GitLab은 모든 암호화 작업을 위해 활성 CMVP 인증서가 있는 FIPS 검증 소프트웨어(목록은 암호화 모듈 검증 프로그램에 나열됨)를 사용해야 합니다.

FIPS 준수 암호화는 암호화 작업이 FIPS 검증된 모듈을 사용함을 의미합니다. FIPS 모드는 모든 통신 세션(클라이언트, 서버 또는 두 쪽 모두) 중 하나 이상의 측면에서 활성화되어야 합니다. 클라이언트에서 FIPS 모드를 활성화하면 클라이언트가 데이터 암호화, 해싱 및 서명에 대해 FIPS 140-3/FIPS 140-2 준수 강력한 암호화 알고리즘을 사용하도록 보장합니다. 클라이언트에서 FIPS 모드가 활성화되지 않은 경우, 서버 측 또는 애플리케이션 로드 밸런서 또는 프록시 서버에서 구현되어야 하며, FIPS 준수 연결이 이루어질 수 있도록 해야 합니다.

FIPS 준수로 GitLab 설치

이 가이드는 FIPS 준수 요구 사항이 있는 일반 사용자 또는 GitLab 팀원을 위한 것입니다. 이 가이드는 Omnibus 및 Cloud Native GitLab 설치의 요소를 사용하여 하이브리드 배포를 설명합니다.

전제 조건

  • Amazon Web Services 계정. 우리의 첫 번째 목표 환경은 AWS에서 실행되며, 다른 FIPS 준수 AWS 자원을 사용합니다. 많은 AWS 리소스의 경우 FIPS 특정 엔드포인트를 사용해야 합니다.
  • GitLab을 위한 Ubuntu 20.04 머신을 실행할 수 있어야 합니다. 우리의 첫 번째 목표 환경은 하이브리드 아키텍처를 사용합니다.
  • 고급 검색: GitLab은 패키지화된 Elastic 또는 OpenSearch 배포를 제공하지 않습니다. FIPS 준수 서비스를 사용하거나 고급 검색을 비활성화해야 합니다.

FIPS 활성화 클러스터 설정

개발 및 테스트를 위해 FIPS 활성화 클러스터를 spin up하려면 GitLab Environment Toolkit을 사용할 수 있습니다. 전제 조건에서 언급했듯이, 이 지침은 첫 번째 목표 환경이기 때문에 Amazon Web Services (AWS)를 사용합니다.

환경 설정

시작하려면 AWS 계정이 AWS Marketplace 콘솔에서 FIPS 활성화 Amazon Machine Image (AMI)에 가입해야 합니다.

이 예에서는 Canonical Group LimitedUbuntu Pro 20.04 FIPS LTS AMI가 귀하의 계정에 추가되었다고 가정합니다. 이 운영 체제는 Amazon EC2에서 실행되는 가상 머신에 사용됩니다.

Omnibus

FIPS 활성화 GitLab 클러스터를 얻는 가장 간단한 방법은 Omnibus 참조 아키텍처를 사용하는 것입니다.

자세한 내용은 GET Quick Start Guide를 참조하십시오. 다음 지침은 Quick Start에 대한 내용을 기반으로 하며 Cloud Native Hybrid 설치에 필요합니다.

Terraform: FIPS AMI 사용

GitLab 팀원들은 FIPS AMI를 사용하는 방법에 대한 자세한 내용을 이 내부 핸드북 페이지에서 확인할 수 있습니다: https://internal.gitlab.com/handbook/engineering/fedramp-compliance/get-configure/#terraform---use-fips-ami

Ansible: FIPS Omnibus 빌드 지정

표준 Omnibus GitLab 릴리즈는 자체 OpenSSL 라이브러리를 구축하며, 이는 FIPS 검증을 받지 않습니다. 그러나, 운영 체제의 OpenSSL 라이브러리와 연결된 Omnibus 패키지를 생성하는 야간 빌드가 있습니다. 이 패키지를 사용하려면 Ansible vars.yml에서 gitlab_editiongitlab_repo_script_url 필드를 업데이트합니다.

GitLab 팀원들은 Ansible (AWS)에 대한 자세한 내용을 이 내부 핸드북 페이지에서 확인할 수 있습니다: https://internal.gitlab.com/handbook/engineering/fedramp-compliance/get-configure/#ansible-aws

Cloud Native Hybrid

Cloud Native Hybrid 설치는 Omnibus와 Cloud Native GitLab (CNG) 이미지를 모두 사용합니다. 이전 지침은 Omnibus 부분을 다루지만, CNG에서 FIPS를 활성화하려면 두 가지 추가 단계가 필요합니다:

  1. 커스텀 Amazon Elastic Kubernetes Service (EKS) AMI를 사용하세요.
  2. RedHat의 Universal Base Image (UBI)로 구축된 GitLab 컨테이너를 사용하세요.
커스텀 EKS AMI 빌드

Amazon은 아직 FIPS 활성화 AMI를 출시하지 않기 때문에, Packer로 직접 빌드해야 합니다.

Amazon은 커스텀 EKS AMI에 대한 정보를 포함한 다음 Git 리포지토리를 발행합니다:

GitHub 풀 리퀘스트는 Kubernetes v1.21에 대해 FIPS가 활성화된 Amazon Linux 2 EKS AMI를 생성할 수 있도록 합니다.

이미지를 구축하려면:

  1. Packer 설치.
  2. 다음을 실행합니다:

    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 # 지역을 적절하게 설정하세요.
    

다른 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 기반 컨테이너를 사용하려면 Ansible vars.yml을 수정하여 사용자 정의 Charts 변수를 사용해야 합니다:

all:
  vars:
    ...
    gitlab_charts_custom_config_file: '/path/to/gitlab-environment-toolkit/ansible/environments/gitlab-10k/inventory/charts.yml'

이제 위에서 지정한 위치에 charts.yml을 생성하고 -fips 접미사가 있는 태그를 지정합니다.

자세한 내용은 FIPS에 대한 Charts 문서를 참조하고, 예시 값 파일은 여기에서 확인하세요.

릴리스 태그도 사용할 수 있지만, 각 구성 요소가 자체 버전 관리 체계를 사용할 수 있어 버전 관리가 복잡합니다. 예를 들어, 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 활성화 환경이 비활성화 환경에 비해 잘 작동하는지 확인하여 이러한 노력을 지원합니다.

테스트 결과 Gitaly SSL 등에서 일부 장소에 영향을 미치는 것으로 나타났지만 고객에게 영향을 미칠 정도로 크지는 않습니다.

다음 이슈에서 FIPS 성능 벤치마킹에 대한 더 많은 정보를 찾을 수 있습니다:

FIPS 활성화 개발 환경 설정하기

가장 간단한 방법은 Red Hat Enterprise Linux 8 을 실행하는 가상 머신을 설정하는 것입니다.

Red Hat은 개발자에게 무료 라이센스를 제공하며, Red Hat 개발자 포털에서 CD 이미지를 다운로드할 수 있도록 허용합니다.

등록이 필요합니다.

가상 머신이 설정되면 GDK 설치 지침을 따를 수 있으며, RHEL에 대한 고급 지침도 포함되어 있습니다.

asdf 도구는 종속성 관리를 위해 사용되지 않으며, RedHat에서 제공하는 Go 컴파일러와 기타 시스템 종속성을 사용하는 것이 필수적입니다.

FIPS 모드 활성화

GDK와 그 종속 항목이 설치된 후, 다음 명령을 실행하고 (루트 권한으로) 가상 머신을 재시작합니다:

fips-mode-setup --enable

효과가 나타났는지 확인하려면 다음 명령을 실행합니다:

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 환경 도구 키트 (GET)에서 사용됩니다.

FIPS 빌드가 생성되는 방식에 대한 섹션을 참조하십시오.

야간 Omnibus FIPS 빌드

배포 팀은 야간 FIPS Omnibus 빌드를 생성했으며, 이는 테스트 목적으로 사용될 수 있습니다. 이러한 빌드는 절대 운영 환경에서 사용해서는 안 됩니다.

러너

FIPS 준수 GitLab 러너를 설치하는 설명서를 참조하십시오.

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은 Go 컴파일러에서 BoringSSL이라는 FIPS 검증 모듈을 정적으로 링크할 수 있는 dev.boringcrypto 브랜치를 유지하고 있습니다.

그러나 BoringSSL은 공개 사용을 위한 것이 아닙니다.

우리는 golang-fips를 사용하여 Go 프로그램을 빌드합니다. 이는 BoringSSL을 사용하는 dev.boringcrypto 브랜치의 포크입니다. 이는 여러 가지 장점을 가지고 있습니다:

  • FIPS 검증된 시스템 OpenSSL 사용이 간단합니다.
  • 이는 Red Hat의 go-toolset 패키지에서 사용되는 소스 코드입니다.
  • go-toolset와 달리 이 포크는 최신 Go 릴리스를 잘 따라잡는 것으로 보입니다.

그러나 이를 위해서는 CGO_ENABLED=1를 통해 cgo를 활성화해야 합니다. C 코드를 호출하는 경우 성능 저하가 발생할 수 있습니다.

Linux x86에서 golang-fips로 컴파일된 프로젝트는 OpenSSL을 사용하는 암호 루틴이 자동으로 포함됩니다. boringcrypto 빌드 태그는 자동으로 존재하지만, 실제로 추가 빌드 태그는 필요하지 않습니다. 이러한 암호 후크를 비활성화하는 특정 빌드 태그도 존재합니다.

우리는 go tool nm을 통해 특정 바이너리가 OpenSSL을 사용하고 있는지 확인할 수 있습니다 . ‘Cfunc__goboringcrypto’ 또는 ‘crypto/internal/boring/sig.BoringCrypto’로 명명된 기호를 찾아보면 됩니다.

예를 들면:

$ # Golang-FIPS 1.17 라이브러리에서 찾기
$ go tool nm nginx-ingress-controller | grep '_Cfunc__goboringcrypto_|\bcrypto/internal/boring/sig\.BoringCrypto' | 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
$ # Golang-FIPS 1.22 라이브러리에서 찾기
$ go tool nm tenctl | grep '_Cfunc__goboringcrypto_|\bcrypto/internal/boring/sig\.BoringCrypto'
  4cb840 t crypto/internal/boring/sig.BoringCrypto.abi0

또한, 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 컴파일러를 사용하는 컨테이너 이미지를 사용하여 생성됩니다. 예를 들어, 이 작업은 RHEL 8 용 패키지를 빌드하는 데 사용된 registry.gitlab.com/gitlab-org/gitlab-omnibus-builder/centos_8_fips:3.3.1 이미지를 생성했습니다.

다른 Linux 배포판에 대한 새로운 FIPS 빌드 추가

먼저, 원하는 Linux 배포판에 대한 Omnibus 빌더 이미지가 있는지 확인해야 합니다. Omnibus 패키지를 빌드하는 데 사용되는 이미지는 Omnibus 빌더 이미지와 함께 생성됩니다.

이 병합 요청을 검토하십시오. 새 이미지는 다음을 통해 추가할 수 있습니다:

  1. _fips 접미사가 있는 CI 작업 추가(예: ubuntu_18.04_fips).
  2. DockerfileSnippets.new(fips: fips).populate를 사용하도록 해야 합니다.

이 이미지에 태그가 추가되면 새로운 CI 작업을 Omnibus GitLab에 추가합니다.

Cloud Native 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 빌드용 기본 이미지

FIPS 파이프라인으로 병합 요청 테스트

Package와 QA를 트리거할 수 있는 병합 요청은 FIPS 패키지 및 참조 아키텍처 테스트 파이프라인을 트리거할 수 있습니다. 트리거에 사용되는 기본 이미지는 Ubuntu 20.04 FIPS입니다:

  1. 이미 트리거되지 않았다면 e2e:test-on-omnibus 작업을 트리거합니다.

  2. gitlab-omnibus-mirror 자식 파이프라인에서 수동으로 Trigger:package:fips를 트리거합니다.

  3. 패키지 작업이 완료되면 수동으로 RAT:FIPS 작업을 트리거합니다.