FreeBSD pf 설치 문서


================================
README.ko
/usr/ports/security/pf
================================


Kernel module pf for FreeBSD 5

설치에 앞서 다음의 URL에서 가장 최근의 snapshot을 사용하는지 먼저
확인 하시기 바랍니다.

http://pf4freebsd.love2party.net/index.html
위의 URL에서 가장 최근의 snapshot과 알려진 문제점을 확인할 수 있습니다.
pf는 /usr/ports/security/pf에서도 설치할 수 있습니다.

1. pf
pf는 OpenBSD의 packet filter로서 ipfilter의 license 문제가 제기 되었을때
OpeBSD진영에서는 이에 반대하여 독자적인 packet filter를 만든데서 유래합니다.
(http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/ipf/Attic/ipf.c)
초창기의 pf는 ipfilter와 거의 비슷한 기능을 지원했지만 지금은 많은 부분이
다르고 고가의 상용 방화벽에서도 보기 어려운 다양한 기능을 제공합니다.
pf의 syntax는 기본적으로는 ipfilter와 많은 부분이 유사하지만 추가적인 기능을
위해서 몇몇은 새로이 추가되었습니다.
pf는 FreeBSD의 ipfw에 비해서 다음과 같은 장점을 가지고 있습니다.

        1. built-in macro expansion
        2. Table support
        3. built-in NAT
        4. defeat NAT detection
        5. direct logging via pflog interface
        6. packet normalization
        7. state modulation
        8. powerful state tracking
        9. automatic rule optimization
        10. Queueing with ALTQ
        11. Load balancing
        12. packet tagging
        13. SYN proxy
        14. passive OS fingerprinting

FreeBSD의 또 다른 방화벽인 ipfilter에 대해서는 다음과 같은 장점을 가지고
있습니다.

        1. built-in macro expansion
        2. defeat NAT detection
        3. Table support
        4. automatic rule optimization
        5. Queueing with ALTQ
        6. packet tagging
        7. SYN proxy
        8. passive OS fingerprinting

OpenBSD의 pf에 관한 자료는 다음 URL을 참조하거나 포함된 man document를 보시기
바랍니다.
http://www.openbsd.org/faq/faq6.html#PF
http://www.inebriated.demon.nl/pf-howto/
http://www.benzedrine.cx/pf.html
(pf(4), pf.conf(5), pflog(4), pfsync(4), pfctl(8), spamd(8), spamd-setup(8),
spamd.conf(6), ftp-proxy(8), authpf(8), tcpdump(8), pftop(8))

2. 포팅 이유
FreeBSD에는 이미 ipfw(ipfw2포함), ipfilter의 두개의 방화벽이 이미 존재하고
있습니다. 대부분의 OS에서 두가지 이상의 방화벽을 동시에 제공하는 경우는 정말
찾아 보기 힘듭니다. FreeBSD사용자는 행복한 고민을 하게 됩니다. 두 프로그램 모두
장단점을 가지고 있고 베이스 시스템의 버젼이 올라가면 이에 따라서 꾸준히 버젼업이
이루어 지고 있습니다.
아는게 병이라고 우연한 기회에 pf의 다양한 기능을 접하고는 ipfw/ipfilter의 기능들
만으로는 저 자신의 욕구를 충족시키기에는 만족스럽지 못했습니다. 실력있는 누가
FreeBSD로 포팅해 주기만을 기다리다가 지쳐서 직접 포팅하게 되었습니다.
사실 FreeBSD Core 진영에서는 OpenBSD의 pf와 같은 새로운 방화벽을 merge할 생각은
없는것 같습니다. Handbook 에서도 ipfw의 사용을 권장하고 있고, 커널 소스의 많은
부분에서 ipfw 지원을 위한 노력이 반영되어 있습니다.
(이 부분이 OpenBSD에서 FreeBSD의 ipfw를 가져오지 않고 새로 pf를 만든 가장 큰
이유중의 하나라고 합니다. 커널에 너무 의존적이라서...)

3. 포팅시의 기술적 제약
OpenBSD의 pf를 FreeBSD로 가져오는데는 mbuf, memory, timer등 많은 부분에서
문제가 있었습니다. BSD계열들이 사용상의 인터페이스는 비슷한데 내부적으로는
너무나도 많이 다르다는것을 뼈저리게 경험했습니다. 특히 다음 부분은 제대로
처리되었는지 저의 능력부족으로 확신할 수 없습니다.

1. pf의 pool(9)을 이용한 memory관리
        이 부분은 zone(9)을 이용하여 최대한 비슷하게 하려고 했지만 water mark
        부분이 zone(9)에 없기 때문에 완벽하지는 못합니다.
2. pf의 single thread 동작방식
        FreeBSD 5.X은 multiple kernel thread로 동작합니다.
        현재 가장 기본적인 locking만 수행합니다.
3. rtalloc()/ip_output()/ip6_output()과 같은 부분의 기능상의 차이
4. hook_establish(9)를 이용한 interface 주소 변경감시
        OpenBSD의 pf는 hook_establish(9)를 이용해서 interface의 주소가 변경되면
        이를 자동으로 감지하여 룰을 변경하도록 되어 있습니다. 
        FreeBSD는 hook_establish(9)가 없기 때문에 이 부분은 무시되었습니다.
        이를 해결하기 위해서 patches 디렉토리에 시험적인 kernel patch가 있습니다.
        (patches/README를 참조하십시요.)
5. thread-safe pfil(9) 인터페이스 사용
        Max Laier의 노력으로 pfil(9)은 이제 thread-safe하고 base system에 commit
        되었습니다. 이전과 달리 더 이상 pfil(9)의 제약은 존재하지 않습니다.
6. H/W checksum offloads 지원
        FreeBSD는 em(4), gx(4), lge(4), nge(4), ti(4), xl(4), fxp(04) driver에서
        checksum offload기능을 지원합니다. 현재 xl(4)은 제대로 동작하는
        것으로 알려져 있습니다. 만일 위의 카드중 하나를 사용한다면 알려주시기
        바랍니다. 사용중인 카드가 H/W checksum offloads 지원하는지 확인하려면
        다음과 같이 하십시요.

        #ifconfig -a
        ...
        xl0: flags=9843<UP,BROADCAST,RUNNING,SIMPLEX,LINK0,MULTICAST> mtu 1500
                options=b<RXCSUM,TXCSUM,VLAN_MTU>
                inet 192.168.10.9 netmask 0xffffff00 broadcast 192.168.10.255
                inet6 fe80::204:76ff:fed9:bdb7%xl0 prefixlen 64 scopeid 0x1
                ether 00:04:76:d9:bd:b7
                media: Ethernet autoselect (100baseTX <full-duplex>)
                status: active
        카드가 H/W checksum offloads를 지원한다면 RXCSUM, TXCSUM이 같이 표시됩니다.

4. pf for FreeBSD의 현재 상태
전체적으로는 IPv6와 ALTQ을 포함하여 모든 필요한 부분이 다 성공적으로 컴파일
되었고 시험이 남아 있습니다. FreeBSD 5.X에서 ALTQ지원은 아직 공식적으로 나와
있지 않고 제한적인 network driver만 지원합니다. ALTQ지원에 관한 보다 자세한
정보는 README.ALTQ를 참조하시기 바랍니다. 물론 ALTQ지원을 뺀 설정도 동시에
지원하기 때문에 ALTQ가 필요없는 분이나 아직 ALTQ에서 지원되지 않는 network
driver를 사용하는 분도 사용할 수 있습니다.
Version 1.0은 OpenBSD 3.3 pf에 기반하고 있고 Version 1.5x는 곧 발표될
OpenBSD-3.4 pf에 기반을 두고 있습니다. 그러므로 OpenBSD-current pf가 변경되면
이에 따라서 같이 버젼업이 이루어 지고 있습니다.
ALTQ와 IPv6 지원부분은 충분히 검증되지 않았습니다.

5. pf for FreeBSD의 구성

        1. pflog.ko : pflog interface 커널 모듈
        2. pfsync.ko : pfsync interface 커널 모듈
        3. pf.ko : packet filter 커널 모듈
        4. pfctl : userland packet filter control program
        5. pflogd : pf 로그데몬
        6. authpf : authenticating gateway user shell
        7. ftp-proxy : ftp proxy server
        8. pftop : top(1)형식으로 pf의 상태표시 tool(ipfstat -t와 유사함)
        9. libpcap : pcap library(pflogd과 tcpdump에서 사용)
        10. tcpdump : pflogd에 의해 저장된 로그확인 프로그램
        11. spamd : spam deferral daemon
        12. spamd-setup : parse and load file of spammer addresses
        13. pfaltq.ko : ALTQ kernel module(experimental)

이중 pflogd와 tcpdump는 libpcap을 수정해야 동작합니다. libpcap, tcpdump모두
FreeBSD에 포함되어 있지만 설치의 편리를 위해서 첨부에는 같이 포함했습니다.

6. 설치 및 실행 
본 프로그램은  현재 FreeBSD 5.0/5.1과 FreeBSD 5-current를 동시에 지원합니다.
4.X는 지원하지 않습니다만 약간만 수정하면 4.X에서도 수행가능할 것으로 생각됩니다.
(4.X로의 변환계획은 없습니다.)
커널 설정파일에는 다음의 옵션과 디바이스가 지정되어 있어야 합니다.

        1. device bpf
        2. options INET
        3. options INET6
        4. options PFIL_HOOKS
        5. options RANDOM_IP_ID

pf for FreeBSD는 커널모듈로 구성되어 있지만 pfil(9) 인터페이스를 사용하기
때문에 "options PFIL_HOOKS"부분이 반드시 들어가 있어야 합니다. 이 부분이
없는 상태에서 실행하면 실행되지 않습니다. pfil(9) 인터페이스의 제약으로 이
부분이 빠져 있다는 것을 실행시에 판단하기가 어렵습니다.
또한 pf는 NAT를 사용하는지 검사할 수 있는 기능을 무력화 시키는 기능이 들어가
있습니다. 이 부분을 사용하기 위해서는 "options RANDOM_IP_ID"가 커널에 들어가
있어야 합니다. 또 다른 방법으로는 make시에 다음과 같이 직접 옵션을 주어서 pf에
포함된 함수를 사용하게 할 수도 있습니다.

make WITH_RANDOM_ID=yes

위의 마지막 두 옵션은 generic kernel에 없기 때문에 custom kernel을 새로
만들어야 합니다. 커널빌드는 다음을 참조 하십시요.

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig.html

그리고 가능하면 DDB, INVARIANTS 같은 부분이 들어가 있는것이, 시스템이  잘못
되었을 경우, 더 이상의 문제를 발생하기 전에 막을 수 있습니다. 설치는 시스템
파일이 있는 위치에 설치하지 않도록 하고 빌드되면 임의의 디렉토리로 복사한 후
시험하면 되겠습니다.

#su - (커널은 이미 options PFIL_HOOKS가 들어가 있다고 가정하겠습니다.)
#gzip -dc pf_freebsd_1.5x.tar.gz|(cd /tmp; tar xf -)
#cd /tmp/pf_freebsd_1.5x
#make (또는 make WITH_RANDOM_ID=1 커널에 "options RANDOM_IP_ID"가 없는 경우)
#mkdir -p /tmp/pf_test
#cp /tmp/pf_freebsd_1.5x/pf/pf.ko /tmp/pf_test/
#cp /tmp/pf_freebsd_1.5x/pflog/pflog.ko /tmp/pf_test/
#cp /tmp/pf_freebsd_1.5x/pfsync/pfsync.ko /tmp/pf_test/
#cp /tmp/pf_freebsd_1.5x/pfctl/pfctl /tmp/pf_test/
#cp /tmp/pf_freebsd_1.5x/pf.conf /tmp/pf_test/
#cp /tmp/pf_freebsd_1.5x/pflogd/pflogd /tmp/pf_test/
#cp /tmp/pf_freebsd_1.5x/tcpdump/tcpdump /tmp/pf_test/

만일 endian이 다른 시스템이나 64비트 환경(Tier1 Alpha, Sparc64)에서 시험한다
면 regress test를 먼저 해 보시기 바랍니다. regress프로그램은 regress 디렉토리
에 있습니다. Version 1.0 또는 0.x를 사용하다 upgade했다면 먼저 이전 log파일을
삭제한 후 시험하십시요.

#rm /var/log/pflog
#cd /tmp/pf_test
#kldload ./pflog.ko
#kldload ./pfsync.ko
#ifconfig pflog0 up
#ifconfig pfsync0 up
#./pflogd
#kldload ./pf.ko
#./pfctl -e -f ./pf.conf
필요시 pf.conf에서 필요한 룰을 설정하도록 합니다.

로그 파일은 /var/log/pflog에 기록됩니다. pf의 로그는 pcap binary data이기 때문에
빌드시 위에서 생성된 tcpdump를 이용해야 볼 수 있습니다.
#./tcpdump -n -e -ttt -r /var/log/pflog

더 이상 커널 모듈이 필요 없다면 kldunload로 모듈을 제거할 수 있습니다.
#killall pflogd
#ifconfig pfsync0 down
#ifconfig pflog0 down
#kldunload pf
#kldunload pflog
#kldunload pfsync

pf for FreeBSD의 문제점을 발견했다면 다음의 메일 주소로 알려 주시면 보다 안정된
pf를 만드는데 많은 도움이 될것 입니다.
<report@pf4freebsd.love2party.net>
만일 문제점이 발견되면 문제를 해결할 수 있도록 충분한 정보를 보내주십시요.
        . FreeBSD version
        . FreeBSD pf version
        . netowork 환경
        . rule set 전체

7. 알려진 문제점
1. bridge상서 pf를 사용한다면 patches 디렉토리를 참조하십시요. FreeBSD bridge
    의 문제로 인해서 pf는 inbound traffic만 검사할 수 있습니다.(i.e. block
    in on fxp0 all) 따라서 state를 만들수 없기 때문에 ipfw처럼 state없이
    사용해야 합니다.
2. pflogd가 실행된 상태에서 pflog.ko 모듈을 제거할 경우 문제가 발생합니다.
    pflogd를 중지한 다음 pflog.ko 모듈을 제거해야 합니다.
3. 수행중 interface 주소가 바뀔 경우 이를 자동으로 감지하지 못합니다. 그러므로
    주소 변경시 사용자가 수동으로 룰을 새로 설정해야 합니다.
    patches디렉토리에는 이를 가능하게 하는 시험적인 kernel patch가 있습니다.
4. 모듈을 제거할 때는 모듈로드시와 반대 순서로 제거해야 합니다. 어떤 경우에는
    모듈로드와 모듈제거를 반복할 경우 시스템 패닉이 올 수 있습니다.
5. 시스템 디렉토리에 모든 커널 모듈을 설치했을 경우 pf.ko모듈을 올리면 필요한
    모든 다른 모듈이 자동적으로 로드됩니다. 반면에 모듈을 하나 하나 지정해서
    로드했을 경우 모듈제거시에 모듈간의 의존성을 무시하고 모듈제거가 가능합니다.
    이 경우 시스템의 패닉을 유발할 수 있습니다.

8. 시험
** 버전 1.5x 프로그램은 아직 베타단계의 프로그램입니다. 따라서 시험시 데이터의
    손실이나 시스템의 패닉등이 있을 수 있습니다.
    
        필요한 시험
        1. test under VLAN, bridge environments
        2. test for IPv6
        3. test under LP64 environments(Tier1 Alpha, Sparc64)
        4. test for ALTQ

9. 앞으로의 계획
        1. Bug fix
        2. Make pf work on bridge with stateful inspection.
        3. Propose changes to FreeBSD to enable additional features.
        4. Try to get pf into the FreeBSD base system.
        5. ALTQ synchronization

사용시에 발생한 문제점이나 개선점, 패치등이 있으면 알려주시면 최대한
반영하도록 하겠습니다.

http://pf4freebsd.love2party.net/

편용헌(yongari@kt-is.co.kr)
Max Laier(max@love2party.net)

출처 - 
http://blog.paran.com/coacoma/4948580
 
Posted by linuxism
,