어떤 소프트웨어든 서비스든 그것의 품질이나 성능도 중요하지만, 보안적 요소또한 매우 중요하다.
AWS에서는 VPC 네트워크의 접근 제어를 위해 보안그룹과 NACL을 사용한다.
보안그룹(Security Group)
NACL(Network Access Control List)
두 가지 모두 네트워크 접근제어를 수행한다는 점에서 비슷한 듯 하지만, 사용방법이나 용도 등 확실한 차이점이 있다.
앞으로의 설명을 위해 몇가지 개념을 짚고 넘어가겠다.
- 화이트리스트(White List) 접근제어
모든 트래픽을 기본적으로 전부 차단한 상태에서 필요한 트래픽만 허가하는 방식
- 블랙리스트(Black List) 접근제어
모든 트래픽을 기본적으로 허가한 상태에서 거부할 트래픽만 차단하는 방식
- 상태 저장 방식(Stateful)
네트워크 통신 시 클라이언트의 IP와 포트 정보가 있는데, 접근 제어시 이를 기억하는 방식
- 상태 비저장 방식(Stateless)
3번과는 다르게 기억하지 않고 처리하는 방식
화이트리스트와 블랙리스트기반으로 차단하긴 하지만, 실제로는 화이트리스트 방식에 허용과 거부를 전부 선언하는 등 두가지 방법 전부 섞어서 사용하고 있다.
그렇기 때문에 규칙 최 하단에 모두 허가가 있으면 블랙리스트 기반 하이브리드, 모두 거부가 있으면 화이트리스트 기반 하이브리드라고 하겠다.
보안그룹은 화이트리스트 방식이다.
명시적으로 허용한 트래픽에 대해서만 통신을 허가하며, 그 외의 트래픽은 전부 차단한다.
혼합된 하이브리드 방식이 아니기 때문에 굳이 규칙에 우선순위를 부여할 필요가 없기에 선언된 규칙에 순서는 없다.
보안그룹은 ENI와 연결되며, 연결된 ENI의 통신을 정해진 규칙에 따라 제어한다.
하나의 ENI에 여러개의 보안그룹을 연결할 수 있고, 하나의 보안그룹을 여러개의 ENI에 연결할 수 있다. 즉, 1:N, N:1 관계가 성립한다.
보안그룹은 상태 저장 방식(Stateful)이다. 이것이 의미하는 바는 아래의 예시를 읽어보면 이해할 수 있을 것이다.
보안그룹이 출발지가 0.0.0.0/0인 목적지 포트가 443인 TCP 인바운드 트래픽을 허가하고 있다. 하지만, 아웃바운드는 명시적으로 허가된 것이 없다.
이때, 443포트로 인바운드 트래픽이 수신된다.
보안그룹 규칙에 의거하여 해당 트래픽은 통신이 허가되며 해당 트래픽이 처리된 후 응답이 돌아온다.
응답은 다시 ENI를 거쳐 클라이언트에게 돌아갈 것이다.
보안그룹에는 명시적인 아웃바운드가 허가된 것이 없다.
하지만, 이미 인바운드에서 해당 트래픽은 허가되었기 때문에 응답 트래픽은 차단되지 않고 무사히 클라이언트로 전송될 수 있다.
이것이 상태 저장 방식이다. 쉽게 말해 해당 트래픽이 보안그룹을 이미 통과한 전적이 있는지 아닌지 기억하고 있으며 허가된 트래픽이라면 재검사 하지 않는다.
NACL은 블랙리스트 기반 하이브리드, 화이트리스트 기반 하이브리드 두가지 방식 모두 가능하다.
NACL 설정에서 최하단 규칙을 모든 트래픽 허용으로 설정하냐 거부로 설정하냐에 따라 달라진다.
NACL은 하이브리드 방식을 사용하기 때문에 규칙에 우선순위를 부여해야 하며, 이 순서에 따라 동작이 바뀔 수 있다.
예시 1
Rule no.1 123.45.67.0/24 -> 192.168.100.100:443 Allow
Rule no.2 123.45.67.50/32 -> 192.168.100.100:443 Deny
Rule no.3 ALL Deny
이 규칙은 127.45.67.0/24 대역이 출발지이며 192.168.100.100의 443포트를 목적지로 하는 트래픽을 허가하고, 123.45.67.50 IP에서 수신되는 트래픽은 차단된다.
하지만, 123.45.67.50은 123.45.67.0/24 대역에 포함되며, 이미 해당 대역이 전부 허가되었기 때문에 거부 규칙은 무시된다.
예시 2
Rule no.1 123.45.67.50/32 -> 192.168.100.100:443 Deny
Rule no.2 123.45.67.0/24 -> 192.168.100.100:443 Allow
Rule no.3 ALL Deny
이 규칙은 123.45.67.50 IP에서 수신되는 트래픽은 차단하고, 127.45.67.0/24 대역이 출발지이며 192.168.100.100의 443포트를 목적지로 하는 트래픽을 허가한다.
비록 2번 규칙에서 123.45.67.0/24 대역을 전부 허가했지만 이보다 우선순위가 높은 1번 규칙에서 123.45.67.50 IP를 차단했기 때문에 예시 1번과는 다르게 해당 아이피는 차단된다.
NACL은 서브넷에 연결되며 서브넷을 통과하는 트래픽을 제어한다.
하나의 서브넷에는 하나의 NACL만 연결할 수 있다. 하지만 NACL은 여러개의 서브넷에 연결 가능하다. 즉, 서브넷과 NACL은 1:N 관계이다.
NACL은 상태 비저장 방식(Stateless)방식이다. 이것이 의미하는 바는 아래의 예시를 읽어보면 이해할 수 있을 것이다.
NACL이 출발지가 0.0.0.0/0인 목적지 포트가 443인 TCP 인바운드 트래픽을 허가하고 있다. 그리고 그 이외의 모든 통신은 차단한다. 또한, 아웃바운드는 명시적으로 허가된 것이 없고 모든 트래픽을 차단한다.
이때, 443포트로 인바운드 트래픽이 수신된다.
NACL 규칙에 의거하여 해당 트래픽은 통신이 허가되며 해당 트래픽이 처리된 후 응답이 돌아온다.
응답은 다시 서브넷을 통과하여 클라이언트에게 돌아갈 예정이다.
하지만, NACL에는 명시적인 아웃바운드가 허가된 것이 없다.
보안그룹과는 다르게 해당 트래픽이 이전에 NACL을 통과하였는지 기억하지 않기 때문에 클라이언트에게 돌아가는 응답, 즉, 아웃바운드 트래픽을 다시 검사한다.
아웃바운드 트래픽은 명시적으로 허가된 것이 없기 때문에 해당 트래픽은 차단되며 클라이언트는 응답을 수신할 수 없다.
이것이 상태 비저장 방식이다. 쉽게말해 보안그룹과는 다르게 해당 트래픽이 보안그룹을 이미 통과한 전적이 있는지 아닌지 기억하지 않으며, 이전에 허가된 트래픽이라도 서브넷을 출입할 시 다시 재검사 한다.
보안그룹과 NACL의 차이점을 요약하자면 아래의 표와 같다.
그리고 보안그룹과 NACL의 관계를 그림으로 나타내면 아래와 같다.
위에서 설명했듯이 보안그룹은 상태 저장 방식이다.
그렇기 때문에 사용 가능한 아주 유용한 기능이 있다.
바로 보안그룹 체이닝이다.
보안그룹 체이닝
보안그룹 규칙을 적용하는 방식 중 하나로, 보안그룹간에 연결을 설정하여 여러 보안그룹의 규칙을 적용할 수 있는 기능
보안그룹에서는 트래픽의 소스를 지정하여 규칙을 설정하는데 CIDR 블록, 특정 AWS 리소스의 접두사와 함께 보안그룹 자체를 지정할 수 있다.
즉, 특정 아이피나 리소스레서 들어오는 트래픽을 허가하는것 뿐 아니라 특정 보안그룹을 거쳐서 오는 트래픽을 지정하여 허가할 수 있다는 뜻이다.
이렇게만 말하면 약간 이해하기 힘드니 예시를 하나 들겠다.
위 그림은 하나의 VPC의 예시를 나타낸 것이다.
VPC에는 퍼블릭 서브넷과 프라이빗 서브넷이 하나씩 있다.
퍼블릭 서브넷에는 FTP 서버 인스턴스와 Web 서버 인스턴스가 존재한다.
프라이빗 서브넷에는 DB 서버가 존재한다.
각 인스턴스에는 하나씩 보안그룹이 설정되어 있고 그림에 표기된대로 각 서비스에 맞는 포트가 허가되어 있다.
일반적인 경우라면 FTP 서버에서 DB 서버로 접근할 일은 없을 것이다. 그렇기 때문에 DB 보안그룹에서는 Web 서버에서 오는 트래픽만 허용하려 할 것이다.
하지만, 이를 어떤 기준으로 나눠야 할지 애매하다.
서브넷에 생성되는 인스턴스의 사설 아이피는 별도로 설정하지 않는 이상 인스턴스가 새로 생성되거나 재시작 할때마다 바뀐다. 만약 Auto Scailing을 적용하여 인스턴스들이 자동으로 생성되고 소멸한다면 아이피를 추적하기 더 힘들 것이다.
하지만, 그렇다고 DB 서버의 보안그룹에 퍼블릭 서브넷의 CIDR인 172.31.10.0/24 대역에 대한 허가를 해버리면 불필요한 FTP 서버에서의 접근이 허가된다.
이는 보안을 고려할 때 대 전제중 하나인 최소 권한의 원칙을 위반하는 것이다.
그렇다고 매번 바뀌는 Web 서버의 아이피를 일일이 보안그룹에 적용하는것은 Elastic 하지 않다.
이럴때 사용할 수 있는 것이 바로 지금 설명하려는 보안그룹 체이닝이다.
만약, DB 서버로 들어오는 트래픽 중 Security Group 2(Web 서버의 보안그룹)을 통과한 트래픽만 허가되도록 설정할 수 있다면 어떨까?
그렇다면 위에서 한 고민을 한번에 해결할 수 있을 것이다.
Security Group 3(DB 서버의 보안그룹)에 규칙을 추가한다.
인바운드 트래픽 중 Security Group 2(Web 서버의 보안그룹)를 통과하고, TCP 3306이 목적지 포트인 트래픽을 허가한다.
이런 식으로 보안그룹의 소스 참조를 다른 보안그룹으로 설정 할 수 있다.
이렇게 한다면 별도로 아이피 대역에 따라 일일이 보안그룹을 설정할 필요 없이 매우 간단하게 보안그룹 관계를 관리할 수 있다.
위에서 설명했듯이 NACL은 규칙에 우선순위가 있으며 그렇기 때문에 각 규칙마다 번호가 매겨져있다.
미미한 팁이지만, 이러한 규칙들을 적절히 정리하고 압축하는것이 좋다.
그 이유는, 다음과 같다.
- 규칙이 너무 엉켜있으면 관리하기 힘들다.
사람이 읽기 힘들면 자칫하다가 보안에 구멍이 생길 수 있다.
- 아주 약간의 네트워크 성능 향상을 노릴 수 있다.
NACL은 1번 규칙부터 아래로 내려오면서 하나씩 체크한다. 그렇기 때문에 규칙의 개수가 많아지면 일일이 비교할 규칙이 많아져 해당 트래픽을 허가할지 거부할지 판별하는데 시간이 더 소요될 것이다.
실 서비스를 제공하는 프로덕션 환경이 아니고, 소규모 프로젝트나 개인이 공부를 하기 위해 AWS를 사용할 경우 보안그룹과 NACL을 Default 설정인 상태로 사용하는 경우가 많다.
물론, 서비스를 위해 보안그룹의 인바운드 규칙은 수정하는 경우가 많겠지만, 그 외의 경우는 따로 설정하지 않아도 서비스에는 문제가 없기 때문이다.
하지만, 이는 보안적으로 매우 큰 문제 중 하나이다.
우선 보안그룹의 경우, 아웃바운드 Default 설정은 0.0.0.0/0으로 가는 모든 트래픽에 대해서 허가한다. 즉, 아웃바운드 트래픽은 아무런 제약을 받지 않는다.
만약 해당 보안그룹을 사용하는 인스턴스가 해킹당해 Reverse Connection 등 악의적인 통신을 시도한다면 이를 막지 못할 것이다.
NACL의 경우, VPC를 생성 시 기본적으로 하나 생성된다. 그리고 VPC에 생성된 모든 Subnet은 별도의 설정을 하지 않는다면 기본생성된 NACL이 연결된다.
기본 생성된 NACL은 인바운드, 아웃바운드 규칙 전부 ALL Allow로 설정되어 있다. 그냥 무조건 모든 트래픽을 수용한다는 것이다.
보안 담당자가 이렇게 설정되어 있는걸 보면 아마 뒷목을 잡을 것이다.
그러니 우리는 보안그룹과 NACL 설정을 잘 살펴보고, 기본 규칙 그대로 놔두는 불상사를 피해야 할 것이다.