EC2에서 프라이빗 RDS로: 같은 VPC, peering, 아니면 다른 방법?
보안 그룹보다 경로를 먼저 선택하세요. 같은 VPC, peering, 공유 VPC 또는 프라이빗 상호 연결입니다.
개발자의 노트북은 직원 VPN을 통해 프라이빗 RDS 인스턴스에 도달하지만 EC2의 애플리케이션은 전혀 연결할 수 없습니다. 이것은 깨진 배포가 아닙니다. 노트북에는 EC2 인스턴스가 절대 상속하지 않는 터널이 있고, RDS의 «프라이빗»은 데이터베이스에 공용 엔드포인트가 없다는 뜻이지 사람 VPN 사용자만 유일한 허용 호출자라는 뜻이 아닙니다. 애플리케이션에는 자체 승인된 경로, 자체 보안 그룹 관계, 자체 데이터베이스 ID가 필요하며, 이 세 가지를 선택하는 순서가 디버깅의 대부분을 절약합니다. 먼저 경로를 정하고, 다음으로 권한을 정하고, 마지막으로 책상이 아니라 배포된 환경에서 검증하세요.
노트북 VPN은 애플리케이션의 경로가 아니다
직원 VPN이 사람에게 무엇을 하든, 해당 인스턴스가 같은 네트워크 경로의 일부임이 명시되지 않는 한 인스턴스에는 아무것도 하지 않습니다. 프라이빗 서브넷의 EC2 인스턴스는 VPC 라우팅, 보안 그룹, 네트워크 ACL을 통해 RDS에 도달합니다. 사람의 터널, 사람의 세션, 사람의 자격 증명을 상속하지 않으며 상속해서도 안 됩니다. 무인 애플리케이션 연결과 직원의 원격 액세스는 독립적으로 운영되어야 합니다.
이 독립성은 장점입니다. VPN이 중단되어도 애플리케이션은 계속 작동합니다. 애플리케이션이 잘못 동작해도 누구도 원격 액세스를 잃지 않습니다. 둘을 하나의 경로로 합치는 설계는 보통 인시던트 도중, 최악의 순간에 발견됩니다.
결정 1: 같은 VPC, 직접 경로
애플리케이션과 데이터베이스가 같은 VPC에 있고 직접 라우팅되며 사이에 검사용 미들박스가 없으면 경로는 단순하고 보안 그룹 참조가 사용 가능한 가장 강력한 도구입니다. 애플리케이션에 자체 그룹을 부여한 다음 주소 범위가 아니라 그 그룹에서 데이터베이스 포트를 허용하세요:
aws ec2 authorize-security-group-ingress --group-id sg-0db123 --protocol tcp --port 5432 --source-group sg-0app456
aws rds describe-db-instances --db-instance-identifier prod-db --query 'DBInstances[0].{Endpoint:Endpoint.Address,Port:Endpoint.Port,Public:PubliclyAccessible,Groups:VpcSecurityGroups}'
포트는 예시이며 엔진과 일치해야 합니다. 그룹 참조는 애플리케이션 인스턴스의 트래픽을 승인하며, 그 규칙을 복사하지도 데이터베이스 로그인을 만들지도 않습니다. 두 가지 별개 문제, 두 가지 별개 수정.
그런 다음 방금 추가한 규칙에서 멈추지 말고 경로의 나머지를 확인하세요. 애플리케이션의 아웃바운드 정책, 데이터베이스에 연결된 그룹의 전체 집합, 서브넷 라우트 테이블, 모든 네트워크 ACL이 모두 일치해야 합니다. 보안 그룹 규칙은 상태 저장이지만 사용자 지정 네트워크 ACL은 요청과 반환 트래픽을 별도 규칙으로 허용해야 하며 임시 포트도 포함합니다. 새롭게 좁힌 데이터베이스 규칙이 이미 연결된 이전의 넓은 허용을 취소하지도 않습니다.
결정 2: 다른 VPC 또는 다른 계정
애플리케이션이 다른 VPC에 있으면 네트워크 소유자가 지원되는 프라이빗 상호 연결을 선택합니다. peering, 트랜짓 설계 또는 공유 VPC 구성입니다. 그런 다음 라우팅의 양방향이 존재해야 하고, 이름 확인이 RDS 엔드포인트에 대해 작동해야 하며, 데이터베이스 정책이 평가하는 소스가 실제로 도착하는 것과 일치해야 합니다. 계정 이름이 일치하거나 공유 결제 관계가 있다고 해서 그중 어느 것도 제공되지는 않습니다.
보안 그룹 참조는 달라지는 부분입니다. 여러 프라이빗 상호 연결 설계에서 작동하지만 미들박스가 소스를 다시 쓰거나 연결을 종료하는 순간 작동을 멈춥니다. 데이터베이스가 애플리케이션 그룹이 아니라 미들박스를 보기 때문입니다. RDS VPC 시나리오는 같은 VPC 내부 액세스와 다른 구성을 구분하므로 규칙 스타일이 그대로 통한다고 가정하기 전에 특정 토폴로지를 이와 대조해 확인할 가치가 있습니다.
누락된 경로를 데이터베이스를 공개적으로 접근 가능하게 만들어 해결하지 마세요. 그것은 다른 소유자가 있는 다른 노출 결정이며, 보통 결과에서 가장 멀리 있는 사람이 제안합니다.
결정 3: 데이터베이스가 받아들이는 ID
네트워크 액세스와 데이터베이스 인증은 별개의 계층이며, 이를 혼동하면 가장 오해를 부르는 오류가 생깁니다. 인스턴스 역할은 AWS API를 호출하기 위한 AWS ID이며 데이터베이스 사용자가 아닙니다. IAM 데이터베이스 인증은 엔진과 구성이 허용하는 경우 지원되는 기능이며, 여전히 데이터베이스 사용자에 대한 매핑이지 그 대체가 아닙니다.
애플리케이션 구성에서는 한 번의 조회로 얻은 주소 대신 RDS 엔드포인트 이름을 사용하세요. Multi-AZ 페일오버는 그 이름 뒤의 주소를 바꾸며, IP에 고정된 애플리케이션은 필요한 바로 그 순간에 실패합니다. 오류를 없애기 위해 엔진의 TLS 검증을 끄는 대신 켜 둔 상태로 유지하세요. 검증 실패는 도달한 엔드포인트에 대해 무언가를 알려줍니다.
그런 다음 데이터베이스 계정에 애플리케이션이 필요로 하는 최소 권한을 실제로 사용하는 스키마에서 부여하세요. 그 작업은 지루하고 감사 가능하며, 인시던트 검토가 묻는 부분입니다.
배포된 환경에서 검증하세요
인스턴스에서 또는 같은 그룹, 서브넷, 역할로 실행되는 작업에서 테스트하세요. 네 가지 실패는 노트북에서 비슷해 보이지만 거기서는 쉽게 구분됩니다. 확인되지 않는 이름, 시간 초과되는 연결, TLS 검증 실패, 거부된 데이터베이스 로그인입니다. 각각은 다른 경계를 가리키며, 어느 것인지 알기 전에 데이터베이스 노출을 바꾸는 것은 추측입니다.
psql "host=prod-db.abc123.eu-west-1.rds.amazonaws.com port=5432 dbname=app sslmode=verify-full" -c 'select 1'
인스턴스에서 연결이 성공하고 책상에서 실패하면 애플리케이션 경로는 정상이며 고쳐야 할 것은 당신의 접근입니다. 둘 다 실패하면 자격 증명이 아니라 위의 그룹과 경로 확인부터 시작하세요. 이 하나의 비교가 이러한 티켓이 만드는 대부분의 혼란을 막습니다.