天天看点

nginx配置

本文主要是记录下nginx各种需求的配置,会持续更新。

nginx 配置优先级

  1. 匹配到全等匹配时,终止后续所有匹配,直接返回;
  2. 步骤一未匹配上时,然后遍历所有的普通匹配,按照最长匹配原则找到最满足的匹配项,如果匹配项前面有^~符号,则终止后续正则匹配,采用该匹配项;反之则继续后续的正则匹配
  3. 步骤一二都未匹配上时,此时进行正则匹配,找到第一个满足的正则匹配项,直接返回,若都不满足,则返回步骤二中的最长匹配项

两个项目通过同一nginx的相同端口访问

nginx nginx.com.cn 10.100.3.10

server 10.100.3.12

访问url:

https://aaa.test.com

https://bbb.test.com

将以上两个域名解析到nginx所在server的ip

使用同一个端口时,就按server_name走

server {
            listen              443 ssl;
            server_name         aaa.test.com;
            ssl_certificate     /xx/xxx/server.crt;
            ssl_certificate_key /xx/xxx/server.key;
    
            location / {
                proxy_pass      http://10.100.3.12:8888;
            }
        }
    
    server {
            listen              443 ssl;
            server_name         bbb.test.com;
            ssl_certificate     /xx/xxx/server.crt;
            ssl_certificate_key /xx/xxx/server.key;
    
            location / {
                proxy_pass      http://10.100.3.12:6666;
            }
        }
           

让http访问跳转到https

访问http://aaa.test.com跳转到https://aaa.test.com,即同时支持http与https访问

server {
        listen              80;
        server_name         aaa.test.com;

        if ($scheme = http ) {
        return 301 https://$host$request_uri;
             }
        }
           

使用同一个域名端口代理两个不同的服务

通过nginx.com.cn:80可以访问到aaa.test.com与bbb.test.com

server {
    listen       80;
    server_name nginx.com.cn;
    index        index.html index.htm index.php;

    location /aaa  {
            proxy_pass https://aaa.test.com/;     
       }
    location /bbb {
            proxy_pass https://bbb.test.com/;
       }
    }
           

以上效果是:

当访问 http://nginx.com.cn/aaa 转到https://aaa.test.com/

当访问 http://nginx.com.cn/bbb 转到https://bbb.test.com/

注: proxy_pass那行的最后一个/的作用是:转发到 https://aaa.test.com/不带旧的路径,当没有这个/,就是http://nginx.com.cn/aaa 转发到https://aaa.test.com/aaa

nginx配置

多个路由跳转同一地址

server {
    listen       80;
    listen       443 ssl;
    server_name  m.aaa.com  x.aaa.com;

    ssl_certificate       aaa.com-chain.pem;
    ssl_certificate_key   aaa.com-key.pem;


    location ^~ /dir1 {
        rewrite ^/(.*) https://e.bbb.com$1 redirect;
    }
    location ~^/(dir2/ttt|dir3|dir4|dir5) {
        if ($scheme = http) {
                        rewrite ^(.*)$  https://$host$1 permanent;  
        }
        proxy_pass https://f.bbb.com;
    }


    location /{
        client_body_buffer_size 20M;
        client_max_body_size 20M;
            if ($scheme = http) {
                        rewrite ^(.*)$  https://$host$1 permanent;
        }
        proxy_pass  https://houduanserverzu;
    }
}
           

rewrite与proxy_pass

rewrite 与 proxy_pass虽然最后访问的页面相同,但是他们访问的方式却是不一样的。

rewrite:用户 http://old.com --> nginx (rewrite http://new.com ) -->返回new url到用户 --> 用户请求http://new.com (现象为用户搜索栏的http://old.com变为http://new.com)此为跳转;

proxy_pass:用户 http://old.com --> nginx (proxy_pass http://new.com ) --> nginx访问http://new.com 返回给用户 (现象为用户搜索栏的http://old.com不变)此为代理。

域名跳转

将域名写在upstream中,会降域名解析成ip,跳转到对应的ip,而不是域名

eg:

www.aaa.com 10.2.1.1

upstream  testdomain {
  server  www.aaa.com;
}

server {
       listen              443 ssl;
       server_name         bbb.test.com;
       ssl_certificate     /xx/xxx/server.crt;
       ssl_certificate_key /xx/xxx/server.key;
    
       location / {
           proxy_pass  http://testdomain;
            }
        }
           

此时效果是 http://10.2.1.1

server {
      listen              443 ssl;
      server_name         bbb.test.com;
      ssl_certificate     /xx/xxx/server.crt;
      ssl_certificate_key /xx/xxx/server.key;
    
      location / {
          proxy_pass  http://www.aaa.com;
            }
        }
           

此时效果是 http://www.aaa.com

location =/ 与 location / 优先级不同,引发的访问错误问题

我域名www.aaa.com 走代理,在代理服务器上配置

server {

listen 80;

listen 443 ssl;

server_name www.aaa.com;

ssl_certificate aaa-chain.pem;
ssl_certificate_key aaa-key.pem;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

location = / {
    if ($scheme = http) {
        rewrite ^(.*)$  https://$host$1 permanent;
    }
    client_body_buffer_size 20M;
    client_max_body_size 20M;
    proxy_pass http://aaa-backend;
}
           

}

http://www.aaa.com/test

后端服务器接受不到请求,请求访问到代理服务器的nginx/html下,并未转到后端代理.

将location =/替换为 location /,访问恢复正常。

请求头与响应头

今天的需求是:将某个文件的 location /test/aaa 的Content-Type配置为json格式"application/json",我做了如下配置一直报错 502

location /test/aaa {

proxy_set_header Content-Type "application/json";

原因:

请求头:客户端/上游代理 通到服务器有关于客户端请求的信息头

响应头:服务器返回到浏览器的信息头

proxy_set_header:是Nginx设置请求头信息给上游服务器

add_header:是Nginx设置响应头信息给浏览器

这里的Content-Type为响应头,需要这样配置:

add_header 'Content-Type' 'application/json';

但是这样配置会添加一个新的响应头,不会覆盖之前的nginx.conf里的 default_type application/octet-stream,那么如何覆盖呢?

headers-more-nginx-module(ngx_headers_more)模块:用于添加、设置和清除输入和输出的头信息
           

nginx -V查看你的nginx是否安装此模块,若没有,请自行安装。

覆盖之前的响应头

location /test/aaa {
    more_set_headers  "Content-Type:application/json";
}
           

注:可能是版本的原因,写成 more_set_headers "Content-Type" "application/json"; 不生效。

删除之前的响应头

location /test/aaa {
    more_clear_headers  "Content-Type:application/json";
}
           

还有其他一些用法,大家可自行查阅其他资料

HSTS 强制跳转请求头

加上HSTS请求头,可以实现http强制跳转https

语法:Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]

max-age 是必须的参数,它是一个以秒为单位的数值,它代表着HSTS Header的过期时间,一般设置为1年,即 31536000秒。

includeSubDomains 是可选参数,如果设置该参数的话,那么意味着当前域名及其子域名均开启HSTS的保护。

preload是可选参数,只有当你申请将自己的域名加入到浏览器内置列表的时候才需要使用到它。

eg: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"