GitLab git clone 연결 오류를 점검하는 유령 네트워크 엔지니어 일러스트

GitLab git clone 연결 오류 해결: 내부 IP·포트·HTTPS·SSH 점검 순서

2026년 8월 21일

3줄 요약

  • GitLab 웹 화면이 내부망에서 열린다고 외부 네트워크의 git clone까지 가능한 것은 아니다. clone URL이 사설 IP라면 외부 인터넷에서 직접 접근할 수 없다.
  • 먼저 nslookup·curl·nc로 DNS와 포트까지 확인한 뒤, HTTPS 인증 또는 SSH 키 문제를 구분한다.
  • Self-Managed GitLab은 사용자가 실제로 접속하는 주소와 external_url, Docker 포트 매핑, SSH 포트가 일치해야 올바른 clone URL을 표시한다.

자체 구축한 GitLab의 웹 화면은 서버와 같은 네트워크에서 정상적으로 열리는데, 다른 장소나 외부 네트워크에서 저장소를 clone하면 실패할 수 있다.

git clone https://gitlab.example.com/group/project.git

이때 Git을 다시 설치하거나 저장소를 새로 만들기 전에 어느 단계에서 연결이 끊겼는지부터 구분해야 한다. DNS가 실패했는지, 서버 포트에 도달하지 못했는지, GitLab 인증에서 거절됐는지에 따라 해결 방법이 완전히 다르다.

이 글은 사설망의 Self-Managed GitLab을 다른 네트워크에서 사용하려다 clone 연결을 점검했던 내용을 공개용으로 일반화한 기록이다. 실제 내부 IP, 포트, 도메인, 그룹명과 사용자명은 예시값으로 변경했다. 정확한 오류 원문과 최종 조치가 보존되지 않은 부분은 성공 사례처럼 꾸미지 않고, GitLab·Git 공식 문서에 따라 재현 가능한 진단 절차로 정리했다.

공식 문서 확인 기준일은 2026년 8월 21일이다.

먼저 결론: 웹 접속·네트워크·인증은 서로 다른 단계다

git clone은 대략 다음 단계를 거친다.

  1. clone URL의 호스트명을 DNS로 조회한다.
  2. HTTPS라면 보통 443, SSH라면 22 또는 별도 SSH 포트에 연결한다.
  3. TLS 인증서나 SSH 호스트 키를 확인한다.
  4. GitLab이 사용자 토큰 또는 SSH 공개키를 인증한다.
  5. 사용자가 해당 프로젝트를 읽을 권한이 있는지 확인한다.
  6. 저장소 객체를 전송한다.

따라서 브라우저에서 로그인 페이지가 보이는 것만으로 4~6단계까지 정상이라고 판단할 수 없다. 반대로 Connection timed out인데 토큰부터 바꾸는 것도 순서가 맞지 않는다.

오류 문구별로 시작점을 정한다

대표 오류 의미 먼저 확인할 부분
Could not resolve host 호스트명 DNS 조회 실패 DNS 레코드, 도메인 오타
Connection timed out 대상 포트까지 응답 없음 라우팅, 공유기 포트 전달, 방화벽
Connection refused 호스트에는 도달했지만 포트가 연결을 거부 서비스 listen 상태, Docker 포트 매핑
SSL certificate problem 인증서 체인·만료·호스트명 불일치 인증서와 clone URL의 도메인
HTTP Basic: Access denied HTTPS 인증 실패 토큰, 권한, 저장된 자격 증명
Permission denied (publickey) SSH 공개키 인증 실패 GitLab 등록 키, 사용 중인 개인키
repository not found 경로가 틀렸거나 읽기 권한 없음 namespace·project 경로와 멤버 권한

이 표에서 앞의 세 오류는 주로 연결, 뒤의 세 오류는 주로 인증·권한 문제다.

1. clone URL에 사설 IP가 들어 있는지 확인한다

다음 주소 대역은 사설 네트워크에서만 사용한다.

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16

IANA는 이 주소가 공용 인터넷에 나타나지 않아야 하는 private-use 주소라고 설명한다. GitLab의 Code 메뉴에 다음처럼 사설 IP가 표시된다면, 같은 사내망·가정망·VPN 안에서는 동작해도 일반 외부 인터넷에서는 직접 접근할 수 없다.

http://10.10.10.20:8080/group/project.git

외부 사용이 필요하다면 일반적으로 다음 중 하나가 필요하다.

  • VPN이나 Tailscale처럼 허가된 사설망 경로 사용
  • 공인 도메인과 HTTPS 리버스 프록시 구성
  • 공유기·클라우드 방화벽의 필요한 포트만 제한적으로 개방

GitLab을 무조건 인터넷 전체에 공개할 필요는 없다. 개인 서버라면 VPN 방식이 공격 표면을 줄이는 데 유리하다. 외부 공개를 선택한다면 HTTPS, 접근 제어, 최신 보안 업데이트, 백업을 함께 운영한다.

2. DNS가 올바른 주소를 반환하는지 확인한다

클라이언트 PC에서 호스트명을 확인한다.

nslookup gitlab.example.com

macOS나 Linux에서는 다음 명령도 사용할 수 있다.

dig +short gitlab.example.com

확인할 내용은 다음과 같다.

  • 외부에서 조회했는데 내부 사설 IP가 반환되지 않는가
  • 이전 서버의 공인 IP가 캐시에 남아 있지 않은가
  • 도메인 철자가 clone URL과 정확히 같은가
  • VPN 전용 도메인이라면 VPN 연결 상태에서만 의도한 IP가 반환되는가

DNS 결과가 없으면 Git 인증까지 진행되지 않는다. 먼저 레코드와 클라이언트 DNS를 고친다.

3. GitLab 웹 포트까지 도달하는지 확인한다

HTTPS 헤더만 요청해 네트워크 경로를 확인한다.

curl -I --connect-timeout 10 https://gitlab.example.com/users/sign_in

로그인 페이지가 200 또는 로그인 경로로 가는 301·302를 반환한다면 HTTP 계층에는 도달한 것이다. timeout이라면 인증 문제가 아니라 라우팅·방화벽·포트 전달을 우선 확인한다.

포트 자체도 검사한다.

nc -vz gitlab.example.com 443
nc -vz gitlab.example.com 22

SSH를 별도 포트로 공개했다면 실제 포트를 사용한다.

nc -vz gitlab.example.com 2424

회사나 공용 네트워크는 임의 SSH 포트를 차단할 수 있다. 같은 노트북이라도 모바일 핫스팟과 사내망에서 결과가 다르면 클라이언트가 연결된 네트워크 정책도 확인한다.

4. Git이 표시하는 실제 clone URL을 점검한다

GitLab 공식 문서에 따르면 Self-Managed GitLab의 external_url은 웹 UI와 HTTP·HTTPS clone URL 등에 사용된다. 사용자가 실제 접속하는 주소와 이 값이 다르면 GitLab 화면이 내부 IP나 잘못된 포트를 clone URL로 안내할 수 있다.

Linux package 설치라면 설정을 확인한다.

sudo grep -n '^external_url' /etc/gitlab/gitlab.rb

예시는 다음과 같다.

external_url 'https://gitlab.example.com'

변경 전에는 현재 설정과 백업을 확인한다. 수정했다면 GitLab 공식 절차에 따라 재구성한다.

sudo gitlab-ctl reconfigure
sudo gitlab-ctl status

Docker로 운영한다면 GITLAB_OMNIBUS_CONFIGexternal_url과 호스트 포트 매핑이 일치해야 한다.

services:
  gitlab:
    image: gitlab/gitlab-ee:<고정한-버전>
    hostname: gitlab.example.com
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.example.com'
        gitlab_rails['gitlab_shell_ssh_port'] = 2424
    ports:
      - "443:443"
      - "2424:22"

GitLab Docker 공식 문서는 사용자 지정 SSH 포트를 쓸 때 표시 포트인 gitlab_shell_ssh_port와 Docker의 hostPort:containerPort 매핑을 함께 맞추는 예시를 제공한다.

Compose 설정을 바꾸기 전에는 데이터·설정·로그 볼륨의 백업과 복구 방법을 확인한다. 포트 오류를 고친다고 GitLab 데이터 볼륨을 삭제할 이유는 없다.

5. HTTPS clone은 git ls-remote로 먼저 시험한다

전체 저장소를 받기 전에 원격 참조만 조회하면 연결과 인증을 빠르게 구분할 수 있다.

git ls-remote https://gitlab.example.com/group/project.git

네트워크와 인증이 정상이면 브랜치·태그의 해시와 참조가 출력된다. 비공개 저장소라면 자격 증명을 요청할 수 있다.

2단계 인증을 사용하거나 인스턴스 정책상 비밀번호 인증을 허용하지 않는다면 GitLab 공식 문서에 따라 HTTPS 비밀번호 입력란에 personal access token을 사용한다. 저장소를 읽기만 한다면 필요 이상으로 넓은 권한을 부여하지 않는다.

토큰을 URL에 직접 넣지 않는 방식이 안전하다.

git clone https://my-user@gitlab.example.com/group/project.git

프롬프트가 나타나면 비밀번호 대신 토큰을 입력한다.

다음 방식은 셸 기록, 프로세스 목록, 로그에 토큰이 남을 수 있으므로 피한다.

https://사용자명:실제토큰@gitlab.example.com/group/project.git

글·메신저·CI 로그에 clone 명령을 공유할 때 URL에 토큰이 포함되지 않았는지 반드시 확인한다. 노출했다면 즉시 폐기하고 새 토큰을 발급한다.

6. SSH clone은 포트와 키를 따로 점검한다

기본 SSH 포트라면 연결을 검증한다.

ssh -T git@gitlab.example.com

사용자 지정 포트라면 -p를 붙인다.

ssh -T -p 2424 git@gitlab.example.com

정상 연결에서는 GitLab 환영 메시지가 나타난다. Permission denied (publickey)라면 방화벽보다 다음 항목을 본다.

  • 현재 PC의 공개키가 GitLab 계정에 등록됐는가
  • 개인키 파일이 ssh-agent에 올라와 있는가
  • 여러 키 중 다른 키를 보내고 있지 않은가
  • ~/.ssh와 개인키 권한이 너무 넓지 않은가
  • clone URL의 SSH 포트가 실제 공개 포트와 같은가

어떤 키를 보내는지 상세히 보려면 GitLab 공식 SSH 문제 해결 문서의 verbose 명령을 사용한다.

ssh -Tvvv -p 2424 git@gitlab.example.com

verbose 로그에는 사용자명·호스트·키 경로와 네트워크 정보가 포함될 수 있다. 공개 질문에 원문 전체를 올리지 말고 필요한 줄만 마스킹한다. 개인키 내용은 어떤 경우에도 공유하지 않는다.

7. 서버에서 서비스와 포트 매핑을 확인한다

GitLab 서버에 접속할 수 있다면 listen 상태를 확인한다.

sudo ss -lntp

전체 출력을 외부에 공개하지 말고, 운영에 사용하는 HTTPS·SSH 포트가 의도한 주소에서 LISTEN 중인지 확인한다.

Docker 설치라면 컨테이너 상태와 노출 포트를 본다.

docker ps --filter name=gitlab \
  --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'

docker inspect gitlab \
  --format '{{json .NetworkSettings.Ports}}'

GitLab 내부 서비스 상태도 확인한다.

docker exec gitlab gitlab-ctl status
docker exec gitlab gitlab-rake gitlab:check SANITIZE=true

Linux package 설치라면 docker exec gitlab 부분을 빼고 실행한다.

sudo gitlab-ctl status
sudo gitlab-rake gitlab:check SANITIZE=true

GitLab 공식 문서는 SANITIZE=true가 점검 출력에서 프로젝트 이름을 생략하는 데 도움이 된다고 안내한다. 그래도 외부 공유 전에는 도메인, 사용자명, 저장 경로와 토큰을 다시 검수한다.

서비스 생존 여부는 공식 health endpoint로 확인할 수 있다.

curl https://gitlab.example.com/-/health

정상 예시는 다음과 같다.

GitLab OK

이 응답은 GitLab 애플리케이션이 살아 있다는 근거이지, 외부 SSH 포트나 특정 프로젝트 권한까지 정상이라는 뜻은 아니다.

8. 원인이 보이지 않을 때만 Git trace를 사용한다

HTTPS 연결의 상세 흐름을 확인할 수 있다.

GIT_TRACE=1 GIT_CURL_VERBOSE=1 \
git ls-remote https://gitlab.example.com/group/project.git

Git 공식 문서에서 GIT_CURL_VERBOSE는 HTTP 통신에 사용하는 curl 메시지를, GIT_TRACE는 Git의 일반 실행 trace를 출력한다고 설명한다.

trace에는 요청 헤더, 호스트, 경로와 인증 관련 정보가 나타날 수 있다. 화면을 공유하기 전에 Authorization, Cookie, 사용자명, 토큰과 내부 주소를 삭제한다. 진단이 끝나면 환경변수를 셸 전역 설정에 남기지 않는다.

TLS 오류가 보이더라도 다음 우회 설정을 상시 적용하지 않는다.

git config --global http.sslVerify false

인증서 검증을 끄면 중간자 공격을 탐지하지 못한다. 인증서의 도메인, 만료일, 중간 인증서 체인을 고치는 것이 정상적인 해결이다.

외부 접속 구조를 선택하는 기준

VPN 전용

  • 개인용·관리용 GitLab에 적합하다.
  • GitLab 포트를 공용 인터넷에 직접 노출하지 않아도 된다.
  • 사용자는 먼저 VPN에 연결해야 한다.

공인 도메인과 HTTPS

  • 여러 장소·기기·CI에서 접근하기 편하다.
  • 올바른 DNS, 인증서, 리버스 프록시와 접근 정책이 필요하다.
  • HTTPS clone과 SSH clone은 서로 다른 포트를 사용할 수 있다.

공유기 포트 전달

  • 외부 포트가 서버의 실제 서비스 포트로 정확히 전달돼야 한다.
  • 이중 NAT·CGNAT 환경에서는 공유기 설정만으로 외부 접속이 되지 않을 수 있다.
  • 관리 페이지나 불필요한 포트까지 함께 공개하지 않는다.

어떤 구조든 clone URL에는 사용자가 실제로 도달할 수 있는 호스트명과 포트가 표시돼야 한다.

최종 점검 순서

아래 순서로 보면 인증 문제와 네트워크 문제를 섞지 않을 수 있다.

# 1. DNS
nslookup gitlab.example.com

# 2. HTTPS 포트
curl -I --connect-timeout 10 https://gitlab.example.com/users/sign_in

# 3. GitLab 상태
curl https://gitlab.example.com/-/health

# 4. 저장소 연결·인증
git ls-remote https://gitlab.example.com/group/project.git

# 5. SSH를 쓴다면
ssh -T -p 2424 git@gitlab.example.com

# 6. 마지막으로 실제 clone
git clone https://gitlab.example.com/group/project.git

결과를 해석할 때는 다음 원칙만 기억하면 된다.

  • 1번 실패: DNS 문제
  • 1번 성공, 2번 timeout: 라우팅·방화벽·포트 문제
  • 2번 성공, 4번 인증 실패: 토큰·권한 문제
  • HTTPS 성공, 5번 실패: SSH 포트·키 문제
  • 모두 성공, clone만 실패: 저장 공간·LFS·submodule·대용량 전송처럼 다음 단계 점검

마무리

Self-Managed GitLab의 git clone 오류는 Git 명령 자체보다 접근 주소와 네트워크 경로가 일치하지 않아 발생하는 경우가 많다. 내부망에서만 열리는 사설 IP를 외부에서 사용하거나, GitLab이 잘못된 external_url과 SSH 포트를 clone URL로 보여 주면 인증을 바꿔도 해결되지 않는다.

DNS → 포트 → GitLab 상태 → HTTPS 인증 → SSH 키 순서로 확인하면 변경해야 할 범위를 줄일 수 있다. 무엇보다 토큰을 URL과 로그에 남기지 않고, 인증서 검증을 끄거나 데이터를 삭제하는 임시 우회를 해결책으로 사용하지 않는 것이 중요하다.

공식 문서