제가 참여하고 있는 커뮤니티에서 “우아한 형제들”에서 진행한 아래의 동영상을 본 후 문의사항이 하나 있었는데요. 이 문의 사항이 다른 분들도 충분히 궁금해하실 수 있는 내용인 것 같아 포스팅합니다.
먼저, 훌륭한 컨텐츠를 제공해주신 발표자분께 감사를 드리며 질문하신 분이 궁금해 하는 내용을 살펴보도록 하겠습니다. 동영상의 뒷부분에서 언급된 내용 중 일부분을 보면 AWS WAF Classic 에서 AWS New WAF 로 규칙을 Migration 하는 과정에서 뜻밖의 예상하지 못한 규칙의 동작을 확인하게 되었고 이를 해결했던 사례에 대한 것이었는데요.
질문자가 궁금해했던 시나리오는 다음과 같습니다.
- AWS WAF Classic 에서 사용했던 규칙이 아래의 그림과 같은 상황이었습니다.
이 규칙의 목적은 Host Header 에 example1. 이나 example2.com 을 포함하지 않는 Host 정보가 있다면 규칙을 위반하는 것으로 판단하고 차단하겠다는 것인데요. 예를 들면 AWS WAF 로 example.com, www.example2.com 과 같이 example1. 과 example2. 를 포함하지 않는 Host 요청에 대해서는 차단하겠다는 겁니다.
2. AWS new WAF 로 이 규칙을 Migration 했고 첫번째 시행착오(?)를 겪은 후 new WAF 에서 제공하는 “OR Statement” 와 “Negate Statement” 옵션을 이용하여 아래와 같이 “Host” Header 값이 “example1.” 을 포함하지 않거나 “example2.” 을 포함하지 않으면 차단되도록 구성하였습니다.
3. 위와 같이 AWS New WAF 에서 “OR Statement” 와 “Negate Statement” 옵션을 이용하여 “example1.” 과 “example2.” 을 포함하지 않는 요청에 대해서는 차단하도록 구성을 하였는데 실제로 규칙을 적용해보니 “www.exampl1.com” 이나 “www.example2.com” 과 같은 모든 정상 트래픽들도 차단이 되었습니다.
4. 그래서 이 문제를 해결하기 위한 방안으로 String Match 가 아닌 정규 표현식을 사용하였습니다.
의문점. 무엇이 문제인가?
이 과정에서 질문하신 분이 궁금했던 부분은 New WAF 에서 “OR Statement” 와 “Negate Statement” 옵션을 이용해서 규칙을 생성했는데 왜 정상적인 트래픽들조차 차단이 되었고 왜 정규표현식을 사용할 수 밖에 없었는가? 이것은 AWS New WAF 의 Bug 인가? 인데요.
결론을 먼저 말씀드리면 이건 AWS New WAF 의 Bug 가 아니라 설정한대로 잘 동작을 한 것입니다.
그럼 이해를 돕기 위해 WAF Classic 의 내용과 New WAF 의 규칙을 한 번 살펴보도록 하겠습니다.
AWS WAF Classic 규칙 분석
먼저, WAF 관리자의 목적을 정리하겠습니다.
규칙의 목적 : Request 의 Host Header 에 example1. 이나 example2. 이 포함되어 있지 않은 요청은 모두 차단한다.
WAF Classic 의 규칙 설명
위 그림의 WAF Classic 규칙을 보면 이렇게 동작하도록 설정되어 있습니다.
Filter 부분을 보면 “Request Header 의 “Host” 값이 “example1.” 을 포함하고 있지 않거나 “example2.” 을 포함하고 있지 않으면 매칭한다.”
그리고 이런 문구가 또 있습니다.
“When a request does not match at least one of the filters in the string match condition”
즉, Filter 에 있는 두 가지 조건 중 하나라도 매칭되지 않은 경우 조건을 매칭하는 것으로 판단한다.
그리고 관리자는 이 규칙의 Action 을 아마 다음과 같이 Block 으로 설정하였을 것입니다.
이 상황에서 여러가지 요청이 유입되었을 때 AWS WAF Classic 은 어떻게 동작하게될지 살펴보겠습니다.
- www.example1.com = Host 에 example1. 이 포함되어 있으므로 Filter 의 조건 중 1개는 만족을 합니다. 즉, Condition 은 만족할 수 없습니다. 왜냐하면 Condition 을 만족하려면 Filter 에 만족하는 조건이 하나도 없어야 하니까요. 따라서, 결과적으로 이 요청은 차단되지 않습니다.
- www.example2.com = Host 에 example2. 이 포함되어 있으므로 Filter 의 조건 중 1개는 만족을 합니다. 즉, Condition 은 만족할 수 없습니다. 왜냐하면 Condition 을 만족하려면 Filter 에 만족하는 조건이 하나도 없어야 하니까요. 따라서, 결과적으로 이 요청은 차단되지 않습니다.
- www.example.com = Host 의 값이 어떤 Filter 도 만족하지 않습니다. 즉, Condition 을 만족할 수 있는 조건이 되었습니다. 따라서, 이 요청은 차단됩니다.
- www.example3.com = Host 의 값이 어떤 Filter 도 만족하지 않습니다. 즉, Condition 을 만족할 수 있는 조건이 되었습니다. 따라서, 이 요청은 차단됩니다.
설명드린 바와 같이 이 규칙의 내용을 살펴보면 관리자가 의도했던대로 잘 동작하는 구조임을 알 수 있습니다.
AWS New WAF 규칙 분석
그럼 이번에는 New WAF 에서 사용했던 규칙을 살펴보도록 하겠습니다.
참고. 이 화면에는 보이지 않지만 관리자는 이 규칙의 Action 도 Block 으로 구성하였을 것입니다.
New WAF 의 설정된 규칙을 살펴보면 내용은 다음과 같습니다.
NOT Statement1 = Request Header 의 Host 값이 example1. 을 포함하고 있지 않으면 매칭된다.
혹은
NOT Statement2 = Request Header 의 Host 값이 example2. 을 포함하고 있지 않으면 매칭된다.
따라서, 이 규칙의 Action 이 Block 이라면 이 규칙의 내용을 말로 풀어서 설명하면
“사용자가 요청한 Request 의 Host Header 가 exampl1. 을 포함하고 있지 않거나 example2. 를 포함하고 있지 않으면 차단한다.”
입니다.
여기까지만 들으면 마치 New WAF 의 이 규칙도 WAF Classic 에서 사용했던 규칙과 동일하게 동작할 것만 같은 느낌인데요. 사실 그럴까요?
WAF Classic 의 경우처럼 몇 가지 상황을 예를 들어 적용해보도록 하겠습니다.
- www.example1.com = Host 에 example1. 이 포함되어 있으므로 두 가지 “Not Statement” 중 첫번째는 매칭되지 않습니다. 하지만 “example2.” 를 포함하고 있는 것은 아니므로 두번째 “Not Statement” 는 매칭되게 됩니다. 그리고 이 규칙은 두 가지 “Not Statement” 중 하나라도 매칭되면 차단될 수 있도록 “OR” 조건을 사용하였습니다. 따라서, 결과적으로 이 요청은 차단됩니다.
- www.example2.com = Host 에 example2. 이 포함되어 있으므로 두 가지 “Not Statement” 중 두번째는 매칭되지 않습니다. 하지만 “example1.” 를 포함하고 있는 것은 아니므로 첫번째 “Not Statement” 는 매칭되게 됩니다. 따라서, 이 요청은 차단됩니다.
- www.example.com = Host 의 값이 두 가지 “Not Statement” 를 모두 만족합니다. 따라서, 이 요청은 차단됩니다.
- www.example3.com = Host 의 값이 두 가지 “Not Statement” 를 모두 만족합니다. 따라서, 이 요청은 차단됩니다.
보시는 바와 같이 이번에는 어떤 요청을 하더라도 모두 차단되는 결과가 나오는 것을 확인할 수 있습니다.
왜 그런걸까요?
아마 여기까지 읽으셨다면 모두 이해하셨겠지만 이 예제에 있는 규칙은 일반적으로 만족할 수 없는 상반된 규칙을 OR 조건으로 구성을 하였기때문입니다.
즉, Host Header 에 example1. 이 없어도 차단하고 example2. 가 없어도 차단한다는 의미와 같기 때문에 example1. 이 포함된 경우에는 example2. 가 없다는 이유로 차단되고 example2. 가 포함된 경우에는 example1. 이 없다는 이유로 차단이 되어버린 것입니다.
따라서, 이 규칙은 얼핏 보기에는 Bug 처럼 보일 수도 있지만 설정된 규칙에 따라 잘 동작한 것임을 알 수 있습니다.
AWS New WAF 에서의 규칙 적용 방법
그렇다면 New WAF 에서는 어떻게 규칙을 구성해야 WAF Classic 에서 사용하던 규칙을 구현할 수 있을까요?
동영상의 예시처럼 정규 표현식을 사용하는 것도 하나의 방법입니다.
즉 “|” 옵션을 정규 표현식에 사용하여 “|” 로 구분되는 String 값을 “OR” 로 선택되도록 하는 방법입니다.
또다른 방법은 여러개의 “Not Statement” 규칙을 위의 예와 같이 “OR” 로 묶지 않고 별도의 규칙으로 구분해서 생성하는 방법입니다.
아래와 같이 “Not Statement” 를 갖는 규칙을 별도로 구분하여 작성하는 것입니다.
Not Statement + OR 의 활용방법
어떤 분은 이런 궁금증이 생기실 수도 있을 것 같습니다.
“그럼 “Not Statement” 를 “OR” 조건으로 묶어서 사용하는 경우는 어떤 경우인가?”
이런 경우를 생각해볼 수 있을 것 같습니다.
example.com 으로 접속하는 모든 사용자 요청은 User-Agent 로 Chrome 을 사용하여야 하고 WAF 에서는 example. 을 포함하지 않는 Host 에 대한 요청은 차단하여야 한다.
이런 요구 사항이라면 두 개의 “Not statement” 를 “OR” 로 조합하여 구성하여 만족할 수 있겠죠.
Not Statement 1 = Host 에 example. 이 포함되어 있지 않은 경우 매칭
OR
Not Statement 2= User-Agent 에 Chrome 이 포함되어 있지 않은 경우 매칭
Action = Block
이렇게 구성되어 있다면 다음과 같은 시나리오가 될 겁니다.
www.example.com (Chrome) = Not Statement 1매칭 안됨, Not Statement 2 매칭 안됨. 따라서, 허용
www.example1.com (Chrome) = Not Statement 1매칭됨, Not Statement 2 매칭 안됨. 따라서, 차단
www.example.com (Safari) = Not Statement 1매칭 안됨, Not Statement 2 매칭 됨. 따라서, 차단
www.example1.com (Safari) = Not Statement 1매칭됨, Not Statement 2 매칭 됨. 따라서, 차단
보시는 바와 같이 Not Statement 2개를 OR 로 구성하였을 경우 기대했던 대로 동작할 수 있는 것을 확인할 수 있습니다.
위 동영상에서도 언급되었지만 WAF 에서의 규칙 적용은 조심스러운 작업일 수 밖에 없습니다. 따라서, 새로운 규칙을 적용할 때에는 Sandbox 환경이나 별도의 테스트 환경에서 해당 규칙을 검증한 후 적용하거나 Count Mode 로 적용하여 새로운 규칙으로 인한 영향도를 파악한 후에 Block Mode 로 전환하는 것을 추천드립니다.
감사합니다.