httpd配置文件詳解及實例
作者:尹正傑
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
一.http協議的組成
http協議是C/S架構:我們可以把瀏覽器(如:IE,Firefox,Safari,Chrome,Opera)看做客戶端,當然我們也可以用命令行(elinks,curl)當做一個客戶端。而服務器端就特別多,比如擅長處理靜態頁面的服務器httpd,lighttpd,nginx,gws等等,還有一些應用程序服務器IIS,Tomcat,jetty,resin等等。客戶端和服務器之間的交互都是使用http協議的request(請求報文)和response(響應報文來實現的)。其實http協議非常簡單,就是由着兩種格式的報文組成,即客戶端請求報文(request)和服務端響應報文(response)。
httpd俗稱Apache。其實早期它是美國的一個官方組織所研發的一款web服務器。早期也就叫做httpd,后來httpd這個項目完成了,功能基本上也就完善了,大家知道一個項目完成之后就會解散項目成員,后來這幫開發httpd的程序員就散入了各個大公司,但是他們都很喜歡這個httpd,也不願意看見它沒落下去,於是他們就通過互聯網自發組織起來來維護這個web服務器,一旦發現它有漏斗就打補丁,如果需要新功能就開發新特性,這就是早起的社區模型。隨着時間的推移,這些牛逼的開發者對httpd進行各種打補丁,使得其功能越來越強大。后來這些開發人員就說這個是一個打滿補丁的服務器(a pachey server),后來大家都知道了,美國的武裝攻擊直升機叫Apache,后來他們就叫做httpd正是稱之為apache服務器。
二.httpd的工作模式
httpd是一個高度模塊化組成的。即它的功能都是模塊化的。
1>.DSO(Dynamic Shared Object)
也就意味着你在安裝httpd的時候,可以自定義選擇你想要安裝用到它的功能,它有些功能不不需要的可以選擇不安裝
2>.MPM(Multipath Processing Module),
多道處理模塊,非一個模塊,而是對一種特性的稱謂。
prefork(多進程模型):一個進程響應一個請求,需要用到select(),其最大可以設置的空閑線程上線為1024,它提前創建出來這些空閑的線程就是為了響應客戶請求,因此等到客戶來時再去創建線程(tast_struch的創建是需要時間的)會花費時間;
worker(多線程模型):一個進程多個線程,一個線程一個請求。一個主進程可以生成多個子進程,每個子進程又可以生成多個線程(注意:每個在某一個時刻線程可以響應一個請求,只有這個線程將請求響應結束后該線程才可以繼續響應其他的請求喲~)提供服務。當一個子進程生成的線程都不工作了之后,主進程就會想法殺掉該子進程以達到釋放空間的目的;
event(事件模型):一個線程相應多個請求,(envent-driven,事件驅動,主要目的是為了實現單線程相應多個請求。)基於事件驅動維持多個用戶請求;
3>.http的功能特性:
a>.路徑別名:alias
b>.用戶認證:authentication
c>.虛擬主機:virtual host
d>.反向代理:(如負載均衡)
e>.用戶站點:當前用戶都可以自行打開創建一個自己的站點。
f>.CGI:Common Gateway Interface等等。
4>.安裝httpd
[root@yinzhengjie ~]# yum -y install httpd
三.了解httpd常用的工作目錄功能
1 [root@yinzhengjie ~]# cat /etc/redhat-release 2 CentOS release 6.6 (Final) 3 [root@yinzhengjie ~]# 4 [root@yinzhengjie ~]# rpm -q httpd 5 httpd-2.2.15-39.el6.centos.x86_64 6 [root@yinzhengjie ~]# 7 [root@yinzhengjie ~]# rpm -ql httpd | head 8 /etc/httpd ------>運行目錄; 9 /etc/httpd/conf ------>主配置目錄; 10 /etc/httpd/conf.d/*.conf ------->擴展配置目錄; 11 /etc/logrotate.d/httpd ------>日志滾動目錄; 12 /usr/sbin/httpd ------>可執行命令目錄; 13 /var/www/html/ ------>文檔根目錄,所有需要請求的文件都放在該目錄下; 14 /var/www/cgi-bin/ ------>CGI目錄; 15 /etc/httpd/logs ----->日志目錄,其實他是一個鏈接; 16 /etc/httpd/modules ------>存放各種不同模塊的目錄,其實它也是一個鏈接; 17 /etc/httpd/run ------>保存運行的pid; 18 /etc/sysconfig/httpd ------->腳本的配置文件; 19 /etc/init.d/httpd ------->服務啟動腳本; 20 .......... 21 [root@yinzhengjie ~]# 22 [root@yinzhengjie ~]# cd /etc/httpd/ 23 [root@yinzhengjie httpd]# ll 24 total 8 25 drwxr-xr-x. 2 root root 4096 Sep 18 07:34 conf 26 drwxr-xr-x. 2 root root 4096 Sep 18 07:34 conf.d 27 lrwxrwxrwx. 1 root root 19 Sep 18 07:34 logs -> ../../var/log/httpd 28 lrwxrwxrwx. 1 root root 29 Sep 18 07:34 modules -> ../../usr/lib64/httpd/modules 29 lrwxrwxrwx. 1 root root 19 Sep 18 07:34 run -> ../../var/run/httpd 30 [root@yinzhengjie httpd]#
四.httpd配置文件詳解
/etc/httpd/conf/httpd.conf 是Apache的主配置文件,
1>.配置文件格式:
全局配置
主機配置:用於僅提供一個站點時
虛擬機主機:用於提供多個站點時,主機配置和虛擬機主機配置不能同時啟用。
2>.配置文件語法測試:
[root@yinzhengjie ~]# service httpd configtest
[root@yinzhengjie ~]# httpd -t
絕大多數配置修改后,可以通過server httpd reload來生效,如果修改了監聽的地址和端口,比如重啟服務才能生效。
3>.監聽套接字
Listen [IP:]port ----->此指令可以出現多次,例如:Listen 80,表示監聽本機所有網卡的80端口,Listen 127.0.0.1:8080,表示只監聽本機的8080端口。
4>.配置使用keep alive
[root@yinzhengjie ~]# more /etc/httpd/conf/httpd.conf | grep -v ^# | grep KeepAlive
KeepAlive Off ------>默認是關閉狀態,它是保持連接的開關,它一旦開啟,下面的兩個參數任意一個都會生效。
MaxKeepAliveRequests 100 ------->定義最大請求次數。即單個連接請求到達100時會自動斷開連接。
KeepAliveTimeout 15 -------->定義連接的超時時間為15秒。
[root@yinzhengjie ~]#
5>.查看http當前可以支持編譯至內核的模塊列表
1 [root@yinzhengjie ~]# httpd -l 2 Compiled in modules: 3 core.c --------->核心模塊 4 prefork.c --------->支持的MPM,早httpd2.2版本編譯時,有且只能有指定一種MPM。 5 http_core.c --------->http的核心模塊 6 mod_so.c --------->支持DSO的機制 7 [root@yinzhengjie ~]#
6>.查看httpd.worker支持的模塊列表
1 [root@yinzhengjie ~]# httpd.worker -l 2 Compiled in modules: 3 core.c 4 worker.c --------->你會發現他們只是MPM的類型不同。如果想要啟動worker模式可以用該命令。 5 http_core.c 6 mod_so.c 7 [root@yinzhengjie ~]#
7>.修改多道處理模塊類型
1 [root@yinzhengjie ~]# more /etc/sysconfig/httpd | grep HTTPD=
2 #HTTPD=/usr/sbin/httpd.worker ------->服務默認是講worker模式是關閉的。而是用的httpd 3 [root@yinzhengjie ~]# 4 [root@yinzhengjie ~]# ps aux | grep httpd | grep -v grep
5 root 2404 0.0 0.3 183936 3828 ? Ss 18:44 0:00 /usr/sbin/httpd 6 apache 2407 0.0 0.3 184072 3168 ? S 18:44 0:00 /usr/sbin/httpd 7 apache 2408 0.0 0.3 184072 3080 ? S 18:44 0:00 /usr/sbin/httpd 8 apache 2409 0.0 0.3 184072 3080 ? S 18:44 0:00 /usr/sbin/httpd 9 apache 2410 0.0 0.3 184072 3096 ? S 18:44 0:00 /usr/sbin/httpd 10 apache 2411 0.0 0.3 184072 3084 ? S 18:44 0:00 /usr/sbin/httpd 11 apache 2412 0.0 0.3 184072 3156 ? S 18:44 0:00 /usr/sbin/httpd 12 apache 2413 0.0 0.3 184072 3156 ? S 18:44 0:00 /usr/sbin/httpd 13 apache 2414 0.0 0.2 183936 2468 ? S 18:44 0:00 /usr/sbin/httpd 14 [root@yinzhengjie ~]# 15 [root@yinzhengjie ~]# more /etc/sysconfig/httpd | grep HTTPD=
16 HTTPD=/usr/sbin/httpd.worker --------------->當然,我們可以手動吧worker功能給打開。 17 [root@yinzhengjie ~]# service httpd restart 18 Stopping httpd: [ OK ] 19 Starting httpd: httpd.worker: Could not reliably determine the server's fully qualified domain name, using 192.168.1.200 for ServerName ------------->這行不用管,原因是你的主機名和IP對應的不一致,該服務會自動進行反解的,只要服務可以正常啟動即可。
20 [ OK ] 21 [root@yinzhengjie ~]# 22 [root@yinzhengjie ~]# ps aux | grep httpd | grep -v grep
23 root 2848 0.0 0.4 184140 4036 ? Ss 19:44 0:00 /usr/sbin/httpd.worker 24 apache 2852 0.6 0.5 593936 5368 ? Sl 19:44 0:00 /usr/sbin/httpd.worker 25 apache 2853 0.0 0.5 528400 5368 ? Sl 19:44 0:00 /usr/sbin/httpd.worker 26 apache 2854 0.4 0.5 528400 5372 ? Sl 19:44 0:00 /usr/sbin/httpd.worker 27 [root@yinzhengjie ~]#
8>./etc/httpd/conf/httpd.conf配置文件的MPM的配置詳解
<IfModule prefork.c> ------>IfModule 方法是判斷模塊是否存在的,很顯然這個標簽是為了判斷prefork.c這個模塊是否存在;
StartServers 8 ------->默認去啟東的工作進程數;
MinSpareServers 5 ------->最少空閑進程數;
MaxSpareServers 20 ------->最大空閑進程數;
ServerLimit 256 ------->最大活動進程數;
MaxClients 256 ------->最大並發請求連接數;
MaxRequestsPerChild 4000 ------->每個子進程在生命周期內所能夠服務的最多請求個數;
</IfModule>
<IfModule worker.c>
StartServers 4 -------->啟動的子進程的個數;
MaxClients 300 -------->並發請求的最大數;
MinSpareThreads 25 -------->最小空閑線程數;
MaxSpareThreads 75 -------->最大空閑線程數;
ThreadsPerChild 25 -------->每個子進程可生成的線程數;
MaxRequestsPerChild 0 ------->每個子進程在生命周期內所能夠服務的最多請求個數,注意,“0”表示的是不限定請求個數;
</IfModule>
9>.DSO模塊加載方式
加載模塊的格式為:"LoadModule module_name /path/to/module",如果使用相對路徑,則對於ServerRoot所定義的位置而言,例如:“LoadModule ldap_module /usr/lib64/httpd/modules/mod_ldap.so ”,如果不需要加載模塊,只需要你在該行前添加“#”號進行注釋,並且讓服務重裝配置文件方能生效。
[root@yinzhengjie ~]# httpd -M:列出已經裝載的所有DSO及非DSO模塊;
[root@yinzhengjie ~]# httpd -l:列出支持使用的非DSO模塊;
10>.配置站點根目錄
[root@yinzhengjie ~]# more /etc/httpd/conf/httpd.conf | grep DocumentRoot | grep -v ^#
DocumentRoot "/var/www/html" ---------->這是默認的站點根目錄,當然,你可以自行修改,修改的目錄必須得存在喲~
[root@yinzhengjie ~]#
[root@yinzhengjie ~]# more /etc/httpd/conf/httpd.conf | grep DocumentRoot | grep -v ^#
DocumentRoot "/yinzhengjie/www/htdocs/" ------>這就是我們修改后的站點根目錄
[root@yinzhengjie ~]#
11>.配置頁面訪問屬性(也就是專門為根目錄設置的容器的屬性)
如果你想定義你的網頁文件能被誰訪問或者是不能被誰訪問就得設置給你的站點根目錄定義頁面訪問屬性。
<Directory "/yinzhengjie/www/htdocs/">
Options:
Indexes:
缺少指定的默認頁面時,運行將目錄中的所有的文件以列表的形式返回給用戶,(這個功能不建議開啟,除非你是想讓人下載你的文件。);
FollowSymLinks:
運行跟隨符號鏈接所指向的原始文件,就是說用戶可以通過瀏覽器訪問到你連接的文件的真實內容喲;
None:
所有屬性都不啟用;
All:
所有屬性都啟用;
ExecCGI:
允許跟隨符號鏈接所指向的原始文件;
Includes:
允許使用mod_include模塊實現服務器端包含(SSI);
MultiViews:
允許使用mod_negotiation實現內容協商;
SymLinksIfOwnerMatch:
在連接文件屬主屬組與原始文件的屬主屬組相同時,允許跟隨符號鏈接所指向的原始文件;.
AllowOverride
<Directory>
12>.基於主機的訪問控制
以下說明是針對Apache2.2版本的,官網文檔地址:http://httpd.apache.org/docs/2.2/mod/core.html#options
<Directory "/yinzhengjie/www/htdocs/">
Options:
請參考上面的基於頁面的訪問控制;
AllowOverride :
None:
該參數表示Order選項其后跟的參數Allow和Deny的配置不被禁用,我們默認下面的配置是基於該參數為None的模式來說的,因為如果你換成其他的模式會導致下面的配置無效的喲~;
ALL:
和上面的參數想法,一次都禁用。
FileInfo:
AuthConfig:
表示基於用戶的認證,而不再完全基於IP的認證了;
Limit:
Order :
該行和Allow以及Deny這三行是用來控制基於IP訪問的,Order主要是定義允許或是解決的次序(例如:Order Deny,Allow 表示默認規則是Allow,不過優先匹配Deny,如果不在Deny的匹配列表中就表示默認運行訪問喲),默認設置為:Order Allow,deny 表示拒絕所有的主機訪問,沒有在Allow的匹配列表中的都被拒絕,但是如果Allow如果寫成Allow from all表示允許所有主機訪問,配合Order的優先匹配規則則表示不拒絕任何的主機,因為所有的規則都會走Allow的優先匹配,換句話說,Order支持最小匹配范圍,它可以智能的支持最佳匹配;
Allow:
允許訪問的主機IP范圍,例如Allow from 172.16.0.0/16則表示只允許“172.16.0.0/16”這個網段的人訪問,其他地址則不允許訪問!,默認設置為Allow from all,表示允許給所有人訪問;
Deny:
拒絕訪問的主機IP范圍,加入Order指定的次序是:"Order allow,deny"表示默認拒絕優先匹配allow例如,如果allow指定的IP范圍是:“Allow from 172.16.0.0/16”則表示允許“172.16.0.0/16”這個網段訪問,這個時候我們如果將Deny寫成"Deny from 172.16.3.210\n Deny from 172.16.3.230"則表示拒絕 172.16.3.210這個主機和 172.16.3.230這個主機的配置,雖然Allow是允許一個網段訪問,但是有2個IP是被拒絕訪問的,因此它會拒絕這個網段的2個IP的訪問,這種機制叫做最佳匹配(從里表中找出最小的能匹配到訪問者的地址的條目為最終生效的,注意,這個和iptables是有所不同多~)。;
<Directory>
擴展小知識:
關於Allow和Deny之間的匹配關系如下:(網址:http://httpd.apache.org/docs/2.2/mod/mod_authz_host.html#order)
| Match | Allow,Deny result | Deny,Allow result |
| Match Allow only | Request allowed | Request allowed |
| Match Deny only | Request denied | Request denied |
| No match | Default to second directive: Denied | Default to second directive: Allowed |
| Match both Allow & Deny | Final match controls: Denied | Final match controls: Allowed |
根據上表我們隊Allow和Deny的匹配規則可以總結一句話:二者都匹配或二者都五匹配時,則以Order定義的后者為准,否則,則以匹配到的為准;
13>.定義默認主頁面
DirectoryIndex :
改參數用於定義首頁的文件名稱,它的意思當用戶訪問一個目錄時,如果他沒有敲擊URL的絕對路徑,比如用戶訪問“www.baidu.com”用戶並沒有輸出完整的URL,這個時候就該DirectoryIndex 表演了,它會默認返回客戶一個頁面,比如:"DirectoryIndex index.html yinzhengjie.html home.html",表示他會優先去找“index.html”這個配置文件,如果當前目錄沒有這個文件的話就會去找“yinzhengjie.html ”這個配置文件,如果這2個文件都沒有的話,就會去找“home.html”這個配置文件,如果在DirectoryIndex 列表中均為找到的話,默認會把當前目錄下的所有文件列出來供用戶選擇(當然如果設置可以被修改的喲!)。
14>.用戶目錄
如果期望讓每個用戶都可以創建個人站點,訪問格式為:"http://Serverr_IP/~Username/"注意訪問格式是在用戶名前面加一個“~”符號喲!
UserDir:
disabled:
改參數跟在userdlied后面表示禁止使用用戶目錄,
yinzhengjie_html:
yinzhengjie_html是用戶家目錄的目錄名稱,所有位於此目錄中的文件均可通過前述的訪問路徑進行訪問,但是要注意的是:用戶的家目錄得富有運行httpd進程的用戶擁有執行權限。
15>.配置日志功能
httpd的日志默認存放在:/var/log/httpd/目錄下,該目錄下默認有2個文件:
access.log:
訪問日志,其需要記錄的內容(比如客戶端地址等等)需要自定義;
LogFormat:
自定義log的格式,如:“LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" yinzhengjie”這個用關鍵字LogFormat定義了一個格式為“"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" ”並且給它起了一個變量名稱叫做:yinzhengjie。
注意:
%h:表示主機名;
%l:表示遠程登錄名,通常為“-”;
%u:表示認證時的遠程用戶名,沒有指定是為“-”;
%t:表示收到請求的具體時間;
\"%r\":表示請求報文的起始行;注意“\”符號表示轉移符,為了就是轉移雙引號;
%>s:表示響應狀態碼;
%b:表示響應報文的長度,單位為字節;
%{Header_name}:記錄請求報文首部的內容(Value)
CustomLog:
該目錄是訪問日志的指令,格式為:【CustomLog "/path/to/access_log_file" LogFormat_name 】,比如:【CustomLog logs/access_log yinzhengjie】,這里就三個參數,第一個參數是用CustomLog生命了一個變量, 第二個參數“logs/access_log”表示日志的路徑名稱,第三個參數值指定日志的格式,表示用一個叫“yinzhengjie”的變量定義的格式來記錄日志內容;
error.log:
錯誤日志,它的信息就沒有那么麻煩了,直接指定路徑即可,因為它就是記錄錯誤日志的,沒有必要弄的那么繁瑣,如:ErrorLog logs/error_log
16>.路徑別名
這個很好理解,其功能就類似於咱們玩Linux上的軟連接,只需要定義別名,就可以直接訪問到定義別名里的具體內容,格式為:Alias /yinzhengjie/ "/yinzhengjie/www/htdocs/",這就意味着用戶訪問:"http://Server_IP/yinzhengjie/"時,其頁面文件來自於“/yinzhengjie/www/htdocs/”這個目錄資源。
17>.設置默認字符集
AddDefaultCharset UTF-8表示設置成默認的字符集為:UTF-8,當然,如果你真正頁面的字符集不是UTF-8的,而是GBK的,那么在瀏覽器打開的內容可能是亂碼,因為你這里設置了其默認的字符集是UTF-8。
18>.CGI(全稱Common Gateway Interface,通用網關接口)腳本路徑別名
我們前面說的路徑別名指的是在根目錄下創建一個連接文件,從而訪問到這個連接文件的源文件內容,而我們這里說的腳本路徑別名功能和其差不多,只不過路徑別名里面存放的是各種資源,而腳本路徑別名里面存放着的是CGI腳本;
a>.什么是CGI呢
web服務器能夠跟某一個應用程序執行環境通信,並且能夠通過這個環境獲取執行結果的協議叫做CGI。我們知道httpd本事是無法解析腳本的,它更不可能將腳本執行的結果返回給你。當用戶請求一種特定資源,我們不把這個資源返回給客戶端,而是讓這個資源在服務器上先執行一下,將結果返回給客戶端。這個時候就該CGI協議上場了,httpd就可以基於CGI協議去調用運行程序的環境,把用戶請求的文件通過CGI協議調用的程序運行一下,再將該文件的執行結果返回給httpd服務器。
b>.遵循CGI協議
所有能夠支持CGI協議的客戶端程序本身都能夠用於開發動態網站,所以bash是其中的一種喲!如果你用bash寫的這個腳本本身遵循CGI協議它就能夠實現將結果返還給客戶端。一般而言,CGI協議要求支持CGI的應用程序第一行需要返回“Content-Type text/html”
c>.CGI的缺陷
CGI協議過於粗糙和簡陋,並且基於CGI協議通信時,它要求運行程序為了獲取某種資源必須以管理員的身份運行,這種操作是非常危險的,因為如果它執行的腳本是“rm -rf /”之類的話,別人再一次請求你的web服務器你就會發現你的web服務掛啦!CGI這種協議目前來講都很少有人用了,因為他的很多程序的實現要求機遇SUID或SGID的機制,這是相當危險的,所以現在有很多其他的動態網站跟前端通信時都不在基於CGI啦。比如像比較安全的PHP,它用的就是SAPI機制,像python用的是UWSGI機制等等。
d>.Apache指定CGI腳本路徑格式
生產環境中畢竟還有一些比較老的項目仍然還是基於CGI協議來進行的,尤其是像一些郵箱站點,web mail等基於CGI模式做起來可能比較容易。而開發CGI模式的語言早期年用的一般是perl語言,它不僅僅是一門腳本語言,它有豐富的庫。接下來,我們看看Apache是如何調用CGI協議吧。
對於Apache而言,並非你寫的任何路徑的CGI腳本都能夠被執行,通常是通過ScriptAlias指令所定義的腳本路徑別名下的腳本才會被執行,它是通過mod_alias(實現路徑別名)和mod_cgi(實現支持CGI協議的)這2個模塊完成工作的。它的格式為:ScriptAlias /URL/ "/path/to/somewhere" ,具體實例我們可以看下Apache配置文件:
1 [root@yinzhengjie ~]# more /etc/httpd/conf/httpd.conf | grep -v ^# | grep -v ^$ | grep ScriptAlias 2 ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
3 [root@yinzhengjie ~]# 4 [root@yinzhengjie ~]# more /var/www/cgi-bin/yinzhengjie 5 #!/bin/bash 6 #@author :yinzhengjie 7 #blog:http://www.cnblogs.com/yinzhengjie
8 #EMAIL:y1053419035@qq.com 9
10 cat <<EOF 11 Content-Type:text/html 12
13 <pre>
14 <h1>The hostname is `hostname`.</h1>
15 The time is `date +%F` 16 <h1>My name is yinzhengjie!</h1>
17 </pre>
18
19 EOF 20 [root@yinzhengjie ~]# 21 [root@yinzhengjie ~]# chmod +x /var/www/cgi-bin/yinzhengjie 22 [root@yinzhengjie ~]# 23 [root@yinzhengjie ~]# ll /var/www/cgi-bin/yinzhengjie 24 -rwxr-xr-x. 1 root root 247 Oct 21 02:51 /var/www/cgi-bin/yinzhengjie 25 [root@yinzhengjie ~]# 26 [root@yinzhengjie ~]# /etc/init.d/iptables stop 27 iptables: Setting chains to policy ACCEPT: filter [ OK ] 28 iptables: Flushing firewall rules: [ OK ] 29 iptables: Unloading modules: [ OK ] 30 [root@yinzhengjie ~]# 31 [root@yinzhengjie ~]# service httpd reload 32 Reloading httpd: 33 [root@yinzhengjie ~]# 34 [root@yinzhengjie ~]# ip a | grep brd |grep inet | awk '{print $2}' | awk -F "/" '{print $1}'
35 192.168.1.115
36 [root@yinzhengjie ~]#

19.基於用戶訪問控制
a>.HTTP的認證機制
HTTP認證分為四個步驟:
第一步(請求):客戶端用GET方法發送第一條請求,改請求是沒有認真信息的;
第二步(質詢):服務器接收到了客戶端的request報文,服務器用401狀態拒絕了客戶端的請求,說明需要用戶提供用戶名和密碼。服務器上可能會分為不同的區域,每個區域都有自己的密碼,所以服務器會在www-Authenticate首部對保護區進行描述。同樣,認證算法也是在www-Authenticate首部中指定的;
第三步(授權):客戶端重新發送請求,但這一次會附加一個GET Authorization首部,用來說明認證算法,用戶名和密碼;
第四步(成功):如果授權書是正確的,服務器會用200狀態告訴客戶端驗證成功,並將文檔返回。有些授權算法在可選的Authentication-Info首部返回一些與授權會話相關的附加信息;
b>.服務虛擬用戶
顧名思義,服務的虛擬用戶並不是指操作系統的用戶名和密碼。而僅僅是為了獲取某一個服務的特定資源訪問時所使用的認證標致而已,所以它的賬號和密碼只是在某種意義上所對應起來的字符串。那么這個虛擬用戶的賬號和密碼應該放在那里呢?解決方案有很多種,比如你可以放在web服務器本地,也可以放在SQL數據庫里,也可以放在dbm二進制數據庫里(已被Oracle公司收購),還可以放在ldap等等。
c>.認證類型(auth)
認證類型分為兩種,即基本認證(basic)和摘要認證(digest)。
基本認證:賬號和密碼是明文發送的;
摘要認證:將所有內容hash編碼之后發送,遺憾的是,很多瀏覽器都不支持摘要認證。
d>.認證提供者(authentication provider)
可以理解是賬號密碼的存放位置
e>.授權機制(authorization)
表示根據什么類型進行授權;
f>.基於文件做基本認證,根據用戶和組進行授權
編輯Apache的主配置文件:“/etc/httpd/conf/httpd.conf”
1 <Directory "/yinzhengjie/www/htdocs/caiwu">
2 Options None ------>表示所有屬性都不啟用 3 AllowOverride AuthConfig ------->表示基於用戶的認證,而不再完全基於IP的認證了 4 AuthType Basic ------>指定認真類型為基本認證 5 AuthName "Please enter your username and password" ------>該參數給用戶一個提示的標題 6 AuthBasicProvider file -------->指定認真模式為基於文件的,認證方式,其實該行可以不寫,默認就是基於文件認真的,而且下面一行以及充分說明認證時基於文件的 7 AuthUserfile /etc/httpd/conf/.ApachePassword -------->指定存放用戶的配置文件 8 #AuthGroupFile /etc/httpd/conf/.ApacheGroup ------->指定存放組名的配置文件 9 Require user yinzhengjie -------->表示只允許yingzhengjie這個用戶訪問,如果你想要“ /etc/httpd/conf/.ApachePassword”這個配置文件的所有用戶都有可以訪問,就可以改成“Require valid-user”。 10 #Require valid-user ----------->允許用戶配置文件的所有用戶都可以訪問 11 #Require group GroupName ------>允許訪問的組名 12 </Directory>
13 g>.創建用戶和密碼 14 [root@yinzhengjie ~]# htpasswd -c -m /etc/httpd/conf/.ApachePassword yinzhengjie #第一次要加“-c”選項,如果第二次創建用戶就不需要啦! 15 New password: 16 Re-type new password: 17 Adding password for user yinzhengjie 18 [root@yinzhengjie ~]# 19 [root@yinzhengjie ~]# htpasswd -m /etc/httpd/conf/.ApachePassword yzj #這是第二次創建用戶,如果加“-m”參數之后,就會將之前的配置給清空掉。 20 New password: 21 Re-type new password: 22 Adding password for user yzj 23 [root@yinzhengjie ~]# 24 [root@yinzhengjie ~]# more /etc/httpd/conf/.ApachePassword #查看我們創建的用戶名和密碼 25 yinzhengjie:$apr1$t/P8rFq4$PAbZS1icMTxnCvIG8lAS3/
26 yzj:$apr1$WKxSWG2B$HuYha4pS6z7.SHyv9zNxv0 27 [root@yinzhengjie ~]# 28 [root@yinzhengjie ~]# ll /yinzhengjie/www/htdocs/caiwu/index.html 29 -rw-r--r--. 1 root root 6792 Oct 21 04:50 /yinzhengjie/www/htdocs/caiwu/index.html 30 [root@yinzhengjie ~]# 31 htpasswd命令:(更多關於htpasswd命令的使用可以參考man幫助。) 32 -c:創建文件,創建第一個用戶時使用; 33 -m:“密碼基於MD5編碼存儲;


擴展小知識:
好了,到這里我們以及學習了基於IP的認證方式和基於用戶的認證方式,顯然后者的相比前面的認證機制要安全的多,因為IP是可以偽裝的,但是基於用戶認真不管你的IP是多少都得需要驗證用戶名和密碼。我們稱IP認證和用戶認證為http協議認證。
基於用戶認證當你訪問某一個特定資源的時候回出現一個彈窗效果讓你輸入用戶名和密碼,當你輸入正確的用戶信息就可以訪問這些特定的資源。但是你可能會為,為什么別人家的認證都不需要彈窗效果,直接在網頁輸入用戶信息就可以啦?比如,登錄網頁版的QQ,郵箱之類的。嘿嘿,問得好,我們直接在網頁上輸入驗證消息的方式我們稱之為表單認證。表單認證直觀程度要比協議認證更好用(更易於控制),所以,大多數認證方式都基於表單認證機制。除非不具備表單認證能力,而又不得不使用認證方式的才會使用協議認證。比如我們用Nagios監控整個網絡,它的控制台是直接可以打開的,這個時候我們就可以基於協議認證。
20.虛擬主機
所謂虛擬主機就是一個物理服務器提供多個站點。如果你的web服務器訪問量不大且你需要提供多個站點,比如,你想訪問:www.yinzhengjie.com,又想訪問www.yinzhengjie.org.cn,還想訪問www.yinzhengjie.gov.cn等等。你是需要找三台服務器去搭建web嗎?答案是否定的,因為這3個web訪問量都不大占用服務器資源不會很多,因此,我們可以把這三個網站部署在同一個服務器上,想要是實現這種功能就得用到Apache的虛擬主機的功能啦!
a>.實現虛擬主機的三種方式
我們知道web服務都是基於socket套接字來向外提供服務的,因此我們有三種方式提供web服務。要注意的是,使用虛擬機主機得先取消中心主機。
第一種,基於不同的IP實現不同的虛擬主機(變化IP);
第二種,基於不同的PORT實現不同的虛擬機主機(變化端口);
第三種,基於不同的FQDN實現不同的虛擬主機(變化ServerName值);
b>.定義虛擬機格式
<VirtualHost IP:PORT> ------>定義虛擬主機;
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot ------->指定網頁存放目錄;
<Directory /> -------->當然也可以給這個目錄定義相應的屬性;
Options FollowSymLinks
AllowOverride None
</Directory>
ServerName ------->設置主機名;
ServerAlias ------->設置服務器的別名,可以定義多個名字;
ErrorLog -------->定義錯誤存放位置和日志的格式
CustomLog -------->定義訪問存放位置和日志的格式
</VirtualHost>
c>.基於不同IP實現虛擬機主機案例
1 [root@yinzhengjie ~]# ifconfig eth0:0 192.168.1.116/24 #在web服務器中添加多個IP以便測試 2 [root@yinzhengjie ~]# ifconfig | grep addr|grep Bcast | awk '{print $2}'|awk -F ":" '{print $2}'
3 192.168.1.115
4 192.168.1.116
5 [root@yinzhengjie ~]# 6 [root@yinzhengjie ~]# more /etc/httpd/conf/httpd.conf | grep DocumentRoot | grep ^#DocumentRoot 7 #DocumentRoot "/yinzhengjie/www/htdocs/" ----->需要先關閉中心主機才能配置虛擬主機 8 [root@yinzhengjie ~]# 9 [root@yinzhengjie ~]# tail -11 /etc/httpd/conf/httpd.conf ------>配置虛擬主機格式如下 10 #ADD by yinzhengjie 11 <VirtualHost 192.168.1.115:80>
12 ServerName www.yinzhengjie.com 13 DocumentRoot "/yinzhengjie/www/yinzhengjie.com/htdocs"
14 </VirtualHost>
15
16 <VirtualHost 192.168.1.116:80> ------->你會發現虛擬主機的IP不一致; 17 ServerName yinzhengjie.org.cn 18 DocumentRoot "/yinzhengjie/www/yinzhengjie.org.cn/htdocs"
19 </VirtualHost>
20
21 [root@yinzhengjie ~]# 22 [root@yinzhengjie ~]# mkdir -p /yinzhengjie/www/yinzhengjie.com/htdocs 23 [root@yinzhengjie ~]# mkdir -p /yinzhengjie/www/yinzhengjie.org.cn/htdocs 24 [root@yinzhengjie ~]# more /yinzhengjie/www/yinzhengjie.org.cn/htdocs/index.html ---->設置主機的IP 25 <h1>www.yinzhengjie.org.cn</h1>
26 [root@yinzhengjie ~]# 27 [root@yinzhengjie ~]# 28 [root@yinzhengjie ~]# more /yinzhengjie/www/yinzhengjie.com/htdocs/index.html 29 <h1>www.yinzhengjie.com</h1>
30 [root@yinzhengjie ~]# 31 [root@yinzhengjie ~]# httpd -t ------>測試配置文件的語法格式是否正確 32 httpd: apr_sockaddr_info_get() failed for yinzhengjie 33 httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
34 Syntax OK ------>諾,這是沒問題的,說是語法OK。 35 [root@yinzhengjie ~]# 36 [root@yinzhengjie ~]# service httpd reload ------->重新加載服務即可。 37 Reloading httpd: 38 [root@yinzhengjie ~]#


d>.基於不同IP和端口的虛擬主機案例展示:
1 [root@yinzhengjie ~]# tail -17 /etc/httpd/conf/httpd.conf 2 #ADD by yinzhengjie 3 <VirtualHost 192.168.1.115:80>
4 ServerName www.yinzhengjie.com 5 DocumentRoot "/yinzhengjie/www/yinzhengjie.com/htdocs"
6 </VirtualHost>
7
8 <VirtualHost 192.168.1.115:8888> ----->我們發現其和上面的虛擬主機不同之處在於端口,一次一定要監聽8080端口喲。 9 ServerName www.yinzhengjie.gov.cn 10 DocumentRoot "/yinzhengjie/www/yinzhengjie.gov.cn/htdocs"
11 </VirtualHost>
12
13
14 <VirtualHost 192.168.1.116:80>
15 ServerName www.yinzhengjie.org.cn 16 DocumentRoot "/yinzhengjie/www/yinzhengjie.org.cn/htdocs"
17 </VirtualHost>
18
19 [root@yinzhengjie ~]# 20 [root@yinzhengjie ~]# more /yinzhengjie/www/yinzhengjie.gov.cn/htdocs/index.html 21 <h1>www.yinzhengjie.gov.cn</h1>
22 [root@yinzhengjie ~]# 23 [root@yinzhengjie ~]# grep Listen /etc/httpd/conf/httpd.conf | grep -v ^# 24 Listen 80
25 Listen 8888 ------>注意,一定要啟用該端口,不然即使上面的虛擬主機配置正確也無法訪問喲 26 [root@yinzhengjie ~]# 27 [root@yinzhengjie ~]# service httpd configtest ------->驗證語法格式是否正確 28 httpd: apr_sockaddr_info_get() failed for yinzhengjie 29 httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
30 Syntax OK ------->很顯然,語法都是OK的。 31 [root@yinzhengjie ~]# 32 [root@yinzhengjie ~]# /etc/init.d/httpd restart ------>重啟服務即可 33 Stopping httpd: [ OK ] 34 Starting httpd: [ OK ] 35 [root@yinzhengjie ~]#



e>.基於主機名(FQDN)的虛擬機主機案例展示
1 [root@yinzhengjie ~]# grep NameVirtualHost /etc/httpd/conf/httpd.conf | grep -v ^# 2 NameVirtualHost *:80 ------>在httpd2.2版本,想要實現FQDN方法,該功能需要開啟。httpd2.4則不需要開啟該功能啦! 3 [root@yinzhengjie ~]# 4 [root@yinzhengjie ~]# tail -17 /etc/httpd/conf/httpd.conf 5 #ADD by yinzhengjie 6 <VirtualHost *:80>
7 ServerName www.yinzhengjie.com 8 DocumentRoot "/yinzhengjie/www/yinzhengjie.com/htdocs"
9 </VirtualHost>
10
11 <VirtualHost *:80>
12 ServerName www.yinzhengjie.gov.cn 13 DocumentRoot "/yinzhengjie/www/yinzhengjie.gov.cn/htdocs"
14 </VirtualHost>
15
16
17 <VirtualHost *:80>
18 ServerName www.yinzhengjie.org.cn 19 DocumentRoot "/yinzhengjie/www/yinzhengjie.org.cn/htdocs"
20 </VirtualHost>
21
22 [root@yinzhengjie ~]# 23 [root@yinzhengjie ~]# more /etc/hosts | grep yinzhengjie ----->我打算在本地進行測試,因此需要修改配置文件 24 192.168.1.105 node1.yinzhengjie.com 25 192.168.1.110 node2.yinzhengjie.com 26 192.168.1.115 node3.yinzhengjie.com 27 192.168.1.200 node4.yinzhengjie.com 28 192.168.1.115 www.yinzhengjie.com 29 192.168.1.115 www.yinzhengjie.gov.cn 30 192.168.1.115 www.yinzhengjie.org.cn 31 [root@yinzhengjie ~]# 32 [root@yinzhengjie ~]# yum -y install elinks ----->安裝命令行工具 33 [root@yinzhengjie ~]# elinks -dump www.yinzhengjie.com -----以下是Linux測試結果 34 www.yinzhengjie.com 35 [root@yinzhengjie ~]# 36 [root@yinzhengjie ~]# 37 [root@yinzhengjie ~]# elinks -dump www.yinzhengjie.gov.cn 38 www.yinzhengjie.com 39 [root@yinzhengjie ~]# 40 [root@yinzhengjie ~]# elinks -dump www.yinzhengjie.org.cn 41 www.yinzhengjie.com 42 [root@yinzhengjie ~]#
當然如果你非要用windows進行測試的話也簡單,和Linux訪問方式一樣,也需要修改hosts文件,我們可以到C:\Windows\System32\drivers\etc這個目錄下去修改。



f>.虛擬主機的單獨配置
在虛擬主機中,可以實現用戶認證,訪問日志,錯誤日志,路徑別名。腳本別名等等。它的配置方法和配置中心主機一致。接下來我們設置一個訪問日志的功能,具體配置如下:
1 [root@yinzhengjie ~]# tail -20 /etc/httpd/conf/httpd.conf 2 #ADD by yinzhengjie 3 <VirtualHost *:80> 4 ServerName www.yinzhengjie.com 5 DocumentRoot "/yinzhengjie/www/yinzhengjie.com/htdocs" 6 CustomLog "/var/log/httpd/www.yinzhengjie.com.log" combined 7 </VirtualHost> 8 9 <VirtualHost *:80> 10 ServerName www.yinzhengjie.gov.cn 11 DocumentRoot "/yinzhengjie/www/yinzhengjie.gov.cn/htdocs" 12 CustomLog "/var/log/httpd/www.yinzhengjie.gov.cn.log" combined 13 </VirtualHost> 14 15 16 <VirtualHost *:80> 17 ServerName www.yinzhengjie.org.cn 18 DocumentRoot "/yinzhengjie/www/yinzhengjie.org.cn/htdocs" 19 CustomLog "/var/log/httpd/www.yinzhengjie.org.cn.log" combined 20 </VirtualHost> 21 22 [root@yinzhengjie ~]# 23 [root@yinzhengjie ~]# httpd -t 24 Syntax OK 25 [root@yinzhengjie ~]# /etc/init.d/httpd restart 26 Stopping httpd: [ OK ] 27 Starting httpd: [ OK ] 28 [root@yinzhengjie ~]# 29 [root@yinzhengjie ~]# cd /var/log/httpd/ ----->客戶端訪問之后,再去日志目錄下查看。 30 [root@yinzhengjie httpd]# ll 31 total 52 32 -rw-r--r--. 1 root root 13007 Oct 21 06:33 access_log 33 -rw-r--r--. 1 root root 19566 Oct 21 06:44 error_log 34 -rw-r--r--. 1 root root 194 Oct 21 06:44 www.yinzhengjie.com.log 35 -rw-r--r--. 1 root root 194 Oct 21 06:44 www.yinzhengjie.gov.cn.log 36 -rw-r--r--. 1 root root 194 Oct 21 06:44 www.yinzhengjie.org.cn.log 37 [root@yinzhengjie httpd]# 38 [root@yinzhengjie httpd]# cat www.yinzhengjie.com.log 39 192.168.1.161 - - [21/Oct/2017:06:44:35 -0700] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" 40 [root@yinzhengjie httpd]# 41 [root@yinzhengjie httpd]# cat www.yinzhengjie.gov.cn.log 42 192.168.1.161 - - [21/Oct/2017:06:44:32 -0700] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" 43 [root@yinzhengjie httpd]# 44 [root@yinzhengjie httpd]# cat www.yinzhengjie.org.cn.log 45 192.168.1.161 - - [21/Oct/2017:06:44:31 -0700] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" 46 [root@yinzhengjie httpd]# 47 [root@yinzhengjie httpd]#
