PF設定編寫

因 pf 是last match,..所以順序錯了,就連不上網了
Macro:定義網路介面
Tables:管理 IP List
Options:選項設定
Traffic Normalization:通訊正常化
Queueing:(ALTQ)定義頻寬控制的進出
Translation:(NAT)定義封包轉換
Packet Filtering:定義防火牆規則

參考資料:
http://blog.tenyi.com/2007/05/windows-vpn-port.html
http://www.freebsd.org/doc/zh_TW/books/handbook/firewalls-pf.html
http://www.freebsd.org/cgi/man.cgi?query=pf.conf&sektion=5
http://www.openbsd.org/faq/pf
http://www.chmhome.com/knowledge/bsd/20070622/24064.html
http://www.freebsdchina.org/forum/topic_24641.html
http://www.weithenn.org/cgi-bin/wiki.pl?PF-%E5%88%A9%E7%94%A8_PF_%E8%BC%95%E9%AC%86%E9%81%94%E6%88%90_NAT
一、Macros 定義網路介面

ext_if="fxp0"
int_if="xl0"
jam2 = "192.168.2.0/24"
ext_ip = "163.20.39.57"

二、Tables:管理 IP List
可以利用 table 可以一次管理很多的 IP,也可以把IP 列在一個檔案中,每行一個IP。
Tables在定義時可以使用下面兩個屬性選項:
1.persist:
告訴kernel即使沒有任何規則使用到這個tables也不會清除它。如果不設置,內核在最後一個規則引用這個table後自動清除它。
2.const:
使用這個參數創建的表只能在創建時設置,可防止用戶在運行中修改它。如果沒這個選項,即使在securelevel(7)=2時,pfctl 也可以隨時對這個tables作修改。

table <private> const { 10/8, 172.16/12, 192.168/16 }
table <badhosts> persist
block on fxp0 from { <private> , <badhosts> } to any

創建一table名為private,存有RFC 1918定義的私有網絡地址;另定義一個空table badhosts。過濾規則block所有從這兩tables發來的傳輸。private table不能作任何修改,badhosts table即使沒有活動規則使用它也會一直存在。在以後可以添加地址到badhosts table,下面例子中的那些地址的傳輸會被blocked:

# pfctl -t badhosts -Tadd 204.92.77.111

table在初始化時可從一個或多個外部文件讀取一連串的地址列表,使用下面的語法:

table <spam> persist file "/etc/spammers" file "/etc/openrelays"
block on fxp0 from <spam> to any

範例二:

table <goodguys> { 192.0.2.0/24 }
table <rfc1918> const { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
table <spammers> persist
block in on fxp0 from { <rfc1918>, <spammers> } to any
pass  in on fxp0 from <goodguys> to any
(也可以用不包含某 IP 的方式):
table <goodguys> { 192.0.2.0/24, !192.0.2.5 }

三、Options:選項設定
可使用set設置pf遇到的各種情況。
set timeout
interval:清除生存期滿的狀態和fragments的時間間隔。
frag:一個未分片的fragment的生存期。
set loginterface
可在給定的網卡上收集數據包及傳輸量的統計信息。這些統計信息查看使用:
# pfctl -s info
在下面的例子中,pf將收集在接口dc0上的各類統計信息:
set loginterface dc0
四、Traffic Normalization:通訊正常化
通訊正常化用於清除收到的一些意思不明確的數據包。標準器將IP碎片重組來防止攻擊者發送大量IP碎片搞亂服務器檢測達到入侵的目的。數據包正常化由scrub使用。
五、Queueing:(ALTQ)定義頻寬控制的進出

#Outgoing bandwidth limit
altq on $ext_if cbq bandwidth 512Kb queue { std_out }
queue std_out bandwidth 256Kb cbq (default)
#Incoming bandwidth limit
altq on $int_if cbq bandwidth 2Mb queue { std_in }
queue std_in bandwidth 768Kb cbq (default borrow)

六、Translation:(NAT)定義封包轉換
nat(網絡地址轉換)
一個nat規則具體指定通過指定端口的IP地址的變化。
這項技術允許內部網絡的IP映射到轉換主機的一個或多個的IP地址(外部)。
從原理來看內部的網絡可以使用任何IP地址,但是NAT只允許使用RFC1918中定義的保留地址族。
rdr(重定向)
數據包被重定向發往指定的地址,端口也可能不同,重定向規則可以靈活指定端口範圍,而不是單一的端口。

rdr ... port 2000:2999 -> ... port 4000

此規則將端口2000到2999(包含2000和2999)重定向到端口4000

rdr ... port 2000:2999 -> ... port 4000:*

此規則將端口2000到2999(包含2000和2999)重定向,對應的方式是2000->4000,2001->4001,...,2999->4999

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
nat on $ext_if from $jam2 to any -> $ext_ip

如果防火牆和 Proxy Server 不在同一台主機(Proxy Server:192.168.13.250):

no rdr on rl0 proto tcp from 192.168.13.250 to any port 80
rdr on rl0 proto tcp from 192.168.13.0/24 to any port 80 -> 192.168.13.250 port 3128

七、Packet Filtering:定義防火牆規則
每個數據包都要按自上至下的順序按規則進行過濾。默認情況下,數據包被標記為通過,這個可以被任一規則改變,在到達最後一條規則前可以被來回改變多次,最後的匹配規則是「獲勝者」。存在一個例外是:過濾規則中的quick關鍵字具有取消進一步往下處理的作用,使得規則指定的動作馬上執行。看一下下面的例子:
錯誤:
block in on fxp0 proto tcp from any to any port ssh
pass in all
在這樣的條件下,block行會被檢測,但永遠也不會有效果,因為它後面的一行允許所有的流量通過。
正確:

block in quick on fxp0 proto tcp from any to any port ssh
pass in all

這些規則執行的結果稍有不同,如果block行被匹配,由於quick選項的原因,數據包會被阻塞,而且剩下的規則也會被忽略。
要讓client 的ftp可以正常使用,要加入一條:

pass in on $ext_if inet proto tcp from any to $ext_if port > 55000 keep state
pass in on $ext_if inet proto tcp from any to $ext_if port 20 flags S/SA modulate state

狀態保持:
當一條規則使用了 keep state 選項,第一個匹配這條規則的數據包在收發雙方之間建立了一個狀態。現在,不僅發送者到接收者之間的數據包匹配這個狀態繞過規則檢驗,而且接收者回覆發送者的數據包也是同樣的。例如:

pass out on fxp0 proto tcp from any to any keep state

這允許fxp0接口上的任何TCP流量通過,並且允許返回的流量通過防火牆。狀態保持是一個非常有用的特性,由於狀態查詢比使用規則進行數據包檢驗快的多,因此它可以大幅度提高防火牆的性能。
八、Bandwidth Control (看哪些 port 或是 ip 要套到個別的頻寬)

pass out on $ext_if proto tcp from any to any queue std_out
pass in on $int_if proto tcp from any to any queue std_in

以下是防火牆規則範例:(以Windows VPN 需要在防火牆開的port為例)
TCP port 1723
UDP port 500、1701、4500
IP protocol 47與50
以下是 pf.conf 裡的設定:

# VPN的NAT
nat on $ext_if from $vpn_ip to any -> $ext_vpn_ip
# VPN 轉 port
rdr on $ext_if proto tcp from any to $ext_vpn_ip port 1723 -> $vpn_ip port 1723
rdr on $ext_if proto udp from any to $ext_vpn_ip port 1701 -> $vpn_ip port 1701
rdr on $ext_if proto {47, 50} from any to $ext_vpn_ip -> $vpn_ip
rdr on $ext_if proto udp from any to $ext_vpn_ip port 4500 -> $vpn_ip port 4500
rdr on $ext_if proto udp from any to $ext_vpn_ip port 500 -> $vpn_ip port 500
rdr on $ext_if proto udp from any to $ext_vpn_ip port 1701 -> $vpn_ip port 1701

Weithenn 的範例,我覺得還不錯,可以參考:
(用 PF 當成 Gateway,負責的服務有 NAT (2 Routing)、WAN to DMZ 及 LAN to DMZ 的 Port Forwarding、Block Bad User IP)
/etc/rc.conf:

 ### TFN FTTB ###
 defaultrouter="219.20.230.254"                               #TFN
 ifconfig_em0="inet 219.22.22.222  netmask 255.255.255.0"
 ### Hinet ADSL ###
 ifconfig_bge0="inet 202.60.43.111  netmask 255.255.255.0"
 ### DMZ Interface ###
 ifconfig_em1="inet 192.168.10.1  netmask 255.255.255.0"
 ### LAN Interface ###
 ifconfig_em2="inet 192.168.20.1  netmask 255.255.255.0"
 ifconfig_em2_alias0="inet 192.168.10.2  netmask 255.255.255.255" # DMZ Mail
 ifconfig_em2_alias1="inet 192.168.10.8  netmask 255.255.255.255" # DMZ FTP
 ifconfig_em2_alias2="inet 192.168.10.9  netmask 255.255.255.255" # DMZ LDAP
 #NAT
 gateway_enable="YES"
 #PF
 pf_enable="YES"
 pflog_enable="YES"

/etc/pf.conf:

 ###Macros###
 ext_if1="em0"                          #TFN
 ext_if2="bge0"                         #Hinet
 dmz_if="em1"                           #DMZ
 lan_if="em2"                           #LAN
 dmz_net="192.168.10.0/24"              #DMZ Subnet
 lan_net="192.168.20.0/24"              #LAN Subnet
 weithenn_home="61.60.59.58/32"         #Weithenn Home IP
 hinet_gw="202.60.43.254/32"            #Routing to Hinet Gateway
 Allow_ftp_ip="{ 61.60.59.58/32 }"      #Allow FTP IP List
 icmp_types = "echoreq"                 #ICMP
 lan_use_icmp="{ 192.168.20.137/32 }"   #Allow Lan User Use ICMP List
 lan_bt="{ 192.168.20.171/32 }"         #Lan User Use BT ? Block it
 ###Tables###
 table <ssh-bruteforce> persist
 ###Options###
 set skip on lo0
 set block-policy return
 ###Scrub###
 scrub in all
 ###NAT/RDR###
 ###1.Lan User Default Routing go TFN
 ###2.If Lan User will Change Routing go Hinet Please Remark 41,85
 ###3.If Lan User will Change Routing go KBT Please Remark 82
 #NAT on TFN (Primary Gateway)
 nat on $ext_if1 from { $dmz_net $lan_net } to any -> ($ext_if1)
 #NAT on Hinet (Backup Gateway)
 nat on $ext_if2 from $lan_net to any -> ($ext_if2)
 #RDR Outside to DMZ Hosts
 rdr on $ext_if1 proto tcp from any to $ext_if1/32 port { 25 80 110 } -> 192.168.10.2        #outside to MAIL pub ip
 rdr on $ext_if2 proto tcp from $Allow_ftp_ip to $ext_if2 port 21 -> 192.168.10.8 port 21    #outside to FTP
 #RDP from weithenn
 rdr on $ext_if1 proto tcp from $weithenn_home to $ext_if1/32 port 3389 -> 192.168.79.10 port 3389
 #RDR LAN to DMZ Hosts
 rdr on $lan_if proto { tcp, udp } from $lan_net to 192.168.88.2/32 port { 22 25 53 80 110 } -> 192.168.10.2  #to MAIL
 rdr on $lan_if proto { tcp, udp } from $lan_net to 192.168.88.8/32 port { 21 22 80 137 138 139 389 443 2355 } -> 192.168.10.8   #to ftp
 rdr on $lan_if proto { tcp, udp } from $lan_net to 192.168.88.9/32 port { 22 25 53 80 110 137 138 139 389 443 465 995 } -> 192.168.10.9 #to ldap
 #RDR LAN outgoing FTP requests to the ftp-proxy
 rdr on $lan_if proto tcp from any to any port ftp -> 127.0.0.1 port 8021
 ###Filter###
 pass quick on lo0 all
 #AntiSpoof
 antispoof quick for $lan_if
 #Lan User Routing Change to Hinet
 #pass in quick on $lan_if route-to ($ext_if2 $hinet_gw) from $lan_net to ! 192.168.0.0/16
 #special rule for ssh/ftp
 pass in on $ext_if1 proto tcp from any to ($ext_if1) port { ftp ssh } flags S/SA keep state (max-src-conn-rate 3/30, overload <ssh-bruteforce> flush global)
 pass in on $ext_if2 proto tcp from any to ($ext_if2) port { ftp ssh } flags S/SA keep state (max-src-conn-rate 3/30, overload <ssh-bruteforce> flush global)
 #block the ssh bruteforce bastards
 block drop in quick on $ext_if1 from <ssh-bruteforce>
 block drop in quick on $ext_if2 from <ssh-bruteforce>
 #LAN use ICMP
 pass in quick on $lan_if proto icmp from $lan_use_icmp to any icmp-type $icmp_types
 block in quick on $lan_if proto icmp from $lan_net to any icmp-type $icmp_types
 #Block Bad User
 block in quick on $lan_if from $lan_bt to any keep state queue bt
Please follow and like us:

0 comments on “PF設定編寫

1 Pings/Trackbacks 於 "PF設定編寫"

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *