前言:
Apache是一种开源的HTTP服务器软件,可以在大多数主流的计算机操作系统中运行(包括UNIX、Linux及Windows),再加上其支持多平台且具有良好的安全性被广泛使用,随着网络技术的普及和不断发展,以及Web技术的不断完善,Web服务已经成为互联网上最重要的服务形式之一。
httpd:俗称apache
官方网站:httpd.apache.org
ASF:apache software foundation
www.netcraft.com
1、http常用的版本:
官方网站:httpd.apache.org
http-1.3
httpd-2.2:event为测试使用
httpd-2.4:event可生产使用
2、httpd的特性
高度模块化:core+modules
DSO:Dynamic Shared Object 动态共享对象
MPM:Multipath Processing Modules 多路处理模块
非一个模块,而是对一种特性的称谓
prefork:多进程模型,每个进程响应一个请求:
一个主进程,负责生成n个子进程,子进程也称为工作进程,每个子进程处理一个用户请求,即便没有用户请求,也会预先生成多个空闲进程,随时等待请求到达:最大不会超过1024个
worker:多线程模型,每个线程响应一个请求
一个主进程,生成多个子进程,每个子进程负责生成多个线程,每个线成响应一个用户请求;
event:事件驱动模型,每个进程响应n个请求
一个主进程,生成m个子进程,每个进程响应n个请求,m*n
在大多数平台上,Prefork MPM在效率上要比Worker MPM要高,但是内存使用大得多。prefork的无线程设计在某些情况下将比worker更有优势:它可以使用那些没有处理好线程安全的第三方模块,并且对于那些线程调试困难的平台而言,它也更容易调试一些。
Worker模式:WorkerMPM 使用多个子进程,每个子进程有多个线程。每个线程在某个确定的时间只能维持一个连接。通常来说,在一个高流量的HTTP服务器上,Worker MPM是个比较好的选择,因为Worker MPM的内存使用比Prefork MPM要低得多。
fork():
进程复制通过fork()自身生成子进程
tack_struct:任务结构,每个进程都有任务结构
3、httpd的功能特性:
路径别名:alias
丰富的用户认证机制:authentication
basic、digest
虚拟主机:virtual host
IP,Port,FQDN
CGI:Common Gateway Interface,通用网关接口
反向代理:
负载均衡:
用户站点:
CGI:Common Gateway Interface 通用网络接口
支持第三方模块
4、安装httpd
1)、rpm包
[root@xxj ~]# rpm -qa|grep httpd [root@xxj ~]# [root@xxj ~]# yum list|grep httpd httpd.x86_64 2.2.15-47.el6.centos updates httpd-devel.i686 2.2.15-47.el6.centos updates httpd-devel.x86_64 2.2.15-47.el6.centos updates httpd-manual.noarch 2.2.15-47.el6.centos updates httpd-tools.x86_64 2.2.15-47.el6.centos updates libmicrohttpd.i686 0.9.33-4.el6 base libmicrohttpd.x86_64 0.9.33-4.el6 base libmicrohttpd-devel.i686 0.9.33-4.el6 base libmicrohttpd-devel.x86_64 0.9.33-4.el6 base libmicrohttpd-doc.noarch 0.9.33-4.el6 base [root@xxj ~]# yum install httpd -y [root@node1 ~]# rpm -ql httpd|head
[root@xxj ~]# netstat -nlptu|grep 80 [root@xxj ~]# service httpd start Starting httpd: httpd: apr_sockaddr_info_get() failed for xxj httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName [ OK ] [root@xxj ~]# netstat -nlptu|grep 80 tcp 0 0 :::80 :::* LISTEN 1639/httpd
注意:上面启动httpd服务时有一个
这不能属于一个错误,因为这个不影响服务的正常运行,但我看着就是不爽。
原因:这个问题应该是没有在 httpd.conf 中设定 ServerName
解决办法:
[root@xxj conf]# sed -i 's/#\(ServerName\) www.example.com:80/\1 localhost:80/' /etc/httpd/conf/httpd.conf [root@xxj conf]# httpd -t # 检查httpd主配置文件是否有错 Syntax OK [root@xxj conf]# service httpd reload # 重新加载httpd主配置文件 Reloading httpd: [root@xxj conf]# service httpd restart Stopping httpd: [ OK ] Starting httpd: [ OK ] # 没有警告信息了
5、程序环境
默认工作目录(根目录):/etc/httpd 通过ServerRoot指定
站点文档目录:/var/www/html 通过DocumentRoot指定
CGI目录:/var/www/cgi-bin 存放动态脚本
主配置文件:/etc/httpd/conf/httpd.conf
分段配置文件:/etc/httpd/conf.d/*.conf
服务脚本:/etc/rc.d/init.d/httpd
服务脚本的配置文件:/etc/sysconfig/httpd
模块文件目录:/etc/httpd/modules-->/usr/lib64/httpd/modules
主程序文件:
/usr/sbin/httpd(prefork)
/usr/sbin/httpd.worker
/usr/sbin/httpd.event
日志文件目录:
/var/log/httpd
access_log:访问日志文件
error_log:错误日志
日志滚动:
日志切割:
access.log
access.log(新的),access1.log(旧的)
access.log,access1.log(旧的),access2.log(更旧的)
根据时间或空间来滚动,在/etc/logrotate.d/httpd中定义
6、配置文件详解
主配置文件:/etc/httpd/conf/httpd.conf
格式:Directive Value
配置参数|指令 值
配置参数|指令字符不区分大小写,指令有可能区分大小写,有些指令可以重复出现多次,取其值的和
配置文件格式:(分三段)
### Section 1: Global Environment 全局配置
### Section 2: 'Main' server configuration 中心主机配置
### Section 3: Virtual Hosts 虚拟主机配置
中心主机和虚拟主机不能同时启用:默认启用的中心主机(经测试可以)
配置文件语法测试:
# service httpd configtest
# httpd -t
绝大多数配置修改后,可通过service httpd reload来使其生效
如果修改了ip和port,必须重启服务才能生效
1)指定监听地址和端口
Listen [IP:]80
(1)IP省略时表示监听本机上所有可用的ip地址:
(2)Listen指令可以出现多次,用于指明多个不同的监听端口或套接字
Listen 172.16.100.11:80
Listen 172.16.100.11:8080
2)持久连接:
连接建立后,每个资源获取结束不会断开连接,而继续等待其它资源请求并完成传输
如何断开?
数量限制:如100
时间限制:如30s
劣势:对并发访问量较大的服务器,开持久连接会有些请求得不到服务:
改进:简短,httpd-2.4支持毫秒级,
非持久连接:每个资源都是单独通过专用的连接进行获取
KeepAlive off|on
MaxKeepAliveRequests 100
KeepAliveTimeout 15
测试:
# telnet server 80
GET /URL HTTP/1.1
Host:serverip
[root@test_181 yum.repos.d]# telnet 172.16.100.181 80 Trying 172.16.100.181... Connected to 172.16.100.181. Escape character is '^]'. GET /welcome.sh http/1.1 Host:172.16.100.181 HTTP/1.1 200 OK Date: Mon, 28 Sep 2015 09:27:49 GMT Server: Apache/2.2.15 (CentOS) Last-Modified: Wed, 09 Sep 2015 11:06:29 GMT ETag: "780474-1d5-51f4e79725740" Accept-Ranges: bytes Content-Length: 469 Connection: close Content-Type: application/x-sh echo -e "You have entered the system: \033[31m\033$(ifconfig eth0|grep "inet addr"|cut -d: -f2|cut -d' ' -f1)\033[0m your username is: \033[31m$(whoami)\033[0m\n\033[31m\033[1m\033[5mWARNING:Proceed with caution! \033[0m\033[31m\033[1mHave any questions please contact the system administrator\033[0m" ################VIM############## mkdir ~/.Backup&>/dev/null cat>~/.vimrc<<EOF set nu set backup set backupext=.bak set backupdir=~/.Backup set patchmode=.orig EOF Connection closed by foreign host.
3)MPM
多路处理模块:并发请求响应的不同实现
prefork,worker,event
httpd-2.2不支持同时编译多个不同的MPM,rpm安装的httpd-2.2提供了三个文件分别用于实现提供对不同的MPM的支持
确认方式:# ps aux|grep httpd
默认为/usr/sbin/httpd,其为prefork;
查看模块列表:
httpd -l:查看静态编译的模块
httpd -M:查看所有模块,包括静态编译和DSO模块
更换支持不同的MPM的主程序:
# vi /etc/sysconfig/httpd启用变量:HTTPD=/usr/sbin/httpd:work|httpd:event
再重启httpd服务
# 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> # 如果prefork.c模块存在则这个容器中的配置有效,否则无效 StartServers 8 # 服务启动时会启动8个空闲进程 MinSpareServers 5 # 最少空闲进程的个数 MaxSpareServers 20 # 最大空闲进程的个数 ServerLimit 256 # 最大活动进程数 MaxClients 256 # 最多客户端并发请求 MaxRequestsPerChild 4000 # 每个子进程对多响应请求的次数 </IfModule> # worker MPM 112 # StartServers: initial number of server processes to start 113 # MaxClients: maximum number of simultaneous client connections 114 # MinSpareThreads: minimum number of worker threads which are kept spare 115 # MaxSpareThreads: maximum number of worker threads which are kept spare 116 # ThreadsPerChild: constant number of worker threads in each server process 117 # MaxRequestsPerChild: maximum number of requests a server process serves 118 <IfModule worker.c> 119 StartServers 4 120 MaxClients 300 #最大用户请求数 121 MinSpareThreads 25 #最少空闲线程数 122 MaxSpareThreads 75 123 ThreadsPerChild 25 #每个子进程最多生成线程数 124 MaxRequestsPerChild 0 #每个子进程响应请求的次数,0表示不限制 125 </IfModule>
4)DSO 动态共享对象
配置指令模块加载
LoadModule<module_name> <module_path>
模块路径:可使用相对路径,相对于ServerRoot指令指向的位置而言
注意:建议使用service httpd reload重新装载配置文件
5)定义‘Main’server的文档页面路径
DocumentRoot指令 配置站点根目录
Document指向的路径为URL其实的位置
6)配置页面访问属性
定义的方式有两种:
文件系统路径:
<Directory [~]"/PATH/TO/SOMEDIR">
....
</Diretory>
URL路径:
<Location [~]"URL">
...
</Location>
限制单个文件:
<File [~]"">
....
</File>
支持正则表达式(这种方式匹配正则速度快):
<LocationMatch "">
...
<LocationMatch>
<Direcotry "/path/to/somewhere">
Options: 选项(页面访问属性)
Indexes:缺少指定的默认页面时,允许将目录中的所有文件已列表形式返回给用户:危险
FollowsymLinks:允许跟随符号链接所指向的原始文件
None:所有都不启用
All:所有的都启用
ExecCGI:允许使用mod_cgi模块执行CGI脚本
Includes:允许使用mod_include模块实现服务器端包含(SSI)
IncludesNOEXEC:允许包含但不允许执行脚本
MultiViews:允许使用mod_negotiation实现内容协商
SymLinksIfOwnerMatch:在链接文件属主属组与原始文件的属主属组相同时,允许跟随符号连接所指向的原始文件
</Direcotry>
7)基于主机访问控制定义
<Direcotry "/path/to/somewhere">
(1)Options(页面访问属性)
Indexes:当访问的路径下无默认主页面文件存在,且没有指定具体要访问的资源时,会将此路径下的所有资源以列表呈现给用户:非常危险,不建议使用
FollowSymlinks:如果某页面文件为指向DocumentRoot之外路径上的其它文件时,将直接显示目标文件的内容
None:都不启用
All:所有的都启用
(2)基于来源地址访问控制
AllowOverride None|All 下面的选项是否被禁用,不禁用|禁用
Order:检查次序
Allow:允许
Deny:拒绝
Order Allow,Deny:只有明确Allow的来源地址,才允许访问,其它的均为Deny(白名单)
Order Deny,Allow:只有明确Deny的来源地址,才允许访问,其它的均为Allow(黑名单)
Allow from:允许访问的来源地址
Deny from:拒绝访问的来源地址
from后可跟上的地址格式:
IP地址:
网络地址:
all:(默认)
</Directory>
注意:最终匹配法则
如果列表中有多条Allow和Deny语句就把所有语句定义的加起来
如果一个IP在Allow和Deny中都没有定义那么就使用默认的,Order Allow,Deny默认是Deny
如果一个IP在Allow和Den中都有定义那么就使用默认的,Order Deny,Allow默认是Allow
例:
Options None AllowOverride None Order allow,deny Allow form 172.16.0.0/16 Deny form 172.16.100.177 Deny form 172.16.0.77
8)定义默认主页面
DirectoryIndex index.html index.html.var
自左而右,找到首次匹配到的文件,就将其作为默认主页面返回
9)用户目录
如果期望让每个用户都可以创建个人站点:http://Server_IP/~Username/
userdir disablied:禁止 建议禁止,安全
如果允许的话可以使用:userdir public_html
public_html是用户家目录下的目录名称,所有位于此目录中的文件均可通过前述的访问路径进行访问
前提:用户的家目录得赋予运行httpd进程的用户拥有执行权限
setfacl -m u:apache:x ~Username
10)配置日志功能
/var/log/httpd/
access.log:访问日志
error.log:错误日志
错误日志:
Errorlog logs/error_log
Loglevel warn
访问日志:要自定义日志格式
Customlog logs/access_log combined
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
combined 为此格式名称,方面后面可直接调用
%h:客户端地址
%l:客户端用户通过identd登录时使用的名称,一般为-(空)
%u:用户认证登录的名字,无登录机制一般-
%t:收到客户端请求时的时间
\":显示引号本身,而不作为引用符号
%r:请求报文首行
<method> <url> <version>
%>s:响应状态状态码
%b:响应报文的大小,单位为字节,不包含首部信息
%{Refer}i:记录Http首部Referer对应的值:即访问入口,从哪个页面跳转至此页面 “-”表示直接访问
%{User-Agent}i:记录http首部User-Aget对应的值,即浏览器类型
详情请参考:http://httpd.apache.org/docs/2.2/mod/mod_log_config.html
11)路径别名
Alias /URL/ "/path/to/some_directory/"
例如:Alias /bbs/ "/web/bbs/htdocs/"
就跟FTP的虚拟目录一样的咯
注意:前面的目录最后加“/",后面的目录也一定要加,前面不加,后面的也一定不要加,要保持一致
12)设定默认字符集
AddDefaultCharset UTF-8
常用字符集:GBK,GB2312,GBK18030
13)CGI脚本路径别名
CGI:Common Gateway Interface 通过网关接口协议
使WEB可以跟一个应用程序进行通信,从通信环境中获得结果
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
URL-->FileSystem Directory
CGI是不安全的,现在web站点一般都不用,很早以前mail服务可能还会使用,实现起来简便
在第一行写入
echo “Content-Type:text/html:
实现该功能的模块:
mod_alias
mod_cgi
ScriptAlias /URL/ "/path/to/somewhere" somewhere下的文件可以被执行,也可以在目录中实现
格式一般为:
cat << EOF
Content-Type:text/html
<pre>
The time is : `date`.
</pre>
EOF
14)基于用户的访问控制
虚拟用户:非系统用户,只是为了访问某个服务的资源所使用的认证标志
Idap:轻量级目录访问协议
质询:WWW-Authenticate:服务器用401状态拒绝客户端请求,说明需要用户提供用户名和密码,弹出对话框:
认证:Authorization:客户端用户填入帐号密码后再次发请求至服务器,认证通过,则请求授权
DocumentRoot "/var/www/html"
images
bbs
employee/
安全域:需要用户认证后方能访问的路径,应该有其名称,用户向用户通知此认证的原因等
http协议支持的认证方式:
basic:基本认证,BASE64,账号和密码明文发送
digest:摘要认证,hash编码之后发送
认证提供者(authentication provider):帐号和密码的存放位置,不定义默认是文件;authn
授权机制(authorization):根据什么进行授权
案例:认证机制实现
1)定义安全域
<Directory "/www/htdocs/fin">
Options None
AllowOverride AuthConfig|None
AuthType Basic 使用基本认证
AuthName "Private Area" 质询时标题
AuthBasicProvider file # 不写也可以
AuthUserFile /etc/http/conf/.htpasswd 密码文件的存放位置
Require valid-user 可访问的用户:所有位于AuthUserFile文件中定义的用户都允许登录
</Directory>
Require另一种实现方式:Require user tom jerry...:仅允许user1,user2等出现AuthUserFile文件中定义的特定几个用户登录
2)、提供用户的帐号文件
使用htpsswd命令用于维护此文件
htpasswd
-c 创建密码,创建第一个用户时创建帐号文件
-s 以sha格式加密存放
-m MD5格式加密存放
-b 批量模式
-D 删除用户
htpasswd -c -m /etc/http/conf/.htpasswd tom
3)、基于组认证
<Directory "/www/htdocs/fin">
options None
AllowOverride None
AuthType Basic 使用基本认证
AuthName "Private Area" 质询时标题
AuthUserFile /etc/http/conf/.htpasswd 密码的存放位置
AuthgroupFile /etc/http/conf/.htgroup 密码的存放位置
Require group GroupName 可访问的组
</Directory>
组文件:(手动创建)
每行定义一个组
先创建用户,在创建组
组名1:用户1 用户2 用户3
http协议认证与表单认证
15)虚拟主机
一个物理服务器可以服务于多个站点,每个站点可通过一个或多个虚拟机来实现
httpd三种类型的虚拟主机:
基于IP
基于PORT
基于FQDN(最常用)
注意:启用虚拟主机得先关闭“main” server # 经测试不关闭也可以,但如果80端口被虚拟主机占用了,那么想要"main server"只要指定另一个监听了的,没被虚拟主机占用的端口即可
方法:注释DocumentRoot指令即可
定义虚拟主机的方法:
<VirtualHost "IP:port">
ServerName (不基于主机名做虚拟主机时可不写)
ServerAlias(可不写)
DocumentRoot (一定要写)
<Directory "">
Options
</Directory>
</VirtualHost>
注意:大多数可用全局或‘main’server中的指令,都可以定义有Virtualhost中
基于IP时本机要配置这里指明的所有IP地址并能够通信
基于端口时要监听这里指明的所有端口
混用IP和PORT时,IP和port都要配置好
基于FQDN时,要启用NameVirtualhost IP:PORT (2.4版本不用)
额外经常用于每个虚拟主机的配置有:
ErrorLog
CustomLog
<Director>
<Location>
ServerAlias
基于端口(port):
基于IP:
基于FQDN:
注意:第三张图是没在虚拟主机中指定的
上面3个条件还可以任意混搭
16)URL Rewrite:URL重写
17)服务器内置的status页面
内生的status信息,且此信息可以通过 web予以显示
取消注释和定义访问控制即可:
<Location /server-status>
SetHandler server-status
Order deny,allow
All from all
</Location>
此信息不应该让别人看见,建议做用户认证