Skip to content

Nginx速查手册

Posted on:2021年9月28日 at 14:53 (8 min read)

TOC

Open TOC

0x00 Nginx 手册

0x01 常用配置

详细参考: nginx 配置语法实用配置

location

匹配命令

参数名称说明示例
普通前端匹配的路径location 后没有参数直接跟着 标准 URI,表示前缀匹配,代表跟请求中的 URI 从头开始匹配。location / {}
=精确匹配的路径用于标准 URI 前,要求请求字符串与其精准匹配,成功则立即处理,nginx 停止搜索其他匹配。location = / {}
^~抢占式前缀匹配的路径用于标准 URI 前,并要求一旦匹配到就会立即处理,不再去匹配其他的那些个正则 URI,一般用来匹配目录location ^~ / {}
~正则匹配用于正则 URI 前,表示 URI 包含正则表达式, 区分大小写
~*正则匹配用于正则 URI 前, 表示 URI 包含正则表达式, 不区分大小写
@命名路径@ 定义一个命名的 location,@ 定义的 locaiton 名字一般用在内部定向,例如 error_page, try_files 命令中。它的功能类似于编程中的 goto。location @a {}

nginx location 的大致匹配顺序:

if

if 指令仅存在于 serverlocation 块中

# 语法
if (condition) {}

condition 判断条件:

0x02 常用配置

静态资源服务器

# 仅允许指定资源访问,当资源不存在时,返回/index.html
server{
  listen 80;
  server_name static.vlean.xyz;
  location / {
    index index.html;
    try_files $uri $uri/ /index.html;
  }
  location ~ .*\.(html|htm|css|js|png|jpeg|gif|svg)$ {
    root /static/path/;
  }
}

# 仅允许指定资源访问,当资源不存在时,报403
server{
  listen 80;
  server_name static.vlean.xyz;
  location / {
    index index.html;
    try_files $uri $uri/ /index.html;

    set $flag 0;
    if ( $request_filename ~* .*\.(html|htm|css|js|png)$){set $flag 1;}
    if ( $request_filename = ""){set $flag 1;}
    if ( $request_filename = "/"){set $flag 1;}
    if ( $flag != 1 ) {
      return 403;
    }
  }
}

PHP-FPM/laravel

server {
  listen 80;
  server_name php.vlean.com;
  root /web/public;

  index index.html index.htm index.php;
  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {
    # 使用socket或端口接收请求
    #fastcgi_pass unix:/var/run/php7.2-fpm.sock;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
  }
}

Python Wsgi

server {
    listen      80;
    server_name python.vlean.xyz;

    location / {
        root /web/fe/;
		    index index.html;
        try_files $uri $uri/ /index.html;
    }
    location /api/ {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:9527;
        uwsgi_param UWSGI_SCRIPT web.wsgi;
        uwsgi_param UWSGI_CHDIR /web/path;
        client_max_body_size  20m;
    }
}

Websocket 反向代理

nginx 反向代理 websocket

# map指令可以将变量组合成为新的变量,会根据客户端传来的连接中是否
# 带有Upgrade头来决定是否给源站传递Connection头, 这样做的方法比直接全部传递upgrade更加优雅
map $http_upgrade $connection_upgrade {
  default upgrade;
  '' close;
}

server {
  listen       80;
  server_name local.vlean.xyz;

  location / {
    # 读写超时时间,默认60s
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;

		# 允许重新定义或附加字段到传递给代理服务器的请求标头。
    # 该value可以包含文本,变量,以及它们的组合。
    # 当且仅当proxy_set_header当前级别上没有定义任何指令时,这些指令才从先前的配置级别继承。
    # 默认情况下,只重新定义了两个字段:Host和Connection
    # http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

    # 多级代理websocket协议,websocket之前可以去除Host
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_http_version 1.1;

    # 升级协议为websocket
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_pass http://127.0.0.1:9527;
  }
}

Gzip 压缩

server {
    # 开启 gzip 压缩(默认 off)
    gzip on;
    # 设置压缩文件的类型(text/html)
    gzip_types text/csv text/xml text/css text/plain text/javascript application/javascript application/json application/xml;
    # 设置 gzip 所需的 HTTP 协议最低版本(HTTP/1.1, HTTP/1.0)
    gzip_http_version 1.1;
    # 设置压缩级别,压缩级别越高压缩时间越长  (1-9)
    gzip_comp_level 4;
    # 设置压缩的最小字节数, 页面 Content-Length 获取
    gzip_min_length 1000;
}

缓存

# 对 html 文件缓存,绝对过期时间
location ~ .*\.(htm|html)$ {
  # h/d/max 小时/天/无限
  expires 24h;
  root /var/www/html;
}

# 对静态资源缓存,相对过期时间
# Cache-Control: public|private|no-cache|nly-if-cached
# max-age=second
location ~* \.(js|css|png|jpg|gif)$ {
    add_header  Cache-Control public,max-age=86400;
}

跨域

server {
  listen       80;
  server_name  example.com;

  # 全局变量获得当前请求 origin,带 Cookie 的请求不支持 *(通配符)
  add_header 'Access-Control-Allow-Origin' $http_origin;
  # 为 true 可带上 cookie
  add_header 'Access-Control-Allow-Credentials' 'true';
  # 允许请求方法,前后端域名不一致时,需要带上OPTIONS
  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  # 允许请求的 header,可以为 *(通配符)
  add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers;
  add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

  if ($request_method = 'OPTIONS') {
    # OPTIONS 请求的有效期,在有效期内不用发出另一条预检请求
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain; charset=utf-8';
    add_header 'Content-Length' 0;

    # 200 也可以
    return 204;
  }

  location / {
    root  /usr/share/nginx/html/be;
    index index.html;
  }
}

防盗链

location ~* \.(gif|jpg|png|jpeg)$ {
  # 只允许 192.168.0.1 请求资源
  # none 表示没带 refer
  # blocked 表示不是标准 HTTP 请求
  valid_referers none blocked 192.168.0.1;

  if ($invalid_referer) {
    rewrite ^/ http://$host/logo.png;
  }
}

强制 HTTPS

server {
  listen 80;

  location / {
    return 301 https://$host$request_uri;
  }
}

server {
  listen 443 ssl;
  # 公钥,发送到连接服务器的客户端
  ssl_certificate         cert/example.com.pem;
  # 私钥,权限要得到保护但 Nginx 的主进程能够读取
  ssl_certificate_key     cert/example.com.key;
  # 设置 SSL/TLS 会话缓存的类型和大小
  ssl_session_cache       shared:SSL:10m;
  # 客户端可以重用会话缓存中 SSL 参数的过期时间
  ssl_session_timeout     10m;
  ssl_protocols               SSLv2 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers                 ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
  ssl_prefer_server_ciphers   on;
}

动静分离

upstream static {
  server host:port;
}

upstream dynamic {
  server host:port;
}

server {
  listen 80;

  # 拦截动态资源
  location ~ .*\.(php|jsp)$ {
    proxy_pass http://dynamic;
  }

  # 拦截静态资源
  location ~ .*\.(jpg|png|htm|html|css|js)$ {
    root /data/;  #html目录
    proxy_pass http://static;
    autoindex on;  #自动打开文件列表
  }
}