使用Nginx代替Openwrt中的uhttpd,并支持php

​ 在之前介绍过Openwrt部署typecho博客:Openert部署typecho博客,用的是默认的uhttpd,挺方便小巧;但是也有不足,就是性能很差,兼容性也不好,于是就萌生了使用Nginx代替uhttpd的想法。
于是需求就很明确了:

  1. 用Nginx实现Openwrt原本的uci界面
  2. 用Nginx实现Openwrt实现Typecho的php页面

现在Nginx已经集成在opkg源了,可以直接安装,安装之前先将uhttpd停用一下

1
/etc/init.d/uhttpd stop && /etc/init.d/uhttpd disable

也将之前uhttpd使用的php8-fastcgi停用一下

1
2
/etc/init.d/php8-fastcgi stop && /etc/init.d/php8-fastcgi disable
#并将/etc/config/php8-fastcgi里面的option enabled 1改成option enabled 0

停用完之后,安装Nginx涉及的包,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
uwsgi
uwsgi-syslog-plugin
uwsgi-cgi-plugin
uwsgi-luci-support
nginx-util
nginx-ssl-util
nginx-ssl
nginx
nginx-mod-luci
libopenssl-conf
openssl-util
nginx-mod-luci-ssl
luci-ssl-nginx
php8-fastcgi
php8-fpm

由于Nginx默认是不支持uci的,所以需要用uwsgi作为转发
装好之后,直接就可以访问Openwrt的uci界面了,接着就是折腾php这一块
1.先修改/etc/php8-fpm.d/www.conf,将chdir = / 改成 chdir = /www (注意/www是Typecho目录,这个看实际情况)
2.建立/etc/nginx/fastcgi_params文件,并放入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

3.新建/etc/nginx/conf.d/php.locations文件,并放入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
#error_log /dev/null;
fastcgi_connect_timeout 300s;
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_buffer_size 32k;
fastcgi_buffers 4 32k;
fastcgi_busy_buffers_size 32k;
fastcgi_temp_file_write_size 32k;
client_body_timeout 10s;
send_timeout 60s; # default, increase if experiencing a lot of timeouts.
output_buffers 1 32k;
fastcgi_index index.php;
#fastcgi_pass 127.0.0.1:1026;
fastcgi_pass unix:/var/run/php8-fpm.sock;
# include the fastcgi_param setting
include fastcgi_params;

# SCRIPT_FILENAME parameter is used for PHP FPM determining
# the script name. If it is not set in fastcgi_params file,
# i.e. /etc/nginx/fastcgi_params or in the parent contexts,
# please comment off following line:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

location = /blog/ {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
#error_log /dev/null;
fastcgi_connect_timeout 300s;
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_buffer_size 32k;
fastcgi_buffers 4 32k;
fastcgi_busy_buffers_size 32k;
fastcgi_temp_file_write_size 32k;
client_body_timeout 10s;
send_timeout 60s; # default, increase if experiencing a lot of timeouts.
output_buffers 1 32k;
fastcgi_index index.php;
index index.php;
#fastcgi_pass 127.0.0.1:1026;
fastcgi_pass unix:/var/run/php8-fpm.sock;
# include the fastcgi_param setting
include fastcgi_params;

# SCRIPT_FILENAME parameter is used for PHP FPM determining
# the script name. If it is not set in fastcgi_params file,
# i.e. /etc/nginx/fastcgi_params or in the parent contexts,
# please comment off following line:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

location = /blog/admin/ {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
#error_log /dev/null;
fastcgi_connect_timeout 300s;
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_buffer_size 32k;
fastcgi_buffers 4 32k;
fastcgi_busy_buffers_size 32k;
fastcgi_temp_file_write_size 32k;
client_body_timeout 10s;
send_timeout 60s; # default, increase if experiencing a lot of timeouts.
output_buffers 1 32k;
fastcgi_index index.php;
index index.php;
#fastcgi_pass 127.0.0.1:1026;
fastcgi_pass unix:/var/run/php8-fpm.sock;
# include the fastcgi_param setting
include fastcgi_params;

# SCRIPT_FILENAME parameter is used for PHP FPM determining
# the script name. If it is not set in fastcgi_params file,
# i.e. /etc/nginx/fastcgi_params or in the parent contexts,
# please comment off following line:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

此处解释一下,location ~ [^/].php(/|$)项是为了手动输入/www下多层目录的php文件,location = /blog/项是为了输入域名/blog后默认打开/blog下的index.php,location = /blog/admin项也是雷同
3.修改/etc/config/nginx文件,下面是我的配置,仅供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
config main global
option uci_enable 'true'

config server '_lan'
#list listen '433 ssl default_server'
#list listen '[::]:433 ssl default_server'
option server_name '_lan'
list include 'restrict_locally'
list include 'conf.d/*.locations'
option uci_manage_ssl 'self-signed'
option ssl_certificate '/etc/nginx/conf.d/_lan.crt'
option ssl_certificate_key '/etc/nginx/conf.d/_lan.key'
option ssl_session_cache 'shared:SSL:32k'
option ssl_session_timeout '64m'
option access_log 'off; # logd openwrt'

config server '_redirect2ssl'
list listen '80'
list listen '[::]:80'
option server_name '_redirect2ssl'
option return '302 https://$host$request_uri'

config server '_redirect2ssl'
list listen '90'
list listen '[::]:90'
option server_name '_redirect2ssl'
option return '302 https://$host:433$request_uri'

解释:由于Openwrt的nginx启动脚本强制从/etc/config/nginx加载后转化成/var/lib/nginx/uci.conf,无法更改太多东西,所以/etc/config/nginx仅改一下端口、强制http转https,因为运营商默认屏蔽80\443端口,只能改其他端口
4.新建/etc/nginx/conf.d/new.conf,并放入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server { #see uci show 'nginx._lan'
listen 433 ssl default_server;
listen [::]:433 ssl default_server;
server_name wangyougx_com;
include restrict_locally;
include conf.d/*.locations;
ssl_certificate /etc/nginx/conf.d/wangyougx_com.crt;
ssl_certificate_key /etc/nginx/conf.d/wangyougx_com.key;
ssl_session_timeout 10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
include mime.types;
}

解释:如果你的域名已有证书,就填入,切记不要试图修改Nginx默认的_lan.crt!没用的;

操作到这里,基本算完成了,接下来重启以下服务:

1
2
3
/etc/init.d/uwsgi restart 
/etc/init.d/php8-fpm restart
/etc/init.d/nginx restart

附加建议:
1.建议将/etc/uwsgi/emperor.ini 内的vassal-set项目改成vassal-set = die-on-idle=false(进程不休眠重启)
2.通过logread命令查看日志,会发现提示/www/favicon.ico文件不存在,这个是网页标签图标,可不理会,也可以找个喜欢的图标放进去即可。

引用:

Nginx之 Location 的生成

openwrt nginx 配置PHP