Nginx

虽然 LAMP 堆栈(Linux + Apache + MySQL + PHP)在支持GeChiUI方面非常流行,但也可以使用 Nginx。GeChiUI支持 Nginx,一些大型GeChiUI网站,例如GeChiUI.com,都是由 Nginx 提供支持的。

谈到 Nginx 时,重要的是要知道 Nginx 有多种实现方式。它可以设置为 Apache 前面的反向代理,这是一个非常强大的设置,允许您使用 Apache 的所有功能和强大功能,同时受益于 Nginx 的速度。大多数报告使用 Nginx 作为服务器的网站(基于从 HTTP 响应标头收集的统计信息)实际上是使用 Nginx 作为反向代理运行的 Apache。(显示“Nginx”的 HTTP 响应标头是由反向代理报告的,而不是服务器本身。)

本指南指的是独立的 Nginx设置,它用作主服务器而不是Apache。应该注意的是,Nginx 并不是 Apache 的完全可互换的替代品。在继续之前,您需要了解影响GeChiUI实施的一些关键差异:

  • 使用 Nginx 没有目录级别的配置文件,如 Apache 的 .htaccess 或 IIS 的 web.config 文件。所有配置都必须由管理员在服务器级别完成,并且GeChiUI不能像 Apache 或 IIS 那样修改配置。
  • 运行 Nginx 时,Pretty Permalinks 功能略有不同。
  • 由于 Nginx 没有 .htaccess-type 能力,而且GeChiUI无法自动为您修改服务器配置,因此无法为您生成重写规则。
  • 在不修改您的安装的情况下,“index.php”将被添加到您的永久链接中。(有一些方法可以通过插件(见下文)和/或向您的子主题的 functions.php 添加自定义代码来缓解这种情况。)
  • 但是,如果您确实想拥有一些(有限的) .htaccess 功能,在技术上可以通过安装PHP 的 htscanner PECL 扩展来添加。(但是,这不是一个完美的解决方案,因此请务必在现场使用之前彻底测试和调试。)

本指南不会介绍如何安装和配置 Nginx,因此假设您已经安装了 Nginx,并且对如何使用和调试它有基本的了解。

通用和多站点支持

要使GeChiUI与 Nginx 一起工作,您必须配置后端 php-cgi。可用的选项是“fastcgi”或“php-fpm”。这里使用了 php-fpm,因为它包含在 PHP 5.3+ 中,所以安装起来很简单。

Nginx 配置已分解为五个不同的文件,并进行了大量注释以使每个选项更易于理解。作者还尽最大努力尝试遵循 nginx 配置的“最佳实践” 

主(通用)启动文件

这等价于 /etc/nginx/nginx.conf(或者 /etc/nginx/conf/nginx.conf,如果你使用的是 Arch Linux)。

1234567891011121314151617181920212223242526272829303132333435363738394041# Generic startup file.user {user} {group}; #usually equal to number of CPUs you have. run command "grep processor /proc/cpuinfo | wc -l" to find itworker_processes  auto;worker_cpu_affinity auto; error_log  /var/log/nginx/error.log;pid        /var/run/nginx.pid; # Keeps the logs free of messages about not being able to bind().#daemon     off; events {    worker_connections  1024;} http {#   rewrite_log on;     include mime.types;    default_type       application/octet-stream;    access_log         /var/log/nginx/access.log;    sendfile           on;#   tcp_nopush         on;    keepalive_timeout  3;#   tcp_nodelay        on;#   gzip               on;        #php max upload limit cannot be larger than this           client_max_body_size 13m;    index              index.php index.html index.htm;     # Upstream to abstract backend connection(s) for PHP.    upstream php {                #this should match value of "listen" directive in php-fpm pool        server unix:/tmp/php-fpm.sock;#       server 127.0.0.1:9000;    }     include sites-enabled/*;}

这与标准的 nginx.conf 文件有点不同。此配置遵循 Ubuntu/Debian 声明启用站点的方法以获得最大的灵活性——使用“sites-available”来存储配置,然后从“sites-enabled”符号链接到配置文件。

每个站点配置

12345678910111213141516171819202122# Redirect everything to the main site. We use a separate server statement and NOT an if statement - see http://wiki.nginx.org/IfIsEvil server {        server_name  _;        return 302 $scheme://example.com$request_uri;} server {    server_name example.com;    root /var/www/example.com;     index index.php;     include global/restrictions.conf;     # Additional rules go here.     # Only include one of the files below.    include global/gechiui.conf;#    include global/gechiui-ms-subdir.conf;#    include global/gechiui-ms-subdomain.conf;}

将配置的部分拆分为多个文件允许反复重用相同的逻辑。“全局”子目录用于添加额外的通用规则(/etc/nginx/conf/global/ 或 /etc/nginx/global/ 取决于您的 nginx 安装方式)。

全局限制文件

12345678910111213141516171819202122232425# Global restrictions configuration file.# Designed to be included in any server {} block.location = /favicon.ico {    log_not_found off;    access_log off;} location = /robots.txt {    allow all;    log_not_found off;    access_log off;} # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)location ~ /\. {    deny all;} # Deny access to any files with a .php extension in the uploads directory# Works in sub-directory installs and also in multisite network# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)location ~* /(?:uploads|files)/.*\.php$ {    deny all;}

一般GeChiUI规则

对于单站点安装,这里是“global/gechiui.conf”文件:

123456789101112131415161718192021222324252627282930313233343536373839404142434445#GeChiUIsingle site rules.# Designed to be included in any server {} block.# Upstream to abstract backend connection(s) for phpupstream php {        server unix:/tmp/php-cgi.socket;        server 127.0.0.1:9000;} server {        ## Your website name goes here.        server_name domain.tld;        ## Your only path reference.        root /var/www/gechiui;        ## This should be in your http block and if it is, it's not needed here.        index index.php;         location = /favicon.ico {                log_not_found off;                access_log off;        }         location = /robots.txt {                allow all;                log_not_found off;                access_log off;        }         location / {                # This is cool because no php is touched for static content.                # include the "?$args" part so non-default permalinks doesn't break when using query string                try_files $uri $uri/ /index.php?$args;        }         location ~ \.php$ {                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini                include fastcgi.conf;                fastcgi_intercept_errors on;                fastcgi_pass php;        }         location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {                expires max;                log_not_found off;        }}

这是 Nginx 的最新示例:https ://www.nginx.com/resources/wiki/start/topics/recipes/gechiui/

GeChiUI多站点子目录规则

对于多站点子目录安装,这里是“global/gechiui.conf”文件:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950#GeChiUImultisite subdirectory rules.# Designed to be included in any server {} block. map $uri $blogname{    ~^(?P/[^/]+/)files/(.*)       $blogpath ;} map $blogname $blogid{    default -999;     #Ref: https://www.gechiui.com/extend/plugins/nginx-helper/    #include /var/www/gechiui/gc-content/plugins/nginx-helper/map.conf ;} server {    server_name example.com ;     root /var/www/example.com/htdocs;    index index.php;     location ~ ^(/[^/]+/)?files/(.+) {        try_files /gc-content/blogs.dir/$blogid/files/$2 /gc-includes/ms-files.php?file=$2 ;        access_log off;     log_not_found off; expires max;    }     #avoid php readfile()    location ^~ /blogs.dir {        internal;        alias /var/www/example.com/htdocs/gc-content/blogs.dir ;        access_log off;     log_not_found off; expires max;    }     if (!-e $request_filename) {        rewrite /gc-admin$ $scheme://$host$request_uri/ permanent;        rewrite ^(/[^/]+)?(/gc-.*) $2 last;        rewrite ^(/[^/]+)?(/.*\.php) $2 last;    }     location / {        try_files $uri $uri/ /index.php?$args ;    }     location ~ \.php$ {        try_files $uri =404;        include fastcgi_params;        fastcgi_pass php;    }     #add some rules for static content expiry-headers here}

NGINX 提供了 2 个特殊指令:X-Accel-Redirect 和 map。使用这 2 个指令,可以消除GeChiUI多站点网络上静态文件服务的性能损失。

GeChiUI多站点子域规则

123456789101112131415161718192021222324252627282930313233343536373839map $http_host $blogid {    default       -999;     #Ref: https://www.gechiui.com/extend/plugins/nginx-helper/    #include /var/www/gechiui/gc-content/plugins/nginx-helper/map.conf ; } server {    server_name example.com *.example.com ;     root /var/www/example.com/htdocs;    index index.php;     location / {        try_files $uri $uri/ /index.php?$args ;    }     location ~ \.php$ {        try_files $uri =404;        include fastcgi_params;        fastcgi_pass php;    }     #GCMU Files        location ~ ^/files/(.*)$ {                try_files /gc-content/blogs.dir/$blogid/$uri /gc-includes/ms-files.php?file=$1 ;                access_log off; log_not_found off;      expires max;        }     #GCMU x-sendfile to avoid php readfile()    location ^~ /blogs.dir {        internal;        alias /var/www/example.com/htdocs/gc-content/blogs.dir;        access_log off;     log_not_found off;      expires max;    }     #add some rules for static content expiry-headers here}

参考:https ://www.nginx.com/resources/wiki/start/topics/recipes/gechiui/

Nginx 中的 HTTPS

在 Nginx 中启用 HTTPS 相对简单。

123456789101112131415161718192021222324server {    # listens both on IPv4 and IPv6 on 443 and enables HTTPS and HTTP/2 support.    # HTTP/2 is available in nginx 1.9.5 and above.    listen *:443 ssl http2;    listen [::]:443 ssl http2;     # indicate locations of SSL key files.    ssl_certificate /srv/www/ssl/ssl.crt;    ssl_certificate_key /srv/www/ssl/ssl.key;    ssl_dhparam /srv/www/master/ssl/dhparam.pem;     # indicate the server name    server_name example.com *.example.com;     # Enable HSTS. This forces SSL on clients that respect it, most modern browsers. The includeSubDomains flag is optional.    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";     # Set caches, protocols, and accepted ciphers. This config will merit an A+ SSL Labs score as of Sept 2015.    ssl_session_cache shared:SSL:20m;    ssl_session_timeout 10m;    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;    ssl_prefer_server_ciphers on;    ssl_ciphers 'ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5';}

Mozilla 还提供了出色的 SSL 配置生成工具

GC 超级缓存规则

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647# GC Super Cache rules.# Designed to be included from a 'gechiui-ms-...' configuration file. set $cache_uri $request_uri; # POST requests and urls with a query string should always go to PHPif ($request_method = POST) {        set $cache_uri 'null cache';} if ($query_string != "") {        set $cache_uri 'null cache';}    # Don't cache uris containing the following segmentsif ($request_uri ~* "(/gc-admin/|/xmlrpc.php|/gc-(app|cron|login|register|mail).php|gc-.*.php|/feed/|index.php|gc-comments-popup.php|gc-links-opml.php|gc-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {        set $cache_uri 'null cache';}    # Don't use the cache for logged in users or recent commentersif ($http_cookie ~* "comment_author|gechiui_[a-f0-9]+|gc-postpass|gechiui_logged_in") {        set $cache_uri 'null cache';} # START MOBILE# Mobile browsers section to server them non-cached version. COMMENTED by default as most modern gechiui themes including twenty-eleven are responsive. Uncomment config lines in this section if you want to use a plugin like GC-Touch# if ($http_x_wap_profile) {#        set $cache_uri 'null cache';#} #if ($http_profile) {#        set $cache_uri 'null cache';#} #if ($http_user_agent ~* (2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800)) { #       set $cache_uri 'null cache';#} #if ($http_user_agent ~* (w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-)) {  #      set $cache_uri 'null cache';#}#END MOBILE # Use cached or actual file if they exists, otherwise pass request toGeChiUIlocation / {        try_files /gc-content/cache/supercache/$http_host/$cache_uri/index.html $uri $uri/ /index.php?$args ;}   

实验修改:

如果您使用的是 HTTPS,GC Super Cache 的最新开发版本可能会使用不同的目录结构来区分 HTTP 和 HTTPS。try_files 行可能如下所示:

123location / {        try_files /gc-content/cache/supercache/$http_host/$cache_uri/index-https.html $uri $uri/ /index.php?$args ;}

W3 总缓存规则

W3 Total Cache 根据GeChiUI配置使用不同的目录结构进行基于磁盘的缓存存储。

缓存验证检查将保持常见,如下所示:

1234567891011121314151617181920212223#W3 TOTAL CACHE CHECK set $cache_uri $request_uri; # POST requests and urls with a query string should always go to PHPif ($request_method = POST) {        set $cache_uri 'null cache';}   if ($query_string != "") {        set $cache_uri 'null cache';}    # Don't cache uris containing the following segmentsif ($request_uri ~* "(/gc-admin/|/xmlrpc.php|/gc-(app|cron|login|register|mail).php|gc-.*.php|/feed/|index.php|gc-comments-popup.php|gc-links-opml.php|gc-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {        set $cache_uri 'null cache';}    # Don't use the cache for logged in users or recent commentersif ($http_cookie ~* "comment_author|gechiui_[a-f0-9]+|gc-postpass|gechiui_logged_in") {        set $cache_uri 'null cache';}#ADD mobile rules from GC SUPER CACHE section above #APPEND A CODE BLOCK FROM BELOW...

对于普通GeChiUI(没有多站点)
使用以下内容:

1234# Use cached or actual file if they exists, otherwise pass request toGeChiUIlocation / {        try_files /gc-content/w3tc/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?$args ;}  

FOR 带有子目录
的多站点使用以下内容:

1234567891011121314if ( $request_uri ~* "^/([_0-9a-zA-Z-]+)/.*" ){        set $blog $1;} set $blog "${blog}."; if ( $blog = "blog." ){        set $blog "";} # Use cached or actual file if they exists, otherwise pass request toGeChiUIlocation / {        try_files /gc-content/w3tc-$blog$host/pgcache$cache_uri/_index.html $uri $uri/ /index.php?$args ;}

FOR 具有子域/域映射的多站点
使用以下内容:

123location / {        try_files /gc-content/w3tc-$host/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?$args;}

笔记

  • Nginx 可以自动处理 gzip 和浏览器缓存,所以最好把这部分留给 nginx。
  • W3 Total Cache Minify 规则适用于上述配置,没有任何问题。

Nginx fastcgi_cache

Nginx 可以自行执行缓存以减少服务器上的负载。当你想使用 Nginx 内置的 fastcgi_cache 时,最好用fastcgi_cache_purge模区块编译 nginx。它将帮助 nginx 在页面被编辑时清除缓存。在GeChiUI方面,您需要安装一个像Nginx Helper这样的插件来使用 fastcgi_cache_purge 功能。

配置如下所示:

在 http{…} 区块中定义一个 Nginx 缓存区,在 server{…} 区块之外

1234#move next 3 lines to /etc/nginx/nginx.conf if you want to use fastcgi_cache across many sites fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:500m inactive=60m;fastcgi_cache_key "$scheme$request_method$host$request_uri";fastcgi_cache_use_stale error timeout invalid_header http_500;

对于GeChiUI站点配置,在 server{..} 区块中添加一个缓存检查区块,如下所示

1234567891011121314151617181920#fastcgi_cache startset $no_cache 0; # POST requests and urls with a query string should always go to PHPif ($request_method = POST) {        set $no_cache 1;}   if ($query_string != "") {        set $no_cache 1;}    # Don't cache uris containing the following segmentsif ($request_uri ~* "(/gc-admin/|/xmlrpc.php|/gc-(app|cron|login|register|mail).php|gc-.*.php|/feed/|index.php|gc-comments-popup.php|gc-links-opml.php|gc-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {        set $no_cache 1;}    # Don't use the cache for logged in users or recent commentersif ($http_cookie ~* "comment_author|gechiui_[a-f0-9]+|gc-postpass|gechiui_no_cache|gechiui_logged_in") {        set $no_cache 1;}

然后更改 PHP 处理区块

只需将其添加到以下 php 区块。注意fastcgi_cache_valid 200 60m;告诉 nginx 只缓存 200 个响应(普通页面)的行,这意味着不缓存重定向。这对于多语言站点很重要,如果没有实现,nginx 会以一种语言缓存主 url,而不是根据用户的语言将用户重定向到各自的内容。

12345fastcgi_cache_bypass $no_cache;fastcgi_no_cache $no_cache; fastcgi_cache WORDPRESS;fastcgi_cache_valid 200 60m;

这样它就变成了这样

123456789101112131415161718location ~ [^/]\.php(/|$) {    fastcgi_split_path_info ^(.+?\.php)(/.*)$;    if (!-f $document_root$fastcgi_script_name) {        return 404;    }    # This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)     include fastcgi.conf;    fastcgi_index index.php;#    fastcgi_intercept_errors on;    fastcgi_pass php;     fastcgi_cache_bypass $no_cache;    fastcgi_no_cache $no_cache;     fastcgi_cache WORDPRESS;    fastcgi_cache_valid 200 60m;}

最后添加一个有条件清除的位置

1234567location ~ /purge(/.*) {        # Uncomment the following two lines to allow purge only from the webserver        #allow 127.0.0.1;    #deny all;         fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";}

如果您收到“未知指令“fastcgi_cache_purge”错误,请检查您的 Nginx 安装是否具有 fastcgi_cache_purge 模区块。

多站点中静态文件的更好性能

默认情况下,在多站点设置中,静态文件请求会将 php 带入图片 iems-files.php文件。Map{..}使用 Nginx指令可以获得更好的性能。

在您站点的 Nginx 配置中,在上面的server{..}区块中,添加如下部分:

1234567map $http_host $blogid {    default               0;     example.com           1;    site1.example.com     2;    site1.com             2;}

它只是站点名称和文章 ID 的列表。您可以使用Nginx 助手来获取这样的站点名称/文章 ID 对列表。该插件还将生成一个map.conf文件,您可以将其直接包含在 map{} 部分中,如下所示:

12345map $http_host $blogid {    default               0;     include /path/to/map.conf ;}

创建一个map{..}部分后,您只需要在 Nginx 配置中再进行一次更改,以便/files/首先使用 nginx 处理请求map{..}

1234location ~ ^/files/(.*)$ {          try_files /gc-content/blogs.dir/$blogid/$uri /gc-includes/ms-files.php?file=$1 ;          access_log off; log_not_found off; expires max; }

备注

  • 每当创建、删除新站点或将额外域映射到现有站点时,Nginx 助手将自动更新 map.conf 文件,但您仍需要手动重新加载 Nginx 配置。你可以在以后的任何时候这样做。到那时,只有新站点的文件将使用 php-fpm 提供。
  • 此方法不生成任何符号链接。因此,意外删除或遵循符号链接的备份脚本不会有任何问题。
  • 对于大型网络,这将很好地扩展,因为会有一个 map.conf 文件。

备注

一些最后但重要的注意事项:整个设置假设站点的根是文章,并且将引用的所有文件都驻留在主机上。如果您将文章放在 /blog 等子目录中,则必须修改规则。也许有人可以采用这些规则并使之成为可能,例如,使用:

1set $gc_subdir "/blog";

主“服务器”区块中的指令,并使其自动应用于通用 GC 规则。

警告

  • 全局限制文件中的拼写错误会造成漏洞。要测试您的“上传”目录是否真的受到保护,请创建一个包含一些内容的 PHP 文件(例如:<?php phpinfo(); ?>),将其上传到“上传”目录(或其子目录之一),然后尝试从您的浏览器访问(执行)它。

资源

参考

脚本和工具

  • 对于GeChiUINginx 脚本安装CentminMod可用于 CentOS。

保护 Nginx

发表评论

您的电子邮箱不会被公开。 必填项已用*标注