第十五章 Proxy Server
15.1 概論
Proxy 可以用來(lái)降低 WWW 及 FTP 的網(wǎng)絡(luò)流量,它的運(yùn)作原理簡(jiǎn)而言之就是當(dāng)網(wǎng)域中其它計(jì)算機(jī)要瀏覽網(wǎng)頁(yè)時(shí),必須先通過(guò) proxy 服務(wù)器,如果在 proxy 中已存有該網(wǎng)頁(yè)時(shí),就直接送出給網(wǎng)域中的計(jì)算機(jī);如果沒(méi)有,則連到該網(wǎng)頁(yè)取回來(lái)存放,并送一份給提出要求的計(jì)算機(jī),待下次再有相同要求時(shí),就可以直接從 proxy 的存檔中送出。
我們會(huì)在 proxy 服務(wù)器中設(shè)定數(shù)據(jù)要存放多久的時(shí)間并更新,以免使用者看到的都是存在 proxy 中的舊網(wǎng)頁(yè)。這對(duì)于內(nèi)部有大量的使用者時(shí),可以明顯降低網(wǎng)絡(luò)流量。如果網(wǎng)域中只有十幾臺(tái)計(jì)算機(jī),那么 proxy 就比較不能發(fā)揮它的功效了。我們也可以在 proxy 中設(shè)定使用者不可以瀏覽的網(wǎng)頁(yè),限制使用者連到某些網(wǎng)站。
一般而言,使用者要使用 proxy 時(shí),必須先在自己計(jì)算機(jī)上做一些設(shè)定。我們也可以利用 proxy 結(jié)合防火墻,當(dāng)使用者對(duì)外提出 HTTP 要求時(shí),即自動(dòng)轉(zhuǎn)向到 proxy server,如此一來(lái),使用者端便不需做任何設(shè)定,甚至不會(huì)發(fā)覺(jué)有 proxy 的存在。
在這里我們介紹一個(gè)被廣為使用的 proxy 軟件 「squid」。squid 的安裝及設(shè)定很簡(jiǎn)單,我們會(huì)在下面幾節(jié)中一一為大家介紹。
15.2 安裝 Squid
感謝美好的 FreeBSD ports,可以讓我們很簡(jiǎn)單的安裝 squid。請(qǐng)使用下列指令:
# cd /usr/ports/www/squid24 # make install
如此便已安裝 squid 了。接下來(lái)就必須要修改 /usr/local/etc/squid/squid.conf 了,squid.conf 是整個(gè) squid 的設(shè)定所在,內(nèi)容很多,我們下一章再做詳細(xì)的介紹。這里我們只作簡(jiǎn)單的設(shè)定,也就是先定義誰(shuí)可以使用 proxy,例如我要定義只有 192.168.0.* 及 *.alexwang.com 可以使用,則在 squid.conf 中找到 ACCESS CONTROLS 的區(qū)段中的 acl 部份,加入下面內(nèi)容:
acl domain_allowed srcdomain .alexwang.com acl ip_allowed src 192.168.0.0/24 |
在上面二行中,我們先將網(wǎng)址及 IP 定義一個(gè)名字,將所有在 *.alexwang.com 的網(wǎng)址定義名稱(chēng)為 domain_allowed;將 192.168.0.0-192.168.0.255 的 IP 命名為 ip_allowed。接著再找到 http_access 的部份,在 http_access deny all 之前加入下面有內(nèi)容:
http_access allow domain_allowed http_access allow ip_allowed |
上面是允許名稱(chēng)為 domain_allowed 及 ip_allowed 的網(wǎng)址使用 proxy。關(guān)于上述設(shè)定的說(shuō)明請(qǐng)參考 squid.conf 介紹。
修改完 squid.conf 之后,接著要建立 cache 目錄結(jié)構(gòu),預(yù)設(shè)的 cache 目錄在 /usr/local/squid/cache 中,如果要將它放在其它目錄的話,必須修改 squid.conf 并建立所設(shè)定的目錄。接著使用下列指定來(lái)改變檔案權(quán)限并建立 cache 的目錄結(jié)構(gòu):
# chown -R nobody:nogroup /usr/local/squid/cache # chown -R nobody:nogroup /usr/local/squid/logs # /usr/local/sbin/squid -z
當(dāng)下達(dá) squid -z 的指令時(shí),必須等上幾分鐘的時(shí)間。安裝好 squid 之后,在 /usr/local/etc/rc.d/ 有一個(gè)名為 squid.sh 的檔案,表示在開(kāi)機(jī)時(shí)便用自動(dòng)啟動(dòng) squid。當(dāng)做好一切設(shè)定之后,我們只要執(zhí)行下列指令即可啟動(dòng) squid。
# /usr/local/etc/rc.d/squid.sh start
我們?cè)谶@里的設(shè)定只是讓你能立即使用 proxy,詳細(xì)的設(shè)定必須再修改 squid.conf,一些相關(guān)的設(shè)定如某個(gè)時(shí)段禁止連到某個(gè)地址、數(shù)據(jù)保存期限等等。
接下來(lái)是 client 端的設(shè)定,以 MS Windows 為例:
對(duì)著桌面的 IE 按右鍵選 [內(nèi)容] 或是在控制臺(tái)中選 [因特網(wǎng)選項(xiàng)],出現(xiàn)圖 15-1 的窗口:
圖 15-1
選擇上方 [聯(lián)機(jī)] 的標(biāo)簽后,再點(diǎn)選 [局域網(wǎng)絡(luò)設(shè)定],出現(xiàn)下面窗口。接著在Porxy 服務(wù)器的部份,在網(wǎng)址的部份輸入 proxy server 的網(wǎng)址,連接端口默認(rèn)值是 3128,接著按確定即可使用瀏覽器來(lái)試試看可不可以使用了:
圖 15-2
15.3 Squid.conf 介紹
Squid 的設(shè)定檔位于 /usr/local/etc/squid/squid.conf。在安裝完 Squid 之后,我們必須修改它以期符合我們的需求。在 squid.conf 中,開(kāi)頭為 "#" 表示批注,每一個(gè)設(shè)定選項(xiàng)都有 TAG 表示選項(xiàng)名稱(chēng)、Usage 表示用法、Defaualt 表示默認(rèn)值。如果不須改變默認(rèn)值,我們不必將該行的批注 "#" 拿掉,否則可能會(huì)產(chǎn)生一些問(wèn)題。在檔案中有的 Default 寫(xiě)著 "none" 表示該選項(xiàng)沒(méi)有默認(rèn)值。
squid.conf 的詳細(xì)說(shuō)明可以到 www.squid-cache.org 參考設(shè)定手冊(cè)。我們?cè)谶@里介紹幾個(gè)常用的選項(xiàng)設(shè)定方式:
選項(xiàng)名稱(chēng): http_port
用法:
http_port port http_port hostname:port http_port 1.2.3.4:port這是 Squid 要接收 HTTP 要求時(shí)所使用的 port??梢允褂萌N格式:只指定 port、使用 hostname 及 port、或是 IP 地址及 port。一般而言,我們只要指定 port 即可。我們也可以設(shè)定多行 http_port 來(lái)使用多個(gè) port。
預(yù)設(shè)的 port 是 3128。
我們也可以在命令列下執(zhí)行 squid 這個(gè)指令,并以參數(shù) -a 來(lái)取代 squid.conf 中所設(shè)定的第一個(gè) port。例如,我們要啟動(dòng) squid 并將 port 改成 8080,可以下指令: /usr/local/sbin/squid -a 8080 使用 -a 來(lái)覆蓋在 squid.conf 中所設(shè)定的第一個(gè) port 只能適用于只指定 port 時(shí),如果在 port 前有加上 ip 或 hostname 的話,這個(gè)指令就不會(huì)產(chǎn)生做用。
選項(xiàng)名稱(chēng): icp_port
當(dāng) Squid 接收到 ICP 查詢時(shí),要響應(yīng)時(shí)所使用的 port,可以設(shè)為 0 來(lái)停用 ICP 查詢。也可以在命令列使用 -u 來(lái)覆蓋這里的設(shè)定。 ICP 是 Squid cache 之間所使用的協(xié)議,用來(lái)交流多臺(tái) Squid 的 cache。目前 ICP 是使用 UDP 協(xié)議。
默認(rèn)值: icp_port 3130
選項(xiàng)名稱(chēng): mcast_groups
這個(gè)選項(xiàng)是用來(lái)指定這臺(tái)服務(wù)器要加入 ICP 廣播的群組,也就是指定 要收到的 ICP 查詢的來(lái)源主機(jī)。 請(qǐng)注意!這個(gè)設(shè)定是 "接收" 查詢而不是 "送出" 查詢。如果要送出 ICP 廣播查詢是使用 cache_peer。 不可以將已加入別的群組的主機(jī)加入。
如果你想更深入了解 multcast 請(qǐng)參考 Squid FAQ (http://www.squid-cache.org/FAQ/)。
用法:
mcast_groups 239.128.16.128 224.0.1.20預(yù)設(shè)是不加入任何群組。
默認(rèn)值:無(wú)
選項(xiàng)名稱(chēng):cache_peer
用法:
cache_peer hostname type http_port icp_port [options]這個(gè)選項(xiàng)可以讓你設(shè)定上游的 proxy server,當(dāng)本地沒(méi)有該筆數(shù)據(jù)時(shí),則向上游查詢。
例如上游的 proxy 是 proxy.ncu.edu.tw,我們可以設(shè)定:
cache_peer proxy.ncu.edu.tw parent 3128 3130
選項(xiàng)名稱(chēng):no_cache
設(shè)定不需要使用 cache 的項(xiàng)目。例如 CGI 不使用 cache,則可以做下列的設(shè)定:
acl QUERY urlpath_regex cgi-bin \? no_cache deny QUERY如果連 php、asp 都不要做 cache:
acl QUERY urlpath_regex cgi-bin \? \.php \.asp \.cgi no_cache deny QUERY
選項(xiàng)名稱(chēng):cache_mem
設(shè)定存放在內(nèi)存中的數(shù)據(jù)大小,以 byte 為單位。這并不表示 squid 程序?qū)⒃谀銉?nèi)存中的所占的容量,除了 cache 的數(shù)據(jù)外,還有一些額外的東西會(huì)被放到內(nèi)存中 (如 HD 的 index)。因此實(shí)際使用的內(nèi)存大小可能是這里設(shè)定的二倍或三倍。建議設(shè)定為實(shí)際內(nèi)存的三分之一。例如:
cache_mem 64 MB
選項(xiàng)名稱(chēng):maximum_object_size
cache 對(duì)象的大小,超過(guò)此設(shè)定值則不存放于硬盤(pán)中。例如要設(shè)定檔案大于 8 MB 則不儲(chǔ)存:
maximum_object_size 8192 KB
選項(xiàng)名稱(chēng):cache_dir
設(shè)定 cache 在硬盤(pán)中的目錄、大小限制等。默認(rèn)值是:
cache_dir ufs /usr/local/squid/cache 100 16 256ufs 是 squid 的儲(chǔ)存格式,一定要加。接下來(lái)的 /usr/local/squid/cache 是存放 cache 數(shù)據(jù)的地方。100 表示最多使用 100 MB 做為 cache 的空間,我們可以把它調(diào)大一點(diǎn)。而 16 256 是 cache 目錄第一層及第二層的結(jié)構(gòu),建議不要更動(dòng)。之前使用 /usr/local/sbin/squid -z 就是在建立 cache 目錄的結(jié)構(gòu)。
為了讓 cache 的資料能存放多一點(diǎn),我們可以將設(shè)定改成下面這樣:
cache_dir ufs /usr/local/squid/cache 2000 16 256
選項(xiàng)名稱(chēng):cache_access_log
cache 的使用記錄存放的位置,內(nèi)容包含了所有 HTTP 及 ICP 要求。默認(rèn)值是:
cache_access_log /usr/local/squid/logs/access.log
選項(xiàng)名稱(chēng):cache_log
這是設(shè)定另一個(gè)記錄文件的位置,該文件中包含了 cache server 的一些信息、和 cache_peer 之間的聯(lián)機(jī)等等。我們可以更改 "debug_options" 的選項(xiàng)來(lái)設(shè)定要記錄的信息。默認(rèn)值是:
cache_log /usr/local/squid/logs/cache.log
選項(xiàng)名稱(chēng):cache_store_log
記錄哪些數(shù)據(jù)被儲(chǔ)存??梢允褂?"none" 來(lái)停止這方面的記錄。上面的 log 檔,都可以用一些工具來(lái)分析 squid 的使用情形,但 store log 并沒(méi)有,所以如果不想記錄可以使用 "none" 來(lái)停止。
選項(xiàng)名稱(chēng):pid_filename
設(shè)定存放 pid (process id) 的檔案位置。
選項(xiàng)名稱(chēng):ftp_user
設(shè)定當(dāng) proxy 以 anonymous FTP 聯(lián)機(jī)時(shí),要使用的 email。你可以設(shè)為:
ftp_user you@yourdomain.com
選項(xiàng)名稱(chēng):cache_dns_program
squid 使用的 dns 查詢程序的位置。squid 在查詢 dns 時(shí),會(huì)新增一個(gè)子程序 (process child) 來(lái)做查詢,以免查詢時(shí)間太長(zhǎng)阻礙了 squid 的正常運(yùn)作。
選項(xiàng)名稱(chēng):dns_children
設(shè)定 dns 查詢的 children 最大數(shù)量,默認(rèn)值是 5,最大可以設(shè)為 32。以一個(gè)忙錄的 squid server 而言,最小建議設(shè)為 10。
選項(xiàng)名稱(chēng):acl
Access Control List。我們可以利用它來(lái)控制聯(lián)機(jī)的權(quán)限及狀態(tài)。用 acl 來(lái)搭配 http_access 等,可以讓我們更方便管理。
用法:
acl aclname acltype string1 ... acl aclname acltype "file" ...aclname 是我們自己命名的標(biāo)識(shí)符,要注意不要使用到 squid 的關(guān)鍵詞。而 acltype 可以使用下列的選項(xiàng):
- src:表示來(lái)源,即 client 的 IP。
如:acl localip src 192.168.0.0/24- srcdomain:表示來(lái)源,為 domain name 的格式。
如:acl localdomains srcdomain .alexwang.com- dst:表示目的地的 IP。
如:acl acceleratedhost dst 172.16.1.115/255.255.255.255- dstdomain:表示目的地的 domain name。
如:acl badwebsite dstdomain www.sex.com- srcdom_regex:對(duì)來(lái)源的 URL 做正規(guī)表達(dá)式(regular expression)運(yùn)算。
如:acl localwebsite srcdom_regex mydomain.com- dstdom_regex:對(duì)目的地的URL 做正規(guī)表達(dá)式(regular expression)運(yùn)算。
如:acl sexwebsite srcdom_regex ^http://www.playboy.com- time:指定時(shí)間。
用法:acl aclname time [day-abbrevs] [h1:m1-h2:m2]
day-abbrevs:
S - Sunday
M - Monday
T - Tuesday
W - Wednesday
H - Thursday
F - Friday
A - Saturday
h1:m1 一定要比 h2:m2 小- port:指定連接埠。
如:acl SSL_ports port 443- proto:指定所使用的通訊協(xié)議。
如:acl allowprotolist proto HTTP更多的 acltype 關(guān)鍵詞請(qǐng)看 squid.conf。
選項(xiàng)名稱(chēng):http_access
用來(lái)控制要開(kāi)放 squid 給哪些來(lái)源使用。預(yù)設(shè)是全部拒絕,最好不要不設(shè)防,例如使用 http_access allow all 就是一個(gè)不好的方式。
我們可以利用 http_access 搭配 acl 來(lái)控制使用情形。例如要開(kāi)放給內(nèi)部網(wǎng)域使用:
# INSERT YOUR OWN RULE HERE TO ALLOW ACCESS FROM # YOUR CLIENTS acl domain_allowed srcdomain .alexwang.com acl ip_allowed src 192.168.0.0/24 http_access allow domain_allowed http_access allow ip_allowed在設(shè)定了可以使用的來(lái)源之后,最后再加上下列設(shè)定來(lái)拒絕其它聯(lián)機(jī):
http_access deny all
選項(xiàng)名稱(chēng):icp_access
控制 squid 只響應(yīng)哪些 sibling/child 的 ICP 詢問(wèn)。例如,只允許校內(nèi)機(jī)器使用:
acl ncu src 140.115.0.0/255.255.0.0 icp_access allow ncu icp_access deny all
選項(xiàng)名稱(chēng):miss_access
控制只能做為 sibling 而不做 parent,例如:
acl localclients src 172.16.0.0/16 miss_access allow localclients miss_access deny !localclients
選項(xiàng)名稱(chēng):cache_peer_access
和 cache_peer 一樣,只是這個(gè)選項(xiàng)可以使用 acl 來(lái)控制。
選項(xiàng)名稱(chēng):cache_mgr
squid 管理者的 email??梢栽O(shè)定為本機(jī)的使用者,例如:
cache_mgr webmaster或別臺(tái)主機(jī)的 email:
cache_mgr jack@otherdomain.com
選項(xiàng)名稱(chēng):cache_effective_user
選項(xiàng)名稱(chēng):cache_effective_group
如果 squid 是以 root 的身份來(lái)執(zhí)行,它會(huì)自動(dòng)切換成這里所設(shè)定的使用者及群組。預(yù)設(shè)是 nobody,所以我們才會(huì)把 /usr/local/squid/cache 及 /usr/local/squid/logs 的擁有者改成 nobody。
選項(xiàng)名稱(chēng):visible_hostname
設(shè)定當(dāng) error message 顯示時(shí)的 hostname。如果沒(méi)有設(shè)定則以 gethostname() 所得到的 hostname 為主。
選項(xiàng)名稱(chēng):httpd_accel_host
選項(xiàng)名稱(chēng):httpd_accel_port
如果要以 Transparent Proxy 來(lái)執(zhí)行,則設(shè)定:
httpd_accel_host virtual
httpd_accel_port 80
選項(xiàng)名稱(chēng):httpd_accel_with_proxy on|off
如果要以 Transparent Proxy 及一般的 proxy 來(lái)執(zhí)行則設(shè)為 on。
選項(xiàng)名稱(chēng):httpd_accel_uses_host_header on|off
如果要以 Transparent Proxy 來(lái)執(zhí)行,則設(shè)為 on。讓 squid 可以經(jīng)由 HTTP header 來(lái)判斷 url。
選項(xiàng)名稱(chēng):logfile_rotate
設(shè)定要保留的 log file 份數(shù),讓執(zhí)行 squid -k rotate 來(lái)分析 squid 時(shí)使用。
選項(xiàng)名稱(chēng):err_html_text
該你可以在指定要出現(xiàn)的 error page (就是會(huì)有 mailto 的網(wǎng)頁(yè))。
選項(xiàng)名稱(chēng):deny_info
用法:
deny_info err_page_name acl可以讓你指定當(dāng)拒絕聯(lián)機(jī)時(shí)要使用的 HTML 檔案。例如:
deny_info ERR_CUSTOM_ACCESS_DENIED bad_guys這些 HTMl 檔都放在 /usr/local/etc/squid/errors/,而且沒(méi)有擴(kuò)展名 .html。
選項(xiàng)名稱(chēng):error_directory
如果自行建立一些 error message 的 HTML,我們可以放在預(yù)設(shè)的 /usr/local/etc/squid/errors 或是自行指定目錄位置。
15.4 Transparent Proxy
有的使用者可能不想設(shè)定 Proxy,或者是管理者希望能不必設(shè)定 client 端即可使用 proxy,我們可以使用 Transparent Proxy 來(lái)強(qiáng)迫使用者使用 Proxy。只要在 Gateway 上使用防火墻來(lái)將對(duì)外的聯(lián)機(jī)要求重導(dǎo)到 proxy server 即可。
這里我們假設(shè) Proxy 就是 Gateway,它身兼 NAT 功能,我們內(nèi)部的網(wǎng)域?yàn)?192.168.0.1/24。我們不提 NAT 的設(shè)定,只針對(duì) Transparent Proxy 相關(guān)的設(shè)定加以說(shuō)明。首先要先確認(rèn) kernel 中除了原有關(guān)于防火墻的設(shè)定外,有沒(méi)有 FORWARD 封包的設(shè)定,如果沒(méi)有必需自行加入并重編 kernel:
# 原有的防火墻設(shè)定 options IPFIREWALL options IPDIVERT options IPFIREWALL_VERBOSE options IPFIREWALL_DEFAULT_TO_ACCEPT # 新加入關(guān)于封包轉(zhuǎn)向的設(shè)定 options IPFIREWALL_FORWARD |
接著在 /etc/rc.firewall 中加入:
/sbin/ipfw add 50000 fwd 127.0.0.1,3128 tcp from 192.168.0.0/24 to any 80 |
上面那一行的設(shè)定表示凡是由 192.168.0.* 的 IP 要連到任何對(duì)于的 port 80 時(shí),便轉(zhuǎn)向到 127.0.0.1 這臺(tái)機(jī)器(也就是本機(jī)) 的 port 3128。你可以依自己的情況加以修改。然后編輯 /usr/local/etc/squid/squid.conf,在最開(kāi)頭加入下面這幾行:
httpd_accel_host virtual httpd_accel_port 80 httpd_accel_with_proxy on httpd_accel_uses_host_header on |
完成后重新啟動(dòng) squid 及 ipfw 即可使用。
15.5 Proxy 管理
15.5.1 log 檔移轉(zhuǎn)
log 檔在頻繁的使用下會(huì)一直成長(zhǎng),因此我們可以利用 crontab 來(lái)設(shè)定每天備份各個(gè) log 檔。執(zhí)行 crontab -e 后,加入下列內(nèi)容:
0 5 * * * /usr/local/sbin/squid -k rotate |
這里我們?cè)O(shè)定為每天早上五點(diǎn)備份 log 檔,如果您對(duì)于 crontab 的用法不熟悉,請(qǐng) man crontab。
15.5.2 關(guān)機(jī)注意事項(xiàng)
由于 squid 對(duì)于硬盤(pán)的讀寫(xiě)十分頻繁,而且有大量的數(shù)據(jù)在內(nèi)存中。因此在關(guān)機(jī)前要先停止 squid:
# /usr/local/etc/rc.d/squid.sh stop