GitLab 토큰 문제 해결
GitLab 토큰을 사용할 때 다음과 같은 문제를 만날 수 있습니다.
만료된 액세스 토큰
기존의 액세스 토큰이 사용 중이고 expires_at
값에 도달하면, 토큰이 만료되고:
- 더 이상 인증에 사용할 수 없습니다.
- UI에서 보이지 않습니다.
이 토큰을 사용하여 수행된 요청은 401 Unauthorized
응답을 반환합니다. 같은 IP 주소에서 짧은 시간에 너무 많은 승인되지 않은 요청은 GitLab.com에서 403 Forbidden
응답을 초래합니다.
인증 요청 한도에 대한 자세한 내용은 Git 및 컨테이너 레지스트리 실패한 인증 금지를 참조하세요.
로그에서 만료된 액세스 토큰 식별하기
- GitLab 17.2에 도입됨 Introduced.
전제 조건:
다음이 필요합니다:
- 관리자인 경우.
-
api_json.log
파일에 접근할 수 있는 경우.
어떤 401 Unauthorized
요청이 만료된 액세스 토큰으로 인해 실패하는지 식별하려면, api_json.log
파일에서 다음 필드를 사용하세요:
필드 이름 | 설명 |
---|---|
meta.auth_fail_reason |
요청이 거부된 이유. 가능한 값: token_expired , token_revoked , insufficient_scope , 및 impersonation_disabled . |
meta.auth_fail_token_id |
시도한 토큰의 타입 및 ID를 설명하는 문자열. |
사용자가 만료된 토큰을 사용하려고 하면, meta.auth_fail_reason
은 token_expired
입니다. 다음은 로그 항목의 일부를 보여줍니다:
{
"status": 401,
"method": "GET",
"path": "/api/v4/user",
...
"meta.auth_fail_reason": "token_expired",
"meta.auth_fail_token_id": "PersonalAccessToken/12",
}
meta.auth_fail_token_id
는 ID 12의 액세스 토큰이 사용되었음을 나타냅니다.
이 토큰에 대한 추가 정보를 찾으려면 개인 액세스 토큰 API를 사용하세요. API를 사용하여 토큰을 회전할 수도 있습니다.
만료된 액세스 토큰 교체하기
토큰을 교체하려면:
- 이 토큰이 이전에 어디에서 사용되었는지 확인하고, 여전히 토큰을 사용하는 자동화에서 제거합니다.
- 개인 액세스 토큰의 경우, API를 사용하여 최근에 만료된 토큰을 나열합니다. 예를 들어
https://gitlab.com/api/v4/personal_access_tokens
로 이동하여 특정expires_at
날짜가 있는 토큰을 찾습니다. - 프로젝트 액세스 토큰의 경우, 프로젝트 액세스 토큰 API를 사용하여 최근에 만료된 토큰을 나열합니다.
- 그룹 액세스 토큰의 경우, 그룹 액세스 토큰 API를 사용하여 최근에 만료된 토큰을 나열합니다.
- 개인 액세스 토큰의 경우, API를 사용하여 최근에 만료된 토큰을 나열합니다. 예를 들어
- 새 액세스 토큰을 생성합니다:
- 개인 액세스 토큰의 경우, UI를 사용하거나 사용자 토큰 API를 사용합니다.
- 프로젝트 액세스 토큰의 경우, UI를 사용하거나 프로젝트 액세스 토큰 API를 사용합니다.
- 그룹 액세스 토큰의 경우, UI를 사용하거나 그룹 액세스 토큰 API를 사용합니다.
- 이전 액세스 토큰을 새 액세스 토큰으로 교체합니다. 이 과정은 토큰을 비밀로 구성했는지 또는 애플리케이션에 포함되었는지에 따라 다릅니다. 이 토큰에서 수행된 요청은 더 이상
401
응답을 반환하지 않아야 합니다.
토큰 수명 연장
이 스크립트를 사용하여 특정 토큰의 만료를 지연시킵니다.
GitLab 16.0부터 모든 액세스 토큰에는 만료 날짜가 있습니다. GitLab 16.0 이상을 배포한 후,
만료되지 않는 액세스 토큰은 배포 날짜로부터 1년 후에 만료됩니다.
이 날짜가 다가오고 아직 회전되지 않은 토큰이 있는 경우,
이 스크립트를 사용하여 만료를 지연시키고 사용자가 토큰을 회전할 수 있는 시간을 더 제공합니다.
특정 토큰의 수명 연장
이 스크립트는 지정된 날짜에 만료되는 모든 토큰의 수명을 연장합니다. 포함된 항목:
- 개인 액세스 토큰
- 그룹 액세스 토큰
- 프로젝트 액세스 토큰
그룹 및 프로젝트 액세스 토큰의 경우, 이 스크립트는 GitLab 16.0 이상으로 업그레이드할 때 자동으로 만료 날짜가 설정된 경우에만 이러한 토큰의 수명을 연장합니다. 만약 그룹 또는 프로젝트 액세스 토큰이 만료 날짜와 함께 생성되었거나 회전된 경우, 해당 토큰의 유효성은 리소스에 대한 유효한 멤버십에 따라 달라지므로 이 스크립트를 사용하여 토큰 수명을 연장할 수 없습니다.
스크립트를 사용하려면:
-
터미널 창에서
sudo gitlab-rails console
명령어로 Rails 콘솔 세션을 시작합니다. -
아래의 전체
extend_expiring_tokens.rb
스크립트를 붙여넣습니다.원하는 경우,
expiring_date
를 다른 날짜로 변경합니다. -
Enter 키를 누릅니다.
-
터미널 창에서 인스턴스에 연결합니다.
-
아래의 전체
extend_expiring_tokens.rb
스크립트를 복사하여 인스턴스의 파일로 저장합니다:-
파일 이름을
extend_expiring_tokens.rb
로 지정합니다. -
원하는 경우,
expiring_date
를 다른 날짜로 변경합니다. -
파일은
git:git
에서 접근할 수 있어야 합니다.
-
-
다음 명령을 실행하여
/path/to/extend_expiring_tokens.rb
를extend_expiring_tokens.rb
파일의 전체 경로로 변경합니다:sudo gitlab-rails runner /path/to/extend_expiring_tokens.rb
자세한 내용은 Rails 러너 문제 해결 섹션을 참조하세요.
extend_expiring_tokens.rb
expiring_date = Date.new(2024, 5, 30)
new_expires_at = 6.months.from_now
total_updated = PersonalAccessToken
.not_revoked
.without_impersonation
.where(expires_at: expiring_date.to_date)
.update_all(expires_at: new_expires_at.to_date)
puts "Updated #{total_updated} tokens with new expiry date #{new_expires_at}"
특정 날짜에 만료되는 개인, 프로젝트 및 그룹 액세스 토큰 식별하기
만료 날짜가 없는 액세스 토큰은 무기한 유효하며, 이는 액세스 토큰이 유출될 경우 보안 위험이 됩니다.
이 위험을 관리하기 위해, GitLab 16.0 이상으로 업그레이드할 경우, 만료 날짜가 없는 모든 개인,
프로젝트, 또는
그룹 액세스 토큰은 업그레이드 날짜로부터 1년 후에 자동으로 만료 날짜가 설정됩니다.
GitLab 17.3 이상에서는 이러한 기존 토큰에 대한 만료 자동 설정이 되돌려졌으며, 새로운 액세스 토큰에 대해 만료 날짜 강제를 비활성화할 수 있습니다.
만약 토큰이 언제 만료되는지 모른다면, 만료 날짜가 변경되었을 때 GitLab에 로그인하려고 할 때 예기치 않은 인증 실패가 발생할 수 있습니다.
이 문제를 관리하려면, GitLab 17.2 이상으로 업그레이드해야 합니다. 이러한 버전에서는 토큰 만료 날짜를 분석, 연장 또는 제거하는 데 도움을 주는 도구를 포함하고 있습니다.
도구를 실행할 수 없는 경우, 자체 관리 인스턴스에서 스크립트를 실행하여 다음 중 하나를 식별할 수 있습니다:
- 특정 날짜에 만료되는 토큰.
- 만료 날짜가 없는 토큰.
이 스크립트들은 터미널 창에서 다음의 두 곳 중 하나에서 실행됩니다:
- Rails 콘솔 세션.
- Rails 러너를 사용하여.
실행하는 특정 스크립트는 GitLab 16.0 이상으로 업그레이드했는지 여부에 따라 다릅니다:
- 아직 GitLab 16.0 이상으로 업그레이드하지 않은 경우, 만료 날짜가 없는 토큰을 식별합니다.
- GitLab 16.0 이상으로 업그레이드한 경우, 다음을 식별하는 스크립트를 사용합니다:
문제에 영향을 받은 토큰을 식별한 후, 필요시 특정 토큰의 수명을 연장하는 최종 스크립트를 실행할 수 있습니다.
이 스크립트는 다음 형식으로 결과를 반환합니다:
Expired group access token in Group ID 25, Token ID: 8, Name: Example Token, Scopes: ["read_api", "create_runner"], Last used:
Expired project access token in Project ID 2, Token ID: 9, Name: Test Token, Scopes: ["api", "read_registry", "write_registry"], Last used: 2022-02-11 13:22:14 UTC
자세한 내용은 사건 18003을 참조하세요.
특정 날짜에 만료되는 모든 토큰 찾기
이 스크립트는 특정 날짜에 만료되는 토큰을 찾습니다.
전제 조건:
- GitLab 16.0으로 인스턴스를 업그레이드한 정확한 날짜를 알아야 합니다.
사용 방법:
- 터미널 창에서 인스턴스에 연결합니다.
-
sudo gitlab-rails console
로 Rails 콘솔 세션을 시작합니다. - 필요에 따라 아래의 전체
expired_tokens.rb
또는expired_tokens_date_range.rb
스크립트를 복사하여 콘솔에 붙여넣습니다.
expires_at_date
를 GitLab 16.0으로 인스턴스가 업그레이드된 후 1년이 되는 날짜로 변경합니다. - Enter를 누릅니다.
- 터미널 창에서 인스턴스에 연결합니다.
- 필요에 따라 아래의 전체
expired_tokens.rb
또는expired_tokens_date_range.rb
스크립트를 복사하여 인스턴스에 파일로 저장합니다:- 이름을
expired_tokens.rb
로 지정합니다. -
expires_at_date
를 GitLab 16.0으로 인스턴스가 업그레이드된 후 1년이 되는 날짜로 변경합니다. - 파일은
git:git
이 접근 가능해야 합니다.
- 이름을
-
이 명령을 실행합니다.
_full_
경로를expired_tokens.rb
파일의 전체 경로로 변경합니다:sudo gitlab-rails runner /path/to/expired_tokens.rb
자세한 내용은 Rails 러너 문제 해결 섹션을 참조하세요.
expired_tokens.rb
이 스크립트는 GitLab 인스턴스가 GitLab 16.0으로 업그레이드된 정확한 날짜를 알아야 합니다.
# 이 값을 GitLab 인스턴스가 업그레이드된 후 1년이 되는 날짜로 변경합니다.
expires_at_date = "2024-05-22"
# 만료되는 개인 접근 토큰 확인
PersonalAccessToken.owner_is_human.where(expires_at: expires_at_date).find_each do |token|
if token.user.blocked?
next
# 출력에서 사용 불가한 차단된 PAT 숨기기
end
puts "만료된 개인 접근 토큰 ID: #{token.id}, 사용자 이메일: #{token.user.email}, 이름: #{token.name}, 범위: #{token.scopes}, 마지막 사용: #{token.last_used_at}"
end
# 만료되는 프로젝트 및 그룹 접근 토큰 확인
PersonalAccessToken.project_access_token.where(expires_at: expires_at_date).find_each do |token|
token.user.members.each do |member|
type = member.is_a?(GroupMember) ? '그룹' : '프로젝트'
puts "#{type} ID #{member.source_id}에 있는 만료된 #{type} 접근 토큰, 토큰 ID: #{token.id}, 이름: #{token.name}, 범위: #{token.scopes}, 마지막 사용: #{token.last_used_at}"
end
end
참고:
차단된 사용자가 소유한 토큰을 숨기는 것뿐만 아니라 제거하려면, if token.user.blocked?
아래에 token.destroy!
를 추가하세요. 그러나 이 작업은 API 메서드와 달리 감사 이벤트를 남기지 않습니다.
주어진 월에 만료되는 토큰 찾기
이 스크립트는 특정 월에 만료되는 토큰을 찾습니다. GitLab 16.0으로 인스턴스가 업그레이드된 정확한 날짜를 알 필요는 없습니다. 사용 방법:
- 터미널 창에서
sudo gitlab-rails console
로 Rails 콘솔 세션을 시작합니다. - 아래의 전체
tokens_with_no_expiry.rb
스크립트를 붙여넣습니다.
원하실 경우date_range
를 다른 범위로 변경하세요. - Enter를 누릅니다.
- 터미널 창에서 인스턴스에 연결합니다.
- 아래의 전체
tokens_with_no_expiry.rb
스크립트를 복사하여 인스턴스에 파일로 저장합니다:- 이름을
expired_tokens_date_range.rb
로 지정합니다. - 원하실 경우
date_range
를 다른 범위로 변경하세요. - 파일은
git:git
이 접근 가능해야 합니다.
- 이름을
-
이 명령을 실행합니다.
/path/to/expired_tokens_date_range.rb
를expired_tokens_date_range.rb
파일의 전체 경로로 변경합니다:sudo gitlab-rails runner /path/to/expired_tokens_date_range.rb
자세한 내용은 Rails 러너 문제 해결 섹션을 참조하세요.
expired_tokens_date_range.rb
# 이 스크립트는 현재 날짜로부터
# 특정 날짜 범위(예: 1개월) 내에 만료되는 토큰을 검색할 수 있게 해줍니다.
# GitLab 16.0 업그레이드가 정확히 언제 완료되었는지 확실하지 않은 경우에 사용하세요.
date_range = 1.month
# 개인 액세스 토큰 확인
PersonalAccessToken.owner_is_human.where(expires_at: Date.today .. Date.today + date_range).find_each do |token|
puts "만료된 개인 액세스 토큰 ID: #{token.id}, 사용자 이메일: #{token.user.email}, 이름: #{token.name}, 범위: #{token.scopes}, 마지막 사용: #{token.last_used_at}"
end
# 만료될 프로젝트 및 그룹 액세스 토큰 확인
PersonalAccessToken.project_access_token.where(expires_at: Date.today .. Date.today + date_range).find_each do |token|
token.user.members.each do |member|
type = member.is_a?(GroupMember) ? '그룹' : '프로젝트'
puts "만료된 #{type} 액세스 토큰, #{type} ID #{member.source_id}, 토큰 ID: #{token.id}, 이름: #{token.name}, 범위: #{token.scopes}, 마지막 사용: #{token.last_used_at}"
end
end
많은 토큰이 만료되는 날짜 식별
이 스크립트는 대부분의 토큰이 만료되는 날짜를 식별합니다. 만약 팀이 아직 토큰 회전을 설정하지 않았다면, 만료 날짜가 다가오고 있는 대규모 배치의 토큰을 식별하고 연장하는 데 이 스크립트를 다른 스크립트와 조합하여 사용할 수 있습니다.
스크립트는 다음 형식으로 결과를 반환합니다:
42 개인 액세스 토큰이 2024-06-27에 만료됩니다.
17 개인 액세스 토큰이 2024-09-23에 만료됩니다.
3 개인 액세스 토큰이 2024-08-13에 만료됩니다.
사용 방법:
- 터미널 창에서
sudo gitlab-rails console
로 Rails 콘솔 세션을 시작합니다. - 전체
dates_when_most_of_tokens_expire.rb
스크립트를 붙여넣습니다. - Enter를 누릅니다.
- 터미널 창에서 인스턴스에 연결합니다.
- 전체
dates_when_most_of_tokens_expire.rb
스크립트를 복사하여 인스턴스의 파일로 저장합니다:- 파일 이름:
dates_when_most_of_tokens_expire.rb
. - 파일은
git:git
에 접근 가능해야 합니다.
- 파일 이름:
-
다음 명령을 실행하며,
/path/to/dates_when_most_of_tokens_expire.rb
를dates_when_most_of_tokens_expire.rb
파일의 전체 경로로 변경합니다:sudo gitlab-rails runner /path/to/dates_when_most_of_tokens_expire.rb
자세한 정보는 Rails 러너 문제 해결 섹션을 참조하세요.
dates_when_most_of_tokens_expire.rb
PersonalAccessToken
.select(:expires_at, Arel.sql('count(*)'))
.where('expires_at >= NOW()')
.group(:expires_at)
.order(Arel.sql('count(*) DESC'))
.limit(10)
.each do |token|
puts "#{token.count} 개인 액세스 토큰이 #{token.expires_at}에 만료됩니다."
end
만료 날짜가 없는 토큰 찾기
이 스크립트는 만료 날짜가 없는 토큰을 찾습니다:
expires_at
값이 NULL
입니다.
아직 GitLab 16.0 버전 이상으로 업그레이드하지 않은 사용자의 경우,
토큰 expires_at
값은 NULL
이며, 만료 날짜를 추가할
대상 토큰을 식별하는 데 사용할 수 있습니다.
이 스크립트는 Rails 콘솔 또는 Rails 러너에서 사용할 수 있습니다:
- 터미널 창에서 인스턴스에 연결합니다.
-
sudo gitlab-rails console
로 Rails 콘솔 세션을 시작합니다. - 아래의 전체
tokens_with_no_expiry.rb
스크립트를 붙여넣습니다. - Enter를 누릅니다.
- 터미널 창에서 인스턴스에 연결합니다.
- 아래의 전체
tokens_with_no_expiry.rb
스크립트를 복사하여 인스턴스의 파일로 저장합니다:- 파일 이름:
tokens_with_no_expiry.rb
. - 파일은
git:git
에 접근 가능해야 합니다.
- 파일 이름:
-
다음 명령을 실행하며, 경로를
tokens_with_no_expiry.rb
파일의 전체 경로로 변경합니다:sudo gitlab-rails runner /path/to/tokens_with_no_expiry.rb
자세한 정보는 Rails 러너 문제 해결 섹션을 참조하세요.
tokens_with_no_expiry.rb
이 스크립트는 expires_at
값이 설정되지 않은 토큰을 찾습니다.
# 이 스크립트는 expires_at 값이 설정되지 않은 토큰을 찾습니다.
# 만료 예정인 개인 액세스 토큰 확인
PersonalAccessToken.owner_is_human.where(expires_at: nil).find_each do |token|
puts "개인 액세스 토큰 ID: #{token.id}, 사용자 이메일: #{token.user.email}, 이름: #{token.name}, 범위: #{token.scopes}, 마지막 사용: #{token.last_used_at}의 expires_at이 nil입니다."
end
# 만료 예정인 프로젝트 및 그룹 액세스 토큰 확인
PersonalAccessToken.project_access_token.where(expires_at: nil).find_each do |token|
token.user.members.each do |member|
type = member.is_a?(GroupMember) ? '그룹' : '프로젝트'
puts "#{type} ID #{member.source_id}에서 #{type} 액세스 토큰의 expires_at이 nil입니다. 토큰 ID: #{token.id}, 이름: #{token.name}, 범위: #{token.scopes}, 마지막 사용: #{token.last_used_at}"
end
end