커피닉스, 시스템 엔지니어의 쉼터
  IPFW How-To 번역 문서 - part 2 (미완성) (글 Daemonize) 작성일 : 2005/01/17 23:51
 
  • 글쓴이 : 좋은진호 ( http://coffeenix.net/ )
  • 조회수 : 5898
     
    ------------------------------------------------------------------------
    출처 : http://www.optro.co.kr/~silpapa/?page=view&ctn=tips&id=222&num=0
    제목: IPFW How-to 번역문서 - part 2 (미완성)
    글쓴이: 뎀오나이즈 [홈페이지]    글쓴시간: 04/02/27 17:40    읽은수: 67
    ------------------------------------------------------------------------

    Stateless 와 Stateful 에 대한 용어가 마땅치 않아서 제가 이해한 데로
    임의로 번역했습니다. 정확한 용어를 알고 계신 분은 좀 가르쳐 주세요.
    그러고 보니 제가 임의로 번역한 말들이 꽤 ㅤㄷㅙㅂ니다.
    고정, 가변 쓰다보니 더 헷갈리네요. 그냥 쓸 걸.. ㅋ..
    나중에 맘에 안들면 수정하겠습니다.

    Stateless - 고정적 Stateful - 가변적 Dynamically - 동적 Statically - 정적

    ------------------------------------------------------------------------------

    5. Logging (로그 남기기)

    5.1. Logging Issues (로깅의 장단점)

    로그의 장점은 뚜렷합니다. 과거에 어떤 연결이 끊겼는지, 그 연결이 어디서 비롯됐는지, 어디로 향하고 있었는지, 대량의 조각난 패킷으로 이루어졌는지 ( 대부분 Dos 공격을 가리킵니다.) 등등의 지식은 사용자에게 어디에서 누구에 의해 언제 연결이 성립되었는지 중요한 정보를 가르쳐 줍니다. 특별히 크래커 등등의 것들을 추적할 경우, 방화벽 기록은 가장 중요한 정보가 됩니다.

    로깅(logging)은 또한 단점도 가지고 있습니다. 주의하지 않는다면 수많은 데이터속에서 사용자 자신이 혼란스러워질 수 있고 (로그를 분석하는 능력 부족으로 인해) 로그 파일로 하드 디스크를 낭비할 수 있게 됩니다. DoS 공격에 의한 하드디스크의 용량 부족은 가장 오래된 수법 중 하나이고, 여전히 신중치 못한 관리자에게 위험합니다. 그것은 잘못 설정된 이메일 서버를 공격하기도 하지만 다양한 로그 데이터를 남기는 어떠한 시스템에게도 위협이 됩니다. 로그가 무한정 커지지 않도록 충분한 하드디스크를 가지고 로그를 신중히 순환시키는 것이 중요합니다.

    한편, 많은 초보자들이, ipfirewall(4)의 로깅 기능을 활성화시켰을 때 터미널이 패킷 동작에 관한 정보로 꽉 차는 일을 경험합니다. 이것은 다음과 같은 것이 조합되어 나타나는 것이죠.

    - 너무나 많은 매치 기록을 로그로 남기기
    - 로그 기록을 콘솔이나 루트 터미널에 출력하는 걸 가능하게 한 것 (좋지 않은 생각입니다.)
    - IPFIREWALL_VERBOSE_LIMIT 에 의해 로그를 조절하지 않은 것

    5.2 System Logging Configuration (시스템 로그 설정)

    5.2.1 Kernel Options (커널 옵션)

    FreeBSD 에서 ipfirewall(4) 로깅을 가능하게 하려면, 적어도 다음의 옵션을 커널에 추가해야 합니다. (커널을 새로 빌드한 후 재부팅 해야 함을 잊지 마세요)

    options IPFIREWALL_VERBOSE

    추가로, 다음의 옵션도 활성화할 수 있습니다.

    options IPFIREWALL_VERBOSE_LIMIT=#

    우리는 이미 방화벽 동작에 관해 설명할 때 이 옵션을 다루었습니다. 이 커널 옵션은  시스템 로그 관리자인 syslogd(8) 에 주어진 룰의 동작과 관련하여 전해줄 연속적 메시지 숫자를 한정합니다. 이 옵션이 커널에 활성화 되어 있다면, 특정 연결에 관한 연속적 메시지의 수는 정해진 수를 넘지 않습니다. 예를 들어, 다음을 가정해 봅시다.

    options IPFIREWALL_VERBOSE_LIMIT=10

    이 옵션으로, 특정 연결에 대해 오로지 10개의 일련의 메시지만이 syslogd(8)에 기록되고, 나머지는 다음과 같은 일반적 메시지로 나타납니다.

    Jan 29 03:26:55 myserver last message repeated 45 times

    이 메시지는 콘솔과 더불어 /var/log/messages 에 일반적으로 기록됩니다. 이러한 설정을 수정하고 싶다면, /etc/syslog.conf 를 수정해야 합니다. syslog.conf(5)는 syslogd(8)가 어떻게 시스템 메시지들을 다룰 것인지에 대해 상당한 정도의 유연성을 제공합니다. IPFIREWALL_VERBOSE_LIMIT 를 어떻게 정할 것인지는 관리자에게 달려 있으나,혼잡한 서버에 10이나 그 이상의 값을 설정하는 것은 콘솔을 상당히 채우게 됩니다. 반면에, 커널 메시지를 콘솔에 내보내지 않고 모든 것을 따로 파일 (기본 설정인 /var/log/messages 가 아닌) 에 기록하고자 하는 것도 가능합니다. 확실히, 이러한 설정하에서 하드가 충분하고 로그 순환으로 인해 간결한 기록만을 남긴다면 IPFIREWALL_VERBOSE_LIMIT 를 정할 필요는 없습니다.


    5.2.2. Configuring syslog(8) for Logging (로그를 위해 syslog 설정하기

    세가지 간편한 절차를 거쳐 사용자는 syslogd(8)이 ipfirewall(4) 메시지를 따로 파일 하나에 기록하게 할 수 있습니다.

    1) 우선 로그 파일을 하나 만들고 로그 디렉토리를 만드십시요. 예를 들어, ipfirewall(4) 로그를 /var/log/ipfw/ 에 남기고자 한다면, 그 디렉토리를 만들고, 그 안에 로그 파일을 생성하십시요. 예를 들어, ipfw.log 라고 해도 됩니다. touch(1) 명령을 사용해 쉽게 이러한 작업을 할 수 있습니다.

    (root@nu)~>#  mkdir /var/log/ipfw && touch  /var/log/ipfw/ipfw.log
    (root@nu)~>#

    다른 유저들이 수정할 수 없도록 그 디렉토리와 파일에 대해 읽기 권한을 주지 마십시요. (make not world-readable)

    2) ipfirwall(4) 메시지를 /var/log/ipfw/ipfw.log 에 기록할 수 있도록, syslog.conf(5) 를 수정하세요. 대부분의 기본 설정에서, 다음과 같은 두 라인을 syslog.conf(5) 의 하단에 추가함으로써 쉽게 할 수 있습니다.

    !ipfw
    *.*   /var/log/ipfw/ipfw.log

    이 파일에서 스페이스키를 사용하지 말고 탭키를 사용해야 한다는 것에 주의하십시요. FreeBSD syslog.conf 에 탭이 필수적이진 않지만, 스페이스를 syslog.conf(5) 에서 받아들이지 않는 다른 유닉스 시스템을 다룸에 있어 이것은 좋은 연습이 될 것입니다. 그래서, /etc/syslog.conf 파일의 상단에 있는 위협성 메시지를 무시할 수 있다 하더라도, 안전한 버릇을 들이기 위해 그러한 규칙을 준수하는게 현명합니다.

    "last messages repeated #" 메시지도 그 파일에 기록됨에 유의하십시요. 그리고 syslog.conf(5) 에 *.err,kern.debug, *.notice 메시지를 기록하도록 한 다른 임의의 파일에도 기록이 남겨집니다. 덧붙여 콘솔도 다음과 같이 정의되어 있다면 메시지를 출력할 것입니다.

    *.err;kern.debug;auth.notice;mail.crit   /dev/console

    console 이 ttyv0 (ALT + F1) 임을 기억하세요. 가상 터미널 (Virtual and pseudo terminals) 에 메시지를 남기는 것은 또 다릅니다. 가상 터미널은 기본 설정의 syslog.conf(5) 파일에 다음 라인들로 컨트롤됩니다.

    *.err   root
    *.notice;news.err   root
    *.alertA   root
    *.emerg    *

    *.err 과 *.notice 를 포함하고 있는 두 라인 모두 룰 매치와 관련된 커널 메시지를 그 권리에 부합하는 유저가 로그인한 터미널에 출력할 것입니다. 이 유저가 root 임을 명심하세요. 성가신 메시지들을 피하는 가장 좋은 방법은 보통 루트로 로그인 하지 않는 것입니다. 역시 루트로 로그인 하여 su 를 통해 다른 유저로 사용하는 방법은 메시지들을 막을 수 없습니다. 위 라인들을 주석처리 하지 않도록 강력히 권장하는 바입니다.
    그러한 메시지들을 루트가 로그인한 터미널에 뿌리는 것은 잘못된 일이 일어날 가능성을 빠르게 인식하는 유용한 방법입니다. 정말로 메시지들을 사용자가 자주 쓰는 UID 로 로그하도록 원할 수도 있습니다. 그렇담 대신 룰을 적절히 세워서, 정말로 중요한 룰 매치만 기록되고 루트 말고 당신의 개인 계정으로 로그인하십시요. 루트로 로그인한 여분의 가상 터미널을 유지하고 주기적으로 체크하십시요.

    종합하면, syslog.conf(5) 설정과 터미널 출력을 다룰 때에는 (when dealing with syslogconf and terminal notification) :

    - 후에 쉬운 검토를 위해 룰 매치 메시지를 다른 파일에 기록하기 위해 위에서 언급한 두 라인을 syslog.conf(5) 에 추가하십시요.
    - 루트 터미널 메시지에 대해 걱정하지 마시고 당신의 일상적 행동을 root 로 하지 마세요. 이것은 모든 보안 어드바이스 (advice) 에 공통된 사항입니다. 대신, 루트로 로그인한 여분의 터미널을 만들고 그것을 주기적으로 체크하십시요.

    3) syslogd(8) 프로세스에 Hangup 시그널을 보내십시요. 가장 간편한 방법은 다음 명령입니다.

    (root@nu)~># killall -HUP syslogd
    (root@nu)~>#

    5.2.3. Configuring newsyslog(8) for Log Rotation (로그 순환을 위한 newsyslog 설정)

    이제 ipfirewall(4) 로그 기능이 활성화 되었으므로, 로그 순환을 위해 newsyslog.conf(5) 를 설정해야 합니다. 혹은 다른 방법으로, 다른 로그 순환 메커니즘을 사용하세요. 모든 가능한 설정 옵션에 대한 설명은newsyslog.conf(5) 매뉴얼 페이지를 참고하시면 됩니다. 하지만, 다음의 엔트리가 대부분의 경우엔 충분할 것입니다. ( 이 예에서, 예로든 로그 파일명은 전에 말했던 이름을 사용합니다.)

    /var/log/ipfw/ipfw.log   600 10 * $W0D2 Z

    이 엔트리는 newsyslog.conf(5) 파일 하단에 덧붙입니다. 처음 부분은 말 그대로 입니다. 두번째 부분은 순환된 파일 (rotated file) 의 권한을 설정한 부분입니다. 세번째는 가장 오래된 파일이 지워질 때까지 순환을 유지할 파일 (keep rotating files) 의 개수입니다. 네번째는 특정한 숫자 대신 와일드 카드인데 이것은 파일들을 순환하기위한 신호로 쓰여질 것입니다. 다섯번째 부분은 로그들을 순환할 시간대 이고 여섯번째 부분은 특별한 옵션입니다. 벌써 추측하신 분들도 있겠지만, 로그 순환은 두 가지 기준인 크기 (size) 와 시간대 (time/date) 중 하나에 의해 이루어집니다. 우리는 시간대 대신, 파일이 특정한 크기에 다다르면 로그를 순환시켜주는 방법을 사용할 수도 있습니다. 위 엔트리에서는 우리는 시간대 (time/date) 방법을 사용했습니다. 로그를 순환함에 있어, 매 일요일 아침 2 AM 에 로그를 순환하도록 하고, (Z 옵션에 의해) gzip(1) 으로 압축하도록 했습니다. 이 때 오로지 10개의 압축 파일만 허락 하도록 했습니다.
    (10 주 분량). 만약 이것보다 긴 기간동안 로그를 유지하고자 한다면, 세번째 인자인 10 만 원하는 것으로 바꿔주면 됩니다.

    일단 newsyslog.conf(5) 파일이 설정되었다면, 로그 순환 (log rotation) 은 모두 된 겁니다. newsyslog(8)은 cron(8)에 의해 구동되는 프로그램이기에, syslogd(8)에 필요한 Hangup 시그널을 보낼 데몬이 필요없습니다. 로그 순환을 하기 위해 다른 방법들이 있습니다. 사용자가 자신만의 로그 순환 스크립트를 작성하여 구동시킬 수 있고, 혹은 좋다고 생각하는 친구의 것을 사용해도 됩니다. 어쨋든간에, 잠재적으로 커다랗게 될 수 있는 로그 파일들에 관해서, 압축을 하고 그들의 크기를 조절할 수 있는 방법이 있다는 것을 아는 것이 중요합니다.

    5.3. Rule Logging Configuration

    일단 시스템이 ipfirewall(4) 로깅을 다룰 수 있게 완벽히 설정되었다면, 어떠한 룰을 언제 매치되었을 때 로그로 남겨야 하는가를 명확히 해야 합니다. 주어진 룰에 대해 로깅을 가능케하기 위해 룰 정보와 연관되어 사용되는 인자들 (parameters) 이 간단히 두개가 있습니다. 그것들은 :

    "log" - 이 키워드를 포함하는 룰이 패킷에 의해 매치가 되면 기록합니다. 이 키워드는 반드시 "action" 뒤에 와야 합니다. 다음과 같은 광범위한 (wide sweeping) 룰에 이 키워드를 사용하지 않도록 주의하셔야 합니다.

    add 0500 allow log all from any to any

    이 룰이전에 광범위한 필터링이 없다면, 대부분의 트래픽이 이 룰에 매치되어, 사용자의 로그 파일은 매우 빠르게 급격히 커질 것입니다. 반면에 다음과 같은 광범위하게 거부하는 (sweeping deny rule) 룰에 대해 로그를 활성화 시키는 것은 상당히 안전합니다.

    add 65000 deny log all from any to any

    이 룰이 보다 안전한 이유는 (여전히 위험할 수는 있지만), 거의 끝에 있는 룰로써 (65000 번을 500 번과 비교하자면) 닫힌 방화벽 정책 (closed firewall policy) 을 취하는 ruleset 에 있어서 중요한 트래픽을 허락하는 많은 룰들이 일반적으로 마지막의 거부 룰전에 있기 때문입니다. 이 중요한 트래픽은 특별한 경우을 제외하곤, 총 트래픽의 상당부분을 차지하는 것입니다. 어떤 룰이 기록될 것인지, 그렇지 않아야 할 것인지에 대해 주의해야 합니다.

    "logamount [number]" - "log" 인자 뒤에 오는 이 인자 (parameter) 는 로깅이 멈추기 전, 한 개의 룰이 얼마나 많은 매치를 가능하게 하는 가에 대한 최대 한계를 지정합니다. 이것은 관리자에게 로깅에 대한 추가적인 컨트롤을 가능하게 합니다. 만약, 예를 들어, 주어진 룰에 대해 10000 매치를
    가능하게 하고 하루에 한 번씩 카운터를 리셋시킨다면, 누군가가 그 서버에 플러딩 (try to flood the server) 을 시도할 때 로그 파일이 잠재적으로 커질 가능성을 완화하고, 주어진 룰에 의해 블록할 수 있게 됩니다.
    10000 매치 이후엔, 그 룰에 대한 로깅은 멈추고, flooder 의 공격은 로그 파일을 크게 하지 않을 것입니다. 대신, 이 인자를 사용하지 않고 *모든 것*을 로그하고자 할 수도 있습니다. FreeBSD 4.x, 3.4+, 그리고 2.2.x 에서는 이것이 허락됩니다만, FreeBSD 3.x 의 초기 버전에서 이 키워드를 사용하지 않는다면, 기본 "logamount" 는 10으로 정해집니다.

    룰이 기록될 때, 다음 정보들이 저장됩니다.

    - 시간과 날짜 (Date & Time)
    - 룰 번호 (Rule Number)
    - 동작 (Action)
    - 전송지와 목적지 IP 주소 (Source & Destination IP addresses)
    - 전송지와 목적지 포트 번호 (Source & Destination Port numbers)
    - 흐름의 방향 (Direction flow)
    - 이것과 관련된 장치 (Device over which this occured)

    예를 들어, 방화벽 로그는 다음과 같을 것입니다.

    Jun 12 13:55:59 mybox1 /kernel:  ipfw: 65000 Deny TCP
    172.16.0.1:62307 192.168.0.1:23 in via xl0

    6. Introduction to Stateless and Stateful Filtering (고정적, 가변적 필터링에 대한 소개)

    가변적 그리고 고정적 필터링 (Stateful and Stateless filtering) 은ipfilter 와 ipfirewall(4)
    지지자들 사이에 벌어지는 논쟁에서 흔히 볼 수 있는 용어들입니다. 고정 필터링 (Stateless filtering) 은 각각의 패킷을 주어진 장치를 통과하는 다른 패킷들과의 연관성을 가지지 않은 개별적인 것으로 다룹니다. 이러한 타입의 필터링은 사용하기가 쉽고 다음에 효과적으로 사용할 수 있습니다.

    - 나쁜 (조각난) 패킷을 필터하기 (filter corrupt (fragmented) packets)
    - 특별한 프로토콜 패킷을 필터하기 (filter particular protocol packets (icmp,udp,igmp, etc))
    - 호스트 기반 필터링하기, 패킷이 어디로 향하는지 어디에서 왔는지에 따라 필터링 하기 (filtering according to where a packet is destined, or where it came from)

    가변 필터링 (Stateful filtering) 은 사용상 좀 더 복잡합니다. 그것은 트래픽을 개별적이고 독립적인 패킷들의 조합으로 다루지 않고, 연결들을 구성하는 (composed of connexions) 것들로 다룹니다. 임의의 프로토콜을 통한 모든 통신은 어떠한 순서로 패킷이 소켓에서 읽혀지는가를 지시하는 시퀀스
    넘버를 사용합니다. (sequence numbers to indicate in which order packets should be read on a socket(2))

    가변적 방화벽은 (Stateful firewall) 이러한 시퀀스 넘버를 인지합니다. 연결 지향적인 TCP 같은 프로토콜은 (Connexion oriented protocols such as TCP) 연결 초기화 (Connexion initiation, SYN)와 종료 (termination FIN) 를 가리키는 특별한 패킷을 가지고 있는데, 가변 방화벽은 이것들 역시 인지합니다. 간단히 말해서,

    - 연결이 어떠한 상태인지 알고 (know what state a connexion is in)
    - 연결이 올바른 절차를 거쳐 성립되었는지, 혹은 규칙을 깨고 있는지 (connexion is following valid procedure, or is breaking the rules) 를 구별하기

    를 수행하고 이러한 조건들에 따라 패킷 필터를 하는 것입니다.

    가변 방화벽은 지금 존재하는 연결에 대해 동적인 룰 (dynamic rules)을 생성시키고, 연결이 종료되었을 경우, 이러한 규칙을 제거합니다. 이것들 모두 방화벽에 의하여 네트웍 트래픽의 보다 고수준의 활동을 좀 더 지능적으로 인식하는 것을 가능케 해줍니다. (allow for a more intelligent
    awarenewss of the higher level activity of network traffic by the firewall)
    단점으로는 가변 방화벽은 각각의 패킷을 개별적으로 다룰 수 없습니다. 왜냐하면 특별한 동적인 룰 (special dynamic rules) 은 연결의 모든 범위에 걸쳐 패킷들이 올바로 동작하는가 하는 문제를 제외하고 그러한 룰에 해당하는 패킷들에 대한 검사를 배제한 채 모든 연결을 허락하도록 작성되기 때문입니다. 따라서, 양쪽의 이점을 모두 취하려면 방화벽 설정에서 고정 룰과 가변 룰을 혼합하는 것이 현명한 방법입니다.

    지금까지 보아온 거의 모든 예시 룰은 고정 룰이었습니다. (stateless) 예외라면, TCP 연결의 상태를 검사하게 하는 "tcpflags","setup", 그리고 "established" 옵션과 관련된 룰뿐이었습니다.
    이것들의 조합으로 간단히 가변 ruleset 의 예를 들어보았는데요. 이러한 옵션들로 원시적인 가변 ruleset 을 작성하는 것은 ipfirewall(4) 에서 예전부터 가능했던 기능입니다. 하지만, 매우 제한적인 가변 필터링 능력(statefule capabilities) 때문에, ipfirewall(4) 은 오랜기간 고정 방화벽 (stateless firewall) 로, IPFilter 는 대안적인 가변 방화벽으로 취급받아왔습니다. FreeBSD 4.0 에 들어와서 ipfirewall(4) 은 보다 광범위한 가변 방화벽 기능을 갖추게 되었고 더욱더 발전하고 있습니다.

    6.1. Basic Stateful Configuration (가변 방화벽의 기본 설정)

    처음 예는 좀 더 오래되고, 기본적인 ipfirewall(4) 의 가변 방화벽 설정 기능을 사용하겠습니다. 많은 분들이, 가변 방화벽의 가장 기본적 기능 (the most basic stateful functionality)을 사용하여 미리 정의된
    ruleset 이 존재하는 ~rc.firewall 파일의 예를 많이 따라하면서 TCP 연결을 컨트롤하는 데 있어 “setup” 이나 “established” 와 같은 키워드를 과도하게 사용합니다. 사실 가변적인 방화벽 설정에 있어 이렇게 할 수도 있겠지만, 적어도 중요하게 생각되는 특성에 대해 한계를 보이게 됩니다.
    우리 예에서는, ssh 연결만을 허용하는 단순한 가변 방화벽 ruleset (stateful firewall ruleset) 을 만들어 볼 것입니다.

    add 1000 allow tcp from any to any established
    add 2000 allow tcp from any to any 22 in setup

    닫힌 방화벽 정책으로 가정하고 (Presuming a closed filrewall policy) (즉 firewall_type 이 “OPEN”으로 정해지지 않고 커널이IPFIREWALL_DEFAULT_TO_ACCEPT 설정을 가지지 않을 때) 위 두라인은 우선 모든 확립된 TCP 연결 (established TCP connexion) 을 허용합니다. 특별히 확립된 TCP 연결을 구성하는 모든 패킷은 1000번 룰과 매치되고 ruleset 탐색은 멈추게 됩니다. 반면에 임의의 패킷이 확립된 TCP 연결의 부분이 아닐 때는 1000번 룰과는 일치하지 않게 되고, ruleset 탐색은 2000번으로 계속 될 것입니다. 거기에서 만약 패킷이 22 번 포트 (ssh 포트)로 향하는 SYN TCP 패킷이라면, 룰과 패킷은 일치되어 통과를 허용합니다. 이런 방법으로, 위 룰들은 전체적으로 TCP 연결을 인지하되 각각의 개별적 패킷을 인식하지는 않음으로써 가변적으로 됩니다. (stateful) 예를 들어 다음과 같이 고정 룰 (stateless rules) 을 사용하여 같은 효과를 낼 수도 있겠죠.

    Add 1000 allow tcp from any to any out
    Add 2000 allow tcp from any to any 22 in

    위 예에서는, 임의의 장소에서 임의로 나가는 (out from any to anywhere) 모든 패킷은 방화벽을 통과하도록 허용되며, 전송지와 목적지에 상관없이 22번 포트를 향해 유입되는 모든 패킷도 통과됩니다. 이 경우에 있어, 룰들은 TCP 연결을 인식하지 않습니다. 대신에 그것이 무엇이든 간에 모든 TCP 패킷의 외부 전송을 허락하고, 22 번 포트로 향해 들어오는 모든 패킷을 역시 그것이 무엇이든간에 통과시킵니다.

    이것이 “setup” 과 “established” 플래그를 사용하는 ipfirewall(4) 에 있어 가변 필터링 (stateful behaviour) 의 핵심적 요소입니다 : 특정한 주소:포트를 향하는 TCP 연결 요구 (TCP setup request)를 허용하고 이렇게 확립된 연결을 허용하는 것입니다.

    네트웍 172.16.0.0/27 에 ssh, email, FTP, 그리고 DNS 쿼리 (query) 가 있을 때 이를 다루는 더욱 화된 예를 살펴봅시다.

    add 1000 allow tcp from any to any established
    add 2000 allow tcp from any to 172.16.0.0/27 21,22,25 setup
    add 3000 allow udp from  172.16.0.0/27 to any 53
    add 3100 allow udp from any 53 to  172.16.0.0/27

    이 예에서, 172.16.0.0 네트웍을 향하는 21, 22, 25 – (각각 FTP, ssh, email 에 해당합니다.) 번 포트에 해당하는 TCP 연결 초기화 (setup of TCP connexions)는 허용됩니다. 그 후 모든 확립된 TCP 연결의 패킷 통과가 허용됩니다. 3000, 3100번 룰은 다른 호스트의 53 번 포트를 향한 UDP 패킷의 통과를 허용하고 다른 호스트의 53 번 포트에서 전송된 UDP 패킷의 방화벽 통과를 허용하게 됩니다. 53번 포트는 DNS 서버가 사용하는 포트입니다. 1000번 룰은 “from any to any” 를 포함해야 하는데 왜냐하면 확립된 TCP 연결의 패킷들은 양방향 모두에 걸쳐 서로 발생되고 도달해야 하기 때문입니다.

    만약 완전히 고정적인 방화벽 설정 (completely stateless)으로 비슷한 ruleset 을 작성하고자 한다면 1024에서 65000 에 해당하는 포트들을 FTP 연결을 위해 열어두어야 합니다. FTP 는 무작위로 넓은 범위에 걸쳐 미리 약속되지 않은 포트들을 사용하기 때문에 상당히 정돈되지 않은 포로토콜 입니다. (wild protocol as it randomly binds to non-reserved ports across a wide range) FTP 를 사용가능 하도록 방화벽에 허용하는 것은 항상 어렵습니다 : 단지 가변 방화벽만이 넓은 범위의 포트를 열어주지 않고도 그것에 대해 완벽한 지원을 합니다. 고정 방화벽에서 포트를 열어놓게 되었을 때의 확실한 단점은 누구라도 그 범위안의 포트로 접속을 시도할 수 있다는 점입니다. 우리의 룰에서는 단지 2000번 룰을 통해 초기화된 TCP 연결만이 1000번의 확립된 연결 통과룰을 통해서 허용됩니다. 이 때 FTP 를 위해 필요한 넓은 범위의 포트를 향하여 전송되는 무작위이고 컨트롤되지 않은 연결 (random and uncontrolled connexion) 을 제한할 수 있게 됩니다.

    6.2 Advanced Statefuel Configuration (심화된 가변 방화벽 설정)

    전에 언급된 바와 같이, “setup” 과 “established” 로 이루어진 가변 방화벽 설정은 매우 제한적입니다. 오로지 TCP 연결에 대해서만 가변적 컨트롤 (stateful control) 을 제공한다는 장점 이외에 이러한 가변적 컨트롤은 기껏해봐야 단순하다는 점을 들 수 있습니다. FreeBSD 4.0 에서부터 시작된 ipfirewall(4) 의 가변 방화벽 기능 (stateful firewall capabilities) 은 대단히 향상되었습니다. 지금은 ipfirewall(4)이 동적 룰을 통하여 (with dynamic rules) TCP, UDP, ICMP 그리고 여러 타입의 패킷들을 가변적으로 다루게 (statefule handling) 설정될 수 있습니다.

    동적 룰 (Dynamic rules)은 FreeBSD 4.0 의 ipfirewall(4)에 새로이 추가된 또 다른 기능입니다. 동적 룰은 이름이 암시하듯 개별적 연결에 대하여 동적으로 발생됩니다. 각자의 동적 룰은 일정한 시간이 경과 할 때 까지 사용되지 않는다면 사라집니다. TCP 연결에 대한 시간 제한은 여러 sysctl(8) 변수에 의해 컨트롤됩니다. 이것은 연결 초기화뿐 아니라, 연결 종료까지도 제어할 수 있게 해주는데 즉, 다른 방식으로 이야기하자면, 특정한 연결의 시작과 끝을 인식하는 ruleset 이 작성될 수 있을 뿐아니라 그것에 따라서 자신을 적용시킬 수 있음을 의미합니다.

    이러한 심화된 가변 방화벽 작용 (advanced stateful behaviour)을 컨트롤하는데에는 하나의 옵션과 하나의 명령이 쓰입니다.

    “set-state” – 이 옵션을 가진 모든 룰은 어떤 패킷에 의해 자신과 일치될 때 마다 동적인 룰을 발생시킵니다.

    “check-state” – 이 명령은 방화벽이 우선 동적 룰을 검색하도록 허용합니다. 만약 이 명령을 가진 룰이 ruleset 의 모든 룰에서 생략된다면, 그 때는 동적 룰이 “set-state” 옵션이 처음 나타났을 때 체크됩니다. 이 명령을 가진 룰과 일치하면 탐색은 멈추고, 그렇지 않다면 계속 될 것입니다.

    우리가 앞서 ssh 연결만을 허용하도록 디자인된 예를, 심화된 가변ipfirewall(4) 기능만을 사용해 구현해 봅시다.

    Add 1000 check-state
    Add 2000 allow tcp from any to any 22 in setup keep-state

    이 룰들은 당신의 방화벽 정책이 닫힌 것 (즉 기본설정으로 모든 것을 막도록 된 것) 임을 가정하고 있음을 명심하십시오. 위 룰에서, 처음 룰은 ipfirewall(4) 에게 동적 룰을 체크하도록 요구합니다. 방화벽을 통과하는 바로 그 때의 패킷은 어떠한 이미 확립된 연결에 속하지 않으므로, 즉 말하자면, 그들이 어떠한 동적 룰에도 매치되지 않으므로, 2000번 룰에 대한 탐색으로 넘어갑니다. 거기에서는 만약 패킷이 TCP SYN 패킷이라면 “keep-state” 가 동적 룰을 만들도록 되어있습니다. 그 연결과 관련된 뒤따르는 연속적인 패킷들은 동적 룰을 만날 것인데, 그것은 1000번 룰에 의해 만들어진 것입니다. 모든 다른 패킷들은 기본 거부 룰에 의해 거부될 것입니다.

    우리가 이미 이러한 효과를 거두기 위해 오래된 가변 혹은 고정 방화벽 방법을 통해 구현해 보았지만, 이 “set-state” 옵션과 “check-state” 명령을 통한 새로운 접근법은 다른 접근법보다 명확한 장점이 있습니다. 오래된 가변 방화벽 기법에서 “established” 옵션은 확립된 연결로부터 비롯되는 모든 TCP 패킷과, 그것이 spoofing 되었든, 지금 존재하는 적법한 TCP 연결에서 발생되지 않은 것일지라 하더라도, 매치됩니다. 새로운 접근법은 그러한 경우가 발생하는 것을 배제합니다. 개개의 동적인 룰은 두 호스트와 그들 각각 포트들 사이의 특정한 연결에만 관여합니다.
    Spoofing 된 TCP 패킷은 전송지와 목적지 IP 주소를 속일 수 있지만, 정말 운이 좋지 않다면 현재의 적절한 TCP 연결이 유지되고 있는 정확한 포트까지 속일 수는 없기 때문에, 따라서 “check-state” 명령을 가진 1000번 룰에서 매치에 실패할 것이고, 그 뒤 2000번 룰에서 그 spoofing 된 패킷이 TCP SYN 패킷이 아니라면 역시 매치에 실패합니다. 결국 마지막의 거부 룰에 의해 패킷은 버려지게 됩니다.

    요약하자면, 패킷이 동적인 룰과 매치되기 위해 검사받는 항목은 다음과 같습니다.

    - 프로토콜
    - 전송지 IP 와 포트
    - 목적지 IP 와 포트
    - 룰의 지속 시간이 다 돼었는가

    전에 말했던 바와 같이 동적인 룰은 일정 시간이 경과할 동안 특별히 사용되지 않으면 버려집니다. 동적 룰이 어떻게 쓰여지는가에 따라, 룰의 수명 (time out) 에 특별한 기간이 정해집니다. 여러가지 타입의 룰에 대한 만기 (time out) 시점은 sysctl 변수를 출력해 봄으로써 알 수 있습니다; 더욱이 사용자는 이 값을 바꿀 수 있습니다. 여기 sysctl 변수들과 그들의 기본 설정값을 나열해 보겠습니다.

    (root@nu)~># sysctl -a | grep  'dyn.*lifetime'
    net.inet.ip.fw.dyn_ack_lifetime:  300
    net.inet.ip.fw.dyn_syn_lifetime: 20
    net.inet.ip.fw.dyn_fin_lifetime:  20
    net.inet.ip.fw.dyn_rst_lifetime: 5
    net.inet.ip.fw.dyn_short_lifetime:  5
    (root@nu)~>#

    처음 sysctl 변수는 TCP ACK 패킷에 의해 사용된 동적 룰이 즉각 사용될 수 있는 시간이 300 초임을 나타냅니다. 두번째 변수는 TCP SYN 패킷에 의해 사용된 동적 룰이 20 초 이내에 사용되어야 함을 나타냅니다. 세번째 변수는 TCP FIN 패킷에 의해 사용된 동적 룰이 역시 20 초 동안 사용될 수 있음을 나타냅니다. 마지막 두 가지의 변수는 TCP RST 패킷과 임의의 다른 패킷들 (UDP, ICMP, 기타 등등)에 의해 사용된 동적 룰이 5초의 시간 여유를 가지고 있음을 나타냅니다.


    커피닉스, 시스템 엔지니어의 쉼터 / URL : http://coffeenix.net/board_view.php?bd_code=695