http、httpd、https、浏览工具
来源:互联网 发布:2017计算机二c语言题库 编辑:程序博客网 时间:2024/06/11 21:35
0 目录
- 目录
- http
- 1 http是什么
- 2 工作机制
- 21 服务器端与客户端
- 22 web资源与MIME
- 23 URL
- 24 http事务的过程
- 3 http报文格式
- 31 请求报文格式
- 311 常见请求方法
- 32 响应报文格式
- 321 常见状态码
- 33 常见header
- 331 通用首部
- 332 请求首部
- 333 响应首部
- 31 请求报文格式
- 4 cookie和session简要说明
- httpd22
- 1 主配置文件Section 1
- 11 ServerRoot
- 12 Listen
- 13 LoadModule
- 14 Include
- 15 持久连接相关
- 151 持久连接是什么
- 152 KeepAlive
- 153 KeepAliveTimeOut
- 154 MaxKeepAliveRequests
- 16 MPM
- 161 prefork
- 162 worker
- 163 event
- 17 User和Group
- 2 主配置文件Section 2
- 21 DocumentRoot
- 22 DirectoryIndex
- 23 对指定文件页面定义特性
- 231 Options
- 232 基于IP的访问控制
- 233 基于用户认证的访问控制
- 234 AllowOverride
- 24 日志相关
- 241 错误日志级别
- 242 访问日志内容格式
- 25 Alias
- 26 status页面
- 3 主配置文件Section3
- 31 各虚拟主机监听不同IP
- 32 各虚拟主机监听不同端口
- 33 各虚拟主机使用不同的FQDN
- 1 主配置文件Section 1
- 两个浏览器工具
- 1 curl
- 2 elinks
- https
- 1 自建CA签发证书
- 2 https配置文件
- 3 配置及测试
- 31 配置
- 32 测试
- httpd24与22的部分不同之处
1 http
1.1 http是什么
http :(hyper text transfer protocol),超文本传输协议,一个基于TCP的应用层协议。
超文本指的是使用html(hyper text mark language,超文本标记语言)编程语言所开发的文本文件。
1.2 工作机制
1.2.1 服务器端与客户端
服务器端即web服务器。运行了http服务端程序(如httpd、nginx等),存放了web资源的主机,可响应给客户端请求的资源,这些资源存放在web服务器上的某文件系统的某路径。服务器端监听在80端口(tcp)。
客户端就是各种浏览器。
1.2.2 web资源与MIME
一次请求和响应的内容,叫做web资源。分为静态、动态资源。
静态资源,jpg、html、mp3等等。就是无需服务端处理,直接发送给客户端的资源(httpd仅能处理静态资源)。为加快响应速度,静态资源可被浏览器缓存一段时间;
动态资源,php、jsp等。是需要服务端运行,将运行结果传给客户端的资源。
一个网页页面上通常有多个资源,一个图片、一个文本、一个链接都是各自独立的资源。不要误以为整个网页是一个资源。
所以,在打开一个页面时,客户端要对每个资源单独请求。显示一个完整网页,客户端其实是请求了多次的。
早期的http协议,仅能够用于文本文件(传输过程使用ASCII码)的传输。1.0之后引入MIME1,从而客户端可请求图片、音频等类型文件(传输过程中仍是文本)。
1.2.3 URL
客户端如何指定要请求哪些资源?
通过URL指定。只需在浏览器地址栏中输入指定URL即可。
URL(Uniform Resource Locator,统一资源定位符),用于唯一标识页面。
格式:Scheme://Server_IP:[port]/[PATH][;PARAMS][?QUERY][#FLAG]
比如,http://www.sohu.com/
Scheme是http;
www.sohu.com是Server_IP:port,只是没有直接用IP而是域名,且http默认80端口,所以可省;
之后的PATH省略,表示访问的是默认主页面index.html。
再比如,https://baike.baidu.com/item/MIME/2900607?fr=aladdin等。
1.2.4 http事务的过程
http的工作机制很简单:客户端向服务器端发送请求资源报文;服务器端返回给客户端响应报文。而这也称为一次http事务。
从服务器端来看,具体过程:
1、对于来访的请求,建立或拒绝连接;
2、接收并处理请求。包括分析请求报文的首部(header)信息,从而得知客户端的请求方法(method)。由于http基于tcp,所以每个资源的请求都要3次握手、4次断开;
3、服务器根据请求报文指定的URL,访问存储设备上对应的资源;
4、服务器得到指定资源,构建响应报文(即加上各首部信息),发送给客户端;
5、服务器将此次访问相关的信息记录日志。
1.3 http报文格式
http的请求、响应报文包括http协议首部(其实行+各headers)和数据实体。
不过请求报文和响应报文的起始行格式、常使用的headers有所不同。
1.3.1 请求报文格式
请求报文格式:
<method> <URL> <version> # 起始行header1: value # 各首部信息header2: value……headerN: value<request body> # 与上述信息隔两行,是数据实体
method:请求方法。即客户端请求服务端对资源完成的动作。
URL:指定资源的URL
version:指明http协议版本
headers:各首部信息。用于描述报文的各种属性。
request body:请求报文的数据实体
起始行信息与各headers,就是http协议首部。隔两行之后是数据实体。
1.3.1.1 常见请求方法
1.3.2 响应报文格式
响应报文与请求报文的格式,主要是起始行的不同:
<version> <status-code> <reason phrase> # 起始行header1: value # 各首部信息header2: value……headerN: value<entity body> # 与上述信息隔两行,是数据实体
version,仍是http协议版本;
status-code,状态码,用于描述不同的响应状态(成功、失败等)
reaon phrase,原因短语,就是对状态码的解释
headers,响应报文用到的各首部
entity body,数据实体。比如客户端要GET某资源,则这时的数据实体就是该资源
1.3.2.1 常见状态码
状态码就是3位数字,其中按1、2、3、4、5开头的对应不同的状态类型:
常见状态码:
1.3.3 常见header
如上所述,请求报文、响应报文的起始行之后,都有任意个首部(header)信息,以描述当前报文的属性等信息。
格式为:header_name: value
如有多个header,则每行一个。
比如,打开浏览器的调试界面(F12),地址栏输入www.sohu.com。随便找一个资源对应的首部信息,可看到该资源对应的请求、响应报文各首部,大致如下:
各常见首部:
1.3.3.1 通用首部
通用首部就是在请求、响应报文都可能用到的首部。
1.3.3.2 请求首部
仅用于请求报文中的常见首部:
1.3.3.3 响应首部
仅用于响应报文中的常见首部:
1.4 cookie和session简要说明
http协议是无状态的,就是服务器端无法识别访问者来源。即便是同一用户访问同一资源,在服务端看来也是两次不同的、独立的请求。
这在需要输入帐号密码、或是电商站点的情形是有问题的:只要一刷新页面就要重新输入验证信息,并且重新选购物品等。
使用cookie就是为了追踪访问者,以保持访问页面的状态。它会记录用户信息和操作记录。在客户端第一次向服务端发请求时,服务端发cookie给客户端。cookie存储在客户端本地,只要再访问服务端,就发送cookie以标明身份。
这样,在安全上又有较大风险,cookie可能泄露隐私信息。
于是引入session,session可看作服务端为用户建立的一种数据结构,用于存储用户操作记录。把cookie的部分信息用session来存储,cookie与session对应起来。
这样,根据指定cookie可在服务器上找到对应用户session,session中记录了用户的操作、行为记录等。
2 httpd2.2
应用层协议的实现,都是通过具体的软件。
httpd就是http协议中,服务器端的安装程序。以下说明httpd2.2的常用配置。笔者使用的是CentOS 6(6的光盘上的rpm包就是httpd2.2,如需在6上安装2.4,需编译安装),IP为192.168.0.105。
安装后只需在浏览器键入地址,即可看到测试页:
httpd2.2的配置文件为:主配置文件/etc/httpd/conf/httpd.conf和其他配置文件/etc/httpd/conf.d/*.conf。
上面的测试页面就是/etc/httpd/conf/httpd.conf/welcome.conf定义配置的。
主配置文件分3段:
### Section 1: Global Environment # 全局环境配置……### Section 2: 'Main' server configuration # 中心主机配置……### Section 3: Virtual Hosts # 虚拟主机配置……
配置格式为:”Command Value”各Command不严格区分大小写,但一般是把每个单词首字母大写。
修改其中的参数后可使用“httpd -t”检查配置文件语法。
下面列出主配置文件中的常用配置:
2.1 主配置文件Section 1
此段中的配置对全局有效。
2.1.1 ServerRoot
ServerRoot,用于定义服务端httpd程序的配置、日志等文件所在的目录(可看作是httpd的工作目录)。
注意,不要在最后加“/”:
……# Do NOT add a slash at the end of the directory path.#ServerRoot "/etc/httpd"
2.1.2 Listen
Listen,用于定义服务端监听的IP和端口。IP可省略,表示监听在所有IP;端口不可省。
可多次使用,表示同时监听在多个IP和端口。
修改监听的IP或端口,只有重启服务才能生效。
比如,修改为监听在80和8000端口:
Listen 80Listen 8000
重启服务后,查看监听端口验证:
[root@localhost ~]% netstat -tnlpActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1592/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1671/master tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 1757/sshd tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 2243/sshd tcp 0 0 :::8000 :::* LISTEN 2347/httpd tcp 0 0 :::80 :::* LISTEN 2347/httpd……
2.1.3 LoadModule
httpd是高度模块化的,支持动态装载、卸载各功能模块(就像内核一样)。
httpd的各模块文件放在/usr/lib64/httpd/modules。
LoadModule,用于指定装载的模块。
格式:LoadModule Module_Name Module_Path
其中模块所在的文件路径可以是相对路径,相对于ServerRoot定义的路径。
可看到httpd默认已经装载了诸多模块:
LoadModule auth_basic_module modules/mod_auth_basic.soLoadModule auth_digest_module modules/mod_auth_digest.soLoadModule authn_file_module modules/mod_authn_file.soLoadModule authn_alias_module modules/mod_authn_alias.so……
httpd命令的”-M”选项,可列出当前装载的所有模块。
2.1.4 Include
包含指定文件到配置文件。
主配置文件中使用了此指令,/etc/httpd/conf.d/*.conf才会作为配置文件生效,因为默认定义的就是此路径:
# Load config files from the config directory "/etc/httpd/conf.d".#Include conf.d/*.conf
2.1.5 持久连接相关
2.1.5.1 持久连接是什么
http基于tcp(连接需3次握手、4次断开)。
默认情况下是非持久连接:客户端每请求一个资源都要与服务端3次握手、获取到资源、4次断开。
当用户数较多时,应采取默认方式,以保证所有用户都能轮流得到响应;
当用户数较少时(比如只有1个用户,请求多个资源),频繁地3次握手、4次断开增加了不必要的开销。
对于后者应采取持久连接(也叫长连接):客户端与服务端一直保持连接状态,直到获取到一定数量的资源或连接达到一定时长才断开(注意,是满足二者中任一条件就断开)。
显然,长连接的情况下,当达到断开条件时,由服务端向客户端发出断开要求,因为只有服务端知道是否达到了资源数或指定时长;
默认情况断开请求是由客户端发出的。
2.1.5.2 KeepAlive
KeepAlive,用于指定是否启用长连接。
# KeepAlive: Whether or not to allow persistent connections (more than# one request per connection). Set to "Off" to deactivate.#KeepAlive Off # 默认是关闭的,如需开启改为on
2.1.5.3 KeepAliveTimeOut
KeepAliveTimeOut,用于指定长连接的时长。
# KeepAliveTimeout: Number of seconds to wait for the next request from the# same client on the same connection.#KeepAliveTimeout 15 # 默认15秒
2.1.5.4 MaxKeepAliveRequests
MaxKeepAliveRequests,用于指定客户端在长连接中最多请求的资源数。
# MaxKeepAliveRequests: The maximum number of requests to allow# during a persistent connection. Set to 0 to allow an unlimited amount.# We recommend you leave this number high, for maximum performance.#MaxKeepAliveRequests 100 # 默认100个
2.1.6 MPM
MPM(Multipath Processing Module,多路处理模块),是指httpd在同时响应多个请求时的工作模型。
分为3种:prefork、worker、event。只能启用其中一种。并且在需要切换模型时,最好是在关闭服务的情况下修改配置文件,修改完成后再开启。
虽然叫做模块,但httpd2.2不支持MPM的动态装载、卸载,2.4开始支持。
所以只要编译时采用了哪种模型,则使用的就是哪种模型。CentOS 6为了方便,3中模型都编译了,对应的应用程序分别为/usr/sbin/httpd、/usr/sbin/httpd.worker、/usr/sbin/httpd.event。
不过2.2上,event模型处于测试阶段;2.4可正常使用。
服务脚本启用httpd时,用的是哪种模型,在服务脚本配置文件/etc/sysconfig/httpd中进行了定义:
# The default processing model (MPM) is the process-based# 'prefork' model. A thread-based model, 'worker', is also# available, but does not work with some modules (such as PHP).# The service must be stopped before changing this variable.##HTTPD=/usr/sbin/httpd.worker 如需启用则把该行注释掉
2.1.6.1 prefork
默认情况下,服务脚本启动的是prefork模型对应的应用程序/usr/sbin/httpd:
[root@localhost ~]# ps aux | grep httpdroot 2000 0.0 0.3 175332 3688 ? Ss 16:07 0:00 /usr/sbin/httpdapache 2002 0.0 0.2 175332 2464 ? S 16:07 0:00 /usr/sbin/httpdapache 2003 0.0 0.2 175332 2444 ? S 16:07 0:00 /usr/sbin/httpdapache 2004 0.0 0.2 175332 2444 ? S 16:07 0:00 /usr/sbin/httpdapache 2005 0.0 0.2 175332 2444 ? S 16:07 0:00 /usr/sbin/httpdapache 2006 0.0 0.2 175332 2444 ? S 16:07 0:00 /usr/sbin/httpdapache 2007 0.0 0.2 175332 2444 ? S 16:07 0:00 /usr/sbin/httpdapache 2008 0.0 0.2 175332 2444 ? S 16:07 0:00 /usr/sbin/httpdapache 2009 0.0 0.2 175332 2444 ? S 16:07 0:00 /usr/sbin/httpdroot 2012 0.0 0.0 103312 880 pts/2 S+ 16:11 0:00 grep httpd
prefork模型:一个主进程用于创建套接字,由该主进程生成若干个子进程(称为服务进程)。处理请求时,由主进程接收并把请求派发给各子进程处理,每个子进程逐个处理资源请求4。处理一定数量的请求后,被主进程销毁、回收。
由于收到请求后再创建进程会影响响应效率,所以主进程会预先创建m个子进程等待用户请求。所以叫做prefork5。
httpd主配置文件中关于prefork的配置:
# prefork MPM# 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# MaxRequestsPerChild: maximum number of requests a server process serves<IfModule prefork.c>StartServers 8 # 服务启动时,启动多少服务进程MinSpareServers 5 # 最小空闲进程数MaxSpareServers 20 # 最大空闲进程数ServerLimit 256 # httpd运行期间,所能够启动的服务进程总数MaxClients 256 # 任一时刻,允许启动的服务进程最大数(即最多同时响应的用户数)MaxRequestsPerChild 4000 # 每个服务进程最多处理的请求数</IfModule>
注意:
1、MaxClients,限制了任一时刻,服务端最多并发响应多少用户的请求。
prefork模式中,同一时间,一个进程响应一个请求。即便每个服务进程响应的都是来自不同用户的请求(这正是服务端能允许并发用户数最多的情况),用户数量也就是恰好等于MaxClients定义的值;其他情况只会小于MaxClients。
2、ServerLimit大于等于MaxClients。
因为整个服务运行期间,服务进程数一共最多有ServerLimit个。所以在某一时刻,启动的服务进程最多就是ServerLimit个(再启动就超过ServerLimit了),而这正是MaxClients等于ServerLimit的情况。否则MaxClients会小于ServerLimit,因为某一时刻启动的最大服务进程数,不一定就是要把服务运行期间所能启动的服务进程都启动起来,可能是一个进程达到响应数量,销毁、回收后再继续启动新服务进程。
2.1.6.2 worker
在/etc/sysconfig/httpd中,修改为启用worker模型,再启动httpd,则会看到运行的程序变为/usr/sbin/httpd.worker:
[root@localhost ~]# ps aux | grep httpdroot 2151 0.0 0.3 175540 3888 ? Ss 19:55 0:00 /usr/sbin/httpd.workerapache 2153 0.0 0.5 519800 5300 ? Sl 19:55 0:00 /usr/sbin/httpd.workerapache 2154 0.0 0.5 519800 5304 ? Sl 19:55 0:00 /usr/sbin/httpd.workerapache 2156 0.0 0.5 519800 5308 ? Sl 19:55 0:00 /usr/sbin/httpd.workerroot 2266 0.0 0.0 103312 876 pts/1 S+ 19:55 0:00 grep httpd
worker模型:一个主进程用于创建套接字,由该主进程生成若干个子进程,各子进程再创建若干线程。处理请求时,由主进程接收并把派发请求,由每个线程逐个响应请求。
最多同时响应”m乘以n”个请求(m为子进程数,n为每个子进程创建的线程数)。
httpd主配置文件中,关于worker模型的配置:
# worker MPM# 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<IfModule worker.c>StartServers 4 # 服务启动时,启动的子进程数MaxClients 300 # 最多同时连接服务端的用户数MinSpareThreads 25 # 最小空闲线程数MaxSpareThreads 75 # 最大空闲线程数ThreadsPerChild 25 # 每个进程有多少线程MaxRequestsPerChild 0 # 默认为0,表示不限制每个子进程响应请求的数量</IfModule>
注意:
1、默认定义的服务启动时的进程数是4,每个进程创建的线程是25。所以服务启动时会有100个空闲线程。但默认定义的最大空闲线程是75,所以服务又会销毁一个进程,变为3个子进程6。
[root@localhost ~]% service httpd restart # 重启服务Stopping httpd: [ OK ]Starting httpd: [ OK ][root@localhost ~]% ps aux | grep httpd # 立即查看可看到4个子进程root 2310 0.0 0.3 175540 3892 ? Ss 20:36 0:00 /usr/sbin/httpd.workerapache 2312 0.0 0.5 519800 5304 ? Sl 20:36 0:00 /usr/sbin/httpd.workerapache 2313 0.0 0.5 519800 5320 ? Sl 20:36 0:00 /usr/sbin/httpd.workerapache 2314 0.0 0.5 519800 5304 ? Sl 20:36 0:00 /usr/sbin/httpd.workerapache 2315 0.0 0.5 519800 5312 ? Sl 20:36 0:00 /usr/sbin/httpd.workerroot 2425 0.0 0.0 103312 880 pts/0 S+ 20:36 0:00 grep httpd[root@localhost ~]% ps aux | grep httpd # 稍等几秒查看,变为3子进程。这就是由于默认的定义导致的root 2310 0.0 0.3 175540 3892 ? Ss 20:36 0:00 /usr/sbin/httpd.workerapache 2313 0.0 0.5 519800 5324 ? Sl 20:36 0:00 /usr/sbin/httpd.workerapache 2314 0.0 0.5 519800 5304 ? Sl 20:36 0:00 /usr/sbin/httpd.workerapache 2315 0.1 0.5 519800 5312 ? Sl 20:36 0:00 /usr/sbin/httpd.workerroot 2427 0.0 0.0 103312 880 pts/0 S+ 20:36 0:00 grep httpd
2、worker配置中的MaxClients和prefork中的意义貌似不同:
prefork模型中的MaxClients定义的是最多同时启动的子进程数,即最多同时响应的用户数;
worker模型中的MaxClients定义的是最多同时连接(注释中使用的是”连接”而非”响应”)的用户数。默认定义的是300,而默认的线程数是75。所以有的用户连接了但是或许要等待(这点不大确定)。
3、ps命令无法查看线程的情况,只能查看进程的情况。
2.1.6.3 event
httpd2.2的event模型处于测试(2.4可正常使用),不能正常使用,httpd2.2的主配置文件中也没有event的配置,关于其配置此处不述。
event:一个主进程用于创建套接字、接收请求,并由它生成若干子进程,并把请求派发给各子进程处理。每个子进程可响应多个请求(这是和prefork的不同之处)。
所以最多可同时响应”m乘以n”个请求,其中m为子进程数,n为每个子进程能响应的请求数。
2.1.7 User和Group
完成创建套接字、监听端口这些功能,需要以root身份运行(小于1023端口的监听,均需要root运行);为了安全起见,服务进程则要由非root用户身份运行。
从上述的prefork、worker的进程的情况可看出,服务进程都是由apache用户运行:
[root@localhost ~]% ps aux | grep httpdroot 2515 0.0 0.3 175332 3680 ? Ss 21:03 0:00 /usr/sbin/httpd # 主进程由root运行apache 2517 0.0 0.2 175332 2456 ? S 21:03 0:00 /usr/sbin/httpd # 子进程由apache用户运行apache 2518 0.0 0.2 175332 2436 ? S 21:03 0:00 /usr/sbin/httpdapache 2519 0.0 0.2 175332 2436 ? S 21:03 0:00 /usr/sbin/httpdapache 2520 0.0 0.2 175332 2436 ? S 21:03 0:00 /usr/sbin/httpdapache 2521 0.0 0.2 175332 2436 ? S 21:03 0:00 /usr/sbin/httpdapache 2522 0.0 0.2 175332 2436 ? S 21:03 0:00 /usr/sbin/httpdapache 2523 0.0 0.2 175332 2436 ? S 21:03 0:00 /usr/sbin/httpdapache 2524 0.0 0.2 175332 2436 ? S 21:03 0:00 /usr/sbin/httpdroot 2526 0.0 0.0 103312 880 pts/0 S+ 21:03 0:00 grep httpd
User和Group,就是用于指定以哪个用户、哪个组的身份,来运行服务进程。
在主配置文件中的默认定义:
# User/Group: The name (or #number) of the user/group to run httpd as.# . On SCO (ODT 3) use "User nouser" and "Group nogroup".# . On HPUX you may not be able to use shared memory as nobody, and the# suggested workaround is to create a user www and use that user.# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET)# when the value of (unsigned)Group is above 60000; # don't use Group #-1 on these systems!#User apacheGroup apache
注意:
由于服务进程是以apache用户身份运行,所以某些请求的资源如无法获取,应排查是否是apache用户没有该资源的文件权限。
2.2 主配置文件Section 2
此段配置的是中心主机各属性。
中心主机:一台物理服务器仅作为一个站点的服务端。
如果用中心主机,则不能用虚拟主机。
2.2.1 DocumentRoot
DocumentRoot,用于定义服务端的网页内容放置在哪个目录。相当于各URL的根。
# 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" # 默认放置在目录/var/www/html
所以,URL如”http://192.168.0.105/test.html“,访问的资源在服务器文件系统的路径就是”/var/www/html/test.html”。
在不使用路径别名alias定义,或允许在DocumentRoot定义的目录下创建符号链接的情况下,页面文件都是在DocumentRoot定义的目录下的。
2.2.2 DirectoryIndex
DirectoryIndex,用于定义主页面。
当用户键入的URL没有指明请求的具体页面时,则返回DirectoryIndex定义的页面给用户。
# DirectoryIndex: sets the file that Apache will serve if a directory# is requested.## The index.html.var file (a type-map) is used to deliver content-# negotiated documents. The MultiViews Option can be used for the # same purpose, but it is much slower.#DirectoryIndex index.html index.html.var # 默认定义的主页面是index.html
2.2.3 对指定文件(页面)定义特性
httpd支持对不同文件单独定义各种特性。
可使用容器Directory、Files、Location、LocationMatch等封装。Directory和Files作用对象是服务端的文件系统路径,Location作用对象是URL,LocationMatch作用对象是正则表达式匹配到的URL。
它们的用法差不多,以Direvtory为例,格式:
<Directory "/PATH"> # 对指定文件定义…… # 封装在此Directory的内容就是对指定文件的配置内容</Directory>
注意:
可多次使用Directory对多个PATH进行配置,但生效的是PATH范围小的那个。
如果对更小范围的路径没有定义配置,则它的配置就继承它上一级目录的。
比如,主配置文件中对默认路径的配置:
# First, we configure the "default" to be a very restrictive set of # features. #<Directory /> # 这里的路径是根,所以只要不被其他Directory显式配置的,生效的都是这个Directory定义的配置,所以是默认配置 Options FollowSymLinks AllowOverride None</Directory>
再比如对页面默认放置路径/var/www/html的设定:
# This should be changed to whatever you set DocumentRoot to.#<Directory "/var/www/html"> Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all</Directory>
由于/var/www/html范围更小,所以对/var/www/html来说就是这个Directory定义的配置生效,而不是上面对根路径配置的Directory。
如果/var/www/html的Directory对某些设置没有定义(比如Options),则它继承比它更大范围的文件路径对应的Directory中对相关配置的定义。比如Options没定义或是仅定义了参数FollowSymLinks,则会继承根路径Directory定义的Indexes;如果需禁用,则要显式定义Options的参数为”None”或”-Indexes”。
容器中常用的配置为:
2.2.3.1 Options
定义访问特性。
常用参数:
由于indexes、followsymlinks不安全,none反而比较常用。不过indexes、followsymlinks默认是被开启的。其他参数不述,可根据配置文件注释查询。
1、indexes效果:
在/var/www/html目录下创建一个test.html作为测试文件,内容是test page:
[root@localhost ~]% echo "<h1>test page</h1>" > /var/www/html/test.html
注销配置文件/etc/httpd/conf.d/welcome.conf中的内容(该配置文件定义了CentOS自带的测试页作为主页),此时就没有主页内容了,于是直接访问服务器IP,页面为:
结果是把test.html文件名列出,用户直接点击就打开该页面。
如果主页面不存在,且为设置Indexes,则会返回403或404错误页面。
2、followsymlinks效果:
比如,在/var/www/html目录下创建/etc/issue的链接文件issue.html,由于默认是开启的,所以URL指定为issue.html,显示的内容是/etc/issue的:
[root@localhost ~]% ln -sv /etc/issue /var/www/html/issue.html`/var/www/html/issue.html' -> `/etc/issue'
如果把/var/www/html的Options参数改为None,则无法访问:
2.2.3.2 基于IP的访问控制
可对Directory指定的路径做基于IP的访问控制。
首先使用指令Order,指定是做白名单还是黑名单。
白名单:
Order allow,deny # 除了显式定义允许的,其他都拒绝
黑名单:
Order deny,allow # 除了显式定义拒绝的,其他都允许
而后通过指令”Allow from”或”Deny from”,定义允许、拒绝的IP和网段。
比如/var/www/html的Directory默认定义的:
Order allow,deny Allow from all
表示允许所有主机访问。
再比如/var/www/html/test.html对应的Directory,如果定义为:
Order allow,deny Allow from 192.168.0.0 Deny from 192.168.0.100
表示仅允许192.168.0.0网段7的主机访问,但禁止192.168.0.100的IP访问。虽然这个IP属于192.168.0.0,但以更小范围的为准。
2.2.3.3 基于用户认证的访问控制
基于IP的访问控制显得比较简陋,可使用httpd自带的用户认证机制8。
有两种方式:基于明文的basic;基于特征码的digest。认证信息通过明文传输是有风险的,但由于有的浏览器不支持digest,所以默认使用basic。
服务端返回认证质询页面的状态码是401。
相关指令:
如果使用文本文件存储帐号密码,使用专用于管理basic认证的命令htpasswd创建,这是httpd自带的一个组件。
格式:htpasswd PASSWD_FILE USER
,表示在文件PASSWD_FILE中创建用户USER。
下面令笔者的192.168.0.105虚拟机上的test页面需认证才可登录,过程、效果:
1、创建帐号、密码文件,在其中创建3帐号(密码就设置为帐号名):
[root@localhost ~]% htpasswd -c -m /etc/httpd/my_passwd user1 # 只有创建第一个用户时使用“-c”选项New password: Re-type new password: Adding password for user user1[root@localhost ~]% htpasswd -m /etc/httpd/my_passwd user2New password: Re-type new password: Adding password for user user2[root@localhost ~]% htpasswd -m /etc/httpd/my_passwd user3New password: Re-type new password: Adding password for user user3
可看到文件内容中包含了帐号和密文存放的密码:
[root@localhost ~]% cat /etc/httpd/my_passwd user1:$apr1$lW68PjQ8$NF9HNaN4xplRcMdyl80tJ1user2:$apr1$2t3DiJUz$a7WLgFq.4QCKFxWq4n3v8/user3:$apr1$RFTMn8.I$0yG8nbmYO8M3Um66iJ6aV/
2、把user2、user3两帐号划分为1组(这个步骤不是必要的,只是为了后续验证对组的权限指派),组名为User_Group:
[root@localhost ~]% echo "User_Group: user2 user3" > /etc/httpd/my_group
3、把各指令定义在主配置文件的/var/www/html/test.html的Directory中:
<Directory "/var/www/html/test.html"> Options None AllowOverride None Order allow,deny Allow from all Authtype basic AuthName "/var/www/html/test.html" AuthUserFile /etc/httpd/my_passwd Require User user1 user2 user3# AuthGroupFile /etc/httpd/my_group# Require Group User_Group</Directory>
注意,基于IP和基于用户做访问控制并不冲突,都有效。只是这里对客户端IP没有做限制。
4、效果:
出现提示框要求帐号、密码认证:
提示信息中的”/var/www/html/test.html”,正是由AuthName定义的字符串;
有警告信息,是因为采用的AuthType是basic这种不安全的发送方式(明文)。
如点击“取消”,或多次输入错误密码,则返回如下页面:
经测试,正确输入user1、user2、user3的帐号密码可显示正确页面内容。
5、为验证组的效果,把第3步的内容改为:
<Directory "/var/www/html/test.html"> Options None AllowOverride None Order allow,deny Allow from all Authtype basic AuthName "/var/www/html/test.html" AuthUserFile /etc/httpd/my_passwd # Require User user1 user2 user3 AuthGroupFile /etc/httpd/my_group Require Group User_Group</Directory>
注意,虽然是验证组的效果,把”Require User”这项注释掉了。但AuthUserFile还是要指定的,因为组文件只是把指定的用户帐号划分为了一组,密码还是存储在AuthUserFile指定的文件中的。如不指定这项,还是会要求认证,但不论输入什么认证都不会通过。
经测试,只有user2、user3才能通过认证。因为User_Group组中仅包含了user2、user3。
2.2.3.4 AllowOverride
AllowOverride,指定哪些访问控制指令可放在.htaccess中。这个文件中定义的指令有效,而配置文件中Directory定义的就无效了。
网站的每个目录下都可以有.htaccess文件,使每个目录都按被分别控制。不常用,降低性能。所以默认参数是none,不起作用。
不常用。
2.2.4 日志相关
httpd的日志分为:访问日志、错误日志。顾名思义。
日志存放位置由配置文件定义(默认使用的是相对路径,相对于ServerRoot):
# ErrorLog: The location of the error log file.# If you do not specify an ErrorLog directive within a <VirtualHost># container, error messages relating to that virtual host will be# logged here. If you *do* define an error logfile for a <VirtualHost># container, that host's errors will be logged there and not here.#ErrorLog logs/error_log
# For a single logfile with access, agent, and referer information# (Combined Logfile Format), use the following directive:#CustomLog logs/access_log combined # 不仅定义了放置路径,还定义了日志格式使用combined格式
不过除了定义的路径,还可看到/var/logs/httpd目录下各文件,做了硬链接:
[root@localhost ~]# ls -li /etc/httpd/logs/total 1441184103 -rw-r--r--. 1 root root 46985 Oct 29 15:59 access_log1184086 -rw-r--r--. 1 root root 25970 Oct 29 11:21 access_log-201710291184104 -rw-r--r--. 1 root root 25789 Oct 29 15:59 error_log1184085 -rw-r--r--. 1 root root 24090 Oct 29 11:22 error_log-20171029[root@localhost ~]# ls -li /var/log/httpd/total 1441184103 -rw-r--r--. 1 root root 46985 Oct 29 15:59 access_log1184086 -rw-r--r--. 1 root root 25970 Oct 29 11:21 access_log-201710291184104 -rw-r--r--. 1 root root 25789 Oct 29 15:59 error_log1184085 -rw-r--r--. 1 root root 24090 Oct 29 11:22 error_log-20171029
2.2.4.1 错误日志级别
对于错误日志,可定义不同级别。
作用是定义,当错误达到哪种级别才记录日志。所以,级别定义得越低,日志文件就会越大。
默认是警告级别就记录日志。
# LogLevel: Control the number of messages logged to the error_log.# Possible values include: debug, info, notice, warn, error, crit,# alert, emerg.#LogLevel warn
2.2.4.2 访问日志内容格式
指令CustomLog定义了访问日志的存放位置和日志内容的格式。各种格式具体为何,则由指令LogFormat定义:
# The following directives define some format nicknames for use with# a CustomLog directive (see below).#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedLogFormat "%h %l %u %t \"%r\" %>s %b" commonLogFormat "%{Referer}i -> %U" refererLogFormat "%{User-agent}i" agent
格式都写在双引号中了,所以双引号中再使用双引号,使用了“\”进行转义。
访问日志默认使用的格式是combined,相对于其他的比较全,各字段意义:
还有其他许多字段,只是combined格式没有使用。参考官方文档:http://httpd.apache.org/docs/2.2/mod/mod_log_config.html
以笔者的192.168.0.105服务器刚产生的一条访问日志为例:
[root@localhost ~]# tail -1 /var/log/httpd/access_log192.168.0.104 - - [29/Oct/2017:17:18:30 +0800] "GET /favicon.ico HTTP/1.1" 403 292 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"
1、客户端IP192.168.0.104;
2、未识别主机名;
3、未识别用户名;
4、收到请求的时间[29/Oct/2017:17:18:30 +0800],使用的是英文标准时间格式;
5、起始行”GET /favicon.ico HTTP/1.1”;
6、状态码403;
7、报文内容大小292字节(因为返回了403对应的页面);
8、笔者是直接从浏览器输入的地址,所以首部referer无值;
9、浏览器类型”Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36”。
2.2.5 Alias
Alias,用于定义路径别名。
格式:Alias fakename realname
fakename为相对于DocumentRoot的URL路径,realname为把前者URL映射为指定的文件系统路径。
所以虽说叫做别名,实际上应该算是改名。
效果:
1、两个不同的页面文件,一个在DocumentRoot定义的路径下,一个在其他路径下:
[root@localhost ~]% cat /var/www/html/test.html # 本机上已定义过的test.html页面,在DocumentRoot指定的路径下<h1>test page</h1>[root@localhost ~]% echo "<h1>another test page</h1>" > /var/www/test.html # 定义另一个不同的页面,在另一路径下
2、在不使用别名的情况下,URL”http://192.168.0.105/test.html“,对应的页面文件是/var/www/html/test.html:
3、在配置文件中定义别名,使URL”http://192.168.0.105/test.html“对应页面文件变为/var/www/test.html:
配置文件中定义:
Alias /test.html "/var/www/test.html" # 注意也可对目录做别名,最后可加斜杠。但前后的斜杠要一致,有斜杠前后都要有
此时同样的URL,页面变为了另一个:
2.2.6 status页面
status页面显示的是站点的运行状态信息。
最好做下认证(基于IP或用户)。
查看status页面,需要加载status模块,默认是加载的:
LoadModule status_module modules/mod_status.so
默认的对于status页面的访问控制定义(默认都是注释着的):
# Allow server status reports generated by mod_status,# with the URL of http://servername/server-status# Change the ".example.com" to match your domain to enable.##<Location /server-status># SetHandler server-status# Order deny,allow# Deny from all# Allow from .example.com # 默认仅允许域.example.com的主机访问#</Location>
这里为查看效果,改为允许笔者的windows主机登录(IP192.168.0.104):
# Allow server status reports generated by mod_status,# with the URL of http://servername/server-status# Change the ".example.com" to match your domain to enable.#<Location /server-status> SetHandler server-status Order deny,allow Deny from all Allow from 192.168.0.104</Location>
使用浏览器查看status页面,效果:
笔者用红框圈住的部分,就是httpd启动的进程的状态。下方有对应的说明,其中几个说明下:
1、“_”表示空闲服务进程,横杠都连在一起了(这里有8个,因为配置文件中StartServer默认是8;最多不超过MaxClients指定的值);
2、“w”表示正在正在响应的服务进程;
3、“.”表示目前还没启动,但服务运行过程中允许启动的进程,所占的位置(所以它的数量是被ServerLimit指定的)。
2.3 主配置文件Section3
此段用于配置虚拟主机。
1物理服务器默认仅作为1个站点的服务端(就是中心主机配置)。但对于访问量不多的站点,可在1主机上配置多个虚拟主机分别作为它们的服务端。
每个虚拟主机使用容器VirtualHost封装定义。大部分可在中心主机定义的指令,也可在虚拟主机中使用:
<VirtualHost IP:PORT> ServerName XXX # ServerName和DocumentRoot显然是必要的,其他可按需定义 DocumentRoot XXX ……</VirtualHost>
重点在于,服务端收到一个请求,如何得知访问的是哪个虚拟主机?
可令不同虚拟主机监听于不同的IP、端口区分,也可使用主机名区分。它们可混合使用。
下面分别使用这3种方式:
2.3.1 各虚拟主机监听不同IP
下面令同一主机有192.168.0.105和108两地址,为它们创建两虚拟主机,它们提供的主页面不一样。访问105地址的服务端返回的是105的页面,访问108返回的是108的页面:
1、配置105、108两IP地址:
[root@localhost ~]% ip addr show eth02: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:05:75:b2 brd ff:ff:ff:ff:ff:ff inet 192.168.0.105/24 brd 192.168.0.255 scope global eth0 inet 192.168.0.108/32 scope global eth0 inet6 fe80::20c:29ff:fe05:75b2/64 scope link valid_lft forever preferred_lft forever
2、配置文件中定义两虚拟主机,以IP区分,对应不同的DocumentRoot:
<VirtualHost 192.168.0.105:80> DocumentRoot "/var/www/html/192.168.0.105" ServerName test1</VirtualHost><VirtualHost 192.168.0.108:80> DocumentRoot "/var/www/html/192.168.0.108" ServerName test2</VirtualHost>
3、在两DocumentRoot定义的目录下均创建test.html,内容就是它们的IP:
[root@localhost ~]% cat /var/www/html/192.168.0.105/test.html 192.168.0.105[root@localhost ~]% cat /var/www/html/192.168.0.108/test.html 192.168.0.108
4、查看不同IP的test.html页面,得到不同页面:
注意,这种方法是为每个站点都提供了一个IP。不实用,不可能对每个站点都申请一个公网IP。
2.3.2 各虚拟主机监听不同端口
令两虚拟主机监听于不同端口。客户端访问同一IP的不同端口,得到不同页面:
1、配置文件中,定义两虚拟主机,监听105的80和8000端口,对应不同的DocumentRoot:
<VirtualHost 192.168.0.105:80> DocumentRoot "/var/www/html/192.168.0.105" ServerName test1</VirtualHost><VirtualHost 192.168.0.105:8000> DocumentRoot "/var/www/html/192.168.0.105:8000" ServerName test2</VirtualHost>
2、不同的DocumentRoot下对应的test.html页面内容不同:
[root@localhost ~]% cat /var/www/html/192.168.0.105/test.html 192.168.0.105[root@localhost ~]% cat /var/www/html/192.168.0.105:8000/test.html 192.168.0.105:8000
3、注意,因为使用了多个端口,所以配置文件的全局段,要设置监听每个端口:
Listen 80Listen 8000
4、访问同一IP的不同端口,得到不同的页面:
注意,一般用户在键入网址时并不知道服务端使用的别的端口,仍会使用默认的80端口。所以这种也不实用。
2.3.3 各虚拟主机使用不同的FQDN
两虚拟主机使用同样的IP和端口,使用不同的FQDN来区分。
虽然请求报文送达服务器时是先通过FQDN解析出IP地址,再发送(FQDN貌似无法起到作用)。但请求报文中包含首部Host,它记录了客户端键入的是哪个FQDN。服务端据此得知FQDN,从而根据FQDN返回对应页面。
1、在配置文件中,设置两虚拟主机监听的IP、端口相同,FQDN不同:
NameVirtualHost 192.168.0.105:80 # 注意,httpd2.2中配置基于FQDN区分的虚拟主机,要使用此命令说明虚拟主机监听的IP和端口,否则语法检查时会被提示使用该指令。httpd2.4中无需这样做<VirtualHost 192.168.0.105:80> DocumentRoot "/var/www/html/test1" ServerName www.test1.com</VirtualHost><VirtualHost 192.168.0.105:80> DocumentRoot "/var/www/html/test2" ServerName www.test2.com</VirtualHost>
2、不同的DocumentRoot下对应的test.html页面内容不同:
[root@localhost ~]% cat /var/www/html/test1/test.html www.test1.com[root@localhost ~]% cat /var/www/html/test2/test.html www.test2.com
3、由于笔者是用windows的浏览器测试,为避免再创建一个DNS服务器用来解析FQDN的麻烦,所以在windows的hosts文件10中添加这两FQDN的解析记录:
4、在浏览器键入不同的FQDN,可看到返回不同的页面:
3 两个浏览器工具
3.1 curl
curl严格来看并不是浏览器,而是一个文件传输工具。可基于URL模拟http、https、ftp等协议的客户端。
作为传输工具,无法解析html文档,所以输出的是html文档的源码。
使用格式:curl [options] [URL...]
常用选项:
仍以192.168.0.105主机作为服务端,验证各选项效果:
选项-A(这里只是验证-A效果,ie6所属的浏览器类型不知道是否就叫ie6):
[root@localhost ~]% curl 192.168.0.105/test.html # 不使用任何选项<h1>test page</h1>[root@localhost ~]% tail -n 1 /etc/httpd/logs/access_log # 日志记录浏览器类型crul……192.168.0.105 - - [31/Oct/2017:21:30:28 +0800] "GET /test.html HTTP/1.1" 200 19 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"[root@localhost ~]% curl -A ie6 192.168.0.105/test.html # -A指定ie6<h1>test page</h1>[root@localhost ~]% tail -n 1 /etc/httpd/logs/access_log # 日志记录浏览器类型ie6192.168.0.105 - - [31/Oct/2017:21:31:21 +0800] "GET /test.html HTTP/1.1" 200 19 "-" "ie6"
选项-I:
[root@localhost ~]% curl -I 192.168.0.105/test.html # 仅显示响应报文首部信息HTTP/1.1 200 OKDate: Tue, 31 Oct 2017 13:34:31 GMTServer: Apache/2.2.15 (CentOS)Last-Modified: Sun, 29 Oct 2017 04:04:49 GMTETag: "121169-13-55ca79f8d26f6"Accept-Ranges: bytesContent-Length: 19Connection: closeContent-Type: text/html; charset=UTF-8
选项-e:
[root@localhost ~]% curl 192.168.0.105/test.html<h1>test page</h1>[root@localhost ~]% tail -n 1 /etc/httpd/logs/access_log # 默认访问,日志的referer字段为“-”192.168.0.105 - - [31/Oct/2017:21:36:04 +0800] "GET /test.html HTTP/1.1" 200 19 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"[root@localhost ~]% curl -e www.haha.com 192.168.0.105/test.html # 使用-e可伪装是从指定的页面跳转而来<h1>test page</h1>[root@localhost ~]% tail -n 1 /etc/httpd/logs/access_log192.168.0.105 - - [31/Oct/2017:21:36:21 +0800] "GET /test.html HTTP/1.1" 200 19 "www.haha.com" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
选项-u:
仍使用标题2.2.3.3中,对/var/www/html/test.html做用户认证的定义。
<Directory "/var/www/html/test.html"> Options None AllowOverride None Order allow,deny Allow from all Authtype basic AuthName "/var/www/html/test.html" AuthUserFile /etc/httpd/my_passwd Require User user1 user2 user3 AuthGroupFile /etc/httpd/my_group Require Group User_Group</Directory>
[root@localhost ~]% curl -u user1 192.168.0.105/test.html # 使用用户user1登录Enter host password for user 'user1': # 要求输入密码,笔者在这里仍输入了“user1”<h1>test page</h1>[root@localhost ~]% curl -u user1:user1 192.168.0.105/test.html # 或是直接输入用户和密码,冒号隔开<h1>test page</h1>
3.2 elinks
elinks是一个文本浏览器,可解析html文档。默认是在交互模式,按q键退出。
仍以192.168.0.5的test.html为例:
[root@localhost ~]% elinks 192.168.0.105/test.html
注意,由于不像windows下的浏览器有各种用于打开不同MIME类型资源的插件,所以它只能打开文本资源(http协议默认就是文本传输),如果页面上有其他类型资源(如图片),会自动过滤掉。
如果不使用交互模式,而是令页面内容一次性输出,使用选项-dump(只是格式会有点不一样):
[root@localhost ~]% elinks -dump 192.168.0.105/test.html test page
3 https
https的服务端监听在tcp的443端口。用于实现加密传输网页。
httpd调用ssl层(介于应用层和传输层之间,可看作应用层的子层),就可作为https的服务端。
SSL会话基于IP,如果把1物理主机上的虚拟主机配置为https的服务端,只能有一个虚拟主机作为https服务端,且不能基于端口、FQDN创建。
下面配置192.168.0.105主机作为https的服务端;192.168.0.102为自建CA。配置、验证https服务端效果:
3.1 自建CA签发证书
1、192.168.0.102主机作为CA,105主机申请证书:
在102主机自建CA:
[root@node2 ~]% openssl genrsa -out /etc/pki/CA/private/cakey.pem # CA的私钥Generating RSA private key, 1024 bit long modulus.......................++++++.....................................++++++e is 65537 (0x10001)[root@node2 ~]% openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem # CA的自签证书You are about to be asked to enter information that will be incorporatedinto 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 blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [XX]:CNState or Province Name (full name) []:TaiWan Locality Name (eg, city) [Default City]:TaipeiOrganization Name (eg, company) [Default Company Ltd]:WCOrganizational Unit Name (eg, section) []:WCCommon Name (eg, your name or your server's hostname) []:node2Email Address []:123456@qq.com[root@node2 ~]% echo 01 > /etc/pki/CA/serial # 在证书的序列号文件中添加一个初始序列号[root@node2 ~]% touch /etc/pki/CA/index.txt # 创建index.txt作为证书的索引文件,没有此文件会报错提示
在105主机,创建私钥、创建证书申请,把申请传给102主机:
[root@localhost ssl]% openssl genrsa -out node1.private # 创建私钥Generating RSA private key, 1024 bit long modulus..................++++++.++++++e is 65537 (0x10001)[root@localhost ssl]% openssl req -new -key node1.private -out node1.csr # 创建证书申请You are about to be asked to enter information that will be incorporatedinto 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 blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [XX]:CNState or Province Name (full name) []:TaiWanLocality Name (eg, city) [Default City]:TaipeiOrganization Name (eg, company) [Default Company Ltd]:WCOrganizational Unit Name (eg, section) []:WCCommon Name (eg, your name or your server's hostname) []:node1 Email Address []:654321@qq.comPlease enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:An optional company name []:[root@localhost ssl]% scp node1.csr root@192.168.0.102:/etc/httpd/ssl/node1.csr # 把证书申请复制至102主机root@192.168.0.102's password: node1.csr 100% 672 0.7KB/s 00:00
在102主机,签发105主机的证书申请,并传给105主机:
[root@node2 ~]% openssl ca -in /tmp/node1.csr -out /etc/pki/CA/certs/node1.crt # 签发证书Using configuration from /etc/pki/tls/openssl.cnfCheck that the request matches the signatureSignature ok……[root@node2 ~]% scp /etc/pki/CA/certs/node1.crt root@192.168.0.105:/tmp/node1.crt # 把签发的证书复制给主机105主机root@192.168.0.105's password: node1.crt 100% 3139 3.1KB/s 00:00
openssl自建CA详细过程见http://blog.csdn.net/wangzhenyu177/article/details/78122812
3.2 https配置文件
httpd默认没有加载ssl模块,需使用yum单独安装mod_ssl模块。
安装完成后,可看到多了一个https的配置文件/etc/httpd/conf.d/ssl.conf。该配置文件直接加载了mod_ssl模块,并监听443端口:
LoadModule ssl_module modules/mod_ssl.soListen 443
配置文件中定义一个叫做”_default_”的虚拟主机,指的是如果解析到的IP地址和其他虚拟主机不匹配,则由该虚拟主机来响应。
该虚拟主机中除了定义ServerRoot、DocumentRoot等必须的参数,还定义了https相关的,常用的有
其他指令如无需要可不修改。
3.3 配置及测试
3.3.1 配置
这里因为是要把192.168.0.105作为https的服务器,所以把虚拟主机_default_改成192.168.0.105:
<VirtualHost 192.168.0.105:443>
根据标题3.1中获得的私钥和自建CA颁发的证书,指定证书路径和私钥路径:
SSLCertificateFile /etc/httpd/ssl/node1.crtSSLCertificateKeyFile /etc/httpd/ssl/node1.private
定义DocumentRoot和ServerName:
DocumentRoot "/var/www/html"ServerName www.node2.com # 注意,主机名要和证书上的名字一致,否则会被认为没有通过证书验证
而后注释掉监听80端口的语句”Listen 80”,虽然http和https互不影响,但这里测试https,多一事不如少一事。
注意,https的实现算是httpd的一个模块,所以语法检查、重启服务等都还是httpd的操作命令,”httpd -t”、”service httpd restart”等。
3.3.2 测试
仍访问之前定义过的/var/www/html/test.html:
这里提示安全证书有问题,因为地址栏键入的是地址,而证书上的主机名是node1。
因为笔者使用windows上的浏览器测试,所以在windows主机上的hosts文件中,还要加入node1:
而后键入地址”https://node1/test.html“:
仍有问题,提示无法证明是访问的就是node1主机11,因为windows上的浏览器并没有添加信任笔者自建的CA(就是192.168.0.102主机)。
于是添加自建CA的自签证书(/etc/pki/CA/cacert.pem文件)到该浏览器。由于添加的目的是让客户端主机信任自建CA所颁发的证书,所以会被系统特别提示:
这里使用了一个向导程序添加,实际对各浏览器添加信任的颁发机构可能略有不同,但差不多,这里不赘述添加证书过程了。
主机node2作为信任CA添加至windows主机的浏览器上了,于是再访问https://node1.test.html就正常显示内容了:
使用IE还可查看加密情况:
至此就实现了https加密通信。
4 httpd2.4与2.2的部分不同之处
2.4比2.2改进的地方很多,这里列出和上述提到的各特性与httpd2.2的不同:
- MPM在2.4中也变成一个可装载、卸载的模块了。启动时仅需主程序/usr/sbin/httpd即可。prefork、worker、event模式可切换;
- 配置文件多了/etc/httpd/conf.modules.d/*.modules用于各模块的配置(包括MPM等),而2.2是写在主配置文件中;
- event在2.4不是测试,可正常使用了;
- 长连接时长可定义至毫秒级(使用ms作单位);
- 基于FQDN的虚拟主机,不再需要NameVirtualHost指令;
- 增加了新指令AllowOverrideList,以增强AllowOverride;
mod_remoteip,用于基于IP的访问控制。且2.4默认所有目录都是禁止访问的,需显式定义访问权限。不再使用allow、deny指令,使用新机制:
- Require all granted,允许所有用户访问
- Require all denied,拒绝所有用户访问
- Require [not] IP,允许、拒绝指定IP访问。也可以是IP段
- Require [not] HOST,允许、拒绝指定主机名访问。可以是具体主机名也可以是域名
如果有多条限制,则需写在容器(容器名不限制)中。比如允许所有主机访问,但拒绝192.168.0.1:
<Require>Require all grantedRequire not 192.168.0.1</Require>
(完)
- MIME:Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型。
MIME规定了用符号表示各类型数据的方法,即各媒体类型如何表示。服务端只要把MIME类型放在响应报文的首部信息中,浏览器可识别服务器返回的资源是哪种媒体类型,从而自动用对应的应用程序(就是浏览器插件),打开对应类型的资源。这样就实现了让http这种文本传输的协议,能够传输图片、音频等多种媒体类型。 ↩ - 虽然http协议工作机制简单,但实际使用中,客户端的请求往往不是直接到达服务器,而是先到达代理服务器(可能要经过多个)。
这样的目的是在代理服务器使用缓存、负载均衡等,可有效提高访问效率,也减小服务器压力。 ↩ - 为加快服务端响应速度、降低服务器压力、降低带宽占用等,本地浏览器会把一些静态资源(如图片等)缓存下来。再获取同样资源时,只需发出条件式请求:如果指定资源未发生改变,则继续使用缓存内容;如果改变,则重新从服务器获取。 ↩
- 每个子进程逐个处理请求。比如5个子进程共处理50个,那么每个就处理10个。但同一时间仅能处理1个,这样逐个处理完10个。 ↩
- fork正是linux中用于创建进程的函数。 ↩
- 默认定义为何这样不得而知,看上去没什么用。 ↩
- 这里网段的写法很灵活,可以有掩码,掩码可以写全也可用长度表示;也可以不要掩码。也可直接写成192.0.0,即仅写明网络号,后面的主机号省略也可以。 ↩
- 注意这和很多盈利性网站要求用户登录不同,那些网站使用的是专门开发的用于认证身份的程序。httpd自带的这个认证是比较简单的。不常用 ↩
- 当记录的用户较多时,设置各用户的访问权限(比如允许哪些用户登录)比较繁琐,可把用户划分为不同的组,以组来指派用户权限就方便多了 ↩
- windows的hosts文件在C盘windows/system32/drivers/etc/hosts ↩
- 虽然此时选择继续通信,通信过程是加密的。如使用IE浏览器更可清楚看到,点击地址栏的”https”,会显示通信过程是加密的,只是身份无法验证。因为https服务端是启动的,所以保证了通信过程是加密的。而身份验证需要客户端信任颁发证书的CA,而且服务端的CA要和服务器的主机名一致。
通信内容加密了,无法验证身份,就无法防止中间人攻击。 ↩
- http、httpd、https、浏览工具
- apache httpd httpd.conf php php.ini url http https
- 使用 Apache httpd 搭建 HTTP/HTTPS/FTP (正向)代理服务器
- 使用 Apache httpd 搭建 HTTP/HTTPS (正向)代理服务器
- http https请求工具类
- 监测HTTP and SSL / HTTPS 的工具
- 通用http、https访问工具类
- httpd设置HTTPS双向认证
- httpd设置HTTPS双向认证
- httpd设置HTTPS双向认证
- httpd设置HTTPS双向认证
- httpd设置https双向认证
- httpd, http, CGI
- 接口调试工具、接口测试工具、http接口调试工具、https接口调试工具
- charles工具抓包教程(http跟https)
- post/get请求(http,https)工具类
- 使用Fiddler工具抓取手机HTTP和HTTPS包
- charles工具抓包教程(http跟https)
- linux mysql:command not find,mysql -e 导出文件
- C# 引用类库dll时也能看到注释
- gcc程序的编译过程和链接原理
- spark读取hdfs的文件存入hbase慢
- Leetcode-Combination(dfs)
- http、httpd、https、浏览工具
- 大荣是未来的大龄程序媛
- java集合类库学习记录———Collection类库的结构
- 迅雷 任务出错 无法下载文件怎么办?轻松解决迅雷 内容违规 任务出错 无法下载
- Java设计模式之二——四种不同的单例模式(Singleton)
- CentOS安装ffmpeg
- Linux下rz命令和sz命令使用方法
- myeclipse控制台输入的中文输出时乱码
- python帮助