openbsd 或者 freebsd 中的 packet filter 规则能不能讲一下?
对 pf 防火墙规则感觉 无所适从!
BSD 超精簡版PF使用手冊 (來自網路)
PF如果在/etc/rc.conf設定啟動的話,就會在開機時讀入/etc/pf.conf設定檔來設定規則
在pf.conf裡有幾個項目必須要照順序,不然它不會讓你載入的
.巨集
.表格
.選項
.修整
.序列
.nat和轉向
.過濾
在我前一篇已經說明如果用nat了,但是要做到控制流量和讓網路效能最佳化,或是要作防火牆的話,就須要其他的設定
在上面我們已經有用過修整和nat和轉向了,接下來要再介紹怎麼用
其實在上一篇就有用到巨集了,巨集就是我們定義的變數,可以以後方便維護用,也比較看得懂啦。
使用方法就直接給名子就好了,名字可以用字母,底線和數字,後面的值要加雙引號,就這樣子而已。
但是後面如果要用到巨集的話,就要在名字前面加$。
ex ext_if="xl0"
如果我們要讓兩張對內的網卡都可以用nat的話就要寫兩個nat規則
nat on $ext_net from 192.168.0.0/24 to any -> ($ext_net)
nat on $ext_net from 192.168.1.0/24 to any -> ($ext_net)
因為以上兩行只有一個地方不一樣而已,我們可以用列表來簡化規則,看起來更乾淨。
只要在大括號內放入項目就可以了,項目間要空格,有逗號和沒逗號都沒關係。
ex nat on $ext_net from {192.168.0.0/24 192.168.1.0/24} to any -> ($ext_net)
這樣當載入規則時,會自動展開成兩行,就和上面一樣。
當然如果再用巨集的話,會更加清楚
int_net1="192.168.0.1/24"
int_net2="192.168.1.1/24"
nat on $ext_net from {$int_net1 $int_net2} to any -> ($ext_net)
有很多項目可以放到列表裡,像是介面、ip位址、port位、protocol ...等
表格和列表一樣,只不過它裡面只能放ip位址,但是當它在管大量ip時的效能會遠比列表好很多,
而且可以動態的在任何時刻加入或刪掉表格裡的ip,有很好的使用彈性。
使用方法是 table <name> {ip1, !ip2, ....}
項目裡的ip可以在前面加 ! 來指定說這個ip不適用於這個表格。
選項,一些最佳化的選項,在此不講。嘿嘿 ^^
修整,可以把一些怪怪的封包的整掉,變成完整的封包,可以讓pf更專心過濾規則,不用去管怪怪的封包。
最常用的就是scrub in all 所有進入的封包都要修整,就這樣。
序列,這個小複雜,這裡先講限頻寬的好了。
講到這個就要講到cbq,這是一種階級序列的演算法使用層級的方法定義頻寬。
如我們想要在512/64的adsl每人限定上傳和下載的頻寬為64/16可像下面這樣定義
altq on $ext_if cbq bandwidth 64Kb queue {std_out}
queue std_out bandwidth 16Kb cbq (default)
altq on $int_if cbq bandwidth 512Kb queue {std_in}
queue std_in bandwidth 64Kb cbq (default borrow)
altq可以指定一個父序列,在父序列下可以有子序列,在子序列下又可以有子序列 (=_=)。
在每個介面上,一次只能有一個父序列而已,通常我們會在對外的介面限上傳頻寬,在對內介面限下載頻寬(理由哦~~以後再說)。注意子序列一定要有一個default。
子序列可以跟父序列借頻寬哦,如果都沒人用網路還限流的話是不是很給他浪費錢勒,所以只要加個borrow就可以借用囉。
序列要怎麼用呢,如果只有序列當然不能用啦,要把過濾規則指派給序列才能限流啊,等等到過濾再說囉。
nat和轉向,語法蠻簡單的,就
nat on 對外介面 from ip to ip -> 真實ip
真實ip的話我們只要直接指定介面就可以了,如果在前後加括號的話如 (tun0) 這是指當ip變動時,nat規則也跟者變動,免得無法上網。
rdr on 介面 from ip1 to ip2 -> ip3
這個就更簡單啦,在某個介面上,把從ip1到ip2的封包轉到ip3
過濾,重點所在,可以用來作防火牆和限流的功能,還有負載平衡哦(就是合併頻寬啦),這裡只說明如果限流,其他的日後有機會再說囉
語法
pass in/out on 介面 from ip1 to ip2 keep state (queue name)
block in/out on 介面 from ip1 to ip2 keep state (queue name)
因為我們丟一個封包出去,就會回來一個封包,所以正常來說在一個連線上我們要寫兩個規則,但這樣子很煩。
如果有加keep state的話,pf會記錄出去的連線,然後封包回來時就不會被擋到啦,這樣子我們只要寫出去的過濾規則就好了。
每條規則都可以指派給序列,就是限流啦,看看下面的例子。
注意這裡的介面如果是adsl撥接的話,不能用我們之前用的tun0,要用xl0,不然不會通。
#先擋掉所以的封包
block on {xl0, rl0} all
#開放所有的封包進入對外介面
pass in on xl0 from any to $ext_net keep state
#限制上載的頻寬
pass out on xl0 from $int_net to any keep state queue std_out
#開放所有對內介面流出的封包
pass out on rl0 from any to any
#限制下載的頻寬
pass in on rl0 from $int_net to any queue std_in
ok,把pf.conf載入就好啦。手有點累~~休息一下。
有錯敬請指正,謝謝
============================================
BSD PF 的一些有用的功能
BLOCKING SPOOFED TRAFFIC
"Spoofing" is the faking of IP addresses, typically for malicious purpos-
es. The antispoof directive expands to a set of filter rules which will
block all traffic with a source IP from the network(s) directly connected
to the specified interface(s) from entering the system through any other
interface.
For example, the line
antispoof for lo0
expands to
block drop in on ! lo0 inet from 127.0.0.1/8 to any
block drop in on ! lo0 inet6 from ::1 to any
For non-loopback interfaces, there are additional rules to block incoming
packets with a source IP address identical to the interface's IP(s). For
example, assuming the interface wi0 had an IP address of 10.0.0.1 and a
netmask of 255.255.255.0, the line
antispoof for wi0 inet
expands to
block drop in on ! wi0 inet from 10.0.0.0/24 to any
block drop in inet from 10.0.0.1 to any
Caveat: Rules created by the antispoof directive interfere with packets
sent over loopback interfaces to local addresses. One should pass these
explicitly.
STATEFUL TRACKING OPTIONS
All three of keep state, modulate state and synproxy state support the
following options:
max _number_
Limits the number of concurrent states the rule may create. When
this limit is reached, further packets matching the rule that would
create state are dropped, until existing states time out.
no-sync
Prevent state changes for states created by this rule from appear-
ing on the pfsync(4) interface.
_timeout_ _seconds_
Changes the timeout values used for states created by this rule.
When the source-track keyword is specified, the number of states
per source IP is tracked. The following limits can be set:
max-src-nodes
Limits the maximum number of source addresses which can si-
multaneously have state table entries.
max-src-states
Limits the maximum number of simultaneous state entries that
a single source address can create with this rule.
For a list of all valid timeout names, see OPTIONS above.
Multiple options can be specified, separated by commas:
pass in proto tcp from any to any
port www flags S/SA keep state
(max 100, source-track rule, max-src-nodes 75,
max-src-states 3, tcp.established 60, tcp.closing 5)
OPTIONS
pf(4) may be tuned for various situations using the set command.
set timeout
interval Interval between purging expired states and fragments.
frag Seconds before an unassembled fragment is expired.
src.track
Length of time to retain a source tracking entry after
the last state expires.
When a packet matches a stateful connection, the seconds to live
for the connection will be updated to that of the proto.modifier
which corresponds to the connection state. Each packet which
matches this state will reset the TTL. Tuning these values may im-
prove the performance of the firewall at the risk of dropping valid
idle connections.
tcp.first
The state after the first packet.
tcp.opening
The state before the destination host ever sends a packet.
tcp.established
The fully established state.
tcp.closing
The state after the first FIN has been sent.
tcp.finwait
The state after both FINs have been exchanged and the connec-
tion is closed. Some hosts (notably web servers on Solaris)
send TCP packets even after closing the connection. Increas-
ing tcp.finwait (and possibly tcp.closing) can prevent block-
ing of such packets.
tcp.closed
The state after one endpoint sends an RST.
ICMP and UDP are handled in a fashion similar to TCP, but with a
much more limited set of states:
udp.first
The state after the first packet.
udp.single
The state if the source host sends more than one packet but
the destination host has never sent one back.
udp.multiple
The state if both hosts have sent packets.
icmp.first
The state after the first packet.
icmp.error
The state after an ICMP error came back in response to an
ICMP packet.
Other protocols are handled similarly to UDP:
other.first
other.single
other.multiple
Timeout values can be reduced adaptively as the number of state
table entries grows.
adaptive.start
When the number of state entries exceeds this value, adaptive
scaling begins. All timeout values are scaled linearly with
factor (adaptive.end - number of states) / (adaptive.end -
adaptive.start).
adaptive.end
When reaching this number of state entries, all timeout val-
ues become zero, effectively purging all state entries imme-
diately. This value is used to define the scale factor, it
should not actually be reached (set a lower state limit, see
below).
These values can be defined both globally and for each rule. When
used on a per-rule basis, the values relate to the number of states
created by the rule, otherwise to the total number of states.
For example:
set timeout tcp.first 120
set timeout tcp.established 86400
set timeout { adaptive.start 6000, adaptive.end 12000 }
set limit states 10000
With 9000 state table entries, the timeout values are scaled to 50%
(tcp.first 60, tcp.established 43200).
set loginterface
Enable collection of packet and byte count statistics for the given
interface. These statistics can be viewed using
# pfctl -s info
In this example pf(4) collects statistics on the interface named
dc0:
set loginterface dc0
One can disable the loginterface using:
set loginterface none
set limit
Sets hard limits on the memory pools used by the packet filter.
See pool(9) for an explanation of memory pools.
For example,
set limit states 20000
sets the maximum number of entries in the memory pool used by state
table entries (generated by keep state rules) to 20000. Using
set limit frags 20000
sets the maximum number of entries in the memory pool used for
fragment reassembly (generated by scrub rules) to 20000. Finally,
set limit src-nodes 2000
sets the maximum number of entries in the memory pool used for
tracking source IP addresses (generated by the sticky-address and
source-track options) to 2000.
These can be combined:
set limit { states 20000, frags 20000, src-nodes 2000 }
set optimization
Optimize the engine for one of the following network environments:
normal
A normal network environment. Suitable for almost all net-
works.
high-latency
A high-latency environment (such as a satellite connection).
satellite
Alias for high-latency.
aggressive
Aggressively expire connections. This can greatly reduce the
memory usage of the firewall at the cost of dropping idle
connections early.
conservative
Extremely conservative settings. Avoid dropping legitimate
connections at the expense of greater memory utilization
(possibly much greater on a busy network) and slightly in-
creased processor utilization.
For example:
set optimization aggressive
set block-policy
The block-policy option sets the default behaviour for the packet
block action:
drop Packet is silently dropped.
return A TCP RST is returned for blocked TCP packets, an ICMP
UNREACHABLE is returned for blocked UDP packets, and all
other packets are silently dropped.
For example:
set block-policy return
set state-policy
The state-policy option sets the default behaviour for states:
if-bound States are bound to interface.
group-bound States are bound to interface group (i.e. ppp)
floating States can match packets on any interfaces (the de-
fault).
For example:
set state-policy if-bound
set require-order
By default pfctl(8) enforces an ordering of the statement types in
the ruleset to: options, normalization, queueing, translation,
filtering. Setting this option to no disables this enforcement.
There may be non-trivial and non-obvious implications to an out of
order ruleset. Consider carefully before disabling the order en-
forcement.
set fingerprints
Load fingerprints of known operating systems from the given file-
name. By default fingerprints of known operating systems are auto-
matically loaded from pf.os(5) in /etc but can be overridden via
this option. Setting this option may leave a small period of time
where the fingerprints referenced by the currently active ruleset
are inconsistent until the new ruleset finishes loading.
For example:
set fingerprints "/etc/pf.os.devel"
set debug
Set the debug level to one of the following:
none Don't generate debug messages.
urgent Generate debug messages only for serious errors.
misc Generate debug messages for various errors.
loud Generate debug messages for common conditions.
https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/firewalls-pf.html