计算机网络通信模型有OSI参考模型和当前正在使用TCP/IP模型
从linux的角度看计算机网络的通信模型,物理层是通过硬件实现的,数据链路层是通过相关硬件的驱动程序实现的,网络层和传输层在内核中实现,应用层在用户空间实现。
应用层的重点是不同的程序实现特有的一些功能,TCP/IP的下三层更通用,重点是数据的传送
物理层提供设备到设备的通信,网络层提供主机到主机的通信,传输层为进程提供端到端的通信服务,传输层使用端口来区分各个进程,传输层使用的协议常用的有两种,TCP和UDP
网络通信实际上也是两个进程之间的通信,套接字(Socket)是进程通信的一种方式,允许位于不同主机的不同进程进行通信,套接字是进程间数据流的端点,以IP协议为通信基础的套接字称为网络套接字,以本地文件系统通信的套接字称为Unix Socket。
套接字有三种类型,一种是以TCP为基础的SOCK_STREAM,一种是以UDP为基础的SOCK_DGRAM,还有一种直接以IP为基础的raw socket
IANA将0-1023的端口已经永久分配给固定的应用使用,叫做特权端口;1024-41951范围内的端口也是由IANA进行注册的端口,但要求不严格,可分配给开发者注册为某应用使用;41952之后的端口是客户端随机使用的端口,也叫做动态端口或私有端口,其范围由/proc/sys/ipv4/ip_local_port_range文件定义。
客户端和服务端组成一组套接字,服务端使用固定的端口监听,客户端使用随机端口。
Socket Domain根据所使用的地址不同,Socket分为AF_INET、AF_INET6、AF_UNIX。
- AF_INET
- AF_INET6
- AF_UNIX:同一主机上不同的进程通信时使用
每类套接字都至少提供了两种Socket数据传输机制:流和数据报。流可以可靠地传递并且是面向连接的,而且是无边界的;数据报是不可靠地传递,报文有边界、无连接。
与套接字相关的系统调用有
- socket():创建套接字
- bind():绑定套接字
- listen():监听套接字
- accept():接受请求
- connect():请求连接建立
- write():发送
- read():接收
超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上广泛使用的协议,提供了一种发布和接收HTML页面的方法。通过HTTP或HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。
C/S架构是一种网络架构,分为客户端和服务端,客户端和服务端要使用相同的协议才可以正常的通信,C/S架构最常见的就是在互联网所浏览的网页,使用的http协议,监听在tcp80端口,用来传输使用html标记的文件,http的客户端多数是浏览器(browser),服务端是http server。
多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions)的引入使html可以支持多媒体,服务端将非文本格式的数据编码为文本数据,客户端将文本数据还原为非文本格式的数据。
HTTP请求对象的内容叫做web资源(web resource),静态文件是最基本的资源,如文本、音频、视频。web资源也有动态资源,如php、jsp。一个页面中展示的资源可能有多个;每个资源都需要单独请求。
资源(媒体)有类型,又称为MIME类型,有主类型和次类型major/minor,如text/html、text/plain、image/gif、video/mpeg。
每个资源的唯一标识符叫做URL,URL是统一资源定位符,是URI的子集,URI是统一资源标识符。URL用于描述某服务器特定资源的位置
URL(Uniform Resource Locator),由三部分组成:URL方案scheme、服务器地址ip:port、资源路径。
URL一般格式:<scheme>://<user>:<password>@<host>:<port>/<path>;<params=>?<query=>#<frag>
URL分为绝对URL和相对URL
http协议的版本
- HTTP/0.9:原型版本
- HTTP/1.0:第一个广泛使用的版本,支持MIME,有缓存缺陷,支持keep-alive
- HTTP/1.1:广泛使用的版本,更多的请求方法,更精细的缓存控制,支持持久连接
- HTTP/2.0:与2015年5月作为互联网标准正式发布
一次完整的HTTP请求处理过程
1、建立或处理连接:接收或拒绝请求
2、接收请求:接收来自于来自于网络请求报文中对某一资源的一次请求过程
3、处理请求:对请求报文进行解析,并获得请求的资源及请求方法等相关信息。请求报文的首部有请求方法、url、请求主机名称、Connection等
4、访问资源:获取请求报文中请求的资源。web服务器即存放了web资源的服务器,负责像请求者提供对方请求的静态资源或动态运行后生成的资源,这些资源放置于本地文件系统某路径下,此路径通常称为DocRoot
5、构建响应报文:
标记资源的MIME类型:显示分类、魔法分类、协商分类
web服务器构建的响应并非客户端请求的资源,而是向客户端提供资源的另外一个访问路径,这叫做URL重定向
6、发送响应报文
7、记录日志
web服务端接收请求时的并发访问模型(web i/o)
- 单进程IO结构:启动一个进程处理用户请求,而且一次只处理一个;多个请求被串行响应;
- 多进程IO结构:启动多个进程,每个进程响应一个请求
- 复用IO结构:一个进程响应多个请求
- 多线程模型:一个进程生成多个线程,每个线程响应一个用户请求;对于Linux而言进程和线程响应量级相似
- event-driven:事件驱动,一个进程直接响应N个请求
- 复用多线程IO结构:启动多个线程,每个线程响应多个请求
服务端资源映射方式
- Docroot
- 路径别名
- 虚拟主机Docroot映射
- 用户家目录docroot映射
HTTP报文
一次请求以及与其对应的响应被称为http的事务,http一种无状态(stateless)协议,一次http事务结束后,连接断开,服务器无法持续追踪客访问者来源,所以引入了cookie和session机制来追踪同一个用户
每请求一个资源都需要tcp三次握手,效率十分低下,使用并行请求或保持连接来提高效率。保持连接有两个条件触发断开保持连接,限制时间或请求资源数。
http方法:GET、put、head、post、delete
http请求:request请求报文
<method> <request-url> <version> #起始行(请求行)
<headers>
<entity-body>
http响应:response响应报文
<vsesion> <status> <reson-phrase> #起始行(响应行)
<headers>
<entity-body>
<method>:请求方法,标明客户端希望服务器对资源执行的动作。常用的有GET、HEAD、POST
- GET:请求从服务器获取一个资源,安全方法
- HEAD:只从服务器获取文档的响应首部,不需要发送资源,安全方法
- POST:向服务器发送要处理的数据,支持html表单提交
- PUT:将请求的主体部分存储在服务器上
- DELETE:请求删除服务器上指定的文档
- TRACE:追踪请求到达服务器中间经过的代理服务器
- OPTIONS:请求服务器返回对指定资源支持使用的请求方法
<request-url>:请求的资源,可以使相对路径,也可以是完整的URL
<version>:协议版本,格式为HTTP/<major>.<minor>,如http/1.1
<headers>:每个请求或响应报文可包含多个首部,每个首部都有首部名称,后面跟一个冒号,而后跟上一个可选空格,接着是一个值
- 通用首部:请求和相应都可以使用
- Connection:定义C/S之间关于请求/响应的有关选项,如在http/1.0中,Connection:keep-alive
- Via:显示了报文经过的中间节点
- Cache-Control:缓存控制
- Date:报文的创建时间
- 请求首部
- Client-IP:客户端IP。下四层的信息由内核处理,IP被拆掉,实际上也有其他方法获取客户端IP
- Host:请求的主机名和端口号。虚拟主机环境下用于标识不同的虚拟主机
- Referer:指明了当前请求的资源是从何处来的,包含当前正在请求的资源的上一级资源。如防盗链,投放广告效果分析
- User-Agent:用户代理,使用什么工具发出的请求
- Accept:通知服务器自己可以接受的媒体类型,标明客户端更倾向于使用的方式
- Accept:指明服务器能发送的媒体类型
- Accept-Charset:支持使用的字符集
- Accept-Encoding:支持使用的编码方式,如gzip
- Accept-Language:支持使用的语言
- 条件请求
- Expect
- If-Modified-Since:是否在指定的时间后修改过此资源
- If-None-Match:本地缓存中存储的文档的ETag标签是否与服务器文档的Etag不匹配
- 安全相关
- Authorization:客户端提交给服务端的认证数据,如账号和密码
- Cookie/Cookie2:客户端发送给服务端的身份标识
- 代理请求首部
- Proxy-Authorization:向代理服务器认证
- 响应首部
- 信息性首部
- Age:响应持续的时间
- Server:向客户端标明服务器程序名称、版本
- 协商首部:某资源有多种表示方法时使用
- Accept-Ranges:对当前资源来讲,服务器能够接受的范围类型
- Vary:首部列表,服务器会根据列表中的内容,挑选出适合的版本发送给客户端
- 安全相关
- Set-Cookie/Cookie2:在客户端第一次请求时,服务端发送的令牌
- WWW-Authentication:质询,要求客户端提供账号和密码
- 信息性首部
- 实体首部:用于指定实体部分的属性
- Location:资源的新位置
- Allow:允许对此资源使用的请求方法
- 内容首部
- Content-Encoding
- Content-Language
- Content-Lentgth
- Content-Location
- Content-Type
- 缓存首部
- ETag:实体标签
- Expires:过期期限
- Last-Modified:上一次的修改时间
- 扩展首部:非标准 首部,可能由程序开发者创建的。
<status>:状态码,三位数字,如200、404、502,标记请求处理过程中发生情况
- 1xx:100-101, 信息提示状态码
- 2xx:200-206, 成功状态码
- 200:成功,请求的所有数据通过响应报文的entity-body部分发送。简要描述为OK
- 3xx:300-305(?307), 重定向状态码
- 301:请求URL指向的资源已被删除,在响应报文中通过首部location指明了资源现在所处的位置。简要描述为Move permanently
- 302:与301相似,在响应报文中通过location指明了资源现在所处的临时位置。简要描述为Found
- 304:客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过此状态码告知客户端。简要描述为Not Modified
- 4xx:400-415, 错误类信息,客户端错误
- 401:需要输入帐号和密码认证,方能访问资源。简要描述为unauthorized
- 403:请求被禁止。简要描述为Forbidden
- 404:服务器无法找到客户端请求的资源。简要描述为Not Found
- 405:Method Not Allowed
- 5xx:500-505, 错误类信息,服务器端错误
- 500:服务器内部错误。简要描述为internal Server Error
- 502:代理服务器从后端服务器收到了一条伪响应。简要描述为Bad Gateway
- 503:ServiceUnavailable
<reson-phrase>:原因短语,解释状态码
<entity-body>:主体部分
http协议分析可以使用tcpdump、tshark和wireshark等抓包分析工具
常见的web服务器程序有httpd、nginx、Lighttpd,还有一些应用程序服务器(APP Server),可以返回动态内容,如ISS、tomcat、jboss、resin、webshpere、weblogic、oc4j。
美国的机构会定期统计各web服务程序在市场的占有率
httpd的版本主要有2.0、2.2、2.4,在CentOS 6默认提供的版本是2.2,CentOS 7默认提供的是2.4
httpd的特性
-
高度模块化:由core和各种modules组成
-
DSO(Dynamic Shared Object)机制:支持模块的动态装卸载
-
MPM(Multipath-Processing Modules)机制:多路处理模块 ,非一个模块,是一种机制
最常见的有下面三个模块:(面试必问,对三个模块形成文字总结,分析各方面的优劣)
-
prefork模块:多进程模型,每个进程响应一个请求。
主进程负责接收请求但不处理请求,一个主进程负责生成多个子进程以及回收子进程,每个子进程处理一个用户请求,即便没有用户请求,也会预先生成多个空闲进程,随时等待请求到达,并发请求最大不会超过1024个。
-
worker:多线程模型,每个线程相应一个请求。一个主进程生成多个子进程,,每个子进程生成多个线程,每个线程响应一个请求;
-
event:事件驱动模型,单线程响应多个请求。一个主进程生成m个线程,每个线程相应n个请求;
-
httpd的功能特性
- 支持虚拟主机virtual host
- CGI(Common Gateway Interface)通用网关接口
- 反向代理
- 支持负载均衡
- 支持路径别名alias
- 丰富的用户认证机制authentication
- 支持第三方模块。
使用httpd -l可以查看编译到server的模块,不包含DSO模块
mod_so.c表示启用DSO机制,prefork.c表示使用MPM中的prefork模式。在httpd2.2编译时,只能编译一种MPM,编译后不能修改。如果想要使用MPM中的worker机制,要使用httpd.worker来启动httpd。在服务脚本/etc/sysconfig/httpd中可以定义默认启动httpd的类型,HTTPD=/usr/sbin/httpd.worker。
在CentOS 6中,rpm包默认提供的是httpd2.2
使用rpm包安装后的http的目录结构
- httpd主目录、网站根目录:/etc/httpd
- 主配置文件:/etc/httpd/conf/httpd.conf
- 补充配置文件:/etc/httpd/conf.d/
- 服务脚本:/etc/rc.d/init.d/httpd
- 服务脚本的配置文件:/etc/sysconfig/httpd
- 主程序:/usr/sbin/httpd、/usr/sbin/httpd.event、/usr/sbin/httpd.worker
- 日志文件:/var/log/httpd,日志文件有两个,一个是access_log访问日志,另外一个是error_log错误日志文件
- DocRoot文档根目录:/var/www/html
- CGI目录:/var/www/cgi-bin
- httpd的模块文件:/usr/lib64/httpd/modules
启动httpd服务时,会对当前的ip地址进行反向解析,如果反向解析的结果和当前的主机名不对应是会报错。实验中可以编辑/etc/host是ip地址和主机名对应。
使用ss -tnlp检查服务的80端口是否监听
主进程的属主是root,工作进程的属主是普通用户apache,因为要在内核中注册使用小于1023的端口,只有管理员有权限, 主进程不响应请求,工作进程响应。
httpd的主配置文件有三部分组成,分为了三个Section,第二段和第三段不要同时使用
Section 1:Global Environment
Section 2:‘Main’ server configuration #主机配置,用于仅提供一个站点时使用
Section 3:Virtual Hosts
一般格式是 directive value,directive不区分大小写,value是文件路径时取决于文件系统。
配置文件语法测试:service httpd configtest或httpd -t,绝大多数的配置修改后,可以通过service httpd reload来生效,如果修改了监听端口的地址或端口,必须要重启服务才能生效
-
Listen [IP:]PORT
监听的地址和端口
ip地址可以省略,表示监听所有ip地址
可以使用多条Listen,用于指定监听多个不同的套接字
-
KeepAlive On|Off
是否开启保持连接
开启后,要设置 MaxKeepAliveRequest和KeepAliveTimeout的值,时间的默认单位是秒
每个资源获取完后不会立即断开连接,而是继续等待其他资源请求 对并发访问量较大的服务器,持久连接可能会使一些访问请求得不到响应 一个折中的解决方案就是使用较短的持久连接时间,在2.4中可以支持毫秒级持久时间 使用数量限制来断开持久连接:默认为100个 使用时间限制来断开持久连接:可配置,单位是秒
测试持久连接: telnet HOST PORT GET /URL HTTP/1.1 HOST:HOSTNAME|IP
-
MPM
http2.2不支持同时编译多个模块,在编译时只能选择一个,rpm安装的包提供了三个二进制程序文件,分别实现了对不同mpm机制的支持。
使用ps -aux | grep httpd,可以查看运行的httpd的类型,默认运行的是/usr/sbin/httpd,使用的是prefork
使用ps命令查看的httpd类型加上-l 查看在核心中静态编译的模块
使用httpd -M显示当前httpd加载的所有模块(静态编译+动态装载模块)
更换使用的httpd程序:编辑脚本配置文件/etc/sysconfig/httpd中HTTPD=...
在配置文件中使用
<IfModule MODULE>...</IfModule>
来判断运行的模块,如果匹配,参数即生效。- StartServers:number of server processes to start 默认启动的工作进程数
- MinSpareServers:minimum number of server processes which are kept spare最少空闲进程数
- MaxSpareServers:maximum number of server processes which are kept spare最大空闲进程数
- ServerLimit:maximum value for MaxClients for the lifetime of the server最大活动进程数
- MaxClients:maximum number of server processes allowed to start并发请求的最大数,要小于等于ServerLimit
- MaxRequestsPerChild:maximum number of requests a server process serves每个子进程在生命周期内所能服务的最多请求个数。达到指定的数值后杀死进程,重新生成新的进程,当然如果一个子进程在重复使用没有问题的情况下,可以将数值调大。
- StartServers: initial number of server processes to start启动的子进程数
- MaxClients: maximum number of simultaneous client connections并发请求的最大数
- MinSpareThreads: minimum number of worker threads which are kept spare最小空闲进程数
- MaxSpareThreads: maximum number of worker threads which are kept spare最大空闲线程数
- ThreadsPerChild: constant number of worker threads in each server process每个子进程生成的线程数
- MaxRequestsPerChild: maximum number of requests a server process serves每个子进程在生命周期内所能服务的最多请求个数。0表示不限定
-
DSO
DSO机制在配置文件中使用LoadModule来指定加载的模块
LoadModule <mod_name> <mod_path>
模块路径可以使用相对路径,相对路径是相当于ServerRoot(/etc/httpd)指向的路径而言。
/etc/httpd/modules是一个符号链接指向了模块的目录
使用httpd -M可以查看所有加载的DSO模块以及非DSO模块
-
DocumentRoot
定义'Main' Server的文档页面根路径
DocumentRoot指向的路径为URL路径的起始位置
使用<Directory "/path/to/somewhere"> </Direcotry> ,可以对DocumentRoot下的目录进行属性的定义。
也可以使用<Directory ~ "regexpress"> </Direcotry>,启用正则表达式,速度慢
也可以使用<Location "URL"></Location>可以基于URL配置属性定义。如果某要配置其属性的URL能映射到某具体文件系统路径,建议使用Directory。
-
页面访问属性和访问控制
-
Options Indexs|FollowSysLinks|None|All|...
-
Indexs:缺少指定的默认页面时,允许将目录中的所有文件以列表形式返回给用户。危险!
-
FollowSysLinks:允许访问符号链接所指向的原始文件
-
None:所有的选项都不启用
-
All:所有的都启用
-
ExecCGI:允许使用mod_cgi模块执行CGI脚本
-
Includes:允许使用mod_include模块实现服务器端包含(SSI)
-
Multiviews:允许使用mod_negotiation实现内容协商
-
SysLinksIfOwnerMatch:在链接文件属主属组域原始文件的属主属组相同时,允许访问符号链接所指向的原始文件
-
-
AllowOverride None| ALL|Options|FileInfo|Limit|...:是否允许覆盖下面的三个选项,None表示不禁用
-
Order、Allow、Deny
Order Deny,Allow:默认Allow,除了指定Deny的--黑名单
Order Allow,Deny:没有Allow的,都Deny--白名单
二者都能匹配到或者都没有匹配到都以默认规则,即后者定义的行为。单个匹配到的,就按匹配的规则执行Deny或Allow
基于主机的访问控制可以使用IP、Network Address定制规则
-
基于用户的访问控制
安全域:需要用户认证后方能访问的路径。每个安全域应该通过名称对其进行标识,并用于告知用户认证的原因
用户的帐号和密码使用的虚拟账号,仅用于访问某服务时用到的认证标识。
认证质询:WWW-Authenticate,响应码为401,拒绝客户端请求,并说明要求客户端提供帐号和密码
认证:Authorization,客户端用户填入账号和密码后再次发送请求报文。认证通过服务端发送响应资源
这里的用户并不是系统真正的用户,而是在获取服务端一些资源时为了验证身份而设置的虚拟用户。
认证类型有两种,一种是basic认证,一种是digest认证。basic认证帐号和密码是明文发送的,digest认证将帐号密码hash编码后发送,但很多浏览器不支持digest认证,大部分浏览器使用的basic认证。在模块中是以auth_开头的模块,共有两个。
认证提供者(authentication provider)是帐号和密码的存放位置,在模块中以authn_开头
授权机制(Authorization)用来定义根据什么授权,在模块中以authz_开头
根据用户和组进行授权,基于文件,做基本认证
- 在httpd的配置文件配置要认证的目录,对/var/www/html/admin目录要求进行认证登录
<Directory "/var/www/html/admin"> Optinos None AllowOverride AuthConfig AuthType Basic #认证类型 AuthName "Private Area" #质询时弹出窗口的提示信息 AuthBasicProvider file #可省略,下面一条就说明了使用File AuthUserFile /etc/httpd/conf/.htpasswd # Require valid-user|tom,simon #valid-user允许账号文件中的所有用户登录访问 </Directory> 也可以基于组认证 <Directory ""> Options None AllowOverride AuthConfig AuthType Basic AuthName "STRING" AuthUserFile "/PATH/TO/HTTPD_USER_PASSWD_FILE" AuthGroupFile "/PATH/TO/HTTPD_GROUP_FILE" Require group GROUP1 GROUP2 ... </Directory>
-
使用htpasswd命令创建AuthUserFile
在没有密码文件时,使用htpasswd -c -m PASSWDFILE USERNAME。-c是创建文件,-m是使用md5将密码加密存放,-s 使用sha1加密用户密码,-D 删除指定用户
组文件手动创建,每一行定义一个组。组文件的格式:组名:User1 User2 User3
-
-
DirectoryIndex
定义默认主页面,页面文件可以有多个,会自左向右查找第一个找到的页面
-
Userdir disabled|public_html
用户目录,如果期望让Linux每个用户都可以创建个人站点
public_htm是用户家目录下的目录名称,所有位于此目录中的文件都可以通过http://Server_IP/~Username/进行访问,用户的家目录得赋予httpd进程的用户拥有执行权限。
-
CustomLog和ErrorLog
httpd有两种日志,一个是access.log访问日志,记录的内容需要自定义,一个是error.log错误日志
设定写入日志级别LogLevel warn
日志级别由低到高:debug, info, notice, warn, error, crit, alert, emerg
CustomLog定义访问日志的文件路径,需要指定日志路径和LogFormat日志格式
定义好的日志格式,可以使用一个名称进行识别,使用CustomLog制定日志格式时使用定义的名称即可,默认使用的是combined
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
%h:Remote Host客户端IP地址 %l: Remote logname (from identd, if supplied),远程登录名,-表示为空 %u: Remote user, (from auth; may be bogus if return status (%s) is 401)。认证时的远程用户名,-表示为空 %t:Time the request was received (standard english format),服务器收到请求的时间 %r:First line of request,请求报文的首行信息(method url version) %>s: 响应状态码 %b: 响应报文的长度,单位是字节,不包括响应报文首部 %{Referer}i:请求报文当中"referer"首部的值;当前资源的访问入口,即从哪个页面中的超链接跳转而来的 %{Header_Name}i:记录指定请求报文首部的内容 %{User-Agent}i:请求报文当中"User-Agent"首部的值;即发出请求用到的应用程序,通常是浏览器,也可是压力测试工具,或是爬虫工具 官方文档:http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats
ErrorLog指定错误日志的位置
-
Alias路径别名
使用路径别名可以访问不在DocumentRoot目录下的文件,使用Alias /目录/ "/var/www/A/"
如:Alias /bbs/ "/forum/htdocs"
http://www.jsp.com/bbs/index.html 使用别名后,文件在/forum/htdocs
-
AddDefaultCharset
指定使用的默认字符集
-
ScriptAlias
CGI脚本路径别名
CGI是通用网关接口协议,当用户请求的是非静态资源时,httpd会使用CGI协议调用其他程序,将运行后的结果返回给用户,CGI的实现有一些问题,需要使用SUID和SGID,是危险操作。目前与前端通信时,php使用SAPI机制,pyton使用UWCGI机制。
并非所有的CGI脚本都能被httpd识别,只有由ScriptAlias所定义的脚本别名路径下的文档才能被当作CGI,由mod_cgi、mod_alias获取后执行。
使用CGI返回结果要使用URLhttp://hostname/cgi-bin/a_script
-
虚拟主机
虚拟主机可以在一台物理主机上架设多个站点
区分虚拟主机可以基于不同的IP、不同的端口、以及FQDN
- 基于ip:为每个虚拟机准备至少一个ip地址
- 基于port:为每个虚拟主机准备至少一个专用port,实践中很少使用
- 基于FQDN:为每个虚拟主机准备至少一个专用hostname。在请求首部可以看到请求的Hostname
可混合使用上述三种方式中的任意方式
一般虚拟主机不要和Main server混用,所以,要使用虚拟主机,先禁用中心主机:注释DocumentRoot
在启用虚拟主机的情况下,如果客户端请求的URL是物理主机的ip地址,httpd则会将配置文件的第一虚拟主机返回给客户端,当然可以定义默认的虚拟主机。
三种虚拟主机的方法可以混合使用,大部分用在中心主机的配置都可以在虚拟主机中使用
基于ip
<VirtualHost 172.16.100.6:80> ServerName web1.jsp.com DocumentRoot "/vhosts/web1/htdocs" <Directory " "> options None </Directory> CustomLog ...... combined </VirtualHost> <VirtualHost 172.16.100.7:80> ServerName web2.jsp.com DocumentRoot "/vhosts/web2/htdocs" CustomLog ...... combined </VirtualHost>
基于port
<VirtualHost 172.16.100.7:80> ServerName web2.jsp.com DocumentRoot "/vhosts/web2/htdocs" CustomLog ...... combined </VirtualHost> <VirtualHost 172.16.100.7:8080> ServerName web3.jsp.com DocumentRoot "/vhosts/web3/htdocs" CustomLog ...... combined </VirtualHost>
基于FQDN
在httpd2.2中,使用FQDN方式的虚拟主机,要在配置文件中将NameVirtualHost *:80启用,并且虚拟主机的定义格式与NameVirtualHost的格式保持一致
NameVirtualHost 172.16.100.6:80 <VirtualHost 172.16.100.6:80> ServerName web1.jsp.com DocumentRoot "/vhosts/web1/htdocs" CustomLog ...... combined </VirtualHost> <VirtualHost 172.16.100.6:80> ServerName web2.jsp.com DocumentRoot "/vhosts/web2/htdocs" CustomLog ...... combined </VirtualHost> <VirtualHost 172.16.100.6:80> ServerName web3.jsp.com DocumentRoot "/vhosts/web3/htdocs" CustomLog ...... combined </VirtualHost>
-
服务器status页面
status页面可以通过web页面进行显示,status只能使用Location进行定义,因为status在文件系统中没有文件。
在apache中有很多处理器,当文件被调用时,apache在内部的表现形式,一般来说,每种类型都有其隐式处理器。status页面信息需要指定处理器,需要加载模块status_mod,显示定义使用的处理器SetHandler
<Location /server-status> SetHandler server-status AuthType Basic AuthUserFile "/etc/httpd/conf/.htpasswd" Require valid-user Order deny,allow Allow from all </Location>
完成水平:不看笔记独立完成所有配置,包括https。
http是明文传输的,要加密传输报文,需要借助于ssl/tls,对内容进行加密。
http是文本协议,https是二进制格式的协议,数据加密后是二进制编码。https监听在tcp/443端口,ssl会话是基于ip地址的,所以不支持基于FQDN的虚拟主机上实现。httpd基于mod_ssl模块实现对ssl的支持
SSL会话的简化过程
(1) 客户端发送可供选择的加密方式,并向服务器请求证书;
(2) 服务器端发送证书以及选定的加密方式给客户端;
(3) 客户端取得证书并进行证书验正:
如果信任给其发证书的CA:
(a) 验正证书来源的合法性;用CA的公钥解密证书上数字签名; (b) 验正证书的内容的合法性:完整性验正 (c) 检查证书的有效期限; (d) 检查证书是否被吊销; (e) 证书中拥有者的名字,与访问的目标主机要一致;
(4) 客户端生成临时会话密钥(对称密钥),并使用服务器端的公钥加密此数据发送给服务器,完成密钥交换; (5) 服务用此密钥加密用户请求的资源,响应给客户端;
客户端验证服务端证书
- 日期检测:验证证书是否在有效期内
- 证书颁发者可信度检测:验证证书颁发者的可信度
- 证书签名检测:验证证书的签名是否可信
- 持有者身份检测:验证请求地址和持有者的地址是否一致
生成私有证书
[root@4fc6vm ~]# cd /etc/pki/CA
[root@4fc6vm CA]# (umask 077; openssl genrsa 2048 > private/cakey.pem)
Generating RSA private key, 2048 bit long modulus
..............................................................................+++
........................+++
e is 65537 (0x10001)
[root@4fc6vm CA]# ls -l private/
total 4
-rw-------. 1 root root 1679 Jun 13 10:12 cakey.pem
修改/etc/pki/tls/openssl.cnf文件,修改默认参数如国家省份等,生成证书时,就不需要多次填写
生成自签署证书
[root@4fc6vm CA]# openssl req -new -x509 -key private/cakey.pem -days 3655 -out cacert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [JiangSu]:
Locality Name (eg, city) [Nanjing]:
Organization Name (eg, company) [JSP Company Ltd]:
Organizational Unit Name (eg, section) [LinuxOP]:
Common Name (eg, your name or your server's hostname) []:ca.jsp.com
Email Address []:[email protected]
[root@4fc6vm CA]# ls
cacert.pem certs crl newcerts private
生成服务器私钥httpd.key
[root@4fc6vm ~]# cd /etc/httpd/conf
[root@4fc6vm conf]# mkdir ssl
[root@4fc6vm conf]# cd ssl
[root@4fc6vm ssl]# (umask 077;openssl genrsa 1024 > httpd.key)
Generating RSA private key, 1024 bit long modulus
..............++++++
..................................................................++++++
e is 65537 (0x10001)
生成证书签署请求httpd.csr
[root@4fc6vm ssl]# openssl req -new -key httpd.key -out httd.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [JiangSu]:
Locality Name (eg, city) [Nanjing]:
Organization Name (eg, company) [JSP Company Ltd]:
Organizational Unit Name (eg, section) [LinuxOP]:
Common Name (eg, your name or your server's hostname) []:www.jsp.com
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@4fc6vm ssl]# ls -l
total 8
-rw-r--r--. 1 root root 712 Jun 13 10:39 httd.csr
-rw-------. 1 root root 887 Jun 13 10:37 httpd.key
CA签署证书httpd.crt
[root@4fc6vm ssl]# cd /etc/pki/CA
[root@4fc6vm CA]# ls
[root@4fc6vm CA]# touch index.txt serial crlnumber
[root@4fc6vm CA]# echo 01 > serial
[root@4fc6vm CA]# cd /etc/httpd/conf/ssl
[root@4fc6vm ssl]# openssl ca -in httpd.csr -out httpd.crt
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Jun 13 02:49:01 2017 GMT
Not After : Jun 13 02:49:01 2018 GMT
Subject:
countryName = CN
stateOrProvinceName = JiangSu
organizationName = JSP Company Ltd
organizationalUnitName = LinuxOP
commonName = www.jsp.com
emailAddress = [email protected]
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
EE:98:40:71:98:CF:30:DD:0A:A1:9D:69:58:66:91:A1:17:64:15:7F
X509v3 Authority Key Identifier:
keyid:A6:B6:A8:F8:5E:53:0A:53:F4:EC:26:80:B8:5B:A8:8A:8C:9E:1B:80
Certificate is to be certified until Jun 13 02:49:01 2018 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@4fc6vm ssl]# ls
httpd.crt httpd.csr httpd.key
确认mod_ssl模块是否安装,使用yum -y install mod_ssl进行安装
[root@4fc6vm ssl]# grep mod_ssl /etc/httpd/conf/httpd.conf
# (e.g. :80) if mod_ssl is being used, due to the nature of the
[root@4fc6vm ssl]# grep mod_ssl /etc/httpd/conf.d/*
[root@4fc6vm ssl]# yum -y install mod_ssl
[root@4fc6vm ssl]# rpm -ql mod_ssl
/etc/httpd/conf.d/ssl.conf
/usr/lib64/httpd/modules/mod_ssl.so
/var/cache/mod_ssl
/var/cache/mod_ssl/scache.dir
/var/cache/mod_ssl/scache.pag
/var/cache/mod_ssl/scache.sem
修改mod_ssl的配置文件,/etc/httpd/conf.d/ssl.conf
检查语法,重启httpd
[root@4fc6vm conf.d]# httpd -t
Syntax OK
[root@4fc6vm conf.d]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@4fc6vm conf.d]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 :::45411 :::*
LISTEN 0 128 *:52068 *:*
LISTEN 0 128 :::111 :::*
LISTEN 0 128 *:111 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::443 :::*
将证书/etc/pki/CA中的证书cacert.pem发给客户端,在windows中重命名为cacert.crt安装即可使用。使用openssl s_client -connect www.jsp.com:443 -CAfile /etc/pki/CA/cacert.pem
也可以进行验证
总结
(1)准备好服务器的私钥和证书
(2)安装mod_ssl
(3)配置/etc/httpd/conf/ssl.conf,配置使用的ssl的虚拟主机的ServerName和DocumentRoot,配置证书和私钥SSLCertificateFile、SSLCertificateKeyFile
(4)重启httpd服务
(5)测试
在浏览器中如果没有明确指定使用https协议,默认都是使用80端口的http协议,在开放80的同时,使访问80端口自动跳转到443端口,这要基于URL RewriteURL重写。
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...]
-I/--head 只显示响应报文首部信息
-A/--user-agent <string> 设置用户代理发送给服务器
-e/--referer <URL> 来源网址
-basic 使用HTTP基本认证
--tcp-nodelay 使用TCP_NODELAY选项
--cacert <file> CA证书 (SSL)
--compressed 要求返回是压缩的格式
-H/--header <line>自定义首部信息传递给服务器
--limit-rate <rate> 设置传输速度
-u/--user <user[:password]>设置服务器的用户和密码
-0/--http1.0 使用HTTP 1.0
另外一个工具叫elinks,一般使用格式:elinks [OPTION]... [URL]...
-dump:不进入交互模式,而直接将url的内容输出至标准输出
使用mod_deflate模块压缩页面可以优化传输速度,默认不启用。压缩要有一个过滤器,来指定压缩文件类型。
适用场景:
(1) 节约带宽,额外消耗CPU;同时,可能有些较老浏览器不支持;
(2) 压缩适于压缩的资源,例如文本文件;
如果在httpd的主配置文件中,没有关于输出过滤器的配置,可以在/etc/httpd/conf.d/目录下建立一个配置文件deflate.conf,
SetOutputFilter DEFLATE #启动输出过滤器为deflate
# mod_deflate configuration
# Restrict compression to these MIME types #对那些格式的文档进行压缩
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
# 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
-
apachectl:apache自带的服务控制脚本,可以控制httpd程序,如apachectl stop,而在/etc/rc.d/init.d目录下的脚本是rpm作者提供的脚本
-
htpasswd: basic认证基于文件实现时,用到的账号密码文件生成工具;
-
apxs:由httpd-devel包提供的,扩展httpd使用第三方模块的工具;
-
rotatelogs:日志滚动工具;
access.log --> access.log, access.1.log access.log, access.1.log, access.2.log
-
suexec:访问某些有特殊权限配置的资源时,临时切换至指定用户运行;
-
ab: Apache benchmark
资源限定有软限制和硬限制。软限制可以超出限制,但仅超出一定时长,硬限制是不能超出的限制,是ulimit可以修改软限制的数值。修改硬限制在配置文件/etc/security/limits.conf,或者在扩展配置/etc/security/limits.d/*.conf中修改,修改不会立即生效,只能重启生效,可以暂时使用ulimit命令修改,立即生效,等重启后读取配置文件即可。
-n [N]:显示或限定能打开的最大的文件句柄数
-u [N]:显示或限定能够运行的最多进程数,没有数字表示显示当前数值
使用ab命令可以会httpd进行压力测试,一般使用格式ab [OPTIONS] URL
-c:模拟最大并发数。c的值要小于等于n的值
-n:总的请求数
-k:以持久连接模式测试
ab -c 100 -n 50000 http://192.168.4.208/index.html
Server Software: Apache/2.4.6
Server Hostname: 192.168.4.208
Server Port: 80
Document Path: /index.html
Document Length: 208 bytes
Concurrency Level: 100
Time taken for tests: 29.451 seconds
Complete requests: 50000
Failed requests: 0
Write errors: 0
Non-2xx responses: 50000
Total transferred: 20350000 bytes
HTML transferred: 10400000 bytes
Requests per second: 1697.72 [#/sec] (mean)
Time per request: 58.903 [ms] (mean)
Time per request: 0.589 [ms] (mean, across all concurrent requests)
Transfer rate: 674.78 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.6 0 20
Processing: 7 58 28.1 59 1111
Waiting: 1 58 27.7 59 1111
Total: 13 59 28.1 60 1111
Percentage of the requests served within a certain time (ms)
50% 60
66% 69
75% 73
80% 76
90% 84
95% 93
98% 104
99% 115
100% 1111 (longest request)
除了ab可以对服务端httpd进行压力测试,还有webbench、http_load也可以做压力测试,但这些测试实际上都无法代表真正意义的流量,使用tcpcopy可以将真实的流量保存,然后使用真实的流量在架构上重放。
充分理解并解释压力测试结果
在CentOS 7中,默认提供apache的版本是2.4,使用RPM包安装httpd的默认路径是/etc/httpd,如果测试页不能正常打开,可以使用iptables或firewall-cmd来允许指定tcp端口或者允许指定的服务。
iptables -I INPUT -p tcp -dport 80 -j ACCEPT
firewall-cmd --permanent --add-service http
新特性
(1) MPM支持运行时装载模块;以模块形式按需加载; (2) 支持event MPM; (3) 支持异步读写; (4) 支持每模块及每个目录分别使用各自的日志级别; (5) 每请求配置;<If> (6) 增强版的表达式分析器; (7) 支持毫秒级的keepalive timeout; (8) 基于FQDN的虚拟主机不再需要NameVirtualHost指令; (9) 支持用户自定义变量;
新模块
(1) mod_proxy_fcgi
(2) mod_ratelimit
(3)mod_request
(4) mod_remoteip
修改了一些配置机制:不再支持使用Order, Deny, Allow来做基于IP的访问控制,统一使用require进行
编译安装httpd-2.4
httpd2.4依赖于apr-1.4+、apr-util-1.4+、apr-iconv,编译安装需要apr、apr-util、apr-icon
apr的全称是apache portable runtime,是一个用来使httpd跨平台的工具
在Cent OS 6中默认的是apr-1.3.9和apr-util-1.3.9
编译安装步骤:
在CentOS 6中要关闭httpd服务service httpd stop,并且确保httpd2.2没有开机启动chkconfig httpd off
1.4+版的apr和apr-util、安装开发环境,安装pcre-devel
(1) apr
# ./configure --prefix=/usr/local/apr
# make && make install
(2) apr-util
# ./configure --prefix=/usr/local/apr-util --with=/usr/local/apr
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/
# make && make install
(3)编译安装httpd2.4
# groupadd -r apache
# useradd -r -g apache apahce
# ./configure --prefix=/usr/local/apache --sysconf=/etc/httpd24 --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util/ --enable-modules=most --enable-mpms-shared=all --with-mpm=prefork
# make && make install
(4)后续配置
导出头文件:ln -sv /usr/local/httpd24/include /usr/include/httpd
导出库文件和man手册
输出二进制程序:编辑/etc/profile.d/httpd.sh,添加export PATH=/usr/local/httpd24/bin$PATH
在CentOS 6中为编译的httpd2.4创建脚本
复制一个httpd2.2的脚本,命名为httpd24,修改文件内容
启动服务:apachectl 或service
CentOS 7中的httpd2.4(rpm)
主配置文件:/etc/httpd/conf/httpd.conf
模块配置文件:/etc/httpd/conf.modules.d/*.conf
辅助配置文件:/etc/httpd/conf.d/*.conf
mpm:以DSO机制提供,配置文件00-mpm.conf
服务控制:systemctl {start|stop|restart|status|reload} httpd.service
基于IP的访问控制
∂绝所有主机访问:Require all deny
控制某网络主机的访问:Require ip IPADDR | Require no ip IPADDR
IPADDR可是是具体地址、网络和子网掩码格式、网络和网络长度
基于Hostname的访问控制
Require host HOSTNAME|Require not host HOSTNAME
HOSTNAME可以是具体的主机,也可以是一个域
练习:在httpd2.4中配置CGI、虚拟主机、https、mod_deflate、mod_status
一个进程同时需要和多个IO打交道,有磁盘IO、网络IO等。有四种机制:
-
阻塞:当一个进程发起IO调用,调用的IO没有完成前,当前的进程会被挂起
-
非阻塞:当一个进程发起IO调用,被调用函数完成之前不会阻塞当前进程而是立即返回结果,提示当前IO未完成
-
同步:进程发起一个过程调用(功能、函数)后,在没得到结果之前,该调用将不会返回
-
异步:进程发起一个过程调用后,即便调用者不能立即得到结果,但调用却会返回结果,返回是未完成状态。调用完成后,内核会通知调用者结果已经OK
常见的有:同步阻塞、异步阻塞、异步非阻塞(真正的异步IO)
五种IO模型
-
同步阻塞(blocking):当进程向内核发起一个对文件系统的访问时,进程阻塞,无法进行其他的任务,等待内核返回结果,而内核也不会立即对进程进行响应,而是到文件系统中将文件载入到内核内存,然后复制到进程内存中。
进程阻塞有两个阶段,第一阶段是等待内核将数据载入到内核内存,第二阶段是等待数据复制到进程内存空间同步阻塞效率低。
-
同步非阻塞(nonblocking):实际上同步非阻塞也是同步阻塞,在第一阶段,进程不会被挂起,而是定时向内核询问(盲等待),直到得到内核响应,此阶段进程是非阻塞,而得到内核响应后,等待数据复制到进程内存阶段,进程仍然是阻塞的。
-
IO复用(I/O multiplexing):IO复用在第一阶段和第二阶段都是阻塞的,只不过有多个IO同时都阻塞。BSD:select(),SysV:poll()
-
信号驱动(signal-driven):第一阶段完成后,内核通知进程,第二阶段进程阻塞。只通知一次的叫做边缘触发,多次通知的叫水平触发。在linux中是epoll(),在BSD是kqueue()
-
异步IO(asynchronous):进程发起调用后,收到通知,数据就已经在进程内存中了
内存映射(mmap)是省去了内核将数据复制到进程内存的步骤,而是进程直接访问内核内存。nginx支持异步IO、边缘触发、mmap,所以nginx性能比httpd好的原因,nginx可以一个线程响应多个请求。
httpd的prefork调用的是select(),最大的并发不超过1024,select()跨平台比较好,event调用的是epoll()