1. 程式人生 > >LNMP架構防盜鏈、訪問控制、解析php、代理的設定

LNMP架構防盜鏈、訪問控制、解析php、代理的設定

11月28日任務
12.13 Nginx防盜鏈
12.14 Nginx訪問控制
12.15 Nginx解析php相關配置
12.16 Nginx代理

 

Nginx防盜鏈

  • 修改虛擬主機配置檔案
# 可以配合過期時間和靜態檔案不記錄的程式碼使用
[[email protected] vhost]# vim /usr/local/nginx/conf/vhost/test.com.conf 
...
# ~*表示忽略大小寫的匹配
    location ~* .*\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$
    {
        expires 7d;
        
        # 設定白名單,server_names可以不寫
        # 白名單可以是多個域名,域名鍵使用空格間隔開
        valid_referers none blocked server_names *.test.com;
        
        # 條件判斷,非白名單域名返回403狀態碼即禁止訪問forbidden;
        if ($invalid_referer) {
            return 403;
        }
        access_log off;
    }
...
  • 驗證效果
  1. 使用不在白名單內的referer訪問,返回的狀態碼為403,forbidden!
[[email protected] vhost]# curl -e "http://www.baudi.com" -x 127.0.0.1:80 test.com/1.gif -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.2
Date: Wed, ... 12:25:35 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
  1. 指定白名單的referer訪問,成功訪問
[[email protected] vhost]# curl -e "http://www.test.com" -x 127.0.0.1:80 test.com/1.gif -I
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Wed, ... 12:26:43 GMT
Content-Type: image/gif
Content-Length: 12
Last-Modified: Wed, ... 11:35:29 GMT
Connection: keep-alive
ETag: "5a4cc001-c"
Expires: Wed, ... 12:26:43 GMT
Cache-Control: max-age=604800
Accept-Ranges: bytes

nginx訪問控制

針對目錄的訪問控制

  • 修改虛擬主機配置檔案
[[email protected] vhost]# vim /usr/local/nginx/conf/vhost/test.com.conf 
...
# 這裡以簡單目錄為例
location /admin/
{
    # nginx中沒有apache裡的order命令,按程式碼先後順序執行
    # nginx中只要有一條規則匹配,後續規則就不會進行匹配
    
    # 允許本機
    allow 127.0.0.1;
    
    allow 192.168.65.133;
    
    # 禁止其他所有ip
    deny all;
}
...
  • 重啟服務
[[email protected] ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload
  • 測試
# 使用allow允許的ip訪問,成功訪問
[[email protected] ~]# curl -x 192.168.65.133:80 test.com/admin/1.php -I
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Thu, ... 12:36:48 GMT
Content-Type: application/octet-stream
Content-Length: 19
Last-Modified: Wed, ... 13:15:00 GMT
Connection: keep-alive
ETag: "5a4cd754-13"
Accept-Ranges: bytes

# 使用非allow允許的ip訪問,403 forbidden
[[email protected] ~]# curl -x 192.168.65.137:80 test.com/admin/1.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.2
Date: Thu, ... 12:44:54 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive

針對檔案的訪問控制

location還可以使用 ~/~* + 正則的方式對某類檔案或目錄進行訪問控制

[[email protected] vhost]# vim /usr/local/nginx/conf/vhost/test.com.conf 
# 禁止upload、admin目錄下的php檔案解析
location ~ .*(upload|admin)/.*\.php$
{
    deny all
}
  • 重啟並測試
[[email protected] ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload

[[email protected] ~]# curl -x 192.168.65.133:80 test.com/upload/1.php -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.2
Date: Thu, ... 12:59:07 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive

針對user_agent

  1. 修改程式碼
[[email protected] ~]# vim /usr/local/nginx/conf/vhost/test.com.conf
# 還可以根據user_agent來做限制
# 這裡限制網站被爬蟲爬取
location / 
{
    if ($http_user_agent ~ 'Spider/3.0|YoudaoBot|Tomato')
    {
        return 403; //等價於deny all;
    }
}
  1. 重啟服務
[[email protected] ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload
  1. 效果測試
# 不指定user_agent
[[email protected] ~]# curl -x 127.0.0.1:80 test.com -I
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Thu, ... 11:44:35 GMT
Content-Type: text/html
Content-Length: 9
Last-Modified: Wed, ... 10:42:12 GMT
Connection: keep-alive
ETag: "5a4cb384-9"
Accept-Ranges: bytes

# 指定user_agent
[[email protected] ~]# curl -A "Tomato" -x 127.0.0.1:80 test.com -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.2
Date: Thu, ... 11:44:54 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive

Nginx解析php相關配置

  • 修改程式碼
[[email protected] ~]# vim /usr/local/nginx/conf/vhost/test.com.conf 
...
	location ~ \.php$
	{
	    include fastcgi_params;
            # fastcgi_pass後接的sock在php-fpm.conf內的pool塊內定義的,選擇哪個程序池就寫哪個socket
	    fastcgi_pass unix:/tmp/php-fcgi.sock;
	    fastcgi_index index.php;
	    fastcgi_param SCRIPT_FILENAME /data/www/test.com$fastcgi_script_name;
	}
...
  • 先測試為設定前是否能解析PHP
# PHP不解析,直接顯示程式碼
[[email protected] ~]# curl -x 127.0.0.1:80 test.com/1.php
<?php
phpinfo();
  • 重啟服務
[[email protected] ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload
  • 驗證效果
# 成功解析,返回網頁html程式碼
[[email protected] ~]# curl -x 127.0.0.1:80 test.com/1.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/
xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<style type="text/css">
body {background-color: #fff; color: #222; font-family: sans-serif;}
pre {margin: 0; font-family: monospace;}
a:link {color: #009; text-decoration: none; background-color: #fff;}
a:hover {text-decoration: underline;}
table {border-collapse: collapse; border: 0; width: 934px; box-shado
w: 1px 2px 3px #ccc;}
.center {text-align: center;}
.center table {margin: 1em auto; text-align: left;}
.center th {text-align: center !important;}
td, th {border: 1px solid #666; font-size: 75%; vertical-align: base
line; padding: 4px 5px;}
h1 {font-size: 150%;}
h2 {font-size: 125%;}
.p {text-align: left;}
.e {background-color: #ccf; width: 300px; font-weight: bold;}
.h {background-color: #99c; font-weight: bold;}
.v {background-color: #ddd; max-width: 300px; overflow-x: auto;}
.v i {color: #999;}
img {float: right; border: 0;}
hr {width: 934px; background-color: #ccc; border: 0; height: 1px;}
</style>
...

訪問報502錯誤分析

  1. socket檔案錯誤 為了測試,這裡我故意將配置檔案內的sock寫錯
# 原本為/tmp/php-fcgi.sock
fastcgi_pass unix:/tmp/php1-fcgi.sock;

重啟服務後重新訪問,返回資訊如下:

[[email protected] ~]# curl -x 127.0.0.1:80 test.com/1.php
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>

因為nginx無法找到sock檔案,檢視錯誤日誌,通過錯誤日誌進行錯誤排查。

[[email protected] ~]# cat /usr/local/nginx/logs/nginx_error.log 
... 17:47:18 [crit] 2456#0: *22 connect() to unix:/tmp/php1-fcgi.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: test.com, request: "GET HTTP://test.com/1.php HTTP/1.1", upstream: "fastcgi://unix:/tmp/php1-fcgi.sock:", host: "test.com"

這裡的socket檔案應該是在/usr/local/php-fpm/etc/php-fpm.conf內定義的。

[[email protected] ~]# cat /usr/local/php-fpm/etc/php-fpm.conf
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
[www]
listen = /tmp/php-fcgi.sock
# 定義了sock必須定義mode,否則許可權為440,執行後會報錯
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024
  1. 設定未對應設定 php-fpm.conf為監聽ip/埠,nginx虛擬主機配置檔案內為監聽socket,沒有對應。
  • 修改配置程式碼
[[email protected] ~]# vim /usr/local/php-fpm/etc/php-fpm.conf
...
# listen = /tmp/php-fcgi.sock
listen = 127.0.0.1:9000
...

# 檢測語法錯誤並重啟php服務
[[email protected] ~]# /usr/local/php-fpm/sbin/php-fpm -t
[... 18:03:27] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful
[[email protected] ~]# /etc/init.d/php-fpm reload
Reload service php-fpm  done
  • 暫時不修改虛擬主機配置檔案進行訪問測試
# 報502錯
[[email protected] ~]# curl -x 127.0.0.1:80 test.com/1.php
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>
  • 修改對應程式碼
[[email protected] ~]# vim /usr/local/nginx/conf/vhost/test.com.conf 
...
    fastcgi_pass 127.0.0.1:9000;
...
  • 重啟服務後測試效果
# 重啟服務
[[email protected] ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload

# 這裡能成功訪問
[[email protected] ~]# curl -x 127.0.0.1:80 test.com/1.php 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/
xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<style type="text/css">
body {background-color: #fff; color: #222; font-family: sans-serif;}
pre {margin: 0; font-family: monospace;}
a:link {color: #009; text-decoration: none; background-color: #fff;}
a:hover {text-decoration: underline;}
table {border-collapse: collapse; border: 0; width: 934px; box-shado
w: 1px 2px 3px #ccc;}
.center {text-align: center;}
.center table {margin: 1em auto; text-align: left;}
.center th {text-align: center !important;}
td, th {border: 1px solid #666; font-size: 75%; vertical-align: base
line; padding: 4px 5px;}
h1 {font-size: 150%;}
h2 {font-size: 125%;}
.p {text-align: left;}
.e {background-color: #ccf; width: 300px; font-weight: bold;}
.h {background-color: #99c; font-weight: bold;}
.v {background-color: #ddd; max-width: 300px; overflow-x: auto;}
.v i {color: #999;}
img {float: right; border: 0;}
hr {width: 934px; background-color: #ccc; border: 0; height: 1px;}
</style>
...

其他出現502錯誤的原因還有伺服器資源耗盡,出現這種問題的解決方法是進行優化。

Nginx代理

  • 什麼是代理 使用者訪問國外web伺服器的速率通常比較慢,導致出現卡頓甚至無法訪問的情況!通過在中間搭建一個代理伺服器實現快速訪問的目的。這個代理伺服器既可以與使用者端快速連線,也可以高速訪問遠端web伺服器。使用者通過訪問代理伺服器,間接地訪問web伺服器,大大加快訪問速度。

  • 程式碼實現

[[email protected] ~]# vim /usr/local/nginx/conf/vhost/proxy.conf
server
{
    listen 80;
    server_name ask.apelearn.com;
    
    location /
    {
        # proxy_pass指定遠端伺服器的ip
        proxy_pass http://121.201.9.155/;
        
        # $host即為server_name
        proxy_set_header Host               $host;
        
        
        proxy_set_header X-Real-IP          $remote_addr;
        
        
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
    }
}
  • 驗證效果
# 正常情況下,無法直接通過本機訪問遠端伺服器
[[email protected] ~]# curl -x127.0.0.1:80 ask.apelea#n.com/robots.txt
# robots.txt for MiWen
#

User-agent: *

Disallow: /?/admin/
Disallow: /?/people/
Disallow: /?/question/
Disallow: /account/
Disallow: /app/
Disallow: /cache/
Disallow: /install/
Disallow: /models/
Disallow: /crond/run/
Disallow: /search/
Disallow: /static/
Disallow: /setting/
Disallow: /system/
Disallow: /tmp/
Disallow: /themes/
Disallow: /uploads/
Disallow: /url-*
Disallow: /views/
Disallow: /*/ajax/

關閉代理設定,重新測試

# 關閉代理功能
[[email protected] ~]# mv /usr/local/nginx/conf/vhost/proxy.conf /usr/local/nginx/conf/vhost/proxy.conf.bak

[[email protected] ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload

# 無法直接通過本機訪問遠端伺服器了
[[email protected] ~]# curl -x127.0.0.1:80 ask.apelearn.com/robots.txt -I
HTTP/1.1 404 Not Found
Server: nginx/1.12.2
Date: Thu, ... 13:42:52 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive