TCP 전달을 위한 Cloud IAP 사용

이 페이지에서는 터널 리소스 권한을 설정하고 Cloud Identity-Aware Proxy(Cloud IAP)를 통해 Compute Engine 인스턴스로 TCP 트래픽을 전달하는 터널을 만들어서 누가 백엔드에서 SSH 및 RDP 같은 관리 서비스에 액세스할 수 있는지 제어하는 방법에 대해 설명합니다.

Cloud IAP가 TCP 전달을 처리하는 방법에 대해 자세히 알아보려면 TCP 전달 개요를 참조하세요.

시작하기 전에

시작하기 전에 다음이 필요합니다.

  • Cloud IAP API가 사용 설정된 Cloud IAP 보안 애플리케이션

    Cloud IAP API 페이지 열기

  • 액세스 권한을 부여하려는 사용자 또는 그룹 이름
  • 원하는 포트에서 Cloud IAP의 TCP 전달 넷블록 35.235.240.0/20의 액세스를 허용하도록 구성된 방화벽 규칙. 이렇게 하면 Cloud IAP의 TCP 전달 IP 주소로부터 리소스에 대한 관리 서비스의 TCP 포트로의 연결이 허용됩니다. default-allow-sshdefault-allow-rdp 기본 규칙이 SSH 및 RDP에 사용된 포트에 적용되는 경우 방화벽 규칙을 조정할 필요가 없습니다.

    방화벽 규칙 페이지 열기

액세스 및 권한 구성

Cloud Identity and Access Management(Cloud IAM) 권한을 설정하려면 다음 단계를 따르세요.

콘솔

  1. Identity-Aware Proxy 페이지로 이동하고 SSH 및 TCP 리소스 탭을 선택하여 SSH 및 TCP 리소스를 봅니다.

    Cloud IAP 관리 페이지 열기

  2. 리소스 옆의 체크박스를 선택하여 리소스에 대한 구성원 권한을 업데이트합니다. 이는 리전 또는 모든 터널 리소스 체크박스를 선택하여 영역(zone) 이름 또는 전체 프로젝트별로 설정할 수 있습니다.
  3. 오른쪽 정보 패널에서 구성원 추가를 클릭합니다.
  4. 새 구성원 필드에 추가하여 액세스 권한을 부여할 사용자 및 그룹을 지정합니다.
  5. 역할 선택 드롭다운 목록을 열고 Cloud IAP > IAP 보안 터널 사용자를 선택하여 구성원에게 터널 리소스에 대한 액세스 권한을 부여합니다.
  6. 필요한 경우 조건 추가를 클릭하고 조건 제목표현식을 입력하여 구성원 제한사항을 추가합니다.

    예를 들어 destination.ipdestination.port Cloud IAM 조건을 사용하는 CEL 표현식으로 표현식을 설정하면 포트 22의 구성원으로만 또는 비공개 IP가 10.0.0.1인 구성원으로 액세스를 제한할 수 있습니다.

    destination.ip == "10.0.0.1" || destination.port == 22
    

    또한 액세스 수준을 사용하면 다음 CEL 표현식으로 액세스를 제한할 수도 있습니다.

    "FULL_ACCESS_LEVEL_NAME" in request.auth.access_levels
    

    여기서 FULL_ACCESS_LEVEL_NAMEaccessPolicies/POLICY_NAME/accessLevels/ACCESS_LEVEL_NAME입니다.

    액세스 수준의 전체 이름을 찾으려면 다음을 수행하세요.

    1. Access Context Manager 페이지를 엽니다.

      Access Context Manager 페이지 열기

    2. 액세스 수준의 이름을 클릭합니다.

    이제 전체 액세스 수준 이름이 오른쪽 패널에 다음 형식으로 표시됩니다.

  7. 저장을 클릭합니다.

API

애플리케이션의 policy.json 파일을 수정하려면 아래 절차를 따릅니다. Cloud IAM API를 사용하여 액세스 정책을 관리하는 방법에 대한 자세한 내용은 Cloud IAP 보안 리소스 액세스 관리를 참조하세요.

  1. 서비스 계정의 사용자 인증 정보 파일을 다운로드합니다.
  2. 다음 변수를 내보냅니다.

    export PROJECT_NUM=PROJECT_NUMBER
    export IAP_BASE_URL=https://iap.googleapis.com/v1beta1/projects/${PROJECT_NUMBER}/iap_tunnel
    # Replace with the path to your local service account's downloaded JSON file
    export JSON_CREDS=EXAMPLE.IAM.GSERVICEACCOUNT.COM.JSON
    # Replace POLICY_FILE.JSON with the name of JSON file to use for setIamPolicy
    export JSON_NEW_POLICY=POLICY_FILE.JSON
    

  3. 다음 명령어를 실행하여 Oauth2l를 사용해서 서비스 계정 사용자 인증 정보 JSON 파일을 OAuth 액세스 토큰으로 전환합니다.

    oauth2l header --json ${JSON_CREDS} cloud-platform

  4. 위 명령어를 처음 실행할 경우 메시지가 표시되면 다음을 수행합니다.

    1. 표시된 링크를 클릭하고 코드를 복사하여 확인 코드를 가져옵니다.
    2. 확인 코드를 앱 프롬프트에 붙여넣습니다.
    3. 반환된 Bearer 토큰을 복사합니다.
    4. 반환된 Bearer 토큰의 값에 할당된 새 변수를 내보냅니다.
      export CLOUD_OAUTH_TOKEN=AUTHORIZATION_BEARER_TOKEN
  5. 이 명령어를 이전에 실행한 경우에는 다음 변수를 내보냅니다.

    export CLOUD_OAUTH_TOKEN ="$(oauth2l header --json ${JSON_CREDS} cloud-platform)"

  6. getIamPolicy 메소드를 사용하여 Compute Engine 인스턴스에 대해 Cloud IAM 정책을 가져옵니다. 마지막에 비어 있는 데이터 비트는 curl 요청을 GET 대신 POST로 전환합니다.

    curl -i -H "${CLOUD_OAUTH_TOKEN}" \
         ${IAP_BASE_URL}/zones/ZONE_NAME/instances/INSTANCE_ID or INSTANCE_NAME:getIamPolicy \
         -d ''

  7. Cloud IAM 정책 JSON 파일을 수정하여 구성원에게 iap.tunnelResourceAccessor 역할을 부여합니다.

  8. 필요한 경우 Cloud IAM 조건액세스 수준을 기반으로 구성원 제한사항을 추가합니다.

    다음은 iap.tunnelResourceAccessor 역할을 VM 인스턴스 관리자 그룹에 바인딩하여, 사용자가 Cloud IAP 보안 터널 리소스에 액세스할 수 있도록 권한을 부여하는 편집된 policy.json 파일 예를 보여줍니다. destination.ipdestination.port Cloud IAM 조건을 사용하여 포트 22에서 비공개 IP 주소가 10.0.0.1인 VM 인스턴스 관리자 그룹의 구성원만 액세스할 수 있도록 만들기 위해 Cloud IAM 조건이 추가되었습니다.


    policy.json 파일 예

    {
      "policy": {
        "bindings": [
          {
            "role": "roles/iap.tunnelResourceAccessor",
            "member": "group:instance-admins@example.com"
            "condition": {
               "expression": "destination.ip == \"10.0.0.1\" && destination.port == 22"
            }
          }
        ]
      }
    }

    액세스 수준을 사용하면 다음 표현식으로 액세스를 제한할 수 있습니다.

    "\"accessPolicies/POLICY_NAME/accessLevels/ACCESS_LEVEL_NAME\" in request.auth.access_levels"
    

    정책 이름을 찾으려면 accessPolicies.list를 호출합니다.

    GET https://accesscontextmanager.googleapis.com/v1beta/accessPolicies
    
  9. setIamPolicy 메소드를 사용하여 새 policy.json 파일을 설정합니다.

    curl -i -H "Content-Type:application/json" \
         -H "$(oauth2l header --json ${JSON_CREDS} cloud-platform)" \
         ${IAP_BASE_URL}/zones/ZONE_NAME/instances/INSTANCE_ID or INSTANCE_NAME:setIamPolicy \
         -d @${JSON_NEW_POLICY}
    

gcloud를 사용한 터널링

gcloud를 사용하려면 연결하려는 인스턴스를 지정해야 합니다. gcloud를 사용하여 터널링하려면 인스턴스 이름을 제공해야 합니다.

일반 TCP 터널링

Cloud IAP의 TCP 전달 기능은 로컬 포트를 할당하여 TCP 트래픽을 처리합니다. 로컬 포트는 HTTPS 스트림에서 로컬 머신으로부터 원격 머신으로의 데이터 트래픽을 터널링합니다. 그런 다음 Cloud IAP가 데이터를 수신하고 액세스 제어를 적용하고 래핑 해제된 데이터를 원격 포트로 전달합니다. 반대로 원격 포트의 모든 데이터도 래핑되어 로컬 포트로 전송되고 이후 래핑 해제됩니다.

아래 명령어는 인스턴스 이름으로 지정된 대로 로컬 머신과 원격 리소스 사이의 암호화된 터널을 만듭니다. Cloud IAP의 TCP 전달 기능은 localhost:LOCAL_PORT에서 연결을 위한 수신 대기를 시작합니다. 무작위로 로컬 포트를 선택하려면 명령어에서 local-host-port 플래그를 삭제하세요.

gcloud beta compute start-iap-tunnel INSTANCE_NAME INSTANCE_PORT \
  --local-host-port=localhost:LOCAL_PORT \
  --network-interface=NETWORK_INTERFACE

각 항목의 의미는 다음과 같습니다.

  • INSTANCE_NAME은 작업을 수행할 인스턴스의 이름입니다.
  • INSTANCE_PORT는 연결할 인스턴스 포트의 이름 또는 구성원입니다.
  • LOCAL_PORT는 프록시가 결합되는 포트입니다.
  • NETWORK_INTERFACE는 연결할 인스턴스 네트워크 인터페이스의 이름입니다. 기본적으로 "nic0"이 사용됩니다.

SSH 터널링

Cloud IAP의 TCP 전달 기능에 SSH를 사용할 때는 로컬 포트를 매핑할 필요가 없습니다. 대신 SSH 연결이 HTTPS 내부에서 직접 래핑되고 Cloud IAP의 TCP 전달을 통해 원격 인스턴스로 전송됩니다.

Cloud IAP를 통해 모든 트래픽을 안전하게 터널링하여, 지정된 인스턴스로 SSH 세션을 만들려면 아래 명령어를 사용하세요.

gcloud beta compute ssh INSTANCE_NAME \
   --command=COMMAND \
   --tunnel-through-iap

각 항목의 의미는 다음과 같습니다.

  • INSTANCE_NAME은 SSH를 통해 연결할 인스턴스의 이름입니다.
  • COMMAND는 인스턴스에서 실행할 명령어입니다. 예를 들면 "ps -ejH"와 같습니다.

이제 Cloud IAP를 통해 터널링되는 SSH 세션이 준비되었습니다.

알려진 제한사항

대역폭: Cloud IAP의 TCP 전달 기능은 대량의 데이터 전송을 위한 것이 아닙니다. Cloud IAP는 사용자의 이 서비스 남용 방지를 위해 용량을 제한할 수 있는 권리가 있습니다.

연결 길이: 유지관리에 필요한 경우가 아니면 Cloud IAP는 활성 세션 연결을 해제하지 않습니다. 연결이 끊어지는 경우 터널을 다시 설정하도록 애플리케이션에 로직을 설정하는 것이 좋습니다.