LabHub
Get started
배우기 러닝패스 코스

Air-Gapped Mirrors and a Private CA

Go modules: air-gapped builds with a file proxy and vendor

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

Go 모듈을 연결된 쪽에서 새 모듈 캐시로 받아 파일 프록시로 옮기고, 폐쇄망 쪽에서 GOPROXY=file:// 와 vendor 두 길로 빌드한다. go.sum 을 반입 매니페스트로 쓰는 법과, GOFLAGS 한 줄이 vendor 를 무시하게 만드는 함정을 직접 확인한다.

왜 중요한가

Go 는 기본으로 proxy.golang.org 에서 받고 sum.golang.org 에 해시를 묻는다. 폐쇄망에서는 둘 다 닿지 않는다. 모듈 캐시의 cache/download 는 그 자체가 프록시 프로토콜 모양이라 옮기기만 하면 프록시가 되고, go.sum 이 완전하면 체크섬 데이터베이스에 물을 일이 없다. 이 파드는 인터넷(80/443)에 닿으므로 받는 쪽 역할을 하고, 폐쇄망 쪽 확인은 채점기가 바깥으로 가는 HTTP(S)를 닫힌 프록시로 보내 막은 채로 한다.

단계

  1. /root/goair/app 에 모듈 example.com/airgap-hello 를 만들고 rsc.io/quote v1.5.2 의 quote.Hello() 를 출력하는 main.go 를 쓴다. 새 모듈 캐시 GOMODCACHE=/root/goair/outside-cache 로 받고 go mod tidy 까지 한다.
  2. /root/goair/outside-cache/cache/download 의 내용을 /srv/goproxy 로 옮긴다.
  3. 폐쇄망 쪽 설정 /root/goair/inside.envGOPROXY=file:///srv/goproxyGOFLAGS=-mod=readonly 를 적는다.
  4. 그 설정을 읽고 바깥을 막은 채 새 모듈 캐시 /root/goair/inside-cache 로 빌드해 /root/goair/bin/hello-proxy 를 만든다.
  5. /root/goair/app 에서 vendor 디렉터리를 만든다.
  6. 이미지의 GOFLAGS=-mod=mod 를 그대로 둔 채 GOPROXY=off 와 빈 모듈 캐시로 빌드해 본다. 실패 메시지를 /root/goair/gomod-trap.txt 에 저장한다.
  7. GOPROXY=off 에서 vendor 만으로 빌드해 /root/goair/bin/hello-vendor 를 만든다.
  8. go.sum 에서 모듈 zip 의 해시 줄(/go.mod 가 붙지 않은 줄)을 모듈 버전 해시 로 옮긴 반입 기록 /root/goair/intake.txt 를 쓴다. 각 해시는 /srv/goproxy.ziphash 와 같아야 한다.

참고

받는 쪽: 새 모듈 캐시로 의존성 받기

/root/goair/app 에 모듈 example.com/airgap-hello 와 main.go 를 만들고, GOMODCACHE=/root/goair/outside-cachersc.io/quote v1.5.2 를 받아 go mod tidy 까지 한다.

go mod init 으로 모듈을 만들고 go get 으로 버전을 정확히 받습니다. 새 캐시 디렉터리를 GOMODCACHE 로 주면 이번에 받은 것만 그 안에 쌓입니다. tidy 는 쓰이는 의존성을 직접 의존으로 정리합니다.

모듈 캐시를 파일 프록시로 옮기기

/root/goair/outside-cache/cache/download 의 내용을 /srv/goproxy 로 옮긴다.

모듈 캐시의 cache/download 아래는 이미 프록시 프로토콜 모양(@v/list, .info, .mod, .zip)입니다. 디렉터리 구조를 그대로 유지해 복사하세요. 풀린 소스가 있는 캐시의 다른 디렉터리는 필요 없습니다.

폐쇄망 쪽 Go 환경 파일

/root/goair/inside.envGOPROXY=file:///srv/goproxyGOFLAGS=-mod=readonly 를 적는다.

셸이 그대로 읽을 수 있는 이름=값 줄입니다. file 스킴 뒤에는 절대 경로가 오므로 슬래시가 세 개가 됩니다. -mod=readonly 는 빌드가 go.mod 를 몰래 고치지 못하게 합니다.

바깥을 막고 파일 프록시로 빌드

inside.env 를 읽고 바깥을 막은 채 새 모듈 캐시 /root/goair/inside-cache 로 빌드해 /root/goair/bin/hello-proxy 를 만든다.

환경 파일을 export 되게 읽은 뒤 GOMODCACHE 를 새 디렉터리로 주고, 바깥 주소는 닫힌 프록시로 보내세요. 이미 받아 둔 캐시로 빌드하면 프록시를 시험한 것이 아닙니다.

두 번째 길: vendor

/root/goair/app 에서 vendor 디렉터리를 만든다.

go mod 의 하위 명령 가운데 의존성 소스를 저장소 안으로 복사하는 것이 있습니다. 결과로 vendor/modules.txt 가 생기는지 보세요.

vendor 가 있는데도 실패하는 빌드

이미지의 GOFLAGS=-mod=mod 를 그대로 둔 채 GOPROXY=off 와 빈 모듈 캐시로 빌드해 보고, 실패 메시지를 /root/goair/gomod-trap.txt 에 저장한다.

이 단계는 실패를 기록하는 단계입니다. go env GOFLAGS 로 지금 값을 먼저 보세요. -mod=mod 가 vendor 를 어떻게 다루는지 읽기 자료를 떠올리면 메시지가 이해됩니다.

GOPROXY=off 에서 vendor 로 빌드

GOPROXY=off 에서 vendor 만으로 빌드해 /root/goair/bin/hello-vendor 를 만든다.

vendor 를 쓰게 하는 -mod 값이 있습니다. 환경의 GOFLAGS 를 덮어쓰거나 명령줄에서 직접 주세요. 모듈 캐시가 비어 있어도 되어야 합니다.

go.sum 으로 반입 기록 쓰기

go.sum 의 모듈 zip 해시 줄을 모듈 버전 해시 로 옮긴 /root/goair/intake.txt 를 쓴다. 각 해시는 /srv/goproxy.ziphash 와 같아야 한다.

go.sum 의 줄은 모듈, 버전, h1: 해시 세 칸입니다. 버전 뒤에 /go.mod 가 붙은 줄은 go.mod 파일의 해시라 zip 과 다릅니다. 프록시 디렉터리의 .ziphash 파일과 한 줄씩 대조해 보세요.