FIPS 규정 준수

FIPS란 “Federal Information Processing Standard”의 약어로, “암호 모듈” (CM)을 정의하는 문서로, 미국 연방 기관에 제품을 판매하는 벤더가 특정 보안 관행을 규정합니다. 특정 보안 기준을 충족시키기 위한 것입니다.

경고: FIPS(연방정보처리표준) 준수 인스턴스를 구축할 수 있지만, 지원되지 않는 기능이 포함되지 않습니다. FIPS 준수 인스턴스는 FIPS 설치 지침을 정확히 따라 구성되어야 합니다.

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

현재 상태

GitLab은 이 설명서에서 명시된 빌드에 대한 FIPS 140-2 규정 준수를 완료했습니다. 당사의 FIPS 140-2 증명은 고객 보증 패키지인 특히 커뮤니티 패키지에서 확인하실 수 있습니다.

GitLab의 FIPS 규정 준수

준수를 위해 모든 구성 요소(GitLab 자체, Gitaly 등)뿐만 아니라 해당 구성 요소 간 통신과 그들이 사용하는 모든 저장소도 준수해야 합니다. 기능을 준수에 도입할 수 없는 경우 FIPS 모드가 활성화될 때 비활성화되어야 합니다.

이용된 암호 모듈

암호 모듈 이름 CMVP 번호 인스턴스 유형 사용된 소프트웨어 구성 요소
Ubuntu 20.04 AWS 커널 암호 API 암호 모듈 4132 EC2 리눅스 커널
Ubuntu 20.04 OpenSSL 암호 모듈 3966 EC2 Gitaly, Rails (Puma/Sidekiq)
Ubuntu 20.04 Libgcrypt 암호 모듈 3902 EC2 인스턴스 gpg, sshd
Amazon Linux 2 커널 암호 API 암호 모듈 3709 EKS 노드 리눅스 커널
Amazon Linux 2 OpenSSL 암호 모듈 3553 EKS 노드 NGINX
RedHat Enterprise Linux 8 OpenSSL 암호 모듈 4271 EKS 노드 UBI 컨테이너: Workhorse, Pages, 컨테이너 레지스트리, Rails (Puma/Sidekiq), 보안 분석기, gitlab-sshd
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 모드에서 제대로 작동하지 않을 수 있습니다:

또한, 다음의 패키지 저장소는 FIPS 모드에서 비활성화됩니다:

GitLab에서 FIPS 검증

FIPS 준수와는 달리, FIPS 검증은 인가된 감사인에 의한 준수의 공식 선언입니다. 감사를 통과하기 위해 필요한 요구 사항은 FIPS 준수와 동일합니다.

FIPS로 검증된 모듈 목록은 NIST(National Institute of Standards and Technology) cryptographic module validation program 에서 찾을 수 있습니다.

FIPS 준수로 GitLab 설치

이 가이드는 FIPS 준수인 프로덕션 인스턴스를 실행해야 하는 공개 사용자 또는 GitLab 팀 구성원을 위한 것입니다. 이 가이드에서는 Omnibus 및 클라우드 네이티브 GitLab 설치요소를 사용한 하이브리드 배포를 소개합니다.

사전 요구 사항

  • Amazon Web Services 계정. 첫 번째 대상 환경은 AWS에서 실행되며 다른 FIPS 준수 AWS 리소스를 사용합니다.
  • GitLab을 위해 Ubuntu 20.04 머신을 실행할 수 있는 능력. 첫 번째 대상 환경은 하이브리드 아키텍처를 사용합니다.

FIPS가 활성화된 클러스터 설정

FIPS 환경 도구킷을 사용하여 개발 및 테스트를 위한 FIPS가 활성화된 클러스터를 생성할 수 있습니다. 사전 요구 사항에서 언급했듯이 이 지침은 첫 번째 대상 환경이기 때문에 Amazon Web Services (AWS)를 사용합니다.

환경 설정

시작하려면 AWS 계정이 AWS 마켓 플레이스 콘솔에서 FIPS가 활성화된 Amazon Machine Image (AMI)를 구독해야 합니다.

본 예는 Canonical Group LimitedUbuntu 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

Ansible: FIPS Omnibus 빌드 지정

표준 Omnibus GitLab 릴리스는 자체적으로 FIPS로 검증된 OpenSSL 라이브러리를 작성하지만, 우리는 운영 체제의 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

클라우드 네이티브 하이브리드

클라우드 네이티브 하이브리드 설치는 Omnibus 및 클라우드 네이티브 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은 다음의 Git 저장소를 통해 사용자 정의 EKS AMI에 대한 정보를 게시합니다.

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이지만, 여러분의 값은 다를 수 있습니다.

RHEL 기반 시스템을 FIPS로 활성화하여 빌드하는 것도 가능하지만, 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 차트를 사용합니다. UBI 기반 컨테이너를 사용하려면 Ansible의 vars.yml을 편집하여 사용자 정의 차트 변수를 지정하세요:

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

이제 위에서 지정한 위치에 charts.yml을 만들고 태그를 -fips 접미사와 함께 지정하세요.

더 많은 세부 정보를 보려면 FIPS에 관한 차트 문서를 참조하세요. 여기에는 참고용 예제 값 파일도 포함되어 있습니다.

릴리스 태그를 사용할 수도 있지만 각 구성 요소마다 고유한 버전 관리 체계를 사용하므로 버전 관리가 까다로울 수 있습니다. 예를 들어, 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은 개발자에게 무료 라이센스를 제공하고 CD 이미지를 Red Hat 개발자 포털에서 다운로드할 수 있도록 허용합니다. 등록이 필요합니다.

가상 머신을 설치한 후 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

옴니버스 FIPS 패키지

GitLab은 FIPS 규정을 준수하는 옴니버스 GitLab 빌드를 위한 전용 저장소 (gitlab/gitlab-fips) 을 보유하고 있습니다. 이러한 GitLab 빌드는 옴니버스에 내장된 OpenSSL 버전 대신 시스템 OpenSSL을 사용하도록 컴파일되었습니다. 이러한 패키지들은 다음을 위해 구축되었습니다:

FIPS 빌드가 어떻게 생성되는지에 대한 섹션을 확인하세요.

매일갱 신버스 FIPS 빌드

유통팀에서는 매일갱 FIPS 옴니버스 빌드를 만들었습니다. 이는 테스트 목적으로 사용할 수 있습니다. 이러한 빌드는 절대 프로덕션 환경에 사용해서는 안 됩니다.

러너

FIPS 규정을 준수하는 GitLab 러너를 설치하는 문서를 참조하세요.

FIPS 확인

다음 섹션에서는 FIPS가 활성화되었는지 확인할 수 있는 방법에 대해 설명합니다.

커널

$ cat /proc/sys/crypto/fips_enabled
1

루비 (옴니버스 이미지)

$ /opt/gitlab/embedded/bin/irb
irb(main):001:0> require 'openssl'; OpenSSL.fips_mode
=> true

루비 (CNG 이미지)

$ irb
irb(main):001:0> require 'openssl'; OpenSSL.fips_mode
=> true

Go

Google은 Go 컴파일러의 dev.boringcrypto 브랜치를 유지하여 OpenSSL에서 포크된 FIPS-검증 모듈인 BoringSSL을 정적으로 링크할 수 있도록 합니다. 그러나 BoringSSL은 일반 사용을 위해 제작된 것이 아닙니다.

우리는 golang-fips를 사용하여 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 이진 파일을 로컬로 빌드하기 위해 FIPS_MODE=1 make를 사용하는 것에 표준화되어 있습니다.

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 Builder 이미지로 생성됩니다.

이 MR(merge request)를 검토하세요. 새 이미지는 다음과 같이 추가할 수 있습니다:

  1. _fips 접미사를 가진 CI 작업을 추가합니다(예: ubuntu_18.04_fips).
  2. DockerfileSnippets.new.populate 대신에 Snippets.new(fips: fips).populate를 사용하도록 합니다.

이 이미지에 태그를 추가한 후, Omnibus GitLab에 새로운 CI job를 추가하세요.

Cloud Native GitLab (CNG)

Cloud Native GitLab CI 파이프라인은 다음과 같은 기본 이미지를 사용하여 이미지를 생성합니다:

UBI 이미지는 RHEL에서 사용되는 것과 동일한 OpenSSL 패키지가 제공됩니다. 이를 통해 RHEL이 필요하지 않고도 FIPS 호환 이진 파일을 빌드할 수 있습니다. RHEL 8.2에는 FIPS-검증된 OpenSSL이 제공되지만, 8.5는 FIPS 검증을 위해 검토 중입니다.

이 MR(merge request)는 CNG 이미지를 위한 FIPS 파이프라인을 소개합니다. FIPS용으로 태그가 지정된 이미지는 -fips 접미사가 붙습니다. 예를 들어, webservice 컨테이너에는 다음과 같은 태그가 있습니다:

  • master
  • master-ubi8
  • master-fips

FIPS 빌드용 기본 이미지

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

패키지 및 QA를 트리거할 수 있는 병합 요청은 FIPS 패키지 및 Reference Architecture 테스트 파이프라인을 트리거할 수 있습니다. 트리거에 사용된 기본 이미지는 Ubuntu 20.04 FIPS입니다:

  1. 이미 e2e:package-and-test 작업이 트리거되지 않은 경우, 해당 작업을 트리거합니다.
  2. gitlab-omnibus-mirror 하위 파이프라인에서 수동으로 Trigger:package:fips 작업을 트리거합니다.
  3. 패키지 작업이 완료되면 RAT:FIPS 작업을 수동으로 트리거합니다.