现代化的 Typecho Nginx 规则书写

现在的中文互联网信息真的是一言难尽,如屎海淘金,不管你如何好学肯上进,搜索问题得到的答案通常都是反复转载且过时甚至是错误的。

好比搜索关于 Typecho 的 Nginx 规则,大概率会得到如下答案:

#伪静态
if (-f $request_filename/index.html){
    rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
    rewrite (.*) $1/index.php;
}
if (!-e $request_filename){
    rewrite (.*) /index.php;
}

    # 安全设置
rewrite /(var|usr)(.+ph*)$ /index.php;
rewrite /(config.inc.php|.htaccess)$ /index.php last;

然而对于现在你手上的 Nginx 来说:

  • if 指令是低效的:Nginx 官方文档多次强调应避免使用 if 来进行路由判断,它的执行顺序和作用域有时会违反直觉,效率也低于 try_files。
  • 丢失了请求参数:rewrite (.*) /index.php; 这句规则的含义是:“如果请求的文件或目录不存在,就把请求的URL重写为/index.php”。问题在于,它把所有不匹配的URL都粗暴地指向了/index.php,却丢掉了原始的请求路径和查询参数。
  • rewrite /(var|usr)(.+ph*)$ /index.php;这条规则意图不明且有风险。Typecho 的核心文件就存放在 usr 目录,这条规则可能会无意中拦截正常的后台请求。
  • rewrite /(config.inc.php|.htaccess)$ /index.php last; 这是一种过时且不安全的写法。对于敏感文件,我们应该直接返回 403 Forbidden 或 404 Not Found,而不是把它重写到 index.php。使用 location 块来处理是更标准、更安全的方式。

下面是一些建议的写法。

  1. 核心的 URL 重写规则 (现代化、高效且正确)解决 404 问题

    location / {
     # 尝试文件 -> 尝试目录 -> 交给 index.php 处理
     try_files $uri $uri/ /index.php?$query_string;;
    }
    
     # try_files 指令会按顺序检查:
     # $uri  - 是否存在与请求URI完全匹配的文件 (例如 /style.css)
     # $uri/ - 是否存在与请求URI完全匹配的目录 (例如 /admin/)
     # /index.php?$args - 如果前两者都找不到,则将请求内部转发给 index.php,并附加原始的请求参数($args)
  2. 统一的安全设置 (更清晰、更标准)

     #    直接禁止访问所有PHP文件在非后台入口的敏感目录
     location ~* /(app|content|lib)/.*\.(php|php5)$ {
         deny all;
     }
     #    禁止访问特定的配置文件和开发文件
     location ~* /(composer\.json|composer\.lock|\.git|\.env|\.htaccess) {
         deny all;
     }
     #    对Typecho根目录的配置文件进行精确匹配和禁止,性能更高
     location = /config.inc.php {
         deny all;
     }
  3. 静态资源处理与优化

     #    为所有静态资源设置浏览器缓存,并添加CORS头
     location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
         # 允许跨域,方便CDN或API调用字体
         add_header Access-Control-Allow-Origin "*";
         # 设置浏览器缓存时间为1个月
         expires 1M;
         # 关闭此location的访问日志,减少IO消耗
         access_log off;
     }
  4. 图片 404 优化

     location ~* \.(jpe?g|png|gif|webp)$ {
         log_not_found off;
         try_files $uri /content/images/system/default/404.gif;
         # 使用 try_files 来更优雅地实现
         # 如果原始图片($uri)存在,就返回它;如果不存在,就返回默认的404图片
     }

现在,你可以尝试着去改改你那些舅姥爷写的 Nginx 规则了,当然记得先备份,先备份,先备份。
改完了别忘了 nginx -t 没问题 nginx -s reload 重新上膛。
OVER!

本文链接:

https://blog.coffox.cc/archives/19/
1 + 2 =
快来做第一个评论的人吧~