This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
ongoing @igor.drozdov @stanhu devops create 2023-07-28

SSH 인증서

요약

GitLab.com의 고객은 자체 최상위 그룹(나중에 조직으로)을 획들합니다. Self-Managed형과 비교하여, 이 수준에서 조직 전체 설정을 관리해야 합니다.

현재 SaaS(Secure Shell(SSH), HTTPS)에서 제공되는 Git 액세스 제어 옵션은 사용자 프로필에 설정된 자격 증명(액세스 토큰, SSH 키)에 의존합니다. 사용자 프로필은 조직의 관리 영향을 받지 않기 때문에 고객은 키가 기밀로 유지되는지 또는 만료 날짜가 정책을 준수하는지를 평가할 방법이 없습니다. 또한 키가 유출된 경우에 대한 피해 제어에 대한 방법이 거의 없으며 고객은 Git 액세스 흐름에 MFA(Multi-Factor Authentication)를 강제할 수 없습니다.

고객은 개발자가 매일 MFA를 통해 내부 시스템에 액세스할 수 있는 임시 SSH 인증서를 요청할 수 있는 프로세스를 가지고 있을 수 있습니다. SaaS에서 동일한 작업 방식을 활성화하기 위해 고객은 GitLab.com SaaS와 공개 Certificate Authority(CA) 파일을 공유할 수 있는 방법이 필요합니다.

동기

  • 사용자가 GitLab.com SaaS와 공개 Certificate Authority(CA) 파일을 공유하고 Git 액세스 제어 목적으로 사용할 수 있도록 합니다.
  • SSH 인증서를 통한 인증을 이미 지원하는 경쟁 제품과의 제품 간 격차를 줄입니다.

목표

이 문서는 다음 요구 사항을 충족시키기 위한 기능을 구현하기 위한 구조적 설계를 제안합니다.

  • 인증서를 발급하는데 사용되는 CA 파일(CA.pub)의 공개 키를 그룹에 추가할 수 있습니다.
  • CA가 발행한 인증서를 사용하여 그룹 및 그 조상 프로젝트에 대한 Git 액세스를 얻을 수 있습니다.
  • 해당 인증서는 그룹과 그 조상 외부 프로젝트에 대한 Git 액세스를 얻을 수 없습니다.

비목표

이 문서는 SSH 인증서를 통한 인증을 지원하기 위한 핵심 기능을 제공하는 데 중점을 둡니다. 잠재적인 개선 사항은 추후 조치에 설명되어 있습니다.

제안

MVC

그룹 관리자는 Certified Authority 파일로 사용할 SSH 키 쌍을 생성합니다(ssh-keygen -f CA):

  • 개인 키는 사용자 인증서를 발급하는 데 사용됩니다.
  • 공개 키는 사용자 인증서를 통해 그룹으로의 액세스 권한을 부여하기 위해 그룹에 추가됩니다.

사용자 인증서

그룹 관리자는 CA 개인 키를 사용하여 사용자 인증서를 발급하고 GitLab 사용자 이름 또는 사용자의 기본 이메일을 키 식별으로 지정합니다:

ssh-keygen -s CA -I user@example.com -V +1d user-key.pub

결과적으로 다음과 유사한 구조의 사용자 인증서가 생성됩니다:

ssh-keygen -L -f ssh_host_ed25519_key-cert.pub

ssh_host_ed25519_key-cert.pub:
        Type: ssh-ed25519-cert-v01@openssh.com user certificate
        Public key: ED25519-CERT SHA256:dRVV49XJHt85X1seqr9xXyxyuuGTbtFV6Lbwlrx6BIQ
        Signing CA: RSA SHA256:UAcgUeGoXrs8WOT/N+bmqY2vB9145Mc5NaN1Y977NCI (using rsa-sha2-512)
        Key ID: "user@example.com"
        Serial: 1
        Valid: from 2023-07-31T18:20:00 to 2023-08-01T18:21:34
        Principals: (none)
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc
  • Type은 사용자 인증서의 유형입니다. GitLab Shell은 사용자 인증서만 허용하며 다른 모든 유형은 거부됩니다.
  • Public Key는 사용자의 공개 키입니다.
  • Signing CACA의 공개 키입니다. 그 지문은 사용자 인증서와 관련된 그룹을 찾는 데 사용됩니다.
  • Key ID는 사용자 이름 또는 기본 이메일입니다. GitLab 사용자를 사용자 인증서에 연결하는 데 사용됩니다.
  • Serial은 사용자 인증서의 일련 번호입니다. 동일한 CA에 의해 생성된 다른 인증서를 구분하는 데 사용할 수 있습니다.
  • Valid는 유효 기간을 나타냅니다. 이 값은 GitLab Shell에서 유효하지 않은 사용자 인증서를 거부합니다.
  • Principals, Critical OptionsExtensions는 사용자 인증서에 추가 정보를 포함하는 데 사용됩니다. 이 필드들은 잠재적으로 사용자 인증서에 추가 제약 조건을 적용하기 위해 미래의 반복에서 사용될 수 있습니다.

응용 프로그램 동작

GitLab Shell은 SSH를 통해 GitLab 인스턴스로 보내는 명령을 처리하는 프로젝트입니다. 사용자가 공개 키로 인증을 시도하려고 할 때 GitLab Shell은 내부 API 요청을 /authorized_keys 엔드포인트로 보내어 키가 GitLab 사용자와 연결되어 있는지를 감지합니다. 인증서가 사용되어 인증할 때, GitLab Shell은 해당 인증서를 인식하고 대신 /authorized_certs로 요청을 수행할 수 있습니다.

  1. 그룹 관리자는 CA.pub 파일을 그룹에 추가합니다.
  2. 사용자가 CA에 의해 서명된 인증서를 사용하여 인증을 시도합니다.
  3. GitLab Shell은 /authorized_certsCA의 지문 및 사용자 식별(또는 GitLab 사용자 이름 또는 기본 이메일)을 보냅니다.
  4. GitLab Rails는 CA.pub의 지문이 추가된 그룹과 사용자를 찾습니다. CA.pub은 지문을 통해 인스턴스마다 고유합니다. 이는 CA와 그룹 간의 일대일 관계를 정의합니다.
  5. GitLab Shell은 설정된 연결마다 네임스페이스 전체 경로를 기억합니다.
  6. 필요한 경우 사용자가 특정 프로젝트에 액세스 권한이 있는지를 확인하기 위해 매번 /allowed 엔드포인트로 요청을 보냅니다. 네임스페이스 전체 경로가 /allowed 엔드포인트에 전달됩니다.
  7. GitLab Rails는 사용자가 이 인증서를 통해 프로젝트에 액세스할 수 있는지를 결정하기 위해 네임스페이스가 프로젝트 네임스페이스 또는 그 조상인지 확인합니다.
  8. 위의 모든 체크가 성공하면 사용자는 프로젝트에 액세스할 수 있습니다.
sequenceDiagram 사용자->>+GitLab Shell: SSH 인증서를 사용한 인증 GitLab Shell->>+GitLab Rails: /authorized_certs?key=서명 키 지문&user_identity=사용자 이름 또는 기본 이메일 GitLab Rails-->>-GitLab Shell: `CA` 구성 및 사용자 이름에 대한 네임스페이스가 있는지에 대한 응답 GitLab Shell-->>사용자: 인증 성공 사용자->>+GitLab Shell: 특정 프로젝트에 대한 Git 명령 GitLab Shell->>+GitLab Rails: /allowed [namespace=namespace] GitLab Rails-->>-GitLab Shell: 사용자가 이 네임스페이스의 프로젝트에 액세스할 수 있다는 응답 GitLab Shell-->>사용자: 성공

예시

  1. CA.pub를 구성한 그룹 외부 프로젝트 액세스

    다음과 같은 그룹 계층 구조가 있다고 가정합시다.

    a/b/c/d/e/f
        |
        └/g/h/i
    
    • 그룹 관리자는 dCA.pub를 추가하고 사용자가 CA에 의해 서명된 인증서를 사용하여 인증하는 경우, 사용자가 a/b/c/d/e/f/project를 복제할 때 a/b/c/d/e/project 프로젝트 전체 경로와 a/b/c/d 네임스페이스 전체 경로를 보냅니다: 사용자는 d가 프로젝트 네임스페이스의 조상이기 때문에 프로젝트를 복제할 수 있습니다.
    • 사용자가 a/b/c/g/h/i/project를 복제할 때, 사용자는 프로젝트를 복제할 수 없습니다. 왜냐하면 d가 그것의 조상 디렉터리에 없기 때문입니다.
  2. CA.pub를 구성한 그룹이 다른 네임스페이스로 이전

기존의 인증서는 여전히 유효합니다. 사용자가 다시 연결할 때마다 /authorized_certs에 대한 추가 요청이 보내어 새로운 네임스페이스의 전체 경로를 반환합니다.

오픈 질문

다중 SSH 인증서로 다른 프로젝트에 접근

사용자는 다른 프로젝트에 액세스하기 위해 다른 SSH 인증서를 가질 수 있습니다. 사용자가 SSH 연결을 설정하면 SSH 클라이언트는 성공적으로 인증하는 옵션을 찾기 위해 여러 가지 potensial 옵션을 반복합니다. 현재의 아키텍처에서는 사용자가 다른 프로젝트에 액세스하기를 원하는 경우라도 해당 namespace에 액세스 권한을 제공하는 첫 번째 인증서가 허용됩니다.

예를 들어:

  1. 사용자는 ab 그룹에 대한 유효한 인증서를 가지고 있습니다.
  2. 사용자는 a를 사용하여 성공적으로 인증되었습니다.
  3. 사용자는 b/project를 복제하려고 시도하며 실패합니다.

해당 시나리오의 해결책은 SSH 연결 중에 특정 인증서를 사용하도록 Git을 구성하는 것입니다. 다음을 .gitconfig 파일에 추가하세요:

[core]
    sshCommand = ssh git@gitlab.com -i cert.pub

단일 인증서를 폐기할 수 없음

단일 사용자 인증서의 폐기는 이번 MVC의 범위를 벗어납니다. 이 기능을 구현하는 것은 가능하지만 실행 가능성에 대해 논의해야 합니다.

지원하는 것은 구현과 UI/UX를 복잡하게 만들 수 있습니다. 그러나, 만료일, CA의 회전, 사용자 인증서 사용을 제한할 수 있는 source-address 기능을 통해 유출된 인증서의 위험은 크게 감소될 수 있습니다.

인증서는 여러 GitLab 인스턴스에서 사용될 수 있음

GitLab 인스턴스에 대한 정보는 사용자 인증서에 포함되어 있지 않습니다. 즉, KeyId 값이 해당 인스턴스에서 인정된 경우 여러 GitLab 인스턴스에서 사용할 수 있음을 의미합니다.

잠재적인 해결책:

  • Extensions를 사용하여 사용자 인증서의 사용을 특정 인스턴스로 제한하는 선택 사항 필드를 후속 조치에서 구현할 수 있습니다. extension:login@gitlab.com=username을 지정하는 것이 더 안전하고 유연한 옵션입니다. 하지만 두 가지를 지원할 수 있습니다.

CA는 여러 그룹에 재사용할 수 없음

CA.pub 지문은 고유해야 하며 여러 그룹에서 재사용할 수 없습니다. 하나 대 한 관계가 사용자가 액세스 권한을 가진 단일 그룹을 찾을 수 있도록 선택되었습니다.

다른 옵션은 Extensions 또는 Critical Options를 사용하여 사용자 인증서에 namespace를 포함하는 것입니다.

장점:

  • CA는 여러 그룹에서 재사용할 수 있음.
  • 사용자 인증서는 액세스할 그룹을 묻는 것이 아니라 액세스할 그룹을 알려줍니다.

단점:

  • 사용자 인증서 형식에 대한 사용자 지정 요구가 필요합니다.
  • 다른 그룹이 CA.pub을 추가하는 경우 사용자가 의도하지 않게 해당 그룹에 액세스할 수 있습니다.

잠재적인 해결책:

  • 후속 조치에서 Extensions 또는 Critical Options를 사용하여 사용자 인증서의 사용을 특정 그룹으로 제한하는 선택 사항 필드를 구현할 수 있습니다. CA는 여전히 재사용할 수 없지만 사용자 인증서는 다른 그룹에 사용할 수 없습니다.

반복 계획

컴포넌트 마일스톤 그룹 변경 사항
GitLab Shell 16.3 소스 코드 GitLab Shell에서 SSH 인증서를 사용하여 인증 구현
GitLab Rails 16.4 소스 코드 내부 GitLab Rails API 엔드포인트 authorized_certs를 구현하여 CA.pub을 구성하는 그룹을 찾음
GitLab Rails 16.4 소스 코드 그룹이 CA.pub을 추가/제거할 수 있도록 GitLab Rails API 엔드포인트를 구현
GitLab Rails 다음 2-3 마일스톤 인증 및 허가 그룹 설정 UX를 구현하여 CA.pub을 추가/제거할 수 있는 옵션을 구현
GitLab Rails 다음 2-3 마일스톤 인증 및 허가 SSH 인증서를 사용하여만 인증하고 개인 SSH 키 및 액세스 토큰을 금지하는 옵션을 구현

후속 조치

해당 주제와 관련된 기능이지만 이 청사진의 범위를 벗어나는 기능:

  • 인스턴스 또는 그룹의 경우 HTTPS를 통한 Git을 비활성화하여 인증을 위해 SSH 인증서만 사용하는 것을 강제화: 필수 기능.
  • 인스턴스 또는 그룹의 경우 Group-level SSH 키만 사용하도록 강제함으로써 개인 SSH 키의 사용을 금지: 필수 기능.
  • 사용자 인증서의 사용을 일련의 IP 주소로 제한하는 source-address Critical Option를 지정: 하고 싶은 기능.
  • 사용자 인증서의 사용을 일련의 인스턴스로 제한하는 login@hostname=username Extensions를 지정: 하고 싶은 기능.
  • SSH 인증서를 사용하여 커밋 서명: 하고 싶은 기능.
  • 단일 사용자 인증서 폐기. 다른 기능을 사용함으로써 중요한 위험은 크게 완화될 수 있지만 복잡한 UI/UX가 필요합니다.