[IT·HW.SW사용법]/H.W·S.W기술팁

Linux IPCHAINS-HOWTO

기쁨조미료25 2008. 11. 2. 16:06

 Linux IPCHAINS-HOWTO
  Paul Russell, Paul.Russell@rustcorp.com.au
  v0.6, Sun May 17 14:29:26 CST 1998
  번역: 이 만용, geoman@nownuri.net


  이 문서는 리눅스를 위해 개선된 일반 IP 방화벽 사슬 소프트웨어를 어떻게
  구하고 설치하고 설정하는지 그리고 이를 사용할 때 알아두어야 할 사항들에
  대하여 자세히 기술하고자 한다.

  <역자의 글>

  리눅스에서 IP 방화벽 코드와 ipfwadm 명령은 매우 흥미롭고 귀중한 자원이다.
  IP 패킷 수준에서의 걸러내기 기능의 유용성을 구태여 말할 필요가 없으리라
  본다.  특히 매스커레이드 기능은 정말 돋보이는 기능 중 하나이다.
  개발 버전 2.1.102 부터 공식적으로 들어와 있는 ``개선된'' IP 방화벽 코드와
  훨씬 더 나아진 관리도구 ipchains 는 리눅스 방화벽 기능을 애호하는 사람들이
  꼭 익혀야 할 내용이라 생각한다.

  또 하나의 획기적인 작품인 커널 2.2 를 기다리며 변화에 적응할 수 있도록
  돕기 위해 번역을 하였다.

  용어 선택이 적절치 못한 것에 대한 의견을 듣고 게속적으로 수정해 나갈
  생각이다.

  ______________________________________________________________________

  목차

  1. 소개

     1.1 무엇?
     1.2 왜?
     1.3 어떻게?
     1.4 어디서?

  2. 패킷 필터링 기본기

     2.1 무엇?
     2.2 왜?
     2.3 어떻게?
        2.3.1 패킷 필터링 기능을 갖춘 커널
        2.3.2 ``ipchains''

  3. 일반적인 IP 방화벽 사슬

     3.1 어떻게 패킷이 필터를 통과하는가?
        3.1.1 ipchains 사용하기
        3.1.2 단일 규칙 상의 동작
        3.1.3 필터 규칙 명시하기
           3.1.3.1 수신지, 목적지 IP 주소 명시하기
           3.1.3.2 역방향 명시하기
           3.1.3.3 프로토콜 명시하기
              3.1.3.3.1 UDP, TCP 포트 명시하기
              3.1.3.3.2 ICMP 유형과 코드 명시하기
           3.1.3.4 인터페이스 명시하기
           3.1.3.5 TCP SYN 패킷만 명시하기
           3.1.3.6 조각(Fragments) 처리
        3.1.4 필터링의 주변 효과
           3.1.4.1 목표 명시하기
           3.1.4.2 패킷 기록하기
           3.1.4.3 서비스 유형 처리하기
           3.1.4.4 패킷 표시하기
           3.1.4.5 전체 사슬에 대한 동작
           3.1.4.6 새로운 사슬 만들기
           3.1.4.7 사슬 지우기
           3.1.4.8 사슬 비우기
           3.1.4.9 사슬 내용 보기
           3.1.4.10 카운터 값을 0 으로 돌려놓기
           3.1.4.11 정책 정하기
        3.1.5 Operations on Masquerading
        3.1.6 Checking a Packet
        3.1.7 Multiple Rules at once and Watching What Happens
     3.2 쓸만한 예제
        3.2.1 ``ipchains-save'' 사용하기
        3.2.2 ``ipchains-restore'' 사용하기

  4. 그 밖의 것들

     4.1 어떻게 방화벽 규칙을 체계화할 수 있는가?
     4.2 어떤 것은 걸러내지 말아야 하는가?
        4.2.1 ICMP 패킷
        4.2.2 DNS 답신
        4.2.3 FTP 의 악몽
     4.3 죽음의 핑 걸러내기
     4.4 티어드롭과 봉크 걸러내기
     4.5 조각 폭탄 걸러내기
     4.6 방화벽 규칙 바꾸기
     4.7 더 높은 수준의 프로젝트
     4.8 앞으로 개선할 점

  5. 별첨 - ipchains 와 ipfwadm 간의 차이점

     5.1 간단한 참조 도표
     5.2 ipfwadm 명령 번역의 예

  6. 별첨 - `ipfwadm-wrapper' 스크립트 사용하기

  7. 별첨 - 감사의 글



  ______________________________________________________________________


  이 글은 리눅스 IPCHAINS-HOWTO 이다.  리눅스 NET-3-HOWTO, IP 매스커레이딩
  하우투, PPP 하우투, 이더넷 하우투 등도 읽어 볼 만한 가치가 있는 글이다.
  (또한 alt.fan.bigfoot FAQ도 괜찮다)


  패킷 필터링에 대하여 이미 알고 있다면 ``왜?'' 섹션과 ``어떻게?'' 섹션을
  읽고 ``일반적인 IP 방화벽 사슬'' 섹션을 읽어나가기 바란다.


  ipfwadm로부터 변환을 하고 있다면 ``소개'' 섹션, ``어떻게?'' 섹션,
  그리고 별첨 ``ipchains와 ipfwadm 간의 차이점'', ``ipfwadm-wrapper 스크
  립트 사용하기''를 읽어나가면 된다.


  리눅스 ipchains 는 리눅스 IPv4 방화벽 코드(주로 BSD로부터 따온 것이다.)를
  다시 만든 것이며 BSD의 ipfw 를 다시 만든 ipfwadm 을 다시 작성한 것이다.


  1.2.  왜?

  현재 사용 중인 리눅스 방화벽 코드는 패킷 조작을 다루지 못하며 32 비트
  카운터(인텔의 경우)를 사용하고 있고 TCP, UDP, ICMP 이외의 프로토콜을
  명시할 수 없다.  쉽게 많은 내용에 변화를 가할 수 없고 역규칙을 명시할
  수 없으며 몇몇 결함을 가지고 있다.  그리고 관리하기도 힘들다.
  (때문에 에러를 유발하기 쉽다)


  1.3.  어떻게?

  현재 이 코드는 커널 2.1.102 부터 공식적으로 포함되어 있다.
  2.0 커널의 경우에는 웹 페이지로부터 커널 패치를 다운로드받아야 한다.


  1.4.  어디서?

  리눅스 일반 IP 방화벽 사슬에대한 공식 웹 페이지는 다음과 같다.
  <http://www.adelaide.net.au/~rustcorp/ipfwchains>


  만약 커다란 익명 FTP 서버를 사용할 수 있다면 FTP 에 소프트웨어를 두었겠지만
  그렇지 못하기 때문에 HTTP 전송으로 제공하고 있다.


  버그 보고, 토론, 개발 그리고 사용에 관한 문제를 다루는 메일링 리스트가
  있다.  wantree.com.au의 ipchains-request로 subscribe 라는 단어가 포함된
  메시지를 보내면 가입된다.  리스트에 메일을 보낼 때는 `ipchains-request'가
  아니라 `ipchains' 앞으로 메일을 보내야 한다.


  2.  패킷 필터링 기본기

  2.1.  무엇?

  네트웍을 통하는 모든 것은 패킷의 형태를 띤다.  예를 들어 지금 이 패키지
  (약 50k)를 받는데는 하나의 크기가 1460 바이트인 패킷 약 36 개 정도를
  발생시킨다. ( 값은 그냥 아무렇게나 잡았다 )


  각 패킷의 앞 부분에는 패킷이 어디로 향하고 있는지, 어디서 왔는지, 어떤
  종류의 패킷인지 그리고 그 밖의 관리 상 필요한 세부 사항이 적혀있다.
  이 부분을 패킷의 `헤더(header)'라 부른다.  나머지 부분에는 전송하고자 하는
  실제 자료가 들어있으며 `몸체(body)'라 부른다.


  웹, 메일, 원격 로그인에서 사용되는 TCP 와 같은 프로토콜은 `접속'이라는
  개념을 사용한다.  보내고자 하는 실제 자료를 포함한 패킷을 보내기에 앞서
  다양한 설정 패킷(특별한 헤더를 가지고 있다)이 교환되는데 그 내용은
  `접속을 원한다', `승인한다', `고맙다'와 같은 메시지라고 보면 된다.
  그리고 나서야 보통의 패킷이 교환된다.


  패킷 필터란 지나가는 패킷의 헤더를 보고 패킷의 운명을 결정짓는 소프트웨어
  이다.  패킷을 무시(deny)할 수 있고(마치 패킷을 안받은 것처럼 버리는 행위)
  패킷이 지나가도록 허용하거나 패킷을 거절(reject)할 수 있다.(무시와 같지만
  패킷을 보낸 곳에 거절함을 통보해준다.)


  리눅스에서는 패킷 필터링 기능이 커널 안에 들어있고 패킷을 처리함에 있어
  고려해야 할 몇 가지 사항들이 있지만 헤더를 살펴보고 패킷의 운명을 결정한다는
  일반적인 원칙은 똑같다.


  2.2.  왜?

  제어.  보안.  감시.



     제어(Control):
내부 네트웍을 다른 네트웍(말하자면 인터넷)에 연결해 주는 용도로
리눅스 박스를 사용하고 있다면 특정 형태의 네트웍 자료를 허용하거나
불허할 수 있다.  예를 들어 패킷 헤더에는 목적지 주소가 들어있기
때문에 특정 외부 네트웍으로 패킷이 나가는 것을 막을 수 있다.
다른 예를 들어보자.  나는 Dilbert 아카이브에 접근하기 위해 네스케이프를
사용한다.  페이지에는 doubleclick.net 의 광고들이 있어 네스케이프가
광고들을 받아대느라 나의 귀중한 시간을 소모하고 있다.
패킷 필터로 하여금 doubleclick.net 으로부터 오는 모든 패킷을 막게
하여 문제를 해결하였다.(물론 이 문제에 대해서는 보다 좋은 방법이 있다)


     보안(Security):
리눅스 박스가 무법천지의 인터넷과 깔끔하고 잘 정돈된 여러분만의
네트웍 사이에 놓인 유일한 컴퓨터인 경우, 여러분에게 방문할 수 있는
권한을 제한하는 방법을 익혀두는 것이 좋다.  예를 들어 여러분의 네트
웍으로부터 밖으로 나가는 것은 별 문제가 아니지만 `죽음의 핑' 같은 것이
악의를 품은 외부인으로부터 오는 것에 대하여 걱정하고 있을 지 모른다.
또는 계정과 패스워드를 제대로 갖고 있다 하더라도 외부에서는 리눅스
박스로 텔넷하여 들어오는 것을 바라지 않을 수 있다.  여러분은 대부분의
사람들과 마찬가지로 인터넷을 구경하는 방문객이 되고 싶을 뿐, 방문객을
받아야 하는 서버가 되고 싶지는 않다고 생각할 지 모른다.
이 때는 간단히 접속에 사용되는 패킷이 들어오는 것만 막아버리면 그만
이다.


     감시(Watchfulness):
몇몇 잘못 설정된 내부 네트웍 상의 머신들이 외부로 패킷을 유출하는
것도 가능하다.  이 때는 패킷 필터로 하여금 비정상적인 일이 벌어지는
것에 대하여 통보하도록 할 수 있다.  이에 대한 조치를 취할 수도 있고
또는 그냥 궁금해서 해 볼 수도 있다.


  2.3.  어떻게?

  2.3.1.  패킷 필터링 기능을 갖춘 커널

  커널 안에 새로운 일반 IP 방화벽 사슬(Generic IP Firewall Chain) 기능을
  갖춰야 한다.  지금 현재 작동 중인 커널이 이 기능을 갖추고 있는지 알아보
  려면 `/proc/net/ip_fwchains' 파일이 있는지 확인하라.  있다면 이미 커널
  안에 기능이 포함되어 있는 것이다.


  그렇지 않다면 일반 IP 방화벽 사슬 기능을 갖도록 커널을 컴파일해야 한다.
  커널을 다운로드받고 위에서 언급한 웹 페이지로부터 가져온 패치를 적용하고
  다음과 같은 설정을 해주어야 한다.  커널 컴파일에 대하여 잘 모른다면
  커널 하우투 문서를 읽어보기 바란다.


  필요한 설정 옵션은 다음과 같다:


  ______________________________________________________________________
          CONFIG_EXPERIMENTAL=y
          CONFIG_FIREWALL=y
          CONFIG_IP_FIREWALL=y
          CONFIG_IP_FIREWALL_CHAINS=y
  ______________________________________________________________________




  `ipchains'라는 도구를 사용하여 커널과 대화하면서 어떠한 패킷을 필터링할
  것인지 말한다.  프로그래머가 아닌 한, 그리고 필요 이상으로 호기심을 갖지
  않는 사람들이라면 ipchains 도구를 사용하여 패킷 필터링을 제어한다.


  2.3.2.  ``ipchains''

  이 도구는 구식의 IP 방화벽 코드에 사용되었던 `ipfwadm'를 대체한다.
  패키지에는 `ipfwadm-wrapper'라는 이름의 쉘 스크립트가 들어있는데 이것을
  사용하면 예전의 패킷 필터링 명령을 그대로 사용할 수 있다.  ipfwadm
  (느린데다 전달 인수를 제대로 점검하지 않는 결점을 가지고 있다)를 사용하던
  시스템으로부터 일단은 빨리 업그레이드한 상태에서 방화벽 기능을 잠시라도
  중단하고 싶지 않은 경우에만 사용하라.  이 스크립트를 사용한다면 이 하우투
  문서를 더 이상 읽을 필요가 없다.  별첨 ``ipchains와 ipfwadm 간의
  차이점''과 별첨 ``ipfwadm-wrapper 스크립트 사용하기''를 읽어보면 ipfwadm
  에 관한 문제를 조금 더 자세히 알 수 있다.


  3.  일반 IP 방화벽 사슬(Generic IP Firewalling Chains)

  이번 섹션에서는 여러분이 원하는 패킷 필터를 구축하는데 있어 정말로 알아둬야
  할 모든 것을 설명한다.

  3.1.  어떻게 패킷이 필터를 지나가는가?

  커널은 3 가지의 규칙 목록(`방화벽 사슬' 또는 간단히 `사슬'이라고 부른다)을
  가지고 시작한다.  이 3 가지 사슬은 `입력(input)', `출력(output)', 그리고
  `전달(forward)'이다.  패킷이 들어오면(예를 들어 이더넷 카드를 통해) 커널은
  패킷의 운명을 결정짓기 위해 `input' 사슬을 사용한다.  만약 이 단계에서
  살아남았다면 이번에는 패킷을 어디로 보내야 할 지 결정한다.
  만약 패킷이 다른 머신으로 가야 한다면 `forward' 사슬을 살펴본다.
  마지막으로 패킷이 떠나려 하는 순간, `output' 사슬을 점검한다.


  사슬이란 `규칙'의 적용 항목이다.  각 규칙은 `만약 패킷 헤더가 이러이러
  하다면 패킷을 이렇게 처리하시오'라고 말한다.  만약 패킷이 규칙에 맞지
  않으면 사슬에 놓인 그 다음 규칙을 적용한다.  마지막으로 더 이상 적용할
  규칙이 없으면 사슬의 `정책'을 따른다.  보안 문제에 민감한 시스템에서는
  거절 또는 무시를 기본 정책으로 삼는다.


  ASCII 아트 팬들을 위해 머신으로 들어온 패킷의 완전한 여행 경로를 그려
  보았다.


                       ACCEPT/
                      REDIRECT                                        ACCEPT
  --> C --> S --> ______ --> D --> ~~~~~~~~ --> local ------> _______ -->
      h  -> a    |input |    e    {Routing } |  __|____ -->->|output |
      e  |  n    |Chain |    m    {Decision} | |forward|   | |Chain  |
      c  |  i    |______|    a     ~~~~~~~~  | |Chain  |   | |_______|
      k  |  t       |        s        |      | |_______|   |     |
      s  |  y       |        q        |      |     |       |     |
      u  |  |       v        e        v      |     |       |     v
      m  |  |     DENY/      r  Local Process|     v       |   DENY/
      |  |  v    REJECT      a        |-------   DENY/     |  REJECT
      |  |DENY               d        |         REJECT     |
      v  |                   e -------+---------------------
     DENY|                            |
         ------------------------------


  각 단계 하나하나에 대한 설명을 해보자면 다음과 같다:


     체크섬(Checksum):
패킷이 전송 중간에 손상되었는지 여부를 점검한다.  만약 손상되었다면
무시된다.


     정상성 테스트(Sanity):
각각의 방화벽 사슬에 앞서 행해지는 정상성 테스트 중 하나이다.
하지만 가장 중요한 것은 입력 사슬 전에 이뤄지는 정상성 테스트이다.
몇몇 잘못 만들어진 패킷은 규칙 점검 코드를 혼란에 빠지게 할 가능성이
있으므로 여기서 무시해버린다.(이런 일이 발생하면 syslog를 통해
메시지가 출력된다)


     입력 사슬(input Chain):
패킷이 제일 먼저 테스트를 거쳐야 할 방화벽 사슬이다.  만약 사슬 점검
결과가 DENY 또는 REJECT가 아니라면 패킷은 남은 길을 가야 한다.


     디매스커레이드(Demasquerade):
만약 패킷이 앞서 매스커레이드된 패킷에 대한 답신 패킷이라면 일단
디매스커레이드하고 출력 사슬로 곧장 진출한다.  IP 매스커레이드를
사용하지 않는 사람은 도표에서 디매스커레이드 부분을 지우고 생각해도
좋다.


     경로 결정(Routing Decision):
라우팅 코드를 거쳐 목적지 필드를 조사하여 패킷이 지역 프로세스
(뒤에 나오는 지역 프로세스 섹션을 참고)에게 갈 것인지 아니면
원격 머신에 전달될 것인지 결정한다.(뒤에 나오는 전달 사슬 섹션을
참고)


     지역 프로세스(Local Process):
머신에서 작동 중인 프로세스는 경로 결정 단계 이후 패킷을 받거나
또는 패킷을 보낼 수 있다.(보낸 패킷이 지역 프로세스를 향해 가는
것이라면 lo 로 설정된 인터페이스의 출력, 입력 사슬을 통과한다.
그렇지 않다면 출력 사슬만 지나간다)  프로세스 간의 사슬 경유 과정은
흥미롭지 않기 때문에 도표에서 충분히 표현하지 않았다.


     지역(local):
지역 프로세스에 의해 생성된 것이 아니라면 전달 사슬에 대하여 점검
하고 지역 프로세스에 의해 만들어진 것이라면 곧장 출력 사슬로 나아간다.


     전달 사슬(forward Chain):
이 머신에서 다른 머신으로 나아가는 패킷에 대하여 사슬을 적용한다.


     출력 사슬(output Chain):
패킷을 보내기 직전에 사슬 규칙을 적용한다.


  3.1.1.  ipchains 사용하기

  우선 이 문서에서 언급하고 있는 ipchains 버전을 가지고 있는지 점검한다:



       $ ipchains --version
       ipchains 1.3.3, 16-May-1998





  ipchains 에는 매우 상세한 설명을 담고 있는 맨페이지가 들어있다. ("man
  ipchains") 만약 특정 분야에 대한 좀 더 자세한 정보를 원한다면 프로그래밍
  인터페이스를 살펴보거나("man 4 ipfw") 커널 소스 중에서
  "net/ipv4/ip_fwtrees.c" 파일을 살펴보라.  이 파일의 내용이 가장 확실한
  정보를 제공할 것임에 틀림없다.


  ipchains를 통해 할 수 있는 일에는 다음과 같다.  우선 전체 사슬을 관리하는
  동작이 있다.  우선 삭제할 수 없는 `input', `output', `forward' 라는 3 가지
  내장 사슬부터 시작해본다.


  1. 새로운 사슬을 만든다 (-N).

  2. 빈 사슬을 지운다 (-X).

  3. 내장 사슬에 대한 기본 정책을 변경한다 (-P).

  4. 사슬 속에 든 규칙을 나열한다 (-L).

  5. 사슬로부터 규칙을 모두 방출한다 (-F).

  6. 사슬 속의 모든 규칙에 대한 패킷, 바이트 카운터 값을 0 으로 설정한다 (-Z).


  사슬 속의 규칙을 관리하는 방법은 다음과 같다:


  1. 사슬에 새로운 규칙을 추가한다 (-A).

  2. 사슬 속 어딘가에 새로운 규칙을 삽입한다. (-I).

  3. 사슬 속 특정 위치의 규칙을 교체한다 (-R).

  4. 사슬 속의 특정 규칙을 삭제한다 (-D).

  5. 사슬 속에서 첫번째 부합되는 규칙을 삭제한다 (-D).


  매스커레이딩을 위한 몇 가지 동작이 ipchains 에 들어있다.


  1. 현재 매스커레이드된 접속 규칙을 나열한다 (-M -L).

  2. 매스커레이딩 타임아웃 값을 설정한다 (-M -S).

  마지막(그리고 어쩌면 가장 유용한) 기능으로는 여러분으로 하여금 어떤 패킷이
  주어진 사슬을 통과할 때 어떤 일이 벌어지는지 점검하는 기능이 있다.


  3.1.2.  하나의 규칙에 대한 동작

  규칙을 자유자재로 관리하는 것, 이것이야말로 ipchains의 핵심이다.
  대부분의 경우 여러분은 추가(-A), 삭제(-D) 명령을 사용한다.
  다른 것들(삽입을 위한 -I, 교체를 위한 -R)은 기초 개념에 대한 단순한
  확장에 불과하다.


  각 규칙은 패킷이 만족시켜야 하는 조건들을 나타내고 조건을 충족하면 어떤
  행위(`target')를 해야 하는지 말한다.  예를 들어 127.0.0.1 이라는 IP 주소로
  부터 오는 모든 ICMP 패킷을 무시하려 한다고 하자.  이 때 프로토콜은 ICMP 여
  야 하고 발신 주소는 127.0.0.1 이어야 한다는 것이 조건이다.  목표(target)는
  "DENY"가 된다.


  127.0.0.1 은 `루프백' 인터페이스로서 실질적인 네트웍 연결이 없어도 항상
  가지고 있는 인터페이스이다.  ping 프로그램을 사용하여 패킷을 발생시킬 수
  있다. (ping은 단순히 ICMP 타입 8(echo request)를 보내며 이에 협조하는
  모든 호스트는 ICMP 타입 0(echo reply)를 보내주도록 되어 있다.)
  테스트해보기에 좋은 예이다.


  # ping -c 1 127.0.0.1
  PING 127.0.0.1 (127.0.0.1): 56 data bytes
  64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms

  --- 127.0.0.1 ping statistics ---
  1 packets transmitted, 1 packets received, 0% packet loss
  round-trip min/avg/max = 0.2/0.2/0.2 ms
  # ipchains -A input -s 127.0.0.1 -p icmp -j DENY
  # ping -c 1 127.0.0.1
  PING 127.0.0.1 (127.0.0.1): 56 data bytes

  --- 127.0.0.1 ping statistics ---
  1 packets transmitted, 0 packets received, 100% packet loss
  #



  위의 예에서 첫번째 ping 은 성공한다. (`-c 1'이란 패킷 하나만 보내라는
  지시이다.)


  그리고 나서 우리는 `input' 사슬에 127.0.0.1 로부터 오며(`-s 127.0.0.1')
  프로토콜은 ICMP 인(`-p ICMP') 패킷에 대하여 DENY 로 점프하라고(`-j DENY')
  규칙을 추가하였다(-A).


  두번째 ping 을 가지고 규칙을 점검해본다.  결코 오지 않을 응답을 기다리느라
  프로그램이 기다리는 시간이 있기 때문에 잠시 지연된다.


  규칙을 지우는 방법은 두 가지이다.  우선 입력 사슬에 규칙이 하나 뿐이라는
  사실을 알고 있기 때문에 숫자를 지정하여 지울 수 있다.


               # ipchains -D input 1
               #




  위의 예는 입력 사슬의 1 번 규칙을 지운다.


  두번째 방법은 -A 명령과 똑같이 하되 -A 를 -D 로 바꾸는 방법이다.
  매우 복잡한 규칙의 사슬이 있고 삭제해야 할 규칙 번호가 무엇인지 찾고
  싶지 않을 때 사용한다.  다음과 같다:


               # ipchains -D input -s 127.0.0.1 -p icmp -j DENY
               #




  -D 문구는 -A 명령(또는 -I, -R)에서와 완전히 똑같은 옵션을 가져야 한다.
  만약 같은 사슬에 동일한 규칙이 여러 개 있다면 첫번째 것만 지워진다.




  3.1.3.  필터링 규칙표현(Specification)

  We have seen the use of `-p' to specify protocol, and `-s' to specify
  앞서 프로토콜을 명시하기 위해 `-p' 를 사용하고 발신 주소를 명시하기 위해
  `-s' 를 사용한 것을 보았다.  하지만 이것 이외에도 패킷의 특성을 표현하는
  다른 옵션들이 많다.  약간 지루하게 느껴질 지도 모르는 요약 설명을 나열하고자
  한다.


  3.1.3.1.  발신, 도착 IP 주소 명시하기

  발신(-s), 도착(-d) IP 주소는 4 가지 방법으로 표현할 수 있다.
  가장 일반적인 방법은 `localhost', `www.linuxhq.com'과 같은 완전한 이름을
  사용하는 것이다.  두번째 방법은 `127.0.0.1'과 같이 IP 주소를 적는 것이다.


  세번째, 네번째 방법은 `199.95.207.0/24' 또는 `199.95.207.0/255.255.255.0'
  와 같이 IP 주소의 그룹을 표현하는 것이다.  이 둘 다 192.95.207.0 부터
  192.95.207.255 까지의 IP 주소를 표현한다.  `/' 다음의 숫자는 IP 주소 중
  어느 부분이 중요한가를 나타낸다.  `/32' 또는 `/255.255.255.255' 이 기본값
  이다.(IP 주소의 모든 부분이 중요)  `/0' 을 사용하면 모든 IP 주소를 나타
  낼 수 있다.


               # ipchains -A input -s 0/0 -j DENY
               #




  위의 방법은 거의 사용되지 않는다.  왜냐하면 아예 `-s' 옵션을 쓰지 않은
  것이나 다름없는 결과이기 때문이다.


  3.1.3.2.  역규칙(Inversion) 명시하기

  `-s', `-d' 플래그를 포함하는 많은 플래그 앞에 `!'를(`not'을 뜻한다) 붙이면
  주어진 주소와 같지 않는 것을 표현한다.  예를 들어 `-s ! localhost'는
  localhost에서 오지 않는 모든 패킷과 일치한다.


  3.1.3.3.  프로토콜 명시하기

  The protocol can be specified with the `-p' flag.  Protocol can be a
  `-p' 플래그를 사용하여 프로토콜을 명시할 수 있다.  프로토콜은 번호
  (IP에 대한 프로토콜 번호를 알고 있는 경우) 또는 `TCP', `UDP', `ICMP'와
  같은 이름을 사용할 수 있다.  대소문자는 중요하지 않으므로 `tcp', `TCP'는
  똑같이 처리된다.


  역표현을 하기 위해 `-p ! TCP' 처럼 `!' 을 붙일 수 있다.


  3.1.3.3.1.  UDP, TCP 포트 명시하기

  TCP, UDP 프로토콜의 경우에는 TCP, UDP 포트 또는 포트의 범위를 추가로
  지정할 수 있다.(``조각 처리하기'' 섹션을 꼭 읽어보기 바람)  범위는
  `6000:6010' 처럼 콜론(:) 문자를 사용하여 표현한다.  이 때 `6000:6010'의
  의미는 6000 부터 시작하여 6010 까지 11 개의 포트 번호이다.
  만약 범위 시작값이 생략되면 0 으로 간주한다.  만약 범위 끝값이 생략되면
  65535 로 간주한다.  따라서 1024 포트 이하로부터 오는 TCP 접속은
  `-p TCP -s 0.0.0.0/0 :1024'라고 표현한다.  포트 번호는 예를 들어 `www'와
  같이 이름으로 표기할 수도 있다.

  포트를 명시함에 있어 `!'를 사용하여 역규칙 표현이 가능하다.
  WWW 패킷 이외의 모든 TCP 패킷을 표현하고자 할 때는 다음과 같이 한다.

  -p TCP -d 0.0.0.0/0 ! www


  -p TCP -d ! 192.168.1.1 www

  위의 명시 방법과

  -p TCP -d 192.168.1.1 ! www

  표현은 서로 전혀 다른 것이라는 사실을 구별할 수 있어야 한다.


  The first specifies any TCP packet to the WWW port on any machine but
  첫번째 것은 192.168.1.1 을 제외한 모든 머신의 WWW 포트를 사용하는 TCP
  패킷을 가리키는 반면 두번째 것은 192.168.1.1 머신으로 오는 WWW 포트
  이외의 모든 TCP 접속을 나타낸다.


  마지막으로 다음 표현은 192.168.1.1 이 아니고 WWW 포트가 아님을 나타낸다:

  -p TCP -d ! 192.168.1.1 ! www




  3.1.3.3.2.  ICMP 타입과 코드 명시하기

  ICMP 역시 부가 옵션을 가지고 있다.  하지만 ICMP 에 있어 포트란 없기 때문에
  그 의미는 전혀 다르다.


  `-s' 옵션 다음에 ICMP 이름(이름을 알아보려면 `ipchains -h icmp'라고 명령
  한다)을 적거나 또는 숫자로 된 ICMP 유형과 코드로 적을 수 있다.
  ICMP 유형는 `-s' 옵션 뒤에 나오고 코드는 `-d' 옵션 뒤에 나올 수 있다.


  ICMP 이름은 상당히 길다: 따라서 다른 것과 구별할 수 있을 정도로만 적어
  주면 된다.


  가장 흔한 ICMP 패킷 중 일부이다.


       번호    이름                     필요로 하는 곳

       0       echo-reply               ping
       3       destination-unreachable  모든 TCP/UDP 자료 교환
       5       redirect                 라우팅 데몬을 사용하지 않을 때의 라우팅
       8       echo-request             ping
       11      time-exceeded            traceroute




  지금 현재로서는 ICMP 이름 앞에 `!'를 붙일 수 없는 상태이다.


  절대로 절대로 ICMP 유형 3 번 메시지를 막아선 안된다.
  (``ICMP 패킷'' 참고)


  3.1.3.4.  인터페이스 명시하기

  `-i' 옵션을 사용하여 적용할 인터페이스 이름을 명시할 수 있다.
  들어오는 패킷에 대한 인터페이스(즉, `input' 사슬을 통과하는 패킷에 대하여)는
  패킷이 들어온 인터페이스를 간주한다.  논리적으로 볼 때 나가는 패킷에 대한
  인터페이스(`output' 사슬을 통과하는 패킷에 대하여)는 그들이 실제로 나갈
  인터페이스를 가리킨다.  `forward' 사슬을 가로지를 패킷에 대한 인터페이스
  또한 패킷이 나갈 인터페이스를 뜻한다.  매우 다양한 조합이 가능하다고 본다.


  지금 현재 존재하지 않는 인터페이스를 명시해도 아무 문제 없다.
  장치가 작동하기 전까지는 그 규칙에 어떠한 경우도 해당되지 않을 것이기
  때문이다.  이 특징은 다이얼 업 PPP 연결(일반적으로 `ppp0')과 같은 경우에
  매우 쓸모있다.


  특별한 경우로서 인터페이스 이름이 `+'로 끝나면 그 문자열로 시작하는 모든
  인터페이스(현재 존재하든 않든 관계없이)에 적용된다.  예를 들어 `-i ppp+'
  옵션을 사용하면 모든 PPP 인터페이스를 가리킨다.


  주어진 인터페이스를 제외한 인터페이스를 표현하기 위해 `!' 를 인터페이스
  이름 앞에 붙일 수 있다.


  3.1.3.5.  TCP SYN 패킷만 명시하기

  때로는 TCP 접속을 한 방향으로만 허용할 필요가 있다.  예를 들어 외부 WWW
  서버에 대한 접속을 허용하면서도 지금 서버 상에 작동 중인 서버에는 접속하지
  못하도록 했으면 할 때가 있다.


  자연스런 접근 방식은 서버로부터 오는 TCP 패킷을 봉쇄하는 것이리라.
  하지만 불행하게도 TCP 접속은 양방향으로 패킷이 오갈 수 있어야만 한다.


  이에 대한 해결책으로서 접속을 요청하는 패킷만 봉쇄하는 방법을 사용한다.
  이 패킷을 SYN 패킷이라 부른다.(기술적인 설명으로는 SYN 플래그가 설정되어
  있고 FIN, ACK 플래그는 설정되지 않은 패킷을 가리킨다)  이 패킷을 허용하지
  않음으로써 접속 요청을 막을 수 있다.


  `-y' 플래그를 이런 용도로 사용한다.  오로지 TCP 프로토콜에만 해당한다.
  예를 들어 192.168.1.1 로부터 오는 TCP 접속을 표현할 때는 다음과 같다.

  -p TCP -s 192.168.1.1 -y


  역시 `!'를 붙임으로써 접속 초기화 패킷 이외의 패킷을 표현할 수 있다.





  3.1.3.6.  조각(Fragments) 처리하기

  때때로 하나의 패킷이 한 번에 한 회선을 통과하기에는 너무 큰 경우가 발생한다.
  이 때는 패킷이 `조각'으로 나뉘어 여러 개의 패킷으로 전송된다.  받는 쪽에서는
  이 조각을 모아 하나의 패킷으로 재구성한다.


  조각과 관련된 문제는 다음과 같다.  앞서 나열한 몇 가지 명시 방법
  (특히 발신지 포트, 목적지 포트, ICMP 유형, ICMP 코드 또는 TCP SYN 플래그)
  은 커널이 패킷의 시작 부분을 보고 판별하는데 이 정보가 오로지 첫번째 조각에
  만 존재한다는 사실로부터 유래한다.


  여러분의 머신이 외부 네트웍으로 나가는 유일한 연결 창구라면 커널 컴파일시
  `IP: always defragment'를 Y 로 설정하고 컴파일함으로써 리눅스 머신을 지나
  가는 모든 조각을 모으도록 할 수 있다.  이렇게 함으로써 문제를 산뜻하게
  처리할 수 있다.


  그렇지 않을 때는 조각이 필터링 규칙에 의해 어떻게 처리되는지 이해하는 일이
  중요하다.  우리가 갖고 있지 못한 정보를 요구하는 어떤 필터링 규칙도 일치
  하지 않을 것이다.  이는 첫번째 조각이 마치 다른 패킷과 마찬가지로 처리됨을
  뜻한다.  하지만 두번째 이후부터는 문제가 발생한다.
  따라서 `-p TCP -s 192.168.1.1 www' 라는 규칙(발신 포트가 `www'인 것)은
  첫번째 조각을 제외하고 나머지 조각에 대하여 일치하지 않는다.
  그 반대 규칙인 `-p TCP -s 192.168.1.1 ! www' 도 마찬가지다.


  그렇지만 `-f' 플래그를 사용하여 두번째 이후의 조각에 대하여 규칙을 명시할
  수 있다.  이 조각들에 대하여 TCP, UDP 포트, ICMP 유형, ICMP 코드 또는
  TCP SYN 플래그를 명시하는 것은 분명히 적절지 않다.


  `!'를 `-f' 앞에 붙임으로써 두번째 이후의 조각이 아닌 것에 대한 규칙을
  명시하는 것이 가능하다.


  Usually it is regarded as safe to let second and further fragments
  일반적으로 두번째 이후의 조각은 그냥 놔두는 것이 안전하다.  왜냐하면 필터링
  규칙이 첫번째 조각에 영향을 줄 것이고 목적지 호스트에서 제대로 조각이 모이지
  못하게 할 것이기 때문이다.  하지만 이런 점을 이용하여 조각들을 보내게 되면
  머신이 다운되는 버그가 발견된 적 있다.  여러분의 판단에 맡긴다.


  네트웍 관리자가 주의할 점 : 잘못 형성된 패킷(TCP, UDP, ICMP 패킷이 포트나
  ICMP 코드, 유형을 방화벽 코드가 읽기에는 너무 작은 경우) 또한 조각으로
  간주한다.  8 번째 위치에 있는 TCP 조각만이 명시적으로 방화벽 코드에 의해
  버려진다.(이 때 syslog 에 에러 메시지가 나타난다 )


  예를 들어 다음 규칙은 192.168.1.1 로 가는 모든 조각을 버린다.




       # ipchains -A output -f -D 192.168.1.1 -j DENY
       #


  3.1.4.  필터링의 부차적인 효과

  좋다. 지금까지 규칙을 사용하여 패킷을 잡아내는 모든 방법을 배웠다.
  만약 패킷이 규칙에 부합하면 다음과 같은 일이 일어난다:


  1. 규칙에 대한 바이트 카운터가 패킷의 크기(헤더오 모든 자료)만큼 증가한다.

  2. 규칙에 대한 패킷 카운터가 증가한다.

  3. 규칙에서 요구하는 경우 패킷을 기록한다.

  4. 규칙에서 요구하는 경우 패킷의 서비스 유형(Type Of Service) 필드를
     변경한다.

  5. 규칙에서 요구하는 경우 패킷을 표시한다.(2.0 커널 시리즈에서는 안됨)

  6. 규칙 목표를 조사하여 패킷에 대하여 어떤 일을 할 것인지 결정한다.


  For variety, I'll address these in order of importance.
  중요성의 순서대로 이 문제를 언급하도록 하겠다.


  3.1.4.1.  목표 명시하기

  `target' 은 커널이 규칙에 맞는 패킷을 어떻게 처리할 것인지 말해주는 것이다.
  ipchains 는 `-j' (어디어디로 점프한다고 생각하라)을 써서 목표을 명시한다.


  가장 간단한 경우는 아무런 목표가 없는 경우이다.  이런 규칙(보통 `회계
  (accounting) 규칙'이라 부른다)은 특정 유형의 패킷에 대하여 갯수를 셀 때
  사용된다.  규칙에 맞든 틀리든 커널은 사슬 속의 다음 규칙으로 향한다.
  예를 들어 192.168.1.1로부터 오는 패킷의 갯수를 세고자 할 때는 다음과
  같이 한다:


       # ipchains -A input -s 192.168.1.1
       #


  (`ipchains -L -v'를 사용하여 각 규칙에 연관된 바이트, 패킷 카운터를 볼
  수 있다.)


  6 개의 특별한 목표가 있다.  처음 3 가지는 `ACCEPT', `REJECT', `DENY' 로서
  매우 간단하다.  ACCEPT는 패킷이 통과하도록 허용한다.  DENY는 마치 패킷을
  받지 않은 것처럼 버린다.  REJECT는 패킷을 버리지만 패킷의 발신지에 ICMP
  답신을 보내어 목적지에 도착할 수 없음을 통보한다.(ICMP 패킷이 아닌 경우)


  그 다음은 `MASQ'로서 커널로 하여금 패킷을 매스커레이드하게 한다.  제대로
  작동하기 위해서는 IP 매스커레이딩이 가능하도록 커널이 컴파일되어 있어야
  한다.  자세한 사항은 Masquerading-HOWTO와 별첨 ``ipchains와 ipfwadm 간의
  차이점''을 참고하라.  이 목표는 `forward' 사슬을 통과하는 패킷에만
  유효하다.


  또 다른 중요한 특별 목표로는 커널로 하여금 패킷이 향하고 어디로 향하고
  있었든 상관없이 지역 포트로 패킷의 방향으로 변경해버리는 `REDIRECT'가
  있다.  TCP, UDP와 같은 프로토콜에서만 가능하다.  선택적으로 포트(이름 또는
  번호)를 `-j REDIRECT' 다음에 적음으로써 어떤 특정 포트로 향하고 있던 패킷을
  다른 포트로 방향전환시킬 수 있다.  이 목표는 `input' 사슬을 통과하는 패킷에
  유효하다.

  특별한 목표의 마지막은 `RETURN'으로서 즉시 사슬의 마지막 항목을 떠나도록
  한다. (``정책 정하기''를 참고)


  이외의 다른 목표는 사용자 정의 사슬(``전체 사슬에 대한 동작'' 참고)이다.
  패킷은 사슬의 규칙을 통과하기 시작한다.  만약 사슬에서 패킷의 운명이
  결정되지 않았고 사슬 통과를 마쳤다면 현재 진행 중이었던 사슬의 바로 다음
  규칙에서 패킷 통과 작업이 재개된다.


  ASCII 아트 시간이 돌아왔다.  다음 2 개의 (약간은 멍청한) 사슬을 생각해
  보자. 하나는 내장 사슬인 `input'이며 하나는 사용자 정의 사슬인 `Test'이다.


           `input'                         `Test'
          ----------------------------    ----------------------------
          | Rule1: -p ICMP -j REJECT |    | Rule1: -s 192.168.1.1    |
          |--------------------------|    |--------------------------|
          | Rule2: -p TCP -j Test    |    | Rule2: -d 192.168.1.1    |
          |--------------------------|    ----------------------------
          | Rule3: -p UDP -j DENY    |
          ----------------------------


  192.168.1.1로부터 와서 1.2.3.4로 가는 TCP 패킷을 생각해본다.  패킷이
  입력 사슬로 들어가서 규칙 1 번에 적용해본다.  해당되지 않는다.
  규칙 2 번이 맞고 그 목표는 `Test'이다.  따라서 조사할 다음 규칙은 `Test'의
  시작 부분이다.  Test의 규칙 1 은 목표를 명시하고 있지 않으므로 그 다음
  규칙 2 를 적용한다.  맞지 않으므로 사슬의 끝에 도달하게 된다.  여기서 우리는
  마치 규칙 2 를 실행하고 나서 규칙 3 을 실행하게 된 것처럼 원래의 `input'
  사슬로 돌아간다.  규칙 3 역시 적용되지 않는다.


  따라서 패킷의 경로는 다음과 같다:

                                  v    __________________________
           `input'                |   /    `Test'                v
          ------------------------|--/    -----------------------|----
          | Rule1                 | /|    | Rule1                |   |
          |-----------------------|/-|    |----------------------|---|
          | Rule2                 /  |    | Rule2                |   |
          |--------------------------|    -----------------------v----
          | Rule3                 /--+___________________________/
          ------------------------|---
                                  v


  사용자 사슬을 효과적으로 사용하기 싶은 사람은 ``여러분만의 방화벽 규칙을
  체계화하기'' 섹션을 참고하라.


  3.1.4.2.  패킷 기록하기

  규칙에 맞을 때 가질 수 있는 부수 효과이다.  일치하는 패킷에 대하여 `-l'
  플래그를 가지고 기록할 수 있다.  일상적인 패킷을 기록하기 보다는 예외적인
  상황을 발견하고자 할 때 사용하게 될 것이다.
  (`man klogd' 또는 `man dmesg' 참고)


  3.1.4.3.  서비스 유형 처리하기

  IP 헤더에서 자주 사용되지는 않는 4 개의 비트를 서비스 유형(Type of
  Service, TOS) 비트라고 부른다.  이 비트들은 패킷의 처리 방식에 영향을
  준다.  4 개의 비트는 "최소 지연(Minimum Delay)", "최대 전송률(Maximum
  Throughput)", "최대 안정성(Maximum Reliability)", "최소 경로(Minimum Cost)"
  이다.  한 번에 하나만 설정할 수 있다.  TOS 처리 코드의 저자인 Rob
  van Nieuwkerk 씨의 말을 들어보겠다.


       무엇보다도 내게 있어선 "최소 지연(Minimum Delay)"이 중요하다.
       나의 상위 라우터(리눅스이다)로 가는 "대화형" 패킷에 대하여 이
       비트를 켜둔다.  나는 33k6 모뎀 뒷쪽이 있다.  리눅스는 3 개의
       큐를 통해 패킷의 우선권을 조정한다.  이런 식으로 동시에 대량의
       다운로드 작업을 하면서도 대화형 작업의 효율을 높일 수 있다.
       (시리얼 장치 드라이버의 큐도 역시 작았더라면 더 향상되었을 수
       있겠지만 어찌 되었든 지연 시간을 1.5 초로 낮출 수 있었다.)



  The most common use is to set telnet & ftp control connections to
  가장 일반적인 사용 방법은 telnet & ftp 제어 접속에 대해서는
  "최소 지연(Minimum Delay)"을 사용하고 FTP 자료에 대해서는
  "최대 전송률(Maximum Throughput)"을 사용하는 것이다.  다음과 같이 하면
  된다.


       ipchains -A output -p tcp -d 0.0.0.0/0 telnet -t 0x01 0x10
       ipchains -A output -p tcp -d 0.0.0.0/0 ftp -t 0x01 0x10
       ipchains -A output -p tcp -s 0.0.0.0/0 ftp-data -t 0x01 0x08



  `-t' 플래그는 2 개의 전달 변수를 16 진수로 받아들인다.  이렇게 함으로써
  복잡한 TOS 비트 조작이 가능하다.  첫번째 매스크는 패킷의 현재 TOS 값에 AND
  되고 두번째 매스크는 XOR 된다.  너무 복잡하게 여겨진다면 다음 도표를
  사용하라.


       TOS 이름                값              전형적인 용도

       Minimum Delay           0x01 0x10       ftp, telnet
       Maximum Throughput      0x01 0x08       ftp-data
       Maximum Reliability     0x01 0x04       snmp
       Minimum Cost            0x01 0x02       nntp



  3.1.4.4.  패킷 표시하기

  현재 사용되고 있지 않지만 커널 v2.1 시리즈에서 Traffic Shaper 코드를
  Alexey Kuznetsov 씨의 새로운 서비스 품질(Quality of Service) 구현으로
  바뀌게 되면 더욱 복잡하고 강력한 상호 작용이 가능할 것이라 예상하고 있다.
  따라서 2.0 시리즈에서도 역시 무시된다.


  3.1.4.5.  전체 사슬에 대한 동작

  ipchains 의 유용한 기능 중 하나는 연관된 규칙을 묶어 사슬 속에 넣을 수
  있다는 것이다.  내장 사슬(`input', `output', `forward')과 내장 목표
  (`MASQ', `REDIRECT', `ACCEPT', `DENY', `REJECT', `RETURN')과 이름 충돌만
  없다면 이 사슬을 어떻게 부르든 상관없다.  본인이 앞으로의 확장 기능에
  대하여 사용할 지 모르므로 대문자 이름을 피하길 권장한다.  사슬 이름은
  8 자까지 가능하다.


  3.1.4.6.  새로운 사슬 만들기

  새로운 사슬을 만들어보자.  본인으로 말할 것 같으면 매우 상상력이 풍부한(?)
  사람이기 때문에 사슬 이름을 `test'라 하겠다 (^^)



       # ipchains -N test
       #



  매우 간단하다.  이제부터 규칙을 추가할 수 있다.


  3.1.4.7.  사슬 지우기

  사슬 지우기 또한 간단하다.



       # ipchains -X test
       #



  왜 `-X' 인가?  아~ 이미 좋은 글자들을 다 써버렸기 때문이다.


  사슬을 지우는데는 몇 가지 제한 사항이 있다.  일단 사슬이 빈 상태여야
  한다.(``사슬 비우기'' 참고)  그리고 사슬이 다른 규칙의 목표가 되어서는
  안된다.  3 가지 내장 사슬은 지울 수 없다.


  3.1.4.8.  사슬 비우기

  `-F' 명령을 사용하면 사슬로부터 모든 규칙을 간단히 비울 수 있다.



               # ipchains -F forward
               #



  사슬을 명시하지 않으면 모든 사슬 내용이 비워진다.


  3.1.4.9.  사슬 내용 보기


  `-L' 명령을 사용하여 사슬 속에 든 모든 규칙을 나열할 수 있다.


       # ipchains -L input
       Chain input (refcnt = 1): (policy ACCEPT)
       target     prot opt    source                destination           ports
       ACCEPT     icmp -----  anywhere              anywhere              any
       # ipchains -L test
       Chain test (refcnt = 0):
       target     prot opt    source                destination           ports
       DENY       icmp -----  localnet/24           anywhere              any
       #


  `test' 항목에 표시된 "refcnt"란 `test'를 목표로 갖고 있는 규칙의 갯수를
  나타낸다.  사슬이 지워기 전에 이 값이 0 이어야 한다.(그리고 사슬 자체도
  빈 상태여야 한다.)


  사슬 이름이 생략되면 빈 것이라 할 지라도 모든 사슬이 표시된다.


  There are three options which can accompany `-L'.  The `-n' (numeric)
  `-L' 명령과 사용할 수 있는 3 개의 옵션이 있다.  `-n'(숫자 표현) 옵션은
  ipchains로 하여금 IP 주소 살펴보기를 하지 않게 하기 때문에 DNS 가 제대로
  설정되지 않아 상당한 지연이 생기거나 DNS 요청을 필터링한 경우에 유용하다.
  포트에 대해서는 포트 이름이 아닌 숫자로 표시되도록 한다.


  `-v' 옵션을 사용하면 패킷, 바이트 카운터, TOS 매스크, 인터페이스 그리고
  패킷 표식과 같은 규칙의 세부 사항을 볼 수 있다.
  옵션을 붙이지 않으면 이 값들은 표시되지 않는다.  예를 보자:



       # ipchains -v -L input
       Chain input (refcnt = 1): (policy ACCEPT)
        pkts bytes target     prot opt   tosa tosx  ifname    mark        source                destination           ports
          10   840 ACCEPT     icmp ----- 0xFF 0x00  lo                    anywhere              anywhere              any



  패킷, 바이트 카운터의 값이 1000, 1,000,000, 1,000,000,000 에 대하여
  `K', `M', `G'라는 접미사를 사용하여 표시된다는 것을 눈여겨 보자.
  `-x' 옵션을 사용하면 그 값이 매우 크다 할 지라도 완전한 숫자로 표시해준다.


  3.1.4.10.  카운터 재설정하기(0으로 만들기)

  카운터 값을 0 으로 만들고 싶을 때가 있다.  `-Z'(제로 카운터) 옵션을 사용
  하면 된다.  예를 보자:


       # ipchains -v -L input
       Chain input (refcnt = 1): (policy ACCEPT)
        pkts bytes target     prot opt   tosa tosx  ifname    mark        source                destination           ports
          10   840 ACCEPT     icmp ----- 0xFF 0x00  lo                    anywhere              anywhere              any
       # ipchains -Z input
       # ipchains -v -L input
       Chain input (refcnt = 1): (policy ACCEPT)
        pkts bytes target     prot opt   tosa tosx  ifname    mark        source                destination           ports
           0     0 ACCEPT     icmp ----- 0xFF 0x00  lo                    anywhere              anywhere              any
       #


  이런 접근 방식의 문제점은 종종 재설정 바로 직전에 카운터 값을 알아야 할
  필요가 있다는 것이다.  위의 예에서 어떤 패킷이 `-L'과 `-Z' 명령 중간에
  지나가는 경우가 발생한다.  이런 이유 때문에 값을 읽으면서 동시에 값을
  재설정하기 위해 `-L'과 `-Z'를 같이 사용한다.  하지만 이 방법으로는 하나의
  사슬에 대하여 명령할 수 없으므로 한 번에 모든 사슬을 보면서 동시에 0 으로
  만들어야 한다.


       # ipchains -L -v -Z
       Chain input (policy ACCEPT):
        pkts bytes target     prot opt   tosa tosx  ifname    mark        source                destination           ports
          10   840 ACCEPT     icmp ----- 0xFF 0x00  lo                    anywhere              anywhere              any

       Chain forward (refcnt = 1): (policy ACCEPT)
       Chain output (refcnt = 1): (policy ACCEPT)
       Chain test (refcnt = 0):
           0     0 DENY       icmp ----- 0xFF 0x00  ppp0                  localnet/24           anywhere              any
       # ipchains -L -v
       Chain input (policy ACCEPT):
        pkts bytes target     prot opt   tosa tosx  ifname    mark        source                destination           ports
          10   840 ACCEPT     icmp ----- 0xFF 0x00  lo                    anywhere              anywhere              any

       Chain forward (refcnt = 1): (policy ACCEPT)
       Chain output (refcnt = 1): (policy ACCEPT)
       Chain test (refcnt = 0):
           0     0 DENY       icmp ----- 0xFF 0x00  ppp0                  localnet/24           anywhere              any
       #


  3.1.4.11.  정책 설정하기

  앞서 ``목표 명시하기'' 에서 어떻게 패킷이 사슬을 통과하는지 이야기할 때
  패킷이 내장 사슬의 마지막을 통과할 때 어떤 일이 벌어지는지 간략히 알아보았다.
  이 때 사슬의 `정책'이 패킷의 운명을 결정한다.  오로지 내장 사슬
  (`input', `output', `forward')만이 정책을 갖는다.  왜냐하면 패킷이 사용자
  정의 사슬을 통과하고 나면 원래의 사슬에서 다시 시작하기 때문이다.


  정책은 다음과 같은 특수한 4 가지 대상 중 하나를 선택할 수 있다.
  `ACCEPT', `DENY', `REJECT', `MASQ'.  여기서 `MASQ'는 오로지
  `forward' 사슬에만 유효하다.


  내장 사슬에 포함된 규칙에 `RETURN' 목표를 두면 패킷이 규칙에
  맞을 때 명시적으로 사슬의 정책을 따르도록 하는데 쓸모 있다
  이 점도 알아두는 것이 좋다.


  3.1.5.  매스러케이딩(Masquerading)에 관련된 동작


  IP 매스커레이딩과 관련하여 써먹을 수 있는 몇 가지 매개변수가 있다.
  이들을 위한 별도의 도구를 만들 이유가 없다고 생각했기에(이 생각은 앞으로
  바뀔 수 있다) `ipchains' 에 그 기능을 포함시켰다.


  IP 매스커레이드 명령은 `-M' 이다.  `-L' 과 같이 쓰면 현재 매스커레이드되어
  있는 접속 현황을 볼 수 있고 `-S'를 사용하여 매스커레이드 매개변수를 정할
  수 있다.


  `-L' 명령에 `-n'을 붙이면 호스트 이름과 포트 이름 대신 모두 숫자로 보여주며
  `-v' 옵션을 주면 매스커레이드된 접속 상황에 대하여 순차 번호(sequence #)의
  델타(delta)값을 보여준다.


  `-S' 명령 뒤에는 3 개의 타임아웃 값을 초 단위로 적어야 한다. 
  하나는 TCP 세션, 또 하나는 FIN 패킷 이후의 TCP 세션, 그리고 하나는
  UDP 패킷에 대한 값이다.  값을 변경하고 싶지 않을 때는 간단히 `0'을
  적는다.


  기본값은 `/usr/include/net/ip_masq.h'에 적혀 있으며 현재는 각각
  15 분, 2 분, 5 분이다.


  일반적으로 변경하는 값은 첫번째 값으로서 FTP 를 위해서이다.
  (``FTP 악몽''을 참고)


  3.1.6.  패킷 점검하기

  때로는 방화벽 사슬을 디버깅하기 위해 어떤 패킷이 머신에 들어오면 어떤
  일이 발생하는지 알고 싶을 때가 있다.  `ipchains'의 `-C' 명령을 사용하면
  된다.  커널이 실제 패킷을 검사할 때 사용하는 동일한 루틴을 사용한다.


  `-C' 인수 다음에 패킷을 테스트해 볼 사슬 이름을 적는다.  커널은 언제나
  `input', `output', `forward' 사슬에서 시작하지만 테스팅을 목적으로 할
  때는 어떤 사슬에서든 시작할 수 있다.


  `패킷'에 대한 세부 설명은 방화벽 규칙을 명시할 때 사용했던 문법 그대로
  사용한다.  특히 프로토콜(`-p'), 발신지 주소(`-s'), 목적지 주소(`-d'),
  인터페이스(`-i') 옵션을 꼭 명시해야 한다.  프로토콜이 TCP 또는 UDP 인 경우
  발신지 주소 하나와 목적지 포트를 명시해야 하며 ICMP 프로토콜인 경우에는
  ICMP 유형과 코드를 꼭 명시해야 한다. (조각 규칙을 가리키기 위해 `-f' 플래그
  를 사용한 경우가 아닐 때 그러하다.  만약 `-f' 옵션이 사용된 경우에는
  발신지 주소, 목적지 포트 옵션은 쓸 수 없다.)


  프로토콜이 TCP 라면(그리고 `-f' 플래그가 없는 상태) `-y' 플래그를 사용하여
  패킷에 SYN 비트가 설정되어 있음을 표현할 수 있다.


  다음은 192.168.1.1 의 60000 포트에서 192.168.1.2 의 www 포트로 향하는
  TCP SYN 패킷이 `input' 사슬에 들어가서 어떤 결과를 내놓는지 테스트하는 예
  이다.  ( 전형적인 WWW 접속 시작 과정의 예이다. )



       # ipchains -C input -p tcp -y -s 192.168.1.1 60000 -d 192.168.1.2 www
       packet accepted
       #



  3.1.7.  한 번에 여러 규칙 만들기와 사건 감시하기

  때로는 하나의 명령으로도 여러 규칙에 영향을 미칠 수 있다.  다음과 같은
  두 가지 방법이 있다.  우선 DNS 를 통하여 여러 개의 IP 주소로 해석되는
  호스트 이름을 명시하게 되면 `ipchains'는 마치 여러분이 각 IP 주소마다
  한 번씩 똑같은 명령을 내린 것처럼 처리한다.


  따라서 만약 `www.foo.com' 이라는 호스트 이름이 3 개의 IP 주소를 가리키고
  `www.bar.com' 호스트 이름이 2 개의 IP 주소를 가리키게 된다고 하고
  `ipchains -A input -j reject -s www.bar.com -d www.foo.com' 라 명령하게
  되면 마치 6 개의 규칙을 `input' 사슬에 넣은 것과 같다.


  `ipchains'가 여러 행동을 취하게 하는 다른 방법은 양방향 플래그(`-b')를
  사용하는 방법이다.  이 플래그를 사용하면 `ipchains'는 명령을 두 번 내린
  것처럼 동작한다.  두번째 명령은 첫번째 것과 `-s', `-d'가 뒤바뀐 명령이다.
  따라서 192.168.1.1로 향하거나 그로부터 들어오는 모든 패킷 전달을 막기 위해
  서는 다음과 같이 할 수 있다.



       # ipchains -b -A forward -j reject -s 192.168.1.1
       #


  개인적으로는 `-b' 옵션을 좋아하지 않는다.  이게 편하다고 생각하는 사람은
  ``ipchains-save 사용하기'' 섹션을 참고하라.


  -b 옵션은 삽입(`-I'), 삭제(`-D') (규칙 번호를 적는 경우 제외), 추가(`-A'),
  점검(`-C') 명령과 함께 사용할 수 있다.


  유용한 플래그로는 여러분의 명령에 따라 `ipchains'가 어떤 일을 하고 있는지
  보여주도록 하는 `-v'(장황하게)가 있다.  다수의 규칙에 영향을 미칠 것이라
  생각하는 명령에서 쓸모있다.  예를 들어 192.168.1.1과 192.168.1.2 사이의
  조각들의 상태를 점검하는 경우를 보겠다.



  # ipchains -v -b -C input -p tcp -f -s 192.168.1.1 -d 192.168.1.2 -i lo
    tcp opt   ---f- tos 0xFF 0x00  via lo    192.168.1.1  -> 192.168.1.2    * ->   *
  packet accepted
    tcp opt   ---f- tos 0xFF 0x00  via lo    192.168.1.2  -> 192.168.1.1    * ->   *
  packet accepted
  #


  3.2.  쓸만한 예제

  나는 전화접속 PPP 접속(`-i ppp0')을 하고 있다.  전화접속을 할 때마다
  뉴스를 긁어오며(`-p TCP -s news.virtual.net.au nntp') 메일을 가져온다.
  (`-p TCP -s mail.virtual.net.au pop-3')  리눅스 박스를 정기적으로 갱신
  하기 위해 데비안 FTP 갱신 방법을 사용한다. (`-p TCP -s ftp.debian.org
  ftp-data')  그 동안 ISP의 프록시를 통해 웹 서핑을 즐긴다.
  (`-p TCP -d proxy.virtual.net.au 8080')  하지만 Dilbert Archive 사이트에
  보이는 doubleclick.net 으로부터 광고를 싫어한다.
  (`-p TCP -y -d 199.95.207.0/24' & `-p TCP -y -s 199.95.208.0/24')


  접속 중에 다른 사람들이 내 머신으로 ftp해 들어오는 것은 게의치 않는다.
  (`-p TCP -d $LOCALIP ftp')  하지만 내 네트웍 외부의 사람들이 내 IP 주소를
  가장하여 사용하길 원치는 않는다. (`-s 192.168.1.0/24')


  내부 네트웍에 다른 머신이 없기 때문에 설정은 매우 쉽게 이뤄진다.


  지역 프로세스 어떤 것도(예를 들어 네스케이프, Gzilla 등등) doubleclick.net
  에 접속하지 못하도록 하고 싶다.



       # ipchains -A input -d 199.95.207.0/24 -j REJECT
       # ipchains -A input -d 199.95.208.0/24 -j REJECT
       #


  지역적으로 생성되어 `input' 사슬을 통과하는 패킷에 대하여 인터페이스를
  `lo'로 설정하기 위해 `-i lo'를 명시할 수도 있다.


  이제 나는 외부로 나가는 패킷에 대하여 우선권을 조정하려 한다. ( 들어오는
  패킷에 대하여 할 수 있는 일이라곤 별로 없다. )  적지 않은 규칙을 가지고
  있기 때문에 이 모두를 `ppp-out'이라는 이름의 사슬에 넣어두는 것이 좋다고
  생각한다.



       # ipchains -N ppp-out
       # ipchains -A output -i ppp0 -j ppp-out
       #



  웹, 텔넷에 대해서는 최소 지연을 원한다.


       # ipchains -A ppp-out -p TCP -d proxy.virtual.net.au 8080 -t 0x00 0x10
       # ipchains -A ppp-out -p TCP -d 0.0.0.0 telnet -t 0x00 0x10
       #



  ftp 자료와 nntp, pop-3 에 대해서는 우선권을 낮춘다:


       # ipchains -A ppp-out -p TCP -d 0.0.0.0/0 ftp-data -t 0x00 0x02
       # ipchains -A ppp-out -p TCP -d 0.0.0.0/0 nntp -t 0x00 0x02
       # ipchains -A ppp-out -p TCP -d 0.0.0.0/0 pop-3 -t 0x00 0x02
       #



  ppp0 인터페이스를 통해 들어오는 패킷을 제한한 몇 가지 규칙이 있다:
  `ppp-in' 이라는 사슬을 만들어보자:



       # ipchains -N ppp-in
       # ipchains -A input -i ppp0 -j ppp-in
       #



  ppp0를 통해 192.168.1.* 이라는 발신 주소를 갖고 들어오는 패킷은 모두
  기록하고 처리한다.



       # ipchains -A ppp-in -s 192.168.1.0/24 -l -j DENY
       #



  DNS (모든 요청을 `203.29.16.1'으로 전달하기 때문에 DNS TCP에 대해서는 응답을
  허가한다), ftp, 반환하는(return) ftp-data 접속을 허가한다.(return ftp-data
  란 1023 포트 위로 나가는 ftp-data를 말한다.)


       # ipchains -A ppp-in -p TCP -s 203.29.16.1 -d $LOCALIP dns -j ACCEPT
       # ipchains -A ppp-in -p TCP -s 0.0.0.0/0 ftp-data -d $LOCALIP 1024: -j ACCEPT
       # ipchains -A ppp-in -p TCP -d $LOCALIP ftp -j ACCEPT
       #


  마지막으로 그 밖에 지역적으로 생성된 패킷은 모두 허가한다:


  # ipchains -A input -i lo -j ACCEPT
  #


  `input' 사슬에 대한 기본 정책은 DENY이다.  따라서 명시된 것 이외의 모든
  것은 거부한다.


       # ipchains -P input DENY
       #


  주의: 실제로 이 순서대로 사슬 설정을 하지는 않는다.  왜냐하면 설정 중에
  패킷들이 지나갈 수 있기 때문이다.  가장 안전한 방법은 우선 정책을 DENY로
  한 후 규칙을 삽입해나가는 것이다.  당연히 규칙에서 DNS 찾아보기를 필요로
  하는 경우에는 문제가 된다.




  3.2.1.  ``ipchains-save'' 사용하기

  여러분이 원하는 대로 방화벽 사슬을 설정해 놓은 후, 다음 번에 어떻게 했는지
  기억하며 끙끙거리는 일은 정말 고통스럽다.


  바로 이 문제를 위해 `ipchains-save'라는 스크립트가 현재의 사슬 설정을
  읽어들여 파일로 저장하는 일을 해준다.  당분간은 `ipchains-restore'가
  어떤 일을 하는지에 대해서만 말해두겠다.


  `ipchains-save' can save a single chain, or all chains (if no chain
  name is specified).  The only option currently permitted is `-v' which
  prints the rules (to stderr) as they are saved.  The policy of the
  chain is also saved for `input', `output' and `forward' chains.



       $ ipchains-save > my_firewall
       Saving `input'.
       Saving `output'.
       Saving `forward'.
       Saving `ppp-in'.
       Saving `ppp-out'.
       $


  3.2.2.  ``ipchains-restore'' 사용하기

  `ipchains-save'를 사용하여 저장한 사슬을 복구하는 스크립트가
  `ipchains-restore' 이다.  두 개의 옵션을 가지고 있다.
  `-v' 는 어떤 규칙이 추가되고 있는지 보여준다.  `-f' 옵션은 앞서 설명한
  대로 사슬이 존재하는 경우 사용자 정의 사슬의 내용을 일단 비우도록 한다.


  만약 스크립트의 입력 내용에 사용자 정의 사슬이 있다면 `ipchains-restore'는
  사슬이 이미 존재하고 있는지 점검한다.  존재하는 경우 일단 사슬의 내용을
  모두 비울 것인지(규칙을 모두 지우는 일) 아니면 그냥 이 부분은 아무런 일도
  하지 않고 넘어갈 것인지 질문을 받는다.  `-f' 옵션을 명령행에 주면
  질문 과정은 없다.  무조건 사슬의 내용이 일단 비워진다.


  스크립트를 실행하기 위해서는 root 여야 한다; 규칙을 복구시켜놓기 위해
  `ipchains'를 사용하기 때문이다.


  예를 보자:


       # ipchains-restore < my_firewall
       Restoring `input'.
       Restoring `output'.
       Restoring `forward'.
       Restoring `ppp-in'.
       Chain `ppp-in' already exists. Skip or flush? [S/f]? s
       Skipping `ppp-in'.
       Restoring `ppp-out'.
       Chain `ppp-out' already exists. Skip or flush? [S/f]? f
       Flushing `ppp-out'.
       #



  4.  기타 등등

  이 섹션에서는 문서의 앞 부분 구조에 넣을 수 없었던 기타 정보와 FAQ를 다룬다.


  4.1.  어떻게 원하는 방화벽 규칙을 체계화할 수 있는가?


  이 질문에 앞서 약간의 생각이 필요하다.  여러분은 속도를 최적화할
  수도 있고(대부분의 패킷에 대하여 점검 규칙의 수를 최소화하는 쪽) 또는
  관리를 편하게 하는 쪽으로 선택할 수 있다.


  PPP 처럼 간헐적으로 연결되는 회선을 가지고 있는 경우에는 부팅하면서
  제일 먼저 input 사슬에 `-i ppp0 -j DENY' 를 설정하고 싶을 것이다.
  그리고 `ip-up' 스크립트에 다음과 같은 내용을 넣어 사용한다.


       # Re-create the `ppp-in' chain.
       ipchains-restore -f < ppp-in.firewall

       # Replace DENY rule with jump to ppp-handling chain.
       ipchains -R input 1 -i ppp0 -j ppp-in


  ip-down 스크립트의 내용은 다음과 같다:


       ipchains -R input 1 -i ppp0 -j DENY



  4.2.  걸러내서는 안될 것


  원하지 않는 모든 것을 걸러내기 시작하기 전에 알아두어야 할 몇 가지
  중요한 점들이 있다.


  4.2.1.  ICMP 패킷

  ICMP packets are used (among other things) to indicate failure for
  (다른 많은 것들 중에서도) ICMP는 다른 프토토콜(TCP, UDP)의 실패를 통보할
  때 사용된다.  `목적지에 도달할 수 없음(destination-unreachable)' 패킷이
  ICMP 패킷의 예이다.  이 패킷을 막게 되면 `호스트에 접근할 수 없음
  (Host unreachable)' 또는 `호스트로의 도달 경로 없음(No route to host)'
  에러를 받을 수 없게 된다.  답신이 오지 않을 경우에도 무작정 기다리게
  된다.  짜증나게 하는 일이지만 그렇게 심각한 것은 아니다.


  더 중요한 문제는 ICMP 패킷이 MTU 찾기에 쓰인다는 사실 때문에 비롯된다.
  잘 되어 있는 TCP 구현체(리눅스 포함)들은 패킷이 조각으로 나뉨없이 목적지에
  도착할 수 있는 가장 큰 패킷의 크기를 알아내기 위해 MTU 찾기를 사용한다.
  (조각현상(fragmentation)은 성능을 저하시키기 때문이다.  특히 조각 중 일부를
  잃게 되면 성능 저하는 매우 심각해진다.)  MTU 찾기는 "조각 나누지 말 것
  (Don't Fragment)" 비트를 설정한 패킷을 보내고 나서 "조각 나누기가 필요하지만
  DF(조각 나누지 않았음) 비트를 설정함(Fragmentation needed but DF set)"
  이라는 메시지를 받을 때까지 조그마한 패킷을 보냄으로써 이뤄진다.
  이 패킷이 바로 `목적지에 도달할 수 없음(destination-unreachable)' 류의
  패킷이다.  만약 이 패킷을 받지 못하면 지역 호스트는 MTU 값을 줄일 수 없게
  되고 성능은 형편없이 떨어지게 된다.


  4.2.2.  DNS 답신


  모든 TCP 접속을 막고 싶을 때가 있겠지만 이렇게 하면 몇 가지 중요한 것이
  작동하지 않을 경우가 있는데 그 첫번째가 바로 DNS 이다.  여러분의 리눅스
  머신은 호스트 이름을 IP 주소로 바꾸기 위해 DNS 를 사용한다.
  정상적인 경우 DNS 는 UDP를 사용하지만 답신이 클 때는 TCP 답신을 사용한다.
  이러한 접속 요구를 막게 되면 DNS 결과를 신뢰할 수 없다.


  DNS 요청을 항상 똑같은 외부 머신이 처리하게 하고 있다면 ( /etc/resolv.conf
  에서 `nameserver' 설정을 해주거나 캐슁 네임서버를 전달 모드로 사용하고
  있는 경우 ) 바로 그 머신에 대해서만 `domain' 포트로의 TCP 접속을 허용하면
  된다.


  4.2.3.  FTP 에 관련한 악몽


  또 하나의 고전적인 문제가 FTP 이다.  FTP에는 두 가지 "모드"가 있다.
  전통적인 것을 `active mode' 라고 부르고 근래에 도입된 것을
  `passive mode' 라고 부른다.  웹 브라우져는 기본적으로 수동 모드를 사용하고
  명령행 ftp 프로그램들은 일반적으로 능동 모드를 사용한다.


  능동 모드에서는 원격 머신이 파일을 보내고자 할 때(또는 ls 나 dir 명령의
  결과) 우선 이 쪽 지역 머신으로 TCP 연결을 시도한다.  따라서 여기서 사용하는
  TCP 접속을 막게 되면 능동 모드의 FTP 가 작동하지 않게 된다.


  만약 수동 모드를 선택할 수 있다면 좋다.  수동 모드는 자료 받기의 경우에도
  클라이언트로부터 서버로 자료 접속이 이뤄지기 때문이다.  선택권이 없다면
  1024 이상의 포트 그리고 6000과 6010 사이의 포트는 제외한 포트로 TCP 접속이
  들어오는 것에 대하여 허가하는 것이 좋다.(6000은 X 윈도우가 사용한다)



  4.3.  죽음의 핑(Ping of Death) 걸러내기


  리눅스 박스는 현재 그 유명한 죽음의 핑(Ping of Death)에 대하여 면역을 가지고
  있다.  이 핑은 비정상적으로 큰 ICMP 패킷을 보내어 TCP 스택 안에서 오버플로우
  가 일어나게 하고 따라서 수신 측에 해를 끼치도록 되어 있다.


  죽음의 핑에 면역 기능을 갖지 않은 리눅스 박스를 보호하기 위해서는 간단히
  ICMP 조각을 막아버리면 그만이다.  정상적인 ICMP 패킷은 조각 나누기가 필요할
  정도로 크지 않기 때문에 거대한 핑 말고 다른 부분에 영향을 없을 것이다.
  본인이 듣기로는(확실한 것은 아니다) 몇몇 시스템의 경우 정상 크기 이상의
  ICMP 패킷의 마지막 조각만으로도 시스템이 망쳐질 수 있기 때문에 첫번째 조각만
  막는 것은 권하지 않는다.


  4.4.  티어드롭(Teardrop)과 봉크(Bonk) 걸러내기


  티어드롭과 봉크는 겹치기 조각(overlapping fragment) 방법을 사용하는 두 가지
  공격 방법으로서 주로 마이크로소프트 윈도우즈 NT 머신에 사용된다.
  여러분의 리눅스 라우터가 조각모으기를 하게 하거나 이 공격에 무력한 윈도우즈
  NT와 같은 머신에 조각이 가지 못하도록 막으면 된다.


  4.5.  조각 폭탄(Fragment Bombs) 걸러내기


  Some less-reliable TCP stacks are said to have problems dealing with
  몇몇 신뢰성없이 구현되어 있는 TCP 스택은 전체 조각을 받지 못한 상태에서
  거대한 양의 조각을 처리할 때 문제를 일으킨다고 한다.  리눅스에는 이러한
  문제가 없다.  조각을 그냥 걸러내버리거나(이 경우에는 정상적인 패킷도 걸러
  내는 효과를 갖는다) 커널을 컴파일할 때 `IP: always defragment' 에서 Y 라고
  한다.  (물론 리눅스 박스가 모든 패킷이 드나드는 유일한 통로일 때만 유효)


  4.6.  방화벽 규칙 변경하기


  방화벽 규칙을 변경하는데 있어 타이밍에 관련된 문제가 있다.  만약 주의하지
  않는다면 규칙을 변경하는 도중 패킷이 지나가도록 놓치는 수가 있다.
  이를 막는 가장 간단한 방법은 다음과 같다.



       # ipchains -I input 1 -j DENY
       # ipchains -I output 1 -j DENY
       # ipchains -I forward 1 -j DENY

       ... 규칙을 변화시킨다 ...

       # ipchains -D input 1
       # ipchains -D output 1
       # ipchains -D forward 1
       #



  변경하는 동안은 모든 패킷을 버리도록 한다.


  만약 한 개의 사슬에 대해서만 변경 작업을 하고 있다면 새로운 규칙으로 새로운
  사슬을 만들어 채운 뒤 교체한 예전 사슬을 가리키고 있는 규칙이 새롭게 만들
  사슬을 가리키도록 교체(`-R')할 수 있다.  그 다음 예전의 사슬을 삭제한다.
  이렇게 하여 교체 작업이 한 번에 이뤄지게 할 수 있다.


  4.7.  보다 나은 계획들


  본인이 작성한 코딩한 `libfw'라는 이름의 사용자 영역 라이브러리를
  소스 코드에 포함시켜 두었다.  IP 사슬 1.3 의 기능을 사용하여 패킷을 사용자
  영역으로 복사해준다.(IP_FIREWALL_NETLINK 옵션을 사용해야 함)


  이 라이브러리를 사용하여 `상태유지 검사(stateful inspection)'와 같은 것을
  사용자 영역에서 구현할 수 있다.(본인은 상태 유지 검사보다는 동적 방화벽
  이라는 용어를 더 선호한다)
  또 다르게 응용할 수 있는 좋은 분야는 사용자별로 패킷을 제어하는 것인데
  이는 사용자 영역의 데몬 살펴보기를 하면 가능하다.  이 작업은 매우 쉬운
  작업이다.


  방화벽의 `표시(mark)' 기능은 많이 사용되고 있지 못한 상태이다.
  패킷의 우선권을 간단히 조절할 수 있도록 서비스 품질(Quality of Service)
  코드에 대한 순위를 나타내도록 사용할 수 있다.


  4.8.  앞으로의 보강 계획


  앞으로는 모든 방화벽 제어를 /proc/sys/net/ipv4 밑에 두고자 한다.
  스크립트를 사용하여 관리하기 쉽고 일반적으로 더 깨끗하게 보이기 때문이다.


  사용자 영역으로부터 특정 사슬로 패킷을 다시 주입하는 좋은 방법을 고안하고
  있다.  이렇게 되면 libfw 설계가 좀 더 간단해진다.



  5.  별첨 - ipchains과 ipfwadm 간의 차이점



  변화된 것 중 일부는 커널 변화의 결과이며 다른 부분은 ipchains와 ipfwadm의
  차이로부터 유래한 것이다.


  1. 많은 인수들이 다시 재배치되었다:  대문자는 명령을 나타내며 소문자는
     옵션을 나타내는데 사용되고 있다.

  2. 임의의 사슬을 만들 수 있으며 내장 사슬이라 할 지라도 플래그 방식이
     아니라 이름을 갖고 있다.(예. `-I'라고 하지 않고 `input'이라고 부름)

  3. `-k' 옵션이 사라졌다: 대신 `! -y' 를 사용하라.

  4. `-b' 옵션은 실제로 두 개의 규칙을 삽입하거나 추가하거나 삭제한다.
     하나로 된 `앙방향' 규칙을 만들지 않는다.

  5. 두 가지를 점검하기 위해(양 방향에 대하여 한 번씩) `-C'에 `-b' 옵션을
     사용할 수 있다.

  6. `-l'에 사용하던 `-x' 옵션이 `-v'로 교체되었다.

  7. 여러 개의 발신지 포트는 더 이상 지원되지 않는다.  포트 범위 앞에 부정을
     하는 방법으로 대신할 수 있으리라 생각한다.

  8. 인터페이스는 오로지 이름으로만 명시할 수 있다.(주소는 안됨)
     구식 방법이 2.1 커널 시리즈에서 말없이 변화되어 있다.

  9. 조각을 검사하며 자동으로 허용하지는 않는다.

  10.
     명시적인 회계 사슬은 없다.

  11.
     IP 에 대한 모든 프로토콜을 지원한다.

  12.
     SYN, ACK 매칭에 대한 구식 방법(TCP 아닌 패킷에 대해서는 무시함)이
     바뀌었따.  SYN 옵션은 TCP 관련 규칙이 아닌 곳에서는 사용할 수 없다.

  13.
     카운터는 x86 에서 32 비트가 아니라 64 비트이다.

  14.
     반대 옵션이 지원된다.

  15.
     ICMP 코드가 지원된다.

  16.
     와일드 카드 인터페이스가 지원된다.

  17.
     TOS 처리에서 정상성 점검이 이뤄진다.  예전 커널 코드에서는 `0 이어야 함
     (Must Be Zero)' TOS 비트를 (불법적으로) 처리하는 경우 그냥 아무 말 없이
     무시했다.  ipchains 는 기타 다른 불법적인 접근의 경우와 마찬가지로 에러를
     발생시킨다.


  5.1.  간략한 참조 도표


  [ 주로 명령 인수는 대문자이고 옵션 인수는 소문자로 되어 있다]


  한 가지 잘 알아둬야 할 것으로서 매스커레이딩은 `-j MASQ' 라고 적는다.
  `-j ACCEPT'와는 전혀 다른 것으로서 ipfwadm과 같이 단순한 2차적 기능으로
  간주하지 않는다.


  ================================================================
  | ipfwadm      | ipchains              | 주의 사항
  ----------------------------------------------------------------
  | -A [both]    | -N acct               | `acct' 사슬을 만들고
  |              |& -I 1 input -j acct   | 들어오고 나가는 패킷이
  |              |& -I 1 output -j acct  | 이 사슬을 통과하도록
  |              |& acct                 | 한다.
  ----------------------------------------------------------------
  | -A in        | input                 | 목표가 없는 규칙
  ----------------------------------------------------------------
  | -A out       | output                | 목표가 없는 규칙
  ----------------------------------------------------------------
  | -F           | forward               | [사슬]로 사용하라.
  ----------------------------------------------------------------
  | -I           | input                 | [사슬]로 사용하라.
  ----------------------------------------------------------------
  | -O           | output                | [사슬]로 사용하라.
  ----------------------------------------------------------------
  | -M -l        | -M -L                 |
  ----------------------------------------------------------------
  | -M -s        | -M -S                 |
  ----------------------------------------------------------------
  | -a policy    | -A [chain] -j POLICY  | (-r 와 -m 참고).
  ----------------------------------------------------------------
  | -d policy    | -D [chain] -j POLICY  | (-r 와 -m 참고).
  ----------------------------------------------------------------
  | -i policy    | -I 1 [chain] -j POLICY| (-r 와 -m 참고).
  ----------------------------------------------------------------
  | -l           | -L                    |
  ----------------------------------------------------------------
  | -z           | -Z                    |
  ----------------------------------------------------------------
  | -f           | -F                    |
  ----------------------------------------------------------------
  | -p           | -P                    |
  ----------------------------------------------------------------
  | -c           | -C                    |
  ----------------------------------------------------------------
  | -P           | -p                    |
  ----------------------------------------------------------------
  | -S           | -s                    | 포트 하나 또는 범위만
  |              |                       | 유효. 다수 지정 불가
  ----------------------------------------------------------------
  | -D           | -d                    | 포트 하나 또는 범위만
  |              |                       | 유효. 다수 지정 불가
  ----------------------------------------------------------------
  | -V           | <none>                | -i [이름]을 사용할 것.
  ----------------------------------------------------------------
  | -W           | -i                    |
  ----------------------------------------------------------------
  | -b           | -b                    | 실제로는 2 개의 규칙 생성
  ----------------------------------------------------------------
  | -e           | -v                    |
  ----------------------------------------------------------------
  | -k           | ! -y                  | -p tcp 를 꼭 같이 사용
  |              |                       | 해야 한다.
  ----------------------------------------------------------------
  | -m           | -j MASQ               |
  ----------------------------------------------------------------
  | -n           | -n                    |
  ----------------------------------------------------------------
  | -o           | -l                    |
  ----------------------------------------------------------------
  | -r [redirpt] | -j REDIR [redirpt]    |
  ----------------------------------------------------------------
  | -t           | -t                    |
  ----------------------------------------------------------------
  | -v           | -v                    |
  ----------------------------------------------------------------
  | -x           | -x                    |
  ----------------------------------------------------------------
  | -y           | -y                    | -p tcp 를 꼭 같이 사용
  |              |                       | 해야 한다.
  ----------------------------------------------------------------




  5.2.  ipfwadm 명령 번역의 예


  Old command: ipfwadm -F  -p deny

  New command: ipchains -P forward DENY


  Old command: ipfwadm -F -a m -S 192.168.0.0/24 -D 0.0.0.0/0

  New command: ipchains -A forward -j MASQ -s 192.168.0.0/24 -d
  0.0.0.0/0


  Old command: ipfwadm -I -a accept -V 10.1.2.1 -S 10.0.0.0/8 -D
  0.0.0.0/0

  New command: ipchains -A input -j ACCEPT -i eth0 -s 10.0.0.0/8 -d
  0.0.0.0/0

  (Note that there is no equivalent for specifying interfaces by
  (주의: 주소를 이용하여 인터페이스를 명시하는 방법은 없다.
   인터페이스 이름만을 사용하라.  이 머신의 예에서 10.1.2.1 은
   eth0 에 해당한다.)


  6.  별첨 - `ipfwadm-wrapper' 스크립트 사용하기


  `ipfwadm-wrapper' 쉘 스크립트는 ipfwadm 2.3a 와 하위 호환성을 갖추기 위해
  만든 ipfwadm 에 대한 플러그-인 교체용이다.


  다룰 수 없는 유일한 기능은 `-V' 옵션이다.  이 옵션이 사용되면 경고 메시지가
  출력될 것이다.  `-W' 옵션을 사용하면 `-V' 옵션을 무시한다.  `-W' 옵션이
  없는 경우에는 `ifconfig' 명령을 사용하여 주소와 연관되어 있는 인터페이스
  이름을 찾으려고 시도한다.  만약 실패한다면(예를 들어 인터페이스가 다운되어
  있는 상태인 경우) 에러 메시지를 내보이고 종료한다.


  `-V' 를 `-W' 로 바꾸거나 스크립트의 표준 출력을 /dev/null 로 리다이렉트
  하여 경고 메시지를 피할 수 있다.


  스크립트에서 실수한 것을 발견하거나 실제 ipfwadm 과 스크립트 간의 차이점이
  있다면 버그 보고를 꼭 해주기 바란다 :
  메일 주소는 Paul.Russell@rustcorp.com.au 이며 주제란에 BUG-REPORT 라고
  적어 보내주길 바란다.  여러분이 갖고 있는 ipfwadm 구버전(`ipfwadm -h')과
  사용 중인 ipchains 의 버전(`ipchains --version'), ipfwadm 랩퍼 스크립트의
  버전(`ipfwadm-wrapper --version')을 나열하고 또한 `ipchains-save'의 출력도
  보내주었으면 한다.  우선 감사의 말을 하고 싶다.


  ipchains와 ipfwadm-wrapper 스크립트를 섞어쓰는 것은 좋지 않으나 여러분의
  자유이다.


  7.  별첨 - 감사의 말


  Many thanks have to go to Michael Neuling, who wrote the first
  releasable cut of the Generic IP Chains code while working for me.
  Public apologies for nixing his result-caching idea, which Alan Cox
  later proposed and I have finally begun implementing, having seen the
  error of my ways.


  Thanks to Alan Cox for his 24-hour EMail tech support, and
  encouragement.


  Thanks to all the authors of the ipfw and ipfwadm code, especially Jos
  Vos.  Standing on the shoulders of giants and all that...  This
  applies to Linus Torvalds and all the kernel and userspace hackers as
  well.


  Thanks to the diligent beta testers and bughunters, especially:

     Jordan Mendelson
        ICMP code suggestion.

     Shaw Carruthers
        For various ipchains and ipfwadm-wrapper bugfixes.

     Kevin Moule
        For a patch for glibc.

     Dr. Liviu Daia
        For documentation fixes and printk fix.

     Helmut Adams
        For fixing a race condition in v. large chains.

     Franck Sicard
        For masquerading listing fix.

     Kevin Littlejohn
        For ipchains-save bugfix with destination ports.

     Matt Kemner
        For more documentation fixes.

     John D. Hardin
        For `ipchains -X' suggestion.

     Alexey Kuznetsov
        For noticing a typo which stop marks being initialised.

     Ricardo Kustner
        For fixing my leftover debug messages in 2.0.33.

 

http://www.hackerschool.org/HS_Boards/data/Lib_network2/IPCHAINS_HOWTO.txt에서발췌함