EMD Blog

[GCP] IAM에 대해 알아보자(3)- 서비스 계정 본문

Public Cloud/GCP

[GCP] IAM에 대해 알아보자(3)- 서비스 계정

EmaDam 2021. 12. 19. 15:54

전 포스팅에 이어서 마저 세팅을 해보자. 이전 포스팅에서는 개발자 용 계정을 생성해 IAM계정에 추가하고 IAP TCP 터널링을 통해 VM에 접속할 수 있도록 설정해주었다. 이제는 배포를 해야하니 파일을 업로드할 수 있도록 설정해보자. 

 

파일을 업로드를 하기 위해서 가장 먼저 생각나는 것은 FTP(또는 SFTP)다. 하지만 우리는 IAP 터널링을 사용하고 있고 보안상 21,22번 포트를 오픈하는 것은 별로 바람직하지 못할 뿐더러 관리적인 측면에서도 불편할 수 있다. 그렇게 생각하면 파일 업로드를 위한 좋은 방법이 두 가지가 존재한다. 

 

- gcloud 명령어 사용 

- Cloud Storage 사용 

 

위 방법외에도 그냥 SCP 명령어(gcloud 말고)를 사용하거나 브라우저 업로드를 하는 방법도 있으나 우리는 IAP 터널링을 사용하고 있기 때문에 해당되지 않는다. (현재는 외부 IP가 존재해서 가능은 하지만 지금은 외부IP가 없다고 생각하자.) 그러면 가장 먼저 생각해볼 것은 gcloud compute scp 명령어를 사용하는 것이다.

 

 SCP는 Secure Copy의 약자다. 프로토콜은 SFTP일테니 아마 Secure CoPy인 듯 하다. 보통은 리눅스에서도 사용할 수 있는 명령어인데 GCP에서 SDK로도 제공해주고 있다. 기존 리눅스에서 사용하는 명령어와 가장 큰 차이점이라고 하면 키 관리 방식이라고 할 수 있는데 GCP는 키 관리를 대신 해주는 방면에 리눅스에서 SCP를 사용하는 것은 키 관리를 직접해야한다. 마치 그냥 ssh와 gcloud compute ssh의 차이와 같다고 할 수 있겠다. 그리고 또 중요한 점은 gcloud를 사용하면 IAP TCP 터널링을 사용해 파일 업로드를 할 수 있다는 것이다. 하지만 IAP TCP 터널링은 파일 전송을 위한 것이 아니기 때문에 GCP측에서 성능을 제한하고 있다. 테스트 결과 대략 1/3에서 크게는 1/10까지 차이가 나니 작은 파일이 아니라면 사용하지 않는 것을 추천한다.

 

 위와 같은 문제 때문에 GCP에서는 IAP TCP 터널링을 사용하고 있는 경우 Cloud Storage를 사용하는 방식을 권장하고 있다. Cloud Storage를 VM에 Mount해서 사용해도 되고 Cloud Storage에 파일을 업로드 후 VM에서 다운로드 받는 식으로 사용해도 된다. 하지만 마운트까지는 너무 과한 것 같아서 그냥 간단하게 업로드하고 다운로드 받는 방식으로 진행해보자. 

 

Cloud Storage 사용하기로 했으므로 다음과 같은 부분들을 생각해봐야 한다. 

 

- 버킷을 만들어야함. 

- 버킷에 개발자가 업로드만 가능해야함.

- VM에서 다운로드만 가능해야함.

 

권한을 굉장히 타이트하게 잡았는데 사실 타이트하게 잡고 필요할 때마다 하나씩 열어주는 것이 좋다. 그리고 어차피 사전 정의된 역할을 사용할 것이므로 필요할 것 같은 권한은 넉넉하게 포함되어 있으니 걱정할 필요도 없다. 

 

그럼 일단 버킷을 만들어보자. 그 전에 이전 포스팅에서 VM 접속을 테스트 했다면 다시 소유자 계정으로 전환해야하니 잊지 말자. 버킷은 gsutil 도구를 사용해 생성할 수 있다. gsutil은 Cloud SDK를 설치할 때 자동으로 설치되므로 그냥 바로 사용하면 된다. gsutil mb 명령어를 사용하자. 

$ gsutil mb -b on -c standard -l asia-northeast3 --pap enforced gs://study-operation-dev/
Creating gs://study-operation-dev/...

 

옵션을 위에서 부터 살펴보면

 

-b : 균일한 버킷 수준 액세스 설정으로 쉽게 말하면 ACL(Access Control List) 없이 역할만으로 액세스를 관리하겠다는 것이다. 역할과 ACL의 차이는 역할의 경우 버킷 단위로 액세스를 관리하고 ACL은 버킷내 객체 단위로 액세스를 관리한다. 즉, 역할(버킷 수준의 액세스 관리)만 사용한다는 것은 버킷 내 객체들에게 균일하게 액세스 할 수 있다는 것을 의미한다. 

-c : 스토리지 클래스를 지정한다. 기본은 Standard이며, 취급 권한이나 보유 기간에 따라 특성에 맞는 스토리지 클래스를 선택할 수 있다. 예를 들어 백업 용으로 사용(자주 액세스 하지 않음)하겠다고 하면 Standard(자주 액세스 할경우 좋음)대신 가격이 저렴한 다른 스토리지 클래스를 선택할 수 있다. 

-l : 버킷의 리전이다.

-pap : 공개 액세스 적용 여부이다. enforced는 공개하지 않겠다는 뜻이다. 

 

위 내용을 요약하면 "asia-northeast3 리전에 study-operation-dev라는 이름으로 버킷을 만드는데, 액세스 관리에는 역할만을 사용할 것이고, 스토리지 클래스는 기본 클래스를 사용하며, 외부에 공개되지 않도록 생성하겠다"라는 뜻이 된다. 

 

이제 스토리지를 만들었으니 개발자에게 역할을 부여해보자. Cloud Storage에 대한 사전 정의된 역할은 아래 문서를 참고하자.

 

Cloud Storage 역할 - https://cloud.google.com/storage/docs/access-control/iam-roles 

 

개발자의 경우 업로드만 허용할 것이라고 했다. 이 말은 버킷에 객체를 생성만 허용하겠다는 뜻이며, 위 문서를 보면 storage.objectCreator(스토리지 객체 생성자) 역할이 적당해 보인다. 그리고 자신이 업로드한 객체도 확인할 수 있어야하니 storage.objectViewer(스토리지 객체 뷰어) 역할도 같이 부여하자. 

 

아래 명령어를 통해 역할을 부여한다. gcloud iam

$ gsutil iam ch user:<IAM_ACCOUNT>:objectCreator,objectViewer gs://study-operation-dev

내용은 주 구성원 타입(user, group,serviceAccount):<IAM_ACCOUNT>에게 objectCreator, objectViewer 역할을 부여하겠다는 뜻이다. 지정된 버킷은 study-operation-dev이.다.

 

명령어가 정상적으로 동작했다면 버킷의 권한을 가지고 있는 주 구성원 목록을 확인해보자. 

$ gsutil iam get gs://study-operation-dev > ~/Desktop/bucket_iam.txt

study-operation-dev 버킷의 권한 목록을 bucket_iam.txt로 받겠다는 뜻이다. 원하는 위치에 받자.

 

그 다음 내용을 확인해 보면 다음과 같이 버킷에 대한 objectCreator, objectViewer 역할이 부여되어 있는 것을 볼 수 있다.

$ cat ~/Desktop/bucket_iam.txt
{
  "bindings": [
    ...
    {
      "members": [
        "user:<IAM_ACCOUNT>"
      ],
      "role": "roles/storage.objectCreator"
    },
    {
      "members": [
        "user:<IAM_ACCOUNT>"
      ],
      "role": "roles/storage.objectViewer"
    }
  ],
  "etag": "CAI="
}

 역할이 잘 부여됐으니 이제 계정을 개발자 계정으로 전환해 파일을 업로드 하고 객체 목록을 조회해보자.

 

먼저 개발자 계정으로 전환한다. 

$ gcloud config set account emadam.developer@gmail.com
Updated property [core/account].
$ gcloud auth list
      Credentialed Accounts
ACTIVE  ACCOUNT
   *    <IAM_ACCOUNT>
        <ROOT_ACCOUNT>

파일을 아무 파일이나 업로드 해보자. 지금은 방금 다운받았던 bucket_iam.txt 파일을 업로드 해보겠다. 참고로 다양한 업로드 옵션을 제공하니 문서를 참고해서 다양하게 시도해보자. 당연한거지만 디렉터리 단위로도 업로드 가능하다.

Cloud Storage 업로드 - https://cloud.google.com/storage/docs/gsutil/commands/cp  

# 업로드
$ gsutil cp ~/Desktop/bucket_iam.txt gs://study-operation-dev/
Copying file://bucket_iam.txt [Content-Type=text/plain]...
/ [1 files][  904.0 B/  904.0 B]
Operation completed over 1 objects/904.0 B.

# 목록 조회
$ gsutil ls gs://study-operation-dev/
gs://study-operation-dev/bucket_iam.txt

업로드와 목록 조회가 잘 된다면 역할이 잘 적용된 것이다. 이제 마지막으로 VM에서 버킷 객체를 다운받을 수 있도록 설정해보자. 

 

 사실 이 상태로 로그인해서 다운로드 받으면 바로 받아진다. 왜냐하면 VM생성 시 서비스 계정을 따로 지정하지 않으면 기본 서비스 계정을 사용하게 되는데 이 계정은 역할이 편집자 역할이다. 편집자의 경우 스토리지 기존 버킷 소유자 역할을 가지고 있기 때문에 프로젝트내 모든 버킷에 대한 대부분의 권한을 가지고 있다. 귀찮더라도 새롭게 서비스 계정을 하나 만들어서 작업을 진행해보자. 

 

다시 소유자 계정으로 전환한 뒤, gcloud iam service-accounts create 명령어를 사용해 서비스 계정을 생성한다.

$ gcloud iam service-accounts create study-web-general-sa --display-name="study-web-general-sa" --description="Web Server용 Service Account"
Created service account [study-web-general-sa].

그 다음 study-operation-dev 버킷에 대한 objectViewer 역할을 부여하자. objectViewer 역할을 부여하면 버킷내 객체 목록을 조회할 수 있고 다운로드 받을 수도 있다. 

$ gsutil iam ch serviceAccount:study-web-general-sa@emadam-playground.iam.gserviceaccount.com:objectViewer gs://study-operation-dev

자 이제 VM 설정에서 서비스 계정을 바꿔주어야 하는데 서비스 계정 수정은 인스턴스를 중지한 상태에서만 가능하니 인스턴스를 먼저 중지 시키자. 이때는 gcloud compute instances stop 명령어를 사용한다.

$ gcloud compute instances stop study-web-dev-1 --zone=asia-northeast3-a
Stopping instance(s) study-web-dev-1...done.
...

그 다음 방금 생성한 서비스 계정으로 변경해주자. gcloud compute instances set-service-account 명령어를 사용하면 된다.

$ gcloud compute instances set-service-account study-web-dev-1 --zone=asia-northeast3-a --service-account=<SERVICE_ACCOUNT>
Updated [https://www.googleapis.com/compute/v1/projects/...

서비스 계정이 잘 설정 되었다면 이제 인스턴스를 다시 시작해 확인해보자. 인스턴스 시작은 gcloud compute instances start 명령어를 사용하면 된다.

$ gcloud compute instances start study-web-dev-1 --zone=asia-northeast3-a
Starting instance(s) study-web-dev-1...done.
...

이제 접속해서 서비스 계정과 역할이 잘 설정되었는지 확인해보자. 접속한 후에는 서비스 계정을 사용하게 되므로 소유자 계정인 상태로 그냥 접속하자. 

$ gcloud compute ssh study-web-dev-1 --tunnel-through-iap

접속이 되었으면 어떤 계정을 사용하고 있는지 직접 확인해보자. 

$ gcloud auth list
                  Credentialed Accounts
ACTIVE  ACCOUNT
*       <SERVICE_ACCOUNT>

인증 계정으로 서비스 계정을 사용하고 있는 것을 볼 수 있다. 이제 객체를 조회하고 파일을 다운로드 받아보자.

# 객체 조회
$ gsutil ls gs://study-operation-dev
gs://study-operation-dev/bucket_iam.txt

# 객체 다운로드 
$ gsutil cp gs://study-operation-dev/bucket_iam.txt ~/
Copying gs://study-operation-dev/bucket_iam.txt...
/ [1 files][  904.0 B/  904.0 B]
Operation completed over 1 objects/904.0 B.

조회와 다운로드가 잘 되는 것을 볼 수 있다. 그럼 파일을 업로드해보자. 업로드의 경우 권한이 없으니 막혀야한다. 

# 업로드할 테스트 파일을 하나 만듬
$ touch ~/test.txt 

# 업로드
$ gsutil cp ~/test.txt gs://study-operation-dev/
Copying file:///.../test.txt [Content-Type=text/plain]...
AccessDeniedException: 403 Provided scope(s) are not authorized

권한이 없어 업로드 되지 않는 것을 볼 수 있다. 

 

이렇게 시나리오를 하나 짜서 진행해보았다. 이렇게 간단한 시나리오인데도 신경쓸 것이 정말 많았는데, IAM의 경우 잘 설정해두지 않으면 보안적으로 위험하거나, 조직 구성이 복잡해질수도 있으니 귀찮더라도 세심하게 신경써주는 것이 좋다. 

 

마치며

 일단 알고 있던 것과 추가로 알게된 것들, 어중간하게 아는 부분들을 모두 정리해서 작성했는데, 아무래도 GWS쪽을 다루지 못한 것이 조금 아쉽다. 그렇다고 회사계정을 쓸 수는 없는 노릇이라 나중에 기회가 된다면 추가로 포스팅 하도록 하겠다.