1、httpd配置文件的组成:
(1)# grep "Section" /etc/httpd/conf/httpd.conf 有三大部分:
### Section 1:Global Environment 全局环境
### Section 2:'Main' server configuration 主服务器的配置
### Section 3:Virtual Hosts 虚拟主机的配置(默认没有)
配置格式:directive value(变量 值)
directive: 不区分字符大小写
value: 为路径时,是否区分大小写,取决于文件系统
(2)一开始我们启动服务的时候,总是出现一句话说没有名字:
于是我们在配置文件中加入名字:
加什么名字都可以,理论上应该加网站名。
就没有那句话了。
2、显示服务器版本信息
使用curl -I能看到首部信息,但目前默认的显示会暴露当前服务的版本号,我们可以在配置文件中修改它的显示方式。
配置响应首部:
ServerTokensMajor|Minor|Min[imal]|Prod[uctOnly]|OS|Full(可能的值,默认是Full)
ServerTokensProd[uctOnly] : Server: Apache
ServerTokensMajor: Server: Apache/2
ServerTokensMinor: Server:Apache/2.0
ServerTokensMin[imal]: Server: Apache/2.0.41
ServerTokens OS: Server: Apache/2.0.41 (Unix)
ServerTokensFull (or not specified): Server:Apache/2.0.41 (Unix) PHP/4.2.2 MyMod/1.2
为了安全我们改成prod,保存退出,重新加载服务。
然后再查看一下
果然变成了只有Apache。
3、文件相对路径
在配置文件中这一段设置了Pid文件路径,run是相对路径,下面的所有相对路径都是上面定义的/etc/httpd:
4、修改监听的IP和Port
Listen [IP:]PORT
1) 省略IP表示为本机所有IP
2) Listen指令至少一个,可重复出现多次
Listen 80
Listen 8080
(1)设置一个端口
保存退出,重启服务。
然后我们可以去访问一下,由于改成了非标准端口,因此访问的时候需要在后面加端口号才可以:
修改成功。
(2)设置多个端口
两个端口都可以进行访问。
(3)绑定IP地址
这样,9527端口只能通过172.17.0.106访问,80端口只能通过192.168.37.106访问。
5、持久连接
PersistentConnection:连接建立,每个资源获取完成后不会断开连接,而是继续等待其它的请求完成,默认关闭持久连接
断开条件:数量限制:100
时间限制:以秒为单位, httpd-2.4支持毫秒级
副作用:对并发访问量较大的服务器,持久连接功能会使用有些请求得不到响应
折衷:使用较短的持久连接时间
设置:KeepAlive On|Off
KeepAliveTimeout 15 时间限制
MaxKeepAliveRequests 100 数量显示
测试:使用telnet可以测试它是否支持持久连接:
telnet WEB_SERVER_IP PORT
GET /URL HTTP/1.1
Host: WEB_SERVER_IP
列表里现在又4个文件
我们使用telnet获取一下index.html资源:
表示只能获取一个资源,然后就关闭连接了。
那现在我们改一下配置文件:
然后退出保存,重新加载。
再次使用telnet获取资源:
只要条件不到,就可以一直获取。
6、MPM( Multi-Processing Module)多路处理模块
prefork, worker,event(试验阶段)
httpd-2.2不支持同时编译多个模块,所以只能编译时选定一个;rpm安装的包提供三个二进制程序文件,分别用于实现对不同MPM机制的支持
确认方法:
ps aux | grep httpd
默认为/usr/sbin/httpd, 即prefork模式
(1)查看模块列表
查看静态编译的模块
httpd -l
查看静态编译及动态装载的模块
httpd –M
动态模块加载:不需重启即生效
动态模块路径
/usr/lib64/httpd/modules/
(2)更换使用的httpd程序:
/etc/sysconfig/httpd
HTTPD=/usr/sbin/httpd.worker
重启服务生效
pstree -p|grep httpd 查看进程和线程
里面有注释的这行,取消注释
保存退出,重启服务。
查看静态编译模块:
更换成功。
Httpd 2.4 与之不同
以动态模块方式提供
配置文件:/etc/httpd/conf.modules.d/00-mpm.conf
httpd –M |grepmpm
重启服务生效
pstree -p|grep httpd 查看进程和线程
(3)prefork设置
在配置文件httpd.conf中,有对prefork的设置:
StartServers:开启8个woeker进程
MinSpareServers:最小空闲进程当8个进程用光之前,会再提前准备5个空闲进程,如果快满了就再生成,保证一直有5个空闲进程
MaxSpareServers:最大空闲进程最多准备20个空闲进程以防万一
ServerLimit:最多进程数为256
MaxClients:最多客户数256
MaxRequestsPerChild:最大请求4000,一个进程响应4000次请求之后会自动销毁,再开启新的进程
那我们现在可以试一下把StartServers改为80
使用ps aux查看
过滤,再记一下数:
一共82,其中有一个master,还有一个是grep命令,所以开启的worker一共80个没错。
(4)worker设置
同样的,在配置文件httpd.conf中,有对prefork的设置:
StartServers:启动进程数
MaxClients:最大用户数为300,一个用户消耗一个线程,因此最多开启300个线程
MinSpareThreads:最小空闲线程
ThreadsPerChild:最大空闲线程
MaxRequestsPerChild:每个子进程开启的最大线程数为25
因为设置的最大空闲线程为75,每个子进程开启的最大线程数为25,所以启动时默认开启进程数应该是3个(即使设置了4个,过一会马上会关掉一个)
变成3个了。
7、DSO: Dynamic Shared Object
加载动态模块配置
/etc/httpd/conf/httpd.conf
配置指定实现模块加载格式:
LoadModule
模块文件路径可使用相对路径:
相对于ServerRoot(默认/etc/httpd)
想使用某个功能,必须先加载对应的模块,如果加载成功的话,在动态模块中有显示:
auth_basic_module就没有了:
这样就没办法使用功能了。
8、定义'Main' server(主站点)的文档页面路径
DocumentRoot“/path”
文档路径映射:
DocumentRoot指向的路径为URL路径的起始位置
注意:SELinux和iptables的状态
默认路径为/var/www/html
因为配置文件中这行代码:
所以你可以将它改为你想改的路径即可。
如果写了两行,那么后面一行会覆盖前面那行。即/app/site1文件夹生效。
我们之前说,除了/etc/httpd/conf/httpd.conf主配置文件以外,还有子配置文/etc/httpd/conf.d/*.conf,之所以也能生效是因为主配置文件中这行代码:
所以我们也可以把文档路径映射这行代码写在独立的自配置文件中。
建立一个test.conf文件,
只写上这行代码即可。
注意:如果不将主配置文件中原来那行/var/www/html路径代码注释掉的话,就要将Include conf.d/*.conf放在那句话后面,这样才能覆盖,才能生效。
9、定义站点主页面
DirectoryIndex index.html index.html.var
如果两个文件都没有的话,如果不是/var/www/html文件夹下,就会显示文件列表。
如果是/var/www/html文件夹下,就会显示主页面,因为在/etc/httpd/conf.d下有个文件叫welcome.conf文件
里面设置的去访问主页面noindex.html
如果这个welcome.conf没有了的话,那么同样也会显示目录结构:
这种情况很不安全,所以一般要有welcome文件并最好保证目录下有一个index.html文件。
10、站点访问控制常见机制
可基于两种机制指明对哪些资源进行何种访问控制
访问控制机制有两种:客户端来源地址,用户账号
(1)本地文件系统路径:
...
...
...
(2)URL路径:
这种包括斜线以及之后的就叫URL。
...
...
(3)示例:
11、中“基于源地址”实现访问控制
(1) Options:后跟1个或多个以空白字符分隔的选项列表
在选项前的+,- 表示增加或删除指定选项
常见选项:
Indexes:指明的URL路径下不存在与定义的主页面资源相符的资源文件时,返回索引列表给用户
FollowSymLinks:允许访问符号链接文件所指向的源文件
None:全部禁用
All: 全部允许
(PS:子目录会继承父目录的设置)
文件夹默认是支持软连接,不支持索引的
我们在子配置文件中添加代码:
设置让/app/site1文件夹下不支持软连接。
再加上indexes
就可以在没有index.html文件的情况下显示目录结构了
如果你也加个减号:
(2)AllowOverride
与访问控制相关的哪些指令可以放在指定目录下的.htaccess(由AccessFileName指定)文件中,覆盖之前的配置指令
只对
AllowOverrideAll: 所有指令都有效
AllowOverrideNone:.htaccess 文件无效
AllowOverrideAuthConfig Indexes 除了AuthConfig 和Indexes的其它指令都无法覆盖
如果你想拒绝软连接,除了上面的方法还有另一种方法。
还是编辑自配置文件,先让它允许让.htaccess文件覆盖所有的信息:
然后我们就要在/app/site1/bbs下建立一个.htaccess文件,然后在里面写上配置。
设置拒绝索引,拒绝软连接
然后重启一下服务,就都拒绝了索引了。
(3)order和allow、deny
放在directory,.htaccess中
order:定义生效次序;写在后面的表示默认法则
Order allow,deny (如果冲突,deny优先级高)
Order deny,allow (如果冲突,allow优先级高)
Allow from, Denyfrom
来源地址:
IP
网络: 172.16
172.16.0.0
172.16.0.0/16
172.16.0.0/255.255.0.0
其他没有被设定的地址就看优先级的高低了,如果deny优先级高的话,所有没有设置的地址都是拒绝的,如果allow优先级高的话,所有没有设置的地址都是允许的。
(4)正则匹配
12、日志设定
(1)日志类型:
(2)错误日志:
ErrorLog logs/error_log 日志路径
LogLevel warn 日志级别
loglevel可选值: debug, info, notice, warn,error,crit, alert, emerg(越往后越严重)
(3)访问日志:
定义日志格式:
LogFormat formatstringsLogFormat "%h %l %u %t \"%r\" %>s %b\"%{Referer}i\" \"%{User-Agent}i\"" combined
使用日志格式:
CustomLog logs/access_log combined
格式说明:
%h 客户端IP地址
%l 远程用户,启用mod_ident才有效,通常为减号“-”
%u 验证(basic,digest)远程用户,非登录访问时,为一个减号“-”
%t 服务器收到请求时的时间
%r First line of request,即表示请求报文的首行;记录了此次请求的“方法”,“URL”以及协议版本
%>s 响应状态码
%b 响应报文的大小,单位是字节;不包括响应报文http首部
%{Referer}i 请求报文中首部“referer”的值;即从哪个页面中的超链接跳转至当前页面的
%{User-Agent}i 请求报文中首部“User-Agent”的值;即发出请求的应用程序(浏览器的类型)
参考帮助http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats
13、设定默认字符集
AddDefaultCharsetUTF-8
中文字符集:GBK, GB2312,GB18030
设置:
查看:
14、定义路径别名
格式: Alias /URL/ "/PATH/"
https服务默认情况下,是访问/var/www/html目录的,当我们在此目录下再建一个目录叫bbs,并在里面写上页面内容
这样我们访问的时候只需要在后面多加一个bbs/就可以访问到这个文件夹下的页面:
那我们现在想要修改这个默认目录,可以让我们在访问192.168.37.106/bbs/的时候访问另外一个文件夹下的页面。
那我们在app目录下建一个文件夹叫bbsdir,文件夹下建个页面叫index.html
我们现在想通过192.168.37.106/bbs/访问到这个app/bbsdir文件夹下的index.html页面。那么就要用到路径别名技术。
在子配置文件中添加如下行:
保存退出,重新加载服务。
修改成功。
(PS:/bbs目录有没有都没关系,它都会指向/app/bbsdir的)
15、基于用户的访问控制
认证质询:WWW-Authenticate:响应码为401,拒绝客户端请求,并说明要求客户端提供账号和密码
认证:Authorization:客户端用户填入账号和密码后再次发送请求报文;认证通过时,则服务器发送响应的资源
认证方式两种:
basic:明文
digest:消息摘要认证兼容性差
安全域:需要用户认证后方能访问的路径;应该通过名称对其进行标识,以便于告知用户认证的原因
用户的账号和密码
虚拟账号:仅用于访问某服务时用到的认证标识
存储:文本文件,SQL数据库,ldap目录存储,nis等
(1)basic认证配置示例:
·定义安全域(大小写不敏感)
Options None 这行可以不写
AllowOverride None 这行也可以不写
AuthType Basic 选择认证方式
AuthName "String" 描述语句,弹出对话框的时候会显示
AuthUserFile "/PATH/HTTPD_USER_PASSWD_FILE" 用户账号密码所放文件的路径(文本需要实现准备好而且有格式要求)
Require user username1 username2 ... (在上面的文本中有很多账号,我们可以只指定其中的某一些可以访问)
(允许账号文件中的所有用户登录访问:Requirevalid-user)
·提供账号和密码存储(文本文件)
使用专用命令htpasswd完成此类文件的创建及用户管理
htpasswd[options] /PATH/HTTPD_PASSWD_FILE username
-c:自动创建文件,仅应该在文件不存在时使用
-m:md5格式加密,默认方式
-s::sha格式加密
-D:删除指定用户(或者也可以直接打开文件手动删除那行)
于是我们编写子配置文件:
可以查看一下文档:
是用不同加密方式建成的。
只有http1和hppt2能访问
设置成功。
如果想让文件中所有用户都可以访问,修改最后一句即可:
(PS:除了上面这个方法,还可以用之前的方法,把代码写在/secret/.htaccess中。
然后在子配置文件中加入下面代码,允许验证信息生效:
(2)基于组账号进行认证
·定义安全域
AuthType Basic
AuthName "String“
AuthUserFile "/PATH/HTTPD_USER_PASSWD_FILE"
AuthGroupFile "/PATH/HTTPD_GROUP_FILE" 组文件名
Require group grpname1 grpname2 ... 指定能访问的组
·创建用户账号和组账号文件;
组文件格式:每一行定义一个组
GRP_NAME:username1 username2 ...
在之前实验的基础上,先在子配置文件中添加两行代码
表示只有组2能访问
再建一个组的文件(推荐可以跟用户密码文件放在一个文件夹下):
创建一个.htgroups文件存放组信息:
保存退出,重新加载服务。
这样就建好了。也就是说现在只有http1和http3能访问了。
(3)远程客户端和用户验证的控制
Satisfy ALL|Any
ALL 客户机IP和用户验证都需要通过才可以
Any客户机IP和用户验证,有一个满足即可
示例:
Requirevalid-user
Order allow,deny
Allow from192.168.1
Satisfy Any
16、status页面
status页面主要记录了一些状态信息,我们默认是不能查看的,需要修改配置。
LoadModule status_modulemodules/mod_status.so 使用模块
SetHandlerserver-status
Order allow,deny
Allow from172.16
ExtendedStatus On 显示扩展信息
那么就可以使用这个功能了。
在主配置文件中,默认是被注释掉的:
我们将注释去掉即可使用了。
我们稍微修改一下,改成我们的主机地址:
保存退出,重新加载服务。
如果想看到更多信息,在主配置文件中,把这行注释也去掉即可:
17、虚拟主机※
(1)在一个服务器上可以建立多个站点,我们将每一个站点就叫做虚拟主机,每个虚拟主机内容是不一样的。
·站点标识: socket
IP相同,但端口不同
IP不同,但端口均为默认端口
FQDN不同;
请求报文中首部
Host: www.magedu.com
·有三种实现方案:
基于ip:为每个虚拟主机准备至少一个ip地址
基于port:为每个虚拟主机使用至少一个独立的port
基于FQDN:为每个虚拟主机使用至少一个FQDN
注意:一般虚拟机不要与main主机混用;因此,要使用虚拟主机,一般先禁用main主机
禁用方法:注释中心主机的DocumentRoot指令即可
(2)虚拟主机的配置方法:
ServerName FQDN
DocumentRoot “/path"
建议:上述配置存放在独立的配置文件中
其它可用指令:
ServerAlias:虚拟主机的别名;可多次使用
ErrorLog: 错误日志
CustomLog:访问日志
Alias
(3)示例:
·基于IP的虚拟主机:
ServerName www.a.com
DocumentRoot "/www/a.com/htdocs"
ServerName www.b.net
DocumentRoot "/www/b.net/htdocs"
ServerName www.c.org
DocumentRoot "/www/c.org/htdocs"
·基于端口的虚拟主机:可和基于IP的虚拟主机混和使用
listen 808
listen 8080
ServerName www.a.com
DocumentRoot "/www/a.com/htdocs"
ServerName www.b.net
DocumentRoot "/www/b.net/htdocs"
ServerName www.c.org
DocumentRoot "/www/c.org/htdocs"
·基于FQDN的虚拟主机:
NameVirtualHost*:80 httpd (2.4不需要此指令)
ServerName www.a.com
DocumentRoot "/www/a.com/htdocs"
ServerName www.b.net
DocumentRoot "/www/b.net/htdocs"
ServerName www.c.org
DocumentRoot "/www/c.org/htdocs"
(4)实验:
1)基于IP
我们先在自己的机器上加几个地址:
然后把每个地址和每个网站关联起来。
修改子配置文件:
保存退出,重新加载服务。
修改成功:
2)基于端口
修改子配置文件:
保存退出,重启网络服务,重新加载httpd服务。
修改成功:
3)基于FQDN
让这三个站点都对应这个IP
然后在服务器端修改子配置文件:
保存退出,重新加载服务。
可以看到,分别对应的日志文件已经生成。
访问一下地址:
设置成功。
如果现在要通过telnet访问的话,host就要写上具体的域名了。因为FQDN是靠报文首部来区分网站的,而不是靠地址。
(注意:此种设置后,访问主网址会显示第一个网站。
在子配置文件中,谁排在第一个谁就是默认站点,就显示谁。)