소개
Snort 는 강력한 오픈 소스 네트워크 침입 탐지 시스템 (NIDS) 입니다. Snort 의 가장 큰 특징 중 하나는 유연한 규칙 기반 언어로, 보안 전문가가 악의적인 네트워크 활동에 대한 시그니처를 직접 정의할 수 있다는 점입니다.
규칙은 이론과 탐지 사이를 잇는 가교입니다. "포트 스캔은 의심스럽다"와 같은 보안 아이디어는 엔진이 실제 트래픽을 평가할 수 있는 형태로 표현될 때 비로소 운영상 유용해집니다. 따라서 규칙 구문을 배우는 것은 단순히 Snort 사용법을 익히는 것을 넘어, 방어자가 어떻게 행동 양식을 기계가 읽을 수 있는 논리로 변환하는지를 배우는 과정입니다.
이 실습에서는 사용자 지정 Snort 규칙의 핵심 구문과 구조를 배웁니다. Action, Protocol, IP 주소, Port 및 Option 을 정의하는 기초 규칙을 작성하여 특정 ICMP 핑과 비정상적인 TCP 트래픽 패턴을 탐지하고 경고하는 방법을 익힙니다. 실습을 마칠 때쯤이면 자신만의 Snort 규칙을 구성하고, 테스트하며, 검증하는 방법을 이해하게 될 것입니다.
규칙 구문 및 헤더 이해하기
이 단계에서는 Snort 규칙의 기본 구조를 배우고 사용자 지정 규칙을 저장할 파일을 생성합니다.
헤더는 사실상 범위 정의 (scope definition) 입니다. 헤더는 어떤 트래픽을 더 자세히 평가할 가치가 있는지 결정합니다. 효율적인 탐지는 더 깊은 콘텐츠 검사를 수행하기 전에 후보 트래픽 집합을 최대한 좁히는 것에서 시작하기 때문에 이는 매우 중요합니다. 범위가 넓은 헤더는 작성하기 쉽지만, 더 많은 노이즈를 발생시킬 수 있습니다.
Snort 규칙은 크게 **규칙 헤더 (Rule Header)**와 **규칙 옵션 (Rule Options)**이라는 두 가지 논리적 섹션으로 나뉩니다.
규칙 헤더에는 규칙의 액션, 프로토콜, 출발지 및 목적지 IP 주소, 출발지 및 목적지 포트가 포함됩니다. 이는 누가 누구에게 통신하며 어떤 프로토콜을 사용하는지를 결정합니다. 기본 구문은 다음과 같습니다:
[Action] [Protocol] [Source IP] [Source Port] -> [Destination IP] [Destination Port] (Options)
헤더 구성 요소에 대한 설명은 다음과 같습니다:
- Action: 규칙 조건과 일치하는 패킷을 발견했을 때 Snort 가 수행할 작업 (예:
alert,log,drop). - Protocol: 트래픽의 프로토콜 (예:
tcp,udp,icmp,ip). - IP Addresses: 출발지 및 목적지 IP 주소.
any를 사용하여 모든 IP 주소와 일치시킬 수 있습니다. - Ports: 출발지 및 목적지 네트워크 포트.
any를 사용하여 모든 포트와 일치시킬 수 있습니다. - Direction Operator:
->기호는 트래픽의 방향 (출발지에서 목적지로) 을 나타냅니다. 양방향 트래픽의 경우<>를 사용할 수도 있습니다.
자신만의 규칙을 작성하기 위해 전용 파일이 필요합니다. 기본 작업 디렉토리 (~/project) 에 있는지 확인하고 local.rules라는 새 파일을 생성합니다.
touch 명령어를 사용하여 빈 파일을 생성합니다:
touch ~/project/local.rules
디렉토리 내용을 나열하여 파일이 성공적으로 생성되었는지 확인할 수 있습니다:
ls -l ~/project/local.rules
파일이 존재하며 현재 비어 있음을 확인하는 다음과 유사한 출력이 표시되어야 합니다:
-rw-r--r-- 1 labex labex 0 Jul 25 10:00 /home/labex/project/local.rules
ICMP 탐지 규칙 작성하기
이 단계에서는 ICMP 트래픽을 탐지하기 위한 첫 번째 Snort 규칙을 작성합니다. ICMP(Internet Control Message Protocol) 는 ping과 같은 네트워크 유틸리티에서 연결 상태를 확인하기 위해 흔히 사용됩니다.
ICMP 는 간단하고 인식하기 쉬워 좋은 학습 예제이지만, 동시에 중요한 운영상의 시사점을 줍니다. 모든 탐지가 공격을 의미하는 것은 아니라는 점입니다. 많은 네트워크에서 핑을 합법적으로 사용합니다. 분석가의 역할은 규칙이 일치시킨 내용과 환경적 맥락을 결합하여 해당 이벤트가 무해한지 아니면 의심스러운지 판단하는 것입니다.
모든 출발지에서 모든 목적지로 이동하는 모든 ICMP 패킷에 대해 경고를 발생시키는 규칙을 작성해 보겠습니다.
nano 텍스트 편집기를 사용하여 local.rules 파일을 엽니다:
nano ~/project/local.rules
편집기에 다음 규칙을 입력합니다:
alert icmp any any -> any any (msg:"ICMP Ping Detected"; sid:1000001; rev:1;)
이 규칙의 의미를 분석해 보겠습니다:
alert: 수행할 작업입니다. Snort 가 경고를 생성합니다.icmp: 모니터링할 프로토콜입니다.any any -> any any: 트래픽은 모든 IP 와 모든 포트에서 발생할 수 있으며, 모든 IP 와 모든 포트로 향할 수 있습니다.(msg:"ICMP Ping Detected"; sid:1000001; rev:1;): 규칙 옵션입니다.msg는 경고 메시지,sid는 고유한 Snort ID(사용자 지정 규칙은 1,000,000 이상의 ID 를 가져야 함),rev는 규칙의 수정 번호입니다.
규칙을 입력한 후 Ctrl+O, Enter를 눌러 파일 이름을 확인하고, Ctrl+X를 눌러 nano를 종료합니다.
이제 Snort 가 규칙 파일을 이해하는지 테스트해 보겠습니다. Snort 에는 탐지 엔진을 실제로 시작하지 않고 구성 및 규칙의 구문 오류를 확인하는 테스트 모드 (-T) 가 있습니다.
다음 명령어를 실행하여 규칙 파일을 테스트합니다:
sudo snort -T -c ~/project/local.rules
Snort 가 초기화되면서 많은 출력이 표시됩니다. 출력 하단 근처에서 Snort 가 구성을 성공적으로 검증했음을 나타내는 성공 메시지를 찾으세요:
Snort successfully validated the configuration!
Snort exiting
이 메시지가 보인다면 ICMP 규칙의 구문이 올바른 것입니다.
TCP 포트 경고 규칙 작성하기
이 단계에서는 특정 TCP 트래픽을 탐지하는 규칙을 작성합니다. ICMP 는 포트를 사용하지 않지만, TCP 와 UDP 는 포트를 사용합니다. 이를 통해 HTTP(포트 80) 나 SSH(포트 22) 와 같은 특정 서비스를 대상으로 하는 규칙을 작성할 수 있습니다.
포트는 대략적인 애플리케이션 맥락을 제공합니다. 포트가 모든 것을 말해주지는 않지만, 방어자가 서비스 유형을 구분하기 위해 사용하는 첫 번째 근사치인 경우가 많습니다. 목적지 포트 80 을 기준으로 하는 규칙은 본질적으로 "웹 서비스로 향할 가능성이 있는 트래픽에 관심이 있다"는 의미입니다.
누군가 포트 80 의 웹 서버에 연결을 시도할 때마다 경고를 보내는 규칙을 작성해 보겠습니다.
nano를 사용하여 local.rules 파일을 다시 엽니다:
nano ~/project/local.rules
기존 ICMP 규칙 아래에 새 줄을 추가하고 다음 TCP 규칙을 입력합니다:
alert tcp any any -> any 80 (msg:"HTTP Traffic to Port 80 Detected"; sid:1000002; rev:1;)
이 새로운 규칙의 헤더를 분석해 보겠습니다:
alert tcp: TCP 프로토콜에 대해 경고를 생성합니다.any any: 출발지는 모든 IP 주소와 모든 포트가 될 수 있습니다.->: 트래픽이 목적지를 향해 흐릅니다.any 80: 목적지는 모든 IP 주소가 될 수 있지만, 목적지 포트는 반드시 80 이어야 합니다.
sid를 1000002로 증가시켰다는 점에 유의하세요. 모든 Snort 규칙은 고유한 Snort ID 를 가져야 합니다.
파일을 저장 (Ctrl+O, Enter) 하고 nano를 종료 (Ctrl+X) 합니다.
다시 한번, 오타가 없는지 확인하기 위해 규칙 구문을 테스트하는 것이 좋습니다. Snort 테스트 명령어를 실행합니다:
sudo snort -T -c ~/project/local.rules
출력 하단으로 스크롤하여 Snort 가 구성을 성공적으로 검증했는지 확인합니다. 이제 두 개의 규칙이 성공적으로 로드되었을 것입니다.
규칙 옵션 포함하기 (Msg, SID, Rev)
이 단계에서는 규칙 옵션 (Rule Options) 섹션을 더 깊이 살펴봅니다. 옵션 섹션은 괄호 ()로 묶이며 세미콜론 ;으로 구분된 키워드/값 쌍을 포함합니다.
규칙 옵션은 대략적인 트래픽 범주를 의미 있는 경고로 만들어주는 곳입니다. 명확한 msg는 사람이 이벤트를 이해하는 데 도움을 줍니다. 고유한 sid는 시스템이 어떤 규칙이 실행되었는지 추적할 수 있게 합니다. rev 값은 팀이 시간이 지남에 따라 탐지 콘텐츠를 관리할 수 있게 합니다. 이러한 필드는 단순한 구문을 넘어 운영을 지원합니다.
이미 가장 기본적인 세 가지 옵션을 사용해 보았습니다. 첫 번째는 msg로, 경고 로그에 출력될 메시지이며 설명적이어야 합니다. 두 번째는 sid(Snort ID) 로, 사용자가 작성한 규칙은 1,000,000 보다 큰 SID 를 가져야 합니다. 세 번째는 rev(수정 번호) 로, 규칙을 수정할 때마다 이 번호를 증가시켜 버전을 추적해야 합니다.
이 옵션들을 연습하기 위해 SSH 연결 시도 (포트 22) 를 탐지하는 규칙을 작성해 보겠습니다.
local.rules 파일을 엽니다:
nano ~/project/local.rules
파일의 맨 끝에 다음 규칙을 추가합니다:
alert tcp any any -> any 22 (msg:"SSH Connection Attempt"; sid:1000003; rev:1;)
이 규칙에서는 기본적인 msg를 설정하고 새로운 고유 SID(1000003) 를 할당했습니다.
나중에 이 규칙의 메시지를 더 구체적으로 업데이트하기로 결정했다고 가정해 봅시다. msg를 변경하고 rev를 2로 증가시켜야 합니다. 지금 바로 해보겠습니다. 파일 맨 아래에 방금 작성한 SSH 규칙을 다음과 같이 수정하세요:
alert tcp any any -> any 22 (msg:"Possible SSH Brute Force Attempt"; sid:1000003; rev:2;)
파일을 저장 (Ctrl+O, Enter) 하고 nano를 종료 (Ctrl+X) 합니다.
마지막으로, 세 가지 규칙 모두 완벽하게 형식이 지정되었는지 확인하기 위해 구문 검사를 한 번 더 실행합니다:
sudo snort -T -c ~/project/local.rules
검증 성공 메시지를 확인하세요. 이제 헤더와 옵션을 사용하여 여러 개의 사용자 지정 Snort 규칙을 성공적으로 작성하고 구조화했습니다.
요약
이 실습에서는 사용자 지정 Snort 규칙을 작성하는 데 필요한 기초 기술을 배웠습니다. 규칙의 구조를 탐색하고 이를 규칙 헤더와 규칙 옵션으로 나누어 보았습니다. 일반적인 ICMP 트래픽과 특정 TCP 포트 트래픽을 탐지하는 규칙을 성공적으로 작성했습니다. 또한 msg, sid, rev와 같은 필수 규칙 옵션을 활용하여 경고를 설명적이고 고유하게 식별할 수 있도록 만드는 방법을 배웠습니다. 이러한 기술은 고급 네트워크 침입 탐지 시그니처를 생성하기 위한 토대가 됩니다.



