ISMS 1편 - AWS(+EKS)에서 업무 환경 망분리

Choi Jepil·2021년 5월 17일
11

isms

목록 보기
1/1
post-thumbnail

안녕하세요 최제필입니다 :) 이번 글에선 AWS 환경에서 ISMS 인증을 위해 망분리를 적용한 경험에 대해 공유하고자 합니다.

ISMS?

먼저 ISMS은 한국인터넷진흥원에서 주관하는 정보자산을 보호하기 위해 관리체계가 인증기준에 적합한 지 심사하여 인증을 부여하는 제도입니다. 인증 취득 시 여러 장점이 있지만 대표적으로 정보보호 관련한 대외 이미지 및 신뢰도 향상이 있습니다.

주로 IDC 환경에서 ISMS를 포함한 인증 취득을 위한 인프라 / 아키텍처에 대한 경험이 있지만 AWS와 같은 Cloud 환경에선 처음이었습니다. ISMS 취득을 위한 정보 보호 관리체계 적용은 굉장히 방대합니다. 이번 글에선 AWS의 여러 서비스를 활용하여 EKS(Kubernetes)에서 운영되는 업무 서비스를 접근하기 위한 망분리 아키텍처에 대해 소개합니다.

망분리와 VDI

망분리란 인터넷과 완전히 격리된 환경에서 업무를 볼 수 있도록 망(네트워크)을 분리하는 것을 의미합니다. 망분리 환경에서 고객(동료)은 인터넷과 연결되지 않은 폐쇄적인 망에서 업무를 수행할 수 있도록 환경을 제공해야했습니다. 먼저 업무를 위한 2 PC(인터넷망 / 보안망)를 제공해야하며 기 지급된(인터넷 연결이 허용된) PC 외 보안망 접근을 위한 PC를 VDI로 제공하기 위해 여러 업체를 검토하였지만 비용 및 사용성에 있어 Amazon Workspace를 채택하였습니다.

Amazon Workspace는 AWS에서 제공하는 관리형 DaaS(Desktop as a Service) 솔루션입니다. 손쉽게 Windows 등 Desktop 프로비저닝이 가능하며 관리가 용이하였습니다. 무엇보다 VDI 업체는 연간/수량 계약을 진행해야하지만 Workspace는 원하는 만큼 프로비저닝이 가능하고 Auto stop 기능을 통해 업무 시간에만 과금되도록 설정하여 비용 감축에 있어서도 효율적이었습니다.

Workspace 과금 구조가 살짝 이상합니다(!) Running Mode: AlwaysOn 경우 한 달 비용이 한 번에 과금되며, AutoStop을 걸어둬도 평균 업무 시간을 8시간으로 계산해보면 한 달 비용이 저렴합니다. 특히 STOPPED 되고 업무가 시작되는 오전에 VDI 부팅 시 시간이 오래 걸려(대략 15~20분) 불편함을 호소하는 경우가 있었습니다. 그래서 저희는 신규 VDI 생성 시 AlwaysOn으로 생성하고 Lambda로 주기적으로 체크하여 사용이 없는 경우 요금 최적화를 위해 AutoStop으로 변경합니다.

생성된 Workspace의 인증 과정은 AD(LDAP)으로 진행합니다. 이를 위해 사내 AD 서버에게 인증을 요청하기 위해 AWS Directory Service의 기능 중 AD Connector를 사용하였습니다. 네트워크 격리를 위해 별도의 VPC, Transit gateway, Customer gateway를 생성하여 사내망에서 Site-to-Site VPN Tunnel을 통해서만 접근이 가능하도록 구성했으며 구조는 아래와 같습니다.

도안에 표기된 것과 같이, VPC를 따로 생성하여 네트워크를 격리하였으며 Internet gateway를 연결하지 않은 Subnet(private)에 위에서 언급한 Directory, Workspace를 구성하였습니다. 이제 사용자는 특정 네트워크 환경(사무실 사내망)에서만 본인의 VDI에 접근이 가능해졌습니다!

EKS?

VDI 사용자가 주로 사용하는 Admin 서비스는 EKS에 구성되어있습니다. 해당 서비스는 별도의 Ingress를 사용하지 않고 ServiceType: LoadBalancer로 K8S service를 ELB로 구성하여 ACL을 사무실 네트워크 대역으로 설정하여 구성된 상황입니다. VDI에서만 접근하게 하기 위해 네트워크 / 인프라 구성을 변경할 필요가 있습니다. VDI가 별도의 VPC에 구성되어있으므로 VPC peering을 하여 Route table rule과 security group을 통해 접근 제어를 할 순 있습니다.

다만 도안과 같이 VDI에서 동일한 Subnet에 구성된 다른 ELB 또한 접근이 가능해집니다. 물론 Security group 등을 통해 제어하면 됩니다. 제가 보안 전문가는 아니지만, 네트워크 관점에서 보안은 접근은 가능하지만 막는 것과 접근이 아예 안되는 건 다르다고 판단하였습니다.

이 문제를 해결하기 위해 Admin 서비스의 ELB만 생성될 수 있는 별도의 Subnet과 Route table rule을 통해 해결할 수 있지만, AWS에서 제공하는 VPC Endpoint를 사용하여 서비스 간 Private 연결로 구성하였습니다.

VPC Endpoint

VPC Endpoint는 가상 장치로 VPC와 AWS Service를 전용 연결(Private connection)을 할 수 있도록 지원합니다. VPC Endpoint를 생성하면 AWS 내부망을 사용하여 내부 통신을 진행하므로 외부에서 접근이 불가능합니다. 또한 특정 서비스(ex. ELB)에만 전용 연결을 구성할 수 있어 위에서 언급한 동일한 Subnet에 구성된 다른 서비스의 접근을 막을 수 있어 안전한 통신이 가능합니다.

Endpoint service

  • VPC Endpoint
    • Gateway 형식과 Interface 형식으로 나뉩니다.
    • s3, Cloudfront 등 사용자 VPC에 생성되지 않는 AWS 서비스는 Gateway 형식으로 / ELB와 같이 사용자 VPC 내 생성되는 AWS 서비스는 Interface 형식으로 연결됩니다.
  • Endpoint service
    • 사용자가 만든 AWS 서비스(= Interface 형식)를 AWS Private link로 연결하기 위해 사용됩니다.
    • 도입 당시 Seoul region 기준 NLB만 지원했으며, 현재 GLB(Gateway Load Balancer)도 지원합니다.
      • 해당 이슈로 인해 기존 Admin의 SVC annotation을 수정하여 NLB로 구성하였습니다.
apiVersion: v1
kind: Service
metadata:
  ...
  annotations:
    ...
    service.beta.kubernetes.io/aws-load-balancer-type: 'nlb' # ELB(Type: NLB)로 구성
    ...

Terraform으로 구성

Admin 서비스는 EKS에서 여러 Micro service 형태로 운영되고 있습니다. 위에서 언급된 이슈로 인해 서비스 별로 NLB가 구성되어 있고 서비스마다 VPC Endpoint / Endpoint service를 만들기 위해 모듈화하여 적용하였습니다.

#--------------------------------------------------------------
# VPC Endpoint, Endpoint service(backend - Nlb) 
#--------------------------------------------------------------
resource "aws_vpc_endpoint_service" "endpoint_service" {
  acceptance_required        = false
  network_load_balancer_arns = [var.endpoint_service_nlb_arn]

  tags = merge(var.tags, {
    Name = "${var.name_prefix}-endpoint-service"
  })
}

resource "aws_vpc_endpoint" "vpc_endpoint" {
  vpc_id            = var.vpc_id
  service_name      = aws_vpc_endpoint_service.endpoint_service.service_name
  vpc_endpoint_type = "Interface"

  security_group_ids = [aws_security_group.vpc_endpoint_allow_http_sg.id]

  subnet_ids          = var.private_subnets
  private_dns_enabled = false

  tags = merge(var.tags, {
    Name = "${var.name_prefix}-vpc-endpoint"
  })
}

Terraform 리소스 생성 우선 순위에 의해 Endpoint service가 먼저 생성되고 VPC Endpoint가 생성됩니다. 다만 Endpoint service가 생성되는 시간이 너무 오래 걸리기 때문에 Timeout을 넉넉히 늘리고 실행하시는 것을 추천드립니다.

인터넷 연결이 되야한다고?

Terraform apply 하고 Workspace에서 연결까지 잘 되는 것 확인하고 QA 검수 완료를 기다리고 있었습니다. QA 분께 메세지가 옵니다.

"제필님, XXX 기능(네이버 지도)가 안되는데요?"

"??? 안되는 게 맞죠. VDI에선 인터넷 연결이 안되니깐요 ㅎㅎ;"

"????????"

자 이렇게 커뮤니케이션 미스가 발생합니다. 보안팀, 프론트엔트 팀과 미팅 후 Admin 클라이언트에서 Naver open API, Google open API 등 외부 Outbound가 필요한 API 등을 정리하였습니다. 이런 API는 허용 가능했으며 이를 위해 Internet gateway 연결 및 Outbound 제어가 필요했습니다.

먼저 고민했던 방법은 Public subnet에 Internet gateway를 배치, private subnet에 Nat instance를 구성하여 iptables를 통해 ip 기반 outbound를 제어하려했지만 외부 서비스의 Open API들은 지속적으로 IP가 변경되었습니다. IP를 지속적으로 추적하여 iptables rule을 추가할 수도 있지만 공수가 많이 발생하였습니다. 좀 더 쉽게 해결할 수 있는 방법을 고민 중에

"어? 나 이거 예전에 비슷한 이슈가 있었는데...?"

IDC에서 운영할 때 이런 비슷한 이슈가 있었습니다. 당시 Squid로 Outbound를 제어한 적이 있었는 데 현 상황을 해결하기에 적합한 솔루션이라고 판단되어 EC2를 생성하고 Squid 설치 이후 테스트를 진행하였습니다.

# squid.conf: Squid 설정 파일
...
acl allow_dst openapi.map.naver.com www.google-analytics.com ... # 필요한 URL만 허용

http_access allow allow_dst
...

Workspace 내 OS proxy 설정에서 Squid를 바라보게 설정 후 연결 테스트 및 QA 검수까지 완료되었습니다. 전체 도안은 아래와 같습니다.

마치며

이렇게 ISMS 1편 - AWS(+EKS)에서 업무 환경 망 분리가 마무리 되었습니다. 개인적으로 작성한 글이라 보안 이슈가 발생할 수도 있는 글인만큼 많은 내용을 생략할 수 밖에 없는 점이 아쉬웠습니다. 혹시 기회가 된다면 K8S svc를 CLB -> NLB로 전환하면서 발생한 문제, Workspace 관리자 OS 기능, VPC Endpoint / Endpoint service의 더 많은 활용 방법 등을 다른 글에서 작성해보고 싶네요.

아직 ISMS 특히 AWS와 같은 클라우드 환경에서 적용할 때 Best practice 관련해 참고할 문서가 적어 아쉬웠습니다. 이 문서가 정답이 아닌 이런 식으로 할 수 있겠구나 정도로 인지해주셨으면 좋겠고 더 나은 방법을 함께 고민해보고 싶습니다.

문서를 작성하는 본인도 보안에 관련하여 전문가는 절대 아닙니다. 이번 프로젝트에서 정말 많은 사람들의 도움을 받았으며, 무엇보다 연결이 되는 데 막는 것과 연결 자체가 안되는 것에는 차이가 있다는 것을 중점을 두고 진행하였습니다.

이 글이 AWS와 같은 클라우드 환경에서 보안 심사를 위한 인프라 아키텍처를 고민하시는 분들께 도움이 됬으면 합니다.

3개의 댓글

comment-user-thumbnail
2021년 5월 18일

잘 보았습니다. 좋은 글 감사합니다.

답글 달기
comment-user-thumbnail
2021년 5월 20일

저희 테크 블로그로 가져가도 되는건가요? ㅎㅎㅎㅎ

답글 달기
comment-user-thumbnail
2021년 6월 3일

참고할민한 사례가 없는가운데 이정도로 고민하고 구현한 노하우를 공유해 주셔서 감사합니다.

답글 달기