因 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
0 comments on “PF設定編寫”
1 Pings/Trackbacks 於 "PF設定編寫"
[...] firewall 的設定問題。 O.S. FreeBSD 9.0-RELEASE, pure-ftpd-1.0.36 後來參考 Weithenn 的範例,新增一個 alias 的 IP 專門來給 FTP 用(不過後來好像改 PF 的 rdr FTP proxy [...]