Linux 运维手册之 NGINX 地址重写及 HTTPS
后知后觉 暂无评论

地址重写及 HTTPS 是网站配置重要的一环,地址重写可以实现伪静态和地址跳转,HTTPS 可以保证网站传输安全。

地址重写(rewrite)

地址重写可以实现地址 A 跳转 B,或者实现伪静态,隐藏网站参数保证(相对)安全。

地址重写规范

语法:rewrite 正则表达式 替换规则 [标记]
语段:server, location, if

重写规则中可以使用 NGINX 内置变量,点击查看 搜索关键字 Embedded Variables

重写规则常用内置变量

变量名说明
$host请求的主机
$request_uri请求的URI
$request_filename请求的文件完整路径
$scheme请求的协议(HTTP/HTTPS)
$server_name请求的服务域名
$server_protocol请求的服务协议
小贴士:$request_filename(包含网站的主目录)与 $request_uri(不包含网站的主目录)

地址重写标记

标记说明
last本条规则匹配完成后,停止匹配,不在匹配后面的规则
break本条规则匹配完成后,停止匹配,不在匹配后面的规则
redirect返回302临时重定向, 地址栏会显示跳转后的地址
permanent返回301永久重定向, 地址栏会显示跳转后的地址

关于 breaklast 区别

location /break/ {
     rewrite ^/break/(.*) /test/$1 break;
     return 402;
}

location /last/ {
     rewrite ^/last/(.*) /test/$1 last;
     return 403;
}

location /test/ {
     return 508;
}

请求: http://domain/break/*
返回: 404

请求: http://domain/last/*
返回: 508

原因: 根据上述内容,break 与 last 都停止处理后续 rewrite 指令集,不同之处在与 last 会重新发起新的请求,而 break 不会。当请求 break 时,如匹配内容存在的话,可以直接请求成功,返回 200 ;而如果请求内容不存在,则返回 404 。当请求为 last 的时候,会对重写的新 uri 重新发起请求,如上例则返回 508 。

总结:last与break都停止处理后续rewrite指令集,最大的不同是,last会重新发起一个新请求,并重新匹配location。

地址重写案例

案例 1

用户访问 www.domain.com/netdata/ 实际上真实访问是 netdata.domain.com/

location /netdata {
    return 302 http://netdata.domain.com$request_uri;
}

案例 2

用户访问 /2018/ccc/bbb/index.html 实际上真实访问是 /2014/ccc/bbb/index.html

server {
    location /2018 {
        rewrite ^/2018/(.*)$ /2014/$1 redirect;
    }
}

案例 3

用户访问 source-11-22-33.html 实际上真实访问是 /source/11/22/33/source.html

server {
    location / {
        rewrite ^/source-(.*)-(.*)-(.*).html$ /source/$1/$2/$3/source.html redirect;
    }
}

HTTPS 相关

小贴士:从 2020 年开始,主流浏览器将禁用 TLS 1.0/1.1,因此从现在开始应该进行适应性修改。另外据谷歌统计,目前 Chrome 只有 0.5% 的 HTTPS 连接使用 TLS 1.0/1.1。

证书区别与种类

证书种类(!AVIF)

如图,SSL 证书按大类一般可分为 DV SSL 、OV SSL 、EV SSL 证书。有的也会叫做域名型、企业型、增强型证书,不同的厂商叫法可能有所不同,但差别不大。

1)域名型SSL证书(DV SSL)
即证书颁布机构只对域名的所有者进行在线检查,通常是验证域名下某个指定文件的内容,或者验证与域名相关的某条 TXT 记录;比如访问 [http|https]://http://www.domain.com/…/test.txt,文件内容: 2016082xxxxx39w7b20nelfa;或在与域名相关的DNS服务器上添加一条 TXT 记录:http://www.domain.com –> TXT –> 20170xxxxxqmkiby43hpvy8
2)企业型SSL证书(OV SSL)
是要购买者提交组织机构资料和单位授权信等在官方注册的凭证,证书颁发机构在签发 SSL 证书前不仅仅要检验域名所有权,还必须对这些资料的真实合法性进行多方查验,只有通过验证的才能颁发 SSL 证书。
3)增强型SSL证书(EV SSL)
与其他 SSL 证书一样,都是基于 SSL/TLS 安全协议,但是验证流程更加具体详细,验证步骤更多,这样一来证书所绑定的网站就更加的可靠、可信。它跟普通 SSL 证书的区别也是明显的,安全浏览器的地址栏变绿,如果是不受信的 SSL 证书则拒绝显示,如果是钓鱼网站,地址栏则会变成红色,以警示用户。

常见国际 CA 厂商

国际 CA 厂商(!AVIF)

小贴士:Let's Encrypt 已经支持多域名及通配符证书。

常见国内 CA 厂商

国内 CA 厂商(!AVIF)

配置全局 HTTPS (NGINX)

此配置需要使用 rewrite 规则,需要将全站重写到 HTTPS。

server {
    listen 80;
    server_name domain.com;
    # 第一种
    rewrite ^(.*) https://$server_name$1 redirect;
    # 第二种
    return 301 https://$server_name$request_uri;
    ...
}

server {
    listen 443;
    server_name domain.com;
    ssl on;
}

配置全局 HTTPS (APACHE)

配置跳转需要使用 Apache mod_rewrite 模块才能实现。

<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteCond %{SERVER_PORT} 80
 RewriteRule ^(.*)$ https://www.domain.com/$1 [R=301,L]
</IfModule>

把这段代码放在 .htaccess 文件,即可实现 HTTPHTTPS 的重定向。

HTTPS 注意事项

重点:想实现全局 HTTPS ,不仅需要配置 NGINX/APACHE ,还需要保证网页内引用的资源全部使用 HTTPS。

负载均衡架构的 HTTPS

在负载均衡架构中,访客的请求会先发送到负载均衡器进行调度,然后分发给后端的集群。

因为 NGINX 中反代有两种方式,因此有两种实现全局 HTTPS 的方式:

四层代理TCP/IP)及七层代理HTTP)两种模型

在企业局域网中这两种方案皆可,异地或者跨机房部署的情况下推荐使用七层代理模式。

此处就七层代理情况下进行详细说明:

其一:在负载均衡器上进行配置

配置代理参数文件

# cat /etc/nginx/proxy_params
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;

proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;

配置代理主文件

# cat /etc/nginx/conf.d/www.conf
upstream backend {
    server 192.168.1.7:443 max_fails=1 fail_timeout=60s;
    server 192.168.1.8:443 max_fails=1 fail_timeout=60s;
}
server {
    listen 80;
    server_name www.domain.com;
    return 301 https://$server_name$request_uri;
}
server {
    listen 443;
    server_name www.domain.com;
    ssl on;
    ssl_certificate     ssl/full_chain.pem;
    ssl_certificate_key ssl/private.key;
    ssl_dhparam         ssl/dhparams.pem;

    ssl_protocols TLSv1.2;

    location / {
        proxy_pass https://backend;
        include proxy_params;
    }
}

其二:在后端负载上进行配置(web01)

# cat /etc/nginx/conf.d/www.conf
server {
    listen 443;
    server_name www.domain.com;
    root /var/www/html;
    index index.php index.html;
    ssl on;
    ssl_certificate     ssl/full_chain.pem;
    ssl_certificate_key ssl/private.key;
    ssl_dhparam         ssl/dhparams.pem;

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        }
}
小贴士:因负载均衡器上已经定义了使用后端 443 端口,因此后端服务器上无需启用 80 端口。

其三:在后端负载上进行配置(web02)

# cat /etc/nginx/conf.d/www.conf
server {
    listen 443;
    server_name www.domain.com;
    root /var/www/html;
    index index.php index.html;
    ssl on;
    ssl_certificate     ssl/full_chain.pem;
    ssl_certificate_key ssl/private.key;
    ssl_dhparam         ssl/dhparams.pem;

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        }
}
注意:后端负载的配置完全一致。

附录

参考链接

本文撰写于一年前,如出现图片失效或有任何问题,请在下方留言。博主看到后将及时修正,谢谢!
禁用 / 当前已拒绝评论,仅可查看「历史评论」。