第十二章 NAT 路由器及防火牆

當一個網路環境中有多台電腦或裝置需要上網,您一定會需要一台路由器,讓內部裝置可以經由路由器連上網際網路。 路由器除了扮演網路閘道的功能外,還可以做為防火牆來保護內部網路。在 FreeBSD 中有幾種不同的防火牆功能, 我們將在本章中一一介紹如何利用這些防火牆功能來架設路由器以保護內部網路的電腦。

讀完本章後,您將了解下列主題:

12.1 概論

一般而言,家中或公司的網路環境大概會像下列結構:

圖 12-1

如果我們以 FreeBSD 做為路由器並連到 ADSL modem 或其它 ISP 提供的設備以連上網際網路。而區域網路內的其它電腦會經由路由器連上網際網路。 在 FreeBSD 伺服器上有二張網路卡,對外的網卡代號為 em0,對內則為 em1。我們假設區網內的 IP 為 192.168.0.X, 以下我們就以此為範例一一說明路由器的功能及設定。

我們知道網際網路上的設備使用 IP 位址來定位及溝通。當一台電腦要連到另外一個電腦時,會需要經由層層的路由器找到對方。 您可以在 FreeBSD 中使用 traceroute 或在 Windows 中使用 tracert 指令來查看你的電腦和目標電腦經過了哪些路由器。這些在網際網路上的 IP 位址都是屬於公有 IP 位址。因為 IPv4 的 IP 位址有限, 在區域網路中,大部份的網路都沒有使用公有 IP 位址,而是使用私有的 IP。這些可以用的私人 IP 如下:

Class 範圍 子網路遮罩
Class A 10.0.0.0 ~ 10.255.255.255 255.0.0.0
Class B 172.16.0.0 ~ 172.31.255.255 255.240.0.0
Class C 192.168.0.0 ~ 192.168.255.255 255.255.0.0

但問題是這些私人的 IP 並不能出現在網際網路上,如果要在網際網路上流動,就必須先將 IP 轉成公有 IP。這個轉換就叫做 NAT (Network Address Translation)。NAT 可以讓區網中多台電腦透過同一個 IP 連線到網際網路。舉個實例而言,一個公司有三十台電腦, 而 ISP 所提供的 ADSL 卻只有八個公有 IP,這種情況下,我們可以將每台電腦的 IP 設定為私有 IP,再讓它們經由一台有公有 IP 的 NAT 伺服器連上網路即可。

在 FreeBSD 中,我們有下列幾種方式來實作 NAT 路由器:

上述這幾個防火牆都各有優缺。FreeBSD 使用手冊的建議是請使用者自己測試、自己決定要使用哪一個。筆者認為 IPFW 及 PF 都是不錯的選擇, 這二種防火牆相對比較多人使用,文件也比較多。IPFW 是 FreeBSD 內建的防火牆,它在 FreeBSD 系統中有最完整的整合度。我個人認為它的語法比較簡單明瞭。 在使用 IPFW 實作 NAT 時有二個選擇,一個是比較新的 in-kernel NAT,一個是使用 userspace natd 來輔助。使用 natd 的效能會很差, 因為資料必須在 kernel 及 userspace 之間傳送,所以效能可能會差到只有 in-kernel NAT 的十分之一。所以我們不會討論設定 natd。

而 PF 似乎是比較強大的選擇,一些使用 FreeBSD 為基礎的 open source 防火牆軟體 (如 pfSense 及 OPNsense) 都是使用 PF 防火牆。 以下我們就以 IPFW 及 PF 來說明如何架設 NAT 路由器。

12.2 以 IPFW 架設 NAT 路由器及防火牆

在以前比較舊的版本,要使用 IPFW 之前,必須先重新編譯核心以加入 IPFW 的功能。 但在新版的 FreeBSD 中,系統會自動載入相關的防火牆核心模組,所以我們可以不需要重新編譯核心。以下我們就直接進入設定啟用 IPFW NAT 防火牆吧。

12.2.1 啟用 NAT 路由器

要啟動路由器及防火牆功能,只要在 /etc/rc.conf 中加入下列內容:

# 設定對外網卡的 IP,這裡的例子是假設我們有固定 IP # em0 是網卡的代號,你可以從 ifconfig 指令中看到自己網卡的代號是什麼 ifconfig_em0=""inet 96.83.34.189 netmask 255.255.255.252" defaultrouter="96.83.34.190" # 設定第二張網路卡的 IP。 ifconfig_em1="inet 192.168.0.1 netmask 255.255.255.0" # 設定啟用路由器的功能。 gateway_enable="YES" # 設定啟用防火牆功能,並設定防火牆類型為 OPEN,也就是允許所有連線。 firewall_enable="YES" firewall_type="Open" # 啟用 in-kernel NAT,並設定對外網卡為 em0 firewall_nat_enable="YES" firewall_nat_interface="em0"

另外,當我們有啟用 NAT 功能時,必須將核心的 TCP segmentation offloading (TSO) 功能關閉。請編輯 /etc/sysctl.conf 並加入下列內容:

net.inet.tcp.tso="0"

這樣就完成了。只要重開機就可以開始使用這台 FreeBSD 為路由器上網了。

我們可以使用區網內其它電腦來測試路由器功能。首先,你的網路架構應該如圖 12-1 所示。我們必須將其他電腦的 IP 設定為和 FreeBSD 伺服器同一個子網路。 以上列設定為例,您必須將其它電腦的 IP 設為 192.168.0.X (除了 192.168.0.1 以外的其它 IP)、子網路遮罩是 255.255.255.0, 並將 gateway 設定為 FreeBSD 連到區域網路的網路卡 IP,在此範例中是 192.168.0.1。然後再設定你的 DNS 為你 ISP 的 DNS 即可。 完成上述的設定後,我們就能享受以 FreeBSD 為NAT上網了。

如果您的其它電腦還是無法上網,您可以依下列步驟除錯:

12.2.2 IPFW 指令及語法

在說明更多 IPFW 進階設定之前,我們先來看一下 IPFW 的指令及語法。下面是一個 IPFW 規則的設定:

ipfw add 65000 pass all from any to any

乍看之下好像很複雜,瞭解它的指令及語法結構後,其實蠻容易上手的。我們先來看一下 IPFW 常用的指令有哪些。

IPFW 常用指令

下表中為常用的 ipfw 指令,我們可以使用這些指令來新增、刪除、或列出 IPFW 規則:

指令 說明
ipfw add [rule] 新增一條規則。規則 (rule) 的語法請參考下一節的說明。
ipfw delete [number] 刪除一條編號為 number 的規則。
ipfw -f flush 清除所有的規則。
ipfw list 列出現在所有規則。

如上表所示,假設我們要列出目前 IPFW 的規則,可以使用下列指令:

#ipfw list
00100 allow ip from any to any via lo0 00200 deny ip from any to 127.0.0.0/8 00300 deny ip from 127.0.0.0/8 to any 00400 deny ip from any to ::1 00500 deny ip from ::1 to any 00600 allow ipv6-icmp from :: to ff02::/16 00700 allow ipv6-icmp from fe80::/10 to fe80::/10 00800 allow ipv6-icmp from fe80::/10 to ff02::/16 00900 allow ipv6-icmp from any to any icmp6types 1 01000 allow ipv6-icmp from any to any icmp6types 2,135,136 65000 allow ip from any to any 65535 deny ip from any to any
IPFW 規則說明

在使用 ipfw add 時,在指令後面要輸入規則。 以下為簡化的 ipfw 規則語法:

[number] action [log] proto from src to dist [option]

使用 [ ] 包起來的表示可有可無,我們一一為大家說明它們的意義:

IPFW Table

為了簡化規則,並有效率的處理類似的規則,IPFW 有一個 Table 的功能, 可以用存放 IP 位址或 Port 等。例如,如果我們有規則是要阻擋幾個有問題的 IP, IPFW 規則可能會像這樣:

ipfw add 1001 deny tcp from 77.245.105.165 to any 22 ipfw add 1002 deny tcp from 180.250.18.20 to any 22

以上二個例子是以 IPFW 阻擋二個不同的 IP 存取 Port 22。如果有十個 IP,就必須重複十條同樣的規則。 為了簡化並讓它更有效率,我們可以建一個 Table 來存放這些 IP。

首先,我們先使用下列指令建 Table,名稱為 blackhosts:

#ipfw table blackhosts create

接著,我們只要新增一條規則來阻擋 blackhosts 這個 Table:

#ipfw add 1001 deny tcp from "table(blackhosts)" to any 22

最後,當有需要阻擋 IP 時,我們只要將 IP 新增到 blackhosts Table 中即可。

#ipfw table blackhosts add 180.250.18.20

另外,我們可以使用下列指令列出所有 Table 的內容:

#ipfw table all list
--- table(port1022), set(0) --- 77.245.105.165/32 0 180.250.18.20/32 0

以上 ipfw 的語法介紹只是它功能的一小部份。如果你想要對 ipfw 的語法有更深入的暸解請 man ipfw

12.2.3 進階 IPFW 防火牆功能

了解了 IPFW 的指令及語法後,我們就可以來進行一些進階的設定。例如 Port forwarding 或使用防火牆來限制頻寬等。

FreeBSD 預設的防火牆規則放在 /etc/rc.firewall 中。 我們可以在 /etc/rc.conf 中設定 firewall_type 來決定防火牆的開放程度。 不過這些規則有點太簡化,我們可以依需求重新寫一份自己的規則。

自定防火牆規則

假設我們要將自定的防火牆規則放在 /etc/ipfw.conf。 我們可以在 /etc/rc.conf 中加入下列內容:

... # 設定使用我們自定的防火牆規則 firewall_script="/etc/ipfw.conf" ....

接著請新增檔案 /etc/ipfw.conf 並加入下列內容:

#!/bin/sh # ipfw 指令位置,不須修改 fwcmd="/sbin/ipfw" # 對外的網路卡名稱 ext_if="em0" # 對內的網路卡名稱 int_if="em1" # 先清空所以規則 ${fwcmd} -f flush # Setup loop back ${fwcmd} add 100 pass all from any to any via lo0 ${fwcmd} add 200 deny all from any to 127.0.0.0/8 ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any # 啟用 NAT 功能 ${fwcmd} add 50 nat 1 ip from any to any via ${ext_if} # 預設允許所有連線 ${fwcmd} add 65000 pass all from any to any

有了上面這個基本的設定檔,我們就可以再加入更多自定的規則了。

Port forwarding

假設我們在區域網路內架了一台網頁伺服器及郵件伺服器,因為這台伺服器在 NAT 防火牆後面,而且沒有公有 IP, 所以區域網路外的電腦無法連上該伺服器。這時候,我們就可以利用 NAT Port Forwarding 的功能來將網頁及郵件的網路封包重新導向到內部伺服器。 例如,我們對外有一台防火牆,在 DNS 設定方面,我們設定了 www.mydomain.com 及 smtp.mydomain.com 都指向這台防火牆。 但我們希望所有 HTTP (port 80)、HTTPS (port 443) 連線都重新導向到內部的 192.168.0.2 這台機器上, 而所有 SMTP (port 25) 連線都交由 192.168.0.3 來處理。這時候我們就可以使用下列設定來達成 Port Forwarding。

請打開我們自定的防火牆規則 /etc/ipfw.conf,在原本啟用 NAT 的下面加入下列 redirect_port 的設定:

... # 啟用 NAT 功能 (nat 1 的 1 表示是第一個 NAT 程序,如果有多張網卡或網域,可以有多個 NAT 程序。) ${fwcmd} add 50 nat 1 ip from any to any via ${ext_if} # 在 nat 1 的設定中加上 redirect_port 的設定 ${fwcmd} nat 1 config if ${ext_if} same_ports unreg_only reset \ redirect_port tcp 192.168.0.2:80 80 \ redirect_port tcp 192.168.0.2:443 443 \ redirect_port tcp 192.168.0.3:25 25 ${fwcmd} add 65000 pass all from any to any

我們可以使用下列指令重新載入 IPFW 設定,這樣就完成了 NAT Port Forwarding 的功能了。

#service ipfw restart

接下來,您可以從外部網路連線到防火牆的外部 IP,看看是不是會被導向到我們設定的內部伺服器。

不過 IPFW 的 Port Forwarding 有一個缺點,就是只有從外部連線進來才會被重新導向。 如果從內網要連到該外部 IP,並不會被導向到內部伺服器。例如,假設您有一個 www.example.com 的伺服器, 它的 DNS 設定是指向防火牆外部 IP 96.83.34.189,在防火牆上我們設定了 Port Forwarding 到內部 192.168.0.2 的機器。當內部其它電腦要連到 www.example.com 時,它們會連到防火牆的外部 IP 96.83.34.189。因為這個連線是從內部網域來,並不會觸發 NAT 的 Port Forwarding,造成內網無法直接以該網址連線。

這種情況下,如果我們想要讓內網可以直接以 www.example.com 連到內部的伺服器,可以有以下三種方式:

限制頻寬

當內部網路中有很多電腦共用網路頻寬時,如果有一個人用量特別大,就會影響所有人的網路速度。如果有需要, 我們可以在防火牆上限制每個人可以使用的最大頻寬。

如果要限制頻寬,系統必須載入 DUMMYNET 的核心模組。所以,我們要先編輯 /etc/rc.conf 來載入 DUMMYNET:

#sysrc dummynet_enable=yes

接著在 /etc/ipfw.conf 中加入頻寬限制的規則:

... # 限制頻寬 # 假設我們要設定每一個內部電腦 (192.168.0.0/24) 最多只能使用的上傳頻寬為 512KB/s, # 下傳頻寬為 1MB/s,則加入下列設定: ${fwcmd} pipe 20 config bw 512KByte/s ${fwcmd} pipe 21 config bw 1MByte/s ${fwcmd} add 1000 pipe 20 ip from 192.168.0.0/24 to any ${fwcmd} add 1100 pipe 21 ip from any to 192.168.0.0/24

最後使用下列指令重新載入 IPFW 設定:

#service ipfw restart
12.2.4 IPFW 規則範例

在建立防火牆時,通常有二種做法,一是預設開放所有連線,只阻擋少數有問題的主機。另一種做法是預設關閉所有連線,只開放少數服務。 預設關閉的方式當然比預設開啟的方式安全,但相對的,也有可能會阻擋到不該擋掉的服務造成使用者的困擾。如果您很清楚內部所會用到的服務, 自然是以預設關閉的方式為主。

以下,我們就提供這二種不同方式的範例供大家參考。

預設開放所有連線
#!/bin/sh # ipfw 指令位置,不須修改 fwcmd="/sbin/ipfw" # 對外的網路卡名稱 ext_if="em0" # 對內的網路卡名稱 int_if="em1" # 先清空所以規則 ${fwcmd} -f flush # 設定內部 loopback 網卡 ${fwcmd} add 100 pass all from any to any via lo0 ${fwcmd} add 200 deny all from any to 127.0.0.0/8 ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any # 不允許私有 IP 從對外網卡連線 ${fwcmd} add 400 deny ip from 10.0.0.0/8 to any in via ${ext_if} ${fwcmd} add 410 deny ip from 172.16.0.0/12 to any in via ${ext_if} ${fwcmd} add 420 deny ip from 192.168.0.0/16 to any in via ${ext_if} # 只允許內部網路對本伺服器使用 SSH 服務 ${fwcmd} add 500 allow tcp from 192.168.0.1/24 to me ssh # 拒絕其他人連到 port 22,並記錄嘗試連線的機器 ${fwcmd} add 510 deny log tcp from any to me 22 # 拒絕任何 ICMP 封包 ${fwcmd} add 600 deny icmp from any to any # 下面這台機器是壞人,不讓它進來,並記錄下來 ${fwcmd} add 1100 deny log all from 211.21.104.102 to any # 啟用 NAT 功能 (nat 1 的 1 表示是第一個 NAT 程序,如果有多張網卡或網域,可以有多個 NAT 程序。) ${fwcmd} add 50 nat 1 ip from any to any via ${ext_if} # 在 nat 1 的設定中加上 redirect_port 的設定 ${fwcmd} nat 1 config if ${ext_if} same_ports unreg_only reset \ redirect_port tcp 192.168.0.2:80 80 \ redirect_port tcp 192.168.0.2:443 443 \ redirect_port tcp 192.168.0.3:25 25 # 限制頻寬 # 假設我們要設定每一個內部電腦 (192.168.0.0/24) 最多只能使用的上傳頻寬為 512KB/s, # 下傳頻寬為 1MB/s,則加入下列設定: ${fwcmd} pipe 20 config bw 512KByte/s ${fwcmd} pipe 21 config bw 1MByte/s ${fwcmd} add pipe 20 ip from 192.168.0.0/24 to any ${fwcmd} add pipe 21 ip from any to 192.168.0.0/24 # 預設允許所有連線 ${fwcmd} add 65000 pass all from any to any
預設關閉所有連線
#!/bin/sh # ipfw 指令位置,不須修改 fwcmd="/sbin/ipfw" # 對外的網路卡名稱 ext_if="em0" # 對內的網路卡名稱 int_if="em1" # 先清空所以規則 ${fwcmd} -f flush # 設定內部 loopback 網卡 ${fwcmd} add 100 pass all from any to any via lo0 ${fwcmd} add 200 deny all from any to 127.0.0.0/8 ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any # 啟用 NAT 功能 (nat 1 的 1 表示是第一個 NAT 程序,如果有多張網卡或網域,可以有多個 NAT 程序。) ${fwcmd} add 50 nat 1 ip from any to any via ${ext_if} # 在 nat 1 的設定中加上 redirect_port 的設定 ${fwcmd} nat 1 config if ${ext_if} same_ports unreg_only reset \ redirect_port tcp 192.168.0.2:80 80 \ redirect_port tcp 192.168.0.2:443 443 \ redirect_port tcp 192.168.0.3:25 25 # 只允許內部網路對本伺服器使用 SSH 服務 # 我們在規則最後加上 keep-state,表示所允許的連線出去之後, # 對方機器的回應也允許送進來 ${fwcmd} add 500 allow tcp from 192.168.0.1/24 to me ssh keep-state # 只允許內部網路使用 HTTP/HTTPS/IMAPS/SMTP/SMTPS 等服務 ${fwcmd} add 600 allow tcp from 192.168.0.1/24 to any http,https,imaps,25,465 keep-state # 允許使用 DNS 服務 ${fwcmd} add 700 allow ip from any to any 53 keep-state # 其它不符合條件的連線全部拒絕 ${fwcmd} add 65000 deny all from any to any
12.2.5 遠端修改 IPFW 規則的建議

在更新 firewall 規則時,如果規則沒有寫好,而你又是以遠端登入的方式修改規則,很可能會因此無法繼續登入。 因此建議更新規則時最好在 console 前執行,若迫不得已一定要使用遠端登入,我們可以使用下列指令來輔助。 該指令會在更新 ipfw 規則後,檢查連線是否正常,如果連線中斷,會自動回復到之前的規則。

#sh /usr/share/examples/ipfw/change_rules.sh

輸入上述指令後,接著會出現文書編輯軟體並最動載入你的 IPFW 規則設定檔讓你編輯, 存檔離開後,會詢問是否要執行新修改的規則。如果執行新的規則後造成斷線,它會自動載入舊的規則,讓我們可以再次連線。

12.3 以 PF 架設 NAT 路由器及防火牆

PF 防火牆是從 OpenBSD 移稙而來。它不僅功能完整、文件也十分齊全。pfSense 及 OPNsense 都使用 PF 來打造防火牆產品, 可見它深受安全專家們的青睞。以下,我們就來看看怎麼使用 PF 打造 NAT 路由器。

12.3.1 啟用 NAT 路由器

首先我們要啟動路由器及 PF 防火牆功能,請在 /etc/rc.conf 中加入下列內容:

# 設定對外網卡的 IP,這裡的例子是假設我們有固定 IP ifconfig_em0=""inet 96.83.34.189 netmask 255.255.255.252" defaultrouter="96.83.34.190" # 設定第二張網路卡的 IP。 ifconfig_em1="inet 192.168.0.1 netmask 255.255.255.0" # 設定啟用路由器的功能。 gateway_enable="YES" # 設定啟用 PF 防火牆功能,並打開 PF 的日誌。 pf_enable="yes" pflog_enable="yes"

接著,請新增 /etc/pf.conf 並加入下列內容:

ext_if = "em0" int_if = "em1" # 不要針對系統 loopback 網卡做限制 set skip on lo # 先檢查並重組封包以確保封完整性以防止一些特別的攻擊封包 scrub in # 啟用 NAT 功能 nat on $ext_if inet from !($ext_if) -> ($ext_if:0) # PF 防火牆規則是會比對到最後一筆符合的規則為主 # 我們先阻擋所有封包,再加入想要開放的規則 block in log all # 允許本機出去的所有連線,我們加上關鍵字 keep state 以允許目的地連線回應 pass out keep state # 允許所有內部網路要出去的連線 pass quick on $int_if no state

以上的範例是允許所有內部要出去的連線,並阻擋其他要進來的連線。我們之後會以此為基礎慢慢加入更多規則。

完成上述設定後,您可以重新開機以套用設定。或者手動設定 IP 位址後,使用下列指令來啟用路由器功能:

#sysctl net.inet.ip.forwarding=1

接著啓用 PF 防火牆:

#service pf start
12.3.2 PF 指令及語法

在進入更多 PF 設定之前,我們先來認識一些 PF 常用的指令及語法。

PF 常用指令

PF 防火牆可以使用 pfctl 這個指令來控制。下表中為常用的 pfctl 指令及參數:

指令 說明
pfctl -e 啟用 PF 防火牆。
pfctl -d 停用 PF 防火牆。
pfctl -F all -f /etc/pf.conf 清除所有的規則並重新載入 /etc/pf.conf 中的規則。
pfctl -s rules 列出現在所有規則。
pfctl -s nat 列出目前的 NAT 規則。
pfctl -s states 列出 state table 的內容。State table 包含了 keep state 連線的狀態。
pfctl -s all 列出所有 pf 的資訊。
pfctl -vnf /etc/pf.conf 檢查 /etc/pf.conf 的 PF 規則語法,但不真的執行。

如上表所示,假設我們要列出目前 PF 的規則,可以使用下列指令:

#pfctl -s rules
scrub in all fragment reassemble block drop in log all pass out all flags S/SA keep state pass quick on igc1 all no state

更多關於 pfctl 的用法,請 man pfctl

PF 的宣告類別

pf.conf 檔案中共有七種不同的宣告類別。 在撰寫規則時,除了 Macros 和 Tables 可以在使用前才宣告外, 其他的類別都必須依照下列順序將同一個類別的宣告放在一起。

類別 說明
Macros

用來定義變數。我們會將一些常用到的共用字串寫成變數,如此一來, 萬一需要修改,只需修改一個地方。例如,對外的 IP 在很多規則中都會重覆用到, 我們就可以把 IP 寫成變數:

ext_ip = "96.83.34.189"

要使用該變數時,只要寫 $ext_ip 即可。

Tables 當有規則要使用大量的來源或目的地 IP 位址時,每個位址寫一個規則很沒效率。 使用 Tables 來定義這些位址會比較簡單且有效率。
Options Options 有很多項目可以定義 pf 封包過濾的行為,例如 timeout 的時間長短。
Traffic Normalization Traffic Normalization 可以將收到的封包先常規化以避免一些特殊封包攻擊。
Queueing 用來設定頻寬控制。
Translation 設定 NAT 及封包轉送的規則。
Packet Filtering 設定封包過濾的規則。
PF 封包過濾的規則

PF 的防火牆封包過濾的規則和 IPFW 最大的不同是 IPFW 的規則是一符合規則就不再往下比對,而 PF 會從上而下比對並執行所有規則, 並以最後一條符合的規則為主。所以在 IPFW 中,我們會把允許全部連線或拒絕全部連線的規則放在最後一條。 而 PF 則是在封包過濾規則的區域中,先拒絕所有連線,再一條一條的加入越來越細的規則。

封包過濾的行為可以分成下列三種:

一條封包過濾規則由上述行為 (block, pass, match) 後再加上規則的關鍵字組成。例如:

pass out proto tcp to any port $tcp_services keep state pass in inet proto tcp on em1 from em1:network to em0:network port 22

以下為常用的關鍵字:

Anchors

除了主要的規則外,我們也可以在一堆規則中加入 Anchor。Anchor 是一個定位點, 讓您可以動態在 Anchor 中加入其他規則。這些新加入的規則順序就會是該 Anchor 在所有規則中的順序。在設定 Anchor 時,我們會給 Anchor 一個名稱, 之後可以使用該名稱以動態載入規則到指定的 Anchor 中。

例如,以下是一個簡單的 pf.conf 內容:

ext_if = "em0" block on $ext_if all anchor spam pass out on $ext_if all pass in on $ext_if proto tcp from any to $ext_if port smtp

我們在上面設定了一個名為 spam 的 Anchor。當我們要阻擋一個亂發垃圾信的 IP 時, 我們可以使用以下指令:

#echo "block in quick from 1.2.3.4 to any" | pfctl -a spam -f -

我們在這個 Anchor 加入了阻擋某個 IP 的規則,因為有加上關鍵字 quick,在符合規則時,就不會再比對其它規則。

如果您要看目前有哪些 Anchors,可以使用下列指令:

#pfctl -s Anchors

如果我們要看 spam 這個 Anchor 包含了什麼規則,可以使用:

#pfctl -a spam -s rules
block drop in quick inet from 1.2.3.4 to any

以上是關於 Anchor 的簡單介紹,之後我們會更深入介紹使用 Anchor 阻擋黑名單的應用。

pf.conf 的設定很多,您可以 man pf.conf 以了解所有可以使用的設定。 在下面幾節中,我們會以實際的例子來說明一些常用的規則。

12.3.3 使用 PF 進行 Port forwarding

假設我們的 NAT 防火牆後有一台郵件伺服器,我們可以使用 PF port forwarding 的功能來將郵件相關的連線重導至該伺服器。

Port forwarding

以下設定中,內部網路郵件伺服器的 IP 是 192.168.0.2, 如果當外部連線要連到 SMTP (port 25)、SMTPS (port 465)、IMAPS (port 993) 時, 就將封包導向該伺服器。我們可以在/etc/pf.conf 中 NAT 設定下面加入下列這一行:

rdr pass on $ext_if proto tcp from any to any port { 25, 465, 993 } -> 192.168.0.2

或者,我們也可以直接寫服務的名稱而非 Port。這些服務的名稱可以在 /etc/services 中找到。以下範例即是使用服務名稱:

rdr pass on $ext_if proto tcp from any to any port { smtp, smtps, imaps } -> 192.168.0.2

在上述設定中,因為有多個 Port,我們使用大括號 {} 括起來。如果只有一個 Port,可以不寫括號。 上面的例子會將外部連進來的 Port 導向到內部相同的 Port。如果我們想要讓外部連進來的 Port 和內部的 Port 不同, 可以使用下列設定:

rdr pass on $ext_if proto tcp from any to any port 1022 -> 192.168.0.2 port 22

這個例子是當外部連線到 Port 1022 時,就導到 192.168.0.2 的 Port 22。

NAT Loopback

我們以上的設定都是將 "外部" 連線重新導向到內部的伺服器。我們在前面 IPFW Port forwarding 的部份提到, 如果從內部使用網域名稱 www.example.com 要連到內部伺服器時,如果該網址指向外部 IP,會造成內部連線無法觸發 NAT 的 Port forwarding。這個時候,我們可以在 PF 中多加一個 NAT Loopback 的設定以重導內部連線。

下列的設定第一行是指內部連線到內部網路時,不要使用 NAT。然後當內網要連到外部 IP 的幾個指定 Port 時,就重導到內部伺服器。最後,要重導內部連線時,我們要使用 NAT,這樣連線才會透過防火牆進出。

no nat on $int_if proto tcp from $int_if to $int_net rdr on $int_if proto tcp from $int_net to $ext_ip port { 25, 165, 993 } -> 192.168.0.2 nat on $int_if proto tcp from $int_net to 192.168.0.2 port { 25, 165, 993 } -> $int_if
完整的 pf.conf 內容

你可能注意到我們上面幾個範例都是使用變數,如 $ext_if 來表示外部網卡的代號。 這個變數必須先在 pf.conf 最上方先定義好。 以下就是完整的 pf.conf 內容:

####### Macros 區段 ####### # 定義對外及對內的網卡及 IP ext_if = "em0" int_if = "em1" ext_ip = "96.83.34.189" int_net = "192.168.0.1/24" ######## Options 區段 ####### #不要針對系統 loopback 網卡做限制 set skip on lo ####### Traffic Normalization 區段 ####### # 先檢查並重組封包以確保封完整性以防止一些特別的攻擊封包 scrub in ####### Translation 區段 ####### # 啟用 NAT 功能 nat on $ext_if inet from !($ext_if) -> ($ext_if:0) # Port forwarding # 將 SMTP, SMTPS, IMAPS 服務轉給內部 192.168.0.2 這台主機 rdr pass on $ext_if proto tcp from any to any port { 25, 465, 993 } -> 192.168.0.2 # 當有外部連線要連到 Port 1022 時,就導給 192.168.0.2 的 Port 22 rdr pass on $ext_if proto tcp from any to any port 1022 -> 192.168.0.2 port 22 # NAT loopback 設定 no nat on $int_if proto tcp from $int_if to $int_net rdr on $int_if proto tcp from $int_net to $ext_ip port { 25, 165, 993 } -> 192.168.0.2 nat on $int_if proto tcp from $int_net to 192.168.0.2 port { 25, 165, 993 } -> $int_if ####### Packet Filtering 區段 ####### # PF 防火牆規則是會比對到最後一筆符合的規則為主 # 我們先阻擋所有封包,再加入想要開放的規則 block in # 允許本機出去的所有連線 pass out # 允許所有內部網路要出去的連線 pass on $int_if no state
12.3.4 使用 PF 進行頻寬控制

PF 防火牆的頻寬控制功能十分強大,在 pf.conf 中,頻寬設定是位於 Queueing 的區段。Queueing 使用系統核心的 ALTQ 模組來進行 QOS (Quality of Service)。我們可以使用它來限制不同網段使用的對外頻寬、 或是針對不同的通訊協定給予不同的優先權、或用它來改善低頻寬環境的網路品質。 不過,ALTQ 模組並未內建於預設的 GERERIC 核心中 而且也不能以動態載入的方式載入模組。所以,在開始設定之前,我們必須先重新編譯核心, 以加入 ALTQ 的功能。

您可以執行下列指令來看看核心有沒有支援 ALTQ 的功能,如果不支援,則會顯示 No ALTQ support in kernel 的訊息:

#pfctl -s queue -vv
No ALTQ support in kernel ALTQ related functions disabled
修改核心設定

請在核心設定檔中加入下列 ALTQ 的設定,接著請參考編譯核心一章以重新編譯核心。

options ALTQ options ALTQ_CBQ # Class Based Queuing (CBQ) options ALTQ_RED # Random Early Detection (RED) options ALTQ_RIO # RED In/Out options ALTQ_HFSC # Hierarchical Packet Scheduler (HFSC) options ALTQ_PRIQ # Priority Queuing (PRIQ)
Queueing 語法

Queueing 頻寬設定可以分成三個部份:

  1. 先在網路介面卡啟用 ALTQ 並設定總頻寬。
  2. 再使用 queue 設定一個 queue 的頻寬上限。
  3. 最後在封包過濾規則中套用 queue。

我們先來看一下如何在介面卡啟用 ALTQ:

altq on $ext_if cbq bandwidth 100Mb queue { std_in, enginner_in }

上面這個例子是在介面卡 $int_if 上啟用 ALTQ。我們使用 cbq 演算法,並設定頻寬 (bandwidth) 為 100Mb,然後我們打算設定二個 queue,名稱分別為 std_in 及 engineer_in。

接著,我們設定 std_in 及 engineer_in 這二個 queue:

queue std_in bandwidth 80Mb cbq (default) queue enginner_in bandwidth 20Mb cbq (default, borrow)

這二個 queue 的意思是限制名稱為 std_in 的 queue 最多使用 80Mb 的頻寬。 而 engineer_in 最多使用 20Mb 的頻寬。我們在 engineer_in 的 queue 中加入關鍵字 borrow,表示當頻寬夠時,它可以借用頻寬,最多可以使用到介面卡上設定的總頻寬。

最後一個步驟是在封包過濾規則上套用 queue。例如,我們假設內部有二個不同的網段 $int_network 及 $engineer_network,當封包要去不同網段時,我們套用不同的 queue :

pass in on $ext_if proto tcp from $ext_if to $int_network queue std_in pass in on $ext_if proto tcp from $ext_if to $enginner_network queue enginner_in

以上是最基本的頻寬限制。我們再來看一下 man pf.conf 中所提到的範例:

altq on dc0 cbq bandwidth 5Mb queue { std, http, mail, ssh } queue std bandwidth 10% cbq(default) queue http bandwidth 60% priority 2 cbq(borrow red) { employees, developers } queue developers bandwidth 75% cbq(borrow) queue employees bandwidth 15% queue mail bandwidth 10% priority 0 cbq(borrow ecn) queue ssh bandwidth 20% cbq(borrow) { ssh_interactive, ssh_bulk } queue ssh_interactive bandwidth 50% priority 7 cbq(borrow) queue ssh_bulk bandwidth 50% priority 0 cbq(borrow) block return out on dc0 inet all queue std pass out on dc0 inet proto tcp from $developerhosts to any port 80 queue developers pass out on dc0 inet proto tcp from $employeehosts to any port 80 queue employees pass out on dc0 inet proto tcp from any to any port 22 queue(ssh_bulk, ssh_interactive) pass out on dc0 inet proto tcp from any to any port 25 queue mail

此範例是在網路卡 dc0 上啟用 ALTQ,頻寬為 5Mbit,並有四個主要的 queue, 名稱為 std, http, mail, 及 ssh。每一個不同的 queue 定義了不同的頻寬百分比, 並設定了不同的優先權 (priority),優先權數字大者優先。在 http 及 ssh 的 queue 中,分別再加了二個子 queue。

接著,在封包過濾的區段,它在各個 pass 的規則上,依連線的 port 不同, 加上了不同的 queue。其中 $developerhosts 和 $employeehosts 是事先定義好的 macros,分別代表不同的網路位址。

PF 的 ALTQ 頻寬限制很強大,也很複雜。不過網路上的資源也不少,如果您使用上有任何的問題, 針對您的使用需求,應該可以找到很多參考文件。

12.3.5 PF 防火牆日誌及狀態

PF 防火牆在運作時,我們可以讓它把阻擋或允許的封包記錄下來,以供日後查看。 要啟用記錄功能,必須先確定在 /etc/rc.conf 中有加入下列設定:

pflog_enable="yes"

接著要在 PF 規則中加上 log 的功能。例如,在下列規則中,我們使用了 log (all) 來記錄被阻擋的封包。如果只寫成 log,只會記錄有建立 state 的連線, 而不會記錄直接被擋掉的封包:

block in log (all) from 192.168.0.6 to any

PF log 會放在 /var/log/pflog,讓檔案是以封包的格式記錄。 我們可以使用下列指令來查看:

#tcpdump -ner /var/log/pflog

另外,我們也可以直接存取 pflog 這個虛擬的網路介面來監看即時的封包記錄:

#tcpdump -nei pflog0

如果您要想監看 PF 防火牆的即時狀況,可以使用 pftop 這個工具。不過 pftop 並不是系統內建的指令, 我們必須先安裝才能使用。請先使用下列指令安裝:

#cd /usr/ports/sysutils/pftop
#make install clean

接著,就可以執行 pftop 以監看 PF 的即時狀態:

#pftop
pfTop: Up State 1-44/56, View: default, Order: none, Cache: 10000 09:27:47 PR DIR SRC DEST STATE AGE EXP PKTS BYTES tcp Out 192.168.165.2:61428 96.7.225.162:443 ESTABLISHED:ESTABLISHED 00:03:24 86379 63 32783 tcp Out 192.168.165.2:53436 211.23.38.103:443 ESTABLISHED:ESTABLISHED 00:03:23 86383 512 341883 tcp Out 192.168.165.2:57257 13.88.31.235:443 ESTABLISHED:ESTABLISHED 00:03:09 86384 30 8881 tcp Out 192.168.165.2:51596 23.218.217.153:443 ESTABLISHED:ESTABLISHED 00:03:03 86368 177 146029 tcp Out 192.168.165.2:65364 52.226.139.180:443 TIME_WAIT:TIME_WAIT 00:02:56 4 6 243 tcp Out 192.168.165.2:50473 211.23.38.102:443 ESTABLISHED:ESTABLISHED 00:02:41 86396 163 30771 tcp Out 192.168.165.2:58516 211.23.38.102:443 ESTABLISHED:ESTABLISHED 00:02:35 86396 160 30358 tcp Out 192.168.165.2:50278 64.233.185.188:5228 ESTABLISHED:ESTABLISHED 00:02:10 86364 31 9474
12.4 以 blacklistd 防止暴力密碼嘗試

網際網路上時常有駭客在掃瞄網路上的伺服器,當發現有需要登入的服務時 (例如 ssh, smtp 等) ,就會嘗試使用程式暴力破解的方式,一直嘗試不同的密碼,以登入伺服器。 最常看到被嘗試的登入的服務就是 SSH 和 SMTP 了。

FreeBSD 系統每天都會寄 daily security run output 的信件給 root,如果有人嘗試登入失敗很多次, 您可能會看到很多類似下列的訊息:

Oct 5 04:20:08 twbsd sshd[36771]: Invalid user cssserver from 93.63.37.231 port 60396 Oct 5 04:20:08 twbsd sshd[36771]: Disconnected from invalid user cssserver 93.63.37.231 port 60396 [preauth] Oct 5 04:20:11 twbsd sshd[36773]: Invalid user support from 93.63.37.231 port 34090 Oct 5 04:20:11 twbsd sshd[36773]: Disconnected from invalid user support 93.63.37.231 port 34090 [preauth] Oct 5 04:20:17 twbsd sshd[36776]: Invalid user patricia from 93.63.37.231 port 35990 Oct 5 04:22:06 twbsd sshd[36805]: Invalid user user13 from 91.205.217.22 port 44684 Oct 5 04:22:06 twbsd sshd[36805]: Disconnected from invalid user user13 91.205.217.22 port 44684 [preauth] Oct 5 04:22:10 twbsd sshd[36810]: Invalid user minerva from 91.205.217.22 port 46540 Oct 5 04:22:10 twbsd sshd[36810]: Disconnected from invalid user minerva 91.205.217.22 port 46540 [preauth] Oct 5 04:22:14 twbsd sshd[36812]: Invalid user gimmig from 90.152.200.81 port 50442 Oct 5 04:22:14 twbsd sshd[36812]: Disconnected from invalid user gimmig 90.152.200.81 port 50442 [preauth]

如果我們的伺服器完全沒有保護,總有一天會被猜中密碼。為了要讓對外的伺服器更安全,首先要確定密碼強度要夠強。 不要使用簡單的密碼。再者,不要使用預設的 Port。例如 SSH,盡量不要使用 Port 22,改用其它的 Port 可以降低被攻擊的可能性。但是,很多服務是無法改 Port 的 (如 SMTP),而且改 Port 還是會受到攻擊。所以, 最好的方式是當嘗試登入太多次時,就把該 IP 擋掉。

FreeBSD 提供了 blacklistd 這個程式,可以讓我們在登入失敗太多次時,就呼叫防火牆來阻擋遠端的 IP。

12.4.1 啟用 blacklistd

我們先來看一下 blacklistd 的設定檔 /etc/blacklistd.conf

# $FreeBSD$ # # Blacklist rule # adr/mask:port type proto owner name nfail disable [local] ssh stream * * * 3 24h ftp stream * * * 3 24h smtp stream * * * 3 24h submission stream * * * 3 24h #6161 stream tcp6 christos * 2 10m * * * * * 3 60 # adr/mask:port type proto owner name nfail disable [remote] #129.168.0.0/16 * * * = * * #6161 = = = =/24 = = #* stream tcp * = = = # 我們加入下列這一行,讓 blacklistd 不要阻擋任何本地的 IP 192.168.0.0/24 * * * * * *

我們最常用來阻擋的服務有 SSH 和 SMTP,預設是在登入失敗三次後 (nfail) 就擋掉該 IP。 而在 24 小時後就不再阻擋 (disable)。我們可以把 24h 延長為 48h 或 72h, 或乾脆改成 * 以永遠阻擋該 IP。另外,我們在檔案最後 [remote] 的區段中, 加入了不要阻擋任何本地 IP (192.168.0.0/24) 的設定。

接著,我們要在 /etc/rc.conf 中啟用 blacklistd:

blacklistd_enable="yes"

然後就可以啟動 blacklistd 了:

#service blacklistd start

啟用了 blacklistd 後,它還需要防火牆的協助才能阻擋連線。防火牆方面, 我們可以使用 IPFW 或 PF。以下,我們就分別針對這二種防火牆來說明其設定,您只要使用其中一個即可。

使用 IPFW

如果您要使用 IPFW 做為防火牆,但是防火牆還有沒啟用,您可以在 /etc/rc.conf 中加入下列設定。如果您已經在使用 IPFW 做 NAT,可以忽略這項設定:

firewall_enable="YES" firewall_type="open"

接著,新增 /etc/ipfw-blacklist.rc 這個檔案來讓 blacklistd 知道我們要使用 IPFW 來阻擋 IP:

#touch /etc/ipfw-blacklist.rc

然後,就可以啟動 IPFW 了:

#service ipfw start
使用 PF

如果您使用的是 PF 防火牆,請先在 /etc/rc.conf 中啟用 PF:

pf_enable="yes" pflog_enable="yes"

如果您已經有使用 PF 防火牆,則只要在過濾規則的最上方加上下列 blacklistd 的 Anchor 即可。 如果您沒有其它的 PF 設定,可以直接新增並編輯 /etc/pf.conf

anchor "blacklistd/*"

然後,就可以啟動 PF 了:

#service pf start
在服務中啟用 blacklistd

在 blacklistd 的設定都啟用後,我們就可以在各種登入服務中啟用 blacklistd 了。首先是 SSH。 請編輯 /etc/ssh/sshd_config,找到 UseBlacklist 並將它改成 Yes:

... UseBlacklist yes ...

然後,執行下列指令來重新載入設定:

#service sshd reload

現在您就可以測試看看登入 SSH 如果失敗三次會不會自動被防火牆阻擋了。

在其它服務方面,如果您有架設 SMTP 服務,Postfix 預設就已經啟用 blacklistd, 我們不需要進行任何設定就可以用了。

12.4.2 管理 blacklistd

blacklistd 提供了 blacklistctl 這個工具讓我們可以查看目前被阻擋的 IP。 我們可以加上參數 -b 只看被阻擋的 IP,或是參數 -a 看所有登入失敗的 IP。

#blacklistctl dump -b
address/ma:port id nfail last access 62.197.136.62/32:25 OK 3/3 2022/05/20 14:28:47 2.58.149.176/32:25 OK 3/3 2022/05/19 15:50:31 5.34.207.107/32:25 OK 3/3 2022/05/20 14:12:05

如果要把一個已經阻擋的 IP 移除,必須從防火牆中著手。以下, 我們就來看看如何在不同防火牆中管理被阻擋的 IP。

管理 IPFW 黑名單

IPFW 使用 table 來管理被阻擋的 IP。您可以使用下列指令列出目前所有 table:

#ipfw table all list
--- table(port25), set(0) --- 2.58.149.176/32 0 5.34.207.171/32 0 --- table(port1022), set(0) --- 163.172.82.100/32 0

blacklistd 會以阻擋的 port 為 table 的名稱。我們可以看到,目前有二個 table, 名稱分別為 port25 及 port1022。如果您只要看 port 25 被阻擋的 IP,可以使用下列指令:

#ipfw table port25 list
2.58.149.176/32 0 5.34.207.171/32 0

如果要把 port25 中的一個 IP 移除,我們可以使用下列指令:

#ipfw table port25 delete 2.58.149.176
deleted: 2.58.149.176/32 0
管理 PF 黑名單

PF 使用 anchor 加 table 來存放黑名單。我們先看一下目前所有的 Anchor 有哪些:

#pfctl -s Anchors
blacklistd

我們可以看到目前只有一個 blacklistd 的 Anchor。但是針對每一個 port, PF 會在 blacklistd 的 anchor 中再存放其它的 anchor。以下指令使用參數 -a 之後加上 anchor 名稱 blacklistd,以查看 blacklistd 下的 anchor 有哪些 (-s Anchors 來看 anchors):

#pfctl -a blacklistd -s Anchors
blacklistd/22 blacklistd/25

我們可以看到現在有二個 anchor,分別是 port 22 及 25。Anchor 的名稱分別為 blacklistd/22 及 blacklistd/25。我們來看看 blacklistd/22 這個 anchor 下有什麼阻擋的規則 (-s rules 來看規則):

#pfctl -a blacklistd/22 -s rules
block drop in quick proto tcp from <port22> to any port = ssh

我們可以看到它使用 table 名稱 port22 來阻擋 IP。我們可以用下列指令來看看 table port22 的內容:

#pfctl -a blacklistd/22 -t port22 -T show
2.58.149.176 2.58.149.55

如果要移除一個 IP,只要使用下列指令

#pfctl -a blacklistd/22 -t port22 -T delete 2.58.149.176
1/1 addresses deleted.
12.5 網路流量監控

做為一台 NAT 路由器,難免會需要監控網路活動。本節中,我們將介紹二個監看活動的工具:iftop 及 ntopng。

12.5.1 iftop

iftop 是一個命令列工具,它可以讓我們看到目前的連線有哪些,及其使用的頻寬。

我們先使用下列指令來安裝 iftop:

#cd /usr/ports/net-mgmt/iftop/
#make install clean

接著,我們就可以使用 iftop 來看網路活動。在使用 iftop 時,我們可以指定要監看的介面卡。以下, 我們加上參數 -i igc1 來查看介面卡 igc1:

#iftop -i igc1
12.5Kb 25.0Kb 37.5Kb 50.0Kb 62.5Kb └─────────────────────┴──────────────────────┴──────────────────────┴──────────────────────┴────────────────────── ym-in-f102.1e100.net => 192.168.0.113 923Kb 308Kb 308Kb <= 15.1Kb 5.05Kb 5.05Kb yq-in-f100.1e100.net => 192.168.0.113 0b 11.5Kb 11.5Kb <= 0b 22.1Kb 22.1Kb dns.google => 192.168.0.113 40.6Kb 17.5Kb 17.5Kb <= 25.4Kb 10.8Kb 10.8Kb iad30s43-in-f14.1e100.net => 192.168.0.113 3.93Kb 2.04Kb 2.04Kb <= 63.9Kb 24.5Kb 24.5Kb yx-in-f102.1e100.net => 192.168.0.113 0b 9.57Kb 9.57Kb <= 0b 6.01Kb 6.01Kb yx-in-f94.1e100.net => 192.168.0.113 8.16Kb 2.72Kb 2.72Kb <= 30.6Kb 10.2Kb 10.2Kb 192.168.0.254 => 192.168.0.113 12.8Kb 10.5Kb 10.5Kb <= 1.56Kb 1.41Kb 1.41Kb yx-in-f95.1e100.net => 192.168.0.113 13.0Kb 4.32Kb 4.32Kb <= 9.70Kb 3.23Kb 3.23Kb yb-in-f132.1e100.net => 192.168.0.113 12.5Kb 4.16Kb 4.16Kb <= 9.56Kb 3.19Kb 3.19Kb ym-in-f91.1e100.net => 192.168.0.113 10.1Kb 3.37Kb 3.37Kb <= 10.1Kb 3.37Kb 3.37Kb dns.google => 192.168.0.113 3.86Kb 1.73Kb 1.73Kb <= 2.63Kb 1.04Kb 1.04Kb yb-in-f95.1e100.net => 192.168.0.113 3.60Kb 1.27Kb 1.27Kb <= 2.17Kb 823b 823b yb-in-f113.1e100.net => 192.168.0.113 0b 0b 0b <= 5.41Kb 1.80Kb 1.80Kb ym-in-f95.1e100.net => 192.168.0.113 0b 0b 0b <= 5.40Kb 1.80Kb 1.80Kb ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── TX: cum: 283KB peak: 1.01Mb rates: 1.01Mb 378Kb 378Kb RX: 72.0KB 183Kb 183Kb 95.9Kb 95.9Kb TOTAL: 355KB 1.19Mb 1.19Mb 474Kb 474Kb
12.5.2 ntopng

第二個工具是 ntopng,它是一個網頁圖形介面的監看工具。您可以到 https://www.ntop.org/ 看更多關於 ntopng 的介紹。

ntopng 使用 redis 做為資料庫。我們先使用下列指定安裝 redis 及 ntopng:

#cd /usr/ports/databases/redis
#make install clean
#cd /usr/ports/net/ntopng/
#make install clean

ntopng 會開啟一個網頁伺服器,讓我們可以登入監看網路流量。因為有登入的需求, 最好使用加密的 HTTPS。為了啟用 HTTPS,我們必需先新增 HTTPS 憑證:

#cd /usr/local/share/ntopng/httpdocs/ssl/
#openssl req -new -x509 -sha1 -extensions v3_ca -nodes -days 365 -out cert.pem
#cat privkey.pem cert.pem > ntopng-cert.pem
#rm privkey.pem cert.pem

新增憑證後,我們就可以在 /etc/rc.conf 中啟用 redis 及 ntopng。 為了使用 HTTPS並只允許對內網路連線,我們在 ntopng_flags 中設定 HTTPS 只接受連到內部 IP 192.168.0.1 的連線。如果您伺服器的內部 IP 不同,請記得更改 IP。

redis_enable="YES" ntopng_enable="YES" ntopng_flags="--http-port=0 --https-port=192.168.0.1:3000"

接著,請使用下列指令啟動 redis 及 ntopng:

#service redis start
#service ntopng start

最後請使用瀏覽器連到 https://192.168.0.1:3000 以登入 ntopng。預設的 ntopng 使用者是 admin, 密碼也是 admin,登入後請修改密碼。

圖 12-2

您登入後,可能會看到右上角有提示 "Running without Geolocation"。 那是因為 ntopng 可以查詢 IP 所在國家,但是我們沒有安裝供查詢的資料庫所致。

ntopng 可以使用 MaxMind 所提供的免費資料庫。如果要安裝 geoip 資料庫,請先到 下列網址註冊 MaxMind 帳號:

https://www.maxmind.com/en/geolite2/signup

註冊完畢且通過郵件認證後,你登入時會顯示您的 AccountID 及 LicenseKey。 請把這二個資訊記下來。

接下來,請安裝 geoip 自動下載程式:

#cd /usr/ports/net/geoipupdate
#make install clean

安裝完後,請編輯 /usr/local/etc/GeoIP.conf, 請在 AccountID 及 LicenseKey 的部份輸入你的帳戶資訊,並在 EditionIDs 設定使用 ASN 及 City 這二個資料庫。如下所示:

AccountID YOUR_ACCOUNT_ID_HERE LicenseKey YOUR_LICENSE_KEY_HERE EditionIDs GeoLite2-ASN GeoLite2-City

存檔後,請使用下列指令下載 geoip 資料庫:

#geoipupdate -d /usr/local/share/ntopng/httpdocs/geoip

你可以看到在 /usr/local/share/ntopng/httpdocs/geoip 中有我們剛下載的資料庫。 最後,重新啟動 ntopng 即可:

#service ntopng restart