gitlab-sshd를 사용한 인스턴스 수준 SSH 인증서
GitLab v19.4Offering: GitLab Self-Managed
요약
GitLab Self-Managed 인스턴스가 gitlab-sshd를 사용한다면 인스턴스 수준 SSH 인증서 인증을 구성할 수 있습니다. 이 방식은 OpenSSH의 TrustedUserCAKeys 지시어에 해당하는 gitlab-sshd 방식이며, OpenSSH 기반 SSH 인증서 설정의 대안입니다.
히스토리
- GitLab 18.11에서 도입되었습니다.
GitLab Self-Managed 인스턴스가 gitlab-sshd를 사용한다면 인스턴스 수준
SSH 인증서 인증을 구성할 수 있습니다.
- 인증 기관(Certificate Authority, CA) 인증서로 SSH 인증을 중앙에서 관리합니다.
- Rails API 호출이나 데이터베이스 변경이 필요하지 않습니다.
이 방식은 OpenSSH의 TrustedUserCAKeys 지시어에 해당하는 gitlab-sshd
방식이며, OpenSSH 기반 SSH 인증서 설정의
대안입니다.
gitlab_sshd 인증 워크플로#
gitlab_sshd 인증 워크플로는 다음 과정을 따릅니다.
- 관리자가 CA 키 쌍을 생성합니다.
- 관리자가
config.yml의sshd.trusted_user_ca_keys아래에 CA 공개 키 파일 경로를 추가합니다. - 관리자가 CA 개인 키로 사용자의 SSH 공개 키에 서명합니다.
인증서의
KeyId는 사용자의 GitLab 사용자 이름으로 설정됩니다. - 사용자가 인증서로 연결하면 다음이 진행됩니다.
gitlab-sshd가 인증서 서명과 만료 여부를 검증합니다.gitlab-sshd가KeyId를 추출해 GitLab 사용자 이름으로 사용합니다.- 표준 GitLab 접근 확인이 진행됩니다(사용자 존재 여부, 프로젝트 권한).
gitlab-sshd 프로세스는 인증서 검증 자체에 Rails API 나 데이터베이스
호출이 필요하지 않습니다. /allowed 엔드포인트는 다른 SSH 연결과
마찬가지로 인가를 위해 여전히 호출됩니다.
다른 SSH 인증서 방식과의 비교#
GitLab은 여러 SSH 인증서 인증 방식을 지원합니다.
| 기능 | 인스턴스 수준 (gitlab-sshd) |
인스턴스 수준 (OpenSSH) | 그룹 수준 |
|---|---|---|---|
| 구성 위치 | config.yml |
sshd_config |
GitLab API/UI |
| SSH 서버 | gitlab-sshd |
OpenSSH | gitlab-sshd |
| Offering | GitLab Self-Managed | GitLab Self-Managed | GitLab.com |
| Tier | Free, Premium, Ultimate | Free, Premium, Ultimate | Premium, Ultimate |
| 범위 | 인스턴스 전체(네임스페이스 제한 없음) | 인스턴스 전체(네임스페이스 제한 없음) | 최상위 그룹 |
| 사용자 이름 매핑 | 인증서 KeyId |
AuthorizedPrincipalsCommand를 통한 인증서 Key ID |
API를 통한 인증서 ID |
| 엔터프라이즈 사용자 필요 여부 | 아니요 | 아니요 | 예 |
| 문서 | 이 페이지 | OpenSSH AuthorizedPrincipalsCommand |
그룹 SSH 인증서 |
사전 요구 사항#
인스턴스 수준 SSH 인증서를 구성하기 전에 다음을 확인합니다.
- GitLab Self-Managed 인스턴스에서
gitlab-sshd가 활성화되어 있어야 합니다. 자세한 내용은gitlab-sshd활성화를 참고합니다. - CA 키를 생성하고
config.yml을 편집하려면 서버 파일 시스템에 접근할 수 있어야 합니다. - SSH 인증서의
KeyId필드는 GitLab 사용자 이름과 정확히 일치해야 합니다.
신뢰할 수 있는 CA 키 구성#
인스턴스 수준 SSH 인증서 인증을 구성하는 방법은 다음과 같습니다.
-
CA 키 쌍을 생성합니다.
ssh-keygen -t ed25519 -f ssh_user_ca -C "GitLab SSH User CA"프롬프트가 나타나면 CA 개인 키를 보호할 강력한 패스프레이즈를 입력합니다.
이 명령은 파일 두 개를 생성합니다.
ssh_user_ca: CA 개인 키입니다.ssh_user_ca.pub: CA 공개 키입니다.
GitLab 서버에는 공개 키만 복사합니다.
sudo cp ssh_user_ca.pub /etc/gitlab/ssh_user_ca.pubCA 개인 키는 안전한 위치에 보관하며, GitLab 서버가 아닌 오프라인 시스템에 두는 것이 가장 좋습니다. 개인 키는 사용자 인증서에 서명할 때만 필요합니다.
-
gitlab-sshd구성에 CA 공개 키 파일 경로를 추가합니다./etc/gitlab/gitlab.rb를 편집합니다.gitlab_sshd['trusted_user_ca_keys'] = ['/etc/gitlab/ssh_user_ca.pub']-
파일을 저장하고 GitLab을 재구성합니다.
sudo gitlab-ctl reconfigure
-
CA 공개 키가 담긴 Kubernetes Secret을 생성합니다.
kubectl create secret generic my-ssh-ca-keys \ --from-file=ca.pub=ssh_user_ca.pub-
Helm 값을 내보냅니다.
helm get values gitlab > gitlab_values.yaml -
Secret을 참조하도록
gitlab_values.yaml을 편집합니다.gitlab: gitlab-shell: sshDaemon: gitlab-sshd config: trustedUserCAKeys: secret: my-ssh-ca-keys keys: - ca.pub -
파일을 저장하고 새 값을 적용합니다.
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlabHelm chart 구성에 대한 자세한 내용은 GitLab Shell chart 문서를 참고합니다.
-
-
다음 로그를 확인해
gitlab-sshd가 정상적으로 시작되었는지 검증합니다.Loaded trusted user CA keys for instance-level SSH certificates count=1
사용자에게 SSH 인증서 발급#
신뢰할 수 있는 CA 키를 구성한 다음에는 사용자에게 인증서를 발급합니다.
-
사용자의 SSH 공개 키를 확보합니다 (예:
id_ed25519.pub). -
-I(identity/KeyId) 플래그를 사용자의 정확한 GitLab 사용자 이름으로 설정해 CA로 사용자의 공개 키에 서명합니다.ssh-keygen -s ssh_user_ca -I <gitlab-username> -V +1d user-key.pub이 명령은 하루 동안 유효한 인증서 파일 (예:
user-key-cert.pub)을 생성합니다.유효 기간을 더 길게 설정하려면
-V플래그를 조정합니다. 예를 들어 30 일은-V +30d, 1 년은-V +52w로 지정합니다. -
사용자에게 인증서 파일을 배포합니다.
-
사용자는 인증서로 연결합니다.
ssh git@gitlab.example.com인증서 파일이 기본 명명 규칙(
<key>옆에<key>-cert.pub)을 따르면 SSH가 자동으로 사용합니다. 그렇지 않으면 인증서를 명시적으로 지정합니다.ssh -o CertificateFile=~/.ssh/id_ed25519-cert.pub git@gitlab.example.com
여러 인증 기관 사용#
CA 교체나 다중 CA 구성을 위해 CA 공개 키 파일을 여러 개 지정할 수 있습니다.
-
/etc/gitlab/gitlab.rb를 편집합니다.gitlab_sshd['trusted_user_ca_keys'] = [ '/etc/gitlab/ssh_user_ca_current.pub', '/etc/gitlab/ssh_user_ca_next.pub' ] -
파일을 저장하고 GitLab을 재구성합니다.
sudo gitlab-ctl reconfigure
-
CA 공개 키 두 개가 모두 담긴 Kubernetes Secret을 생성합니다.
kubectl create secret generic my-ssh-ca-keys \ --from-file=ca_current.pub=ssh_user_ca_current.pub \ --from-file=ca_next.pub=ssh_user_ca_next.pub -
Helm 값을 내보냅니다.
helm get values gitlab > gitlab_values.yaml -
Secret을 참조하도록
gitlab_values.yaml을 편집합니다.gitlab: gitlab-shell: sshDaemon: gitlab-sshd config: trustedUserCAKeys: secret: my-ssh-ca-keys keys: - ca_current.pub - ca_next.pub -
파일을 저장하고 새 값을 적용합니다.
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
하나의 파일에 CA 공개 키를 한 줄에 하나씩 여러 개 담을 수도 있습니다.
gitlab-sshd는 파일 전체에서 키 중복을 자동으로 제거합니다.보안 고려 사항#
인스턴스 수준 SSH 인증서는 CA 개인 키를 가진 모든 사람에게 인증 권한을 부여합니다. 배포하기 전에 다음 보안 고려 사항을 검토합니다.
WarningCA 개인 키에 접근할 수 있는 사람은 인스턴스의 모든 GitLab 사용자에 대한 인증서에 서명할 수 있습니다. 제한적인 파일 권한, 하드웨어 보안 모듈(HSM), 오프라인 환경 등 적절한 접근 제어로 CA 개인 키를 보호합니다.
인증서 해지 없음#
gitlab-sshd에는 내장된 인증서 해지 메커니즘이 없습니다. 인증서나 CA 키가 손상되면trusted_user_ca_keys구성에서 해당 CA를 제거하고 새 CA로 인증서를 재발급합니다. 노출 기간을 최소화하려면 단기 인증서(예: 24 시간)를 사용합니다.CA 구성 변경에 대한 감사 이벤트 없음#
GitLab은
config.yml의trusted_user_ca_keys변경을 감사 이벤트로 기록하지 않습니다. 인프라 모니터링 도구로 이 구성 파일의 변경을 모니터링합니다.gitlab-sshd는 SSH 인증서 인증의 성공 및 실패 시도를ssh_user,public_key_fingerprint,signing_ca_fingerprint,certificate_identity,certificate_username필드와 함께 로그에 기록합니다.클러스터 배포#
gitlab-sshd노드가 여러 개인 환경에서는 모든 노드에 걸쳐 구성과 CA 공개 키 파일을 동기화합니다. 구성이 일치하지 않으면 간헐적인 인증 실패가 발생할 수 있습니다. Helm chart 배포에서는 Kubernetes Secret 이 Pod 전체에 자동으로 공유됩니다.문제 해결#
CA 키 추가 후
gitlab-sshd시작 실패#CA 키 파일을 읽을 수 없거나 유효하지 않은 내용이 들어 있으면
gitlab-sshd가 시작되지 않습니다. 로그 출력에 다음과 같은 오류 메시지가 있는지 확인합니다.failed to load trusted user CA keys: 파일을 읽을 수 없습니다. 파일이 존재하고 권한이 올바른지(git사용자가 읽을 수 있는지) 확인합니다.failed to parse trusted user CA key in file: 파일 내용이 유효한 SSH 공개 키가 아닙니다. 파일에 OpenSSH 형식의 유효한 공개 키가 들어 있는지 확인합니다.trusted_user_ca_keys configured but no valid CA keys were loaded: 구성에 CA 키 파일이 나열되어 있지만 그중 유효한 키를 담은 파일이 없습니다.
certificate rejected: not a user certificate#인증서가 사용자 인증서가 아니라 호스트 인증서로 생성되었습니다.
ssh-keygen으로 서명할 때는-h플래그를 사용하지 않습니다.certificate KeyId does not match GitLab username format#인증서의
KeyId가 GitLab 사용자 이름 규칙을 따르지 않습니다. 서명할 때 사용한-I값이 GitLab 사용자 이름과 정확히 일치하는지 확인합니다.ssh: cert has expired#인증서 유효 기간이 지났습니다.
-V플래그를 사용해 적절한 유효 기간으로 새 인증서를 발급합니다.