1 socket
1.1跨網(wǎng)絡的主機間通訊
?在建立通信連接的每一端,進程間的傳輸要有兩個
?IP地址和端口號,合稱為套接字地址 socket address
?客戶機套接字地址定義了一個唯一的客戶進程
?服務器套接字地址定義了一個唯一的服務器進程

1.2 Socket套接字

Socket:套接字,進程間通信IPC的一種實現(xiàn),允許位于不同主機(或同一主機)上不同進程之間進行通信和數(shù)據(jù)交換,SocketAPI出現(xiàn)于1983年,4.2 BSD實現(xiàn)
?Socket API:封裝了內(nèi)核中所提供的socket通信相關的系統(tǒng)調(diào)用
?Socket Domain:根據(jù)其所使用的地址
AF_INET:Address Family,IPv4
AF_INET6:IPv6
AF_UNIX:同一主機上不同進程之間通信時使用
?Socket Type:根據(jù)使用的傳輸層協(xié)議
SOCK_STREAM:流,tcp套接字,可靠地傳遞、面向連接
SOCK_DGRAM:數(shù)據(jù)報,udp套接字,不可靠地傳遞、無連接
SOCK_RAW: 裸套接字,無須tcp或udp,APP直接通過IP包通信
1.3 客戶/服務器程序的套接字函數(shù)


套接字相關的系統(tǒng)調(diào)用:
socket(): 創(chuàng)建一個套接字
bind(): 綁定IP和端口
listen(): 監(jiān)聽
accept(): 接收請求
connect(): 請求連接建立
write(): 發(fā)送
read(): 接收
close(): 關閉連接
2 http 服務通信過程


3 http 工作機制:
3.1 工作機制:
http 請求: http request
http 響應:http response
一次http 事務:http 請求《------------------》http 響應
web 資源:
靜態(tài)文件:無需服務端組做出額外處理,客戶端發(fā)送request 到http服務器
文件后綴:.html .txt .jpg .js .css .mp3 .avi
動態(tài)文件:需要服務器端執(zhí)行程序,返回執(zhí)行的結(jié)果。
文件后綴:.php .jsp .asp
3.2 http 連接請求
1 客戶端訪問www.xxx.com;
2 DNS 解析www.xxx.com 結(jié)果IP-A給客戶端;
3 客戶端通過IP-A 訪問http服務器1,服務器1?返回index.html 文件給客戶端;
4 index.html包含很多資源,客戶端訪問其他服務器獲取相關資源;
3.3 http 連接介紹
3.3.1 http 串行連接

3.3.2 http 并行連接

3.3.3 http 持久連接

3.3.4 http 管道化持久連接

小結(jié):
串行連接:http 事務1、http 事務2、、、、 依次執(zhí)行,每一個TCP 三次握手承載一個http 事務,客戶端-服務器頻繁建立TCP 三次握手并finish;
并行連接:http 事務1、http 事務2、、、、 并行執(zhí)行,每一個TCP 三次握手承載一個http 事務,客戶端-服務器頻繁建立TCP 三次握手并finish,通過多條TCP連接發(fā)起并發(fā)的HTTP請求,相比串行連接效率高;
持久連接:首次tcp 三次握手成功后,http 事務1、http 事務2、、、、串行重用此TCP連接;
管道化連接:首次tcp 三次握手成功后,http 事務1、http 事務2、、、、并行重用此TCP連接;
4 http 協(xié)議介紹
4.1協(xié)議介紹
http 0.9:1991 , 原型版本,只支持GET命令,GET index.html,服務器端只能回應html 格式字符串;
http/1.0: 1996 ,支持cache、MIME,method;
引入POST和HEAD 命令;
每個TCP 連接只能發(fā)送一個請求,發(fā)送數(shù)據(jù)完畢后后連接關閉;
http/1.1:1997
引入了持久連接(persistent connection),即TCP連接默認不關閉,可以被多個請求復用,不用聲明Connection: keep-alive。對于同一個域名,大多數(shù)瀏覽器允許同時建立6個持久連接
引入了管道機制(pipelining),即在同一個TCP連接里,客戶端可以同時發(fā)送多個請求,進一步改進了HTTP協(xié)議的效率
新增方法:PUT、PATCH、OPTIONS、DELETE
HTTP 協(xié)議不帶有狀態(tài),每次請求都必須附上所有信息。請求的很多字段都是重復的,浪費帶寬,影響速度
http/2.0:2015年 ? HTTP2.0是SPDY的升級版
頭信息和數(shù)據(jù)體都是二進制,稱為頭信息幀和數(shù)據(jù)幀復用TCP連接,在一個連接里,客戶端和瀏覽器都可以同時發(fā)送多個請求或回應,且不用按順序一一對應,避免了“隊頭堵塞“,此雙向的實時通信稱為多工(Multiplexing)?
引入頭信息壓縮機制(header compression),頭信息使用gzip或compress壓縮后再發(fā)送;客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,不發(fā)送同樣字段,只發(fā)送索引號,提高速度
HTTP/2 允許服務器未經(jīng)請求,主動向客戶端發(fā)送資源,即服務器推送(server push)?
4.2 URI:統(tǒng)一資源標識
URI:統(tǒng)一資源標識,分為URL URN
URN:統(tǒng)一資源命名
URL:統(tǒng)一資源定位符,用于描述某個服務器某特定資源位置;
兩者區(qū)別:URN 定義某事物的身份,而URL 提供查找該事物的方法;
URL 組成:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
? scheme:方案,訪問服務器以獲取資源時要使用哪種協(xié)議
? user:用戶,某些方案訪問資源時需要的用戶名
? password:密碼,用戶對應的密碼,中間用:分隔
? Host:主機,資源宿主服務器的主機名或IP地址
? port:端口,資源宿主服務器正在監(jiān)聽的端口號,很多方案有默認端口號
? path:路徑,服務器資源的本地名,由一個/將其與前面的URL組件分隔
? params:參數(shù),指定輸入的參數(shù),參數(shù)為名/值對,多個參數(shù),用;分隔
? query:查詢,傳遞參數(shù)給程序,如數(shù)據(jù)庫,用?分隔,多個查詢用&分隔
? frag:片段,一小片或一部分資源的名字,此組件在客戶端使用,用#分隔
4.3 HTTP 通信過程舉例:

1 建立連接
client 瀏覽器輸入http://www.xxxx.com/index.html(DNS 解析過程略),發(fā)送http request;
2 接受請求
http 服務器接收到http request ,http request?進入http 服務器網(wǎng)卡緩沖區(qū),操作系統(tǒng)將數(shù)據(jù)從網(wǎng)卡緩沖區(qū)讀入到內(nèi)核網(wǎng)絡socket buffer 緩沖區(qū)中,在從socket buffer 中復制到httpd 進程;
3 處理請求
httpd 分析http request報文頭部獲取請求資源的操作GET index.html;
4 訪問資源
httpd 發(fā)送命令給內(nèi)核kernel希望到磁盤中得到index.html 文件,內(nèi)核通過DMA 直接將磁盤上的文件讀入到內(nèi)核數(shù)據(jù)緩沖區(qū)中,再從數(shù)據(jù)緩沖區(qū)復制到httpd 的內(nèi)存空間,httpd獲得index.html 文件;
5 構(gòu)建響應報文
httpd封裝http repose 報文;
6 發(fā)送響應報文;
httpd將響應報文發(fā)送至 -----> 內(nèi)核kernel socket buffer?----->?網(wǎng)卡緩沖區(qū)-?----->?客戶端;
7 記錄日志;
事務結(jié)束時,web 服務器在 日志文件中添加日志記錄已執(zhí)行完成的事務;
4.4 MPM 工作模式
perfork MPM

Prefork MPM: 預派生模式,有一個主控制進程,然后生成多個子進程,每個子進程有一個獨立的線程響應用戶請求,相對比較占用內(nèi)存,但是比較穩(wěn)定,可以設置最大和最小進程數(shù),是最古老的一種模式,也是最穩(wěn)定的模式,適用于訪問量不是很大的場景
?優(yōu)點:穩(wěn)定
?缺點:慢,占用資源,不適用于高并發(fā)場景
worker MPM

worker MPM:是一種多進程和多線程混合的模型,有一個控制進程,啟動多個子進程,每個子進程里面包含固定的線程,使用線程程來處理請求,當線程不夠使用的時候會再啟動一個新的子進程,然后在進程里面再啟動線程處理請求,由于其使用了線程處理請求,因此可以承受更高的并發(fā)。
?優(yōu)點:相比prefork 占用的內(nèi)存較少,可以同時處理更多的請求
?缺點:使用keep-alive的長連接方式,某個線程會一直被占據(jù),即使沒有傳輸數(shù)據(jù),也需要一直等待到超時才會被釋放。如果過多的線程,被這樣占據(jù),也會導致在高并發(fā)場景下的無服務線程可用。(該問題在prefork模式下,同樣會發(fā)生)
event MPM

event MPM:Apache中最新的模式,屬于事件驅(qū)動模型(epoll),每個進程響應多個請求,在現(xiàn)在版本里的已經(jīng)是穩(wěn)定可用的模式。它和worker模式很像,最大的區(qū)別在于,它解決了keep-alive場景下,長期被占用的線程的資源浪費問題(某些線程因為被keep-alive,空掛在哪里等待,中間幾乎沒有請求過來,甚至等到超時)。eventMPM中,會有一個專門的線程來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務線程,執(zhí)行完畢后,又允許它釋放。這樣增強了高并發(fā)場景下的請求處理能力
? event只在有數(shù)據(jù)發(fā)送的時候才開始建立連接,連接請求才會觸發(fā)工作線程,即使用了TCP的一個選項,叫做延遲接受連接TCP_DEFER_ACCEPT,加了這個選項后,若客戶端只進行TCP連接,不發(fā)送請求,則不會觸發(fā)Accept操作,也就不會觸發(fā)工作線程去干活,進行了簡單的防攻擊(TCP連接)
? 優(yōu)點:單線程響應多請求,占據(jù)更少的內(nèi)存,高并發(fā)下表現(xiàn)更優(yōu)秀,會有一個專門的線程來管理keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務線程,執(zhí)行完畢后,又允許它釋放
? 缺點:沒有線程安全控制
5 httpd 配置
5.1 軟件安裝:
[root@localhost ~]#?yum install httpd
[root@localhost ~]# ll /etc/httpd
total 0
drwxr-xr-x. 2 root root? 37 Oct? 3 15:10 conf
drwxr-xr-x. 2 root root? 82 Oct? 3 15:10 conf.d
drwxr-xr-x. 2 root root 146 Oct? 3 15:10 conf.modules.d
lrwxrwxrwx. 1 root root? 19 Oct? 3 15:10 logs -> ../../var/log/httpd
lrwxrwxrwx. 1 root root? 29 Oct? 3 15:10 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx. 1 root root? 10 Oct? 3 15:10 run -> /run/httpd
5.2 http 配置文件
配置文件:
/etc/httpd/conf/httpd.conf
/etc/httpd/conf.d/*.conf
httpd服務程序的配置信息被寫到??/etc/httpd/conf.d/xxx.conf 這樣的文件中,其實也就等于寫在主配置文件 /etc/httpd/conf/httpd.conf里。
因為這寫文件在httpd主配置文件生效的時候,就已經(jīng)被加載進來了。
vim /etc/httpd/conf/httpd.conf
打開主配置文件,按下G進入尾行,我們看到
# Supplemental configuration
# Load config files in the "/etc/httpd/conf.d" directory, if any.
IncludeOptional conf.d/*.conf
這表示,包含相對目錄conf.d下,所有以.conf后綴的配置文件的信息。
備份重要配置文件:
[root@localhost ~]# cp /etc/httpd/conf/httpd.conf{,.bak}
[root@localhost ~]# cd /etc/httpd/conf/
[root@localhost conf]# ll
total 40-rw-r--r--. 1 root root 11753 Aug? 2? 2017 httpd.conf
-rw-r--r--. 1 root root 11753 Oct? 3 19:27 httpd.conf.bak
-rw-r--r--. 1 root root 13077 Aug? 4? 2017 magic
站點網(wǎng)頁文檔根目錄:
/var/www/html
5.3 http 常見配置
httpd 配置文件主要組成:
配置格式:directive value
directive 不區(qū)分字符大小寫
value 為路徑時,是否區(qū)分大小寫,取決于文件系統(tǒng)
5.3.1 修改監(jiān)聽的IP和Port
vim /etc/httpd/conf/httpd.conf
格式:
Listen [IP:]PORT
[root@localhost ~]# systemctl restart httpd
[root@localhost ~]# ss -ntl? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 查看端口是否處于監(jiān)聽狀態(tài)
[root@localhost html]# curl -I http://192.168.38.141
HTTP/1.1 200 OK
Date: Thu, 03 Oct 2019 12:17:15 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Thu, 03 Oct 2019 12:16:36 GMT
ETag: "15-594008e92cec0"
Accept-Ranges: bytes
Content-Length: 21
Content-Type: text/html; charset=UTF-8
5.3.2 顯示服http 常見配置務器版本信息
ServerTokens Major|Minor|Min[imal]|Prod[uctOnly]|OS|Full
This directive controls whether?Server?response header field which is sent back to clients includes a description of the generic OS-type of the server as well as information about compiled-in modules.
ServerTokens Full?(or not specified)
Server sends (e.g.):?Server: Apache/2.4.2 (Unix) PHP/4.2.2 MyMod/1.2
ServerTokens Prod[uctOnly]
Server sends (e.g.):?Server: Apache
ServerTokens Major
Server sends (e.g.):?Server: Apache/2
ServerTokens Minor
Server sends (e.g.):?Server: Apache/2.4
ServerTokens Min[imal]
Server sends (e.g.):?Server: Apache/2.4.2
ServerTokens OS
Server sends (e.g.):?Server: Apache/2.4.2 (Unix)
5.3.3 持久連接
Persistent Connection:連接建立,每個資源獲取完成后不會斷開連接,而是繼續(xù)等待其它的請求完成,默認關閉持久連接
斷開條件:時間限制:以秒為單位, 默認5s,httpd-2.4 支持毫秒級
副作用:對并發(fā)訪問量大的服務器,持久連接會使有些請求得不到響應
折衷:使用較短的持久連接時間
設置:KeepAlive On|Off
? ? ? ? ? ?KeepAliveTimeout 15
測試:
telnet WEB_SERVER_IP PORT
GET /URL HTTP/1.1
Host: WEB_SERVER_IP
5.3.4 DSO: Dynamic Shared Object
加載動態(tài)模塊配置,不需重啟即生效
/etc/httpd/conf/httpd.conf
Include conf.modules.d/*.conf
配置指定實現(xiàn)模塊加載格式:
LoadModule <mod_name> <mod_path>
模塊文件路徑可使用相對路徑:相對于ServerRoot(默認/etc/httpd)
示例:LoadModule auth_basic_module modules/mod_auth_basic.so
? 動態(tài)模塊路徑: /usr/lib64/httpd/modules/
? 查看靜態(tài)編譯的模塊
httpd -l
? 查看靜態(tài)編譯及動態(tài)裝載的模塊
httpd –M
5.3.5? MPM( Multi-Processing Module)多路處理模塊
prefork, worker, event
切換使用的MPM
/etc/httpd/conf.modules.d/00-mpm.conf
啟用要啟用的MPM相關的LoadModule指令即可
[root@localhost ~]# cat /etc/httpd/conf.modules.d/00-mpm.conf
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:
# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#LoadModule mpm_event_module modules/mod_mpm_event.so
5.3.6 定義main server?文檔頁面路徑
DocumentRoot “/path”
[root@localhost html]# vi /etc/httpd/conf/httpd.conf
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.#DocumentRoot "/var/www/html"
5.3.7定義站點主頁面
[root@localhost html]# vi /etc/httpd/conf/httpd.conf
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
<IfModule dir_module>
?DirectoryIndex index.html
</IfModule>
5.3.8?站點訪問控制常見機制
可基于兩種機制指明對哪些資源進行何種訪問控制
訪問控制機制有兩種:客戶端來源地址,用戶賬號
<Directory>中“基于源地址”實現(xiàn)訪問控制
Options:后跟1個或多個以空白字符分隔的選項列表
在選項前的+,- 表示增加或刪除指定選項
常見選項:
Indexes:指明的URL路徑下不存在與定義的主頁面資源相符的資源文件時,返回索引列表給用戶
FollowSymLinks:允許訪問符號鏈接文件所指向的源文件
None:全部禁用
All: 全部允許
舉例;
[root@localhost conf.d]# cat testhttp.conf
<Directory "/var/wwwi/html">
? Require all granted
options Indexes
</Directory>
AllowOverride與訪問控制相關的哪些指令可以放在指定目錄下的.htaccess(由AccessFileName指定)文件中,覆蓋之前的配置指令
只對<directory>語句有效
AllowOverride All: .htaccess中所有指令都有效
AllowOverride None: .htaccess 文件無效
AllowOverride AuthConfig .htaccess 文件中,除了AuthConfig 其它指令都無法生效
[root@localhost html]# cat .htaccess
Options FollowSymLinks[root@localhost html]# cat /etc/httpd/conf/httpd.conf? ?//對。ht文件的訪問進行限制
<Files ".ht*">
Require all denied
</Files>[root@localhost conf.d]# cat testhttp.conf
<Directory "/var/wwwi/html">
?Require all granted
AllowOverride All
</Directory>
基于IP的訪問控制:
無明確授權(quán)的目錄,默認拒絕
允許所有主機訪問:Require all granted
拒絕所有主機訪問:Require all denied
控制特定的IP訪問:
Require ip IPADDR:授權(quán)指定來源的IP訪問
Require not ip IPADDR:拒絕特定的IP訪問
控制特定的主機訪問:
Require host HOSTNAME:授權(quán)特定主機訪問
Require not host HOSTNAME:拒絕
舉例:.conf文件拒絕訪問

不能有失敗,至少有一個成功匹配才成功,即失敗優(yōu)先
<RequireAll>
Require all granted
Require not ip 172.16.1.1 拒絕特定IP
</RequireAll>
?多個語句有一個成功,則成功,即成功優(yōu)先
<RequireAny>
Require all denied
require ip 172.16.1.1 允許特定IP
</RequireAny>
舉例:

5.3.9 日志:
日志類型:
訪問日志
錯誤日志
[root@localhost html]# ls /etc/httpd/logs/
access_log? error_log
[root@localhost httpd]# ll -d /etc/httpd/logslrwxrwxrwx. 1 root root 19 Oct? 3 22:03 /etc/httpd/logs -> ../../var/log/httpd
[root@localhost logs]# cd /var/log/httpd/
[root@localhost httpd]# ll
-rw-r--r--. 1 root root 250094 Oct? 8 22:16 access_log
-rw-r--r--. 1 root root? 10425 Oct? 8 22:15 error_log
5.3.10定義路徑別名
格式:Alias /URL/ "/PATH/"
5.3.11 基于用戶的訪問控制
? 認證質(zhì)詢:WWW-Authenticate:響應碼為401,拒絕客戶端請求,并說明要求客戶端提供賬號和密碼
? 認證:Authorization:客戶端用戶填入賬號和密碼后再次發(fā)送請求報文;認證通過時,則服務器發(fā)送響應的資源
? 認證方式兩種:
basic:明文
digest:消息摘要認證,兼容性差
? 安全域:需要用戶認證后方能訪問的路徑;應該通過名稱對其進行標識,以便于知用戶認證的原因
? 用戶的賬號和密碼
虛擬賬號:僅用于訪問某服務時用到的認證標識存儲:文本文件,SQL數(shù)據(jù)庫,ldap目錄存儲,nis等
提供賬號和密碼存儲(文本文件)
使用專用命令完成此類文件的創(chuàng)建及用戶管理
htpasswd [options] /PATH/HTTPD_PASSWD_FILE username
-c 自動創(chuàng)建文件,僅應該在文件不存在時使用
-p 明文密碼
-d CRYPT格式加密,默認
-m md5格式加密
-s sha格式加密
-D 刪除指定用戶
舉例:
basic認證配置示例:
方法1
在/etc/http/conf.d 下創(chuàng)建保存用戶密碼的文檔httpuser(文件名字自定義)
root@localhost conf.d]# htpasswd -c httpuser bob
New password:
Re-type new password:
Adding password for user bob[root@localhost conf.d]# htpasswd? httpuser alice
New password:
Re-type new password:
Adding password for user alice[root@localhost conf.d]# ll
total 24
-rw-r--r--. 1 root root 2926 Aug? 4? 2017 autoindex.conf
-rw-r--r--. 1 root root? ? 0 Oct? 8 09:12 cat
-rw-r--r--. 1 root root? 86 Oct? 9 21:15 httpuser
-rw-r--r--. 1 root root? 366 Aug? 4? 2017 README
-rw-r--r--. 1 root root? 172 Oct? 9 20:49 test2.conf
-rw-r--r--. 1 root root 1252 Aug? 2? 2017 userdir.conf
-rw-r--r--. 1 root root? 824 Aug? 2? 2017 welcome.conf[root@localhost conf.d]# cat httpuser
bob:$apr1$K.EznJdk$HNxgjFrGRCpm/YTkJbNA7/
alice:$apr1$XY32GHVl$d89ieqA8VDc/HjJwRUDCV0
定義安全域
[root@localhost conf.d]# cat test2.conf<Directory /var/www/html/admin>
AuthType Basic
AuthName "Admin Page"
AuthUserFile "/etc/httpd/conf.d/httpuser"
Require user alice#Require valid-user? ?? 允許賬號文件中的所有用戶登錄
</Directory>
備注:/var/www/html/admin 下放置需要訪問的頁面
方法2:
[root@localhost conf.d]# cat test2.conf
<Directory /var/www/html/admin>
allowoveroride authconfig
</Directory>[root@localhost conf.d]#? vim /var/www/html/admin/htaccess?
AuthType Basic
AuthName "Admin Page"
AuthUserFile "/etc/httpd/conf.d/httpuser"
Require user alice
驗證:https://192.168.38.141:8080/admin 彈出以下驗證,輸入密碼后,正常顯示網(wǎng)頁

5.3.12 實現(xiàn)用戶家目錄的http共享
?基于模塊mod_userdir.so實現(xiàn)
?相關設置:
vim /etc/httpd/conf.d/userdir.conf
<IfModule mod_userdir.c>
#UserDir disabled
UserDir public_html #指定共享目錄的名稱</IfModule>
?準備目錄
su – wang;mkdir ~/public_html
setfacl –m u:apache:x ~wang
?訪問
http://localhost/~wang/index.html
5.3.13 ServerSignature On | Off | EMail
當客戶請求的網(wǎng)頁并不存在時,服務器將產(chǎn)生錯誤文檔,如果打開了ServerSignature選項,錯誤文檔的最后一行將包含服務器的名字、Apache的版本等信息,如果不對外顯示這些信息,就可以將這個參數(shù)設置為Off設置為Email,將顯示ServerAdmin 的Email提示
5.3.14 status頁面
[root@localhost ~]# httpd -M | grep status
status_module (shared)
配置文件增加如下配置:
<Location "/status">
SetHandler server-status
</Location>
驗證:http://192.168.38.141:8080/status 查看狀態(tài);

為保證安全性,需對登錄的ip 進行限制,配置如下:

5.3.14 虛擬主機
有三種實現(xiàn)方案:
基于ip:為每個虛擬主機準備至少一個ip地址
基于port:為每個虛擬主機使用至少一個獨立的port
基于FQDN:為每個虛擬主機使用至少一個FQDN
[root@localhost ~]# cd /etc/httpd/conf.d/
[root@localhost conf.d]# mkdir /data
[root@localhost conf.d]# cd /data/
[root@localhost data]# mkdir {a,b,c}site
[root@localhost data]# echo www.a.com >asite/index.html
[root@localhost data]# echo www.b.com >bsite/index.html
[root@localhost data]# echo www.c.com >csite/index.html
舉例:基于IP 方案
[root@localhost conf.d]# vi test2.con
<VirtualHost 192.168.38.101:8080>
DocumentRoot "/etc/httpd/conf.d/data/asite"
<Directory "/etc/httpd/conf.d/data/asite">
Require all granted
</Directory></VirtualHost>
<VirtualHost 192.168.38.102:8080>
DocumentRoot "/etc/httpd/conf.d/data/bsite"
<Directory "/etc/httpd/conf.d/data/bsite">
Require all granted
</Directory></VirtualHost>
<VirtualHost 192.168.38.102:8080>
DocumentRoot "/etc/httpd/conf.d/data/csite"
<Directory "/etc/http/conf.d/data/csite">
Require all granted
</Directory>
</VirtualHost>
6 HTTPS
6.1 https 介紹
為解決安全問題,網(wǎng)景在1994年創(chuàng)建了HTTPS,并應用在網(wǎng)景導航者瀏覽器中。最初,HTTPS是與SSL一起使用的;在SSL逐漸演變到TLS時(其實兩個是一個東西,只是名字不同而已),最新的HTTPS也由在2000年五月公布的RFC2818正式確定下來。HTTPS就是安全版的HTTP,目前大型網(wǎng)站基本實現(xiàn)全站HTTPS
?HTTPS協(xié)議需要到CA申請證書,一般免費證書很少,需要交費
?HTTP協(xié)議運行在TCP之上,所有傳輸?shù)膬?nèi)容都是明文,HTTPS運行在SSL/TLS之上,SSL/TLS運行在TCP之上,所有傳輸?shù)膬?nèi)容都經(jīng)過加密的
?HTTP和HTTPS使用的是不同的連接方式,端口不同,前者是80,后者是443
?HTTPS可以有效的防止運營商劫持,解決了防劫持的一個大問題
?HTTPS 中的SSL握手等過程降低用戶訪問速度,但是只要經(jīng)過合理優(yōu)化和部署,HTTPS 對速度的影響完全可以接受
6.2 ssl
https:http over ssl
? SSL會話的簡化過程
(1) 客戶端發(fā)送可供選擇的加密方式,并向服務器請求證書
(2) 服務器端發(fā)送證書以及選定的加密方式給客戶端
(3) 客戶端取得證書并進行證書驗證
如果信任給其發(fā)證書的CA
(a) 驗證證書來源的合法性;用CA的公鑰解密證書上數(shù)字簽名
(b) 驗證證書的內(nèi)容的合法性:完整性驗證
(c) 檢查證書的有效期限
(d) 檢查證書是否被吊銷
(e) 證書中擁有者的名字,與訪問的目標主機要一致
(4) 客戶端生成臨時會話密鑰(對稱密鑰),并使用服務器端的公鑰加密此數(shù)據(jù)發(fā)送給服務器,完成密鑰交換
(5) 服務用此密鑰加密用戶請求的資源,響應給客戶端
6.3 https實現(xiàn)
? (1) 為服務器申請數(shù)字證書
測試:通過私建CA發(fā)證書
?(a) 創(chuàng)建私有CA
?(b) 在服務器創(chuàng)建證書簽署請求
?(c) CA簽證
? (2) 配置httpd支持使用ssl,及使用的證書
yum -y install mod_ssl
配置文件:/etc/httpd/conf.d/ssl.conf
DocumentRoot
ServerName
SSLCertificateFile
SSLCertificateKeyFile
? (3) 測試基于https訪問相應的主機
openssl s_client [-connect host:port] [-cert filename] [-CApath directory] [-CAfilefilename]
舉例: 軟件安轉(zhuǎn)ssl
[root@localhost conf.d]#
[root@localhost conf.d]# yum install mod_ssl
[root@localhost conf.d]# rpm -ql mod_ssl
/etc/httpd/conf.d/ssl.conf
/etc/httpd/conf.modules.d/00-ssl.conf
/usr/lib64/httpd/modules/mod_ssl.so
/usr/libexec/httpd-ssl-pass-dialog
/var/cache/httpd/ssl
[root@localhost conf.d]# systemctl restart httpd
[root@localhost conf.d]# ss -ntl
State? ? ? Recv-Q Send-Q Local Address:Port? ? ? ? ? ? ? Peer Address:Port? ? ? ? ? ? ?
LISTEN? ? 0? ? ? 128? ? 192.168.38.141:8080? ? ? ? ? ? ? ? ? ? *:*? ? ? ? ? ? ? ? ?
LISTEN? ? 0? ? ? 128? ? ? ? ? *:22? ? ? ? ? ? ? ? ? ? ? *:*? ? ? ? ? ? ? ? ?
LISTEN? ? 0? ? ? 100? ? 127.0.0.1:25? ? ? ? ? ? ? ? ? ? ? *:*? ? ? ? ? ? ? ? ?
LISTEN? ? 0? ? ? 128? ? ? ? :::22? ? ? ? ? ? ? ? ? ? ? :::*? ? ? ? ? ? ? ? ?
LISTEN? ? 0? ? ? 100? ? ? ? ::1:25? ? ? ? ? ? ? ? ? ? ? :::*? ? ? ? ? ? ? ? ?
LISTEN? ? 0? ? ? 128? ? ? ? :::443?
舉例:搭建CA
CA服務器:
生成私鑰
(umask 077; openssl genrsa -out private/cakey.pem 2048)
生成自簽名證書
openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 3650? <<EOF
touch /etc/pki/CA/index.txt
echo 01 > /etc/pki/CA/serial
HTTPS 服務器:
[root@localhost conf.d]# mkdir ssl
[root@localhost conf.d]# pwd
/etc/httpd/conf.d
[root@localhost conf.d]# cd ssl
給web服務器生成私鑰
[root@localhost ssl]# (umask 066;openssl genrsa -out httpd.key)
Generating RSA private key, 2048 bit long modulus
..........................................................+++
.....................................................................................+++
-----
生成證書申請文件
[root@localhost ssl]# openssl req -new -key httpd.key -out httpd.cs
將證書請求文件傳輸給CA服務器
[root@localhost ssl]# scp /etc/httpd/conf.d/ssl/httpd.csr 192.168.38.142:/etc/pki/CA
CA服務器:
CA簽署證書,并將證書頒發(fā)給請求者
[root@localhost CA]# openssl ca -in /etc/pki/CA/httpd.csr -out /etc/pki/CA/certs/http.crt -days 100
[root@localhost CA]# scp /etc/pki/CA/certs/http.crt 192.168.38.141:/etc/httpd/conf.d/ssl/
[root@localhost CA]# scp /etc/pki/CA/cacert.pem 192.168.38.141:/etc/httpd/conf.d/ssl/
https 服務器修改配置文件
vim /etc/httpd/conf.d/ssl.conf
SSLCertificateKeyFile /etc/httpd/conf.d/ssl/httpd.key
SSLCertificateKeyFile /etc/httpd/conf.d/ssl/httpd.key
SSLCertificateFile /etc/httpd/conf.d/ssl/httpd.crt
[root@localhost ssl]# ll
-rw-r--r--. 1 root root 1424 Oct 10 19:15 cacert.pem
-rw-r--r--. 1 root root 4621 Oct 10 19:15 http.crt
-rw-r--r--. 1 root root 1054 Oct 10 19:03 httpd.csr
-rw-------. 1 root root 1679 Oct 10 19:01 httpd.key
6.4 將http請求轉(zhuǎn)發(fā)至https的URL
?重定向
Redirect [status] URL-path URL
?status狀態(tài):
?Permanent: 返回永久重定向狀態(tài)碼 301
?Temp:返回臨時重定向狀態(tài)碼302. 此為默認值
?示例:Redirect temp / https://www.magedu.com/

說明如下:
瀏覽器發(fā)起訪問http://www.a.com
服務器重定向信息;
瀏覽器發(fā)起https://ww.a.com,對服務器訪問
6.5 HSTS:HTTP Strict Transport Security
服務器端配置支持HSTS后,會在給瀏覽器返回的HTTP首部中攜帶HSTS字段。瀏覽器獲取到該信息后,會將所有HTTP訪問請求在內(nèi)部做307跳轉(zhuǎn)到HTTPS。而無需任何網(wǎng)絡過程;
1)瀏覽器發(fā)起訪問http://www.a.com
2)服務器返回HSTS 字段以及重定向信息;
3)瀏覽器緩存收到的重定向信息,當有訪問http://www.a.com時直接調(diào)轉(zhuǎn)到https://ww.a.com,對服務器發(fā)起訪問
l

HSTS preload list
是Chrome瀏覽器中的HSTS預載入列表,在該列表中的網(wǎng)站,使用Chrome瀏覽器訪問時,會自動轉(zhuǎn)換成HTTPS。Firefox、Safari、Edge瀏覽器也會采用這個列表
實現(xiàn)HSTS示例:
vim /etc/httpd/conf/httpd.conf
Header always set Strict-Transport-Security "max-age=31536000"
RewriteEngine on
RewriteRule ^(/.*)$ https://%{HTTP_HOST}$1 [redirect=302]
7 HTTP 協(xié)議報文分析
7.1 HTTP請求報文

7.2 HTTP響應報文

7.3 HTTP 語法
?request報文
<method> <request-URL> <version>
<headers>
<entity-body>
?response報文
<version> <status> <reason-phrase>
<headers>
<entity-body>
?method: 請求方法,標明客戶端希望服務器對資源執(zhí)行的動作
GET、HEAD、POST等
?version:
HTTP/<major>.<minor>
?status:
三位數(shù)字,如200,301, 302, 404, 502; 標記請求處理過程中發(fā)生的情況
?reason-phrase:
狀態(tài)碼所標記的狀態(tài)的簡要描述
?headers:
每個請求或響應報文可包含任意個首部;每個首部都有首部名稱,后面跟一個冒號,而后跟一個可選空格,接著是一個值
?entity-body:請求時附加的數(shù)據(jù)或響應時附加的數(shù)據(jù)
Method 方法:
GET: 從服務器獲取一個資源
HEAD: 只從服務器獲取文檔的響應首部
POST: 向服務器輸入數(shù)據(jù),通常會再由網(wǎng)關程序繼續(xù)處理
PUT: 將請求的主體部分存儲在服務器中,如上傳文件
DELETE: 請求刪除服務器上指定的文檔
TRACE: 追蹤請求到達服務器中間經(jīng)過的代理服務器
OPTIONS:請求服務器返回對指定資源支持使用的請求方法
7.4 http協(xié)議首部
?通用首部:請求報文和響應報文兩方都會使用的首部
?請求首部:從客戶端向服務器端發(fā)送請求報文時使用的首部。補充了請求的附加內(nèi)容、客戶端信息、請求內(nèi)容相關優(yōu)先級等信息
?響應首部:從服務器端向客戶端返回響應報文時使用的首部。補充了響應的附加內(nèi)容,也會要求客戶端附加額外的內(nèi)容信息
?實體首部:針對請求報文和響應報文的實體部分使用的首部。補充了資源內(nèi)容更新時間等與實體有關的的信息
?擴展首部
7.4.1 通用首部:
Date: 報文的創(chuàng)建時間
Connection:連接狀態(tài),如keep-alive, close
Via:顯示報文經(jīng)過的中間節(jié)點(代理,網(wǎng)關)
Cache-Control:控制緩存,如緩存時長
MIME-Version:發(fā)送端使用的MIME版本
Warning:錯誤通知
請求首部:
Accept:通知服務器自己可接受的媒體類型
Accept-Charset: 客戶端可接受的字符集
Accept-Encoding:客戶端可接受編碼格式,如gzip
Accept-Language:客戶端可接受的語言
Client-IP: 請求的客戶端IP
Host: 請求的服務器名稱和端口號
Referer:跳轉(zhuǎn)至當前URI的前一個URL
User-Agent:客戶端代理,瀏覽器版本
條件式請求首部:
Expect:允許客戶端列出某請求所要求的服務器行為
If-Modified-Since:自從指定的時間之后,請求的資源是否發(fā)生過修改
If-Unmodified-Since:與上面相反
If-None-Match:本地緩存中存儲的文檔的ETag標簽是否與服務器文檔的
Etag不匹配
If-Match:與上面相反
?安全請求首部:
Authorization:向服務器發(fā)送認證信息,如賬號和密碼
Cookie: 客戶端向服務器發(fā)送cookie
?代理請求首部:
Proxy-Authorization: 向代理服務器認證
7.4.2 響應首部:
?信息性:
Age:從最初創(chuàng)建開始,響應持續(xù)時長
Server:服務器程序軟件名稱和版本
?協(xié)商首部:某資源有多種表示方法時使用
Accept-Ranges:服務器可接受的請求范圍類型
Vary:服務器查看的其它首部列表
?安全響應首部:
Set-Cookie:向客戶端設置cookie
WWW-Authenticate:來自服務器對客戶端的質(zhì)詢列表
7.4.3 實體首部:
Allow: 列出對此資源實體可使用的請求方法
Location:告訴客戶端真正的實體位于何處
Content-Encoding:對主體執(zhí)行的編碼
Content-Language:理解主體時最適合的語言
Content-Length: 主體的長度
Content-Location: 實體真正所處位置
Content-Type:主體的對象類型,如text
緩存相關:
ETag:實體的擴展標簽
Expires:實體的過期時間
Last-Modified:最后一次修改的時間
7.4.4 解決http協(xié)議無狀態(tài)方法
7.4.4.1 cookie
HTTP 是一種無狀態(tài)協(xié)議。協(xié)議自身不對請求和響應之間的通信狀態(tài)進行保存。也就是說在 HTTP 這個級別,協(xié)議對于發(fā)送過的請求或響應都不做持久化處理。這是為了更快地處理大量事務,確保協(xié)議的可伸縮性,而特意把 HTTP 協(xié)議設計成如此簡單的??墒请S著 Web 的不斷發(fā)展,很多業(yè)務都需要對通信狀態(tài)進行保存。于是引入了 Cookie 技術(shù)。使用 Cookie 的狀態(tài)管理Cookie 技術(shù)通過在請求和響應報文中寫入 Cookie 信息來控制客戶端的狀態(tài)。Cookie 會根據(jù)從服務器端發(fā)送的響應報文內(nèi)的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存Cookie。當下次客戶端再往該服務器發(fā)送請求時,客戶端會自動在請求報文中加入 Cookie 值后發(fā)送出去。服務器端發(fā)現(xiàn)客戶端發(fā)送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發(fā)來的連接請求,然后對比服務器上的記錄,最后得到之前的狀態(tài)信息;

Set-cookie首部字段示例:
Set-Cookie: status=enable; expires=Fri, 24 Nov 2017 20:30:02 GMT;path=/;
?NAME=VALUE 賦予 Cookie 的名稱和其值,此為必需項
?expires=DATE Cookie 的有效期,若不明確指定則默認為瀏覽器關閉前為止
?path=PATH 將服務器上的文件目錄作為Cookie的適用對象,若不指定則默認為文檔所在的文件目錄
?domain=域名 作為 Cookie 適用對象的域名,若不指定則默認為創(chuàng)建Cookie的服務器的域名
?Secure 僅在 HTTPS 安全通信時才會發(fā)送 Cookie
?HttpOnly 加以限制使 Cookie 不能被 JavaScript 腳本訪問
7.4.4.2cookie vs session
session和cookie的作用有點類似,都是為了存儲用戶相關的信息。不同的是,cookie是存儲在本地瀏覽器,而session存儲在服務器。存儲在服務器的數(shù)據(jù)會更加的安全,不容易被竊取。但存儲在服務器也有一定的弊端,就是會占用服務器的資源;
通過cookie存儲一個session_id,然后具體的數(shù)據(jù)則是保存在session中。如果用戶已經(jīng)登錄,則服務器會在cookie中保存一個session_id,下次再次請求的時候,會把該session_id攜帶上來,服務器根據(jù)session_id在session庫中獲取用戶的session數(shù)據(jù)。就能知道該用戶到底是誰,以及之前保存的一些狀態(tài)信息