1 socket
1.1跨网络的主机间通讯
在建立通信连接的每一端,进程间的传输要有两个
IP地址和端口号,合称为套接字地址 socket address
客户机套接字地址定义了一个唯一的客户进程
服务器套接字地址定义了一个唯一的服务器进程
1.2 Socket套接字
Socket:套接字,进程间通信IPC的一种实现,允许位于不同主机(或同一主机)上不同进程之间进行通信和数据交换,SocketAPI出现于1983年,4.2 BSD实现
Socket API:封装了内核中所提供的socket通信相关的系统调用
Socket Domain:根据其所使用的地址
AF_INET:Address Family,IPv4
AF_INET6:IPv6
AF_UNIX:同一主机上不同进程之间通信时使用
Socket Type:根据使用的传输层协议
SOCK_STREAM:流,tcp套接字,可靠地传递、面向连接
SOCK_DGRAM:数据报,udp套接字,不可靠地传递、无连接
SOCK_RAW: 裸套接字,无须tcp或udp,APP直接通过IP包通信
1.3 客户/服务器程序的套接字函数
套接字相关的系统调用:
socket(): 创建一个套接字
bind(): 绑定IP和端口
listen(): 监听
accept(): 接收请求
connect(): 请求连接建立
write(): 发送
read(): 接收
close(): 关闭连接
2 http 服务通信过程
3 http 工作机制:
3.1 工作机制:
http 请求: http request
http 响应:http response
一次http 事务:http 请求《------------------》http 响应
web 资源:
静态文件:无需服务端组做出额外处理,客户端发送request 到http服务器
文件后缀:.html .txt .jpg .js .css .mp3 .avi
动态文件:需要服务器端执行程序,返回执行的结果。
文件后缀:.php .jsp .asp
3.2 http 连接请求
1 客户端访问www.xxx.com;
2 DNS 解析www.xxx.com 结果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 管道化持久连接
小结:
串行连接:http 事务1、http 事务2、、、、 依次执行,每一个TCP 三次握手承载一个http 事务,客户端-服务器频繁建立TCP 三次握手并finish;
并行连接:http 事务1、http 事务2、、、、 并行执行,每一个TCP 三次握手承载一个http 事务,客户端-服务器频繁建立TCP 三次握手并finish,通过多条TCP连接发起并发的HTTP请求,相比串行连接效率高;
持久连接:首次tcp 三次握手成功后,http 事务1、http 事务2、、、、串行重用此TCP连接;
管道化连接:首次tcp 三次握手成功后,http 事务1、http 事务2、、、、并行重用此TCP连接;
4 http 协议介绍
4.1协议介绍
http 0.9:1991 , 原型版本,只支持GET命令,GET index.html,服务器端只能回应html 格式字符串;
http/1.0: 1996 ,支持cache、MIME,method;
引入POST和HEAD 命令;
每个TCP 连接只能发送一个请求,发送数据完毕后后连接关闭;
http/1.1:1997
引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。对于同一个域名,大多数浏览器允许同时建立6个持久连接
引入了管道机制(pipelining),即在同一个TCP连接里,客户端可以同时发送多个请求,进一步改进了HTTP协议的效率
新增方法:PUT、PATCH、OPTIONS、DELETE
HTTP 协议不带有状态,每次请求都必须附上所有信息。请求的很多字段都是重复的,浪费带宽,影响速度
http/2.0:2015年 HTTP2.0是SPDY的升级版
头信息和数据体都是二进制,称为头信息帧和数据帧复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,且不用按顺序一一对应,避免了“队头堵塞“,此双向的实时通信称为多工(Multiplexing)
引入头信息压缩机制(header compression),头信息使用gzip或compress压缩后再发送;客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,不发送同样字段,只发送索引号,提高速度
HTTP/2 允许服务器未经请求,主动向客户端发送资源,即服务器推送(server push)
4.2 URI:统一资源标识
URI:统一资源标识,分为URL URN
URN:统一资源命名
URL:统一资源定位符,用于描述某个服务器某特定资源位置;
两者区别:URN 定义某事物的身份,而URL 提供查找该事物的方法;
URL 组成:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
scheme:方案,访问服务器以获取资源时要使用哪种协议
user:用户,某些方案访问资源时需要的用户名
password:密码,用户对应的密码,中间用:分隔
Host:主机,资源宿主服务器的主机名或IP地址
port:端口,资源宿主服务器正在监听的端口号,很多方案有默认端口号
path:路径,服务器资源的本地名,由一个/将其与前面的URL组件分隔
params:参数,指定输入的参数,参数为名/值对,多个参数,用;分隔
query:查询,传递参数给程序,如数据库,用?分隔,多个查询用&分隔
frag:片段,一小片或一部分资源的名字,此组件在客户端使用,用#分隔
4.3 HTTP 通信过程举例:
1 建立连接
client 浏览器输入http://www.xxxx.com/index.html(DNS 解析过程略),发送http request;
2 接受请求
http 服务器接收到http request ,http request 进入http 服务器网卡缓冲区,操作系统将数据从网卡缓冲区读入到内核网络socket buffer 缓冲区中,在从socket buffer 中复制到httpd 进程;
3 处理请求
httpd 分析http request报文头部获取请求资源的操作GET index.html;
4 访问资源
httpd 发送命令给内核kernel希望到磁盘中得到index.html 文件,内核通过DMA 直接将磁盘上的文件读入到内核数据缓冲区中,再从数据缓冲区复制到httpd 的内存空间,httpd获得index.html 文件;
5 构建响应报文
httpd封装http repose 报文;
6 发送响应报文;
httpd将响应报文发送至 -----> 内核kernel socket buffer -----> 网卡缓冲区- -----> 客户端;
7 记录日志;
事务结束时,web 服务器在 日志文件中添加日志记录已执行完成的事务;
4.4 MPM 工作模式
perfork MPM
Prefork MPM: 预派生模式,有一个主控制进程,然后生成多个子进程,每个子进程有一个独立的线程响应用户请求,相对比较占用内存,但是比较稳定,可以设置最大和最小进程数,是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:慢,占用资源,不适用于高并发场景
worker MPM
worker MPM:是一种多进程和多线程混合的模型,有一个控制进程,启动多个子进程,每个子进程里面包含固定的线程,使用线程程来处理请求,当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,由于其使用了线程处理请求,因此可以承受更高的并发。
优点:相比prefork 占用的内存较少,可以同时处理更多的请求
缺点:使用keep-alive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用。(该问题在prefork模式下,同样会发生)
event MPM
event MPM:Apache中最新的模式,属于事件驱动模型(epoll),每个进程响应多个请求,在现在版本里的已经是稳定可用的模式。它和worker模式很像,最大的区别在于,它解决了keep-alive场景下,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)。eventMPM中,会有一个专门的线程来管理这些keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
event只在有数据发送的时候才开始建立连接,连接请求才会触发工作线程,即使用了TCP的一个选项,叫做延迟接受连接TCP_DEFER_ACCEPT,加了这个选项后,若客户端只进行TCP连接,不发送请求,则不会触发Accept操作,也就不会触发工作线程去干活,进行了简单的防攻击(TCP连接)
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控制
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主配置文件生效的时候,就已经被加载进来了。
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
站点网页文档根目录:
/var/www/html
5.3 http 常见配置
httpd 配置文件主要组成:
配置格式:directive value
directive 不区分字符大小写
value 为路径时,是否区分大小写,取决于文件系统
5.3.1 修改监听的IP和Port
vim /etc/httpd/conf/httpd.conf
格式:
Listen [IP:]PORT
[root@localhost ~]# systemctl restart httpd
[root@localhost ~]# ss -ntl // 查看端口是否处于监听状态
[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:连接建立,每个资源获取完成后不会断开连接,而是继续等待其它的请求完成,默认关闭持久连接
断开条件:时间限制:以秒为单位, 默认5s,httpd-2.4 支持毫秒级
副作用:对并发访问量大的服务器,持久连接会使有些请求得不到响应
折衷:使用较短的持久连接时间
设置: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
加载动态模块配置,不需重启即生效
/etc/httpd/conf/httpd.conf
Include conf.modules.d/*.conf
配置指定实现模块加载格式:
LoadModule <mod_name> <mod_path>
模块文件路径可使用相对路径:相对于ServerRoot(默认/etc/httpd)
示例:LoadModule auth_basic_module modules/mod_auth_basic.so
动态模块路径: /usr/lib64/httpd/modules/
查看静态编译的模块
httpd -l
查看静态编译及动态装载的模块
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>中“基于源地址”实现访问控制
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的访问控制:
无明确授权的目录,默认拒绝
允许所有主机访问:Require all granted
拒绝所有主机访问:Require all denied
控制特定的IP访问:
Require ip IPADDR:授权指定来源的IP访问
Require not ip IPADDR:拒绝特定的IP访问
控制特定的主机访问:
Require host HOSTNAME:授权特定主机访问
Require not host HOSTNAME:拒绝
举例:.conf文件拒绝访问
不能有失败,至少有一个成功匹配才成功,即失败优先
<RequireAll>
Require all granted
Require not ip 172.16.1.1 拒绝特定IP
</RequireAll>
多个语句有一个成功,则成功,即成功优先
<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 基于用户的访问控制
认证质询:WWW-Authenticate:响应码为401,拒绝客户端请求,并说明要求客户端提供账号和密码
认证:Authorization:客户端用户填入账号和密码后再次发送请求报文;认证通过时,则服务器发送响应的资源
认证方式两种:
basic:明文
digest:消息摘要认证,兼容性差
安全域:需要用户认证后方能访问的路径;应该通过名称对其进行标识,以便于知用户认证的原因
用户的账号和密码
虚拟账号:仅用于访问某服务时用到的认证标识存储:文本文件,SQL数据库,ldap目录存储,nis等
提供账号和密码存储(文本文件)
使用专用命令完成此类文件的创建及用户管理
htpasswd [options] /PATH/HTTPD_PASSWD_FILE username
-c 自动创建文件,仅应该在文件不存在时使用
-p 明文密码
-d CRYPT格式加密,默认
-m md5格式加密
-s sha格式加密
-D 删除指定用户
举例:
basic认证配置示例:
方法1
在/etc/http/conf.d 下创建保存用户密码的文档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 弹出以下验证,输入密码后,正常显示网页
5.3.12 实现用户家目录的http共享
基于模块mod_userdir.so实现
相关设置:
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
当客户请求的网页并不存在时,服务器将产生错误文档,如果打开了ServerSignature选项,错误文档的最后一行将包含服务器的名字、Apache的版本等信息,如果不对外显示这些信息,就可以将这个参数设置为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 查看状态;
为保证安全性,需对登录的ip 进行限制,配置如下:
5.3.14 虚拟主机
有三种实现方案:
基于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 介绍
为解决安全问题,网景在1994年创建了HTTPS,并应用在网景导航者浏览器中。最初,HTTPS是与SSL一起使用的;在SSL逐渐演变到TLS时(其实两个是一个东西,只是名字不同而已),最新的HTTPS也由在2000年五月公布的RFC2818正式确定下来。HTTPS就是安全版的HTTP,目前大型网站基本实现全站HTTPS
HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费
HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的
HTTP和HTTPS使用的是不同的连接方式,端口不同,前者是80,后者是443
HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题
HTTPS 中的SSL握手等过程降低用户访问速度,但是只要经过合理优化和部署,HTTPS 对速度的影响完全可以接受
6.2 ssl
https:http over ssl
SSL会话的简化过程
(1) 客户端发送可供选择的加密方式,并向服务器请求证书
(2) 服务器端发送证书以及选定的加密方式给客户端
(3) 客户端取得证书并进行证书验证
如果信任给其发证书的CA
(a) 验证证书来源的合法性;用CA的公钥解密证书上数字签名
(b) 验证证书的内容的合法性:完整性验证
(c) 检查证书的有效期限
(d) 检查证书是否被吊销
(e) 证书中拥有者的名字,与访问的目标主机要一致
(4) 客户端生成临时会话密钥(对称密钥),并使用服务器端的公钥加密此数据发送给服务器,完成密钥交换
(5) 服务用此密钥加密用户请求的资源,响应给客户端
6.3 https实现
(1) 为服务器申请数字证书
测试:通过私建CA发证书
(a) 创建私有CA
(b) 在服务器创建证书签署请求
(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]
举例: 软件安转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签署证书,并将证书颁发给请求者
[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请求转发至https的URL
重定向
Redirect [status] URL-path URL
status状态:
Permanent: 返回永久重定向状态码 301
Temp:返回临时重定向状态码302. 此为默认值
示例:Redirect temp / https://www.magedu.com/
说明如下:
浏览器发起访问http://www.a.com
服务器重定向信息;
浏览器发起https://ww.a.com,对服务器访问
6.5 HSTS:HTTP Strict Transport Security
服务器端配置支持HSTS后,会在给浏览器返回的HTTP首部中携带HSTS字段。浏览器获取到该信息后,会将所有HTTP访问请求在内部做307跳转到HTTPS。而无需任何网络过程;
1)浏览器发起访问http://www.a.com
2)服务器返回HSTS 字段以及重定向信息;
3)浏览器缓存收到的重定向信息,当有访问http://www.a.com时直接调转到https://ww.a.com,对服务器发起访问
l
HSTS preload list
是Chrome浏览器中的HSTS预载入列表,在该列表中的网站,使用Chrome浏览器访问时,会自动转换成HTTPS。Firefox、Safari、Edge浏览器也会采用这个列表
实现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 协议报文分析
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: 请求方法,标明客户端希望服务器对资源执行的动作
GET、HEAD、POST等
version:
HTTP/<major>.<minor>
status:
三位数字,如200,301, 302, 404, 502; 标记请求处理过程中发生的情况
reason-phrase:
状态码所标记的状态的简要描述
headers:
每个请求或响应报文可包含任意个首部;每个首部都有首部名称,后面跟一个冒号,而后跟一个可选空格,接着是一个值
entity-body:请求时附加的数据或响应时附加的数据
Method 方法:
GET: 从服务器获取一个资源
HEAD: 只从服务器获取文档的响应首部
POST: 向服务器输入数据,通常会再由网关程序继续处理
PUT: 将请求的主体部分存储在服务器中,如上传文件
DELETE: 请求删除服务器上指定的文档
TRACE: 追踪请求到达服务器中间经过的代理服务器
OPTIONS:请求服务器返回对指定资源支持使用的请求方法
7.4 http协议首部
通用首部:请求报文和响应报文两方都会使用的首部
请求首部:从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、请求内容相关优先级等信息
响应首部:从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息
实体首部:针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的的信息
扩展首部
7.4.1 通用首部:
Date: 报文的创建时间
Connection:连接状态,如keep-alive, close
Via:显示报文经过的中间节点(代理,网关)
Cache-Control:控制缓存,如缓存时长
MIME-Version:发送端使用的MIME版本
Warning:错误通知
请求首部:
Accept:通知服务器自己可接受的媒体类型
Accept-Charset: 客户端可接受的字符集
Accept-Encoding:客户端可接受编码格式,如gzip
Accept-Language:客户端可接受的语言
Client-IP: 请求的客户端IP
Host: 请求的服务器名称和端口号
Referer:跳转至当前URI的前一个URL
User-Agent:客户端代理,浏览器版本
条件式请求首部:
Expect:允许客户端列出某请求所要求的服务器行为
If-Modified-Since:自从指定的时间之后,请求的资源是否发生过修改
If-Unmodified-Since:与上面相反
If-None-Match:本地缓存中存储的文档的ETag标签是否与服务器文档的
Etag不匹配
If-Match:与上面相反
安全请求首部:
Authorization:向服务器发送认证信息,如账号和密码
Cookie: 客户端向服务器发送cookie
代理请求首部:
Proxy-Authorization: 向代理服务器认证
7.4.2 响应首部:
信息性:
Age:从最初创建开始,响应持续时长
Server:服务器程序软件名称和版本
协商首部:某资源有多种表示方法时使用
Accept-Ranges:服务器可接受的请求范围类型
Vary:服务器查看的其它首部列表
安全响应首部:
Set-Cookie:向客户端设置cookie
WWW-Authenticate:来自服务器对客户端的质询列表
7.4.3 实体首部:
Allow: 列出对此资源实体可使用的请求方法
Location:告诉客户端真正的实体位于何处
Content-Encoding:对主体执行的编码
Content-Language:理解主体时最适合的语言
Content-Length: 主体的长度
Content-Location: 实体真正所处位置
Content-Type:主体的对象类型,如text
缓存相关:
ETag:实体的扩展标签
Expires:实体的过期时间
Last-Modified:最后一次修改的时间
7.4.4 解决http协议无状态方法
7.4.4.1 cookie
HTTP 是一种无状态协议。协议自身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。可是随着 Web 的不断发展,很多业务都需要对通信状态进行保存。于是引入了 Cookie 技术。使用 Cookie 的状态管理Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息;
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 适用对象的域名,若不指定则默认为创建Cookie的服务器的域名
Secure 仅在 HTTPS 安全通信时才会发送 Cookie
HttpOnly 加以限制使 Cookie 不能被 JavaScript 脚本访问
7.4.4.2cookie vs session
session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源;
通过cookie存储一个session_id,然后具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息