InfoGrab Docs

Git 트러블슈팅

요약

Git을 사용할 때 예상대로 작동하지 않거나 예상치 못한 상황이 발생할 수 있습니다. GitLab 서버에서 Git 문제를 디버깅할 때, 오래된 버전일 수 있는 시스템에서 제공하는 git 바이너리 대신 /opt/gitlab/embedded/bin/git를 사용하세요.

Git을 사용할 때 예상대로 작동하지 않거나 예상치 못한 상황이 발생할 수 있습니다. 다음은 Git 문제를 트러블슈팅하고 해결하는 데 도움이 되는 몇 가지 팁입니다.

디버깅#

GitLab 서버에서 Git 문제를 디버깅할 때, 오래된 버전일 수 있는 시스템에서 제공하는 git 바이너리 대신 /opt/gitlab/embedded/bin/git를 사용하세요.

Git 명령에 사용자 지정 SSH 키 사용#

GIT_SSH_COMMAND="ssh -i ~/.ssh/gitlabadmin" git <command>

<command>를 실행하고 싶은 Git 명령으로 대체하세요.

SSH를 통한 Git 디버그#

GIT_SSH_COMMAND="ssh -vvv" git clone <git@url> 2>&1 \
| tee /tmp/gitlab-clone-test.log

<git@url>를 리포지터리의 SSH URL로 대체하세요. 출력은 /tmp/gitlab-clone-test.log에 저장됩니다.

HTTPS를 통한 Git 디버그#

GIT_TRACE_PACKET=1 GIT_TRACE=2 GIT_CURL_VERBOSE=1 git clone <url> 2>&1 \
| tee /tmp/gitlab-clone-test.log

<url>을 리포지터리의 HTTPS URL로 대체하세요. 출력은 /tmp/gitlab-clone-test.log에 저장됩니다.

추적을 사용한 Git 디버그#

Git에는 Git 명령 디버깅을 위한 추적의 완전한 세트가 포함되어 있습니다. 예를 들어:

  • GIT_TRACE_PERFORMANCE=1: 성능 데이터 추적을 활성화하여 각 git 호출이 얼마나 걸리는지 표시합니다.
  • GIT_TRACE_SETUP=1: git이 상호작용하는 리포지터리와 환경에 대해 발견하는 내용 추적을 활성화합니다.
  • GIT_TRACE_PACKET=1: 네트워크 작업에 대한 패킷 수준 추적을 활성화합니다.
  • GIT_CURL_VERBOSE=1: curl의 상세 출력을 활성화합니다. 자격 증명이 포함될 수 있습니다.

git push에서 Broken pipe 오류#

원격 리포지터리로 푸시를 시도할 때 Broken pipe 오류가 발생할 수 있습니다. 푸시할 때 일반적으로 다음이 표시됩니다:

Write failed: Broken pipe
fatal: The remote end hung up unexpectedly

이 문제를 해결하기 위한 몇 가지 가능한 해결책이 있습니다.

Git에서 POST 버퍼 크기 증가#

HTTPS를 통한 Git으로 대형 리포지터리를 푸시하려고 할 때 다음과 같은 오류 메시지가 발생할 수 있습니다:

fatal: pack has bad object at offset XXXXXXXXX: inflate returned -5

이 문제를 해결하려면:

  • 로컬 Git 구성에서 http.postBuffer 값을 증가시킵니다. 기본값은 1 MB입니다. 예를 들어, 500 MB 리포지터리를 복제할 때 git clone이 실패하면 다음을 실행합니다:

    1. 터미널 또는 명령 프롬프트를 엽니다.

    2. http.postBuffer 값을 증가시킵니다:

      # http.postBuffer 크기를 바이트 단위로 설정
      git config http.postBuffer 524288000
      

로컬 구성으로 문제가 해결되지 않으면 서버 구성을 수정해야 할 수 있습니다. 이는 주의해서 수행해야 하며 서버 액세스 권한이 있는 경우에만 수행해야 합니다.

  • 서버 측에서 http.postBuffer 증가:

    1. 터미널 또는 명령 프롬프트를 엽니다.

    2. GitLab 인스턴스의 gitlab.rb 파일을 수정합니다:

      gitaly['configuration'] = {
        # ...
        git: {
          # ...
          config: [
            # http.postBuffer 크기를 바이트 단위로 설정
            {key: "http.postBuffer", value: "524288000"},
          ],
        },
      }
      
    3. 구성 변경 사항을 적용합니다:

      sudo gitlab-ctl reconfigure
      

오류: stream 0 was not closed cleanly#

이 오류가 표시되면 느린 인터넷 연결로 인한 것일 수 있습니다:

RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)

SSH 대신 HTTP를 통해 Git을 사용하는 경우, 다음 수정 사항 중 하나를 시도하세요:

  • git config http.postBuffer 52428800으로 Git 구성에서 POST 버퍼 크기를 증가시킵니다.
  • git config http.version HTTP/1.1HTTP/1.1 프로토콜로 전환합니다.

어느 방법으로도 오류가 해결되지 않으면 다른 인터넷 서비스 공급자가 필요할 수 있습니다.

SSH 구성 확인#

SSH를 통해 푸시하는 경우 먼저 SSH 구성을 확인하세요. 'Broken pipe' 오류는 SSH의 근본적인 문제(예: 인증)로 인해 발생할 수 있습니다. SSH 트러블슈팅 문서의 지침을 따라 SSH가 올바르게 구성되어 있는지 확인하세요.

서버 액세스 권한이 있는 GitLab 관리자는 클라이언트 또는 서버에서 SSH keep-alive를 구성하여 세션 타임아웃을 방지할 수도 있습니다.

Note

클라이언트와 서버 모두를 구성할 필요는 없습니다.

클라이언트 측에서 SSH를 구성하려면:

  • UNIX에서 ~/.ssh/config를 편집하고(파일이 없으면 생성) 다음을 추가하거나 편집합니다:

    Host your-gitlab-instance-url.com
      ServerAliveInterval 60
      ServerAliveCountMax 5
    
  • Windows에서 PuTTY를 사용하는 경우, 세션 속성으로 이동한 다음 Connection으로 이동하여 Sending of null packets to keep session active 아래에서 Seconds between keepalives (0 to turn off)60으로 설정합니다.

서버 측에서 SSH를 구성하려면 /etc/ssh/sshd_config를 편집하고 다음을 추가합니다:

ClientAliveInterval 60
ClientAliveCountMax 5

git repack 실행#

'pack-objects' 유형 오류도 표시되는 경우, 원격 리포지터리로 다시 푸시하기 전에 git repack 실행을 시도할 수 있습니다:

git repack
git push

Git 클라이언트 업그레이드#

이전 버전의 Git(< 2.9)을 실행 중인 경우 >= 2.9로 업그레이드하는 것을 고려하세요. 자세한 내용은 Git 리포지터리로 푸시할 때 broken pipe를 참조하세요.

ssh_exchange_identification 오류#

사용자는 SSH를 통해 Git을 사용하여 푸시 또는 풀을 시도할 때 다음 오류가 발생할 수 있습니다:

Please make sure you have the correct access rights
and the repository exists.
...
ssh_exchange_identification: read: Connection reset by peer
fatal: Could not read from remote repository.

또는

ssh_exchange_identification: Connection closed by remote host
fatal: The remote end hung up unexpectedly

또는

kex_exchange_identification: Connection closed by remote host
Connection closed by x.x.x.x port 22

이 오류는 일반적으로 SSH 데몬의 MaxStartups 값이 SSH 연결을 스로틀링하고 있음을 나타냅니다. 이 설정은 SSH 데몬에 대한 동시 미인증 연결의 최대 수를 지정합니다. 모든 연결은 처음에 '미인증'이기 때문에 올바른 인증 자격 증명(SSH 키)을 가진 사용자에게 영향을 미칩니다. 기본값10입니다.

이는 호스트의 sshd 로그를 검사하여 확인할 수 있습니다. Debian 계열 시스템의 경우 /var/log/auth.log를 참조하고, RHEL 파생 버전의 경우 다음 오류에 대해 /var/log/secure를 확인하세요:

sshd[17242]: error: beginning MaxStartups throttling
sshd[17242]: drop connection #1 from [CLIENT_IP]:52114 on [CLIENT_IP]:22 past MaxStartups

이 오류가 없으면 SSH 데몬이 연결을 제한하고 있지 않음을 의미하며, 근본적인 문제가 네트워크와 관련될 수 있습니다.

미인증 동시 SSH 연결 수 증가#

/etc/ssh/sshd_config에 값을 추가하거나 수정하여 GitLab 서버에서 MaxStartups를 증가시킵니다:

MaxStartups 100:30:200

100:30:200은 최대 200에 도달할 때까지 연결의 30%가 삭제되기 전까지 최대 100개의 SSH 세션이 제한 없이 허용된다는 의미입니다.

MaxStartups 값을 수정한 후 구성에 오류가 없는지 확인합니다.

sudo sshd -t -f /etc/ssh/sshd_config

구성 확인이 오류 없이 실행되면 변경사항이 적용되도록 SSH 데몬을 다시 시작해도 안전합니다.

# Debian/Ubuntu
sudo systemctl restart ssh

# CentOS/RHEL
sudo service sshd restart

git push / git pull 중 타임아웃#

리포지터리에서 풀/푸시가 50초 이상 걸리면 타임아웃이 발생합니다. 다음 예시와 같이 수행된 작업 수와 각각의 타이밍에 대한 로그가 포함됩니다:

remote: Running checks for branch: master
remote: Scanning for LFS objects... (153ms)
remote: Calculating new repository size... (canceled after 729ms)

이를 통해 성능이 저하되는 작업을 더 조사하고 서비스 개선 방법에 대한 자세한 정보를 GitLab에 제공할 수 있습니다.

오류: Operation timed out#

Git을 사용할 때 이런 오류가 발생하면 일반적으로 네트워크 문제를 나타냅니다:

ssh: connect to host gitlab.com port 22: Operation timed out
fatal: Could not read from remote repository

근본적인 문제를 파악하는 데 도움이 되는 방법:

  • 로컬 네트워크 또는 방화벽 문제를 배제하기 위해 다른 네트워크를 통해 연결합니다(예: Wi-Fi에서 셀룰러 데이터로 전환).
  • tracerouteping 정보를 수집하려면 다음 bash 명령을 실행합니다: mtr -T -P 22 <gitlab_server>.com. MTR과 출력 읽는 방법에 대해 알아보려면 My Traceroute(MTR)에 관한 Cloudflare 문서를 참조하세요.

오류: transfer closed with outstanding read data remaining#

HTTP를 통해 git clone을 실행할 때 오래된 또는 대용량 리포지터리를 복제하면 다음 오류가 표시될 수 있습니다:

error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

이 문제는 대용량 파일이나 많은 파일을 처리하지 못하는 Git 자체의 일반적인 문제입니다. Git LFS는 이 문제를 해결하기 위해 만들어졌지만 제한이 있습니다. 이는 일반적으로 다음 이유 중 하나로 발생합니다:

  • 리포지터리의 파일 수.
  • 히스토리의 리비전 수.
  • 리포지터리의 대용량 파일 존재.

대용량 리포지터리를 복제할 때 이 오류가 발생하면 복제 깊이를 1의 값으로 줄일 수 있습니다. 예를 들어:

이 방법은 근본 원인을 해결하지는 않지만 리포지터리를 성공적으로 복제할 수 있습니다. 복제 깊이를 1로 줄이려면 다음을 실행합니다:

variables:
  GIT_DEPTH: 1

LDAP 사용자에 대한 SSH를 통한 Git 가져오기에서 Your password expired 오류#

git fetch가 GitLab Self-Managed에서 이 HTTP 403 Forbidden 오류를 반환하면, GitLab 데이터베이스에서 이 사용자의 비밀번호 만료일(users.password_expires_at)이 과거 날짜입니다:

Your password expired. Please access GitLab from a web browser to update your password.

SSO 계정으로 수행된 요청이고 password_expires_atnull이 아닌 경우 이 오류가 반환됩니다:

"403 Forbidden - Your password expired. Please access GitLab from a web browser to update your password."

이 문제를 해결하려면 다음 중 하나로 비밀번호 만료를 업데이트할 수 있습니다:

  • GitLab Rails 콘솔을 사용하여 사용자 데이터를 확인하고 업데이트합니다:

    user = User.find_by_username('')
    user.password_expired?
    user.password_expires_at
    user.update!(password_expires_at: nil)
    
  • gitlab-psql 사용:

    # gitlab-psql
    UPDATE users SET password_expires_at = null WHERE username='';
    

이 버그는 이슈 332455에 보고되었습니다.

Git 가져오기 오류: HTTP Basic: Access Denied#

HTTP(S)를 통해 Git을 사용할 때 HTTP Basic: Access denied 오류가 발생하면 이중 인증 트러블슈팅 가이드를 참조하세요.

이 오류는 Git for Windows 2.46.0 이상에서도 발생할 수 있습니다. 토큰으로 인증할 때 사용자 이름은 어떤 값이든 될 수 있지만 빈 값은 인증 오류를 트리거할 수 있습니다.

이를 해결하려면 사용자 이름 문자열을 지정하세요. 을 GitLab 사용자 이름으로 대체하여 다음 방법 중 하나를 사용하세요:

  • 리포지터리를 복제할 때:

    git clone https://@gitlab.com/path/to/a/project.git
    
  • 기존 원격 URL 업데이트:

    git remote set-url origin https://@gitlab.com/path/to/a/project.git
    
  • 특정 호스트에 대해 항상 사용자 이름을 사용하도록 Git 구성:

    git config --global url."https://@gitlab.com/".insteadOf "https://gitlab.com/"
    

성공적인 git clone 중에 기록된 401 오류#

HTTP로 리포지터리를 복제할 때 production_json.log 파일에 초기 상태 401(미인증)이 표시되고 바로 뒤에 200이 표시될 수 있습니다.

{
   "method":"GET",
   "path":"/group/project.git/info/refs",
   "format":"*/*",
   "controller":"Repositories::GitHttpController",
   "action":"info_refs",
   "status":401,
   "time":"2023-04-18T22:55:15.371Z",
   "remote_ip":"x.x.x.x",
   "ua":"git/2.39.2",
   "correlation_id":"01GYB98MBM28T981DJDGAD98WZ",
   "duration_s":0.03585
}
{
   "method":"GET",
   "path":"/group/project.git/info/refs",
   "format":"*/*",
   "controller":"Repositories::GitHttpController",
   "action":"info_refs",
   "status":200,
   "time":"2023-04-18T22:55:15.714Z",
   "remote_ip":"x.x.x.x",
   "user_id":1,
   "username":"root",
   "ua":"git/2.39.2",
   "correlation_id":"01GYB98MJ0CA3G9K8WDH7HWMQX",
   "duration_s":0.17111
}

HTTP 기본 액세스 인증 작동 방식으로 인해 HTTP를 통해 수행되는 각 Git 작업에 대해 이 초기 401 로그 항목이 예상됩니다.

Git 클라이언트가 복제를 시작하면 GitLab으로 보내는 초기 요청에는 인증 세부 정보가 포함되지 않습니다. GitLab은 해당 요청에 대해 401 Unauthorized 결과를 반환합니다. 몇 밀리초 후 Git 클라이언트는 인증 세부 정보가 포함된 후속 요청을 보냅니다. 이 두 번째 요청은 성공해야 하며 200 OK 로그 항목이 생성됩니다.

401 로그 항목에 해당하는 200 로그 항목이 없으면 Git 클라이언트가 다음 중 하나를 사용하고 있을 가능성이 높습니다:

  • 잘못된 비밀번호.
  • 만료되거나 취소된 토큰.

해결하지 않으면 403(Forbidden) 오류가 발생할 수 있습니다.

HTTP를 통해 Git 작업을 수행할 때 403 오류#

HTTP를 통해 Git 작업을 수행할 때 403(Forbidden) 오류는 IP 주소가 인증 실패 차단으로 차단되었음을 나타냅니다:

fatal: unable to access 'https://gitlab.com/group/project.git/': The requested URL returned error: 403

인증 실패 차단 제한은 GitLab Self-Managed 또는 GitLab SaaS를 사용하는지에 따라 다릅니다.

실패한 인증에 대한 로그 확인#

403production_json.log에서 볼 수 있습니다:

{
   "method":"GET",
   "path":"/group/project.git/info/refs",
   "format":"*/*",
   "controller":"Repositories::GitHttpController",
   "action":"info_refs",
   "status":403,
   "time":"2023-04-19T22:14:25.894Z",
   "remote_ip":"x.x.x.x",
   "user_id":1,
   "username":"root",
   "ua":"git/2.39.2",
   "correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
   "duration_s":0.00875
}

IP 주소가 차단된 경우 auth_json.log에 해당 로그 항목이 있습니다:

{
    "severity":"ERROR",
    "time":"2023-04-19T22:14:25.893Z",
    "correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
    "message":"Rack_Attack",
    "env":"blocklist",
    "remote_ip":"x.x.x.x",
    "request_method":"GET",
    "path":"/group/project.git/info/refs?service=git-upload-pack"}

Git 트러블슈팅

Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기
요약

Git을 사용할 때 예상대로 작동하지 않거나 예상치 못한 상황이 발생할 수 있습니다. GitLab 서버에서 Git 문제를 디버깅할 때, 오래된 버전일 수 있는 시스템에서 제공하는 git 바이너리 대신 /opt/gitlab/embedded/bin/git를 사용하세요.

Git을 사용할 때 예상대로 작동하지 않거나 예상치 못한 상황이 발생할 수 있습니다. 다음은 Git 문제를 트러블슈팅하고 해결하는 데 도움이 되는 몇 가지 팁입니다.

디버깅#

GitLab 서버에서 Git 문제를 디버깅할 때, 오래된 버전일 수 있는 시스템에서 제공하는 git 바이너리 대신 /opt/gitlab/embedded/bin/git를 사용하세요.

Git 명령에 사용자 지정 SSH 키 사용#

GIT_SSH_COMMAND="ssh -i ~/.ssh/gitlabadmin" git <command>

<command>를 실행하고 싶은 Git 명령으로 대체하세요.

SSH를 통한 Git 디버그#

GIT_SSH_COMMAND="ssh -vvv" git clone <git@url> 2>&1 \
| tee /tmp/gitlab-clone-test.log

<git@url>를 리포지터리의 SSH URL로 대체하세요. 출력은 /tmp/gitlab-clone-test.log에 저장됩니다.

HTTPS를 통한 Git 디버그#

GIT_TRACE_PACKET=1 GIT_TRACE=2 GIT_CURL_VERBOSE=1 git clone <url> 2>&1 \
| tee /tmp/gitlab-clone-test.log

<url>을 리포지터리의 HTTPS URL로 대체하세요. 출력은 /tmp/gitlab-clone-test.log에 저장됩니다.

추적을 사용한 Git 디버그#

Git에는 Git 명령 디버깅을 위한 추적의 완전한 세트가 포함되어 있습니다. 예를 들어:

  • GIT_TRACE_PERFORMANCE=1: 성능 데이터 추적을 활성화하여 각 git 호출이 얼마나 걸리는지 표시합니다.
  • GIT_TRACE_SETUP=1: git이 상호작용하는 리포지터리와 환경에 대해 발견하는 내용 추적을 활성화합니다.
  • GIT_TRACE_PACKET=1: 네트워크 작업에 대한 패킷 수준 추적을 활성화합니다.
  • GIT_CURL_VERBOSE=1: curl의 상세 출력을 활성화합니다. 자격 증명이 포함될 수 있습니다.

git push에서 Broken pipe 오류#

원격 리포지터리로 푸시를 시도할 때 Broken pipe 오류가 발생할 수 있습니다. 푸시할 때 일반적으로 다음이 표시됩니다:

Write failed: Broken pipe
fatal: The remote end hung up unexpectedly

이 문제를 해결하기 위한 몇 가지 가능한 해결책이 있습니다.

Git에서 POST 버퍼 크기 증가#

HTTPS를 통한 Git으로 대형 리포지터리를 푸시하려고 할 때 다음과 같은 오류 메시지가 발생할 수 있습니다:

fatal: pack has bad object at offset XXXXXXXXX: inflate returned -5

이 문제를 해결하려면:

  • 로컬 Git 구성에서 http.postBuffer 값을 증가시킵니다. 기본값은 1 MB입니다. 예를 들어, 500 MB 리포지터리를 복제할 때 git clone이 실패하면 다음을 실행합니다:

    1. 터미널 또는 명령 프롬프트를 엽니다.

    2. http.postBuffer 값을 증가시킵니다:

      # http.postBuffer 크기를 바이트 단위로 설정
      git config http.postBuffer 524288000
      

로컬 구성으로 문제가 해결되지 않으면 서버 구성을 수정해야 할 수 있습니다. 이는 주의해서 수행해야 하며 서버 액세스 권한이 있는 경우에만 수행해야 합니다.

  • 서버 측에서 http.postBuffer 증가:

    1. 터미널 또는 명령 프롬프트를 엽니다.

    2. GitLab 인스턴스의 gitlab.rb 파일을 수정합니다:

      gitaly['configuration'] = {
        # ...
        git: {
          # ...
          config: [
            # http.postBuffer 크기를 바이트 단위로 설정
            {key: "http.postBuffer", value: "524288000"},
          ],
        },
      }
      
    3. 구성 변경 사항을 적용합니다:

      sudo gitlab-ctl reconfigure
      

오류: stream 0 was not closed cleanly#

이 오류가 표시되면 느린 인터넷 연결로 인한 것일 수 있습니다:

RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)

SSH 대신 HTTP를 통해 Git을 사용하는 경우, 다음 수정 사항 중 하나를 시도하세요:

  • git config http.postBuffer 52428800으로 Git 구성에서 POST 버퍼 크기를 증가시킵니다.
  • git config http.version HTTP/1.1HTTP/1.1 프로토콜로 전환합니다.

어느 방법으로도 오류가 해결되지 않으면 다른 인터넷 서비스 공급자가 필요할 수 있습니다.

SSH 구성 확인#

SSH를 통해 푸시하는 경우 먼저 SSH 구성을 확인하세요. 'Broken pipe' 오류는 SSH의 근본적인 문제(예: 인증)로 인해 발생할 수 있습니다. SSH 트러블슈팅 문서의 지침을 따라 SSH가 올바르게 구성되어 있는지 확인하세요.

서버 액세스 권한이 있는 GitLab 관리자는 클라이언트 또는 서버에서 SSH keep-alive를 구성하여 세션 타임아웃을 방지할 수도 있습니다.

Note

클라이언트와 서버 모두를 구성할 필요는 없습니다.

클라이언트 측에서 SSH를 구성하려면:

  • UNIX에서 ~/.ssh/config를 편집하고(파일이 없으면 생성) 다음을 추가하거나 편집합니다:

    Host your-gitlab-instance-url.com
      ServerAliveInterval 60
      ServerAliveCountMax 5
    
  • Windows에서 PuTTY를 사용하는 경우, 세션 속성으로 이동한 다음 Connection으로 이동하여 Sending of null packets to keep session active 아래에서 Seconds between keepalives (0 to turn off)60으로 설정합니다.

서버 측에서 SSH를 구성하려면 /etc/ssh/sshd_config를 편집하고 다음을 추가합니다:

ClientAliveInterval 60
ClientAliveCountMax 5

git repack 실행#

'pack-objects' 유형 오류도 표시되는 경우, 원격 리포지터리로 다시 푸시하기 전에 git repack 실행을 시도할 수 있습니다:

git repack
git push

Git 클라이언트 업그레이드#

이전 버전의 Git(< 2.9)을 실행 중인 경우 >= 2.9로 업그레이드하는 것을 고려하세요. 자세한 내용은 Git 리포지터리로 푸시할 때 broken pipe를 참조하세요.

ssh_exchange_identification 오류#

사용자는 SSH를 통해 Git을 사용하여 푸시 또는 풀을 시도할 때 다음 오류가 발생할 수 있습니다:

Please make sure you have the correct access rights
and the repository exists.
...
ssh_exchange_identification: read: Connection reset by peer
fatal: Could not read from remote repository.

또는

ssh_exchange_identification: Connection closed by remote host
fatal: The remote end hung up unexpectedly

또는

kex_exchange_identification: Connection closed by remote host
Connection closed by x.x.x.x port 22

이 오류는 일반적으로 SSH 데몬의 MaxStartups 값이 SSH 연결을 스로틀링하고 있음을 나타냅니다. 이 설정은 SSH 데몬에 대한 동시 미인증 연결의 최대 수를 지정합니다. 모든 연결은 처음에 '미인증'이기 때문에 올바른 인증 자격 증명(SSH 키)을 가진 사용자에게 영향을 미칩니다. 기본값10입니다.

이는 호스트의 sshd 로그를 검사하여 확인할 수 있습니다. Debian 계열 시스템의 경우 /var/log/auth.log를 참조하고, RHEL 파생 버전의 경우 다음 오류에 대해 /var/log/secure를 확인하세요:

sshd[17242]: error: beginning MaxStartups throttling
sshd[17242]: drop connection #1 from [CLIENT_IP]:52114 on [CLIENT_IP]:22 past MaxStartups

이 오류가 없으면 SSH 데몬이 연결을 제한하고 있지 않음을 의미하며, 근본적인 문제가 네트워크와 관련될 수 있습니다.

미인증 동시 SSH 연결 수 증가#

/etc/ssh/sshd_config에 값을 추가하거나 수정하여 GitLab 서버에서 MaxStartups를 증가시킵니다:

MaxStartups 100:30:200

100:30:200은 최대 200에 도달할 때까지 연결의 30%가 삭제되기 전까지 최대 100개의 SSH 세션이 제한 없이 허용된다는 의미입니다.

MaxStartups 값을 수정한 후 구성에 오류가 없는지 확인합니다.

sudo sshd -t -f /etc/ssh/sshd_config

구성 확인이 오류 없이 실행되면 변경사항이 적용되도록 SSH 데몬을 다시 시작해도 안전합니다.

# Debian/Ubuntu
sudo systemctl restart ssh

# CentOS/RHEL
sudo service sshd restart

git push / git pull 중 타임아웃#

리포지터리에서 풀/푸시가 50초 이상 걸리면 타임아웃이 발생합니다. 다음 예시와 같이 수행된 작업 수와 각각의 타이밍에 대한 로그가 포함됩니다:

remote: Running checks for branch: master
remote: Scanning for LFS objects... (153ms)
remote: Calculating new repository size... (canceled after 729ms)

이를 통해 성능이 저하되는 작업을 더 조사하고 서비스 개선 방법에 대한 자세한 정보를 GitLab에 제공할 수 있습니다.

오류: Operation timed out#

Git을 사용할 때 이런 오류가 발생하면 일반적으로 네트워크 문제를 나타냅니다:

ssh: connect to host gitlab.com port 22: Operation timed out
fatal: Could not read from remote repository

근본적인 문제를 파악하는 데 도움이 되는 방법:

  • 로컬 네트워크 또는 방화벽 문제를 배제하기 위해 다른 네트워크를 통해 연결합니다(예: Wi-Fi에서 셀룰러 데이터로 전환).
  • tracerouteping 정보를 수집하려면 다음 bash 명령을 실행합니다: mtr -T -P 22 <gitlab_server>.com. MTR과 출력 읽는 방법에 대해 알아보려면 My Traceroute(MTR)에 관한 Cloudflare 문서를 참조하세요.

오류: transfer closed with outstanding read data remaining#

HTTP를 통해 git clone을 실행할 때 오래된 또는 대용량 리포지터리를 복제하면 다음 오류가 표시될 수 있습니다:

error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

이 문제는 대용량 파일이나 많은 파일을 처리하지 못하는 Git 자체의 일반적인 문제입니다. Git LFS는 이 문제를 해결하기 위해 만들어졌지만 제한이 있습니다. 이는 일반적으로 다음 이유 중 하나로 발생합니다:

  • 리포지터리의 파일 수.
  • 히스토리의 리비전 수.
  • 리포지터리의 대용량 파일 존재.

대용량 리포지터리를 복제할 때 이 오류가 발생하면 복제 깊이를 1의 값으로 줄일 수 있습니다. 예를 들어:

이 방법은 근본 원인을 해결하지는 않지만 리포지터리를 성공적으로 복제할 수 있습니다. 복제 깊이를 1로 줄이려면 다음을 실행합니다:

variables:
  GIT_DEPTH: 1

LDAP 사용자에 대한 SSH를 통한 Git 가져오기에서 Your password expired 오류#

git fetch가 GitLab Self-Managed에서 이 HTTP 403 Forbidden 오류를 반환하면, GitLab 데이터베이스에서 이 사용자의 비밀번호 만료일(users.password_expires_at)이 과거 날짜입니다:

Your password expired. Please access GitLab from a web browser to update your password.

SSO 계정으로 수행된 요청이고 password_expires_atnull이 아닌 경우 이 오류가 반환됩니다:

"403 Forbidden - Your password expired. Please access GitLab from a web browser to update your password."

이 문제를 해결하려면 다음 중 하나로 비밀번호 만료를 업데이트할 수 있습니다:

  • GitLab Rails 콘솔을 사용하여 사용자 데이터를 확인하고 업데이트합니다:

    user = User.find_by_username('')
    user.password_expired?
    user.password_expires_at
    user.update!(password_expires_at: nil)
    
  • gitlab-psql 사용:

    # gitlab-psql
    UPDATE users SET password_expires_at = null WHERE username='';
    

이 버그는 이슈 332455에 보고되었습니다.

Git 가져오기 오류: HTTP Basic: Access Denied#

HTTP(S)를 통해 Git을 사용할 때 HTTP Basic: Access denied 오류가 발생하면 이중 인증 트러블슈팅 가이드를 참조하세요.

이 오류는 Git for Windows 2.46.0 이상에서도 발생할 수 있습니다. 토큰으로 인증할 때 사용자 이름은 어떤 값이든 될 수 있지만 빈 값은 인증 오류를 트리거할 수 있습니다.

이를 해결하려면 사용자 이름 문자열을 지정하세요. 을 GitLab 사용자 이름으로 대체하여 다음 방법 중 하나를 사용하세요:

  • 리포지터리를 복제할 때:

    git clone https://@gitlab.com/path/to/a/project.git
    
  • 기존 원격 URL 업데이트:

    git remote set-url origin https://@gitlab.com/path/to/a/project.git
    
  • 특정 호스트에 대해 항상 사용자 이름을 사용하도록 Git 구성:

    git config --global url."https://@gitlab.com/".insteadOf "https://gitlab.com/"
    

성공적인 git clone 중에 기록된 401 오류#

HTTP로 리포지터리를 복제할 때 production_json.log 파일에 초기 상태 401(미인증)이 표시되고 바로 뒤에 200이 표시될 수 있습니다.

{
   "method":"GET",
   "path":"/group/project.git/info/refs",
   "format":"*/*",
   "controller":"Repositories::GitHttpController",
   "action":"info_refs",
   "status":401,
   "time":"2023-04-18T22:55:15.371Z",
   "remote_ip":"x.x.x.x",
   "ua":"git/2.39.2",
   "correlation_id":"01GYB98MBM28T981DJDGAD98WZ",
   "duration_s":0.03585
}
{
   "method":"GET",
   "path":"/group/project.git/info/refs",
   "format":"*/*",
   "controller":"Repositories::GitHttpController",
   "action":"info_refs",
   "status":200,
   "time":"2023-04-18T22:55:15.714Z",
   "remote_ip":"x.x.x.x",
   "user_id":1,
   "username":"root",
   "ua":"git/2.39.2",
   "correlation_id":"01GYB98MJ0CA3G9K8WDH7HWMQX",
   "duration_s":0.17111
}

HTTP 기본 액세스 인증 작동 방식으로 인해 HTTP를 통해 수행되는 각 Git 작업에 대해 이 초기 401 로그 항목이 예상됩니다.

Git 클라이언트가 복제를 시작하면 GitLab으로 보내는 초기 요청에는 인증 세부 정보가 포함되지 않습니다. GitLab은 해당 요청에 대해 401 Unauthorized 결과를 반환합니다. 몇 밀리초 후 Git 클라이언트는 인증 세부 정보가 포함된 후속 요청을 보냅니다. 이 두 번째 요청은 성공해야 하며 200 OK 로그 항목이 생성됩니다.

401 로그 항목에 해당하는 200 로그 항목이 없으면 Git 클라이언트가 다음 중 하나를 사용하고 있을 가능성이 높습니다:

  • 잘못된 비밀번호.
  • 만료되거나 취소된 토큰.

해결하지 않으면 403(Forbidden) 오류가 발생할 수 있습니다.

HTTP를 통해 Git 작업을 수행할 때 403 오류#

HTTP를 통해 Git 작업을 수행할 때 403(Forbidden) 오류는 IP 주소가 인증 실패 차단으로 차단되었음을 나타냅니다:

fatal: unable to access 'https://gitlab.com/group/project.git/': The requested URL returned error: 403

인증 실패 차단 제한은 GitLab Self-Managed 또는 GitLab SaaS를 사용하는지에 따라 다릅니다.

실패한 인증에 대한 로그 확인#

403production_json.log에서 볼 수 있습니다:

{
   "method":"GET",
   "path":"/group/project.git/info/refs",
   "format":"*/*",
   "controller":"Repositories::GitHttpController",
   "action":"info_refs",
   "status":403,
   "time":"2023-04-19T22:14:25.894Z",
   "remote_ip":"x.x.x.x",
   "user_id":1,
   "username":"root",
   "ua":"git/2.39.2",
   "correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
   "duration_s":0.00875
}

IP 주소가 차단된 경우 auth_json.log에 해당 로그 항목이 있습니다:

{
    "severity":"ERROR",
    "time":"2023-04-19T22:14:25.893Z",
    "correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
    "message":"Rack_Attack",
    "env":"blocklist",
    "remote_ip":"x.x.x.x",
    "request_method":"GET",
    "path":"/group/project.git/info/refs?service=git-upload-pack"}