0x00前言
最近采用Linux+Nginx+PHP+Mysql的方式搭建一个CodeIgniter框架的系统,需求为除了某个特定URL采用HTTP访问以外,其余均强制采用HTTPS访问。
2018-8-28更新配置实现,特定路径(如:/api/*)采用HTTP访问以外,其余均强制采用HTTPS访问。
0x01系统搭建
- 服务器配置ubuntu+nginx+mysql+php5配置,参考链接:How To Install Linux, nginx, MySQL, PHP (LEMP) stack on Ubuntu 14.04
- HTTPS配置,参考链接:How To Secure Nginx with Let’s Encrypt on Ubuntu 14.04
0x02特定URL采用HTTP访问以外,其余均强制采用HTTPS访问的Nginx配置
按照前面系统搭建过程安装并配置、选择采用全部重定向HTTPS的默认配置文件如下:
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
38server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.php index.html index.htm;
server_name 域名或IP地址;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
listen 443 ssl; # managed by Certbot
ssl_certificate fullchain.pem文件路径; # managed by Certbot
ssl_certificate_key privkey.pem文件路径; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
}根据需求添加对CodeIgniter框架的支持和某个特定URL采用HTTP访问,其余均强制采用HTTPS访问。
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
52server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.php index.html index.htm;
server_name 域名;
location / {
try_files $uri $uri/ =404;
}
location /二级目录/ {
try_files $uri /二级目录/index.php;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/域名/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/域名/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
set $flag 0;
if ($scheme != "https") {
set $flag "${flag}1";
}
if ($request_uri != "特定的URL") {
set $flag "${flag}2";
}
if ($flag = "012") {
return 301 https://$host$request_uri;
} # managed by Certbot
}
其中主要添加如下两处配置配置:
对CodeIgniter框架的支持
1
fastcgi_param PATH_INFO $fastcgi_path_info;
某个特定URL采用HTTP访问以外,其余均强制采用HTTPS访问添加的配置,由于Nginx的判断if条件不支持逻辑&&,需求的等价逻辑如下:
1
2
3if ($scheme != "https" && $request_uri != "特定的URL" ){
return 301 https://$host$request_uri;
}
曲折的具体实现为:1
2
3
4
5
6
7
8
9
10
11set $flag 0;
if ($scheme != "https") {
set $flag "${flag}1";
}
if ($request_uri != "特定的URL") {
set $flag "${flag}2";
}
if ($flag = "012") {
return 301 https://$host$request_uri;
} # managed by Certbot
0x03特定路径(如:/api/*)采用HTTP访问以外,其余均强制采用HTTPS访问的Nginx配置
曲折的具体实现为:1
2
3
4
5
6
7
8
9
10
11set $flag 0;
if ($scheme != "https") {
set $flag "${flag}1";
}
if ($request_uri !~= /特定路径/*) {
set $flag "${flag}2";
}
if ($flag = "012") {
return 301 https://$host$request_uri;
} # managed by Certbot
0x04小结
通常网络上关于NginxHTTPS配置主要有两种:HTTP和HTTPS同时存在或者所有HTTP强制转发HTTPS。然而项目需要特定URL支持HTTP访问,其余URL强制采用HTTPS,所有产生了本文。此外添加$scheme != “https”的判断是为了防止请求被循环重定向导致网页无法正常访问的问题,由于Nginx配置文件不支持逻辑与(and),采用等价的配置完成需要的功能。