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。基本格式:
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.178linux.com/51818