亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3781 | 回復(fù): 0
打印 上一主題 下一主題

PF防火墻詳解 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2010-01-11 20:04 |只看該作者 |倒序?yàn)g覽

PF防火墻



PF ( 全稱:Packet Filter ) --- 包過濾


UNIX
LIKE系統(tǒng)上進(jìn)行
TCP
/
IP
流量過濾和
網(wǎng)絡(luò)地址轉(zhuǎn)換
的軟件系統(tǒng)。PF同樣也能提供TCP/IP流量的整形和控制,并且提供帶寬控制和數(shù)據(jù)包優(yōu)先集控制。
PF最早是由
Daniel Hartmeier
開發(fā)的,現(xiàn)在的開發(fā)和維護(hù)由
Daniel

openbsd
小組的其他成員負(fù)責(zé)。
目錄

  • 基本配置


  • 列表和宏





  • 包過濾


  • 網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)


  • 基本配置


  • 列表和宏





  • 包過濾


  • 網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)


  • 重定向 (端口轉(zhuǎn)發(fā))


  • 規(guī)則生成捷徑


  • 高級配置


  • 流量整形


  • 錨定和命名規(guī)則集


  • 地址池和負(fù)載均衡


  • 數(shù)據(jù)包標(biāo)記


  • 日志


  • 性能


  • 研究 FTP


  • 驗(yàn)證: 用Shell 進(jìn)行網(wǎng)關(guān)驗(yàn)證


  • 實(shí)例:家庭和小型辦公室防火墻


  • 參考資料

    [顯示全部]


    編輯本段
       
    回目錄
       
    PF防火墻 - 基本配置


    激活

    要激活pf并且使它在啟動(dòng)時(shí)調(diào)用配置文件,編輯/etc/rc.conf文件,修改配置pf的一行:
    pf=YES
    重啟
    操作系統(tǒng)
    讓配置生效。
    也可以通過
    pfctl
    程序啟動(dòng)和停止pf
    # pfctl -e
    # pfctl -d
    注意這僅僅是啟動(dòng)和關(guān)閉PF,實(shí)際它不會載入規(guī)則集,規(guī)則集要么在系統(tǒng)啟動(dòng)時(shí)載入,要在PF啟動(dòng)后通過命令單獨(dú)載入。
    配置
    系統(tǒng)引導(dǎo)到在
    rc腳本
    文件運(yùn)行PF時(shí)PF從/etc/pf.conf文件載入配置規(guī)則。注意當(dāng)/etc/pf.conf文件是默認(rèn)配置文件,在系統(tǒng)調(diào)用rc腳本文件時(shí),它僅僅是作為文本文件由pfctl裝入并解釋和插入pf的。對于一些應(yīng)用來說,其他的規(guī)則集可以在系統(tǒng)引導(dǎo)后由其他文件載入。對于一些設(shè)計(jì)的非常好的unix程序,PF提供了足夠的靈活性。
    pf.conf 文件有7個(gè)部分:
    * 宏:              用戶定義的
    變量
    ,包括
    IP
    地址,接口名稱等等
    * 表:              一種用來保存IP地址列表的結(jié)構(gòu)
    * 選項(xiàng):          控制PF如何工作的變量
    * 整形:          重新處理
    數(shù)據(jù)包
    ,進(jìn)行正;
    碎片整理
    * 排隊(duì):          提供帶寬控制和數(shù)據(jù)包優(yōu)先級控制.
    * 轉(zhuǎn)換:          控制網(wǎng)絡(luò)地址轉(zhuǎn)換和數(shù)據(jù)包重定向.
    * 過濾規(guī)則:   在數(shù)據(jù)包通過接口時(shí)允許進(jìn)行選擇性的過濾和阻止

    除去宏和表,其他的段在配置文件中也應(yīng)該按照這個(gè)順序出現(xiàn),盡管對于一些特定的應(yīng)用并不是所有的段都是必須的。
    空行會被忽略,以#開頭的行被認(rèn)為是注釋.


    # pfctl -sa控制

    引導(dǎo)之后,PF可以通過pfctl程序進(jìn)行操作,以下是一些例子:
    # pfctl -f /etc/pf.conf 載入 pf.conf 文件
    # pfctl -nf /etc/pf.conf 解析文件,但不載入
    # pfctl -Nf /etc/pf.conf 只載入文件中的
    NAT
    規(guī)則
    # pfctl -Rf /etc/pf.conf 只載入文件中的過濾規(guī)則
    # pfctl -sn 顯示當(dāng)前的NAT規(guī)則
    # pfctl -sr 顯示當(dāng)前的過濾規(guī)則
    # pfctl -ss 顯示當(dāng)前的狀態(tài)表
    # pfctl -si 顯示過濾狀態(tài)和計(jì)數(shù)
    # pfctl -sa 顯示任何可顯示的
    完整的命令列表,請參閱pfctl的man手冊頁。
    編輯本段
       
    回目錄
       
    PF防火墻 - 列表和宏
    列表
    一個(gè)列表允許一個(gè)規(guī)則集中指定多個(gè)相似的標(biāo)準(zhǔn)。例如,多個(gè)
    協(xié)議
    ,
    端口號
    ,
    網(wǎng)絡(luò)地址
    等等。因此,不需要為每一個(gè)需要阻止的IP地址編寫一個(gè)過濾規(guī)則,一條規(guī)則可以在列表中指定多個(gè)IP地址。列表的定義是將要指定的條目放在{ }大括號中。
    當(dāng)pfctl在載入規(guī)則集碰到列表時(shí),它產(chǎn)生多個(gè)規(guī)則,每條規(guī)則對于列表中的一個(gè)條目。例如:
    block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any
    展開后:
    block out on fxp0 from 192.168.0.1 to any
    block out on fxp0 from 10.5.32.6 to any

    多種列表可以在規(guī)則中使用,并不僅僅限于過濾規(guī)則:
    rdr on fxp0 proto tcp from any to any port { 22 80 } -> \
    192.168.0.6
    block out on fxp0 proto { tcp udp } from { 192.168.0.1, \
    10.5.32.6 } to any port { ssh telnet }

    注意逗號在列表?xiàng)l目之間是可有可無的。



    是用戶定義變量用來指定IP地址,端口號,接口名稱等等。
    宏可以降低PF規(guī)則集的復(fù)雜度并且使得維護(hù)規(guī)則集變得容易。
    宏名稱必須以字母開頭,可以包括字母,數(shù)字和下劃線。宏名稱不能包括保留關(guān)鍵字如:
    pass, out, 以及 queue.
    ext_if = "fxp0"
    block in on $ext_if from any to any
    這生成了一個(gè)宏名稱為ext_if. 當(dāng)一個(gè)宏在它產(chǎn)生以后被引用時(shí),它的名稱前面以$字符開頭。
    宏也可以展開成列表,如:
    friends = "{ 192.168.1.1, 10.0.2.5, 192.168.43.53 }"
    宏能夠被重復(fù)定義,由于宏不能在引號內(nèi)被擴(kuò)展,因此必須使用下面得語法:
    host1 = "192.168.1.1"
    host2 = "192.168.1.2"
    all_hosts = "{" $host1 $host2 "}"

    宏 $all_hosts 現(xiàn)在會展開成 192.168.1.1, 192.168.1.2.
    編輯本段
       
    回目錄
       
    PF防火墻 - 表


    簡介

    表是用來保存一組
    IPv4
    或者
    IPv6
    地址。在表中進(jìn)行查詢是非?斓模⑶冶攘斜硐母俚
    內(nèi)存

    cpu
    時(shí)間。由于這個(gè)原因,表是保存大量地址的最好方法,在50,000個(gè)地址中查詢僅比在50個(gè)地址中查詢稍微多一點(diǎn)時(shí)間。表可以用于下列用途:
    * 過濾,整形,NAT和重定向中的源或者目的地址.
    * NAT規(guī)則中的轉(zhuǎn)換地址.
    * 重定向規(guī)則中的重定向地址.
    * 過濾規(guī)則選項(xiàng)中 route-to, reply-to, 和 dup-to的目的地址.

    表可以通過在pf.conf里配置和使用pfctl生成。
    配置
    在pf.conf文件中, 表是使用table
    關(guān)鍵字
    創(chuàng)建出來的。下面的關(guān)鍵字必須在創(chuàng)建表時(shí)指定。
    * constant - 這類表的內(nèi)容一旦創(chuàng)建出來就不能被改變。如果這個(gè)屬性沒有指定,可以使用pfctl添加和刪除表里的地址,即使系統(tǒng)是運(yùn)行在2或者更高得安全級別上。
    * persist - 即使沒有規(guī)則引用這類表,內(nèi)核也會把它保留在內(nèi)存中。如果這個(gè)屬性沒有指定,當(dāng)最后引用它的規(guī)則被取消后內(nèi)核自動(dòng)把它移出內(nèi)存。
    實(shí)例:
    table  { 192.0.2.0/24 }
    table  const { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
    table  persist

    block in on fxp0 from { ,  } to any
    pass in on fxp0 from  to any

    地址也可以用“非”來進(jìn)行修改,如:
    table  { 192.0.2.0/24, !192.0.2.5 }
    goodguys表將匹配除192.0.2.5外192.0.2.0/24網(wǎng)段得所有地址。
    注意表名總是在符號得里面。
    表也可以由包含IP地址和網(wǎng)絡(luò)地址的文本文件中輸入:
    table  persist file "/etc/spammers"
    block in on fxp0 from  to any
    文件 /etc/spammers 應(yīng)該包含被阻塞的IP地址或者
    CIDR
    網(wǎng)絡(luò)地址,每個(gè)條目一行。以#開頭的行被認(rèn)為是注釋會被忽略。
    用 pfctl 進(jìn)行操作
    表可以使用pfctl進(jìn)行靈活的操作。例如,在上面產(chǎn)生的表中增加條目可以這樣寫:
    # pfctl -t spammers -T add 218.70.0.0/16
    如果這個(gè)表不存在,這樣會創(chuàng)建出這個(gè)表來。列出表中的內(nèi)容可以這樣:
    # pfctl -t spammers -T show
    -v 參數(shù)也可以使用-Tshow 來顯示每個(gè)表的條目內(nèi)容統(tǒng)計(jì)。要從表中刪除條目,可以這樣:
    # pfctl -t spammers -T delete 218.70.0.0/16
    指定地址
    除了使用IP地址來指定主機(jī)外,也可以使用主機(jī)名。當(dāng)主機(jī)名被解析成IP地址時(shí),IPv4和IPv6地址都被插進(jìn)規(guī)則中。IP地址也可以通過合法的接口名稱或者self關(guān)鍵字輸入表中,這樣的表會分別包含接口或者機(jī)器上(包括
    loopback地址
    )上配置的所有IP地址。
    一個(gè)限制時(shí)指定地址0.0.0.0/0 以及 0/0在表中不能工作。替代方法是明確輸入該地址或者使用宏。
    地址匹配
    表中的地址查詢會匹配最接近的規(guī)則,比如:
    table  { 172.16.0.0/16, !172.16.1.0/24, 172.16.1.100 }
    block in on dc0 all
    pass in on dc0 from  to any

    任何自dc0上數(shù)據(jù)包都會把它的源地址和goodguys表中的地址進(jìn)行匹配:
    * 172.16.50.5 - 精確匹配172.16.0.0/16; 數(shù)據(jù)包符合可以通過
    * 172.16.1.25 - 精確匹配!172.16.1.0/24; 數(shù)據(jù)包匹配表中的一條規(guī)則,但規(guī)則是“非”(使用“!”進(jìn)行了修改);數(shù)據(jù)包不匹配表會被阻塞。
    * 172.16.1.100 - 準(zhǔn)確匹配172.16.1.100; 數(shù)據(jù)包匹配表,運(yùn)行通過
    * 10.1.4.55 - 不匹配表,阻塞。
    編輯本段
       
    回目錄
       
    PF防火墻 - 包過濾


    簡介

    包過濾是在數(shù)據(jù)包通過網(wǎng)絡(luò)接口時(shí)進(jìn)行選擇性的運(yùn)行通過或者阻塞。pf檢查包時(shí)使用的標(biāo)準(zhǔn)是基于的3層(IPV4或者IPV6)和4層(
    TCP
    ,
    UDP
    ,
    ICMP
    ,
    ICMPv6
    )包頭。最常用的標(biāo)準(zhǔn)是
    源和目的地址
    ,
    源和目的端口
    ,以及
    協(xié)議

    過濾規(guī)則集指定了數(shù)據(jù)包必須匹配的標(biāo)準(zhǔn)和規(guī)則集作用后的結(jié)果,在規(guī)則集匹配時(shí)通過或者阻塞。規(guī)則集由開始到結(jié)束順序執(zhí)行。除非數(shù)據(jù)包匹配的規(guī)則包含quick關(guān)鍵字,否則數(shù)據(jù)包在最終執(zhí)行動(dòng)作前會通過所有的規(guī)則檢驗(yàn)。最后匹配的規(guī)則具有決定性,決定了數(shù)據(jù)包最終的執(zhí)行結(jié)果。存在一條潛在的規(guī)則是如果數(shù)據(jù)包和規(guī)則集中的所有規(guī)則都不匹配,則它會被通過。
    規(guī)則語法
    一般而言,最簡單的過濾規(guī)則語法是這樣的:
    action direction [log] [quick] on interface [af] [proto protocol] \
    from src_addr [port src_port] to dst_addr [port dst_port] \
    [tcp_flags] [state]

    action
    數(shù)據(jù)包匹配規(guī)則時(shí)執(zhí)行的動(dòng)作,放行或者阻塞。放行動(dòng)作把數(shù)據(jù)包傳遞給核心進(jìn)行進(jìn)一步出來,阻塞動(dòng)作根據(jù)block-policy 選項(xiàng)指定的方法進(jìn)行處理。默認(rèn)的動(dòng)作可以修改為阻塞丟棄或者阻塞返回。
    direction
    數(shù)據(jù)包傳遞的方向,進(jìn)或者出
    log
    指定數(shù)據(jù)包被pflogd( 進(jìn)行日志記錄。如果規(guī)則指定了keep state, modulate state, or synproxy state 選項(xiàng),則只有建立了連接的狀態(tài)被日志。要記錄所有的日志,使用log-all
    quick
    如果數(shù)據(jù)包匹配的規(guī)則指定了quick關(guān)鍵字,則這條規(guī)則被認(rèn)為時(shí)最終的匹配規(guī)則,指定的動(dòng)作會立即執(zhí)行。
    interface
    數(shù)據(jù)包通過的網(wǎng)絡(luò)接口的名稱或組。組是接口的名稱但沒有最后的整數(shù)。比如
    ppp

    fxp
    ,會使得規(guī)則分別匹配任何ppp或者fxp接口上的任意數(shù)據(jù)包。
    af
    數(shù)據(jù)包的地址類型,
    inet
    代表Ipv4,
    inet6
    代表Ipv6。通常PF能夠根據(jù)源或者目標(biāo)地址自動(dòng)確定這個(gè)參數(shù)。
    protocol
    數(shù)據(jù)包的4層協(xié)議:
    tcp
    udp
    icmp
    icmp6
    /etc/protocols中的協(xié)議名稱
    0~255之間的協(xié)議號
    使用列表的一系列協(xié)議.
    src_addr, dst_addr
    IP頭中的源/目標(biāo)地址。地址可以指定為:
    單個(gè)的Ipv4或者Ipv6地址.
    CIDR 網(wǎng)絡(luò)地址.
    能夠在規(guī)則集載入時(shí)通過DNS解析到的合法的域名,IP地址會替代規(guī)則中的域名。
    網(wǎng)絡(luò)接口名稱。網(wǎng)絡(luò)接口上配置的所有ip地址會替代進(jìn)規(guī)則中。
    帶有/掩碼(例如/24)的網(wǎng)絡(luò)接口的名稱。每個(gè)根據(jù)掩碼確定的CIDR網(wǎng)絡(luò)地址都會被替代進(jìn)規(guī)則中。.
    帶有()的網(wǎng)絡(luò)接口名稱。這告訴PF如果網(wǎng)絡(luò)接口的IP地址改變了,就更新規(guī)則集。這個(gè)對于使用
    DHCP
    或者撥號來獲得IP地址的接口特別有用,IP地址改變時(shí)不需要重新載入規(guī)則集。
    帶有如下的修飾詞的網(wǎng)絡(luò)接口名稱:
    o :network - 替代CIDR網(wǎng)絡(luò)地址段 (例如:192.168.0.0/24)
    o :broadcast - 替代
    網(wǎng)絡(luò)廣播地址
    (例如:192.168.0.255)
    o :peer - 替代點(diǎn)到點(diǎn)鏈路上的ip地址。
    另外,:0修飾詞可以附加到接口名稱或者上面的修飾詞后面指示PF在替代時(shí)不包括網(wǎng)絡(luò)接口的其余附加(alias)地址。這些修飾詞也可以在接口名稱在括號()內(nèi)時(shí)使用。例如:fxp0:network:0
    表.
    上面的所有項(xiàng)但使用。ǚ牵┬揎椩~
    使用列表的一系列地址.
    關(guān)鍵字 any 代表所有地址
    關(guān)鍵字 all 是 from any to any的縮寫。
    src_port, dst_port
    4層數(shù)據(jù)包頭中的源/目標(biāo)端口。端口可以指定為:
    1 到 65535之間的整數(shù)
    /etc/services中的合法服務(wù)名稱
    使用列表的一系列端口
    一個(gè)范圍:
    o != (不等于)
    o  (大于)
    o = (大于等于)
    o > (反轉(zhuǎn)范圍)
    最后2個(gè)是二元操作符(他們需要2個(gè)參數(shù)),在范圍內(nèi)不包括參數(shù)。
    o : (inclusive range)
    inclusive range 也是二元操作符但范圍內(nèi)包括參數(shù)。
    tcp_flags
    指定使用TCP協(xié)議時(shí)TCP頭中必須設(shè)定的標(biāo)記。 標(biāo)記指定的格式是: flags check/mask. 例如: flags S/SA -這指引PF只檢查S和A(SYN and ACK)標(biāo)記,如果SYN標(biāo)記是“on”則匹配。
    state
    指定狀態(tài)信息在規(guī)則匹配時(shí)是否保持。
    keep state - 對 TCP, UDP, ICMP起作用
    modulate state - 只對 TCP起作用. PF會為匹配規(guī)則的數(shù)據(jù)包產(chǎn)生強(qiáng)壯的初始化序列號。
    synproxy state - 代理外來的TCP連接以保護(hù)服務(wù)器不受TCP SYN FLOODs欺騙。這個(gè)選項(xiàng)包含了keep state 和 modulate state 的功能。
    默認(rèn)拒絕
    按照慣例建立
    防火墻
    時(shí)推薦執(zhí)行的是默認(rèn)拒絕的方法。也就是說先拒絕所有的東西,然后有選擇的允許某些特定的流量通過防火墻。這個(gè)方法之所以是推薦的是因?yàn)樗鼘幙墒е^于謹(jǐn)慎(也不放過任何風(fēng)險(xiǎn)),而且使得編寫規(guī)則集變得簡單。
    產(chǎn)生一個(gè)默認(rèn)拒絕的過濾規(guī)則,開始2行過濾規(guī)則必須是:
    block in all
    block out all

    這會阻塞任何通信方在任何方向上進(jìn)入任意接口的所有流量。
    通過流量
    流量必須被明確的允許通過防火墻或者被默認(rèn)拒絕的策略丟棄。這是數(shù)據(jù)包標(biāo)準(zhǔn)如源/目的端口,源/目的地址和協(xié)議開始活動(dòng)的地方。無論何時(shí)數(shù)據(jù)包在被允許通過防火墻時(shí)規(guī)則都要設(shè)計(jì)的盡可能嚴(yán)厲。這是為了保證設(shè)計(jì)中的流量,也只有設(shè)計(jì)中的流量可以被允許通過。
    實(shí)例:
    # 允許本地網(wǎng)絡(luò)192.168.0.0/24流量通過dc0接口進(jìn)入訪問openbsd機(jī)器的IP地址
    #192.168.0.1,同時(shí)也允許返回的數(shù)據(jù)包從dc0接口出去。
    pass in on dc0 from 192.168.0.0/24 to 192.168.0.1
    pass out on dc0 from 192.168.0.1 to 192.168.0.0/24

    # Pass TCP traffic in on fxp0 to the web server running on the
    # OpenBSD machine. The interface name, fxp0, is used as the
    # destination address so that packets will only match this rule if
    # they‘re destined for the OpenBSD machine.
    pass in on fxp0 proto tcp from any to fxp0 port www

    quick 關(guān)鍵字
    每個(gè)數(shù)據(jù)包都要按自上至下的順序按規(guī)則進(jìn)行過濾。默認(rèn)情況下,數(shù)據(jù)包被標(biāo)記為通過,這個(gè)可以被任一規(guī)則改變,在到達(dá)最后一條規(guī)則前可以被來回改變多次,最后的匹配規(guī)則是“獲勝者”。存在一個(gè)例外是:過濾規(guī)則中的quick關(guān)鍵字具有取消進(jìn)一步往下處理的作用,使得規(guī)則指定的動(dòng)作馬上執(zhí)行?匆幌孪旅娴睦樱
    錯(cuò)誤:
    block in on fxp0 proto tcp from any to any port ssh
    pass in all

    在這樣的條件下,block行會被檢測,但永遠(yuǎn)也不會有效果,因?yàn)樗竺娴囊恍性试S所有的流量通過。
    正確:
    block in quick on fxp0 proto tcp from any to any port ssh
    pass in all

    這些規(guī)則執(zhí)行的結(jié)果稍有不同,如果block行被匹配,由于quick選項(xiàng)的原因,數(shù)據(jù)包會被阻塞,而且剩下的規(guī)則也會被忽略。
    狀態(tài)保持
    PF一個(gè)非常重要的功能是“狀態(tài)保持”或者“
    狀態(tài)檢測
    ”。狀態(tài)檢測指PF跟蹤或者處理網(wǎng)絡(luò)連接狀態(tài)的能力。通過存貯每個(gè)連接的信息到一個(gè)狀態(tài)表中,PF能夠快速確定一個(gè)通過防火墻的數(shù)據(jù)包是否屬于已經(jīng)建立的連接。如果是,它會直接通過防火墻而不用再進(jìn)行規(guī)則檢驗(yàn)。
    狀態(tài)保持有許多的優(yōu)點(diǎn),包括簡單的規(guī)則集和優(yōu)良的數(shù)據(jù)包處理性能。
    PF is able to match packets moving in either direction to state table entries meaning that filter rules which pass returning trafficdon‘t need to be written.
    并且,由于數(shù)據(jù)包匹配狀態(tài)連接時(shí)不再進(jìn)行規(guī)則集的匹配檢測,PF用于處理這些數(shù)據(jù)包的時(shí)間大為減少。
    當(dāng)一條規(guī)則使用了keep state選項(xiàng),第一個(gè)匹配這條規(guī)則的數(shù)據(jù)包在收發(fā)雙方之間建立了一個(gè)狀態(tài)。現(xiàn)在,不僅發(fā)送者到接收者之間的數(shù)據(jù)包匹配這個(gè)狀態(tài)繞過規(guī)則檢驗(yàn),而且接收者回復(fù)發(fā)送者的數(shù)據(jù)包也是同樣的。例如:
    pass out on fxp0 proto tcp from any to any keep state
    這允許fxp0接口上的任何TCP流量通過,并且允許返回的流量通過防火墻。狀態(tài)保持是一個(gè)非常有用的特性,由于狀態(tài)查詢比使用規(guī)則進(jìn)行數(shù)據(jù)包檢驗(yàn)快的多,因此它可以大幅度提高防火墻的性能。
    狀態(tài)調(diào)整選項(xiàng)和狀態(tài)保持的功能在除了僅適用于TCP數(shù)據(jù)包以為完全相同。在使用狀態(tài)調(diào)整時(shí),輸入連接的初始化序列號(
    ISN
    )是隨機(jī)的,這對于保護(hù)某些選擇ISN存在問題的操作系統(tǒng)的連接初始化非常有用。從openbsd 3.5開始,狀態(tài)調(diào)整選項(xiàng)可以應(yīng)用于包含非TCP的協(xié)議規(guī)則。
    對輸出的TCP, UDP, ICMP數(shù)據(jù)包保持狀態(tài),并且調(diào)整
    TCP ISN

    pass out on fxp0 proto { tcp, udp, icmp } from any to any modulate state
    狀態(tài)保持的另一個(gè)優(yōu)點(diǎn)是
    ICMP
    通信流量可以直接通過防火墻。例如,如果一個(gè)TCP連接使用了狀態(tài)保持,當(dāng)和這個(gè)TCP連接相關(guān)的ICMP數(shù)據(jù)包到來時(shí),它會自動(dòng)找到合適的狀態(tài)記錄,直接通過防火墻。
    狀態(tài)記錄的范圍被state-policy runtime選項(xiàng)總體控制,也能基于單條規(guī)則由if-bound, group-bound, 和 floating state選項(xiàng)關(guān)鍵字設(shè)定。這些針對單條規(guī)則的關(guān)鍵字在使用時(shí)具有和state-policy選項(xiàng)同樣的意義。例如:
    pass out on fxp0 proto { tcp, udp, icmp } from any to any modulate state (if-bound)
    狀態(tài)規(guī)則指示為了使數(shù)據(jù)包匹配狀態(tài)條目,它們必須通過fxp0網(wǎng)絡(luò)接口傳遞。
    需要注意的是,nat,binat,rdr規(guī)則隱含在連接通過過濾規(guī)則集審核的過程中產(chǎn)生匹配連接的狀態(tài)。
    UDP狀態(tài)保持
    “不能為UDP產(chǎn)生狀態(tài),因?yàn)閁DP是無狀態(tài)的協(xié)議”。確實(shí),UDP通信會話沒有狀態(tài)的概念(明確的開始和結(jié)束通信),這絲毫不影響PF為 UDP會話產(chǎn)生狀態(tài)的能力。對于沒有開始和結(jié)束數(shù)據(jù)包的協(xié)議,PF僅簡單追蹤匹配的數(shù)據(jù)部通過的時(shí)間。如果到達(dá)超時(shí)限制,狀態(tài)被清除,超時(shí)的時(shí)間值可以在pf.conf配置文件中設(shè)定。
    TCP 標(biāo)記
    基于標(biāo)記的TCP包匹配經(jīng)常被用于過濾試圖打開新連接的TCP數(shù)據(jù)包。TCP標(biāo)記和他們的意義如下所列:
    * F :
    FIN
    - 結(jié)束; 結(jié)束會話
    * S :
    SYN
    - 同步; 表示開始會話請求
    * R :
    RST
    - 復(fù)位;中斷一個(gè)連接
    * P : PUSH - 推送; 數(shù)據(jù)包立即發(fā)送
    * A :
    ACK
    - 應(yīng)答
    * U :
    URG
    - 緊急
    * E :
    ECE
    - 顯式擁塞提醒回應(yīng)
    * W :
    CWR
    - 擁塞窗口減少
    要使PF在規(guī)則檢查過程中檢查TCP標(biāo)記,flag關(guān)鍵需按如下語法設(shè)置。
    flags check/mask
    mask部分告訴PF僅檢查指定的標(biāo)記,check部分說明在數(shù)據(jù)包頭中哪個(gè)標(biāo)記設(shè)置為“on”才算匹配。
    pass in on fxp0 proto tcp from any to any port ssh flags S/SA
    上面的規(guī)則通過的帶SYN標(biāo)記的TCP流量僅查看SYN和ACK標(biāo)記。帶有SYN和ECE標(biāo)記的數(shù)據(jù)包會匹配上面的規(guī)則,而帶有SYN和ACK的數(shù)據(jù)包或者僅帶有ACK的數(shù)據(jù)包不會匹配。
    注意:在前面的openbsd版本中,下面的語法是支持的:
    . . . flags S
    現(xiàn)在,這個(gè)不再支持,mask必須被說明。
    標(biāo)記常常和狀態(tài)保持規(guī)則聯(lián)合使用來控制創(chuàng)建狀態(tài)條目:
    pass out on fxp0 proto tcp all flags S/SA keep state
    這條規(guī)則允許為所有輸出中帶SYN和ACK標(biāo)記的數(shù)據(jù)包中的僅帶有SYN標(biāo)記的TCP數(shù)據(jù)包創(chuàng)建狀態(tài)。
    使用標(biāo)記時(shí)必須小心,理解在做什么和為什么這樣做。小心聽取建議,因?yàn)橄喈?dāng)多的建議時(shí)不好的。一些人建議創(chuàng)建狀態(tài)“只有當(dāng)SYN標(biāo)記設(shè)定而沒有其他標(biāo)記”時(shí),這樣的規(guī)則如下:
    . . . flags S/FSRPAUEW 糟糕的主意!!
    這個(gè)理論是,僅為TCP開始會話時(shí)創(chuàng)建狀態(tài),會話會以SYN標(biāo)記開始,而沒有其他標(biāo)記。問題在于一些站點(diǎn)使用ECN標(biāo)記開始會話,而任何使用ECN連接你的會話都會被那樣的規(guī)則拒絕。比較好的規(guī)則是:
    . . . flags S/SAFR
    這個(gè)經(jīng)過實(shí)踐是安全的,如果流量進(jìn)行了整形也沒有必要檢查FIN和RST標(biāo)記。整形過程會讓PF丟棄帶有非法TCP標(biāo)記的進(jìn)入數(shù)據(jù)包(例如SYN和FIN以及SYN和RST)。強(qiáng)烈推薦總是進(jìn)行流量整形:
    scrub in on fxp0
    .
    .
    .
    pass in on fxp0 proto tcp from any to any port ssh flags S/SA \
    keep state

    TCP SYN 代理
    通過,當(dāng)客戶端向服務(wù)器初始化一個(gè)TCP連接時(shí),PF會在二者直接傳遞握手?jǐn)?shù)據(jù)包。然而,PF具有這樣的能力,就是代理握手。使用握手代理,PF自己會和客戶端完成握手,初始化和服務(wù)器的握手,然后在二者之間傳遞數(shù)據(jù)。這樣做的優(yōu)點(diǎn)是在客戶端完成握手之前,沒有數(shù)據(jù)包到達(dá)服務(wù)器。這樣就消沉了TCP SYN FLOOD欺騙影響服務(wù)器的問題,因?yàn)檫M(jìn)行欺騙的客戶端不會完成握手。
    TCP SYN 代理在規(guī)則中使用synproxy state關(guān)鍵字打開。例如:
    pass in on $ext_if proto tcp from any to $web_server port www \
    flags S/SA synproxy state

    這樣, web服務(wù)器的連接由PF進(jìn)行TCP代理。
    由于synproxy state工作的方式,它具有keep state 和 modulate state一樣的功能。
    如果PF工作在橋模式下,SYN代理不會起作用。
    阻塞欺騙數(shù)據(jù)包
    地址欺騙是惡意用戶為了隱藏他們的真實(shí)地址或者假冒網(wǎng)絡(luò)上的其他節(jié)點(diǎn)而在他們傳遞的數(shù)據(jù)包中使用虛假的地址。一旦實(shí)施了地址欺騙,他們可以隱蔽真實(shí)地址實(shí)施網(wǎng)絡(luò)攻擊或者獲得僅限于某些地址的網(wǎng)絡(luò)訪問服務(wù)。
    PF通過antispoof關(guān)鍵字提供一些防止地址欺騙的保護(hù)。
    antispoof [log] [quick] for interface [af]
    log
    指定匹配的數(shù)據(jù)包應(yīng)該被pflogd進(jìn)行日志記錄
    quick
    如果數(shù)據(jù)包匹配這條規(guī)則,則這是最終的規(guī)則,不再進(jìn)行其他規(guī)則集的檢查。
    interface
    激活要進(jìn)行欺騙保護(hù)的網(wǎng)絡(luò)接口。也可以是接口的列表。
    af
    激活進(jìn)行欺騙保護(hù)的地址族,inet代表Ipv4,inet6代表Ipv6。
    實(shí)例:
    antispoof for fxp0 inet
    當(dāng)規(guī)則集載入時(shí),任何出現(xiàn)了antispoof關(guān)鍵字的規(guī)則都會擴(kuò)展成2條規(guī)則。假定接口fxp0具有ip地址10.0.0.1和子網(wǎng)掩碼255.255.255.0(或者/24),上面的規(guī)則會擴(kuò)展成:
    block in on ! fxp0 inet from 10.0.0.0/24 to any
    block in inet from 10.0.0.1 to any

    這些規(guī)則實(shí)現(xiàn)下面的2個(gè)目的:
    * 阻塞任何不是由fxp0接口進(jìn)入的10.0.0.0/24網(wǎng)絡(luò)的流量。由于10.0.0.0/24的網(wǎng)絡(luò)是在fxp0接口,具有這樣的源網(wǎng)絡(luò)地址的數(shù)據(jù)包絕不應(yīng)該從其他接口上出現(xiàn)。
    * 阻塞任何由10.0.0.1即fxp0接口的IP地址的進(jìn)入流量。主機(jī)絕對不會通過外面的接口給自己發(fā)送數(shù)據(jù)包,因此任何進(jìn)入的流量源中帶有主機(jī)自己的IP地址都可以認(rèn)為是惡意的!
    注意:antispoof規(guī)則擴(kuò)展出來的過濾規(guī)則會阻塞loopback接口上發(fā)送到本地地址的數(shù)據(jù)包。這些數(shù)據(jù)包應(yīng)該明確的配置為允許通過。例如:
    pass quick on lo0 all
    antispoof for fxp0 inet
    使用antispoof應(yīng)該僅限于已經(jīng)分配了IP地址的網(wǎng)絡(luò)接口,如果在沒有分配IP地址的網(wǎng)絡(luò)接口上使用,過濾規(guī)則會擴(kuò)展成:
    block drop in on ! fxp0 inet all
    block drop in inet all

    這樣的規(guī)則會存在阻塞所有接口上進(jìn)入的所有流量的危險(xiǎn)。
    被動(dòng)操作系統(tǒng)識別
    被動(dòng)操作系統(tǒng)識別是通過基于遠(yuǎn)端主機(jī)TCP SYN數(shù)據(jù)包中某些特征進(jìn)行操作系統(tǒng)被動(dòng)檢測的技術(shù)。這些信息可以作為標(biāo)準(zhǔn)在過濾規(guī)則中使用。
    PF檢測遠(yuǎn)端操作系統(tǒng)是通過比較TCP SYN數(shù)據(jù)包中的特征和已知的特征文件對照來確定的,特征文件默認(rèn)是/etc/pf.os。如果PF起作用,可是使用下面的命令查看當(dāng)前的特征列表。
    # pfctl -s osfp
    在規(guī)則集中,特征可以指定為OS類型,版本,或者子類型/補(bǔ)丁級別。這些條目在上面的pfctl命令中有列表。要在過濾規(guī)則中指定特征,需使用os關(guān)鍵字:
    pass in on $ext_if any os OpenBSD keep state
    block in on $ext_if any os "Windows 2000"
    block in on $ext_if any os "Linux 2.4 ts"
    block in on $ext_if any os unknown
    指定的操作系統(tǒng)類型unknow允許匹配操作系統(tǒng)未知的數(shù)據(jù)包。
    注意以下的內(nèi)容::
    *操作系統(tǒng)識別偶爾會出錯(cuò),因?yàn)榇嬖谄垓_或者修改過的使得看起來象某個(gè)操作系統(tǒng)得數(shù)據(jù)包。
    * 某些修改或者打過補(bǔ)丁得操作系統(tǒng)會改變棧得行為,導(dǎo)致它或者和特征文件不符,或者符合了另外得操作系統(tǒng)特征。
    * OSFP 僅對TCP SYN數(shù)據(jù)包起作用,它不會對其他協(xié)議或者已經(jīng)建立得連接起作用。
    IP 選項(xiàng)
    默認(rèn)情況下,PF阻塞帶有IP選項(xiàng)得數(shù)據(jù)包。這可以使得類似nmap得操作系統(tǒng)識別軟件工作困難。如果應(yīng)用程序需要通過這樣的數(shù)據(jù)包,例如多播或者
    IGMP
    ,可以使用allow-opts關(guān)鍵字
    pass in quick on fxp0 all allow-opts
    過濾規(guī)則實(shí)例
    下面是過濾規(guī)則得實(shí)例。運(yùn)行PF的機(jī)器充當(dāng)防火墻,在一個(gè)小得內(nèi)部網(wǎng)絡(luò)和因特網(wǎng)之間。只列出了過濾規(guī)則,queueing, nat, rdr,等等沒有在實(shí)例中列出。
    ext_if = "fxp0"
    int_if = "dc0"
    lan_net = "192.168.0.0/24"

    # scrub incoming packets
    scrub in all

    # setup a default deny policy
    block in all
    block out all

    # pass traffic on the loopback interface in either direction
    pass quick on lo0 all

    # activate spoofing protection for the internal interface.
    antispoof quick for $int_if inet

    # only allow ssh connections from the local network if it‘s from the
    # trusted computer, 192.168.0.15. use "block return" so that a TCP RST is
    # sent to close blocked connections right away. use "quick" so that this
    # rule is not overridden by the "pass" rules below.
    block return in quick on $int_if proto tcp from ! 192.168.0.15 \
    to $int_if port ssh flags S/SA

    # pass all traffic to and from the local network
    pass in on $int_if from $lan_net to any
    pass out on $int_if from any to $lan_net

    # pass tcp, udp, and icmp out on the external (Internet) interface.
    # keep state on udp and icmp and modulate state on tcp.
    pass out on $ext_if proto tcp all modulate state flags S/SA
    pass out on $ext_if proto { udp, icmp } all keep state

    # allow ssh connections in on the external interface as long as they‘re
    # NOT destined for the firewall (i.e., they‘re destined for a machine on
    # the local network). log the initial packet so that we can later tell
    # who is trying to connect. use the tcp syn proxy to proxy the connection.
    pass in log on $ext_if proto tcp from any to { !$ext_if, !$int_if } \
    port ssh flags S/SA synproxy state

    編輯本段
       
    回目錄
       
    PF防火墻 - 網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)

    簡介
    網(wǎng)絡(luò)地址轉(zhuǎn)換
    是映射整個(gè)網(wǎng)絡(luò)(或者多個(gè)網(wǎng)絡(luò))到單個(gè)IP地址的方法。當(dāng)ISP分配的IP地址數(shù)目少于要連上互聯(lián)網(wǎng)的計(jì)算機(jī)數(shù)目時(shí),
    NAT
    是必需的。NAT在
    RFC1631
    中描述。
    NAT允許使用
    RFC1918
    中定義的保留地址族。典型情況下,內(nèi)部網(wǎng)絡(luò)可以下面的地址族:
    10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
    172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
    192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
    擔(dān)任NAT任務(wù)的操作系統(tǒng)必須至少要2塊網(wǎng)卡,一塊連接到因特網(wǎng),另一塊連接內(nèi)部網(wǎng)絡(luò)。NAT會轉(zhuǎn)換內(nèi)部網(wǎng)絡(luò)的所有請求,使它們看起來象是來自進(jìn)行NAT工作的主機(jī)系統(tǒng)。
    NAT如何工作
    當(dāng)內(nèi)部網(wǎng)絡(luò)的一個(gè)客戶端連接因特網(wǎng)上的主機(jī)時(shí),它發(fā)送目的是那臺主機(jī)的IP數(shù)據(jù)包。這些數(shù)據(jù)包包含了達(dá)到連接目的的所有信息。NAT的作用和這些信息相關(guān)。
    * 源 IP 地址 (例如, 192.168.1.35)
    * 源 TCP 或者 UDP 端口 (例如, 2132)
    當(dāng)數(shù)據(jù)包通過NAT
    網(wǎng)關(guān)
    時(shí),它們會被修改,使得數(shù)據(jù)包看起來象是從NAT網(wǎng)關(guān)自己發(fā)出的。NAT網(wǎng)關(guān)會在它的狀態(tài)表中記錄這個(gè)改變,以便:
    a)將返回的數(shù)據(jù)包反向轉(zhuǎn)換
    b)確保返回的數(shù)據(jù)包能通過防火墻而不會被阻塞。
    例如,會發(fā)生下面的改變:
    * 源 IP: 被網(wǎng)關(guān)的外部地址所替換(例如, 24.5.0.5)
    * 源端口:被隨機(jī)選擇的網(wǎng)關(guān)沒有在用的端口替換 (例如, 53136)
    內(nèi)部主機(jī)和因特網(wǎng)上的主機(jī)都不會意識到發(fā)生了這個(gè)轉(zhuǎn)變步驟。對于內(nèi)部主機(jī),NAT系統(tǒng)僅僅是個(gè)因特網(wǎng)網(wǎng)關(guān),對于因特網(wǎng)上的主機(jī),數(shù)據(jù)包看起來直接來自NAT系統(tǒng),它完全不會意識到內(nèi)部工作站的存在。
    當(dāng)因特網(wǎng)網(wǎng)上的主機(jī)回應(yīng)內(nèi)部主機(jī)的數(shù)據(jù)包時(shí),它會使用NAT網(wǎng)關(guān)機(jī)器的外部地址和轉(zhuǎn)換后的端口。然后NAT網(wǎng)關(guān)會查詢狀態(tài)表來確定返回的數(shù)據(jù)包是否匹配某個(gè)已經(jīng)建立的連接;贗P地址和端口的聯(lián)合找到唯一匹配的記錄告訴PF這個(gè)返回的數(shù)據(jù)包屬于內(nèi)部主機(jī)192.168.1.35。然后PF會進(jìn)行和出去的數(shù)據(jù)包相反的轉(zhuǎn)換過程,將返回的數(shù)據(jù)包傳遞給內(nèi)部主機(jī)。
    ICMP數(shù)據(jù)包的轉(zhuǎn)換也是類似的,只是不進(jìn)行源端口的修改。

    NAT和包過濾
    注意:轉(zhuǎn)換后的數(shù)據(jù)包仍然會通過
    過濾引擎
    ,根據(jù)定義的過濾規(guī)則進(jìn)行阻塞或者通過。唯一的例外是如果nat規(guī)則中使用了pass關(guān)鍵字,會使得經(jīng)過nat的數(shù)據(jù)包直接通過過濾引擎。
    還要注意由于轉(zhuǎn)換是在過濾之前進(jìn)行,過濾引擎所看到的是上面“nat如何工作”中所說的經(jīng)過轉(zhuǎn)換后的ip地址和端口的數(shù)據(jù)包。
    IP 轉(zhuǎn)發(fā)
    由于NAT經(jīng)常在路由器和網(wǎng)關(guān)上使用,因此IP轉(zhuǎn)發(fā)是需要的,使得數(shù)據(jù)包可以在UNIX機(jī)器的不同網(wǎng)絡(luò)接口間傳遞。IP轉(zhuǎn)發(fā)可以通過sysctl命令打開:
    # sysctl -w net.inet.ip.forwarding=1
    # sysctl -w net.inet6.ip6.forwarding=1 (if using IPv6)

    要使這個(gè)變化永久生效,可以增加如下行到/etc/sysctl.conf文件中:
    net.inet.ip.forwarding=1
    net.inet6.ip6.forwarding=1

    這些行是本來就存在的,但默認(rèn)安裝中被#前綴注釋掉了。刪除#,保存文件,IP轉(zhuǎn)發(fā)在機(jī)器重啟后就會發(fā)生作用。
    配置NAT
    一般的NAT規(guī)則格式在pf.conf文件中是這個(gè)樣子:
    nat [pass] on interface [af] from src_addr [port src_port] to \
    dst_addr [port dst_port] -> ext_addr [pool_type] [static-port]

    nat
    開始NAT規(guī)則的關(guān)鍵字。
    pass
    使得轉(zhuǎn)換后的數(shù)據(jù)包完全繞過過濾規(guī)則。
    interface
    進(jìn)行數(shù)據(jù)包轉(zhuǎn)換的網(wǎng)絡(luò)接口。
    af
    地址類型,inet代表Ipv4,inet6代表Ipv6。PF通常能根據(jù)源/目標(biāo)地址自動(dòng)確定這個(gè)參數(shù)。
    src_addr
    被進(jìn)行轉(zhuǎn)換的IP頭中的源(內(nèi)部)地址。源地址可以指定為:
    單個(gè)的Ipv4或者Ipv6地址.
    CIDR 網(wǎng)絡(luò)地址.
    能夠在規(guī)則集載入時(shí)通過DNS解析到的合法的域名,IP地址會替代規(guī)則中的域名。
    網(wǎng)絡(luò)接口名稱。網(wǎng)絡(luò)接口上配置的所有ip地址會替代進(jìn)規(guī)則中。
    帶有/掩碼(例如/24)的網(wǎng)絡(luò)接口的名稱。每個(gè)根據(jù)掩碼確定的CIDR網(wǎng)絡(luò)地址都會被替代進(jìn)規(guī)則中。.
    帶有()的網(wǎng)絡(luò)接口名稱。這告訴PF如果網(wǎng)絡(luò)接口的IP地址改變了,就更新規(guī)則集。這個(gè)對于使用DHCP或者撥號來獲得IP地址的接口特別有用,IP地址改變時(shí)不需要重新載入規(guī)則集。
    帶有如下的修飾詞的網(wǎng)絡(luò)接口名稱:
    o :network - 替代CIDR網(wǎng)絡(luò)地址段 (例如, 192.168.0.0/24)
    o :broadcast - 替代網(wǎng)絡(luò)廣播地址(例如, 192.168.0.255)
    o :peer - 替代點(diǎn)到點(diǎn)鏈路上的ip地址。
    另外,:0修飾詞可以附加到接口名稱或者上面的修飾詞后面指示PF在替代時(shí)不包括網(wǎng)絡(luò)接口的其余附加(alias)地址。這些修飾詞也可以在接口名稱在括號()內(nèi)時(shí)使用。例如:fxp0:network:0
    表.
    上面的所有項(xiàng)但使用。ǚ牵┬揎椩~
    使用列表的一系列地址.
    關(guān)鍵字 any 代表所有地址
    關(guān)鍵字 all 是 from any to any的縮寫。
    src_port
    4層數(shù)據(jù)包頭中的源端口。端口可以指定為:
    1 到 65535之間的整數(shù)
    /etc/services中的合法服務(wù)名稱
    使用列表的一系列端口
    一個(gè)范圍:
    o != (不等于)
    o  (大于)
    o = (大于等于)
    o > (反轉(zhuǎn)范圍)
    最后2個(gè)是二元操作符(他們需要2個(gè)參數(shù)),在范圍內(nèi)不包括參數(shù)。
    o : (inclusive range)
    inclusive range 也是二元操作符但范圍內(nèi)包括參數(shù)。
    Port選項(xiàng)在NAT規(guī)則中通常不使用,因?yàn)槟繕?biāo)通常會NAT所有的流量而不過端口是否在使用。
    dst_addr
    被轉(zhuǎn)換數(shù)據(jù)包中的目的地址。目的地址類型和源地址相似。
    dst_port
    4層數(shù)據(jù)包頭中的目的目的端口,目的端口類型和源端口類型相似。
    ext_addr
    NAT網(wǎng)關(guān)上數(shù)據(jù)包被轉(zhuǎn)換后的外部地址。外部地址可以是:
    單個(gè)的Ipv4或者Ipv6地址.
    CIDR 網(wǎng)絡(luò)地址.
    能夠在規(guī)則集載入時(shí)通過DNS解析到的合法的域名,IP地址會替代規(guī)則中的域名。
    網(wǎng)絡(luò)接口名稱。網(wǎng)絡(luò)接口上配置的所有ip地址會替代進(jìn)規(guī)則中。
    帶有/掩碼(例如/24)的網(wǎng)絡(luò)接口的名稱。每個(gè)根據(jù)掩碼確定的CIDR網(wǎng)絡(luò)地址都會被替代進(jìn)規(guī)則中。.
    帶有()的網(wǎng)絡(luò)接口名稱。這告訴PF如果網(wǎng)絡(luò)接口的IP地址改變了,就更新規(guī)則集。這個(gè)對于使用DHCP或者撥號來獲得IP地址的接口特別有用,IP地址改變時(shí)不需要重新載入規(guī)則集。
    帶有如下的修飾詞的網(wǎng)絡(luò)接口名稱:
    o :network - 替代CIDR網(wǎng)絡(luò)地址段 (例如, 192.168.0.0/24)
    o :broadcast - 替代網(wǎng)絡(luò)廣播地址(例如, 192.168.0.255)
    o :peer - 替代點(diǎn)到點(diǎn)鏈路上的ip地址。
    另外,:0修飾詞可以附加到接口名稱或者上面的修飾詞后面指示PF在替代時(shí)不包括網(wǎng)絡(luò)接口的其余附加(alias)地址。這些修飾詞也可以在接口名稱在括號()內(nèi)時(shí)使用。例如:fxp0:network:0
    使用列表的一系列地址.
    pool_type
    指定轉(zhuǎn)換后的地址池的類型
    static-port
    告訴PF不要轉(zhuǎn)換TCP和UDP數(shù)據(jù)包中的源端口
    這條規(guī)則最簡單的形式如下:
    nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5
    這條規(guī)則是說對從tl0網(wǎng)絡(luò)接口上到來的所有192.168.1.0/24網(wǎng)絡(luò)的數(shù)據(jù)包進(jìn)行NAT,將源地址轉(zhuǎn)換為24.5.0.5。
    盡管上面的規(guī)則是正確的,但卻不是推薦的形式。因?yàn)榫S護(hù)起來有困難,當(dāng)內(nèi)部或者外部網(wǎng)絡(luò)有變化時(shí)都要修改這一行。比較一下下面這條比較容易維護(hù)的規(guī)則:(tl0時(shí)外部,dc0是內(nèi)部):
    nat on tl0 from dc0:network to any -> tl0
    優(yōu)點(diǎn)是相當(dāng)明顯的,可以任意改變2個(gè)接口的IP地址而不用改變這條規(guī)則。
    象上面這樣在地址轉(zhuǎn)換中使用接口名稱時(shí),IP地址在pf.conf文件載入時(shí)確定,并不是憑空的。如果使用DHCP還配置外部地址,這會存在問題。如果分配的IP地址改變了,NAT仍然會使用舊的IP地址轉(zhuǎn)換出去的數(shù)據(jù)包。這會導(dǎo)致對外的連接停止工作。為解決這個(gè)問題,應(yīng)該給接口名稱加上括號,告訴PF自動(dòng)更新轉(zhuǎn)換地址。
    nat on tl0 from dc0:network to any -> (tl0)
    這個(gè)方法對IPv4 和 IPv6地址都用效。

    雙向映射 (1:1 映射)
    雙向映射
    可以通過使用
    binat
    規(guī)則建立。Binat規(guī)則建立一個(gè)內(nèi)部地址和外部地址一對一的映射。這會很有用,比如,使用獨(dú)立的外部IP地址用內(nèi)部網(wǎng)絡(luò)里的機(jī)器提供web服務(wù)。從因特網(wǎng)到來連接外部地址的請求被轉(zhuǎn)換到內(nèi)部地址,同時(shí)由(內(nèi)部)web服務(wù)器發(fā)起的連接(例如DNS查詢)被轉(zhuǎn)換為外部地址。和NAT規(guī)則不過,binat規(guī)則中的tcp和udp端口不會被修改。
    例如:
    web_serv_int = "192.168.1.100"
    web_serv_ext = "24.5.0.6"

    binat on tl0 from $web_serv_int to any -> $web_serv_ext
    轉(zhuǎn)換規(guī)則例外設(shè)置
    使用no關(guān)鍵字可以在轉(zhuǎn)換規(guī)則中設(shè)置例外。例如,如果上面的轉(zhuǎn)換規(guī)則修改成這樣:
    no nat on tl0 from 192.168.1.10 to any
    nat on tl0 from 192.168.1.0/24 to any -> 24.2.74.79

    則除了192.168.1.10以外,整個(gè)192.168.1.0/24網(wǎng)絡(luò)地址的數(shù)據(jù)包都會轉(zhuǎn)換為外部地址24.2.74.79。
    注意第一條匹配的規(guī)則起了決定作用,如果是匹配有no的規(guī)則,數(shù)據(jù)包不會被轉(zhuǎn)換。No關(guān)鍵字也可以在binat和rdr規(guī)則中使用。
    檢查 NAT 狀態(tài)
    要檢查活動(dòng)的NAT轉(zhuǎn)換可以使用pfctl帶-s state 選項(xiàng)。這個(gè)選項(xiàng)列出所有當(dāng)前的NAT會話。
    # pfctl -s state
    fxp0 TCP 192.168.1.35:2132 -> 24.5.0.5:53136 -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT
    fxp0 UDP 192.168.1.35:2491 -> 24.5.0.5:60527 -> 24.2.68.33:53 MULTIPLE:SINGLE

    解釋 (對第一行):
    fxp0
    顯示狀態(tài)綁定的接口。如果狀態(tài)是浮動(dòng)的,會出現(xiàn)self字樣。
    TCP
    連接使用的協(xié)議。
    192.168.1.35:2132
    內(nèi)部網(wǎng)絡(luò)中機(jī)器的IP地址 (192.168.1.35),源端口(2132)在地址后顯示,這個(gè)也是被替換的IP頭中的地址。 of the machine on the internal network. The
    source port (2132) is shown after the address. This is also the address
    that is replaced in the IP header.
    24.5.0.5:53136
    IP 地址 (24.5.0.5) 和端口 (53136) 是網(wǎng)關(guān)上數(shù)據(jù)包被轉(zhuǎn)換后的地址和端口。
    65.42.33.245:22
    IP 地址 (65.42.33.245) 和端口 (22) 是內(nèi)部機(jī)器要連接的地址和端口。
    TIME_WAIT:TIME_WAIT
    這表明PF認(rèn)為的目前這個(gè)TCP連接的狀態(tài)。
    編輯本段
       
    回目錄
       
    PF防火墻 - 重定向 (端口轉(zhuǎn)發(fā))

    簡介
    如果在辦公地點(diǎn)應(yīng)用了NAT,內(nèi)部網(wǎng)所有的機(jī)器都可以訪問因特網(wǎng)。但如何讓NAT網(wǎng)關(guān)后面的機(jī)器能夠被從外部訪問?這就是重定向的來源。重定向允許外來的流量發(fā)送到NAT網(wǎng)關(guān)后面的機(jī)器。
    看個(gè)例子:
    rdr on tl0 proto tcp from any to any port 80 -> 192.168.1.20
    這一行重定向了TCP端口80(
    web服務(wù)器
    )流量到內(nèi)部網(wǎng)絡(luò)地址192.168.1.20。因此,即使192.168.1.20在網(wǎng)關(guān)后面的內(nèi)部網(wǎng)絡(luò),外部仍然能夠訪問它。
    上面rdr行中from any to any部分非常有用。如果明確知道哪些地址或者子網(wǎng)被允許訪問web服務(wù)器的80端口,可以在這部分嚴(yán)格限制:
    rdr on tl0 proto tcp from 27.146.49.0/24 to any port 80 -> 192.168.1.20
    這樣只會重定向指定的子網(wǎng)。注意這表明可以重定向外部不同的訪問主機(jī)到網(wǎng)關(guān)后面不同的機(jī)器上。這非常有用。例如,如果知道遠(yuǎn)端的用戶連接上來時(shí)使用的IP地址,可以讓他們使用網(wǎng)關(guān)的IP地址和端口訪問他們各自的桌面計(jì)算機(jī)。
    rdr on tl0 proto tcp from 27.146.49.14 to any port 80 -> \
    192.168.1.20
    rdr on tl0 proto tcp from 16.114.4.89 to any port 80 -> \
    192.168.1.22
    rdr on tl0 proto tcp from 24.2.74.178 to any port 80 -> \
    192.168.1.23

    重定向和包過濾
    注意:轉(zhuǎn)換后的數(shù)據(jù)包仍然會通過過濾引擎,根據(jù)定義的過濾規(guī)則進(jìn)行阻塞或者通過。唯一的例外是如果rdr規(guī)則中使用了pass關(guān)鍵字,會使得重定向的數(shù)據(jù)包直接通過過濾引擎。
    還要注意由于轉(zhuǎn)換是在過濾之前進(jìn)行,過濾引擎所看到的是在匹配rdr規(guī)則經(jīng)過轉(zhuǎn)換后的目標(biāo)ip地址和端口的數(shù)據(jù)包。
    * 192.0.2.1 - 因特網(wǎng)上的主機(jī)
    * 24.65.1.13 - openbsd路由器的外部地址
    * 192.168.1.5 - web服務(wù)器的內(nèi)部IP地址

    重定向規(guī)則:
    rdr on tl0 proto tcp from 192.0.2.1 to 24.65.1.13 port 80 \
    -> 192.168.1.5 port 8000

    數(shù)據(jù)包在經(jīng)過rdr規(guī)則前的模樣:
    * 源地址: 192.0.2.1
    * 源端口: 4028 (由操作系統(tǒng)任意選擇)
    * 目的地址: 24.65.1.13
    * 目的端口: 80
    數(shù)據(jù)包經(jīng)過rdr規(guī)則后的模樣:
    * 源地址: 192.0.2.1
    * 源端口: 4028
    * 目的地址: 192.168.1.5
    * 目的: 8000
    過濾引擎看見的IP數(shù)據(jù)包時(shí)轉(zhuǎn)換發(fā)生之后的情況。
    安全隱患
    重定向確實(shí)存在安全隱患。在防火墻上開了一個(gè)允許流量進(jìn)入內(nèi)部網(wǎng)絡(luò)的洞,被保護(hù)的網(wǎng)絡(luò)安全潛在的受到了威脅!例如,如果流量被轉(zhuǎn)發(fā)到了內(nèi)部的web服務(wù)器,而web服務(wù)器上允許的守護(hù)程序或者CGI腳本程序存在漏洞,則這臺服務(wù)器存在會被因特網(wǎng)網(wǎng)上的入侵者攻擊危險(xiǎn)。如果入侵者控制了這臺機(jī)器,就有了進(jìn)入內(nèi)部網(wǎng)絡(luò)的通道,僅僅是因?yàn)檫@種流量是允許通過防火墻的。
    這種風(fēng)險(xiǎn)可以通過將允許外部網(wǎng)絡(luò)訪問的系統(tǒng)限制在一個(gè)單獨(dú)的網(wǎng)段中來減小。這個(gè)網(wǎng)段通常也被稱為非軍事化區(qū)域(
    DMZ
    )或者私有服務(wù)網(wǎng)絡(luò)(
    PSN
    )。通過這個(gè)方法,如果web服務(wù)器被控制,通過嚴(yán)格的過濾進(jìn)出DMZ/PSN的流量,受影響的系統(tǒng)僅限于DMZ/PSN網(wǎng)段。
    重定向和反射
    通常,重定向規(guī)則是用來將因特網(wǎng)上到來的連接轉(zhuǎn)發(fā)到一個(gè)內(nèi)部網(wǎng)絡(luò)或者局域網(wǎng)的私有地址。例如:
    server = 192.168.1.40
    rdr on $ext_if proto tcp from any to $ext_if port 80 -> $server \
    port 80

    但是,當(dāng)一個(gè)重定向規(guī)則被從局域網(wǎng)上的客戶端進(jìn)行測試時(shí),它不會正常工作。這是因?yàn)橹囟ㄏ蛞?guī)則僅適用于通過指定端口($ext_if,外部接口,在上面的例子中)的數(shù)據(jù)包。從局域網(wǎng)上的主機(jī)連接防火墻的外部地址,并不意味著數(shù)據(jù)包會實(shí)際的通過外部接口。防火墻上的TCP/IP棧會把到來的數(shù)據(jù)包的目的地址在通過內(nèi)部接口時(shí)與它自己的IP地址或者別名進(jìn)行對比檢測。那樣的數(shù)據(jù)包不會真的通過外部接口,棧在任何情況下也不會建立那樣的通道。因而,PF永遠(yuǎn)也不會在外部接口上看到那些數(shù)據(jù)包,過濾規(guī)則由于指定了外部接口也不會起作用。
    指定第二條針對內(nèi)部接口的也達(dá)不到預(yù)想的效果。當(dāng)本地的客戶端連接防火墻的外部地址時(shí),初始化的TCP握手?jǐn)?shù)據(jù)包是通過內(nèi)部接口到達(dá)防火墻的。重定向規(guī)則確實(shí)起作用了,目標(biāo)地址被替換成了內(nèi)部服務(wù)器,數(shù)據(jù)包通過內(nèi)部接口轉(zhuǎn)發(fā)到了內(nèi)部的服務(wù)器。但源地址沒有進(jìn)行轉(zhuǎn)換,仍然包含的是本地客戶端的IP地址,因此服務(wù)器把它的回應(yīng)直接發(fā)送給了客戶端。防火墻永遠(yuǎn)收不到應(yīng)答不可能返回客戶端信息,客戶端收到的應(yīng)答不是來自它期望的源(防火墻)會被丟棄,TCP握手失敗,不能建立連接。
    當(dāng)然,局域網(wǎng)里的客戶端仍然會希望象外部客戶一樣透明的訪問這臺內(nèi)部服務(wù)器。有如下的方法解決這個(gè)問題:
    水平分割 DNS
    存在這樣的可能性,即配置DNS服務(wù)器使得它回答內(nèi)部主機(jī)的查詢和回答外部主機(jī)的查詢不一樣,因此內(nèi)部客戶端在進(jìn)行名稱解析時(shí)會收到內(nèi)部服務(wù)器的地址。它們直接連接到內(nèi)部服務(wù)器,防火墻根本不牽扯。這會降低本地流量,因?yàn)閿?shù)據(jù)包不會被送到防火墻。
    將服務(wù)器移到獨(dú)立的本地網(wǎng)絡(luò)
    增加單獨(dú)的網(wǎng)絡(luò)接口卡到防火墻,把本地的服務(wù)器從和客戶端同一個(gè)網(wǎng)段移動(dòng)到專用的網(wǎng)段(DMZ)可以讓本地客戶端按照外部重定向連接的方法一樣重定向。使用單獨(dú)的網(wǎng)段有幾個(gè)優(yōu)點(diǎn),包括和保留的內(nèi)部主機(jī)隔離增加了安全性;服務(wù)器(我們的案例中可以從因特網(wǎng)訪問)一旦被控制,它不能直接存取本地網(wǎng)絡(luò)因?yàn)樗械倪B接都必須通過防火墻。
    TCP 代理
    一般而言,TCP代理可以在防火墻上設(shè)置,監(jiān)聽要轉(zhuǎn)發(fā)的端口或者將內(nèi)部接口上到來的連接重定向到它監(jiān)聽的端口。當(dāng)本地客戶端連接防火墻時(shí),代理接受連接,建立到內(nèi)部服務(wù)器的第二條連接,在通信雙方間進(jìn)行數(shù)據(jù)轉(zhuǎn)發(fā)。
    簡單的代理可以使用
    inetd

    nc
    建立。下面的/etc/inetd.conf中的條目建立一個(gè)監(jiān)聽套接字綁定到lookback地址(127.0.0.1)和端口5000。連接被轉(zhuǎn)發(fā)到服務(wù)器192.168.1.10的80端口。
    127.0.0.1:5000 stream tcp nowait nobody /usr/bin/nc nc -w \
    20 192.168.1.10 80

    下面的重定向規(guī)則轉(zhuǎn)發(fā)內(nèi)部接口的80端口到代理:
    rdr on $int_if proto tcp from $int_net to $ext_if port 80 -> \
    127.0.0.1 port 5000

    RDR 和 NAT 結(jié)合
    通過對內(nèi)部接口增加NAT規(guī)則,上面說的轉(zhuǎn)換后源地址不變的問題可以解決。
    rdr on $int_if proto tcp from $int_net to $ext_if port 80 -> \
    $server
    no nat on $int_if proto tcp from $int_if to $int_net
    nat on $int_if proto tcp from $int_net to $server port 80 -> \
    $int_if

    這會導(dǎo)致由客戶端發(fā)起的初始化連接在收到內(nèi)部接口的返回?cái)?shù)據(jù)包時(shí)轉(zhuǎn)換回來,客戶端的源ip地址被防火墻的內(nèi)部接口地址代替。內(nèi)部服務(wù)器會回應(yīng)防火墻的內(nèi)部接口地址,在轉(zhuǎn)發(fā)給本地客戶端時(shí)可以反轉(zhuǎn)NAT和RDR。這個(gè)結(jié)構(gòu)是非常復(fù)雜的,因?yàn)樗鼮槊總(gè)反射連接產(chǎn)生了2個(gè)單獨(dú)的狀態(tài)。必須小心配置防止NAT規(guī)則應(yīng)用到了其他流量,例如連接由外部發(fā)起(通過其他的重定向)或者防火墻自己。注意上面的rdr規(guī)則會導(dǎo)致TCP/IP棧看到來自內(nèi)部接口帶有目的地址是內(nèi)部網(wǎng)絡(luò)的數(shù)據(jù)包。
    編輯本段
       
    回目錄
       
    PF防火墻 - 規(guī)則生成捷徑
    簡介
    PF提供了許多方法來進(jìn)行規(guī)則集的簡化。一些好的例子是使用宏和列表。另外,規(guī)則集的語言或者語法也提供了一些使規(guī)則集簡化的捷徑。首要的規(guī)則是,規(guī)則集越簡單,就越容易理解和維護(hù)。
    使用宏
    宏是非常有用的,因?yàn)樗峁┝?br /> 硬編碼地址
    ,端口號,接口名稱等的可選替代。在一個(gè)規(guī)則集中,服務(wù)器的IP地址改變了?沒問題,僅僅更新一下宏,不需要弄亂花費(fèi)了大量時(shí)間和精力建立的規(guī)則集。
    通常的慣例是在PF規(guī)則集中定義每個(gè)網(wǎng)絡(luò)接口的宏。如果網(wǎng)卡需要被使用不同驅(qū)動(dòng)的卡取代,例如,用
    intel
    代替
    3com
    ,可以更新宏,過濾規(guī)則集會和以前功能一樣。另一個(gè)優(yōu)點(diǎn)是,如果在多臺機(jī)器上安裝同樣的規(guī)則集,某些機(jī)器會有不同的網(wǎng)卡,使用宏定義網(wǎng)卡可以使的安裝的規(guī)則集進(jìn)行最少的修改。使用宏來定義規(guī)則集中經(jīng)常改變的信息,例如端口號,IP地址,接口名稱等等,建議多多實(shí)踐!
    # define macros for each network interface
    IntIF = "dc0"
    ExtIF = "fxp0"
    DmzIF = "fxp1"

    另一個(gè)慣例是使用宏來定義IP地址和網(wǎng)絡(luò),這可以大大減輕在IP地址改變時(shí)對規(guī)則集的維護(hù)。
    # define our networks
    IntNet = "192.168.0.0/24"
    ExtAdd = "24.65.13.4"
    DmzNet = "10.0.0.0/24"

    如果內(nèi)部地址擴(kuò)展了或者改到了一個(gè)不同的IP段,可以更新宏為:
    IntNet = "{ 192.168.0.0/24, 192.168.1.0/24 }"
    當(dāng)這個(gè)規(guī)則集重新載入時(shí),任何東西都跟以前一樣。
    使用列表
    來看一下一個(gè)規(guī)則集中比較好的例子使得
    RFC1918
    定義的內(nèi)部地址不會傳送到因特網(wǎng)上,如果發(fā)生傳送的事情,可能導(dǎo)致問題。
    block in quick on tl0 inet from 127.0.0.0/8 to any
    block in quick on tl0 inet from 192.168.0.0/16 to any
    block in quick on tl0 inet from 172.16.0.0/12 to any
    block in quick on tl0 inet from 10.0.0.0/8 to any
    block out quick on tl0 inet from any to 127.0.0.0/8
    block out quick on tl0 inet from any to 192.168.0.0/16
    block out quick on tl0 inet from any to 172.16.0.0/12
    block out quick on tl0 inet from any to 10.0.0.0/8

    看看下面更簡單的例子:
    block in quick on tl0 inet from { 127.0.0.0/8, 192.168.0.0/16, \
    172.16.0.0/12, 10.0.0.0/8 } to any
    block out quick on tl0 inet from any to { 127.0.0.0/8, \
    192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }

    這個(gè)規(guī)則集從8行減少到2行。如果聯(lián)合使用宏,還會變得更好:
    NoRouteIPs = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \
    10.0.0.0/8 }"
    ExtIF = "tl0"
    block in quick on $ExtIF from $NoRouteIPs to any
    block out quick on $ExtIF from any to $NoRouteIPs

    注意雖然宏和列表簡化了pf.conf文件,但是實(shí)際是這些行會被pfctl(8)擴(kuò)展成多行,因此,上面的例子實(shí)際擴(kuò)展成下面的規(guī)則:
    block in quick on tl0 inet from 127.0.0.0/8 to any
    block in quick on tl0 inet from 192.168.0.0/16 to any
    block in quick on tl0 inet from 172.16.0.0/12 to any
    block in quick on tl0 inet from 10.0.0.0/8 to any
    block out quick on tl0 inet from any to 10.0.0.0/8
    block out quick on tl0 inet from any to 172.16.0.0/12
    block out quick on tl0 inet from any to 192.168.0.0/16
    block out quick on tl0 inet from any to 127.0.0.0/8

    可以看到,PF擴(kuò)展僅僅是簡化了編寫和維護(hù)pf.conf文件,實(shí)際并不簡化pf(4)對于規(guī)則的處理過程。
    宏不僅僅用來定義地址和端口,它們在PF的規(guī)則文件中到處都可以用:
    pre = "pass in quick on ep0 inet proto tcp from "
    post = "to any port { 80, 6667 } keep state"

    # David‘s classroom
    $pre 21.14.24.80 $post

    # Nick‘s home
    $pre 24.2.74.79 $post
    $pre 24.2.74.178 $post

    擴(kuò)展后:
    pass in quick on ep0 inet proto tcp from 21.14.24.80 to any \
    port = 80 keep state
    pass in quick on ep0 inet proto tcp from 21.14.24.80 to any \
    port = 6667 keep state
    pass in quick on ep0 inet proto tcp from 24.2.74.79 to any \
    port = 80 keep state
    pass in quick on ep0 inet proto tcp from 24.2.74.79 to any \
    port = 6667 keep state
    pass in quick on ep0 inet proto tcp from 24.2.74.178 to any \
    port = 80 keep state
    pass in quick on ep0 inet proto tcp from 24.2.74.178 to any \
    port = 6667 keep state

    PF 語法
    PF的語法相當(dāng)靈活,因此,允許編寫非常靈活的規(guī)則集。PF能夠自動(dòng)插入某些關(guān)鍵字因此它們不必在規(guī)則中明確寫出,關(guān)鍵字的順序也是隨意的,因此不需要記憶嚴(yán)格的語法限制。
    減少關(guān)鍵字
    要定義全部拒絕的策略,使用下面2條規(guī)則:
    block in all
    block out all

    這可以簡化為:
    block all
    如果沒有指定方向,PF會認(rèn)為規(guī)則適用于數(shù)據(jù)包傳遞的進(jìn)、出2個(gè)方向。
    同樣的, "from any to any" 和 "all" 子句可以在規(guī)則中省略,例如
    block in on rl0 all
    pass in quick log on rl0 proto tcp from any to any port 22 keep state

    可以簡化為:
    block in on rl0
    pass in quick log on rl0 proto tcp to port 22 keep state

    第一條規(guī)則阻塞rl0上從任意到任意的進(jìn)入數(shù)據(jù)包,第二條規(guī)則允許rl0上端口22的TCP流量通過。
    Return 簡化
    用于阻塞數(shù)據(jù)包,回應(yīng)TCP RST或者ICMP不可到達(dá)的規(guī)則集可以這么寫:
    block in all
    block return-rst in proto tcp all
    block return-icmp in proto udp all
    block out all
    block return-rst out proto tcp all
    block return-icmp out proto udp all

    可以簡化為::
    block return
    當(dāng)PF看到return關(guān)鍵字,PF可以智能回復(fù)合適應(yīng)答,或者完全不回復(fù),取決于要阻塞的數(shù)據(jù)包使用的協(xié)議。W
    關(guān)鍵字順序
    在大多數(shù)情況下,關(guān)鍵字的順序是非常靈活的。例如,規(guī)則可以這么寫:
    pass in log quick on rl0 proto tcp to port 22 \
    flags S/SA keep state queue ssh label ssh

    也可以這么寫:
    pass in quick log on rl0 proto tcp to port 22 \
    queue ssh keep state label ssh flags S/SA

    其他類似的順序也能夠正常工作。
    編輯本段
       
    回目錄
       
    PF防火墻 - 高級配置
    運(yùn)行選項(xiàng)
    運(yùn)行選項(xiàng)是控制pf操作的選擇。這些選項(xiàng)在pf.conf中使用set指定。
    set block-policy
    設(shè)定過濾規(guī)則中指定的block動(dòng)作的默認(rèn)行為。
    drop - 數(shù)據(jù)包悄然丟棄.
    return - TCP RST 數(shù)據(jù)包返回給遭阻塞的TCP數(shù)據(jù)包,ICMP不可到達(dá)數(shù)據(jù)包返回給其他。
    注意單獨(dú)的過濾規(guī)則可以重寫默認(rèn)的響應(yīng)。
    set debug
    設(shè)定pf的調(diào)試級別。
    none - 不顯示任何調(diào)試信息。
    urgent - 為嚴(yán)重錯(cuò)誤產(chǎn)生調(diào)試信息,這是默認(rèn)選擇。
    misc - 為多種錯(cuò)誤產(chǎn)生調(diào)試信息。(例如,收到標(biāo)準(zhǔn)化/整形的數(shù)據(jù)包的狀態(tài),和產(chǎn)生失敗的狀態(tài))。.
    loud - 為普通條件產(chǎn)生調(diào)試信息(例如,收到被動(dòng)操作系統(tǒng)檢測信息狀態(tài))。
    set fingerprints file
    設(shè)定應(yīng)該裝入的進(jìn)行操作系統(tǒng)識別的操作系統(tǒng)特征文件來,默認(rèn)是 /etc/pf.os.
    set limit
    frags - 在內(nèi)存池中進(jìn)行數(shù)據(jù)包重組的最大數(shù)目。默認(rèn)是5000。
    src-nodes - 在內(nèi)存池中用于追蹤源地址(由stick-address 和 source-track選項(xiàng)產(chǎn)生)的最大數(shù)目,默認(rèn)是10000。
    states - 在內(nèi)存池中用于狀態(tài)表(過濾規(guī)則中的keep state)的最大數(shù)目,默認(rèn)是10000。
    set loginterface int
    設(shè)定PF要統(tǒng)計(jì)進(jìn)/出流量和放行/阻塞的數(shù)據(jù)包的數(shù)目的接口卡。統(tǒng)計(jì)數(shù)目一次只能用于一張卡。注意 match, bad-offset, 等計(jì)數(shù)器和狀態(tài)表計(jì)數(shù)器不管 loginterface是否設(shè)置都會被記錄。
    set optimization
    為以下的網(wǎng)絡(luò)環(huán)境優(yōu)化PF:
    normal - 適用于絕大多數(shù)網(wǎng)絡(luò),這是默認(rèn)項(xiàng)。
    high-latency - 高延時(shí)網(wǎng)絡(luò),例如衛(wèi)星連接。
    aggressive - 自狀態(tài)表中主動(dòng)終止連接。這可以大大減少繁忙防火墻的內(nèi)存需求,但要冒空閑連接被過早斷開的風(fēng)險(xiǎn)。
    conservative - 特別保守的設(shè)置。這可以避免在內(nèi)存需求過大時(shí)斷開空閑連接,會稍微增加CPU的利用率。
    set state-policy
    設(shè)定 PF在狀態(tài)保持時(shí)的行為。這種行為可以被單條規(guī)則所改變。見狀態(tài)保持章節(jié)。
    if-bound - 狀態(tài)綁定到產(chǎn)生它們的接口。如果流量匹配狀態(tài)表種條目但不是由條目中記錄的接口通過,這個(gè)匹配會失敗。數(shù)據(jù)包要么匹配一條過濾規(guī)則,或者被丟棄/拒絕。
    group-bound - 行為基本和if-bound相同,除了數(shù)據(jù)包允許由同一組接口通過,例如所有的ppp接口等。
    floating - 狀態(tài)可以匹配任何接口上的流量。只要數(shù)據(jù)包匹配狀態(tài)表?xiàng)l目,不管是否匹配它通過的接口,都會放行。這是默認(rèn)的規(guī)則。
    set timeout
    interval - 丟棄過期的狀態(tài)和數(shù)據(jù)包碎片的秒數(shù)。
    frag - 不能重組的碎片過期的秒數(shù)。
    例如:
    set timeout interval 10
    set timeout frag 30
    set limit { frags 5000, states 2500 }
    set optimization high-latency
    set block-policy return
    set loginterface dc0
    set fingerprints /etc/pf.os.test
    set state-policy if-bound

    編輯本段
       
    回目錄
       
    PF防火墻 - 流量整形
    簡介
    流量整形是將數(shù)據(jù)包標(biāo)準(zhǔn)化避免最終的數(shù)據(jù)包出現(xiàn)非法的目的。流量整形指引同時(shí)也會重組數(shù)據(jù)包碎片,保護(hù)某些操作系統(tǒng)免受某些攻擊,丟棄某些帶有非法聯(lián)合標(biāo)記的TCP數(shù)據(jù)包。流量整形指引的簡單形式是:
    scrub in all
    這會對所有接口上到來的數(shù)據(jù)包進(jìn)行流量整形。
    一個(gè)不在接口上進(jìn)行流量整形的原因是要透過PF使用NFS。一些非openbsd的平臺發(fā)送(和等待)奇怪的數(shù)據(jù)包,對設(shè)置不分片位的數(shù)據(jù)包進(jìn)行分片。這會被流量整形(正確的)拒絕。這個(gè)問題可以通過設(shè)置no-df選項(xiàng)解決。另一個(gè)原因是某些多用戶的游戲在進(jìn)行流量整形通過PF時(shí)存在連接問題。除了這些極其罕見的案例,對所有的數(shù)據(jù)包進(jìn)行流量整形時(shí)強(qiáng)烈推薦的設(shè)置。
    流量整形指引語法相對過濾語法是非常簡單的,它可以非常容易的選擇特定的數(shù)據(jù)包進(jìn)行整形而不對沒指定的數(shù)據(jù)包起作用。
    選項(xiàng)
    流量整形有下面的選項(xiàng):
    no-df
    在IP數(shù)據(jù)包頭中清除不分片位的設(shè)置。某些操作系統(tǒng)已知產(chǎn)生設(shè)置不分片位的分片數(shù)據(jù)包。尤其是對于
    NFS
    。流量整形(
    scrub
    )會丟棄這類數(shù)據(jù)包除非設(shè)置了no-df選項(xiàng)。某些操作系統(tǒng)產(chǎn)生帶有不分片位和用0填寫IP包頭中分類域,推薦使用no-df和random-id 聯(lián)合使用解決。
    random-id
    用隨機(jī)值替換某些操作系統(tǒng)輸出數(shù)據(jù)包中使用的可預(yù)測
    IP分類域
    的值這個(gè)選項(xiàng)僅適用于在選擇的數(shù)據(jù)包重組后不進(jìn)行分片的輸入數(shù)據(jù)包。
    min-ttl num
    增加IP包頭中的最小存活時(shí)間(TTL)。
    max-mss num
    增加在TCP數(shù)據(jù)包頭中最大分段值(MSS)。
    fragment reassemble
    在傳遞數(shù)據(jù)包到過濾引擎前緩沖收到的數(shù)據(jù)包碎片,重組它們成完整的數(shù)據(jù)包。優(yōu)點(diǎn)是過濾規(guī)則僅處理完整的數(shù)據(jù)包,忽略碎片。缺點(diǎn)是需要內(nèi)存緩沖數(shù)據(jù)包碎片。這是沒有設(shè)置分片選項(xiàng)時(shí)的默認(rèn)行為。這也是能和NAT一起工作的唯一分片選項(xiàng)。
    fragment crop
    導(dǎo)致重復(fù)的碎片被丟棄,重疊的被裁剪。與碎片重組不同,碎片不會被緩沖,而是一到達(dá)就直接傳遞。
    fragment drop-ovl
    跟 fragment crop 相似,除了所有重復(fù)和重疊的碎片和其他更多的通信碎片一樣被丟棄。
    reassemble tcp
    TCP連接狀態(tài)標(biāo)準(zhǔn)化。當(dāng)使用了 scrub reassemble tcp時(shí),方向(進(jìn)/出)不用說明,會執(zhí)行下面的標(biāo)準(zhǔn)化過程:
    連接雙方都不允許減少它們的IP TTL值。這樣做是為了防止攻擊者發(fā)送數(shù)據(jù)包到防火墻,影響防火墻保持的連接狀態(tài),使數(shù)據(jù)包在到達(dá)目的主機(jī)前就過期。所有數(shù)據(jù)包的TTL都為了這個(gè)連接加到了最大值。
    用隨機(jī)數(shù)字調(diào)整TCP數(shù)據(jù)包頭中的 RFC1323 時(shí)間戳。這可以阻止竊聽者推斷主機(jī)在線的時(shí)間和猜測NAT網(wǎng)關(guān)后面有多少主機(jī)。
    實(shí)例:
    scrub in on fxp0 all fragment reassemble min-ttl 15 max-mss 1400
    scrub in on fxp0 all no-df
    scrub on fxp0 all reassemble tcp

    編輯本段
       
    回目錄
       
    PF防火墻 - 錨定和命名規(guī)則集
    簡介
    除了主要的規(guī)則集,PF還可以載入子規(guī)則
    該網(wǎng)絡(luò)的隊(duì)列策略:
    * 為Bob保留玩在線游戲的80Kbps下行帶寬,以減少另外兩人對他的影響,并且總帶寬富余的情況下可以超出該限制。
    * 交互的SSH和即時(shí)信息流量要有高于其他流量的優(yōu)先級。
    * DNS請求和反饋數(shù)據(jù)流要有第二高的優(yōu)先級。
    * 流出的TCP ACK 數(shù)據(jù)包的優(yōu)先級要高于其他流出數(shù)據(jù)包的優(yōu)先級。
    下面是對應(yīng)的策略(省略了其他部分策略,如rdr、nat等):
    # enable queueing on the external interface to control traffic going to
    # the Internet. use the priq scheduler to control only priorities. set
    # the bandwidth to 610Kbps to get the best performance out of the TCP
    # ACK queue.

    altq on fxp0 priq bandwidth 610Kb queue { std_out, ssh_im_out, dns_out, \
    tcp_ack_out }

    # define the parameters for the child queues.
    # std_out - the standard queue. any filter rule below that does not
    # explicitly specify a queue will have its traffic added
    # to this queue.
    # ssh_im_out - interactive SSH and various instant message traffic.
    # dns_out - DNS queries.
    # tcp_ack_out - TCP ACK packets with no data payload.

    queue std_out priq(default)
    queue ssh_im_out priority 4 priq(red)
    queue dns_out priority 5
    queue tcp_ack_out priority 6

    # enable queueing on the internal interface to control traffic coming in
    # from the Internet. use the cbq scheduler to control bandwidth. max
    # bandwidth is 2Mbps.

    altq on dc0 cbq bandwidth 2Mb queue { std_in, ssh_im_in, dns_in, bob_in }
    # define the parameters for the child queues.
    # std_in - the standard queue. any filter rule below that does not
    # explicitly specify a queue will have its traffic added
    # to this queue.
    # ssh_im_in - interactive SSH and various instant message traffic.
    # dns_in - DNS replies.
    # bob_in - bandwidth reserved for Bob‘s workstation. allow him to
    # borrow.

    queue std_in cbq(default)
    queue ssh_im_in priority 4
    queue dns_in priority 5
    queue bob_in bandwidth 80Kb cbq(borrow)

    # ... in the filtering section of pf.conf ...
    alice = "192.168.0.2"
    bob = "192.168.0.3"
    charlie = "192.168.0.4"
    local_net = "192.168.0.0/24"
    ssh_ports = "{ 22 2022 }"
    im_ports = "{ 1863 5190 5222 }"

    # filter rules for fxp0 inbound
    block in on fxp0 all

    # filter rules for fxp0 outbound
    block out on fxp0 all
    pass out on fxp0 inet proto tcp from (fxp0) to any flags S/SA \
    keep state queue(std_out, tcp_ack_out)
    pass out on fxp0 inet proto { udp icmp } from (fxp0) to any keep state
    pass out on fxp0 inet proto { tcp udp } from (fxp0) to any port domain \
    keep state queue dns_out
    pass out on fxp0 inet proto tcp from (fxp0) to any port $ssh_ports \
    flags S/SA keep state queue(std_out, ssh_im_out)
    pass out on fxp0 inet proto tcp from (fxp0) to any port $im_ports \
    flags S/SA keep state queue(ssh_im_out, tcp_ack_out)

    # filter rules for dc0 inbound
    block in on dc0 all
    pass in on dc0 from $local_net

    # filter rules for dc0 outbound
    block out on dc0 all
    pass out on dc0 from any to $local_net
    pass out on dc0 proto { tcp udp } from any port domain to $local_net \
    queue dns_in
    pass out on dc0 proto tcp from any port $ssh_ports to $local_net \
    queue(std_in, ssh_im_in)
    pass out on dc0 proto tcp from any port $im_ports to $local_net \
    queue ssh_im_in
    pass out on dc0 from any to $bob queue bob_in

    實(shí)例 #2: 公司網(wǎng)絡(luò)
    ( IT Dept ) [ Boss‘s PC ]
    | | T1
    -- ---- ----- ---------- dc0 [ OpenBSD ] fxp0 -------- ( Internet )
    | fxp1
    [ COMP1 ] [ WWW ] /
    | /
    -- ----------‘
    這個(gè)例子中OpenBSD作為公司網(wǎng)絡(luò)的防火墻,公司內(nèi)部在
    DMZ
    區(qū)運(yùn)行了
    WWW服務(wù)器
    ,用戶通過FTP上傳他們的網(wǎng)站。IT部門有自己的子網(wǎng),老板的電腦主要用來收發(fā)電子郵件和網(wǎng)頁沖浪。防火墻通過1.5Mbps雙向帶寬的T1電路連接因特網(wǎng),其他網(wǎng)段均使用快速以太網(wǎng)(100Mbps)。
    實(shí)現(xiàn)上述要求的策略如下:
    * 限制WWW服務(wù)器到因特網(wǎng)之間的雙向流量――500Kbps。
    * WWW服務(wù)器和內(nèi)部網(wǎng)絡(luò)之間沒有流量限制。
    * 賦予WWW服務(wù)器和因特網(wǎng)間的流量高于其他流量的優(yōu)先級(例如FTP上傳流量)。
    * 為IT部門保留500Kbps的帶寬使他們可以下載到最新的軟件,同時(shí)如果總帶寬富余,他們可以借用。
    * 為老板訪問因特網(wǎng)的流量賦予比其他訪問因特網(wǎng)流量高的優(yōu)先級。
    下面是對應(yīng)的策略(省略了其他部分策略,如rdr、nat等):
    # enable queueing on the external interface to queue packets going out
    # to the Internet. use the cbq scheduler so that the bandwidth use of
    # each queue can be controlled. the max outgoing bandwidth is 1.5Mbps.

    altq on fxp0 cbq bandwidth 1.5Mb queue { std_ext, www_ext, boss_ext }
    # define the parameters for the child queues.
    # std_ext - the standard queue. also the default queue for
    # outgoing traffic on fxp0.
    # www_ext - container queue for WWW server queues. limit to
    # 500Kbps.
    # www_ext_http - http traffic from the WWW server
    # www_ext_misc - all non-http traffic from the WWW server
    # boss_ext - traffic coming from the boss‘s computer

    queue std_ext cbq(default)
    queue www_ext bandwidth 500Kb { www_ext_http, www_ext_misc }
    queue www_ext_http priority 3 cbq(red)
    queue www_ext_misc priority 1
    queue boss_ext priority 3

    # enable queueing on the internal interface to control traffic coming
    # from the Internet or the DMZ. use the cbq scheduler to control the
    # bandwidth of each queue. bandwidth on this interface is set to the
    # maximum. traffic coming from the DMZ will be able to use all of this
    # bandwidth while traffic coming from the Internet will be limited to
    # 1.0Mbps (because 0.5Mbps (500Kbps) is being allocated to fxp1).

    altq on dc0 cbq bandwidth 100% queue { net_int, www_int }
    # define the parameters for the child queues.
    # net_int - container queue for traffic from the Internet. bandwidth
    # is 1.0Mbps.
    # std_int - the standard queue. also the default queue for outgoing
    # traffic on dc0.
    # it_int - traffic to the IT Dept network.
    # boss_int - traffic to the boss‘s PC.
    # www_int - traffic from the WWW server in the DMZ.

    queue net_int bandwidth 1.0Mb { std_int, it_int, boss_int }
    queue std_int cbq(default)
    queue it_int bandwidth 500Kb cbq(borrow)
    queue boss_int priority 3
    queue www_int cbq(red)

    # enable queueing on the DMZ interface to control traffic destined for
    # the WWW server. cbq will be used on this interface since detailed
    # control of bandwidth is necessary. bandwidth on this interface is set
    # to the maximum. traffic from the internal network will be able to use
    # all of this bandwidth while traffic from the Internet will be limited
    # to 500Kbps.

    altq on fxp1 cbq bandwidth 100% queue { internal_dmz, net_dmz }
    # define the parameters for the child queues.
    # internal_dmz - traffic from the internal network.
    # net_dmz - container queue for traffic from the Internet.
    # net_dmz_http - http traffic.
    # net_dmz_misc - all non-http traffic. this is also the default queue.

    queue internal_dmz # no special settings needed
    queue net_dmz bandwidth 500Kb { net_dmz_http, net_dmz_misc }
    queue net_dmz_http priority 3 cbq(red)
    queue net_dmz_misc priority 1 cbq(default)

    # ... in the filtering section of pf.conf ...
    main_net = "192.168.0.0/24"
    it_net = "192.168.1.0/24"
    int_nets = "{ 192.168.0.0/24, 192.168.1.0/24 }"
    dmz_net = "10.0.0.0/24"

    boss = "192.168.0.200"
    wwwserv = "10.0.0.100"

    # default deny
    block on { fxp0, fxp1, dc0 } all

    # filter rules for fxp0 inbound
    pass in on fxp0 proto tcp from any to $wwwserv port { 21, \
    > 49151 } flags S/SA keep state queue www_ext_misc
    pass in on fxp0 proto tcp from any to $wwwserv port 80 \
    flags S/SA keep state queue www_ext_http

    # filter rules for fxp0 outbound
    pass out on fxp0 from $int_nets to any keep state
    pass out on fxp0 from $boss to any keep state queue boss_ext

    # filter rules for dc0 inbound
    pass in on dc0 from $int_nets to any keep state
    pass in on dc0 from $it_net to any queue it_int
    pass in on dc0 from $boss to any queue boss_int
    pass in on dc0 proto tcp from $int_nets to $wwwserv port { 21, 80, \
    > 49151 } flags S/SA keep state queue www_int

    # filter rules for dc0 outbound
    pass out on dc0 from dc0 to $int_nets

    # filter rules for fxp1 inbound
    pass in on fxp1 proto { tcp, udp } from $wwwserv to any port 53 \
    keep state

    # filter rules for fxp1 outbound
    pass out on fxp1 proto tcp from any to $wwwserv port { 21, \
    > 49151 } flags S/SA keep state queue net_dmz_misc
    pass out on fxp1 proto tcp from any to $wwwserv port 80 \
    flags S/SA keep state queue net_dmz_http
    pass out on fxp1 proto tcp from $int_nets to $wwwserv port { 80, \
    21, > 49151 } flags S/SA keep state queue internal_dmz

    編輯本段
       
    回目錄
       
    PF防火墻 - 地址池和負(fù)載均衡
    簡介
    地址池
    是提供2個(gè)以上的地址供一組用戶共享的。地址池可以是rdr規(guī)則中的重定向地址;可以是nat規(guī)則中的轉(zhuǎn)換地址;也可以是route-to, reply-to, 和 dup-to filter選項(xiàng)中的目的地址。
    有4種使用地址池的方法:
    * bitmask - 截取被修改地址(nat規(guī)則的源地址;rdr規(guī)則的目標(biāo)地址)的最后部分和地址池地址的網(wǎng)絡(luò)部分組合。例如:如果地址池是192.0.2.1/24,而被修改地址是10.0.0.50,則結(jié)果地址是192.0.2.50。如果地址池是192.0.2.1/25,而被修改地址是10.0.0.130,這結(jié)果地址是192.0.2.2。
    * random - 從地址池中隨機(jī)選擇地址.
    * source-hash - 使用源地址 hash 來確定使用地址池中的哪個(gè)地址。這個(gè)方法保證給定的源地址總是被映射到同一個(gè)地址池。Hash算法的種子可以在source-hash關(guān)鍵字后通過16進(jìn)制字符或者字符串來指定。默認(rèn)情況下,pfctl(8)在規(guī)則集裝入時(shí)會隨機(jī)產(chǎn)生種子。
    * round-robin - 在地址池中按順序循環(huán),這是默認(rèn)方法,也是表中定義的地址池唯一的方法。
    除了round-robin方法,地址池的地址必須表達(dá)成CIDR(Classless Inter-Domain Routing )的網(wǎng)絡(luò)地址族。round-robin 方法可以接受多個(gè)使用列表和表的單獨(dú)地址。
    sticky-address 選項(xiàng)可以在 random 和round-robin 池類型中使用,保證特定的源地址始終映射到同樣的重定向地址。
    NAT 地址池
    地址池在NAT規(guī)則中可以被用做轉(zhuǎn)換地址。連接的源地址會被轉(zhuǎn)換成使用指定的方法從地址池中選擇的地址。這對于PF負(fù)載一個(gè)非常大的網(wǎng)絡(luò)的NAT會非常有用。由于經(jīng)過NAT的連接對每個(gè)地址是有限的,增加附加的轉(zhuǎn)換地址允許NAT網(wǎng)關(guān)增大服務(wù)的用戶數(shù)量。
    在這個(gè)例子中,2個(gè)地址被用來做輸出數(shù)據(jù)包的轉(zhuǎn)換地址。對于每一個(gè)輸出的連接,PF按照順序循環(huán)使用地址。
    nat on $ext_if inet from any to any -> { 192.0.2.5, 192.0.2.10 }
    這個(gè)方法的一個(gè)缺點(diǎn)是成功建立連接的同一個(gè)內(nèi)部地址不會總是轉(zhuǎn)換為同一個(gè)外部地址。這會導(dǎo)致沖突,例如:瀏覽根據(jù)用戶的ip地址跟蹤登錄的用戶的web站點(diǎn)。一個(gè)可選擇的替代方法是使用source-hash 方法,以便每一個(gè)內(nèi)部地址總是被轉(zhuǎn)換為同樣的外部地址。,要實(shí)現(xiàn)這個(gè)方法,地址池必須是CIDR網(wǎng)絡(luò)地址。
    nat on $ext_if inet from any to any -> 192.0.2.4/31 source-hash
    這條NAT規(guī)則使用地址池192.0.2.4/31 (192.0.2.4 - 192.0.2.5)做為輸出數(shù)據(jù)包的轉(zhuǎn)換地址。每一個(gè)內(nèi)部地址會被轉(zhuǎn)換為同樣的外部地址,由于source-hash關(guān)鍵字的緣故。
    外來連接負(fù)載均衡
    地址池也可以用來進(jìn)行外來連接
    負(fù)載均衡
    。例如,外來的web服務(wù)器連接可以分配到服務(wù)器群。
    web_servers = "{ 10.0.0.10, 10.0.0.11, 10.0.0.13 }"
    rdr on $ext_if proto tcp from any to any port 80 -> $web_servers \
    round-robin sticky-address

    成功的連接將按照順序重定向到web服務(wù)器,從同一個(gè)源到來的連接發(fā)送到同一個(gè)服務(wù)器。這個(gè)sticky connection會和指向這個(gè)連接的狀態(tài)一起存在。如果狀態(tài)過期,sticky
    connection也過期。那個(gè)主機(jī)的更多連接被重定向到按順序的下一個(gè)web服務(wù)器。
    輸出流量負(fù)載均衡
    地址池可以和route-to過濾選項(xiàng)聯(lián)合使用,在多路徑路由協(xié)議(例如BGP4)不可用是負(fù)載均衡2個(gè)或者多個(gè)因特網(wǎng)連接。通過對round-robin地址池使用route-to,輸出連接可以平均分配到多個(gè)輸出路徑。
    需要收集的附加的信息是鄰近的因特網(wǎng)路由器IP地址。這要加入到route-to選項(xiàng)后來控制輸入數(shù)據(jù)包的目的地址。
    下面的例子通過2條到因特網(wǎng)的連接平衡輸出流量:
    lan_net = "192.168.0.0/24"
    int_if = "dc0"
    ext_if1 = "fxp0"
    ext_if2 = "fxp1"
    ext_gw1 = "68.146.224.1"
    ext_gw2 = "142.59.76.1"

    pass in on $int_if route-to \
    { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
    from $lan_net to any keep state

    route-to 選項(xiàng)用來在收到流量的內(nèi)部接口上指定平衡的流量經(jīng)過各自的網(wǎng)關(guān)到輸出的網(wǎng)絡(luò)接口。注意route-to 選項(xiàng)必須在每個(gè)需要均衡的過濾規(guī)則上出現(xiàn)。返回的數(shù)據(jù)包會路由到它們出去時(shí)的外部接口(這是由ISP做的),然后正常路由回內(nèi)部網(wǎng)絡(luò)。
    要保證帶有屬于$ext_if1源地址的數(shù)據(jù)包總是路由到$ext_gw1($ext_if2 和 $ext_gw2也是同樣的),下面2行必須包括在規(guī)則集中:
    pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 \
    to any
    pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 \
    to any

    最后,NAT也可以使用在輸出接口中:
    nat on $ext_if1 from $lan_net to any -> ($ext_if1)
    nat on $ext_if2 from $lan_net to any -> ($ext_if2)

    一個(gè)完整的輸出負(fù)載均衡的例子應(yīng)該是這個(gè)樣子:
    lan_net = "192.168.0.0/24"
    int_if = "dc0"
    ext_if1 = "fxp0"
    ext_if2 = "fxp1"
    ext_gw1 = "68.146.224.1"
    ext_gw2 = "142.59.76.1"

    # nat outgoing connections on each internet interface
    nat on $ext_if1 from $lan_net to any -> ($ext_if1)
    nat on $ext_if2 from $lan_net to any -> ($ext_if2)

    # default deny
    block in from any to any
    block out from any to any

    # pass all outgoing packets on internal interface
    pass out on $int_if from any to $lan_net
    # pass in quick any packets destined for the gateway itself
    pass in quick on $int_if from $lan_net to $int_if
    # load balance outgoing tcp traffic from internal network.
    pass in on $int_if route-to \
    { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
    proto tcp from $lan_net to any flags S/SA modulate state
    # load balance outgoing udp and icmp traffic from internal network
    pass in on $int_if route-to \
    { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
    proto { udp, icmp } from $lan_net to any keep state

    # general "pass out" rules for external interfaces
    pass out on $ext_if1 proto tcp from any to any flags S/SA modulate state
    pass out on $ext_if1 proto { udp, icmp } from any to any keep state
    pass out on $ext_if2 proto tcp from any to any flags S/SA modulate state
    pass out on $ext_if2 proto { udp, icmp } from any to any keep state

    # route packets from any IPs on $ext_if1 to $ext_gw1 and the same for
    # $ext_if2 and $ext_gw2
    pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
    pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any

    編輯本段
       
    回目錄
       
    PF防火墻 - 數(shù)據(jù)包標(biāo)記
    簡介
    數(shù)據(jù)包標(biāo)記是給數(shù)據(jù)包打內(nèi)部標(biāo)記的方法,以后可以在過濾和轉(zhuǎn)換規(guī)則中使用。使用標(biāo)記,有可能做這樣的事情,比如在接口間產(chǎn)生信任關(guān)系,或者確定數(shù)據(jù)包是否已經(jīng)經(jīng)過了轉(zhuǎn)換規(guī)則處理。也可能從基于規(guī)則的過濾中移出,開始執(zhí)行基于策略的過濾。
    給數(shù)據(jù)包打標(biāo)記
    要給數(shù)據(jù)包打標(biāo)記,使用tag 關(guān)鍵字:
    pass in on $int_if all tag INTERNAL_NET keep state
    標(biāo)記 INTERNAL_NET 會增加到任何匹配上述規(guī)則的數(shù)據(jù)包中。
    注意keep state的使用; keep state (或者 modulate state/synproxy state) 在標(biāo)記數(shù)據(jù)包通過的規(guī)則中使用。
    標(biāo)記也可以通過宏來打,比如:
    name = "INTERNAL_NET"
    pass in on $int_if all tag $name keep state

    有一組預(yù)先定義的宏也可以被使用。
    * $if - 接口
    * $srcaddr - 源 IP 地址
    * $dstaddr - 目的 IP 地址
    * $srcport - 源端口
    * $dstport - 目的端口
    * $proto - 協(xié)議
    * $nr - 規(guī)則號
    這些宏在規(guī)則集裝入時(shí)擴(kuò)展,而不是運(yùn)行時(shí)。
    標(biāo)記遵循以下規(guī)則:
    * 標(biāo)記是粘性的。一旦一個(gè)標(biāo)記被匹配的規(guī)則打到一個(gè)數(shù)據(jù)包,就不能被刪除。但它可以被不同的標(biāo)記替換。
    * 由于標(biāo)記的粘性,打了標(biāo)記的數(shù)據(jù)包會一直保持,即使所有的規(guī)則都沒有使用這個(gè)標(biāo)記。
    * 一個(gè)數(shù)據(jù)包一次最多只能打一個(gè)標(biāo)記。
    * 標(biāo)記是內(nèi)部標(biāo)識符,標(biāo)記不會被送到網(wǎng)上。
    看看下面的例子:
    (1) pass in on $int_if tag INT_NET keep state
    (2) pass in quick on $int_if proto tcp to port 80 tag \
    INT_NET_HTTP keep state
    (3) pass in quick on $int_if from 192.168.1.5 keep state

    * 按照規(guī)則1,$int_if 接口上收到的數(shù)據(jù)包會打上INT_NET 標(biāo)記。
    * $int_if 接口上收到的目標(biāo)端口80的數(shù)據(jù)包根據(jù)規(guī)則1首先打上INT_NET 標(biāo)記,然后根據(jù)規(guī)則2,被INT_NET_HTTP 標(biāo)記替代。
    * $int_if 接口上收到的來自192.168.1.5的數(shù)據(jù)包根據(jù)規(guī)則3會方向,由于這是最終匹配規(guī)則,因此如果它們的目標(biāo)端口是80,則標(biāo)記是INT_NET_HTTP ,否則標(biāo)記是INT_NET 。
    標(biāo)記除了適用于過濾規(guī)則以外, nat, rdr, binat轉(zhuǎn)換規(guī)則也可以用tag關(guān)鍵字使用標(biāo)記。
    檢查數(shù)據(jù)包標(biāo)記
    要檢查先前已經(jīng)打的標(biāo)記,可以使用tagged關(guān)鍵字:
    pass out on $ext_if tagged INT_NET keep state
    在$ext_if輸出的數(shù)據(jù)包為了匹配上述規(guī)則必須打上INT_NET標(biāo)記。反轉(zhuǎn)匹配也可以使用!操作:
    pass out on $ext_if tagged ! WIFI_NET keep state
    策略過濾
    過濾策略提供了編寫過濾規(guī)則集的不同方法。定義的策略設(shè)定規(guī)則,說明哪種流量放行,哪種流量阻塞。數(shù)據(jù)包被基于傳統(tǒng)的標(biāo)準(zhǔn)如源/目的IP地址,協(xié)議等等分配到不同的策略。例如,檢查下面的防火墻策略:
    * 自內(nèi)部LAN到DMZ的流量是允許的 (LAN_DMZ)。
    * 自因特網(wǎng)到DMZ的服務(wù)器流量是允許的。 (INET_DMZ)
    * 自因特網(wǎng)被重定向到spamd(8)是允許的 (SPAMD)
    * 其他所有流量阻塞。
    注意策略是如何覆蓋所有通過防火墻的流量的。括號里面的項(xiàng)目指示這個(gè)策略項(xiàng)目將使用的標(biāo)記。
    需要過濾和轉(zhuǎn)換規(guī)則來把數(shù)據(jù)包分配到不同的策略。
    rdr on $ext_if proto tcp from to port smtp \
    tag SPAMD -> 127.0.0.1 port 8025

    block all
    pass in on $int_if from $int_net tag LAN_INET keep state
    pass in on $int_if from $int_net to $dmz_net tag LAN_DMZ keep state
    pass in on $ext_if proto tcp to $www_server port 80 tag INET_DMZ keep
    state

    現(xiàn)在要設(shè)置定義策略的規(guī)則。
    pass in quick on $ext_if tagged SPAMD keep state
    pass out quick on $ext_if tagged LAN_INET keep state
    pass out quick on $dmz_if tagged LAN_DMZ keep state
    pass out quick on $dmz_if tagged INET_DMZ keep state

    現(xiàn)在要建立整個(gè)規(guī)則集,修改分類規(guī)則。例如,如果pop3/SMTP服務(wù)器增加到了DMZ區(qū),就需要增加針對POP3和SMTP流量的分類,如下:
    mail_server = "192.168.0.10"
    ...
    pass in on $ext_if proto tcp to $mail_server port { smtp, pop3 } \
    tag INET_DMZ keep state

    Email 流量會作為INET-DMZ策略的條目被放行。t
    完整的規(guī)則:
    # macros
    int_if = "dc0"
    dmz_if = "dc1"
    ext_if = "ep0"
    int_net = "10.0.0.0/24"
    dmz_net = "192.168.0.0/24"
    www_server = "192.168.0.5"
    mail_server = "192.168.0.10"

    table persist file "/etc/spammers"
    # classification -- classify packets based on the defined firewall
    # policy.
    rdr on $ext_if proto tcp from to port smtp \
    tag SPAMD -> 127.0.0.1 port 8025

    block all
    pass in on $int_if from $int_net tag LAN_INET keep state
    pass in on $int_if from $int_net to $dmz_net tag LAN_DMZ keep state
    pass in on $ext_if proto tcp to $www_server port 80 tag INET_DMZ keep state
    pass in on $ext_if proto tcp to $mail_server port { smtp, pop3 } \
    tag INET_DMZ keep state

    # policy enforcement -- pass/block based on the defined firewall policy.
    pass in quick on $ext_if tagged SPAMD keep state
    pass out quick on $ext_if tagged LAN_INET keep state
    pass out quick on $dmz_if tagged LAN_DMZ keep state
    pass out quick on $dmz_if tagged INET_DMZ keep state

    標(biāo)記以太網(wǎng)幀
    打標(biāo)記可以在以太網(wǎng)級別進(jìn)行,如果執(zhí)行標(biāo)記/過濾的機(jī)器同時(shí)做為網(wǎng)橋。通過創(chuàng)建使用tag關(guān)鍵字的網(wǎng)橋過濾規(guī)則,PF可以建立基于源/目的MAC地址的過濾規(guī)則。網(wǎng)橋規(guī)則可以由brconfig(8)命令產(chǎn)生,例如:
    # brconfig bridge0 rule pass in on fxp0 src 0:de:ad:be:ef:0 \
    tag USER1

    然后在 pf.conf文件中:
    pass in on fxp0 tagged USER1

    編輯本段
       
    回目錄
       
    PF防火墻 - 日志

    簡介
    PF的包日志是由pflogd完成的,它通過監(jiān)聽pflog0接口然后將包以tcpdump二進(jìn)制格式寫入日志文件(一般在/val/log/pflog)。過濾規(guī)則定義的日志和log-all關(guān)鍵字所定義的日志都是以這種方式記錄的。
    讀取日志文件
    由pflogd生成的二進(jìn)制格式日志文件不能通過文本編輯器讀取,必須使用
    Tcpdump
    來查看日志。
    使用如下格式查看日志信息:
    # tcpdump -n -e -ttt -r /var/log/pflog
    使用tcpdump( 查看日志文件并不是實(shí)時(shí)的,若要實(shí)時(shí)查詢?nèi)罩拘畔⑿杓由蟨flog0參數(shù):
    # tcpdump -n -e -ttt -i pflog0
    注意:當(dāng)查看日志時(shí)需要特別注意tcpdump的詳細(xì)協(xié)議解碼(通過在命令行增加-v參數(shù)實(shí)現(xiàn))。
    Tcpdump的詳細(xì)協(xié)議解碼器并不具備完美的安全歷史,至少在理論上是這樣。日志記錄設(shè)備所記載的部分包信息可能會引發(fā)延時(shí)攻擊,因此推薦在查詢?nèi)罩疚募畔⒅跋葘⒃撊罩疚募䦶姆阑饓ι弦谱摺?br /> 另外需要注意的是對日志文件的安全訪問。默認(rèn)情況下,pflogd 將在日志文件中記錄96字節(jié)的包信息。訪問日志文件將提供訪問部分敏感包信息的途徑(就像telnet(1)或者ftp(1)的用戶名和密碼)。
    導(dǎo)出日志
    由于pflogd以tcpdump二進(jìn)制格式記錄日志信息,因此當(dāng)回顧這些日志時(shí)可以使用tcpdump的很多特點(diǎn)。例如,只查看與特定端口匹配的包:
    # tcpdump -n -e -ttt -r /var/log/pflog port 80
    甚至可以限定具體的主機(jī)和端口:
    # tcpdump -n -e -ttt -r /var/log/pflog port 80 and host 192.168.1.3
    同樣的方法可以應(yīng)用到直接從pflog0接口讀取的信息:
    # tcpdump -n -e -ttt -i pflog0 host 192.168.4.2
    注意這與包被記錄到pflogd日志文件不相沖突;上述語句只以包被記錄的形式顯示。
    除了使用標(biāo)準(zhǔn)的tcpdump(8)過濾規(guī)則外,OpenBSD的tcpdump過濾語言為讀取pflogd而被擴(kuò)展:
    * ip -IPv4版本地址。
    * ip6 - IPv6版本地址。
    * on int - 包通過int接口。
    * ifname int - 與 on int相同.
    * rulenum num - 包匹配的過濾規(guī)則編號為num。
    * action act - 對包的操作?赡苁莗ass(通過)或者block(阻斷)。
    * reason res - 執(zhí)行對包操作的原因。可能的原因是match(匹配), bad-offset, fragment, short, normalize(規(guī)格化), memory(內(nèi)存)。
    * inbound -入棧包。
    * outbound - 出棧包。
    舉例:
    # tcpdump -n -e -ttt -i pflog0 inbound and action block and on wi0
    這將以實(shí)時(shí)方式顯示被wi0接口阻斷的入棧包的日志信息。
    通過Syslog記錄日志
    很多情況下需要將防火墻的日志記錄以
    ASCII
    代碼格式存儲,或者(同時(shí))把這些日志存到遠(yuǎn)程的日志服務(wù)器上。這些可以通過兩個(gè)小的腳本文件實(shí)現(xiàn),是對 openbsd配置文件和syslogd,日志守護(hù)進(jìn)程的少許修改。Syslogd進(jìn)程以ASCII格式存儲日志,同時(shí)可以將日志存儲到遠(yuǎn)程日志服務(wù)器。
    首先必須建立一個(gè)用戶,pflogger,使用 /sbin/nologin shell.最簡單的建立用戶的方法是使用adduser(8)。
    完成后建立如下兩個(gè)腳本:
    /etc/pflogrotate
    FILE=/home/pflogger/pflog5min.$(date " %Y%m%d%H%M")
    kill -ALRM $(cat /var/run/pflogd.pid)
    if [ $(ls -l /var/log/pflog | cut -d " " -f -gt 24 ]; then
    mv /var/log/pflog $FILE
    chown pflogger $FILE
    kill -HUP $(cat /var/run/pflogd.pid)
    fi

    /home/pflogger/pfl2sysl
    for logfile in /home/pflogger/pflog5min* ; do
    tcpdump -n -e -ttt -r $logfile | logger -t pf -p local0.info
    rm $logfile
    done

    編輯root的cron 任務(wù):
    # crontab -u root -e
    增加如下兩行:
    # rotate pf log file every 5 minutes
    0-59/5 * * * * /bin/sh /etc/pflogrotate

    為用戶pflogger建立一個(gè)cron任務(wù):
    # crontab -u pflogger -e
    增加如下兩行:
    # feed rotated pflog file(s) to syslog
    0-59/5 * * * * /bin/sh /home/pflogger/pfl2sysl

    將下行增加到 /etc/syslog.conf:
    local0.info /var/log/pflog.txt
    如果需要日志記錄到遠(yuǎn)程日志服務(wù)器,增加:
    local0.info @syslogger
    確定主機(jī)syslogger已在hosts(5)中定義。
    建立文件 /var/log/pflog.txt 使 syslog 可以向該文件寫入日志:
    # touch /var/log/pflog.txt
    重啟syslogd使變化生效:
    # kill -HUP $(cat /var/run/syslog.pid)
    所有符合標(biāo)準(zhǔn)的包將被寫入/var/log/pflog.txt. 如果增加了第二行,這些信息也將被存入遠(yuǎn)程日志服務(wù)器syslogger。
    腳本 /etc/pflogrotate 將執(zhí)行,然后刪除 /var/log/pflog ,因此
    rotation of pflog by newsyslog(Cool 不再必需可以被禁用。然而, /var/log/pflog.txt 替代 /var/log/pflog and rotation of it 要被啟用。 改變 /etc/newsyslog.conf 如下:
    #/var/log/pflog 600 3 250 * ZB /var/run/pflogd.pid
    /var/log/pflog.txt 600 7 * 24

    PF 將日志以ASCII格式記錄到/var/log/pflog.txt. 如果這樣配置 /etc/syslog.conf, 系統(tǒng)將把日志存到遠(yuǎn)程服務(wù)器。存儲過程不會馬上發(fā)生,但是會在符合條件的包出現(xiàn)在文件中前5-6分鐘實(shí)現(xiàn)。

    編輯本段
       
    回目錄
       
    PF防火墻 - 性能
    “PF可以處理多少帶寬?”
    “我需要多少臺計(jì)算機(jī)處理因特網(wǎng)連接?”
    這個(gè)問題沒有簡單的答案。對于一些應(yīng)用程序來說,一臺486/66主機(jī),帶有2個(gè)比較好的ISA網(wǎng)卡在做過濾和NAT時(shí)接近5Mbps,但是對于其他應(yīng)用程序,一個(gè)更快的計(jì)算機(jī)加上更有效的PCI網(wǎng)卡也會顯得能力不足。真正的問題不是每秒處理的位數(shù)而是每秒處理的包數(shù)和規(guī)則集的復(fù)雜程度。
    體現(xiàn)PF性能的幾個(gè)參數(shù):
    * 每秒處理包的數(shù)量.
    一個(gè)1500
    字節(jié)
    的包和一個(gè)只有1個(gè)字節(jié)的包所需要的處理過程的數(shù)目幾乎是一樣的。每秒處理包的數(shù)量標(biāo)志著狀態(tài)表和過濾規(guī)則集在每秒內(nèi)被評估的次數(shù) ,標(biāo)志著一個(gè)系統(tǒng)最有效的需求(在沒有匹配的情況下)。
    * 系統(tǒng)總線性能.

    ISA
    總線最大帶寬 8MB/秒, 當(dāng)
    處理器
    訪問它時(shí), 它必須降速到80286的有效速度,不管處理器的真實(shí)處理速度如何,PCI總線有更有效的帶寬,與處理器的沖突更小。
    * 網(wǎng)卡的效率.
    一些網(wǎng)卡的工作效率要高于其他網(wǎng)卡。 基于
    Realtek 8139
    的網(wǎng)卡性能較低,而基于
    Intel 21143
    的網(wǎng)卡性能較好。為了取得更好的性能,建議使用千兆網(wǎng)卡,盡管所連接的網(wǎng)絡(luò)不是千兆網(wǎng),這些千兆網(wǎng)卡擁有高級的緩存,可以大幅提高性能。
    * 規(guī)則集的設(shè)計(jì)和復(fù)雜性。
    規(guī)則越復(fù)雜越慢。越多的包通過keep和quick方式過濾,性能越好。對每個(gè)包的策略越多,性能越差。
    * 值得一提:
    CPU 和內(nèi)存。由于PF是基于內(nèi)核的進(jìn)程,它不需要swap空間。所以,如果你有足夠的內(nèi)存,它將運(yùn)行很好,如果沒有,將受影響。不需要太大量的內(nèi)存。 32MB內(nèi)存對小型辦公室或者家庭應(yīng)用足夠,300MHz的cpu如果配置好網(wǎng)卡和規(guī)則集,足夠滿足要求。
    人們經(jīng)常詢問PF的基準(zhǔn)點(diǎn)。唯一的基準(zhǔn)是在一個(gè)環(huán)境下系統(tǒng)的性能。不考慮環(huán)境因素將影響所設(shè)計(jì)的防火墻的系統(tǒng)性能。
    PF 曾經(jīng)在非常大流量的系統(tǒng)中工作,同時(shí)PF的開發(fā)者也是它的忠實(shí)用戶。
    編輯本段
       
    回目錄
       
    PF防火墻 - 研究 FTP


    FTP 模式

    FTP
    是一種協(xié)議,它可以追溯到因特網(wǎng)發(fā)展初期,那時(shí)的因特網(wǎng)規(guī)模小,聯(lián)網(wǎng)的計(jì)算機(jī)彼此友好,過濾和嚴(yán)格安全性在那時(shí)不是必須的。FTP設(shè)計(jì)之初就沒有考慮包過濾、穿透防火墻和NAT。
    FTP的工作模式分為被動(dòng)(passive)和主動(dòng)(active)兩種。通常這兩種選擇被用來確定哪邊有防火墻問題。實(shí)際上,為了方便用戶應(yīng)該全部支持這兩種模式。
    在active模式下,當(dāng)用戶訪問遠(yuǎn)程FTP服務(wù)器并請求一個(gè)文件信息時(shí),那臺FTP服務(wù)器將與該用戶建立一個(gè)新的連接用來傳輸請求的數(shù)據(jù),這被稱為數(shù)據(jù)連接。具體過程為:客戶端隨機(jī)選擇一個(gè)端口號,在該端口監(jiān)聽的同時(shí)將端口號傳給服務(wù)器,由服務(wù)器向客戶端的該端口發(fā)起連接請求,然后傳遞數(shù)據(jù)。在 NAT后的用戶訪問FTP服務(wù)器的時(shí)候會出現(xiàn)問題,由于NAT的工作機(jī)制,服務(wù)器將向NAT網(wǎng)關(guān)的外部地址的所選端口發(fā)起連接,NAT網(wǎng)關(guān)收到該信息后將在自己的狀態(tài)表中查找該端口對應(yīng)的內(nèi)部主機(jī),由于狀態(tài)表中不存在這樣的記錄,因此該包被丟棄,導(dǎo)致無法建立連接。
    在passive模式下(OpenBSD的ftp客戶端默認(rèn)模式),由客戶端請求服務(wù)器隨機(jī)選擇一個(gè)端口并在此端口監(jiān)聽,服務(wù)器通知客戶端它所選擇的端口號,等待客戶端連接。不幸的是,ftp服務(wù)器前的防火墻可能會阻斷客戶端發(fā)往服務(wù)器的請求信息。OpenBSD的ftp(1)默認(rèn)使用 passive模式;要強(qiáng)制改為active模式,使用-A參數(shù),或者在“ftp>”提示符下使用命令“passive off”關(guān)閉 passive模式。
    工作在防火墻之后的FTP客戶端
    如前所述,F(xiàn)TP對NAT和防火墻支持不好。
    包過濾機(jī)制通過將FTP數(shù)據(jù)包重定向到一個(gè)FTP代理服務(wù)器解決這一問題。這一過程將引導(dǎo)FTP數(shù)據(jù)包通過NAT網(wǎng)關(guān)/防火墻。OpenBSD和PF使用的FTP代理是ftp-proxy(8),可以通過在pf.conf中的NAT章節(jié)增加下列信息激活該代理:
    rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \
    port 8021

    這條語句的解釋為:在內(nèi)部接口上的ftp數(shù)據(jù)包被重定向到本機(jī)的8021端口
    顯然該代理服務(wù)器應(yīng)該已在OpenBSD中啟動(dòng)并運(yùn)行。配置方法為在/etc/inetd.conf中增加下列信息:
    127.0.0.1:8021 stream tcp nowait root /usr/libexec/ftp-proxy \
    ftp-proxy

    重啟系統(tǒng)或者通過下列命令發(fā)送一個(gè)‘HUP’標(biāo)記來生效:
    kill -HUP `cat /var/run/inetd.pid`
    ftp代理在8021端口監(jiān)聽,上面的rdr語句也是將數(shù)據(jù)包轉(zhuǎn)發(fā)到這一端口。這一端口號是可選的,因?yàn)?021端口沒有被其他應(yīng)用程序占用,因此不失為一個(gè)好的選擇。
    請注意ftp-proxy(8)是用來幫助位于PF過濾器后的ftp客戶端傳遞信息;并不用于PF過濾器后的ftp服務(wù)器。
    PF“自保護(hù)”FTP服務(wù)器
    當(dāng)PF運(yùn)行在一個(gè)FTP服務(wù)器上,而不是單獨(dú)的一臺防火墻。這種情況下處理passive模式的FTP連接請求時(shí)FTP服務(wù)器將隨機(jī)取一個(gè)較大的 TCP端口接收數(shù)據(jù)。默認(rèn)情況下OpenBSD的本地FTP服務(wù)器ftpd(8)使用49152~65535范圍內(nèi)的端口,顯然,必須要有對應(yīng)的過濾規(guī)則放行這些端口的數(shù)據(jù):
    pass in on $ext_if proto tcp from any to any port 21 keep state
    pass in on $ext_if proto tcp from any to any port > 49151 \
    keep state

    如果需要可以調(diào)整上述端口范圍。在OpenBSD的ftpd(8)環(huán)境下,可以通過sysctl(8)進(jìn)行調(diào)整 net.inet.ip.porthifirst 和net.inet.ip.porthilast。
    使用NAT外部 PF防火墻保護(hù)FTP服務(wù)器
    這種情況下,防火墻必須將數(shù)據(jù)重定向到FTP服務(wù)器。為了討論方便,我們假設(shè)該FTP服務(wù)器使用標(biāo)準(zhǔn)的OpenBSD ftpd(8),并使用默認(rèn)端口范圍。
    這里有個(gè)例子
    ftp_server = "10.0.3.21"
    rdr on $ext_if proto tcp from any to any port 21 -> $ftp_server \
    port 21
    rdr on $ext_if proto tcp from any to any port 49152:65535 -> \
    $ftp_server port 49152:65535

    # in on $ext_if
    pass in quick on $ext_if proto tcp from any to $ftp_server \
    port 21 keep state
    pass in quick on $ext_if proto tcp from any to $ftp_server \
    port > 49151 keep state

    # out on $int_if
    pass out quick on $int_if proto tcp from any to $ftp_server \
    port 21 keep state
    pass out quick on $int_if proto tcp from any to $ftp_server \
    port > 49151 keep state

    FTP的更多信息
    過濾FTP和FTP如何工作的更多信息可以參考下面的白皮書。
    編輯本段
       
    回目錄
       
    PF防火墻 - 驗(yàn)證: 用Shell 進(jìn)行網(wǎng)關(guān)驗(yàn)證
    簡介
    Authpf
    (Cool是身份認(rèn)證網(wǎng)關(guān)的用戶shell。身份認(rèn)證網(wǎng)關(guān)類似于普通網(wǎng)關(guān),只不過用戶必須在網(wǎng)關(guān)上通過身份驗(yàn)證后才能使用該網(wǎng)關(guān)。當(dāng)用戶 shell被設(shè)置為/usr/sbin/authpf時(shí)(例如,代替了ksh(1),csh(1)等),并且用戶通過SSH登錄,authpf將對pf (4)策略集做必要的修改以便該用戶的數(shù)據(jù)包可以通過過濾器或者(和)使用NAT、重定向功能。一旦用戶退出登錄或者連接被斷開,authpf將移除加載到該用戶上的所有策略,同時(shí)關(guān)閉該用戶打開的所有會話。因此,只有當(dāng)用戶保持著他的SSH會話進(jìn)程時(shí)他才具備透過防火墻發(fā)送數(shù)據(jù)包的能力。
    Authpf通過向附加到錨點(diǎn)的命名策略集增加策略來改變pf(4)的策略集。每次用戶進(jìn)行身份驗(yàn)證,authpf建立一個(gè)新的命名策略集,并將已經(jīng)配置好的filter、nat、binat和rdr規(guī)則加載上去。被authpf所加載的策略可以被配置為針對單獨(dú)的一個(gè)用戶相關(guān)或者針對總體。
    Authpf可以應(yīng)用在:
    * 在允許用戶訪問因特網(wǎng)之前進(jìn)行身份驗(yàn)證。
    * 賦予特殊用戶訪問受限網(wǎng)絡(luò)的權(quán)利,例如管理員。
    * 只允許特定的無線網(wǎng)絡(luò)用戶訪問特定的網(wǎng)絡(luò)。
    * 允許公司員工在任何時(shí)候訪問公司網(wǎng)絡(luò),而公司之外的用戶不能訪問,并可以將這些用戶重定向到特定的基于用戶名的資源(例如他們自己的桌面)。
    * 在類似圖書館這樣的地方通過PF限制guest用戶對因特網(wǎng)的訪問。Authpf可以用來向已注冊用戶開放完全的因特網(wǎng)連接。
    Authpf通過syslogd(8)記錄每一個(gè)成功通過身份驗(yàn)證用戶的用戶名、IP地址、開始結(jié)束時(shí)間。通過這些信息,管理員可以確定誰在何時(shí)登陸,也使得用戶對其網(wǎng)絡(luò)流量負(fù)責(zé)。
    配置
    配置authpf的基本步驟大致描述如下。詳細(xì)的信息請查看man手冊。
    將authpf連入主策略集
    通過使用錨點(diǎn)策略將authpf連入主策略集:
    nat-anchor authpf
    rdr-anchor authpf
    binat-anchor authpf
    anchor authpf
    錨點(diǎn)策略放入策略集的位置就是PF中斷執(zhí)行主策略集轉(zhuǎn)為執(zhí)行authpf策略的位置。上述4個(gè)錨點(diǎn)策略并不需要全部存在,例如,當(dāng)authpf沒有被設(shè)置加載任何nat策略時(shí),nat-anchor策略可被省略。
    配置加載的策略
    Authpf通過下面兩個(gè)文件之一加載策略:
    * /etc/authpf/users/$USER/authpf.rules
    * /etc/authpf/authpf.rules

    第一個(gè)文件包含只有當(dāng)用戶$USER(將被替換為具體的用戶名)登錄時(shí)才被加載的策略。當(dāng)特殊用戶(例如管理員)需要一系列不同于其他默認(rèn)用戶的策略集時(shí)可以使用每用戶策略配置。第二個(gè)文件包含沒定義自己的authpf.rules文件的用戶所默認(rèn)加載的策略。如果用戶定義的文件存在,將覆蓋默認(rèn)文件。這兩個(gè)文件至少存在其一,否則authpf將不會工作。
    過濾器和傳輸策略與其他的PF策略集語法一樣,但有一點(diǎn)不同:authpf允許使用預(yù)先定義的宏:
    * $user_ip �C 登錄用戶的IP地址
    * $user_id �C 登錄用戶的用戶名
    推薦使用宏$user_ip,只賦予通過身份驗(yàn)證的計(jì)算機(jī)透過防火墻的權(quán)限。
    訪問控制列表
    可以通過在/etc/authpf/banned/目錄下建立以用戶名命名的文件來阻止該用戶使用authpf。文件的內(nèi)容將在authpf斷開與該用戶的連接之前顯示給他,這為通知該用戶被禁止訪問的原因并告知他解決問題聯(lián)系人提供了一個(gè)便捷的途徑。
    相反,有可能只允許特定的用戶訪問,這時(shí)可以將這些用戶的用戶名寫入/etc/authpf/authpf.allow文件。如果該文件不存在或者文件中輸入了“*”,則authpf將允許任何成功通過SSH登錄的用戶進(jìn)行訪問(沒有被明確禁止的用戶)。
    如果authpf不能斷定一個(gè)用戶名是被允許還是禁止,它將打印一個(gè)摘要信息并斷開該用戶的連接。明確禁止將會使明確允許失效。
    將authpf配置為用戶shell
    authpf必須作為用戶的登錄shell才能正常工作。當(dāng)用戶成功通過sshd(8)登錄后,authpf將被作為用戶的shell執(zhí)行。它將檢查該用戶是否有權(quán)使用authpf,并從適當(dāng)?shù)奈募屑虞d策略,等等。
    有兩種途徑將authpf設(shè)置為用戶shell:
    1.為每個(gè)用戶手動(dòng)使用chsh(1), vipw(Cool, useradd(Cool, usermod(Cool,等。
    2.通過把一些用戶分配到一個(gè)登錄類,在文件/etc/login.conf中改變這個(gè)登錄類的shell屬性
    查看登陸者
    一旦用戶成功登錄,并且authpf調(diào)整了PF的策略,authpf將改變它的進(jìn)程名以顯示登錄者的用戶名和IP地址:
    # ps -ax | grep authpf
    23664 p0 Is 0:00.11 -authpf:
    charlie@192.168
    (authpf)
    在這里用戶chalie從IP地址為192.168.1.3的主機(jī)登錄。用戶可以通過向authpf進(jìn)程發(fā)送SIGTERM信號退出登錄。Authpf也將移除加載到該用戶上的策略并關(guān)閉任何該用戶打開的會話連接。
    # kill -TERM 23664
    實(shí)例
    OpenBSD網(wǎng)關(guān)通過authpf對一個(gè)大型校園無線網(wǎng)的用戶進(jìn)行身份驗(yàn)證。一旦某個(gè)用戶驗(yàn)證通過,假設(shè)他不在禁用列表中,他將被允許SSH并訪問網(wǎng)頁(包括安全網(wǎng)站https),也可以訪問該校園的任一個(gè)DNS服務(wù)器。
    文件 /etc/authpf/authpf.rules包含下列策略:
    wifi_if = "wi0"
    dns_servers = "{ 10.0.1.56, 10.0.2.56 }"

    pass in quick on $wifi_if proto udp from $user_ip to $dns_servers \
    port domain keep state
    pass in quick on $wifi_if proto tcp from $user_ip to port { ssh, http, \
    https } flags S/SA keep state

    管理員charlie除了網(wǎng)頁沖浪和使用SSH外還需要訪問校園網(wǎng)的SMTP和POP3服務(wù)器。下列策略被配置在/etc/authpf/users/charlie/authpf.rules 中:
    wifi_if = "wi0"
    smtp_server = "10.0.1.50"
    pop3_server = "10.0.1.51"
    dns_servers = "{ 10.0.1.56, 10.0.2.56 }"

    pass in quick on $wifi_if proto udp from $user_ip to $dns_servers \
    port domain keep state
    pass in quick on $wifi_if proto tcp from $user_ip to $smtp_server \
    port smtp flags S/SA keep state
    pass in quick on $wifi_if proto tcp from $user_ip to $pop3_server \
    port pop3 flags S/SA keep state
    pass in quick on $wifi_if proto tcp from $user_ip to port { ssh, http, \
    https } flags S/SA keep state

    定義在/etc/pf.conf中的主策略集配置如下:
    # macros
    wifi_if = "wi0"
    ext_if = "fxp0"

    scrub in all
    # filter
    block drop all

    pass out quick on $ext_if proto tcp from $wifi_if:network flags S/SA \
    modulate state
    pass out quick on $ext_if proto { udp, icmp } from $wifi_if:network \
    keep state

    pass in quick on $wifi_if proto tcp from $wifi_if:network to $wifi_if \
    port ssh flags S/SA keep state

    anchor authpf in on $wifi_if
    該策略集非常簡單,作用如下:
    * 阻斷所有(默認(rèn)拒絕)。
    * 放行外部網(wǎng)卡接口上的來自無線網(wǎng)絡(luò)并流向外部的TCP,UDP和ICMP數(shù)據(jù)包。
    * 放行來自無線網(wǎng)絡(luò),目的地址為網(wǎng)關(guān)本身的SSH數(shù)據(jù)包。該策略是用戶登錄所必須的。
    * 在無線網(wǎng)絡(luò)接口上為流入數(shù)據(jù)建立錨點(diǎn)“authpf”。
    設(shè)計(jì)主策略集的主導(dǎo)思想為:阻斷任何包并允許盡可能小的數(shù)據(jù)流通過。在外部接口上流出數(shù)據(jù)包是允許的,但是默認(rèn)否策略阻斷了由無線接口進(jìn)入的數(shù)據(jù)包。用戶一旦通過驗(yàn)證,他們的數(shù)據(jù)包被允許通過無線接口進(jìn)入并穿過網(wǎng)關(guān)到達(dá)其他網(wǎng)絡(luò)。

    編輯本段
       
    回目錄
       
    PF防火墻 - 實(shí)例:家庭和小型辦公室防火墻

    概況
    在這個(gè)例子中,PF作為防火墻和NAT網(wǎng)關(guān)運(yùn)行在OpenBSD機(jī)器上,為家庭或辦公室的小型網(wǎng)絡(luò)提供服務(wù)。總的目標(biāo)是向內(nèi)部網(wǎng)提供因特網(wǎng)接入,允許從因特網(wǎng)到防火墻的限制訪問。下面將詳細(xì)描述:
    網(wǎng)絡(luò)
    網(wǎng)絡(luò)配置如下:
    [ COMP1 ] [ COMP3 ]
    | | ADSL
    --- ------ ----- ------- fxp0 [ OpenBSD ] ep0 -------- ( 因特網(wǎng) )
    |
    [ COMP2 ]
    內(nèi)部網(wǎng)有若干機(jī)器,圖中只劃出了3臺,這些機(jī)器除了COMP3之外主要進(jìn)行網(wǎng)頁沖浪、電子郵件、聊天等;COMP3運(yùn)行一個(gè)小型web服務(wù)器。內(nèi)部網(wǎng)使用192.168.0.0/24網(wǎng)段。
    OpenBSD網(wǎng)關(guān)運(yùn)行在 Pentium 100計(jì)算機(jī)上,裝有兩塊網(wǎng)卡:一個(gè)3com 3c509B(ep0),另一個(gè) Intel EtherExpress Pro/100(fxp0)。該網(wǎng)關(guān)通過ADSL連接到因特網(wǎng),同時(shí)通過NAT向內(nèi)網(wǎng)共享因特網(wǎng)連接。外部網(wǎng)卡的 IP地址動(dòng)態(tài)分配。
    目標(biāo)
    * 向內(nèi)部網(wǎng)絡(luò)的每臺計(jì)算機(jī)提供無限制的因特網(wǎng)接入。
    * 啟用一條“默認(rèn)拒絕”策略。
    * 允許下列來自因特網(wǎng)的請求訪問防火墻:
    SSH (TCP 端口 22): 用來遠(yuǎn)程維護(hù)防火墻。
    Auth/Ident (TCP 端口 113): SMTP和IRC服務(wù)用到的端口。
    ICMP Echo Requests: ping(8)用到的ICMP包類型。
    * 重定向訪問80端口(訪問web的請求)的請求到計(jì)算機(jī)COMP3,同時(shí),允許指向COMP3計(jì)算機(jī)的80端口的數(shù)據(jù)流過防火墻。
    * 記錄外部網(wǎng)卡接口上的過濾日志。
    * 默認(rèn)為阻斷的包返回一個(gè) TCP RST 或者 ICMP Unreachable 信息。
    * 盡量保持策略集簡單并易于維護(hù)。
    準(zhǔn)備
    這里假設(shè)作為網(wǎng)關(guān)的OpenBSD主機(jī)已經(jīng)配置完成,包括IP網(wǎng)絡(luò)配置,因特網(wǎng)連接和設(shè)置net.inet.ip.forwarding 的值為1。
    規(guī)則集
    下面將逐步建立策略集以滿足上訴要求。

    定義下列宏以增強(qiáng)策略集的可維護(hù)性和可讀性:
    int_if = "fxp0"
    ext_if = "ep0"

    tcp_services = "{ 22, 113 }"
    icmp_types = "echoreq"

    priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"
    comp3 = "192.168.0.3"
    前兩行定義了發(fā)生過濾的網(wǎng)絡(luò)接口。第3、4行定義了向因特網(wǎng)開放的服務(wù)端口號(SSH和ident/auth)和允許訪問防火墻的ICMP包類型。第5行定義了回送地址段和RFC1918定義的私有地址段。最后一行定義了主機(jī)COMP3的IP地址。
    注意:如果ADSL接入因特網(wǎng)需要PPPoE,則過濾和NAT將發(fā)生在tun0接口上而不是ep0接口。
    選項(xiàng)
    下列兩個(gè)選項(xiàng)用來設(shè)置阻斷后的默認(rèn)操作為反饋,并在外部接口設(shè)置開啟日志記錄:
    set block-policy return
    set loginterface $ext_if

    流量整修
    沒有理由不起用對所有進(jìn)入防火墻的所有包進(jìn)行規(guī)格化,因此只需要簡單的一行:
    scrub in all
    NAT(網(wǎng)絡(luò)地址轉(zhuǎn)換)
    為所有內(nèi)部網(wǎng)啟用NAT可以通過下列策略:
    nat on $ext_if from $int_if:network to any -> ($ext_if)
    由于外部網(wǎng)卡的IP地址是動(dòng)態(tài)獲得的,因此在外部網(wǎng)卡接口處增加小括號以使當(dāng)IP地址發(fā)生變化時(shí)PF可以自適應(yīng)。
    重定向
    第一個(gè)需要重定向策略的是ftp-proxy(8),只有這樣內(nèi)部網(wǎng)上的FTP客戶端才可以訪問因特網(wǎng)上的FTP服務(wù)器。
    rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
    注意這條策略只捕獲到21端口的數(shù)據(jù)包,如果用戶通過其他端口訪問FTP服務(wù)器,則在定義目的端口時(shí)需要使用list(列表),例如: from any to any port { 21, 2121 }。
    第二個(gè)重定向策略捕獲因特網(wǎng)上的用戶訪問防火墻80端口的數(shù)據(jù)包。用戶試圖訪問網(wǎng)絡(luò)的web服務(wù)器時(shí)將產(chǎn)生合法的訪問該端口的數(shù)據(jù)包,這些連接請求需要重定向到主機(jī)COMP3:
    rdr on $ext_if proto tcp from any to any port 80 -> $comp3
    過濾規(guī)則
    過濾規(guī)則第一行是默認(rèn)否規(guī)則:
    block all
    這時(shí)沒有任何數(shù)據(jù)包可以流過防火墻,甚至來自內(nèi)部網(wǎng)絡(luò)的數(shù)據(jù)包。下面的規(guī)則將逐個(gè)依據(jù)上面提到的目標(biāo)開啟防火墻上的虛擬接口。
    每個(gè)Unix系統(tǒng)都有一個(gè)“l(fā)oopback(回送)”接口,它是用于系統(tǒng)中應(yīng)用程序間通信的虛擬網(wǎng)絡(luò)接口。在OpenBSD中,回送接口是lo(4)。
    pass quick on lo0 all
    下一步,由RFC 1918定義的私有地址將在外部網(wǎng)卡接口的進(jìn)和出方向被阻斷。這些地址不應(yīng)該出現(xiàn)在公網(wǎng)上,通過阻斷這些地址可以保證防火墻不向外部網(wǎng)泄漏內(nèi)網(wǎng)地址,同時(shí)也阻斷了來自外部網(wǎng)中源地址為這些私有地址的數(shù)據(jù)包流入內(nèi)網(wǎng)。
    block drop in quick on $ext_if from $priv_nets to any
    block drop out quick on $ext_if from any to $priv_nets

    這里block drop用來通知PF停止反饋TCP RST或者ICMP Unreachabel 數(shù)據(jù)包。因?yàn)镽FC 1918規(guī)定的地址不會存在于因特網(wǎng)上,發(fā)往那些地址的數(shù)據(jù)包將沒有意義。Quick 選項(xiàng)用來通知PF如果這條規(guī)則匹配則不再進(jìn)行其他規(guī)則的匹配操作,來自或流向$ priv_nets的數(shù)據(jù)包將被立即丟棄。
    現(xiàn)在將打開因特網(wǎng)上的一些服務(wù)所用到的端口:
    pass in on $ext_if inet proto tcp from any to ($ext_if) \
    port $tcp_services flags S/SA keep state

    通過在宏$tcp_services中定義服務(wù)端口可以更方便的進(jìn)行維護(hù)。開放UDP服務(wù)也可一模仿上述語句,只不過改為proto udp。
    已經(jīng)有了一條rdr策略將web訪問請求轉(zhuǎn)發(fā)到主機(jī)COMP3上,我們必須建立另一條過濾規(guī)則使得這些訪問請求可以通過防火墻:
    pass in on $ext_if proto tcp from any to $comp3 port 80 \
    flags S/SA synproxy state

    考慮到安全問題,我們使用
    TCP SYN Proxy
    保護(hù)web服務(wù)器――
    synproxy state
    。
    現(xiàn)在將允許ICMP包通過防火墻:
    pass in inet proto icmp all icmp-type $icmp_types keep state
    類似于宏$tcp_services,當(dāng)需要增加允許進(jìn)入防火墻的ICMP數(shù)據(jù)包類型時(shí)可以容易地編輯宏$icmp_types。注意這條策略將應(yīng)用于所有網(wǎng)絡(luò)接口。
    現(xiàn)在數(shù)據(jù)流必須可以正常出入內(nèi)部網(wǎng)絡(luò)。我們假設(shè)內(nèi)網(wǎng)的用戶清楚自己的所作所為并且確定不會導(dǎo)致麻煩。這并不是必然有效的假設(shè),在某些環(huán)境下更具限制性的策略集會更適合。
    pass in on $int_if from $int_if:network to any keep state
    上面的策略將允許內(nèi)網(wǎng)中的任何計(jì)算機(jī)發(fā)送數(shù)據(jù)包穿過防火墻;然而,這并沒有允許防火墻主動(dòng)與內(nèi)網(wǎng)的計(jì)算機(jī)建立連接。這是一種好的方法嗎?評價(jià)這些需要依靠網(wǎng)絡(luò)配置的一些細(xì)節(jié)。如果防火墻同時(shí)充當(dāng)DHCP服務(wù)器,它需要在分配一個(gè)地址之前ping一下該地址以確認(rèn)該地址沒有被占用。允許防火墻訪問內(nèi)部網(wǎng)絡(luò)同時(shí)也允許了在因特網(wǎng)上通過ssh控制防火墻的用戶訪問內(nèi)網(wǎng)。請注意禁止防火墻直接訪問內(nèi)網(wǎng)并不能帶來高安全性,因?yàn)槿绻粋(gè)用戶可以訪問防火墻,他也可以改變防火墻的策略。增加下列策略可以使防火墻具備訪問內(nèi)網(wǎng)的能力:
    pass out on $int_if from any to $int_if:network keep state
    如果這些策略同時(shí)存在,則keep state選項(xiàng)將不是必須的;所有的數(shù)據(jù)包都可以流經(jīng)內(nèi)網(wǎng)接口,因?yàn)橐粭l策略規(guī)定了雙向放行數(shù)據(jù)包。然而,如果沒有pass out這條策略時(shí),pass in策略必須要有keep state選項(xiàng)。這也是keep state的有點(diǎn)所在:在執(zhí)行策略匹配之前將先進(jìn)行state表檢查,如果state表中存在匹配記錄,數(shù)據(jù)包將直接放行而不比再進(jìn)行策略匹配。這將提高符合比較重的防火墻的效率。
    最后,允許流出外部網(wǎng)卡接口的數(shù)據(jù)包通過防火墻
    pass out on $ext_if proto tcp all modulate state flags S/SA
    pass out on $ext_if proto { udp, icmp } all keep state

    TCP, UDP, 和 ICMP數(shù)據(jù)包將被允許朝因特網(wǎng)的方向出防火墻。State信息將被保存,以保證反饋回來的數(shù)據(jù)包通過防火墻。
    完整規(guī)則集
    # macros
    int_if = "fxp0"
    ext_if = "ep0"

    tcp_services = "{ 22, 113 }"
    icmp_types = "echoreq"

    priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"
    comp3 = "192.168.0.3"
    # options
    set block-policy return
    set loginterface $ext_if

    # scrub
    scrub in all

    # nat/rdr
    nat on $ext_if from $int_if:network to any -> ($ext_if)
    rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \
    port 8021
    rdr on $ext_if proto tcp from any to any port 80 -> $comp3

    # filter rules
    block all

    pass quick on lo0 all
    block drop in quick on $ext_if from $priv_nets to any
    block drop out quick on $ext_if from any to $priv_nets

    pass in on $ext_if inet proto tcp from any to ($ext_if) \
    port $tcp_services flags S/SA keep state

    pass in on $ext_if proto tcp from any to $comp3 port 80 \
    flags S/SA synproxy state

    pass in inet proto icmp all icmp-type $icmp_types keep state
    pass in on $int_if from $int_if:network to any keep state
    pass out on $int_if from any to $int_if:network keep state

    pass out on $ext_if proto tcp all modulate state flags S/SA
    pass out on $ext_if proto { udp, icmp } all keep state

    編輯本段
       
    回目錄
       
    PF防火墻 - 參考資料
    http://www.freebsdchina.org/forum/topic_24641.html
    http://www.google.com

    轉(zhuǎn)自:http://www.hudong.com/wiki/PF%E9%98%B2%E7%81%AB%E5%A2%99

    本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u2/63141/showart_2145993.html
  • 您需要登錄后才可以回帖 登錄 | 注冊

    本版積分規(guī)則 發(fā)表回復(fù)

      

    北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年舉報(bào)專區(qū)
    中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
    感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP