Apache配置防盗链及访问控制

Apache配置防盗链及访问控制

evobot 799 2018-05-31

本文主要介绍Apache如何配置防盗链,以及访问控制Directory和FilesMatch。


防盗链配置

  • 防盗链是为了防止外站引用本站的资源,导致本站流量上升,占用带宽资源;

  • 防盗链的配置就是让资源只能在本站域名引用,不让其他域名引用,即referer,在虚拟主机配置里增加以下配置:

    <VirtualHost *:80>
        DocumentRoot "/data/wwwroot/xtears.cn"
        ServerName xtears.cn
        ServerAlias www.abc.com www.123.com
        <Directory /data/wwwroot/xtears.cn>
            SetEnvIfNoCase Referer "http://xtears.cn" local_ref
            SetEnvIfNoCase Referer "http://abc.com" local_ref
            SetEnvIfNoCase Referer "^$" local_ref
            <filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)">
                Order Allow,Deny
                Allow from env=local_ref
            </filesmatch>
        </Directory>
        ErrorLog "logs/xtears.cn-error_log"
        CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/xtears.cn-access_%Y%m%d.log 86400" common 
    </VirtualHost>
    
    • 这里Directory设置了两个域名白名单:xtears.cn和abc.com,FilesMatch配置设置了需要做防盗链的文件格式,FilesMatch可以不区分大小写,然后在FilesMatch中配置了访问控制,让白名单的域名允许引用,其他的引用被Deny。
    • 在两个白名单域名后面有一个空referer:SetEnvIfNoCase Referer "^$" local_ref,空referer是指直接访问资源链接,并不是其他站点引用之后访问的,所以为了防止用户直接复制资源源地址访问被403拒绝,这里增加允许空referer的访问。
  • 使用curl -e "http://domain.com" -x127.0.0.1:80 xtears.cn/red.jpg -I可以模拟referer,选项-e用来指定referer:

    $ curl -e "http://www.qq.com" -x118.24.153.130:80 xtears.cn/red.jpg -I
    HTTP/1.1 403 Forbidden
    Date: Thu, 31 May 2018 14:55:40 GMT
    Server: Apache/2.4.33 (Unix) PHP/5.6.32
    Content-Type: text/html; charset=iso-8859-1
    
    • 可以看到访问被403拒绝,而如果注释掉空Referer,直接访问也会返回403错误:

    403

访问控制

Directory

  • 之前设置管理员的二次认证,在这个基础上,还可以进一步配置访问控制,只允许指定IP地址能够访问页面,Directory访问控制配置如下,写入虚拟主机配置:

    <VirtualHost *:80>
        DocumentRoot "/data/wwwroot/xtears.cn"
        ServerName xtears.cn
        ServerAlias www.abc.com www.123.com
        <Directory /data/wwwroot/xtears.cn/admin>
            Order deny,allow
            Deny from all
            Allow from 127.0.0.1
        </Directory>
    
        <Directory /data/wwwroot/xtears.cn>
            SetEnvIfNoCase Referer "http://xtears.cn" local_ref
            SetEnvIfNoCase Referer "http://abc.com" local_ref
            #SetEnvIfNoCase Referer "^$" local_ref
            <filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)">
                Order Allow,Deny
                Allow from env=local_ref
            </filesmatch>
        </Directory>
        ErrorLog "logs/xtears.cn-error_log"
        CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/xtears.cn-access_%Y%m%d.log 86400" common
    </VirtualHost>
    
  • 这里为了防止两个Directory冲突,所以将访问控制放在了上面,其中Order是定义访问控制的顺序,即先执行deny的语句还是allow的语句,控制语句不论是否匹配,都会按照Order的顺序执行,所以这里如果访问来自127.0.0.1,那么会先被deny拒绝,然后再被允许访问。

  • 更新配置后,创建网站根目录下的admin目录和网页文件,然后在服务器本地尝试访问,结果被允许访问:

    # curl -x127.0.0.1:80 xtears.cn/admin/index.php -I
    HTTP/1.1 200 OK
    Date: Thu, 31 May 2018 15:14:54 GMT
    Server: Apache/2.4.33 (Unix) PHP/5.6.32
    X-Powered-By: PHP/5.6.32
    Content-Type: text/html; charset=UTF-8
    
  • 从其他IP访问,返回403状态码:

    $ curl -x118.24.153.130:80 xtears.cn/admin/index.php -I
    HTTP/1.1 403 Forbidden
    Date: Thu, 31 May 2018 15:18:02 GMT
    Server: Apache/2.4.33 (Unix) PHP/5.6.32
    Content-Type: text/html; charset=iso-8859-1
    

FilesMatch

  • 上面的访问控制是控制目录的访问,另外也可以对链接或者文件进行访问控制,比如访问的链接后面带有参数的情况,这时就可以用FilesMatch来进行访问控制;

  • 虚拟主机配置文件配置如下:

    <VirtualHost *:80>
        DocumentRoot "/data/wwwroot/xtears.cn"
        ServerName xtears.cn
        ServerAlias www.abc.com www.123.com
        <Directory /data/wwwroot/xtears.cn>
            <FilesMatch admin.php(.*)>
            Order deny,allow
            Deny from all
            Allow from 127.0.0.1
            </FilesMatch>
        </Directory>
        ErrorLog "logs/xtears.cn-error_log"
        CustomLog "|/usr/local/apache2.4/bin/rotatelogs -l logs/xtears.cn-access_%Y%m%d.log 86400" common
    </VirtualHost>
    
  • admin.php(.*)是为了匹配地址后面带有参数的情况,测试如下:

    # curl -x118.24.153.130:80 'xtears.cn/admin.php?asd' -I
    HTTP/1.1 403 Forbidden
    Date: Thu, 31 May 2018 16:13:04 GMT
    Server: Apache/2.4.33 (Unix) PHP/5.6.32
    Content-Type: text/html; charset=iso-8859-1
    
    # curl -x127.0.0.1:80 'xtears.cn/admin.php?asd' -I
    HTTP/1.1 200 OK
    Date: Thu, 31 May 2018 16:13:22 GMT
    Server: Apache/2.4.33 (Unix) PHP/5.6.32
    X-Powered-By: PHP/5.6.32
    Content-Type: text/html; charset=UTF-8
    

其他访问控制

  • 禁止访问指定目录/文件,如不允许访问.inc扩展名文件,保护php类库,虚拟主机配置增加如下内容:

    <Files ~ "\.inc$">
        Order allow,deny
        Deny from all
    </Files>
    
  • 禁止访问指定目录:

    <Directory ~ "^/var/www/(.+/)*[0-9]{3}">
        Order allow,deny
        Deny from all
    </Directory>
    
    
  • 通过文件匹配来禁止,如禁止访问图片:

    <FilesMatch \.(gif|jpe?g|png)$>
        Order allow,deny
        Deny from all
    </FilesMatch>
    
    
  • 针对URL相对路径的访问控制:

    <Location /dir/>
        Order allow,deny
        Deny from all
    </Location>
    
  • 禁止某些IP访问:

    <Directory "/var/www/web/">
    	Order allow,deny
    	Allow from all
    	Deny from 10.0.0.1 #阻止ip
    	Deny from 192.168.0.0/24 #阻止ip段
    </Directory>
    
    
  • 允许某些IP访问,适合内部或合作公司访问:

    <Directory "/var/www/web/">
    	Order deny,allow
    	Deny from all
    	All from example.com #允许域名
    	All from 10.0.0.1	#允许一个IP
    	All from 10.0.0.1 10.0.0.2	#允许多个IP
    	Allow from 10.1.0.0/255.255.0.0	#允许一个IP段、掩码对
    	All from 10.0.1 192.168	#允许一个IP段,ip段后面不写
    	All from 192.168.0.0/24
    </Directory>
    
    

Apache禁止trace

  • 禁止Trace和Track这两种调试web服务器链接的http凡是,可以防止xss攻击,具体可以使用rewrite功能实现:

    RewriteEngine On
    RewriteCond %{REQUEST_METHOD}^TRACE
    RewriteRule .* - [F]
    
    
    • 或者再apache配置文件中配置TraceEnable off参数项。

Apache配置https

  • 首先下载openssl源码包并使用默认配置编译,默认将安装到/usr/local/ssl

    tar -zxf openssl-0.9.8k.tar.gz
    cd openssl-0.9.8k
    ./config   
    make && make install
    
  • 然后编译apache指定ssl支持,可以编译为静态模块或动态模块:

    • 静态:--enable-ssl=static --with-ssl=/usr/local/ssl
    • 动态:--enable-ssl=shared --with-ssl=/usr/local/ssl
    • 动态编译的情况会在module目录生成mod_ssl.so文件,并且需要在httpd.conf中加入LoadModule ssl_module modules/mod_ssl.so
  • 接着创建私钥:

    cd /usr/local/ssl/bin
    openssl genrsa -out server.key 2048
    //如果需要对server.key添加保护密码,使用 -des3 扩展命令。Windows环境下不支持加密格式私钥,Linux环境下使用加密格式私钥时,每次重启Apache都需要您输入该私钥密码(例:openssl genrsa -des3 -out server.key 2048)
    cp server.key /usr/local/apache/conf/ssl.key/
    
    
  • 之后生成证书请求(CSR)文件:

    # openssl req -new -key server.key -out certreq.csr
    Country Name:                           //所在国家的ISO标准代号,中国为CN   
    State or Province Name:                 //单位所在地省/自治区/直辖市   
    Locality Name:                          //单位所在地的市/县/区   
    Organization Name:                      //单位/机构/企业合法的名称   
    Organizational Unit Name:               //部门名称   
    Common Name:                            //通用名,例如:www.itrus.com.cn。此项必须与访问提供SSL服务的服务器时所应用的域名完全匹配。   
    Email Address:                          //邮件地址,不必输入,直接回车跳过   
    "extra"attributes                        //以下信息不必输入,回车跳过直到命令执行完毕。 
    
  • 将生成的certreq.csr文件提交到证书申请机构,等待CA证书签发,服务器证书密钥对必须配对使用,私钥丢失会导致证书不可用。

  • 将签发的两张中级CA证书内容保存到conf/ssl.crt/intermediatebundle.crt文件中,并将服务器证书内容保存到ssl.crt/server.crt文件中。

  • 在httpd.conf中增加以下内容:

    Listen 443
    NameVirtualHost *:443
    
    	DocumentRoot "/data/web/www"
    	ServerName aaa.com:443
    	ErrorLog "logs/error.log"
    	CustomLog "logs/access.log" combined
    
    		SSLEngine on
    		SSLCertificateFile /usr/local/apache/conf/ssl.crt/server.crt
    		SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/server.key
    		SSLCertificateChainFile /usr/local/apache/conf/ssl.crt/intermediatebundle.crt
    


# Apache