LAMP环境搭建与配置
LAMP是Linux Apache MySQL PHP的简写,即把Apache、MySQL以及PHP安装在Linux系统上,组成一个环境来运行PHP的脚本语言,通常是网站,比如阿铭的论坛ask.apelearn.com就是用PHP语言写出来的。至于什么是PHP脚本语言,阿铭在这里不再介绍。Apache是最常用的Web服务软件,而MySQL是比较小型的数据库软件,这两个软件以及PHP都可以安装到Windows的机器上。
14.1安装MySQL
我使用的是免编译二进制包。
建议以后把所有的软件包都放到这个目录下面
14.1.2 初始化
先解压缩
挪动位置
建立MySQL用户
创建datadir,存放数据库文件,更改权限
执行命令./scripts/mysql_install_db --user=mysql --datadir=mysql
当提示这个报错时,这是因为缺少包perl-Module-Install,使用yum install -y perl-Module-Install安装。
安装后再次执行命令./scripts/mysql_install_db --user=mysql --datadir=mysql
在执行完最后一条命令后,马上执行echo $? 看输出结果是否为0
或者是查看是否出现两个ok,如果有说明执行正确
14.1.3 配置 MySQL
首先复制配置文件
因为系统默认有/etc/my.cnf,所以会提示是否覆盖,直接按“y”即可。然后打开配置文件,做一些简单的配置,把配置文件改成如下内容:
其中,basedir是MySQL包所在的路径,datadir是定义的存放数据的地方、默认情况下,错误日志也会记录在这个目录下面。port定义MySQL服务监听的端口,如果不定义默认就是3306。server_id定义该MySQL服务的ID号,这个参数用在做主从配置的时候,后续会介绍。socket定义MySQL服务监听的套接字地址,在Linux系统下面,很多服务不仅可以监听一个端口(通过TCP/IP的方式通信),也可以监听socket,两个进程就可以通过这个socket文件通信。
然后复制启动脚本文件并修改其属性:
然后修改启动脚本:
把启动脚本加入系统服务项,设定开机启动并启动MySQL:
14.2 安装 Apache
Apache其实是一个软件基金会组织的名字,早期他们开发的Web Server软件非常流行,当时名字就叫做Apache,不过后来改名字叫作httpd了,所以,以后大家说Apache的时候说的就是httpd。
首先解压好下载的源码包
其中apr(包含apr和lapr-util)可以理解成一个通用的函数库,主要为上层应用提供支持。在这里,httpd是依赖apr和lapr-util的,如果不安装这两个东西,httpd就无法工作。先来安装apr以及apr-util:
看到这个报错使用 yum install -y libtool*,然后再次编译
返回值是0,安装成功。
看到这个报错时,使用yum install -y expat-devel 安装
安装之后先make clean
再重新安装
返回值是0,安装成功。
安装完apr以及apr-util,继续安装httpd:
这里,--prefix指定安装目录,--enable-so表示启用DSO。DSO的意思是,把某些功能以模块(一个功能模块就是一个so文件,这些文件在编译完httpd后会看到)的形式展现出来。enable-mods-shared=most表示以共享的方式安装大多数功能模块,安装后会在modules目录下面看到这些文件。因为选择了大多数,所以后面的编译时间就会大大增加。另外,为了避免在make的时候出现错误,你最好提前安装好一些库文件,如下所示:
安装成功后会在apache2.4目录下生成文件
前面以AH00558开头的行,并不是错误,仅仅是一个警告,你可以在配置文件中定义ServerName使其消失。这些带有shared字样的,表示该模块为动态共享模块;当然还有static字样的,它表示以静态的形式存在。动态和静态的区别在于,静态模块直接和主程序( /usr/local/apache2.4/bin/httpd)绑定在一起,我们看不到,而动态的模块都是一个个独立存在的文件( modules目录下面的.so文件即是)。
14.3 安装PHP
首先下载并解压源码包:
然后配置编译参数:
错误1
解决方法
错误2
解决方法
错误3
解决方法
错误4
解决方法
错误5
解决方法
然后编译安装
返回值为0,安装成功
最后复制配置文件
14.4 配置httpd支持PHP
httpd的主配置文件为/usr/local/apache2.4/conf/httpd.conf,编辑这个文件:
更改如下信息:
14.5 测试LAMP是否成功
httpd、MySQL和PHP安装之后,需要先检验httpd的配置文件是否正确,只有正确配置才可以正确解析PHP文件。
14.5.1测试配置文件是否正确
启动httpd之前需要检验配置文件是否正确:
启动httpd:
查看是否启动成功:
如果显示了这行则说明已经启动成功。
另外我们也可以使用curl命令进行简单的测试:
如果显示这行则说明测试成功。
14.5.2 测试是否正确解析PHP
首先编写一个测试脚本:
保存脚本后测试:
14.6 httpd配置
14.6.1 默认虚拟主机
先来解释“虚拟主机”,早期的Linux服务器上,一个服务器只能运行一个网站,也就是说只能跑一个域名。但随着技术的发展,一个服务器上可以跑多个域名了,这样可以帮助我们节省了成本。其实这里的服务器就叫做主机,早期一个主机对应一个站点。现在一个主机可以跑多个站点,所以就有了虚拟主机的概念。物品们可以报一台服务器虚拟出多个主机出来,这样就可以实现一台服务器上跑多个站点。
既然服务器上可以有多个虚拟主机,每个虚拟主机都会定义一个域名(当然也可以定义多个),只要把这个域名解析指向到该台服务器,我们自然就可以访问这个站点了。说到这儿,你可能又有新的问题:什么叫解析指向?咱们访问一个网站,需要在浏览器里面输入域名,然后就能访问到网站内容。这个过程是需要浏览器和远程服务器通信的,网站内容就是从服务器上读取到的。而这个服务器是由你访问的域名来决定在哪里的,而域名之所以能决定服务器在哪里,就是因为这个域名做了解析指向。域名解析服务器IP地址,这个行为是由DNS服务器来完成的。
假如你访问的域名指向了你的服务器,而你又在这台服务器上做了配置标记了这个域名,这样这个域名就能被正常访问。但如果没有在服务器上给这个域名做标记,按理说,没有做标记的域名是不合法的,是不能正常返回结果的。
上面讲了那么多关于域名的东西,目的就是更容易理解“默认虚拟主机”的概念。httpd有一个特点,它首先是支持多个虚拟主机的,也就是说可以在一个服务器上运行多个站点,标记多个域名。但如果没有标记的域名也指向了这台服务器,那总得有一个处理这个域名的虚拟主机吧。而这个虚拟主机就叫作“默认虚拟主机”。通俗点讲,你的服务器上有很多域名,很多站点,很多虚拟主机,这些域名都是在httpd的配置文件中做过标记的,都是“名花有主”的,都是一一对应的,每个域名都能对应着自己的虚拟主机。但是,有一个特殊的域名也指向了服务器,却没有跟它对应的虚拟主机。这时候,httpd就会把这个域名直接丢给一个特殊的虚拟主机来处理。那这个特殊的虚拟主机就是“默认虚拟主机”。
最后总结成一句话,任何一个域名指向这台服务器,只要是没有对应的虚拟主机,就会由这个默认虚拟主机来处理。编辑配置文件httpd.conf(这个是httpd服务的主配置文件):
搜索关键词httpd-vhost,找到这行把行首的#删除
保存主配置文件,然后编辑虚拟主机配置文件:
你可以先看看该文件最后面的两段(以<VirtualHost>开头,以</VirtualHost>结尾),这样一段就是一个虚拟主机,在这里面可以定义网站的域名和对应的网站程序所在目录。而默认虚拟主机就是第一个配置段,把该配置文件里面的两段</VirtualHost>重新编辑如下:
ServerAdmin指定管理员邮箱,这个没有什么实质作用,DocumentRoot为该虚拟主机站点的根目录,网站的程序就放在这个目录下面。ServerName为网站的域名,ServerAlias为网站的第二域名,ServerAlias后面的域名可以写多个,用空格分隔,但ServerName后面的域名不支持写多个。ErrorLog为站点的错误日志,CustomLog为站点的访问日志。
假如在虚拟主机配置文件中,我们只定义了两个站点——whr.com和123.com,那么当把第三个域名abc.com指向本机的时候,当在浏览器访问abc.com时,会去访问aming.com,也就是默认虚拟主机。我们不妨来做个测试下:
由此,可以看出默认虚拟主机为whr.com,不管把什么域名指向该服务器,只要配置文件中没有标记,就会访问这个默认虚拟主机。
14.6.2 用户认证
这个功能就是在用户访问网站的时候,需要输入用户名密码才能顺利访问。一些比较重要的站点或者网络后台通常会加上用户认证,目的是保证安全。先对123.com站点做一个全站的用户认证:
这样httpd的配置文件配置完成,但还需要创建密码文件:
配置完成后,需要到宿主机上修改hosts文件
14.6.3 配置域名跳转
这个用法比较普遍,一个网站可能会有多个域名,主要有两方面的作用:第一,一个站点有多个域名会对SEO有影响,说白了就是百度搜索关键词的排名有影响,如果把多个域名全部跳转到指定的一个域名,这样以这个域名为中心,就可以把权重集中在这个域名上,所以搜索关键词的排名也就靠前了;第二,如果之前的某个域名不再使用了,但是搜索引擎还留着之前老域名的链接,这意味着用户可能会搜到我们的网站并且点击老的域名,固需要把老域名做个跳转跳到新域名.这样用户搜的时候,也可以访问到网站。
在RewriteRule里是有正则表达式存在的,这和第11章的正则异曲同工。RewriteRule后面由空格划分成三部分,第一部分为当前的URL(也就是网址),不过这个URL是不把主机头(也就是域名)算在内的。第二部分为要跳转的目标地址,这个地址可以写全(包含了主机头),当然也可以不加主机头,默认就是前面定义的ServerName。第三部分为一些选项,需要用方括号括起来,301为状态码,它称作“永久重定向”(还有一种跳转用的状态码为302,叫作“临时重定向”),L表示“last”,意思是跳转一次就结束了。要实现域名跳转,需要有rewrite模块支持,所以先查看httpd是否已经加载该模块,如果没有还需要配置:
如没有任何输出,则需要编辑配置文件:
搜索rewrite,找到那行把前面的#删除
配置完后,进行测试:
可以看到状态码为301,跳转后的网址为http://www.123.com/。
14.6.4 配置访问日志
访问日志作用很大,不仅可以记录网站的访问情况,还可以在网站有异常发生时帮助我们定位问题,比如当有攻击时,是可以通过查看日志看到一些规律的。要配置httpd访问日志,首先要在主配置文件中定义访问日志的格式,打开主配置文件:
搜索LogFormat
可以看到两个格式的日志,建议使用第一个,记录的信息会更全。%为访问网站的IP;%l为远程登录名,这个字段基本上为“-";%u为用户名,当使用用户认证时,这个字段为认证的用户名;%t为时间;%r为请求的动作(比如用curl -I时就为HEADE );%s为请求的状态码,写成%>s为最后的状态码;%b为传输数据大小;%{Referer}i为referer信息(请求本次地址上一次的地址就为referer,%[User-Agent}i为浏览器标识,比如你用Firefox或者Chrome浏览器,则该字段显示内容不一样,是带有浏览器的标识的。对于这个日志格式,你可以自定义调整各个字段的位置,也可以额外增加其他字段,比如可以增加‰D(请求耗费时间)。
然后继续编辑虚拟主机配置文件:
保存配置文件后,测试语法并重新加载配置:
再次curl,发现生成了日志,并且有相关的日志记录。
使用火狐浏览器访问一下,再次查看日志,发现又多了一行:
一个网站会有很多元素,尤其是图片、js、css等静态的文件非常多,用户每请求一个页面就会访问诸多的图片、js等静态元素,这些元素的请求都会被记录在日志中。如果一个站点访问量很大,那么访问日志文件增长会非常快,一天就可以达到几GB。这不仅对于服务器的磁盘空间造成影响,更重要的是会影响磁盘的读写速度。访问日志很重要,我们又不能不记录。还好这些巨量的静态元素请求记录到日志里意义并不大,所以可以限制这些静态元素去记录日志,并且需要把日志按天归档,一天一个日志,这样也可以防止单个日志文件过大。配置如下:
先定义了一个image-request环境变量,把gif、jpg 、png、bmp、swf、js、css等格式的文件全部归类到image-request里,后面的env=!image-request有用到一个“!”,这相当于取反了,意思是把image-request以外的类型文件记录到日志里。
正常应该CustomLog后面为日志文件名,但在这里阿铭用了一个管道,它会把日志内容交给后面的rotatelogs命令处理。这个rotetelogs为httpd自带切割日志的工具,它会把访问日志按我们定义的文件名格式进行切割,其中86400单位是“秒”,相当于“一天”。保存配置文件后,测试配置文件是否有错误,没有错误重新加载服务。
再次访问,生成新的日志:
这里的123.com-access_20201118.log就是新生成的日志,而且以后每天生成一个按日期命名的日志。下面再来测试一下“在日志不记录静态元素”的配置:
可以看到,123.com-access_20201118.log日志中只有whr.txt的请求日志,但没有whr.jpg的请求日志。
14.6.5 配置静态文件元素过期时间
这部分配置用到了mod_expires模块,相关配置内容并不难理解,通过字面也可以大致猜到其含义。这里gif、jpeg.png格式的文件过期时长为1天, css、js、flash格式的文件过期时长为2小时,其他文件过期时长为0,也就是不缓存。保存配置文件,检查配置是否有问题,没问题重新加载服务:
检查httpd是否加载expires模块:
没有任何输出,说明当前httpd并不支持expires模块,所以需要修改配置文件,搜索expires关键词,找到下面这行,把最前面的#删除
重新加载服务:
下面,使用curl来测试它的效果:
可以看到max-age=86400,这说明jpg的图片将缓存86400秒,也就是一天。
另外也可以测试一下txt的文件:
其中max-age=0,说明没有缓存该类型的文件
14.6.6 配置防盗链
防盗链,通俗讲,就是不让别人盗用你网站上的资源。这个资源,通常指的是图片、视频、歌曲、文档等。讲解防盗链配置之前,先了解一下referer的概念,你通过A网站的一个页面http://a.com/a.html里面的链接去访问B网站的一个页面http:/b.com/b.html,那么这个B网站页面的referer就是http:/a.com/a.html。也就是说,一个referer其实就是一个网址。下面配置防盗链:
编辑虚拟主机文件:
首先定义允许访问链接的referer,其中^$为空referer,当直接在浏览器里输入图片地址去访问它时,它的referer就为空。然后又使用filesmatch来定义需要保护的文件类型,访问txt 、doc , mp3 .zip、rar、jpg、gif格式的文件,当访问这样类型的文件时就会被限制。下面是测试过程:
使用-e来定义referer,这个referer一定要以http://开头,否则不管用
使用非允许的referer会返回403的状态码
访问HTML类型的文件,也不会被保护
14.6.7 访问控制
对于一些比较重要的网站内容,除了可以使用用户认证限制访问之外,还可以通过其他一些方法做到限制,比如可以限制IP,也可以限制user_agent。限制P指的是限制访问网站的来源IP,而限制user agent。通常用来限制恶意或者不正常的请求。编辑配置文件:
使用<Directory>来指定要限制访问的目录,order定义控制顺序,哪个在前面就先匹配哪个规则。在本例中deny在前面,所以先匹配Deny from all,这样所有的来源IP都会被限制,然后匹配Allow from127.0.0.1,这样又允许了127.0.0.1这个IP。最终的效果是,只允许来源IP为127.0.0.1的访问。下面为验证过程:
也可以单独针对某个文件来做限制:
对于使用PHP语言编写的网站,有一些目录是有需求上传文件的。如果网站代码有漏洞,让黑客上传了一个用PHP代码写的木马,由于网站可以执行PHP程序,最终会让黑客拿到服务器权限。为了避免这种情况发生,我们需要把能上传文件的目录直接禁止解析PHP代码(不用担心会影响网站访问,若这种目录也需要解析PHP,那说明程序员不合格),配置如下:
添加下列代码:
验证过程如下:
这说明1.php是不能正常解析的。 下面是针对user_agent来做访问控制:
增加上述配置,这个需求也用到了rewrite模块,%(HTTP_USER_AGENT}为user_agent的内置变量,在本例中当user_agent匹配curl或者baidu.com时,都会触发下面的规则。方括号中的OR表示“或者”,NC表示“不区分大小写”,F相当于Forbidden。验证过程如下:。
curl的-A选项指定user_agent。第一个请求,user_agent为“curl7.29.0”匹配了第一个条件,所以会403;第二个请求,user_agent为自定义的“123123”没有匹配任何条件,所以状态码为200。
14.7 PHP配置
虽然PHP是以httpd一个模块的形式存在的,但是PHP本身也有自己的配置文件,查看PHP配置文件所在位置的命令为:
php.ini为PHP的配置文件,可以看出其在/usr/local/phpletc/php.ini,warning为警告信息,可以忽略,取消这个警告需要编辑php.ini,找到date.timezone设置如下:
14.7.1 PHP的disable_functions
PHP有诸多内置的函数,有一些函数(比如exec )会直接调取Linux系统命令,如果开放将会非常危险。因此,基于安全考虑应该把一些存在安全风险的函数禁掉:
重启httpd服务使其生效:
14.7.2 配置error_log
PHP的日志对于程序员来讲非常重要,他是排查问题的重要手段,设置PHP错误日志,有诸多步骤:
vim /usr/local/ php/etc/ php.ini
//搜素log_errors,改成如下
log_errors - On
//再搜素error_log,改为
error_log - /var/log/ php/ php_errors.log
//再搜索error_reporting,改为
error_reporting = E_ALL& ~E_NOTICE
//再搜索display_errors,改为
display_errors =off
log_errors可以设置为on或者off,如果想让PHP记录错误日志,需要设置为on。error_log设定错误日志路径;error_reporting设定错误日志的级别,E_ALL为所有类型的日志,不管是提醒还是警告都会记录。在开发环境下面设置为E_ALL,可以方便程序员排查问题,但也会造成日志记录很多无意义的内容。&符号表示并且,~表示排除,所以两个组合在一起就是在E_ALL的基础上排除掉notice相关的日志。display_errors设置为on,则会把错误日志直接显示在浏览器里,这样对于用户访问来说体验不好,而且还会暴露网站的一些文件路径等重要信息,所以要设置为off。设置完php.ini,还需做一些额外的操作:
下面做一个演示:
故意把结尾的;丢掉
出现了状态码500,这说明我们访问的页面是存在错误的,此时需要查看PHP的错误日志来判定错误原因:
通过日志可以判断,test.php文件第三行少了分号。
14.7.3 配置open_baseedir
一个服务器上跑很多网站,这是几乎所有小公司为节省成本采用的做法,但这样做也会有一些弊端:多个网站跑在同一个服务器上,如果其中一个网站被黑,很有可能连累到其他站点。还好PHP有一个概念叫作open_basedir,它的作用是将网站限定在指定目录里,就算该站点被黑了,黑客只能在该目录下面有所作为,而不能左右其他目录。如果你的服务器上只有一个站点,那可以直接在php.ini中设置open_basedir参数。但如果服务器上跑的站点比较多,那在php.ini中设置就不合适了,因为在php.ini中只能定义一次,也就是说所有站点都一起定义限定的目录,那这样似乎起不到隔离多个站点的目的。先来看如何在php.ini中设置open_basedir :
open_basedir可以是多个目录,用:分隔,先来验证open_basedir的作用吧。因为已经限制PHP只能在/tmp和/data/wwwroot/www.123.com两个目录下面活动,所以这次拿whr.com来演示:
发现whr.com/1.php不能访问,状态码为500,所以查看一下错误日志,得到信息如下:
下面给单个虚拟主机设置open——basedir:
起作用的就是这句php_admin_value,它可以定义php.ini里面的参数,除此之外像error_log之类的也可以定义。这样就可以实现,一个虚拟主机定义一个open_basedir。
14.8 PHP动态扩展模块安装
编译httpd时,有涉及动态和静态模块,其实PHP也一样有这样的说法。在本章PHP安装时,所有的模块全部都为静态,并没有任何动态的模块。所谓动态,就是一个独立存在的.so文件,在httpd中PHP就是以动态模块的形式被加载的。PHP一旦编译完成后,要想再增加一个功能模块的话,要么重新编译PHP,要么直接编译一个扩展模块(生成一个.so文件),然后在php.ini中配置一下,就可以被加载使用了。首先,你应该学会查看PHP都加载了哪些功能模块:
下面安装一个PHP的redis扩展模块:
进入/usr/local/src目录,下载扩展包
解压压缩包,并进入目录
使用phpize生成./configure文件
查看扩展模块存放目录
怎能国家一行配置,可以放到文件最后一行
步骤虽然多,但并不复杂。以后你遇到增加扩展模块的需求,都可以按照此方法安装。另外,要想在PHP网站使用redis模块,还需要重启一下httpd服务。