欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LAMP环境搭建与配置(三)

程序员文章站 2024-02-21 16:52:22
...

配置防盗链

防盗链,通俗讲,就是不让别人盗用网站上的资源,这个资源通常是指图片、视频、歌曲、文档等。
防止有人利用网站文件上传的功能,把一些静态媒体资源放到我们的网站上,然后在他们的网站上设置这些资源的链接到我们的网站上,当他们网站用户访问这些资源时,就会跳转到我们的服务器上,导致我们的服务器带宽流量异常增大。为了防止这种情况发生,我们利用apache服务器访问控制实现防盗链功能。

  • 配置虚拟主机配置文件:
<VirtualHost *:80>
    ServerAdmin [email protected]123.com
    DocumentRoot "/data/wwwroot/123.com"
    ServerName 123.com
    ServerAlias www.123.com
    CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/123.com-access_%Y%m%d.log 86400" combined
    <Directory /data/wwwroot/123.com>
      SetEnvIfNoCase Referer "http://www.123.com" local_ref   //指定referer白名单
      SetEnvIfNoCase Referer "http://123.com" local_ref   //指定referer白名单
      SetEnvIfNoCase Referer "^$" local_ref   //空的referer也能访问
      <FilesMatch "\.(txt|doc|mp3|zip|rar|jpg|gif)">   //定义保护文件类型
         Order Allow,Deny    //访问控制顺序,先允许后拒绝。
         Allow from env=local_ref   //只有符合白名单上的referer才能访问123.com目录。
      </FilesMatch>
    </Directory>

referer指的是访问该网站时上一次访问某个网站的网址,^$表示空referer,当直接在浏览器输入图片地址去访问它时,它的referer就为空

  • 验证上面配置:
[[email protected] ~]# curl -x127.0.0.1:80 -I -e "http://www.123.com/123.txt" http://www.123.com/1.jpg    //-e 定义referer,这个referer一定要以http://开头,否则不管用
HTTP/1.1 403 Forbidden
Date: Sun, 01 Jul 2018 01:24:44 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
X-Powered-By: PHP/5.6.36
Content-Type: text/html; charset=UTF-8

使用非允许的referer会返回403的状态码

[[email protected] ~]# curl -x127.0.0.1:80 -I -e "http://www.123.com/123.txt" http://www.123.com/index.html   
HTTP/1.1 200 OK
Date: Sun, 01 Jul 2018 01:26:20 GMT
Etag:"8-53ceaf03230b4"
Accept-Ranges:bytes
Content-Length8
Content-Type:text/html

访问html类型的文件时,不会被禁止

访问控制

对于比较重要的网站内容,除了可以使用用户认证限制访问之外,还可以限制IP和限制user_agent,限制IP指的是限制访问网站的来源IP,而限制user_agent,通常用来限制恶意或者不正常的请求。

IP

对目录做访问控制:
  • 配置虚拟主机配置文件:
[[email protected] ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf 
<VirtualHost *:80>
    ServerAdmin [email protected]123.com
    DocumentRoot "/data/wwwroot/123.com"
    ServerName 123.com
    ServerAlias www.123.com
    CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/123.com-access_%Y%m%d.log 86400"
 combined
   <Directory /data/wwwroot/123.com/admin/>    //指定要限制访问的目录
    Order deny,allow        //order定义控制顺序,哪个在前就先匹配哪个规则
    Deny from all       //所有的来源IP都被限制
    Allow from 127.0.0.1       //允许来源为127.0.0.1的访问
    </Directory>
    ErrorLog "logs/123.com-error_log"
    CustomLog "logs/123.com-access_log" common
</VirtualHost>
[root@localhost ~]# mkdir /data/wwwroot/123.com/admin/    //创建admin目录,模拟后台
[root@localhost ~]# echo "admin" > /data/wwwroot/123.com/admin/index.html    //在后台目录创建文件,并写入内容
[root@localhost ~]# > /usr/local/apache2.4/logs/123.com-access_20180701.log     //清空当天的访问日志
  • 验证上面配置:
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl graceful
[root@localhost ~]# curl -x192.168.100.140:80 -I 123.com/admin/index.html
HTTP/1.1 403 Forbidden        //IP为192.168.100.140的访问被禁止
Date: Sun, 01 Jul 2018 03:28:28 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
Content-Type: text/html; charset=iso-8859-1
[root@localhost ~]# curl -x127.0.0.1:80 -I 123.com/admin/index.html
HTTP/1.1 200 OK        //IP为127.0.0.1的访问被允许
Date: Sun, 01 Jul 2018 03:31:47 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
Last-Modified: Sun, 01 Jul 2018 03:13:45 GMT
ETag: "6-56fe7780401e4"
Accept-Ranges: bytes
Content-Length: 6
Content-Type: text/html
[root@localhost ~]# tail -1 /usr/local/apache2.4/logs/123.com-access_20180701.log 
192.168.100.1 - - [01/Jul/2018:11:32:58 +0800] "GET /admin/ HTTP/1.1" 403 215 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5514.400 QQBrowser/10.1.1660.400"    //可以看到Windows机器上的访问记录,我这里是QQ浏览器

用Windows机器在浏览器*问:
LAMP环境搭建与配置(三)
显示Forbidden,无法访问到123.com/admin/目录

对文件做访问控制:
  • 配置虚拟主机配置文件:
[[email protected] ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf
<VirtualHost *:80>
    ServerAdmin [email protected]123.com
    DocumentRoot "/data/wwwroot/123.com"
    ServerName 123.com
    ServerAlias www.123.com
    CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/123.com-access_%Y%m%d.log 86400" combined
   <Directory /data/wwwroot/123.com>
    <FilesMatch "admin.php(.*)">    //指定要限制访问的文件
    Order deny,allow        //order定义控制顺序,哪个在前就先匹配哪个规则
    Deny from all        //所有的来源IP都被限制
    Allow from 127.0.0.1     //允许来源为127.0.0.1的访问
    </FilesMatch>
    </Directory>
    ErrorLog "logs/123.com-error_log"
    CustomLog "logs/123.com-access_log" common
</VirtualHost>
  • 验证上面配置:
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl graceful
[root@localhost ~]# curl -x192.168.100.140:80 -I '123.com/admin.php?asadfwepf' 
HTTP/1.1 403 Forbidden       //IP为192.168.100.140的访问被禁止
Date: Sun, 01 Jul 2018 03:58:00 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
Content-Type: text/html; charset=iso-8859-1
[root@localhost ~]# curl -x127.0.0.1:80 -I '123.com/admin.php?asadfwepf' 
HTTP/1.1 404 Not Found       //IP为127.0.0.1的访问被允许,404表示已经可以访问,但找不到对应的文件,因为这里我并没有去创建这个文件
Date: Sun, 01 Jul 2018 03:58:35 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
Content-Type: text/html; charset=iso-8859-1

除了可以对目录和文件做访问控制外,我们还可以把能上传文件的目录禁止解析PHP代码,对于使用PHP语言编写的网站,这样做无疑更加安全。

  • 配置虚拟主机配置文件:
[[email protected] ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf 
<VirtualHost *:80>
    ServerAdmin lzx@123.com
    DocumentRoot "/data/wwwroot/123.com"
    ServerName 123.com
    ServerAlias www.123.com
    CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/123.com-access_%Y%m%d.log 86400" combined
   <Directory /data/wwwroot/123.com/upload>
   php_admin_flag engine off
   # <FilesMatch "admin.php(.*)">
   # Order deny,allow
   # Deny from all 
   # Allow from 127.0.0.1
   # </FilesMatch>
    </Directory>
    ErrorLog "logs/123.com-error_log"
    CustomLog "logs/123.com-access_log" common
</VirtualHost>
  • 验证上面配置:
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl graceful
[root@localhost ~]# mkdir /data/wwwroot/123.com/upload
[root@localhost ~]# cp /usr/local/apache2.4/htdocs/1.php /data/wwwroot/123.com/upload/
[root@localhost ~]# curl -x127.0.0.1:80 123.com/upload/1.php
<?php
  echo "php解析正常";       //这里显示的是代码,说明1.php无法正常解析
?>

user_agent

user_agent就是指浏览器标识,当用curl访问时,user_agent为“curl/7.29.0”,针对user_agent可以限制一些访问,例如蜘蛛爬虫或cc攻击,这一类的恶意请求的user_agent相同或者类似,这样我们就可以限制user_agent发挥防攻击的作用。

  • 配置虚拟主机配置文件:
[root@localhost ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf 
<VirtualHost *:80>
    ServerAdmin lzx@123.com
    DocumentRoot "/data/wwwroot/123.com"
    ServerName 123.com
    ServerAlias www.123.com
    CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/123.com-access_%Y%m%d.log 86400" combined
    <IfModule mod_rewrite.c>  //用到rewrite模块
      RewriteEngine on   //打开rewrite模块功能
      RewriteCond %{HTTP_USER_AGENT} .*curl.* [NC,OR]    //%{HTTP_USER_AGENT}为user_agent的内置变量 ,NC表示不区分大小写,OR表示 或者 
      RewriteCond %{HTTP_USER_AGENT} .*baidu.com.* [NC]      //匹配了curl 和 baidu.com
      RewriteRule .* - [F]   //指定规则,F表示Forbidden
    </IfModule>
   # <Directory /data/wwwroot/123.com/upload>
   # php_admin_flag engine off
   # <FilesMatch "admin.php(.*)">
   # Order deny,allow
   # Deny from all 
   # Allow from 127.0.0.1
   # </FilesMatch>
   # </Directory>
    ErrorLog "logs/123.com-error_log"
    CustomLog "logs/123.com-access_log" common
</VirtualHost>
  • 验证上面配置:
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl -t
Syntax OK
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl graceful
[root@localhost ~]# curl -x127.0.0.1:80 -I 123.com/upload/1.php
HTTP/1.1 403 Forbidden     //curl的user_agent被禁止
Date: Sun, 01 Jul 2018 04:33:24 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
Content-Type: text/html; charset=iso-8859-1
[root@localhost ~]# curl -A "123" -x127.0.0.1:80 -I 123.com/upload/1.php   //-A 指定user_agent
HTTP/1.1 200 OK       //指定user_agent为123之后,访问成功
Date: Sun, 01 Jul 2018 04:34:48 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
X-Powered-By: PHP/5.6.36
Content-Type: text/html; charset=UTF-8

11.6 PHP配置

PHP虽然是作为httpd的一个模块的形式存在的,但PHP也有自己的配置文件

查看PHP配置文件所在位置:

[[email protected] ~]# /usr/local/php/bin/php -i |grep -i "loaded configuration file"
PHP Warning:  Unknown: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Unknown on line 0
Loaded Configuration File => /usr/local/php/etc/php.ini

PHP.ini为PHP的配置文件,可以看出它在/usr/local/php/etc/php.ini ,第一行是警告信息,可以取消

[root@localhost ~]# vim /usr/local/php/etc/php.ini
date.timezone = Asia/Shanghai  //找到data.timezone(设置时区参数),做这样设置
[root@localhost ~]# /usr/local/php/bin/php -i |grep -i "loaded configuration file"
Loaded Configuration File => /usr/local/php/etc/php.ini

PHP的disable_functions

PHP有很多内置的函数,有一些函数(如exec)会直接调用Linux系统命令,开放的话会比较危险,因此基于安全考虑要禁掉。

[root@localhost ~]# vim /usr/local/php/etc/php.ini
disable_functions = eval,assert,popen,passthru,escapeshellarg,escapeshellcmd,passthru,exec,system,chroot,scandir,chgrp,chown,escapeshellcmd,escapeshellarg,shell_exec,proc_get_status,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,leak,popepassthru,stream_socket_server,popen,proc_open,proc_close

更改完配置,需要重启httpd服务使其生效:

[root@localhost ~]# /usr/local/apache2.4/bin/apachectl restart

配置error_log

PHP的日志对于程序员来讲非常重要,是排错的重要手段。

  • 设置PHP错误日志,有诸多步骤:
[[email protected] ~]# vim /usr/local/php/etc/php.ini
log_errors = On      //搜索log_errors ,改为 on
error_log = /var/log/php/php_errors.log      //搜索error_log 改为/var/log/php/php_errors.log
error_reporting = E_ALL & ~E_NOTICE    //搜索error_reporting,改为E_ALL & ~E_NOTICE
display_errors = Off       //搜索display_errors,改为off

logs_errors 可以设置为on或off,如果想让PHP记录错误日志,就设置为on
error_log 设定错误日志路径
error_reporting 设定错误日志的基本,E_ALL为所有类型的日志,不管是提醒还是警告都会记录,&表示并且,~表示排除,即在E_ALL的基础上排除notice相关的日志
display_errors 设置为on,则会把错误日志直接显示在浏览器里,这对用户来说体验不好,还会暴露网站相关信息,因此设置为off

  • 配置完php.ini后,还需要做一些额外操作:
[root@localhost ~]# mkdir /var/log/php
[root@localhost ~]# chmod 777 /var/log/php     //需要保证PHP的错误日志所在目录存在,且权限为可写
[root@localhost ~]# /usr/local/apache2.4/bin/apachectl graceful
  • 验证上面配置:
[[email protected] ~]# vim /data/wwwroot/123.com/3.php
<?php
echo lzx
[[email protected] ~]# curl -A "123" -x127.0.0.1:80 -I 123.com/3.php
HTTP/1.0 500 Internal Server Error         //说明访问的页面存在错误
Date: Sun, 01 Jul 2018 05:35:42 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
X-Powered-By: PHP/5.6.36
Connection: close
Content-Type: text/html; charset=UTF-8
  • 查看日志来判断错误原因:
[[email protected] ~]# cat /var/log/php/php_errors.log 
[01-Jul-2018 13:35:42 Asia/Shanghai] PHP Parse error:  syntax error, unexpected end of file, expecting ',' or ';' in /data/wwwroot/123.com/3.php on line 4

通过日志可以判断,3.php文件第四行少了个分号

[[email protected] ~]# vim /data/wwwroot/123.com/3.php
<?php
echo lzx;     //给3.php增加分号
[[email protected] ~]# curl -A "123" -x127.0.0.1:80 -I 123.com/3.php
HTTP/1.1 200 OK         //访问成功
Date: Sun, 01 Jul 2018 05:39:59 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
X-Powered-By: PHP/5.6.36
Content-Type: text/html; charset=UTF-8

配置open_basedir

一个服务器上可以跑很多个网站,但是这样做会有一些弊端,因为如果一个网站被黑,那很有可能波及到很多站点。

不过PHP有open_basedir,它的作用是将网站限定在指定目录里,就算某站点被黑,黑客也只能在该目录下活动,而不能左右其他目录。

  • 在php.ini中设置open_basedir(只能定义一次):
[root@localhost ~]# vim /usr/local/php/etc/php.ini
open_basedir = /tmp:/data/wwwroot/123.com    //搜索 open_basedir,改成/tmp:/data/wwwroot/123.com    

open_basedir可以是多个目录,用:分隔,上面已经限制PHP只能在/tmp和/data/wwwroot/123.com两个目录下面里面活动

  • 验证上面配置:
[[email protected] ~]# /usr/local/apache2.4/bin/apachectl graceful
[[email protected] ~]# cp /usr/local/apache2.4/htdocs/1.php /data/wwwroot/abc.com/
[[email protected] ~]#  curl -A "123" -x127.0.0.1:80 -I abc.com/1.php
HTTP/1.0 500 Internal Server Error
Date: Sun, 01 Jul 2018 05:56:56 GMT
Server: Apache/2.4.33 (Unix) PHP/5.6.36
X-Powered-By: PHP/5.6.36
Connection: close
Content-Type: text/html; charset=UTF-8

发现abc.com/1.php 不能访问,状态码为500

  • 查看错误日志:
[01-Jul-2018 13:56:56 Asia/Shanghai] PHP Warning:  Unknown: open_basedir restriction in effect. File(/data/wwwroot/abc.com/1.php) is not within the allowed path(s): (/tmp:/data/wwwroot/123.com) in Unknown on line 0
[01-Jul-2018 13:56:56 Asia/Shanghai] PHP Warning:  Unknown: failed to open stream: Operation not permitted in Unknown on line 0
[01-Jul-2018 13:56:56 Asia/Shanghai] PHP Fatal error:  Unknown: Failed opening required '/data/wwwroot/abc.com/1.php' (include_path='.:/usr/local/php/lib/php') in Unknown on line 0

上面表明限制成功

我们还可以给单个虚拟主机配置open_basedir。

对于php.ini里面的配置,在httpd.conf也是可以设置的:

[root@localhost ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf 
<VirtualHost *:80>
    ServerAdmin lzx@123.com
    DocumentRoot "/data/wwwroot/123.com"
    ServerName 123.com
    ServerAlias www.123.com
    CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/123.com-access_%Y%m%d.log 86400" combined
    php_admin_value open_basedir "/data/wwwroot/123.com/:/tmp/"       //php_admin_value 可以定义php.ini里面的参数
   # <IfModule mod_rewrite.c>
     #  RewriteEngine on 
     # RewriteCond %{HTTP_USER_AGENT} .*curl.* [NC,OR]
     # RewriteCond %{HTTP_USER_AGENT} .*baidu.com.* [NC]
     # RewriteRule .* - [F]
   # </IfModule>
   # <Directory /data/wwwroot/123.com/upload>
   # php_admin_flag engine off
   # <FilesMatch "admin.php(.*)">
   # Order deny,allow
   # Deny from all 
   # Allow from 127.0.0.1
   # </FilesMatch>
   # </Directory>
    ErrorLog "logs/123.com-error_log"
    CustomLog "logs/123.com-access_log" common
</VirtualHost>

起作用的是php_admin_value ,除此之外的像error_log之类的也可以定义,这样就可以实现,一个虚拟主机定义一个open_basedir


11.7 PHP动态扩展模块安装:

编译httpd时,有涉及到动态和静态模块,其实PHP也有。在之前PHP安装时,所有的模块全部为静态模块,没有动态模块。所谓动态,就是一个单独存在的.so文件,在httpd中PHP就是以动态模块的形式被加载的。

PHP一旦编译完成后,想要再增加一个功能模块的话,要么重新编译,要么直接编译一个扩展模块(生成一个.so文件),然后在php.ini中配置一下。

  • 查看PHP加载的功能模块:
[[email protected] ~]# /usr/local/php/bin/php -m
[PHP Modules]
bz2
Core
ctype
date
dom
ereg
exif
fileinfo
filter
gd
hash
iconv
json
libxml
mbstring
mcrypt
mysql
mysqli
openssl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
Reflection
session
SimpleXML
soap
sockets
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zlib

[Zend Modules]
  • 编译安装PHP的redis扩展模块:
[root@localhost ~]# cd /usr/local/src/
[root@localhost src]# wget https://codeload.github.com/phpredis/phpredis/zip/develop
[root@localhost src]# mv develop phpredis-develop.zip   //改名为phpredis-develop.zip
[root@localhost src]# unzip phpredis-develop.zip     //解压phpredis-develop.zip
[root@localhost src]# cd phpredis-develop
[root@localhost phpredis-develop]# /usr/local/php/bin/phpize        //目的是生成configure文件
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.    //提示错误Cannot find autoconf,需要安装一些autoconf
[root@localhost phpredis-develop]# yum install -y autoconf
[root@localhost phpredis-develop]# /usr/local/php/bin/phpize
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226
[root@localhost phpredis-develop]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@localhost phpredis-develop]# echo $?
0
[root@localhost phpredis-develop]# make
[root@localhost phpredis-develop]# echo $?
0
[root@localhost phpredis-develop]# make install 
Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-zts-20131226/        //make install 的时候会把编译好的redis.so文件放到扩展模块存放目录下面
[root@localhost phpredis-develop]# echo $?
0
  • 上面已经编译安装,接下来做一下额外操作:
[root@localhost phpredis-develop]# /usr/local/php/bin/php -i |grep extension_dir     //查看扩展模块存放目录,可以在php.ini中自定义该路径
extension_dir => /usr/local/php/lib/php/extensions/no-debug-zts-20131226 => /usr/local/php/lib/php/extensions/no-debug-zts-20131226
sqlite3.extension_dir => no value => no value
[root@localhost phpredis-develop]# ls /usr/local/php/lib/php/extensions/no-debug-zts-20131226
opcache.so  redis.so     //可以看到 redis.so
[root@localhost phpredis-develop]# vim /usr/local/php/etc/php.ini
extension = redis.so   //增加这一行配置
[root@localhost phpredis-develop]# /usr/local/php/bin/php -m |grep redis    //查看是否加载redis模块
redis       //可以看到已经加载redis模块
[root@localhost phpredis-develop]# /usr/local/apache2.4/bin/apachectl restart     //想要使用redis模块,需要重启httpd服务

更多资料参考:
几种限制ip的方法
apache 配置https支持ssl
Apache Rewrite规则详解
php错误日志级别参考
php.ini详解

上一篇: logrotate 配置

下一篇: php代码优化