Web服務器之apache
Web系統是典型的C/S架構,客戶端與服務器之間遵循HTTP協議(超文本傳輸協議),HTTP是應用層協議。常見的Web服務器有httpd、nginx、lighttpd、IIS等,常用的客戶端瀏覽器有IE、Chrome、Firefox、elinks、curl、wegt等,它們都是HTTP協議的實現。用戶使用瀏覽器訪問URL(統一資源定位符)查看Web頁面,Web頁面是用HTML(超文本標記語言)編寫的,可以實現頁面跳轉,以及嵌入聲音、圖像、視頻等多媒體信息。
客戶端與服務器采用請求和響應通信模型,任何兩次的請求和響應之間是Staless的,如果要建立KeepAlive則需要Cookice的支持,客戶端再次訪問時將帶上一個標識,直到斷開連接之前的訪問無需重復確認身份。
請求報文:
-
Request Headers:name:value
如:HOST: 10.1.253.29
Connection: keep-alive
Referer: https://www.baidu.com/
User-Agents: Mozilla/5.0 -
即:First Line:< method >< url >< version >
-
method:GET、HEAD、POST、DELETE、OPTIONS、TRACE ……
-
url:scheme://[user[:passwd]@host[:port]/path;params?query#frag,通常映射到DocumentRoot下的資源或Alias指定的路徑
-
version:HTTP/1.1
響應報文:
-
Response Headers:name:value
如:Request Method: GET
Status Code: 200 OK #此部分內容單獨放在General中
Server: bfe/1.0 -
即:First Line:< version >< status >< reason phrase >
-
status:1##、2##(成功響應)、3##(成功重定向)、4##(客戶端錯誤)、5##(服務端錯誤)
Http報文首部分類大致有以下五種:
通用首部、請求首部、響應首部、實體首部、擴展首部
-
通用首部:
Connection: {close|keep-alive}
Date:報文創建的日期時間
Via:經由,代理服務器追加
Cache-Control:緩存控制;
Pragma: -
請求首部:
Host:
Referer:跳轉至當前頁面的上級資源;
User-Agent:用戶代理;
Client-IP:Accept:可接收的MIME類型;
Accept-Language:
Accept-Encoding:gzip, defalte,
Accept-Charset:
...
條件式請求首部:
Except:
If-Modified-Since
If-Unmodified-Since
If-None-Match
If-Match
安全相關的請求首部:
Authorization:請求授權
Cookie:
Cookie2: -
響應首部:
信息性首部:
Server:協商類首部:
Accept-Range:服務器端可接受的請求類型范圍
Vary:其它首部列表
安全相關的首部:
WWW-Authenticate:認證質詢
Set-Cookie:
Set-Cookie2: -
實體首部:
Content-Encoding
Content-Language
Content-Lenth
Content-Location
Content-Type
…Allow:允許使用的請求方法;
Location:
緩存相關:
Etag:擴展標簽
Last-Modified:
Expires: -
擴展首部:
X-Forwarded-For
……
一次Web請求的處理過程有如下七個步驟:
-
建立連接
-
接收請求
-
處理請求
-
加載資源
-
構建響應
-
發送響應
-
記錄日志
telnet的使用
telnet 10.1.253.29
GET /test.html HTTP/1.1
Host: 10.1.253.x
換行
等待下次請求,超時自動斷開
curl命令
curl [options][URL……]
curl -I #只顯示響應首部
curl --compressed #壓縮請求
-X,--request <command> #自定義請求方法
-H/--header <line> #自定義首部信息傳遞給服務器
-0/--http1.0 #使用HTTP 1.0
-u,--user [user[:password]]
--basic 使用HTTP基本認證
--cacert <file> CA證書 (SSL)) #https
-A/--user-agent <string> 設置用戶代理發送給服務器
httpd的相關配置
-
httpd的版本
-
httpd-1.x
-
httpd-2.2
-
httpd-2.4:
-
httpd的特性:
-
管理員才能啟動httpd,因為默認偵聽80端口
-
把眾多功能組合成一個程序,多個子命令進行片段化管理,采用高度模塊化的設計(core modules、standard modules、other modules)
-
DSO:Dynamic shared Object
-
MPM:multipath process modules:
prefork:兩級結構,主進程接收請求,每子進程處理一個請求,
worker:三級結構,每線程處理一個請求,但Linux中的線程與進程相似
event:事件驅動使得進程處理多個請求,其內部是線程模型,較輕量 -
支持CGI:動態網站
-
虛擬主機:IP、PORT、ServerName
-
反向代理:http、fcgi、wsgi、
-
負載均衡:繁忙調度
安裝httpd2.4,查詢安裝的內容
yum -y install httpd
rpm -ql httpd
主程序文件:/usr/sbin/httpd
模塊文件:/usr/lib64/httpd/modules/*.so
當前已經裝載的模塊:httpd -M
主配置文件:
/etc/httpd/conf/httpd.conf #主配置文件一般不修改
/etc/httpd/conf.d/*.conf #被Include到httpd.conf中,一般
#新建一個配置段,而不修改主配置文件
/etc/httpd/conf.modules.d/*.conf #2.4才有的module配置文件
配置文件語法
DIRECTIVE VALUE #除了路徑,不區分字符大小寫
站點文檔路徑
/var/www/html/
日志文件
/var/log/httpd/
access_log
error_log
Unit File
/usr/lib/systemd/system/httpd.service
自帶管理腳本
/usr/sbin/apachtctl
啟動服務,查看偵聽的端口
systemctl start httpd.service
systemctl enable httpd service
ss -tnlp | grep ":80\>"
修改配置文件后檢查語法,再重載配置文件
httpd -t
apachectl
systemctl reload httpd.service
無需重啟的情況:與端口無關的修改、增加了偵聽的端口
需要重啟的情況:修改了已有的偵聽端口號、修改偵聽一個ip的端口為所有ip的端口
welcome.conf — 403 forbidden
Apache默認的錯誤頁面,這是一個403狀態的錯誤,可自行添加,代替默認的頁面
mv /etc/httpd/conf.d/welcome.conf{,.bak}
修改監聽的端口和地址
Listen 80 #默認為本機所有可用ip的80端口,可指定ip
#Browser默認訪問80端口,shift F5 強制刷新
# Listen [ip:]PORT
#Linsten可多次使用
ss -tnlp
保持連接
客戶端資源獲取完成后不會斷開,繼續等待請求其他資源,適合服務器較空閑的狀態,否則會造成其他的連接無法被處理,需要針對具體業務以請求數量或連接時間而定保持連接的配置。httpd中默認是開啟的,時間大約為30s
vi /etc/httpd/conf.d/keepalive.conf
KeepAlive On|Off
MaxKeepAliveRequests 20
KeepAliveTimout 5
-
測試保持連接
瀏覽器中的請求狀態為:connection close 或 keep-alive
telnet 10.1.0.68
GET /index.html /HTTP1.1
Host: 10.1.0.68 回車
換行
DSO
動態裝卸模塊
#查看已裝載的模塊
httpd -t -D DUMP_MODULES : show all loaded module
httpd -M : a synonym for -t -D DUMP_MODULE
#已LoadModule及未啟用的module,注釋時注意相關依賴性
vi /etc/httpd/conf.modules.d/00-xxxx.conf #suexec
#啟用模塊的語法,名字自取,路徑為/usr/lib64/httpd/module
LoadModule mod_name modules/mod_file_name
相對路徑 ServerRoot:/etc/httpd/
modules/ --> /etc/httpd/modules/
定義物理主機站點文檔
-
默認識別index.html,可定義多個文件
vi /etc/httdp/conf/httpd.conf
DirectoryIndex index.html fielname2 ……
-
默認的站點文檔路徑
#做到標準化,如/date/htdoc/
DocumentRoot "/var/www/html"
<Directory "/var/www/html"> #授權/var/www/html這個路徑
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
-
httpd的主機名
#默認是注釋的,此時讀取主機名及127.0.0.1的反向解析,如果不一致則報錯
ServerName www.jasonmc.com #反解的主機名應與hostname一致
資源訪問授權
(1) httpd-2.4 規定所有需被訪問的資源文件要授權才能訪問,可對URL或資源路徑授權,如使用URL授權給status模塊,通過Directory授權給/forum目錄
#站點文檔訪問授權及眾多服務特性的配置
<Directory "/PATH/TO/DIR"> #資源路徑的授權
Optinos None #Indexes、FollowSymLinks、All、None、ExecCGI,針對資源路徑有效
AllowOverride None #是否允許站點目錄.htaccess覆蓋conf中的配置,針對資源路徑有效
#授權所有主機訪問
Require all granted #基于來源地址的訪問控制,all granted、all denied
#或禁止單個ip,如果是HOST則依賴于DNS的解析,一般不采用
#允許一個網段:Require ip 10.1
<RequireALL>
Require not ip 10.1.0.200 #denied by server config
Require all granted
</RequireALL>
</DIrectory>
------------------------------
<File "/PATH/TO/FILE"> #單個文件的授權
……
</FILE>
------------------------------
<Location "URL"> #URL的授權
setHandel xxxx
Require all granted
</Location>
------------------------------
<LocationMatch ~ "URL_PATTERN"> #URL的授權,模式匹配
……
</LocationMatch>
(2)Apache的運行者身份User/Group
進程的安全上下文規定了進程的權限,只有執行者有權限訪問資源文件時才能加載對應的資源,因此站點資源必須給予apache用戶可讀的權限
路徑別名Alias
允許使用 ip/URL 代替完整路徑
Alias /URL/ /PATH/TO/SOME_DIR/
#授權
<Directory "/PATH/TO/SOME_DIR/">
Options None
AllowOverride None
Require all granted
</Directory>
本地httpd-manual
同官網http://httpd.apache.org/docs/2.4/
本地瀏覽http://host/manual/
yum -y install httpd-manual
conf.d/manual.conf #使用了alias到/usr/share/httpd/manual
cat /etc/httpd/conf.d/manual.conf
# http://localhost/manual/
#AliasMatch匹配模式為manual開頭的文件
AliasMatch ^/manual(?:/(?:de|en|fr|ja|ko|ru))?(/.*)?$ "/usr/share/httpd/manual$1"
<Directory "/usr/share/httpd/manual">
Options Indexes
AllowOverride None
Require all granted
</Directory>
開啟status
顯示httpd狀態信息,訪問status自動生成的數據
httpd -M | grep status_module
vi /etc/httpd/conf.d/status.conf
<Location /status>
SetHandler server-status #啟用內建的功能模塊,幫助生成相關信息
<RequireALL>
Require ip 10.1.0.19 #only allow ip
Require all granted
</RequireALL>
</Location>
日志設定
系統針對錯誤日志設置了不同的級別,warn級別之上的日志將被記錄
vi /etc/httpd/conf/httpd.conf
ErrorLog "/logs/error_log"
logLevel warn #include:debug,info,notice,warn,error,crit,alert,emerg.
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog "logs/access_log" combined #格式符為combined
CustomLog
format_strings:
-
%h:訪問主機名,需被反解析,默認只是ip
-
%l:identd識別的用戶名,無有效值為 –
-
%u:http協議認證時客戶端輸入的用戶名
-
%t:收到客戶端請求的時間
-
%r:First line requests,起始行
-
%>s:記錄站內重定向后的status,%s記錄的是第一次的響應狀態碼
-
%b:size of response in bytes
-
%{VARNAME}i:記錄有VARNAME所表示的請求報文的首部的值,例如{Referer}i,表示跳轉的之前的來源URL,在/var/log/httpd/access_log的倒數第二列;
偽裝來源:curl -e “www.xxx.com” 10.1.0.68 #偽裝Referer來源
虛擬主機
一般而言,物理主機與虛擬主機不同時使用,在httpd-2.4中自動失效物理主機;在httpd-2.2中使用基于ServerName的虛擬主機時,要使用專用配置指令NameVirtualHost IP:POR,且要注釋物理主機的DocumentRoot。
每個虛擬主機最好單獨放在一個文件中,方便使用腳本進行管理
主機標識方式:(混合使用,但ip:port限制了ServerName)
IP方式
PORT方式
ServerName方式:Browser在request報文HEADERS中的Host值傳遞了訪問域名,可作為虛擬主機區分訪問的方式
vi /etc/httpd/conf.d/vhost.conf
<VirtualHost IP:PORT> #容器
ServerName www.jasonmc.com
DocumentRoot "/testdir/www1"
<Directory "/testdir/www1">
Optinos None
AllowOverride Node
Require all granted
</Directory>
ErrorLog "logs/www1-error_log"
CustomLog "logs/www1-access_log" combined
</VirtualHost>
-
測試虛擬主機
#創建虛擬主機站點文檔
for i in {1..3}; do mkdir -p /testdir/vhost\$i ; echo "vhost$i" > /testdir/vhost$i/index.html done
systemctl reload httpd.service
基于用戶的訪問控制
在實際運用中基于ip的訪問控制不常用,更為常用的是基于用戶的訪問控制。當用戶訪問某站點資源時要求輸入暗號,認證通過才能訪問。httpd根據已有的賬戶口令對比客戶端發送的暗號,認證方式大致有兩種:basic 或digest,而認證的對象可以是多個用戶或用戶組。Require user USER_LIST、Requier group GRPLIST
-
http協議的認證過程:
-
認證質詢,在響應首部中
www-Authencate:
響應碼為401,拒絕客戶端請求,并說明用戶需要輸入正確的賬號和密碼之后方可訪問; -
認證請求,在請求首部中
Authorization:
客戶端填入賬號和密碼,再次發送請求報文;認證通過,服務器發送響應內容;
#在虛擬主機中的<Directory "">中添加Author內容
<Directory "/path/html">
Option None
AllowOverride None
Authtype Basic
AuthName "STRING"
AuthUserFile "/path/password"
Require user USER1 ……
</Directory>
# htpasswd:basic認證基于文件實現,用于生成賬號和密碼的程序
htpasswd -h #獲取幫助
htpasswd -c -m alice #文件、虛擬用戶創建
htpasswd -m tom #只創建虛擬用戶
httpd壓力測試
#webbench,httpload, ...
#loadrunner,jmeter
#tcpcopy
ab:- Apache HTTP server benchmarking tool
ab[OPTIONS] [http[s]://]hostname[:port]/path
[ -n requests ]請求數,應大于并發數
[ -c concurrency ]并發數
[ -k ]
ab -n 5000 -c 200 http://www.jasonmc.com/pmn
Completed 500 requests #每組并發的請求數,10%
Document Length: 231 bytes #資源大小
Non-2xx responses: 5000 #響應次數
Total transferred: 2420000 bytes #包括響應首部的總大小
HTML transferred: 1155000 bytes #資源總大小
Requests per second: 3443.57 [#/sec] (mean) #并發響應數
Time per request: 58.079 [ms] (mean) #單次每組并發總時間
Time per request: 0.290 [ms] (mean, across all concurrent requests)
Transfer rate: 1627.63 [Kbytes/sec] received #傳輸率 * 8為帶寬
平均 中值
min mean[+/-sd] median max
Connect: 0 3 44.7 0 1000 #建立連接
Processing: 8 52 145.1 36 1419 #處理請求
Waiting: 1 52 145.1 36 1419 #響應接收
Total: 24 55 152.5 36 1427
Percentage of the requests served within a certain time (ms)
50% 36 #并發平均值,沒有拖后腿
……
100% 1427 (longest request) #最長的一次并發時間拖后腿情況
使用 mod_deflate 壓縮數據
使用mod_deflate模塊壓縮頁面優化傳輸速度,一般用于壓縮適于壓縮的資源,例如文本文件;雖能節約帶寬,但是額外消耗CPU,同時,可能有些較老瀏覽器不支持。
MIME媒體類型(簡稱為MIME類型)是描述報文實體主體內容的一些標準化名稱
(比如,text/html、image/jpeg),通過MIME機制把所有資源以text方式在http上傳輸,接收后再通過MIME機制還原數據。
vi /etc/httpd/conf.d/deflate.conf #也可放在主配置文件中
SetOutputFilter DEFLAT #輸出過濾器設置
# mod_deflate configuration
# Restrict compression to these MIME types #要壓縮的MIME類型
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
# Level of compression (Highest 9 - Lowest 1)
DeflateCompressionLevel 9 #壓縮比,權衡CPU與帶寬的利用率
# Netscape 4.x has some problems. #不同瀏覽器的壓縮方式
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
-
測試資源壓縮效果
curl -I http://ip/file
Vary:Accept-Enconding #響應報文告訴客戶端支持壓縮
curl --compressed -I http://ip/file
Vary:gzip #使用gzip壓縮,明顯減小Content-Length
虛擬主機啟用https
OpenSSL有三個基本的組件libcrpyto加密算法、libssl(ssl/tls)接口庫、openssl開源實現,在Linux之上,應用程序調用libssl庫建立ssl會話,并使用libcrpyto加密算法對數據進行加密傳輸。
SSL會話認證的公鑰基礎設施PKI包括認證中心CA、證書吊銷列表CRL等
ssl會話基于TCP連接,需三次握手建立連接,再建立ssl會話;
ssl加密會降低效率:所有URL都需要建立ssl會話傳輸,對于服務器的處理能力影響較大,因此可使用ssl會話緩存提高性能;
Https:與http的區別在于https使用了網景的SSL,SSL為HTTP連接提供了端到端的加密機制。其語法與HTTP的語法相同,默認端口為443?;靖袷剑?nbsp;
https://:< port>/< path>?< query>#< frag>
Apache中的SSL基于IP地址創建,基于ServerName驗證,在httpd上單ip主機只能有一個虛擬主機啟用https功能。當然在Nginx上支持TLS協議的SNI擴展,使得在同一IP上對多個虛擬主機啟用https功能。
-
SSL會話過程:
-
客戶端發送可供選擇的加密方式,并向服務器請求證書
-
服務器發送證書以及選定的加密方式給客戶端
-
客戶端取得證書并驗證,首先得信任證書頒發機構CA
(1)證書來源的合法性;用CA的公玥解密證書上的數字簽名
(2)驗證證書的內容合法性;完整性驗證
(3)檢查證書的有效期
(4)檢查證書是否被吊銷
(5)證書中擁有者的名字,與訪問的目標主機要一致 -
客戶端生成臨時會話密鑰(對稱密鑰),并使用服務器端的公玥加密此數據發送給服務器,完成密鑰交換
-
服務器使用此密鑰加密用戶請求的資源,響應給客戶端
-
建立私有認證中心CA
#在建立CA服務器
cd /etc/pki/CA
(umask 077;openssl genrsa -out private/cakey.pem 4096)
ll private/ #權限600的私鑰
#由私鑰申請CA自簽的證書文件
openssl req -new -x509 -key private/cakey.pem -out cacert.pem
echo 01 > serial #CA釋放出的證書編號
touch index.txt #數據庫文件
-
向CA申請Web服務器使用的證書
在CA這臺主機上申請即可,但是一定要在Common Name 中填寫Web主機的主機名,如www.jasonmc.com.如果通過互聯網上的CA機構申請證書,流程是先在本機安裝openssl程序,生成一個rsa的私鑰文件,再有私鑰文件產生自己的Web主機名的證書簽署請求文件。再把證書簽署請求文件給CA機構即可。
#生成Web服務器端的私鑰文件
cd /etc/httpd/
mkdir certs
(umask 077;openssl genrsa -out certs/httpd.key 2048)
#由私鑰文件生成對應主機名的證書簽署請求文件
openssl req -new -key certs/httpd.key -out certs/httpd.csr
……
#CA主機使用Web主機的CSR文件生產crt證書
openssl ca -in certs/httpd.csr -out certs/pma_jasonmc_com.crt
-
httpd 啟用ssl模塊
yum -y install mod_ssl
rpm -ql mod_ssl
vim /etc/http/conf.d/ssl.conf
Listen 443 https #偵聽443端口
<VirtualHost _default_:443> #默認主機
DocumentRoot "/data/htdoc/phpAdmin"
ServerName pma.jasonmc.com
<Directory "/data/htdoc/phpAdmin">
Options None
AllowOverride None
Require all granted
</Directory>
SSLEngine on
SSLCertificateFile /etc/httpd/certs/pma_jasonmc_com.crt
SSLCertificateKeyFile /etc/httpd/certs/httpd.key
訪問測試
-
如果Browser沒有導入私有CA的證書,則顯示為不可信任,無法找到該證書的頒發者;
-
如果不使用主機名訪問則顯示無法建立私密連接;
-
如果客戶端的系統時間in the past,則返回Verify return code: 9 (certificate is not yet valid)
#在瀏覽器測試
1、導入CA服務器的證書文件cacert.pem,使瀏覽器信任CA,如 12306
2、添加host文件,必須使用主機名訪問
#在另一臺測試
vi /etc/hosts 添加ip pma.jasonmc.com
openssl s_client -connect pma.jasonmc.com:443 -CAfile /tmp/cacert.pem
GET /message.txt HTTP/1.1
HOST: pma.jasonmc.com
#在另一臺測試
curl --cacert /tmp/cacert.pem https://pma.jasonmc.com
httpd-2.2的不同之處
httpd-2.2的MPM默認為httpd.prefork,這是一個獨立的程序,沒有模塊之稱,此外還支持httpd.worker,但并不能提高性能,一般被忽略。
#查看httpd的mpm程序
httpd -M | grep mpm #為httpd.prefork的mpm
#還可以設置httpd的默認mpm程序,僅供娛樂
vi /etc/httpd/conf/httpd.conf
HTTPD=/usr/sbin/httpd #或httpd.worker
#配置prefork并發參數
102 <IfModule prefork.c>
103 StartServers 8
104 MinSpareServers 5
105 MaxSpareServers 20
106 ServerLimit 256
107 MaxClients 256
108 MaxRequestsPerChild 4000
109 </IfModule>
#配置worker并發參數
118 <IfModule worker.c>
119 StartServers 4
120 MaxClients 300
121 MinSpareThreads 25
122 MaxSpareThreads 75
123 ThreadsPerChild 25
124 MaxRequestsPerChild 0
125 </IfModule>
-
訪問控制,httpd-2.2中,站點資源無需顯示授權
order 指令的值是由一個逗號隔開的名單,這個名單表明了哪一個指令更高的優先權,第二條指令 deny 定義不能訪問該目錄的主機,第三條指令 allow 定義可以訪問該目錄的主機。該目錄除了IP地址外的機器都不能訪問。
Order deny,allow #優先級從低到高,一般而言會以此順序是開啟白名單
deny from all
allow form HOST #白名單ip..., ip/24, 10.1.253
Order allow,deny #開啟黑名單,并無軟用
allow from all
deny form HOST #黑名單ip..., ip/24, 10.1.253
-
虛擬主機
啟用虛擬主機需注釋物理主機,且各映射的資源無需顯示授權,但是在配置文件中需添加NameVirtualHost *:port表示虛擬主機是基于主機名的,否則是基于ip或port進行區分的。也就是說有一個ip只能偵聽一個80端口,當有多個虛擬主機使用同一個ip的80端口時會報錯。
vi /etc/httpd/conf/httpd.conf
#DocumentRoot #注釋conf中的文檔路徑
vi /etc/httpd/conf.d/vhost.conf
NameVirtualHost *:80 #使用ServerName進行區分
<VirtualHost *:80>
ServerName www1
DocumentRoot
</VirtualHost>
<VirtualHost *:80>
ServerName www2
DocumentRoot
</VirtualHost>
以上就是 httpd-2.4 的全部內容,以及httpd-2.2的部分功能實現。還是那句話 httpd 的功能非常豐富,在生產環境中需掌握虛擬主機的創建、ssl功能的使用以及在LAMP環境中如何與php結合使用的相關配置等等功能。以上內容是根據實驗結果總結而來,如有不懂的地方,也沒有關系,不懂就算了^.^
原創文章,作者:helloc,如若轉載,請注明出處:http://www.www58058.com/51818