아테네(Athens)를 이용한 Go 모듈 관리

검프·2020년 6월 22일
4

회사에서 개발과 운영을 하다보면 서버에서 Outbound 네트워크 정책을 제한적으로 운영하는 경우가 많습니다. 다름아닌 보안 때문인데요, Outbound 네트워크가 열려 있게되면 외부 공격으로부터 취약해 질 수 있습니다. 물론 제한한다고해서 반드시 안전하다는 것은 아니지만, 적절한 정책을 운영하는 것과 아닌 것에는 차이가 크겠죠.

최근 개발 환경은 온라인으로 의존성을 관리하는 경우가 대부분입니다. 이렇다보니 프로젝트의 빌드, 배포, 운영을 위한 여러 상황에서 보안 정책과 충돌이 발생하기도합니다. 이런 경우 Private repository를 구축하는 것으로 문제를 해결할 수 있습니다. 대표적으로 Sonatype의 Nexus가 있겠네요.

이 포스팅에서는 GoLang을 위해서 개발된 아테네Athens^{Athens}를 사용하는 방법에 대해서 알아봅니다.

아테네 웹 사이트에 들어가면 가장먼저 아래와 같은 설명이 보입니다.

Athens is a Server for Your Go Packages

말 그대로 Go 패키지를 위한 서버가 되겠습니다.
아테네를 이용하면 아래와 같은 일들을 할 수 있습니다.

  • Go를 위한 Public/Private 레포 구축
  • Private 레포에 대한 인증, 접근 통제
  • 다운로드 모드를 이용한 유연한 모듈 관리
    • 동기/비동기 다운로드
    • 특정 모듈 다운로드 차단
    • 특정 모듈을 다른 Proxy로 리다이렉션
  • 다운로드한 모듈을 캐시로 남겨서 더 나은 다운로드 성능 제공

간단히 설치와 사용을 해보겠습니다.


Athens 설치하기

설치는 macOS에서 Docker로 진행합니다.

$ go version
go version go1.14 darwin/amd64

$ docker version
Client: Docker Engine - Community
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        afacb8b
 Built:             Wed Mar 11 01:21:11 2020
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.17
  Git commit:       afacb8b
  Built:            Wed Mar 11 01:29:16 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

설치 방법은 Using the Athens Docker images :: Athens에 자세하게 나와 있습니다.

$ export ATHENS_STORAGE=[your-athens-storage-path]
$ mkdir -p $ATHENS_STORAGE
$ docker run -d -v $ATHENS_STORAGE:/var/lib/athens \
   -e ATHENS_DISK_STORAGE_ROOT=/var/lib/athens \
   -e ATHENS_STORAGE_TYPE=disk \
   --name athens-proxy \
   --restart always \
   -p 3000:3000 \
   gomods/athens:latest
7f20272735df5af5ac98b7893a5a0cbe02d2e6b31da106b930a31e9157e1175f
  • ATHENS_STORAGE : 아테네를 이용하여 다운로드된 모듈의 저장 경로
  • ATHENS_STORAGE_TYPE : 아테네는 다양한 스토리지 타입을 지원합니다. 여기서는 로컬 Disk를 사용합니다.

정상적으로 실행되었는지 확인해 봅니다.

$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                      NAMES
7f20272735df        gomods/athens:latest   "/sbin/tini -- athen…"   1 minutes ago       Up 1 minutes        0.0.0.0:3000->3000/tcp     athens-proxy

Athens를 이용하여 Hello Gump 프로젝트 만들기

우선 Go module 프로젝트를 생성합니다.

$ mkcd hello-gump
$ go mod init main
go: creating new go.mod: module main

$ mkdir src
$ vi src/hello-gump.go

hello-gump.go 파일을 작성합니다.

package main

import (
	"net/http"
	"github.com/labstack/echo/v4"
)

func main() {
	e := echo.New()

	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello Gump!")
	})

	e.Logger.Fatal(e.Start(":80"))
}

이제 실행해 보겠습니다.

$ go run src/hello-gump.go
go: finding module for package github.com/labstack/echo/v4
go: found github.com/labstack/echo/v4 in github.com/labstack/echo/v4 v4.1.16

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.16
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:80

Echo 라이브러리가 다운로드된 후 정상적으로 실행이 됩니다.
http://localhost 로 접속해보면 Hello Gump!를 확인할 수 있습니다.

자, 이제 아테네를 이용해서 모듈을 다운로드 해보겠습니다.
우선은 환경 변수 설정을 확인해 보겠습니다.

$ go env
GO111MODULE=""

..블라블라..

GOPATH="/Users/gump/go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.14/libexec"
GOSUMDB="sum.golang.org"

..어쩌구저쩌구..
  • GO111MODULE : Go 1.11부터 Go modules 추가
    • on : Go modules로 동작
    • off : 기존 GOPATH, vendor/ 방식으로 동작
    • 빈값 or auto : GOPATH/src에서는 기존 방식, 외부에서는 Go modues로 동작
  • GOPROXY : Go 1.13부터 Proxy 설정 추가
    • 콤마로 구분하여 여러 Proxy URL 설정 가능
    • direct : VCS로 직접 연결 (기본 GitHub.com)
    • off : 네트워크 연결을 허용 안함
  • 참고 자료 : Why you should use a Go module proxy · Fatih Arslan

GOPROXY를 로컬에 설치한 아테네로 설정합니다.

$ export GO111MODULE=on
$ export GOPROXY=http://localhost:3000
$ go env
GO111MODULE="on"
GOPROXY="http://localhost:3000"

그리고 정상적인 테스트를 위하여 GOPATH에 모듈 캐시를 삭제합니다.

$ rm -rf /Users/gump/go/pkg/mod/cache/download/github.com/labstack
$ rm -rf /Users/gump/go/pkg/mod/github.com/labstack

이제 준비가 되었으니 다시 실행해 보도록 하겠습니다.

$ go run src/hello-gump.go
go: downloading github.com/labstack/echo/v4 v4.1.16
go: downloading github.com/labstack/gommon v0.3.0

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.16
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:80

정상적으로 실행이 되었습니다. 확인해 보면 ATHENS_STORAGE으로 설정한 디렉토리에 패키지가 다운로드 된것이 확인됩니다.

$ cd $ATHENS_STORAGE
$ ls -l
drwxr-xr-x  3 gump  staff  96 Jun 22 21:31 github.com

네트워크를 차단 후 Athens로 모듈 설치하기

다시 GOPATH에 모듈 캐시를 삭제하고, 이번엔 네트워크를 Disable 시킨 후 다시 테스트를 수행해 보겠습니다.

$ rm -rf /Users/gump/go/pkg/mod/cache/download/github.com/labstack
$ rm -rf /Users/gump/go/pkg/mod/github.com/labstack
$ go run src/hello-gump.go
go: downloading github.com/labstack/echo/v4 v4.1.16
go: downloading github.com/labstack/gommon v0.3.0

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.16
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:80

아테네에 캐시가 생성된 덕분에 오프라인 상태에서도 정상적으로 의존성을 다운로드 받을 수 있습니다. 이것으로 간단하게 아테네 사용방법에 대해서 알아봤습니다.


마치며

최근 회사에서 제 첫 Go 프로젝트를 진행하면서 아테네를 사용했습니다. 개발의 재미만큼이나 보안과 컴플라이언스도 중요한 요소이기 때문에 프로젝트 설정 초기부터 아테네를 이용하여 개발 환경을 구성했습니다. 아테네를 이용한 환경 구성은 대단히 간결한 편이어서 누구나 어렵지않게 사용해 보실 수 있을 것 같습니다. 아테네를 이용하여 개발과 보안 두마리 토끼를 잡아보세요!

profile
권구혁

0개의 댓글