HTTP服务和APACHE2
HTTP服务和APACHE2
知识点
- 请求报文响应报文
- 错误码
- 请求重定向
- 编译安装
- 实现https
- curl工具
1. http协议
-
http协议版本
http/0.9, http/1.0, http/1.1(较多), http/2.0(将来) -
http协议无状态
- stateless 无状态
服务器无法持续追踪访问者来源 - 解决http协议无状态方法
- cookie:客户端存放
- session:服务端存放
多服务器session解决方案- 在调度器中记录cookie的id,始终将其分配到第一次访问的服务器
- 让服务器之间复制session信息,每台服务器都存放所有服务器的session
- 搭专用的session服务器(用到redis),需要实现主从,提高容错
- stateless 无状态
-
协议查看或分析的工具
tcpdump,wireshark,tshark -
http事务一次访问的过程
-
请求:request
- HTTP请求报文图示
- request报文语法格式
<method> <request-URL> <version> <headers>
- HTTP请求报文图示
-
<entity-body>
- 1
- 2
- 3
- 4
响应:response
- HTTP响应报文图示
- response报文语法格式:
<version> <status> <reason-phrase> <headers>
<entity-body>
- 1
- 2
- 3
- 4
参数说明
- method (
获取服务器支持的动作curl -i -x OPTIONS
)
请求方法,标明客户端希望服务器对资源执行的动作GET、HEAD、POST等- GET:从服务器获取一个资源
- HEAD:只从服务器获取文档的响应首部,相当于
- POST:向服务器输入数据,通常会再由网关程序继续处理
- PUT:将请求的主体部分存储在服务器中,如上传文件
- DELETE:请求删除服务器上指定的文档
- TRACE:追踪请求到达服务器中间经过的代理服务器
- OPTIONS:请求服务器返回对指定资源支持使用的请求方法
- version
http协议版本:HTTP/<major>.<minor>
- status:
三位数字,如200,301, 302, 404, 502; 标记请求处理过程中发生的情况 - reason-phrase
状态码所标记的状态的简要描述 - headers
每个请求或响应报文可包含任意个首部;每个首部都有首部名称,后面跟一个冒号,而后跟一个可选空格,接着是一个值 - entity-body
请求时附加的数据或响应时附加的数据
http协议状态码(status)分类
- 1xx:100-101 信息提示
- 2xx:200-206 成功
- 200
成功,请求数据通过响应报文的entity-body部分发送;OK
- 200
- 3xx:300-305 重定向
- 301
请求的URL指向的资源已经被删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;Moved Permanently - 302
响应报文Location指明资源临时新位置 Moved Temporarily - 304
客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过响应此响应状态码通知客户端;客户端上有缓存,直接从缓存返回结果;Not Modified
- 301
- 4xx:400-415 错误类信息,客户端错误
- 401
需要输入账号和密码认证方能访问资源;Unauthorized - 403
请求被网站禁止,不是防火墙禁止访问;Forbidden - 404
服务器无法找到客户端请求的资源;Not Found
- 401
- 5xx:500-505 错误类信息,服务器端错误
- 500
服务器内部错误;Internal Server Error - 502
代理服务器从后端服务器收到了一条伪响应,如无法连接到网关;Bad Gateway - 503
服务不可用,临时服务器维护或过载,服务器无法处理请求 - 504
网关超时 Gateway Time-out
- 500
HTTP 首部字段(headers)
首部字段同时存在于请求和响应报文内,并涵盖 HTTP 报文相关的内容信息。使用首部字段是为了给客服端和服务器端提供报文主体大小、所使用的语言、认证信息等内容
- 首部字段结构
HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:”分隔,字段值对应单个 HTTP 首部字段可以有多个值
报文首部中出现了两个或以上具有相同首部字段名的首部字段时,在规范内尚未明确,根据浏览器内部处理逻辑的不同,优先处理的顺序可能不同,结果可能并不一致 - 首部的分类
-
通用首部
请求报文和响应报文两方都会使用的首部
-
首部字段 | 描述 |
---|---|
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 |
Cookie2 | 用于说明请求端支持的cookie版本 |
代理请求首部
首部字段 | 描述 |
---|---|
Proxy-Authorization | 向代理服务器认证 |
响应首部
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息
信息性
首部字段 | 描述 |
---|---|
Age | 从最初创建开始,响应持续时长 |
Server | 服务器程序软件名称和版本 |
协商首部:某资源有多种表示方法时使用
首部字段 | 描述 |
---|---|
Accept-Ranges | 服务器可接受的请求范围类型 |
Vary | 服务器查看的其它首部列表 |
安全响应首部:
首部字段 | 描述 |
---|---|
Set-Cookie | 向客户端设置cookie |
Set-Cookie2 | 以上面相似 |
WWW-Authenticate | 来自服务器对客户端的质询列表 |
实体首部
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的的信息
首部字段 | 描述 |
---|---|
Allow | 列出对此资源实体可使用的请求方法 |
Location | 告诉客户端真正的实体位于何处 |
Content-Encoding | 对主体执行的编码 |
Content-Language | 理解主体时最适合的语言 |
Content-Length | 主体的长度 |
Content-Location | 实体真正所处位置 |
Content-Type | 主体的对象类型,如text |
缓存相关:
首部字段 | 描述 |
---|---|
ETag | 实体的扩展标签 |
Expires | 实体的过期时间 |
Last-Modified | 最后一次修改的时间 |
扩展首部
HTTP 无状态及解决方案 Cookie
协议自身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。可是随着 Web 的不断发展,很多业务都需要对通信状态进行保存。于是引入了 Cookie 技术。
- Cookie 技术
使用 Cookie 的状态管理Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存Cookie。
当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息- cookie过期时间
- 会话cookie
生命期在浏览器会话期间,关闭浏览器此cookie就会消失,一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。 - 持久性cookie
若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间,存储在硬盘上的cookie可以在不同的浏览器进程间共享
- 会话cookie
- 安全性
- 隐患
在Web应用中,Cookie常用来标记用户或授权会话。因此,如果Web应用的Cookie被窃取,可能导致授权用户的会话受到攻击,例如跨站请求伪造(CSRF)跨站请求伪造(CSRF)
如在不安全聊天室或论坛上的一张图片,它实际上是一个给你银行服务器发送提现的
当你打开含有了这张图片的HTML页面时,如果你之前已经登录了你的银行帐号并且Cookie仍然有效(还没有其它验证步骤),你银行里的钱很可能会被自动转走。 - 应对方法
- 对用户输入进行过滤阻止XSS
- 任何敏感操作都需要确认
- 用于敏感信息的cookie只能拥有较短的生命期
- 隐患
- Set-Cookie首部字段
- 示例
Set-Cookie: status=enable; expires=Fri, 24 Nov 2017 20:30:02 GMT; path=/;
- 1
- 键值描述
- NAME=VALUE
赋予 Cookie 的名称和其值,此为必需项 - expires=DATE
Cookie 的有效期,若不明确指定则默认为浏览器关闭前为止 - path=PATH
将服务器上的文件目录作为Cookie的适用对象,若不指定则默认为文档所在的文件目录 - domain=域名
作为 Cookie 适用对象的域名,若不指定则默认为创建 Cookie的服务器的域名 - Secure
Cookie只应通过被HTTPS协议加密过的请求发送给服务端,因为Cookie有其固有的不安全性,敏感信息也不应该通过Cookie传输 - HttpOnly
加以限制使 Cookie 不能被 JavaScript 脚本访问
- NAME=VALUE
- cookie实现过程示例
安装php软件,提供httpd动态页面处理[root@hai7-6 conf]$yum install php
- 1
[root@hai7-6 html]$vim /var/www/html/setcookie.php <?php <==php语句块关键字 setcookie('title','cto'); <==setcookie为系统函数,用于设置cookie的键值对 setcookie('name','wang',time()+3600*12); <==time()为系统函数,表示当前时间,+3600*12表示有效期有12小时 ?>
- 1
- 2
- 3
- 4
- 5
http://192.168.50.107/setcookie.php
- 1
- 示例
- cookie过期时间
- 服务器端session
服务器端记录用户状态的机制,用户与服务器建立连接的同时,服务器会自动为其分配一个SessionId,此ID以cookie的键值形式发送给用户(key为JSSIONID,value为ID)
session用于存储用户会话所需的属性及配置信息,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去 - cookie和session区别
- cookie是存放在客户端,session存放在服务器
- cookie通常有大小限制(常见4k)以及数量限制(部分浏览器为20个),session大小和硬件有关,通常没有规定大小
2. curl工具和elinks工具
-
curl工具
基于URL语法在命令行方式下工作的文件传输工具,它支持FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE及LDAP等协议。
curl支持HTTPS认证,并且支持HTTP的POST、PUT等方法, FTP上传, kerberos认证,HTTP上传,代理服务器,cookies,用户名/密码认证, 下载文件断点续传,上载文件断点续传, http代理服务器管道( proxy tunneling),还支持IPv6,socks5代理服务器,通过http代理服务器上传文件到FTP服务器等,功能十分强大- 语法格式
curl [options] [URL…] - 常用选项
-A/--user-agent <string>
:设置用户代理发送给服务器1. 正常访问网站,会在日志文件中记录使用的浏览器 [root@hai6 ~]$curl http://192.168.50.107 在日志中显示的信息为 "curl/7.19.7 (x86_64-redhat-linux-gnu)" 2. 增加-A,指定浏览器为IE100 [root@hai6 ~]$curl -A 'IE100' http://192.168.50.107 在日志中显示的信息为 "IE100" ```
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-e/--referer <URL>
:来源网址,伪造跳转网站1. 在访问时增加-e,会伪造指定的跳转地址 [root@hai6 ~]$curl -A 'IE100' -e 'www.baidu.com' http://192.168.50.107 2. 在访问日志文件referer行就会添加www.baidu.com "www.baidu.com" "IE100"
- 1
- 2
- 3
- 4
--cacert <file>
: CA证书 (SSL)-k/--insecure
:允许忽略证书进行 SSL 连接--compressed
: 要求返回是压缩的格式,需要服务器端支持压缩-H/--header <line>
:自定义首部信息传递给服务器指定主机头HOST:www.a.com,实际访问的为www.c.com [root@hai6 ~]$curl -H "host: www.c.com" www.a.com
- 1
- 2
-i
:显示页面内容,包括报文首部信息-I/--head
: 只显示响应报文首部信息-D/--dump-header <file>
:将url的header信息存放在指定文件中--basic
: 使用HTTP基本认证-u/--user <user[:password]>
:设置服务器的用户和密码-L
:如果有3xx响应码,重新发请求到新位置1. '当访问网站被跳转时,使用curl正常访问只会返回网站被跳转信息' [root@hai6 ~]$curl www.taobao.com <p>The requested resource resides temporarily under a different URI.</p> 2. '加上-L会显示跳转后的页面' [root@hai6 ~]$curl -L www.taobao.com
- 1
- 2
- 3
- 4
- 5
-O
: 使用URL中默认的文件名保存文件到本地-o <file>
:将网络文件保存为指定的文件中,不可以下载二进制文件,可能会出错--limit-rate <rate>
: 设置传输速度-0/--http1.0
: 指定使用HTTP 1.0-v/--verbose
: 更详细-C
:选项可对文件使用断点续传功能-c/--cookie-jar <file name>
: 将url中cookie存放在指定文件中-x/--proxy <proxyhost[:port]>
:指定代理服务器地址-X/--request <command>
: 向服务器发送指定请求方法[root@hai6 ~]$curl -I -X OPTIONS 192.168.50.107 Allow: GET,HEAD,POST,OPTIONS,TRACE
- 1
- 2
-U/--proxy-user <user:password>
: 代理服务器用户和密码-T
: 选项可将指定的本地文件上传到FTP服务器上--data/-d
:方式指定使用POST方式传递数据-b name=data
: 从服务器响应set-cookie得到值,返回给服务器
- 语法格式
-
elinks工具
- 安装服务包
yum -y install elinks
- 1
- 语法格式
elinks [OPTION]… [URL]… - 参数
- -dump:非交互式模式,将URL的内容输出至标准输出
- -source:打印源码
- 安装服务包
3. mod_deflate模块
mod_deflate模块提供DEFLATE输出过滤器,运行在通过网络发送到客户端之前压缩来自服务器的输出
-
适用场景:
- 节约带宽,额外消耗CPU;同时,可能有些较老浏览器不支持
- 压缩适于压缩的资源,例如文本文件
-
可以压缩常见的基于文本的内容类型
AddOutputFilterByType DEFLATE |text/html |text/plain |text/xml |text/css |text/javascript| application/javascript|
- 1
-
查看模块是否已加载
[root@hai7-6 html]$httpd -M |grep deflate deflate_module (shared) <==加载状态
- 1
- 2
-
加载模块配置方法
LoadModule deflate_module modules/mod_deflate.so
-
将压缩限制为特定的MIME类型,使用AddOutputFilterByType指令
<Directory "/your-server-root/manual"> <==授权目录 AddOutputFilterByType DEFLATE text/html <==限定需要压缩的类型 </Directory>
- 1
- 2
- 3
-
压缩级别Level of compression (Highest 9 - Lowest 1)
DeflateCompressionLevel 9 -
排除特定旧版本的浏览器,不支持压缩
- Netscape 4.x 只压缩text/html
BrowserMatch ^Mozilla/4 gzip-only-text/html
- 1
- Netscape 4.06-08三个版本 不压缩
BrowserMatch ^Mozilla/4\.0[678] no-gzip
- 1
- Internet Explorer标识本身为“Mozilla / 4”,但实际上是能够处理请求的压缩。如果用户代理首部匹配字符串“MSIE”(“B”为单词边界”),就关闭之前定义的限制
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
- 1
- Netscape 4.x 只压缩text/html
-
示例:将text/html格式的文件输出时压缩压缩,配置如下
SetOutputFilter DEFLATE # Restrict compression to these MIME types AddOutputFilterByType DEFLATE text/html <==支持压缩的格式,可以自定义选择
- 1
- 2
- 3
4. 加密访问https(http over ssl)
Apache一个IP地址只支持一次加密,虚拟主机FQDN方式只能加密一个
-
SSL会话的简化过程
- 客户端发送可供选择的加密方式,并向服务器请求证书
- 服务器端发送证书以及选定的加密方式给客户端
- 客户端取得证书并进行证书验证(如果信任给其发证书的CA)
- 验证证书来源的合法性;用CA的公钥解密证书上数字签名
- 验证证书的内容的合法性:完整性验证
- 检查证书的有效期限
- 检查证书是否被吊销
- 证书中拥有者的名字,与访问的目标主机要一致
- 客户端生成临时会话密钥(对称密钥),并使用服务器端的公钥加密此数据发送给服务器,完成密钥交换
- 服务用此密钥加密用户请求的资源,响应给客户端
-
https实现过程
- 配置httpd支持使用ssl,及使用的证书,需要安装
mod_ssl
,使httpd支持加密模块[root@hai7115 ~]$yum -y install mod_ssl
- 1
- 搭建私有CA(在生产中是需要向权威机构申请证书的)
- 在预搭建CA主机A上申请私钥,必须放在 private/下,必须叫cakey.pem,因为有配置文件定义,所以要按规范写
进入CA目录 [root@hai7115 ~]$cd /etc/pki/CA [root@hai7115 CA]$(umask 077;openssl genrsa -out private/cakey.pem 2048)
- 1
- 2
- 3
- 自签名证书,生成的证书必须放在当前/etc/pki/CA目录
[root@hai7115 CA]$openssl req -new -x509 -key private/cakey.pem -out cacert.pem
- 1
- 创建颁发系列号
[root@hai7115 CA]$touch index.txt [root@hai7115 CA]$echo 01 > serial
- 1
- 2
- 在预搭建CA主机A上申请私钥,必须放在 private/下,必须叫cakey.pem,因为有配置文件定义,所以要按规范写
- http服务器B申请证书
- 在B主机上生成私钥,然后生成证书申请
生成证书申请文件 [root@hai7-6 ssl]$openssl req -new -key httpd.key -out httpd.csr
- 1
- 2
- 将文件拷贝到CA服务器
[root@hai7-6 ssl]$scp httpd.csr 192.168.50.115:/etc/pki/CA/
- 1
- CA服务器为B签名,签名后将证书发送给B
1. '为申请证书B签名' [root@hai7115 CA]$openssl ca -in httpd.csr -out certs/httpd.crt 2. '将客户端证书和CA证书一起发送给客户端' [root@hai7115 CA]$scp cacert.pem certs/httpd.crt 192.168.50.107:/etc/httpd/conf.d/ssl
- 1
- 2
- 3
- 4
- 在B主机上生成私钥,然后生成证书申请
- http服务器拿到证书后,实现https配置
- 客户端修改mod_ssl配置文件,重启服务
[root@hai7-6 ~]$vim /etc/httpd/conf.d/ssl.conf # Server Certificate: SSLCertificateFile /etc/httpd/conf.d/ssl/httpd.crt <==修改为申请的证书存放路径 # Server Private Key: SSLCertificateKeyFile /etc/httpd/conf.d/ssl/httpd.key <==修改为生成的私钥路径 # Certificate Authority (CA): SSLCACertificateFile /etc/httpd/conf.d/ssl/cacert.pem <==去掉注释,修改CA证书存放路径
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 重启服务
[root@hai7-6 conf.d]$systemctl restart httpd
- 1
- 客户端修改mod_ssl配置文件,重启服务
- 配置httpd支持使用ssl,及使用的证书,需要安装
-
测试基于https访问相应的主机
- 语法格式
openssl s_client [-connect host:port] [-cert filename] [-CApath directory] [-CAfile filename]
- 示例
- 通过CA证书测试目标地址证书信息
[root@hai7115 CA]$openssl s_client -connect 192.168.50.107:443 -CAfile cacert.pem
- 1
- 使用curl通过CA证书测试目标地址,cacert.pem为CA证书
[root@hai7115 CA]$curl --cacert cacert.pem https://www.moli.com
- 1
- 通过CA证书测试目标地址证书信息
- 语法格式
-
安装mod_ssl 时系统会通过脚本,生成默认的私钥和证书文件
查看生成默认私钥和证书的脚本 [root@hai7-6 conf]$rpm -q --scripts mod_ssl
- 1
- 2
5. http重定向https
将http请求转发至https的URL,https带来的问题是并发处理能力降低
-
在介绍内容前,先将http和https的网页做成不同的样式
- 新建一个目录,放https主页文件
1. '在/var/www/下创建ssl目录放https的页面文件' [root@hai7-6 www]$mkdir /var/www/ssl 2. '在ssl下创建一个页面文件index.html' root@hai7-6 www]$echo /var/www/ssl/index.html > /var/www/ssl/index.html
- 1
- 2
- 3
- 4
- 修改mod_ssl配置文件
[root@hai7-6 ssl]$vim /etc/httpd/conf.d/ssl.conf #DocumentRoot "/var/www/html" <==https默认的访问页面路径,可以修改 DocumentRoot "/var/www/ssl" <==新建一行以上项,修改为我们定义的https页面文件目录
- 1
- 2
- 3
- 新建一个目录,放https主页文件
-
实现重定向
- 配置命令
Redirect [status] URL-path URL - 参数
status状态:- Permanent
Returns a permanent redirect status (301) indicating that the resource has moved permanently - Temp
Returns a temporary redirect status (302). This is the default - 示例:
Redirect temp / https://192.168.50.107/
- Permanent
- 配置命令
-
实现跳转HTTPS示例
- 在http配置文件中加入跳转命令配置
[root@hai7-6 ~]$vim /etc/httpd/conf.d/text.conf Redirect temp / https://192.168.50.107 <==跳转配置,只要访问服务器根目录,自动跳转到https上
- 1
- 2
- 这样配置后,跳转到https后,会出现保存提示
ERR_TOO_MANY_REDIRECTS
,因为访问根就会跳转,所以跳转到https后,又一次访问192.168.50.107的根目录,再次跳转,解决此问题配置为如下内容1. '修改配置文件' [root@hai7-6 ~]$vim /etc/httpd/conf.d/text.conf RewriteEngine on <==启动RewriteEngine引擎 rewritecond %{SERVER_PORT} !^443 <==设置跳转条件,接口号非443才跳转 RewriteRule ^(/.*)$ https://%{HTTP_HOST}$1 [redirect=302] <==跳转到哪里 3. 重新启动服务 [root@hai7-6 conf.d]$systemctl restart httpd
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 在http配置文件中加入跳转命令配置
-
HSTS:HTTP Strict Transport Security
- 作用
HSTS可以用来抵御SSL剥离攻击,只要浏览器曾经与服务器创建过一次安全连接,之后浏览器会强制使用HTTPS,即使链接被换成了HTTPSSL剥离的实施方法是阻止浏览器与服务器创建HTTPS连接。它的前提是用户很少直接在地址栏输入https://,用户总是通过点击链接或3xx重定向,从HTTP页面进入HTTPS页面。所以攻击者可以在用户访问HTTP页面时替换所有https://开头的链接为http://,达到阻止HTTPS的目的
- HSTS实现过程
当客户端通过HTTPS向服务器XXX发出请求时,在服务器返回的超文本传输协议响应头中包含Strict-Transport-Security字段(非加密传输时设置的HSTS字段无效)
在STS字段中定义的时间内,客户端浏览器只要向服务器XXX发起请求,浏览器会在内部做3XX重定向跳转到HTTPS,而无需任何网络过程, - 不足之处
用户首次访问某网站是不受HSTS保护的,这是因为首次访问时,浏览器还未收到HSTS,所以仍有可能通过明文HTTP来访问 - 解决方案为HSTS preload list(HSTS预列表)
- HSTS preload list
此列表将世界上目前有的https网站都收录起来,载入到浏览器中,方便用户第一次访问网站时直接加密访问,是Chrome浏览器中的HSTS预载入列表,在该列表中的网站,使用Chrome浏览器访问时,会自动转换成HTTPS,Firefox、Safari、Edge浏览器也会采用这个列表 - 将HSTS信息加入到域名系统记录中
需要保证DNS的安全性,也就是需要部署域名系统安全扩展。截至2014年这一方案没有大规模部署
- HSTS preload list
- 作用
6. httpd自带的工具程序和压力测试工具
- httpd自带工具
- htpasswd
basic认证基于文件实现时,用到的账号密码文件生成工具 - apachectl
httpd自带的服务控制脚本,支持start和stop[root@hai7-6 ~]$apachectl stop [root@hai7-6 ~]$apachectl start
- 1
- 2
- rotatelogs
日志滚动工具,当系统文件过大时让其生成一个新的文件,可以确保日志的完整性
access.log -->
access.log, access.1.log -->
access.log, acccess.1.log, access.2.log
- htpasswd
- httpd的压力测试工具
- 常见测试工具
ab, webbench, http_load,seige,Jmeter (开源),Loadrunner (商业),tcpcopy(网易,复制生产环境中的真实请求,并将之保存) - ab工具介绍:来自httpd-tools包,不可以在线上做压测,在测试环境就测好了
正常压测过程中,打开一个网页不能超过3秒,测试结果的支持并发数按80%取
跨并发测试,每种压测至少要测3次以上,取平均值
ab测试只有参考价值,没有实际意义,因为只请求了一个URL
一个服务器如果对静态资源只能承载10000个,那么对于动态资源可能要少于1000- 语法格式
ab [OPTIONS] URL
- 常用参数
-n:总请求数
-c:模拟的并行数,每一个并发对应一个客户端,一个客户端就需要一个套接字,一个套接字对应一个文件,一个文件对应一个文件描述符,而linux默认一个程序打开的文件上限为1024个
-k:以持久连接模式测试 - 示例,测试条件超出系统范围解决方法
[root@hai7115 ~]$ab -c 1000 -n 1500 http://192.168.50.115/ socket: Too many open files (24)
- 1
- 2
1. '查看系统当前文件管理设置值' [root@hai7115 ~]$ulimit -a <==查询所有 [root@hai7115 ~]$ulimit -n <==查询单项 2. '调整值大小' [root@hai7115 ~]$ulimit -n 2000
- 1
- 2
- 3
- 4
- 5
- 示例,压测输出信息
- 语法格式
- 常见测试工具
[root@hai7-6 conf.d]$ab -c 50 -n 100 http://192.168.50.107/
….省略
Server Software: Apache/2.4.6 <==服务器程序版本号
Server Hostname: 192.168.50.107 <==请求的主机名称
Server Port: 80 <==服务器对应端口
Document Path: / <==压测时的URL
Document Length: 5 bytes <==URL对应相应内容的长度
Concurrency Level: 50 <==并发数
Time taken for tests: 0.023 seconds <==整体测试时间
Complete requests: 100 <==整体完成相应请求数
Failed requests: 0 <==错误的请求数
Write errors: 0 <==相应错误数
Total transferred: 27400 bytes <==整体字节数
HTML transferred: 500 bytes <==HTML占了多少内容,上面那个是带首部的总体大小
Requests per second: 4359.58 [#/sec] (mean) <==每秒处理请求数
Time per request: 11.469 [ms] (mean) <==平均每组请求所有时间
Time per request: 0.229 [ms] (mean, across all concurrent requests) <==每个请求平均用时
Transfer rate: 1166.53 [Kbytes/sec] received <==传输速率
Connection Times (ms)
min mean[+/-sd] median max
最少用时 平均值 中间值 最慢用时
Connect: 0 1 1.0 2 3
连接建立
Processing: 1 7 2.4 8 10
处理请求
Waiting: 1 7 2.5 8 10
等待将请求报文发送给客户端接收完成
Total: 4 8 1.8 9 12
整体完成
Percentage of the requests served within a certain time (ms)
50% 9
66% 9
75% 10
80% 10
90% 10
95% 11
98% 11
99% 12
100% 12 (longest request)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
7. httpd-2.4较2.2的改变
- 新增特性
- MPM支持运行为DSO机制;以模块形式按需加载
- event MPM生产环境可用
- 异步读写机制
- 支持每模块及每目录的单独日志级别定义
- 每请求相关的专用配置
- 增强版的表达式分析式
- 毫秒级持久连接时长定义
- 基于FQDN的虚拟主机不需要NameVirutalHost指令
- 新指令,AllowOverrideList
- 支持用户自定义变量
- 更低的内存消耗
- 修改了一些配置机制
不再支持使用Order, Deny, Allow来做基于IP的访问控制- 新模块
- mod_proxy_fcgi
支持FastCGI Protocol - mod_remoteip
用反向代理的IP地址代替远程客户机的IP - mod_ratelimit
提供带宽控制
- mod_proxy_fcgi
- 基于IP的访问控制:
- 无明确授权的目录,默认拒绝
- 允许所有主机访问:Require all granted
- 拒绝所有主机访问:Require all denied
- 控制特定的IP访问:
- 先授权指定来源的IP访问:Require ip IPADDR
- 再拒绝特定的IP访问:Require not ip IPADDR
- 控制特定的主机访问:
- 授权特定主机访问:Require host HOSTNAME
- 拒绝 HOSTNAME:Require not host HOSTNAME
- 特定主机:FQDN
- 指定域名下的所有主机:domin.tld
- 虚拟主机
基于FQDN的虚拟主机不再需要NameVirutalHost指令<VirtualHost *:80> ServerName www.b.net DocumentRoot "/apps/b.net/htdocs" <Directory "/apps/b.net/htdocs"> Options None AllowOverride None Require all granted </Directory> </VirtualHost>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- KeepAlive on
毫秒级持久连接时长定义
KeepAliveTimeout #ms
MaxKeepAliveRequests 100
- 新模块
8. Sendfile机制
- 不用 sendfile 的传统网络传输过程(需要经历4次I/O过程)
- 过程
- 网络I\O连接过程,通过网卡接收请求存放在网卡buffer,接收完成后发送给内核,暂存在内核buffer当中
- 内核解封装后找到监听端口,转发给进程
- 进程分析用户请求后,要通过内核读取磁盘拿到网页文件,也就是磁盘I/O过程
- 内核读取磁盘文件,需要将数据加载到内核的内存空间,加载完成后再发送个用户空间的进程(此过程很慢,进程将大量时间耗在等待)
- 应用程序进程处理数据,添加头部信息,形成新的回应报文,发送给内核,在通过网卡传回给用户
- 4次I/O
硬盘 >> kernel buffer >> user buffer >> kernel socket buffer >> 协议栈
一般网络应用通过读硬盘数据,写数据到 socket 来完成网络传输,底层执行过程:- 系统调用 read() 产生一个上下文切换:从 user mode 切换到 kernel mode,然后 DMA 执行拷贝,把文件数据从硬盘读到一个 kernel buffer 里。
- 数据从 kernel buffer 拷贝到 user buffer,然后系统调用 read() 返回,这时又产生一个上下文切换:从kernel mode 切换到 user mode
- 系统调用 write() 产生一个上下文切换:从 user mode 切换到 kernel mode,然后把步骤2读到 user buffer 的数据拷贝到 kernel buffer(数据第2次拷贝到 kernel buffer),不过这次是个不同的 kernel buffer,这个 buffer和 socket 相关联。
- 系统调用 write() 返回,产生一个上下文切换:从 kernel mode 切换到 user mode(第4次切换),然后DMA从 kernel buffer 拷贝数据到协议栈(第4次拷贝)
- 过程
- Sendfile机制
在kernel 2.0+ 版本中,系统调用 sendfile() 就是用来简化上面步骤提升性能的。sendfile() 不但能减少切换次数而且还能减少拷贝次数
用 sendfile() 来进行网络传输的过程:sendfile(socket, file, len)
硬盘 >> kernel buffer (快速拷贝到kernel socket buffer) >> 协议栈- 系统调用 sendfile() 通过 DMA 把硬盘数据拷贝到 kernel buffer,然后数据被 kernel 直接拷贝到另外一个与 socket 相关的 kernel buffer。这里没有 user mode 和 kernel mode 之间的切换,在 kernel 中直接完成了从一个 buffer 到另一个 buffer 的拷贝
- DMA 把数据从 kernel buffer 直接拷贝给协议栈,没有切换,也不需要数据从 user mode 拷贝到 kernel mode,因为数据就在 kernel 里
- 不支持Sendfile的场景
服务器上的数据是通过其他服务器获取的,也就是说用户访问的数据不在本机磁盘中
反向代理功能
- 启用反向代理
需要2个配置命令- 将客户端请求从服务器A转发到另一个服务器B
ProxyPass “/” “http://www.example.com/” - 服务器B将数据再转回给服务器A,由A来回应用户
ProxyPassReverse “/” “http://www.example.com/”
- 将客户端请求从服务器A转发到另一个服务器B
- 特定URL反向代理
ProxyPass “/images” “http://www.example.com/”
ProxyPassReverse “/images” http://www.example.com/
编译安装httpd-2.4
-
安装httpd-2.4需要的源码
- httpd-2.4源码:httpd-2.4.34.tar.bz2
- arp可移植运行库源码:apr-1.6.3.tar.gz、apr-util-1.6.1.tar.gz
-
安装前准备开发包:
- 开发环境包组:Development Tools,Server
- 依赖包:pcre-devel openssl-devel expat-devel
-
APR(Apache portable Run-time libraries,Apache可移植运行库)
- 作用
主要为上层的应用程序提供一个可以跨越多操作系统平台使用的底层支持接口库 - 为何开发
在早期的Apache版本中,应用程序本身必须能够处理各种具体操作系统平台的细节,并针对不同的平台调用不同的处理函数
随着Apache的进一步开发,Apache组织决定将这些通用的函数独立出来并发展成为一个新的项目。这样,APR的开发就从Apache中独立出来,Apache仅仅是使用 APR而已。目前APR主要还是由Apache使用,由于APR的较好的移植性,因此一些需要进行移植的C程序也开始使用APR,开源项目比如用于服务器压力测试的Flood loader tester,该项目不仅仅适用于Apache - 参考
http://httpd.apache.org/test/flood
- 作用
-
编译安装httpd-2.4方法
- 方法一,将内核与接口分别编译
- 编译安装apr-1.4+
- 进入apr解压目录:
cd apr-1.6.2
- 编译:./configure --prefix=/app/apr
- 构造并安装:make && make install
- 进入apr解压目录:
- 编译安装apr-util-1.4+
- 进入apr-util解压目录:cd …/apr-util-1.6.0
- 编译:./configure --prefix=/app/apr-util --with-apr=/app/apr/
- 构造并安装make -j 2 && make install
- 编译安装httpd-2.4
- 进入httpd解压目录:cd …/httpd-2.4.27
- 编译:./configure --prefix=/app/httpd24 --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/app/apr/ --with-apr-util=/app/apr-util/ --enable-modules=most --enable-mpms-shared=all --with-mpm=prefork
- 构造并安装:make -j 4 && make install
- 编译安装apr-1.4+
- 方法二,放在一起编译
- 安装开发包组
[root@hai7115 ~]$yum groupinstall "development tools"
- 1
- 安装依赖的程序包,以下这些为编译经验所得,可以在编译过程中发现查看安装
[root@hai7115 ~]$yum install pcre-devel openssl-devel expat-devel
- 1
- 官方下载httpd源码,以及依赖的apr包(apr-1.6.3.tar.gz、apr-util-1.6.1.tar.gz 、httpd-2.4.34.tar.bz2
),导入linux中,然后解压缩[root@hai7115 srcd]$tar xf apr-1.6.3.tar.gz [root@hai7115 srcd]$tar xf apr-util-1.6.1.tar.gz [root@hai7115 srcd]$tar xf httpd-2.4.34.tar.bz2
- 1
- 2
- 3
- 将apr和apr-util整个目录拷贝到httpd-2.4.34/srclib/目录下
[root@hai7115 srcd]$cp -r apr-1.6.3 httpd-2.4.34/srclib/apr [root@hai7115 srcd]$cp -r apr-util-1.6.1 httpd-2.4.34/srclib/apr-util
- 1
- 2
- 编译
'进入httpd解压后的目录,运行configure' ./configure\ --prefix=/app/httpd24\ --enable-so\ <==是否支持动态模块 --enable-ssl\ <==是否支持加密 --enable-cgi\ --enable-rewrite\ --with-zlib\ --with-pcre\ <==正则表达式 --with-included-apr\ <==表示已经将apr相关需要编译的内容放在httpd相关的路径下,可以一起编译 --enable-modules=most\ <==是否支持大部分模块 --enable-mpms-shared=all\ --with-mpm=prefork <==是否支持mpm的prefork工作模型
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 构造和安装
[root@hai7115 httpd-2.4.34]$make -j 8 && make install
- 1
- 配置环境变量,生效变量,启动程序
[root@hai7115 httpd-2.4.34]$echo PATH=/app/httpd24/bin:$PATH > /etc/profile.d/httpd.sh [root@hai7115 httpd-2.4.34]$. /etc/profile.d/httpd.sh
- 1
- 2
- 初始页面存放目录
[root@hai7115 htdocs]$cat /app/httpd24/htdocs/index.html <html><body><h1>It works!</h1></body></html>
- 1
- 2
- 设置开机启动,将其放在系统启动脚本中,给启动脚本加上执行权限
[root@hai7115 ~]$echo "/app/httpd24/bin/apachectl start" >> /etc/rc.d/rc.local [root@hai7115 ~]$chmod +x /etc/rc.d/rc.local
- 1
- 2
- 安装开发包组
- 方法一,将内核与接口分别编译
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-7f770a53f2.css" rel="stylesheet">
</div>