Apache虚拟主机测试

一、虚拟机主机简介

   
部署多个站点,每个站点,希望用不同的域名和站点目录,或者是不同的端口,或不同的ip,就需要虚拟主机功能。简单的说一个http服务要配置多个站点,就需要虚拟主机。(一句话一个http服务要配置多个站点,就需要虚拟主机)

二、虚拟主机分类

  1. 基于域名
  2. 基于端口
  3. 基于ip

所谓的基于XX,就是靠XX来区分不同的站点,支持各种混合,N多个虚拟主机。

三、基于域名虚拟主机实例

域名              站点
www.qzl.com      /var/html/www    
blog.qzl.com     /var/html/blog
bbs.qzl.com      /var/html/bbs       

1.创建虚拟主机目录

[root@A extra]# mkdir -p /var/html/{www,blog,bbs}
[root@A extra]# touch /var/html/{www,blog,bbs}/index.html
[root@A www]# for name in www blog bbs ;do echo "http://$name.qzl.com" >/var/html/$name/index.html;done

[root@A www]# for name in www blog bbs ;do cat /var/html/$name/index.html;done
http://www.qzl.com
http://blog.qzl.com
http://bbs.qzl.com

2.修改配置文件

[root@A conf]# grep ^Include httpd.conf 
Include conf/extra/httpd-vhosts.conf    #打开加载,加载虚拟主机配置文件

[root@A extra]# vim httpd-vhosts.conf
<VirtualHost *:80>
    ServerAdmin 83891*64@qq.com      #配置管理员邮箱
    DocumentRoot "/var/html/www"      #配置虚拟主机目录
    ServerName www.qzl.com          #配置域名
    ErrorLog "logs/www-error_log"      #配置错误日志路径
    CustomLog "logs/www-access_log" common   #配置访问日志路径
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin 83891*64@qq.com      #注意,这里应该是你管理员的有效的邮箱,而不应该打掩码的,
    DocumentRoot "/var/html/blog"
    ServerName blog.qzl.com
    ErrorLog "logs/blog-error_log"
    CustomLog "logs/blog-access_log" common
</VirtualHost>

<Directory /var/html>
    Options FollowSymLinks #FollowSymLinks表示禁止使用符号链接,Indexes表示允许目录浏览
    AllowOverride None    #表示禁止用户对目录配置文件(.htaccess进行修改)重载
    Order allow,deny     #以allow优先处理,没有明确说明允许的话都将拒绝访问
    allow from all      #允许所有的访问
</Directory>

3.修改本地的hosts文件(用于DNS解析)

未分类

4.优雅启动apache

[root@A apache]# /application/apache/bin/apachectl graceful
httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.1.7 for ServerName
解决办法:
将httpd.conf 里第99行,修改ServerName 127.0.0.1:7

说明:这里可以用restart重启,但是用graceful更好,这个参数可以在处理完毕请求后再重新启动,即重启时不会强行中断用户访问,所以建议用graceful这个参数

5.Apache日志

1) 通用日志格式(CommonLog Format)
  组合日志格式(CombinedLOG Format)

2) 安装日志轮询工具cronolog(链接:https://pan.baidu.com/s/1xZBQbgahwCdv8l47kWz2LQ 提取码:7zd3 )

cd /home/king/tools/
wget http://cronolog.org/download/cronolog-1.6.2.tar.gz
tar xf cronolog-1.6.2.tar.gz 
cd cronolog-1.6.2
./configure 
make 
make install
cd /usr/local/sbin/
pwd
ll /usr/local/sbin

查看 ll /usr/local/sbin/ 可以看到俩文件cronolog 和cronosplit权限都是755 的权限

说明:cronolog轮询日志的正确写法,被轮询的日志路径要写全路径这是大多数网站的常规配置方法(按天记录日志,日志不会自动覆盖)修改配置文件日志vim httpd-vhosts.conf

<VirtualHost *:80>
    ServerAdmin 83891*64@qq.com
    DocumentRoot "/var/html/www"
    ServerName www.qzl.com
    ErrorLog "|/usr/local/sbin/cronolog /application/apache/logs/www-error_%Y%m%d.log" 
    CustomLog "|/usr/local/sbin/cronolog /application/apache/logs/www-access_%Y%m%d.log" combined
</VirtualHost>

四.举例子

例1:apache不记录图片的日志

答:因为统计日志PV时一个页面才算一个PV,而图片,JS,CSS等只是图片的元素,如果记录在日志里,然后按日志行进行计算PV就不准确了,所以可以考虑不记录图片等日志。

<FilesMatch ".(css|js|gif|jpg|ico|swf)">
    setEnv IMAG 1
</FilesMatch>

CustomLog "|/usr/local/sbin/cronolog /application/apache/logs/www-access_%Y%m%d.log" combined  env=!IMAG

例2:RS服务器不记录负载均衡健康检查日志

虚拟主机不记录负载均衡向下健康检查文件的日志(check.txt)

SetEnvIf Request_URI "^/check.txt$" dontlog
CustomLog "|/usr/local/sbin/cronolog /application/apache/logs/www-access_%Y%m%d.log" combined  env=!dontlog

例3:日志统计

awk '{print $1}' 文件名字|sort|uniq -c|sort -rn |head -10

庖丁解牛,高大上的日志统计命令:

awk '{++S[$1]} END {for(key in S) print S[key],key}' 文件名字|sort -rn -k1|head -10

首先++S是一个名字为S的数组,for循环key是在名字为S的数组中取值,然后按照key的默认格式打印出来,在sort进行排序。

nginx/apache 配置静态资源允许跨域访问

有时为了优化网站访问速度,会给一些静态资源配置cdn加速,但是有时候会出现跨域访问的问题,在nginx和apache服务中可进行如下配置

1. apache

找到apache配置文件httpd.conf

找到这行

#LoadModule headers_module modules/mod_headers.so

把#注释符去掉

LoadModule headers_module modules/mod_headers.so

目的是开启apache头信息自定义模块

在独立主机配置文件中新增header

Header set Access-Control-Allow-Origin *

例如:

<VirtualHost *:88>
  ServerAdmin admin@example.com
  DocumentRoot "****************"
  ServerName www.jianzhi12.com
  Header set Access-Control-Allow-Origin *

  ErrorLog "***********"
  CustomLog "****************************" common
<Directory "**************">
  SetOutputFilter DEFLATE
  Options FollowSymLinks ExecCGI
  Require all granted
  AllowOverride All
  Order allow,deny
  Allow from all
  DirectoryIndex index.html index.php
</Directory>
</VirtualHost>
ApacheCopy

意思是对这个域名的资源进行访问时,添加一个头信息

重启apache

service httpd restart

2. nginx

同理 找到相应域名配置文件

在server模块中添加配置:

add_header ‘Access-Control-Allow-Origin’ ‘*’;1

例:

server {
        listen       80;
        add_header 'Access-Control-Allow-Origin' '*';
        location /Roboto/ {
            root   /home/images;
            autoindex on;
        }
    }

nginx重载

./nginx -s reload

Apache安装SSL证书

1.创建私钥(可选,用于申请证书):

openssl genrsa 2048 > private-key.pem

2.创建证书签名 (CSR,可选):

openssl req -new -key private-key.pem -out csr.pem

3.上传到服务器:

scp ./STAR_yourdomain_com/* yourdomain:/etc/pki/tls/private/

4.合并正规渠道获得的证书:

cat STAR_yourdomain_com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl-bundle.crt

5.配置Apache(不再累述详细配置过程):

<VirtualHost *:443>
  ServerName *.yourdomain.com
  SSLEngine on

  SSLCertificateFile /etc/pki/tls/private/STAR_yourdomain_com.crt
  SSLCertificateKeyFile /etc/pki/tls/private/STAR_yourdomain_com.key
  SSLCertificateChainFile /etc/pki/tls/private/ssl-bundle.crt
  SSLCACertificateFile /etc/pki/tls/private/AddTrustExternalCARoot.crt
</VirtualHost>

Apache、Nginx、php-fpm为PHP设置、添加$_SERVER服务器环境变量

在PHP开发中为了区分线上生产环境还是本地开发环境,

如果我们能通过判断$_SERVER['RUNTIME_ENVIROMENT']'DEV'还是'PRO'来区分该多好,

可惜的是$_SERVER数组里面根本没有RUNTIME_ENVIROMENT这个元素。

一、通过nginx的fastcgi_param来设置

在nginx配置文件中,可以在nginx总体的配置文件nginx.conf中,也可以在单独的网站配置环境中进行设置,如:www.regskynet.com.conf

在配置环境server段location中添加相应的配置信息:

    location ~ .php$ {
        limit_conn conn_zone 15;
        limit_req zone=req_zone burst=25 nodelay;
        try_files $uri /index.php =404;
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        root           $root;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $root$fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_param  RUNTIME_ENVIROMENT 'PRO';
    }

然后重启重启nginx

service nginx reload

二、通过php主配置文件php-fpm.conf来设置

这个设置必须放在主配置文件php-fpm.conf里,不能放到include指令设置的子配置文件里,否则会报错:「Array are not allowed in the global section」

我的php-fpm.conf位置在/etc/php-fpm.conf

直接在配置文件中添加:

env[RUNTIME_ENVIROMENT] = 'PRO'

添加后重启php-fpm

service php-fpm reload

通过上面2种方式添加$_SERVER变量值后,我们就可以直接在php文件中通过$_SERVER来获取相应的变量值了。

不过据说配置信息通过nginxfastcgi_param来设置的话,当nginx和php交互时,会带来大量的数据传输。

三、通过Apache设置环境变量

SetEnv 变量名 变量值

<VirtualHost *:80>
    ServerAdmin ...
    DocumentRoot ...
    ServerName www.regskynet.com
    ErrorLog ...
    CustomLog ...
    SetEnv RUNTIME_ENVIROMENT PRO
    <Directory "...">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Centos6.x下设置Apache自建https的证书

第一步 – 安装Mod SSL

为了建立自签名证书,我们首先要确保mod_ssl ,Apache模块,它提供了支持SSL加密,安装在我们的VPS。
我们可以安装mod_ssl与yum命令:

#  sudo yum install mod_ssl

#  sudo vim  /etc/httpd/conf/httpd.conf
LoadModule ssl_module /usr/lib64/httpd/modules/mod_ssl.so

第二步 – 创建新证书

现在Apache已准备好使用加密,我们可以继续生成新的SSL证书。
该证书将存储有关您网站的一些基本信息,并且将伴有允许服务器安全处理加密数据的密钥文件。

首先,我们需要创建一个新目录,我们将存储服务器密钥和证书:

#  sudo mkdir /etc/httpd/ssl

现在,我们必须把我们的文件的位置,我们可以创建一个SSL密钥和证书文件openssl :

#  sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/httpd/ssl/apache.key -out /etc/httpd/ssl/apache.crt

适当填写提示。 最重要的线是要求一个Common Name 。
您需要输入要与服务器关联的域名。 如果您没有域名,可以输入公共IP地址。

第三步 – 设置证书

我们现在拥有完成的接口的所有必需的组件。 接下来要做的是设置虚拟主机以显示新证书。

使用root权限在文本编辑器中打开Apache的SSL配置文件:

# sudo vim /etc/httpd/conf.d/ssl.conf

内容如下:

Listen 443
<VirtualHost *:443>
        DocumentRoot "/www/test"
        ServerName www.test120.com
        #SSL引擎操作开关
        SSLEngine on
        #指定服务器证书位置
        SSLCertificateFile "/etc/httpd/ssl/apache.crt"
        #服务器私钥文件
        SSLCertificateKeyFile "/etc/httpd/ssl/apache.key"
</VirtualHost>
#   sudo  service httpd restart 

最后 ,访问浏览器

https://www.test120.com/

successful

windows 搭建 apache + php

1. 安装 apache

登录 apache 官网, 不懂英语的我看的一脸懵, 然后偷偷去百度了…
登录https://www.apachelounge.com/download/

未分类

我的电脑是 win10 64 位 所以我选择了这里

解压, 修改 conf 文件夹下的 httpd.conf 文件

打开 J:apacheApache24conf 目录下的 httpd.conf 文件并作以下修改:

ServerRoot(apache 目录)改为 J:apacheApache24

ServerName (服务器名称) 去掉 #,改为 127.0.0.1

DocumentRoot (修改网站根目录地址)自己设置,一般设置为 J:apacheApache24htdocs

运行 bin 目录下的 httpd.exe 就 ok 了 , 我固定到了开始菜单栏
如果需要安装服务 , 请看这里https://blog.csdn.net/hi_xww/article/details/78045518

2. 安装 php

http://www.cnblogs.com/flyingeagle/articles/6583201.html

3. php 扩展 mysql

这里搞了很长时间…
php.ini 搜索 extension_dir
添加 extension_dir = "D:php7ext"

未分类

开启 mysql 扩展, 去掉这两行的注释, 这个地方 我找了好久

未分类

查看 /ext 目录下 是否有 php_mysql.dll , 如果没有可以在这里下载

https://img.vseu.com/php_mysql.dll

Apache/Nginx中Host头攻击的一些差异

1. Host header

服务器的域名(用于虚拟主机 ),以及服务器所监听的传输控制协议端口号。如果所请求的端口是对应的服务的标准端口,则端口号可被省略。
自超文件传输协议版本1.1(HTTP/1.1)开始便是必需字段。
以上是维基百科中对于Host头部的说明。可以看到Host头部并非是用于区别发送到哪台主机的字段。而是用于区分一台主机上不同的虚拟主机。(可以在Apache和Nginx中配置相应Host对应的虚拟主机。

利用PHP可以在 $_SERVER['HTTP_HOST'] 字段中获取到该字段的值

var_dump($_SERVER['HTTP_HOST']);

未分类

当没有配置虚拟主机或者匹配不到对应的Host主机时,webserver就会发送请求到默认的目录中去解析

从而Host头部就变成了一个可控的字段,当一些应用程序没有对$SERVER[‘HTTP_HOST’]字段进行处理,过分信任时,就会产生一些安全问题

未分类

2. Diff of win/linux

这里用的测试环境分别是

  • win10下的 phpstudy
  • ubuntu 18.04中默认安装的nginx和apache2

在1.php中会输出$_SERVER[‘HTTP_HOST’]变量

2.1 Windows

Apache

可以任意修改apache中的值,服务器都会默认接受

未分类

甚至可以插入两个Host头部,在win下会用,将两个头部相连

Host: localhost
Host:123468

未分类

Nginx

nginx中对于任意脏字符都是允许修改的

未分类

但是在插入两个Host头部的时候只会获取到第二个Host值

Host: localhost
Host: 'select user();

未分类

2.2 Linux

但是在linux中又会有些不同

Apache

linux下的apache就有着较为严格的限制,只允许修改对应的ip数字

未分类

插入一些脏字符就会返回400的错误

Host: 192.168.85.145'

未分类

两个头部也是一样的情况,即使头部是合法的

Host: 192.168.85.145
Host: 192.168.85.145

未分类

Nginx

linux下nginx中对于Host的处理类似于win中的就不过多介绍

未分类

从而网上有一些防御手段就变成了设置虚拟主机(virtual host),从而可以确保Host字段不会被更改,因为一旦修改了Host字段就不会解析到对应的目录当中。

3. Virtual Host

但即使配置了虚拟主机之后,所接受的Host字段就是可以信任的么?

在Apache、Nginx中会呈现不同的状态

测试环境为

  • ubuntu 18.04
  • Apache/2.4.29 (Ubuntu)
  • nginx/1.14.0 (Ubuntu)
  • PHP 7.2.10-0ubuntu0.18.04.1

至于虚拟主机配置的部分就不过多介绍,在网上可以找到很多配置的文章

至于域名,可以买一个域名修改解析,或者直接修改host文件

然后在/var/www目录下新建了三个文件夹

  • html 默认主目录
  • apache Apache的虚拟主机目录
  • nginx Nginx的虚拟主机目录

3.1 Apache

可以看到,在配置了虚拟主机之后,访问对应的域名就会访问到对应的目录中

Host: localhost.ba123.top

未分类

当遇到一个不认识的域名的时候,就会解析到默认目录下(当然,假如默认目录下没有1.php这个文件就会返回一个404

Host: localhost.ba123.to

未分类

那想攻击Apache中的虚拟主机时Host字段就不能添加别的脏字符了么?目前找到的可以添加的就只有通过冒号:分割开的端口号

只要是一个合法的端口就可以发起正常的请求

Host: localhost.ba123.top:23333

未分类

但是当想插入一些字符或者端口号过大的时候,都会拒绝请求,返回一个400,更不会允许两个Host头部的请求

Host: localhost.ba123.top:23333'select

未分类

总体来说,Apache对于Host字段的限制还是比较严格的,在开启了虚拟主机之后,几乎比较难以插入脏字符。

3.2 Nginx

在nginx中似乎有着更多的攻击手法

对于未知的主机名,处理方式还是与apache中一致,会解析到默认目录中

Host: localhost.ba123.to'select

未分类

但是这里假如利用冒号:的形式分割之后,冒号后面的port部分会直接被nginx给抛弃,从而可以插入任意的字符

Host: localhost.ba123.top'select sleep(5);

未分类

甚至在nginx中可以传入两个Host头部,Nginx将以第一个为准传送到对应的虚拟主机处理,而PHP-FPM将以第二个为准给$_SERVER[‘HTTP_HOST’]赋值。

Host: localhost.ba123.top
Host:'select sleep(5);

未分类

但是在apache中传入两个Host头部的时候,就会直接返回400

由此可见,在ngin中对于Host的并没有做过多的限制,从而可以比较容易的进行Host头部攻击。

windows上的虚拟主机原谅我确实没怎么遇到过,就没测试了,感兴趣的可以自己测试下。

4. Summary

可以看到Host头部,在不同的情况下会呈现出不同的状态,因此在编写程序的时候一定要将Host这个值设置为不可信任的,对其进行一些正则或者转义的一些过滤。否则极易引发安全问题。

在windows下对于这种头部的限制比较松,apache和nginx都能比较轻松的绕过去。

而在两个服务器相比,Apache对于数据的解析更加严谨,尤其是在linux的环境中,极大的限制了非法的请求。

Nginx则甚至会出现Nginx与PHP-FPM解析不一致的情况,有时这种解析不一样甚至会带来更多的危害。

5. Reference

https://www.leavesongs.com/PENETRATION/some-tricks-of-attacking-lnmp-web-application.html

Error: Apache shutdown unexpectedly

有些时候,开启Apache会报这个错误,而且日志文件里面什么信息都没有。

未分类

通常是因为端口被占用。

如果下载下来之后没有更改任何东西的话,Apache默认Port是80,ssl的端口是443。

那么我们就要先看一下是什么进程占用了80端口和443端口。

win+r

cmd运行命令行

输入netstat -ano 来查看端口连接状态。

我们可以很明显地看到,80和443都被占用了

未分类

那么怎么办?

两个方法:

1.关掉这两个进程

2.改Apache的端口

方法1

先看好PID,这里80端口的PID是10120;443端口的PID是7860

直接在cmd里面输入

taskkill /PID 10120

taskkill /PID 7860

方法2

在control面板,点击Config

先选httpd.conf

ctrl+r把所有的80全改成一个自己喜欢的数字,比如88或者888或者8888。(别改成已被占用的端口号)

再选httpd-ssl.conf

一样的,把所有的443改成另一个数字。

再开启Apache就可以了

如果还是同样的错误

xamppapachebin 的目录下 运行cmd

cmd里面输入 httpd.exe

来看具体的错误。按照报错信息来修改

未分类

centos中apache使用问题

以下总结在配置及启动apache2时出现报错的处理方法

一、启动apache遇到错误:httpd: Could not reliably determine the server’s fully qualified domain name

[root@server httpd-2.2.4]# /usr/local/apache/bin/apachectl start
 
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName

1)进入apache的安装目录:(视个人安装情况而不同) [root@server ~]# cd /usr/local/apache/conf
 
2)编辑httpd.conf文件,搜索"#ServerName",添加ServerName localhost:80

[root@server conf]# ls
extra  httpd.conf  magic  mime.types  original
[root@server conf]# vi httpd.conf
#ServerName www.example.com:80
ServerName localhost:80

3)再重新启动apache 即可。

[root@server ~]# /usr/local/apache/bin/apachectl restart

二、重启报错apache2 address already in use:make_sock:could not bind to address [::]:80

此错误为端口被占用,只有进入root用户,才可以查看所有端口被占用的情况。

$su

#netstat -lnp | grep 80

tcp 0      x x.x.x.x:8084        ...   listen   1167/mono

tcp 0      x x.x.x.x:80          ...   listen   1194/inetd

udp 0      x x.x.x.x:2080        ...   listen   14427/drcomauthsvr

查看知道是Inetd占用了80端口

#kill 1194

#exit //退出root用户

$sudo apapche2ctl -k start

启动成功!

三、在安装完apache2之后的默认index.html网页里面输入文字显示乱码,修改AddDefaultCharset 也没有用,即使在网页头部添加meta,指定charset=GB2312|GBK也没有用

注意,亲,此处因为默认文档的字号为h1,大号字体,中文无法显示,此处修改为小号字体即可,本人修改为h5,乱码消失,正常显示中文!

四、在网页运行html文件调用cgi程序时,提示找不到cgi程序以及找到程序后得不到想要的结果。

首先查看apache2配置文件,在/etc/apache2/site-enables查看系统默认的cgi-bin目录,可以在这个里面根据需要来修改默认cgi-bin目录。apt安装完后默认的cgi-bin目录是在/usr/lib/cgi-bin/

具体是修改ScriptAlias参数,如果你不知道你的类似site-enables的目录在哪,毕竟各个版本有些不一样,可以直接搜索ScriptAlisa这个参数,因为不管哪个版本,这个参数基本没改动。

apache如何做到日志分割

现在许多网站都是用 apache 做 web 代理的,随时间时间的推长,apache 的访问日志 access.log 会越来越大,所以如果能实现每天分割成一个新得日志,这是比较方便管理的。

当然,apache 本身就具备这样的功能,我需要在 apache 的配置文件中,每个网站的日志部分需要调整成如下的格式

httpd.conf:ErrorLog "| /usr/local/apache/bin/rotatelogs /data/www/log/%Y_%m_%d_error.log 86400 480"
httpd.conf: CustomLog "| /usr/local/apache/bin/rotatelogs /data/www/log/%Y_%m_%d_access.log 86400 480" common

在上面的 ErrorLog 和 CustomLog 需要调整成上面的格式。

最后的效果如下

未分类