회사에서 개발과 운영을 하다보면 서버에서 Outbound 네트워크 정책을 제한적으로 운영하는 경우가 많습니다. 다름아닌 보안 때문인데요, Outbound 네트워크가 열려 있게되면 외부 공격으로부터 취약해 질 수 있습니다. 물론 제한한다고해서 반드시 안전하다는 것은 아니지만, 적절한 정책을 운영하는 것과 아닌 것에는 차이가 크겠죠.
최근 개발 환경은 온라인으로 의존성을 관리하는 경우가 대부분입니다. 이렇다보니 프로젝트의 빌드, 배포, 운영을 위한 여러 상황에서 보안 정책과 충돌이 발생하기도합니다. 이런 경우 Private repository를 구축하는 것으로 문제를 해결할 수 있습니다. 대표적으로 Sonatype의 Nexus가 있겠네요.
이 포스팅에서는 GoLang을 위해서 개발된 아테네를 사용하는 방법에 대해서 알아봅니다.
아테네 웹 사이트에 들어가면 가장먼저 아래와 같은 설명이 보입니다.
Athens is a Server for Your Go Packages
말 그대로 Go 패키지를 위한 서버가 되겠습니다.
아테네를 이용하면 아래와 같은 일들을 할 수 있습니다.
간단히 설치와 사용을 해보겠습니다.
설치는 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
정상적으로 실행되었는지 확인해 봅니다.
$ 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
우선 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" ..어쩌구저쩌구..
Go 1.11
부터 Go modules 추가GOPATH
, vendor/
방식으로 동작GOPATH/src
에서는 기존 방식, 외부에서는 Go modues로 동작Go 1.13
부터 Proxy 설정 추가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
다시 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 프로젝트를 진행하면서 아테네를 사용했습니다. 개발의 재미만큼이나 보안과 컴플라이언스도 중요한 요소이기 때문에 프로젝트 설정 초기부터 아테네를 이용하여 개발 환경을 구성했습니다. 아테네를 이용한 환경 구성은 대단히 간결한 편이어서 누구나 어렵지않게 사용해 보실 수 있을 것 같습니다. 아테네를 이용하여 개발과 보안 두마리 토끼를 잡아보세요!