httpd2.2官方配置手册:
http://httpd.apache.org/docs/2.2/
注意:关闭防火墙,iptables规则
vim /etc/sysconfig/selinux
SELINUX=disabled
iptables -F
httpd-2.2的常用配置
主配置文件:/etc/httpd/conf/httpd.conf
### Section 1: Global Environment
### Section 2: 'Main' server configuration
### Section 3: Virtual Hosts
配置格式:
directive value
directive:不区分字符大小写;
value:为路径时,是否区分字符大小写,取决于文件系统;
常用配置:
1、修改监听的IP和PORT
Listen [IP:]PORT
(1) 省略IP表示为0.0.0.0;表示本机上的所有ip地址
(2) Listen指令可重复出现多次;
Listen 80 Listen 8080
(3) 修改监听socket,重启服务进程方可生效;
2、持久连续
Persistent Connection:tcp连续建立后,每个资源获取完成后不全断开连接,而是继续等待其它资源请求的进行;
如何断开?
数量限制
时间限制
副作用:对并发访问量较大的服务器,长连接机制会使得后续某些请求无法得到正常响应;
折衷:使用较短的持久连接时长,以及较少的请求数量;
1 KeepAlive On|Off #注意,只有在keepAlive的状态为on时,下面的两项才是启用的; 2 KeepAliveTimeout 15 3 MaxKeepAliveRequests 100
测试:使用telnet工具
1 yum install -y telnet #安装telnet 2 (keepalive off) 3 [root@httpd ~]# telnet 192.168.1.16 80 4 Trying 192.168.1.16... 5 Connected to 192.168.1.16. 6 Escape character is '^]'. 7 GET /test.html HTTP/1.1 #表示使用HTTP1.1的协议 8 Host: 192.168.1.16 #请求的主机是192.168.1.16;//此处回车两次出现结果 9 10 HTTP/1.1 200 OK 11 Date: Thu, 27 Apr 2017 02:33:40 GMT 12 Server: Apache/2.2.15 (CentOS) 13 Last-Modified: Thu, 27 Apr 2017 02:18:59 GMT 14 ETag: "8023f-1e-54e1c94668f44" 15 Accept-Ranges: bytes 16 Content-Length: 30 17 Connection: close 18 Content-Type: text/html; charset=UTF-8 19 20 <h1>this www.linuxedu.top<h1> 21 Connection closed by foreign host. #此处是断开的 22 (keepalive on) 23 [root@httpd ~]# telnet 192.168.1.16 80 24 Trying 192.168.1.16... 25 Connected to 192.168.1.16. 26 Escape character is '^]'. 27 GET /test.html HTTP/1.1 28 Host: 192.168.1.16 #此处回车两次出现结果 29 30 HTTP/1.1 200 OK 31 Date: Thu, 27 Apr 2017 02:34:56 GMT 32 Server: Apache/2.2.15 (CentOS) 33 Last-Modified: Thu, 27 Apr 2017 02:18:59 GMT 34 ETag: "8023f-1e-54e1c94668f44" 35 Accept-Ranges: bytes 36 Content-Length: 30 37 Content-Type: text/html; charset=UTF-8 38 39 <h1>this www.linuxedu.top<h1> 40 #此处是回车,并没有断开,但是受到MaxKeepAliveRequests以及KeepAliveTimeout的限制最终也会断开
3、MPM
httpd-2.2不支持同时编译多个MPM模块,所以只能编译选定要使用的那个;CentOS 6的rpm包为此专门提供了三个应用程序文件,httpd(prefork), httpd.worker, httpd.event,分别用于实现对不同的MPM机制的支持;确认现在使用的是哪下程序文件的方法:
1 [root@httpd ~]# ps aux | grep httpd 2 root 1658 0.0 0.2 177816 3872 ? Ss 10:34 0:00 /usr/sbin/httpd 3 apache 1660 0.0 0.1 177816 2496 ? S 10:34 0:00 /usr/sbin/httpd 4 apache 1661 0.0 0.1 177816 2496 ? S 10:34 0:00 /usr/sbin/httpd 5 apache 1662 0.0 0.1 177816 2496 ? S 10:34 0:00 /usr/sbin/httpd
默认使用的为/usr/sbin/httpd,其为prefork的MPM模块 ;
1 [root@httpd ~]# /usr/sbin/httpd -l 2 Compiled in modules: 3 core.c 4 prefork.c 5 http_core.c 6 mod_so.c
查看httpd程序的模块列表:
查看静态编译的模块:
# httpd -l
查看静态编译及动态编译的模块:
1 [root@httpd ~]# httpd -M 2 httpd: Could not reliably determine the server's fully qualified domain name, using 0.0.0.0 for ServerName 3 Loaded Modules: 4 core_module (static) 5 mpm_prefork_module (static) 6 http_module (static) 7 so_module (static) 8 auth_basic_module (shared) 9 auth_digest_module (shared) 10 ...
更换使用httpd程序,以支持其它MPM机制;/etc/sysconfig/httpd
MPM更改的选项有:HTTPD=/usr/sbin/httpd.{worker,event}
注意:对于centos6来讲,httpd2.2版本的event还是测试的阶段,因此不建议在生产环境中使用;
操作步骤:建议先停止服务,然后修改配置文件,最后启动服务才能生效
1 [root@httpd ~]# service httpd stop 2 停止 httpd: [确定] 3 [root@httpd ~]# vim /etc/sysconfig/httpd 4 [root@httpd ~]# cat /etc/sysconfig/httpd | grep '^HTTPD' 5 HTTPD=/usr/sbin/httpd.worker 6 [root@httpd ~]# service httpd start 7 正在启动 httpd:httpd.worker: apr_sockaddr_info_get() failed for httpd 8 httpd.worker: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName 9 [确定] 10 [root@httpd ~]# ps aux | grep httpd 11 root 1746 0.0 0.2 178024 4132 ? Ss 10:56 0:00 /usr/sbin/httpd.worker 12 apache 1860 0.0 0.2 522284 5372 ? Sl 10:56 0:00 /usr/sbin/httpd.worker 13 root 1889 0.0 0.0 103256 840 pts/0 S+ 10:56 0:00 grep --color httpd
思考:为什么编辑/etc/sysconfig/httpd就会生效呢?先来了解一下什么是脚本的配置文件
1 [root@httpd ~]# cat useradd.sh 2 3 #!/bin/bash 4 # 5 [ -f /tmp/useradd.conf ] && source /tmp/useradd.conf 6 username=${username:-testuser} 7 echo $username 8 [root@httpd ~]# cat /tmp/useradd.conf 9 username=myuser
1、脚本首先会判断/tmp/useradd.conf这个文件是否存在,如果存在就会把文件中的内容读取到当前环境中,
2、${username:-testuser},表示如果当前环境中username这个变量有值,那么echo $username就是当前环境中的值myuser,如果没有值,echo $username的值就是testuser
---->这样看来就很好理解为什么编辑/etc/sysconfig/httpd就会生效的
MPM详细的参数配置:/etc/httpd/conf/httpd.conf中
prefork的配置
# StartServers:服务器刚启动时启动多少个进程
# MinSpareServers:最小保持空闲进程的数量
# MaxSpareServers:最大保持空闲进程的数量
# ServerLimit: MaxClients在服务器生命周期中的最大值
# MaxClients:最大并发客户端连接数
# MaxRequestsPerChild: 服务器进程服务的最大请求数
1 <IfModule prefork.c> #条件式参数,表示如果模块是 2 StartServers 8 3 MinSpareServers 5 4 MaxSpareServers 20 5 ServerLimit 256 6 MaxClients 256 7 MaxRequestsPerChild 4000 8 </IfModule>
worker的配置:
# StartServers: 启动服务器进程的初始数量
# MaxClients:最大并发客户端连接数
# MinSpareThreads: 保留多少空余线程数量
# MaxSpareThreads:最大保留多少空余线程数量
# ThreadsPerChild: 每个服务器进程中不断的工作线程数
# MaxRequestsPerChild: 服务器进程服务的最大请求数
1 <IfModule worker.c> 2 StartServers 4 3 MaxClients 300 4 MinSpareThreads 25 5 MaxSpareThreads 75 6 ThreadsPerChild 25 7 MaxRequestsPerChild 0 8 </IfModule>
注意:这里虽然定义的StartServers是4个,但是每次查看都是3个,我们可以通过以下查看
1 ps aux | grep httpd 2 service httpd restart 3 watch -n.5 'ps aux | grep httpd' #每0.5秒监测一下发现会自动销毁一个
PV,UV
PV:Page View,页面访问,一个页面可能就上百个资源;
UV: User View,用户浏览量,指的是浏览的独立IP
4、DSO
配置指定实现模块加载
1 #LoadModule <mod_name> <mod_path> 2 LoadModule auth_basic_module modules/mod_auth_basic.so
模块文件路径可使用相对路径:
相对于ServerRoot(默认/etc/httpd)
1 lrwxrwxrwx. 1 root root 29 4月 27 09:41 modules -> ../../usr/lib64/httpd/modules
5、定义'Main' server的文档页面路径
1 DocumentRoot "/var/www/html" #注意更改此路径时,一定要确定你的selinux是关闭的
文档路径映射:
DoucmentRoot指向的路径为URL路径的起始位置,其相当于站点URL的根路径;
(FileSystem) /web/host1/index.html --> (URL) /index.html
注意:在httpd2.4上只修改DocumentRoot是一定不会生效的,必须要设置站点访问控制机制;如下
1 DocumentRoot "/var/www/html" 2 <Directory "/var/www/html">
6、站点访问控制常见机制
可基于两种机制指明对资源进行何种访问控制
(1)文件系统路径:
1 <Directory ""> 2 ... #表示对该目录下的所有包含子目录生效 3 </Directory> 4 <File ""> 5 ... #表示对单个文件进行访问控制 6 </File> 7 <FileMatch "PATTERN"> 8 ... #表示对一类文件进行访问控制(被PATTERN匹配的一类文件) 9 </FileMatch>
(2)URL路径:
1 <Location ""> 2 ... #表示对""中指定的位置下的所有做访问控制 3 </Location> 4 5 <LocationMatch ""> 6 ... #表示对匹配到的位置进行访问控制 7 </LocationMatch>
<Directory>中“基于源地址”实现访问控制:
(1)
Options
后跟1个或多个以空白字符分隔的“选项”列表;
选项:Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
- Indexes:指明的URL路径下不存在与定义的主页面资源相符的资源文件时,返回索引列表给用户;一般只是做为下载站点时才采用;默认是启用的;
- FollowSymLinks:允许跟踪符号链接文件所指向的源文件;就是可以读取访问控制目录下的所有被链接到的文件的内容;有风险
- None:表示不启用,不使用任何选项
- All:包含除了MultiViews的所有选项
- includes :表示包含服务器端由mod_include提供的
- SymLinksifOwnerMatch:服务器将仅跟踪目标文件或目录所拥有的符号链接与链接相同的用户标识
- ExecCGI:表示允许执行mod_CGI提供的脚本
(2)
AllowOverride 允许覆盖
与访问控制相关的哪些指令可以放在.htaccess文件(网站目录下的每个子目录都可以有一个)中;
All: 所有的指定都可以放进去
None:不放任何指定
注意:还有一些其他的选项:FileInfo(文件信息) AuthConfig Limit
(3) order和allow、deny
order:定义生效次序;表示对源地址进行访问控制;写在后面的表示默认法则;
Allow from:表示允许那些范围(白名单)
Deny from:表示拒绝那些范围(黑名单)
7、定义站点主页面:
1 DirectoryIndex index.html index.html.var index.php
注意:如果匹配不到以上的所有的后缀索引,那么访问站点时可能会有以下集中情况
- 告诉用户你所访问的资源不存在
- 返回该路径下的所有可用的URL给列出来;相当于暴露了网站的源码,但是又可以用于作为下载站点;
8、定义路径别名
格式:Alias /URL
/ "/PATH/TO/SOMEDIR/"
1 DocumentRoot "/www/htdocs" 2 http://www.magedu.com/download/bash-4.4.2-3.el6.x86_64.rpm #正常情况下基于URL映射 3 /www/htdocs/download/bash-4.4.2-3.el6.x86_64.rpm #正常情况下基于文件系统映射 4 5 Alias /download/ "/rpms/pub/" 6 http://www.magedu.com/download/bash-4.4.2-3.el6.x86_64.rpm 7 /rpms/pub/bash-4.4.2-3.el6.x86_64.rpm 8 9 http://www.magedu.com/images/logo.png 10 /www/htdocs/images/logo.png
9、设定默认字符集
AddDefaultCharset UTF-8
中文字符集:GBK, GB2312, GB18030
10、日志设定
日志类型:访问日志 和 错误日志
错误日志:
ErrorLog logs/error_log
LogLevel warn
可能存在的值有: 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:表示使用自定义格式的格式名称,如
1 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 2 LogFormat "%h %l %u %t \"%r\" %>s %b" common 3 LogFormat "%{Referer}i -> %U" referer 4 LogFormat "%{User-agent}i" agent
%h:客户端IP地址;
%l:Remote User, 通常为一个减号(“-”);
%u:Remote user (from auth; may be bogus if return status (%s) is 401);非为登录访问时,其为一个减号;
%t:服务器收到请求时的时间;
%r:First line of request,即表示请求报文的首行;记录了此次请求的“方法”,“URL”以及协议版本;
%>s:响应状态码;
%b:响应报文的大小,单位是字节;不包括响应报文的http首部;
%{Referer}i:请求报文中首部“referer”的值;即从哪个页面中的超链接跳转至当前页面的;
%{User-Agent}i:请求报文中首部“User-Agent”的值;即发出请求的应用程序;
11、基于用户的访问控制
认证质询:
WWW-Authenticate:响应码为401,拒绝客户端请求,并说明要求客户端提供账号和密码;
认证:
Authorization:客户端用户填入账号和密码后再次发送请求报文;认证通过时,则服务器发送响应的资源;
认证方式有两种:
basic:明文
digest:消息摘要认证
安全域:需要用户认证后方能访问的路径;应该通过名称对其进行标识,以便于告知用户认证的原因;
用户的账号和密码存放于何处?
虚拟账号:仅用于访问某服务时用到的认证标识
存储:文本文件,SQL数据库,ldap目录存储;
basic认证配置示例:
(1) 定义安全域
1 <Directory ""> 2 Options None 3 AllowOverride None 4 AuthType Basic 5 AuthName "String“ 6 AuthUserFile "/PATH/TO/HTTPD_USER_PASSWD_FILE" 7 Require user username1 username2 ... #授权指定用户可以访问,如果需要让所有的人可访,改成Require valid-user 8 </Directory>
允许账号文件中的所有用户登录访问:
Require valid-user
1 <Directory ""> 2 Options None 3 AllowOverride None 4 AuthType Basic 5 AuthName "String“ 6 AuthUserFile "/PATH/TO/HTTPD_USER_PASSWD_FILE" 7 Require valid-user #授权指定用户可以访问,如果需要让所有的人可访,改成Require valid-user 8 </Directory>
(2) 提供账号和密码存储(文本文件)
使用专用命令完成此类文件的创建及用户管理
htpasswd [options] /PATH/TO/HTTPD_PASSWD_FILE username
-c:自动创建此处指定的文件,因此,仅应该在此文件不存在时使用;
-m:md5格式加密
-s: sha格式加密
-D:删除指定用户
范例1:
1 mkdir /var/www/html/admin 2 echo "<h1>admin page</h1>" > index.html 3 <Directory /var/www/html/admin/> 4 Options None 5 AllowOverride None 6 AuthType Basic 7 AuthName "Admin Realm" 8 AuthUserFile "/etc/httpd/conf/.htpasswd" 9 Require user tom 10 </Directory>
配置加密文件
1 cd /etc/httpd/conf/ 2 [root@httpd conf]# htpasswd -c -m ./.htpasswd tom 3 New password: 4 Re-type new password:
访问浏览器
另外:基于组账号进行认证;
(1) 定义安全域
1 <Directory ""> 2 Options None 3 AllowOverride None 4 AuthType Basic 5 AuthName "String“ 6 AuthUserFile "/PATH/TO/HTTPD_USER_PASSWD_FILE" 7 AuthGroupFile "/PATH/TO/HTTPD_GROUP_FILE" 8 Require group grpname1 grpname2 ... 9 </Directory>
(2) 创建用户账号和组账号文件;
组文件:每一行定义一个组
GRP_NAME: username1 username2 ...
案例2
1 mkdir /var/www/html/upload;cp /var/www/html/admin/index.html /var/www/html/upload/ 2 echo "<h1>upload page</h1>" > /var/www/html/upload/index.html 3 <Directory /var/www/html/upload/> 4 Options None 5 AllowOverride None 6 AuthType Basic 7 AuthName "Admin Realm" 8 AuthUserFile "/etc/httpd/conf/.htpasswd" 9 AuthGroupFile "/etc/httpd/conf/.htgroup" 10 Require group mygroup 11 </Directory> 12 [root@httpd conf]# cat ./.htgroup 13 mygroup: tom Jason 14 othergroup: obama
12、虚拟主机
站点标识: socket
IP相同,但端口不同;
IP不同,但端口均为默认端口;
FQDN不同;
请求报文中首部
Host: www.linuxedu.top
有三种实现方案:
基于ip:
为每个虚拟主机准备至少一个ip地址;
基于port:
为每个虚拟主机使用至少一个独立的port;
基于FQDN:
为每个虚拟主机使用至少一个FQDN;
注意:一般虚拟机不要与中心主机混用;因此,要使用虚拟主机,得先禁用'main'主机;
禁用方法:注释中心主机的DocumentRoot指令即可;
虚拟主机的配置方法:
1 <VirtualHost IP:PORT> 2 ServerName FQDN 3 DocumentRoot "" 4 </VirtualHost>
其它可用指令:
ServerAlias:虚拟主机的别名;可多次使用;
ErrorLog:
CustomLog:
<Directory "">
...
</Directory>
Alias
...
完成以下三种方案:
注意注释掉中心主机,关闭selinux,清空防火墙规则;
基于IP的虚拟主机示例:
1 <VirtualHost 172.16.100.6:80> 2 ServerName www.a.com 3 DocumentRoot "/www/a.com/htdocs" 4 </VirtualHost> 5 6 <VirtualHost 172.16.100.7:80> 7 ServerName www.b.net 8 DocumentRoot "/www/b.net/htdocs" 9 </VirtualHost> 10 11 <VirtualHost 172.16.100.8:80> 12 ServerName www.c.org 13 DocumentRoot "/www/c.org/htdocs" 14 </VirtualHost>
基于端口的虚拟主机
1 <VirtualHost 172.16.100.6:80> 2 ServerName www.a.com 3 DocumentRoot "/www/a.com/htdocs" 4 </VirtualHost> 5 6 <VirtualHost 172.16.100.6:808> 7 ServerName www.b.net 8 DocumentRoot "/www/b.net/htdocs" 9 </VirtualHost> 10 11 <VirtualHost 172.16.100.6:8080> 12 ServerName www.c.org 13 DocumentRoot "/www/c.org/htdocs" 14 </VirtualHost>
基于FQDN的虚拟主机:
1 NameVirtualHost 172.16.100.6:80 2 <VirtualHost 172.16.100.6:80> 3 ServerName www.a.com 4 DocumentRoot "/www/a.com/htdocs" 5 </VirtualHost> 6 7 <VirtualHost 172.16.100.6:80> 8 ServerName www.b.net 9 DocumentRoot "/www/b.net/htdocs" 10 </VirtualHost> 11 12 <VirtualHost 172.16.100.6:80> 13 ServerName www.c.org 14 DocumentRoot "/www/c.org/htdocs" 15 </VirtualHost>
13、status页面
1 LoadModule status_module modules/mod_status.so 2 <Location /server-status> 3 SetHandler server-status 4 Order allow,deny 5 Allow from 172.16 6 </Location>
思考如何实现虚拟主机的https
参考文献
要实现一个Apache服务器上提供多个SSL虚拟主机,可以:
* 使用多域名SSL证书,可以实现一个IP,一个443端口上多个SSL虚拟主机;
* 一个ip,为所有SSL虚拟主机配置单独的端口。比如,默认的虚拟主机使用443,其他的使用8080或8081等,且每个SSL虚
拟主机必须独占一个端口;
* 为Apache服务器配置多个IP,每个SSL虚拟主机独占IP。如果只有一张物理网卡,可以配置为网卡配置子接口;
* 使用mod_gnutls模块,创建多个SSL虚拟主机
1. Apache中同一IP多个HTTPS虚拟主机的实现
在 Apache 文档中提到,不能在单个 IP 上同时有多个按名字识别的虚拟主机("named virtual host")。不完全是这样。
HTTPS协议的过程是:服务器首先与客户机之间进行服务器身份验证并协商安全会话,然后,客户端向服务器发送 HTTP 请求。这样一来,在客户端开始发送HTTP请求之前,服务器就已经把证书发给了客户端(客户端根据本地的根证书去验证证书链,等等)。而最重要的是,为了表明身份,这个证书的"Common Name"填写的应该是域名,否则浏览器会给出警告。
既然在这个过程中,客户端就所访问的域名所处的地位是"被告知"的地位,因此,客户端再发出的 Host: 请求头也就显得不那么有意义了。另一方面,如果客户请求的域名与Common Name不符,浏览器也会给出警告。至少,在表面上看是这样。
不过,对于自行签署的证书,以及一些发证机构而言,其实还可以签署一种普适HTTPS证书,这种证书的 Common Name 一栏是 *.domain.tld 这样的形式,即其主机名部分可以是任意字符串,而只有域名部分是确定的。
当然,这种证书的安全性有一定的负面影响:由于一个证书可以验证整个域下面的所有服务器,一旦其被破解,则所有加密通讯也就同时失密了(当然,可以每台服务器使用自己的单独的证书),不过这个问题并不是太严重,通常还算是尚可接受的范围。另一个潜在的影响是,某些手机上运行的浏览器不能正确处理这种证书,不过这个问题仅限于希望给手机提供服务的网站。
因此,简而言之,符合这样几个条件的前提下,是可以在同一个IP上部署多个HTTPS虚拟主机的:
a) 这些虚拟主机是同属于同一域名的子域名
b) 拥有普适证书
c) 正确地配置Apache。
如果要在一个IP地址上需要部署多个SSL网站,
(1)一种方法:如果要在同一个IP地址的443端口上部署多个网站,必须保证这些网站的域名都能匹配相同的一张SSL证书。这是因为SSL握手协议过程中,是通过IP+Port来进行通信,一个IP的一个端口只能返给客户一张SSL证书(即使有多张证书,也只能返回第一张,因为无法分辨用户会需要返回哪张证书),如果这张证书能够满足这些网站的主机名匹配要求(访问b.test.com时,使用a.test.com段的证书,证书中包含a.test.com,于虚拟主机中的主机名之一匹配),就可以使用。
一般能匹配多个主机名的证书有通配符证书*.domain.com和多域名证书(www.domain.com,ftp.domain.com 等),以下我们提供一个典型同一个IP上的多主机名部署配置,www.domain.com对应的根目录在WWW下,ftp.domain.com对应的根目录在FTP下, www.domain.com 与 ftp.domain.com 使用相同的证书:
* 一个ip,为所有SSL虚拟主机配置单独的端口。比如,默认的虚拟主机使用443,其他的使用8080或8081等,且每个SSL虚
拟主机必须独占一个端口;
* 为Apache服务器配置多个IP,每个SSL虚拟主机独占IP。如果只有一张物理网卡,可以配置为网卡配置子接口;
* 使用mod_gnutls模块,创建多个SSL虚拟主机
1. Apache中同一IP多个HTTPS虚拟主机的实现
在 Apache 文档中提到,不能在单个 IP 上同时有多个按名字识别的虚拟主机("named virtual host")。不完全是这样。
HTTPS协议的过程是:服务器首先与客户机之间进行服务器身份验证并协商安全会话,然后,客户端向服务器发送 HTTP 请求。这样一来,在客户端开始发送HTTP请求之前,服务器就已经把证书发给了客户端(客户端根据本地的根证书去验证证书链,等等)。而最重要的是,为了表明身份,这个证书的"Common Name"填写的应该是域名,否则浏览器会给出警告。
既然在这个过程中,客户端就所访问的域名所处的地位是"被告知"的地位,因此,客户端再发出的 Host: 请求头也就显得不那么有意义了。另一方面,如果客户请求的域名与Common Name不符,浏览器也会给出警告。至少,在表面上看是这样。
不过,对于自行签署的证书,以及一些发证机构而言,其实还可以签署一种普适HTTPS证书,这种证书的 Common Name 一栏是 *.domain.tld 这样的形式,即其主机名部分可以是任意字符串,而只有域名部分是确定的。
当然,这种证书的安全性有一定的负面影响:由于一个证书可以验证整个域下面的所有服务器,一旦其被破解,则所有加密通讯也就同时失密了(当然,可以每台服务器使用自己的单独的证书),不过这个问题并不是太严重,通常还算是尚可接受的范围。另一个潜在的影响是,某些手机上运行的浏览器不能正确处理这种证书,不过这个问题仅限于希望给手机提供服务的网站。
因此,简而言之,符合这样几个条件的前提下,是可以在同一个IP上部署多个HTTPS虚拟主机的:
a) 这些虚拟主机是同属于同一域名的子域名
b) 拥有普适证书
c) 正确地配置Apache。
如果要在一个IP地址上需要部署多个SSL网站,
(1)一种方法:如果要在同一个IP地址的443端口上部署多个网站,必须保证这些网站的域名都能匹配相同的一张SSL证书。这是因为SSL握手协议过程中,是通过IP+Port来进行通信,一个IP的一个端口只能返给客户一张SSL证书(即使有多张证书,也只能返回第一张,因为无法分辨用户会需要返回哪张证书),如果这张证书能够满足这些网站的主机名匹配要求(访问b.test.com时,使用a.test.com段的证书,证书中包含a.test.com,于虚拟主机中的主机名之一匹配),就可以使用。
一般能匹配多个主机名的证书有通配符证书*.domain.com和多域名证书(www.domain.com,ftp.domain.com 等),以下我们提供一个典型同一个IP上的多主机名部署配置,www.domain.com对应的根目录在WWW下,ftp.domain.com对应的根目录在FTP下, www.domain.com 与 ftp.domain.com 使用相同的证书:
1 NameVirtualHost 11.22.33.44:443 2 3 <VirtualHost 11.22.33.44:443> 4 DocumentRoot "C:/Apache2.2/htdocs/www" 5 ServerName www.domain.com 6 SSLEngine on 7 SSLCertificateFile "C:/Apache2.2/conf/server.cer" 8 SSLCertificateKeyFile "C:/Apache2.2/conf/server.key" 9 </VirtualHost> 10 11 <VirtualHost 11.22.33.44:443> 12 DocumentRoot "C:/Apache2.2/htdocs/ftp" 13 ServerName ftp.domain.com 14 SSLEngine on 15 SSLCertificateFile "C:/Apache2.2/conf/server.cer" 16 SSLCertificateKeyFile "C:/Apache2.2/conf/server.key" 17 </VirtualHost> 18 19 (2)另一种办法就是给每个网站分配不同的端口号; 20 <VirtualHost 11.22.33.44:443> 21 DocumentRoot "C:/Apache2.2/htdocs/www" 22 ServerName www.domain.com 23 SSLEngine on 24 SSLCertificateFile "C:/Apache2.2/conf/server.cer" 25 SSLCertificateKeyFile "C:/Apache2.2/conf/server.key" 26 </VirtualHost> 27 28 <VirtualHost 11.22.33.44:8443> 29 DocumentRoot "C:/Apache2.2/htdocs/ftp" 30 ServerName ftp.domain.com 31 SSLEngine on 32 SSLCertificateFile "C:/Apache2.2/conf/server.cer" 33 SSLCertificateKeyFile "C:/Apache2.2/conf/server.key" 34 </VirtualHost>
基于域名的虚拟主机只能使用同一个证书,或者说,即使有不同的证书,最终使用的都是排在前面的默认的第一个
2. Apache中一张网卡绑定不同IP实现多个HTTPS虚拟主机
一张网卡绑定多个ip,ifconfig eth0:0......
1 <VirtualHost 220.181.75.109:8443> 2 ServerAdmin lala@corp.net.com 3 DocumentRoot /home/lala/apache/htdocs/test 4 ServerName a.test.com 5 SSLEngine on 6 SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL 7 SSLCertificateFile /home/lala/apache/conf/ssl.key/server.crt 8 SSLCertificateKeyFile /home/lala/apache/conf/ssl.key/server.key 9 #Include /home/lala/apache/conf/ssl.conf 10 #ErrorLog logs/dummy-a.test.com-error_log 11 #CustomLog logs/a.test.com-access_log common 12 </VirtualHost> 13 14 <VirtualHost 220.181.75.65:8443> 15 ServerAdmin lala@corp.net.com 16 DocumentRoot /home/lala/apache/htdocs/test2 17 ServerName d.test.com 18 SSLEngine on 19 SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL 20 SSLCertificateFile /home/lala/apache/conf/ssl.key/server2.crt 21 SSLCertificateKeyFile /home/lala/apache/conf/ssl.key/server2.key 22 #Include /home/lala/apache/conf/ssl.conf 23 #ErrorLog logs/dummy-a.test.com-error_log 24 #CustomLog logs/a.test.com-access_log common 25 </VirtualHost>