2024-12-18 18:08:02 +08:00

401 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "Nginx 笔记"
date: 2019-10-30T11:47:55+08:00
lastmod: 2024-11-28T13:22:00+08:00
tags: ["nginx", "https", "ssl", "反向代理"]
categories: ["web"]
---
## set
- set ${变量名} {字符串};
## 全局变量
- $args $query_string 请求行中的参数
- $content_length 请求头里的 Content-length 字段
- $content_type 请求头里的 Content-type 字段
- $document_root 请求在 root 指令中指定的值
- $host 请求头里的 Host 字段,如果没有则是服务器名
- $http_user_agent 客户端agent信息
- $http_cookie 客户端cookie信息
- $limit_rate 这个变量可以限制连接速率
- $request_method 客户端请求的动作通常为GET或POST
- $remote_addr 客户端的IP地址
- $remote_port 客户端的端口
- $remote_user 已经经过 Auth Basic Module 验证的用户名
- $request_filename 请求的文件路径,由 root 或 alias 指令与 URI 请求生成
- $scheme http 或者 https
- $server_protocol 请求使用的协议 HTTP/1.0 或 HTTP/1.1
- $server_addr 服务器地址,在完成一次系统调用后可以确定这个值
- $server_name 服务器名称
- $server_port 请求到达服务器的端口号
- $request_uri 包含请求参数的原始URI不包含主机名如"/foo/bar.php?arg=baz"
- $document_uri $uri 不带请求参数的当前URI不包含主机名如"/foo/bar.html"
## map
- 语法
```
map 源变量 自定义变量 {
hostnames; # 可以使用通配来匹配源变量
default 0; # 如果都不匹配,自定义变量的值是 0
源变量匹配字符串1 自定义变量值1;
源变量匹配字符串2 自定义变量值2;
...
源变量匹配字符串n 自定义变量值n;
include filename; # 包含“源变量匹配字符串”和“自定义变量值”对应关系的文件
}
```
- 位置http
- 匹配优先级,由高到低
* 常量
* 固定后缀的通配,示例如下
```
*.aa.com 1;
*.bb.cn 2;
```
* 固定前缀的通配,示例如下
```
aa.bb.*
cc.*
```
* 正则,必须以“~”或“~\*”开头,优先匹配第一个,可以包含命名捕获和位置捕获,示例如下
```
~^ab.cd$ # “~”开头,大小写敏感
~*ab.cd$ # “~*”开头,大小写不敏感
~^ab(?<name>.*)cd$ # 包含命名捕获
~^ab(/.*) # 包含位置捕获
```
## rewrite
- rewrite {url正则} {replacement} {last|break|redirect|permanent};
### location {} 外
- break 和 last 一样,只终止后续 server 级别的 rewrite
### location {} 内
- last
- 屏蔽当前 location {} 内的 root 和 proxy_pass
- 终止当前 location {} 内后续的 rewrite
- 尝试匹配其他 location {}
- 尝试执行 server 级别的 root
- break
- 终止当前 location {} 内后续的 rewrite
- 尝试执行当前 location {} 内的 proxy_pass
- 尝试执行当前 location {} 内的 root
- 尝试执行 server 级别的 root
### 重新发起请求
- redirect 返回 302 临时重定向
- permanent 返回 301 永久重定向
## if
- if(condition){...}
- false 字符串为空或以 0 开头都是
- = != 变量比较
- ~ !~ 区分大小写正则是否匹配
- ~* !~* 不区分大小写是否匹配
- -f !-f 判断文件是否存在
- -d !-d 判断目录是否存在
- -e !-e 判断文件、目录、链接是否存在
- -x !-x 判断可执行文件是否存在
## location
- = 精确匹配
- ^~ 开头匹配指定字符串,不是正则,匹配符合后停止搜索
- ~ 区分大小写的正则匹配,匹配符合后继续向下搜索
- ~`*` 不区分大小写的正则匹配,匹配符合后继续向下搜索
- / 通用匹配,可匹配任何请求,匹配后继续向下搜索
## try_files
- 未找到这四个文件时,跳转到 url/a/b/c
```
try_files file1 file2 file3 file4 /a/b/c;
```
- 未找到文件或目录时返回 403
```
try_files file1 dir2/ =403;
```
- 直接跳转到 location @app
```
try_files _ @app;
```
## error_page
- 语法
```
error_page code ... [=[response]] uri;
# code 只能是 4xx 或 5xx
# uri 可以包含变量,内部重定向请求,方法是 GET
```
- 位置: http, server, location, if in location
- 5xx 重定向到 /fk.html
```
error_page 500 502 503 504 /fk.html;
```
- 指定响应码
```
error_page 404 =200 /fk.html;
# 404 重定向到 /fk.html返回 200
error_page 401 = /proxy/api;
# 401 重定向到一个反代 location返回反代接口的响应码
```
- url 重定向
```
error_page 403 http://another-site/a/b/c;
# 403 重定向到 302返回 url
error_page 403 =301 http://another-site/a/b/c;
# 403 重定向到 301返回 url
```
## 客户端访问控制
- deny all 拒绝全部访问
- deny 192.168.1.0/24 拒绝指定网段
- deny 192.168.1.2 拒绝指定ip
- allow all 允许全部访问(默认)
- allow 192.168.1.0/24 允许指定网段
- allow 192.168.1.2 允许指定ip
## 配置 web 访问目录
```bash
location / {
root /var/www/html/;
index index.html index.htm;
}
```
## 下载
```nginx
location ^~ /attachment/ {
root /data/;
# alias /data/attachment/;
add_header Content-Disposition: 'attachment;';
}
```
## 浏览目录文件
```nginx
location ^~ /share/ {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
```
## 禁止浏览器缓存
```nginx
loaction ^~ /xxxxweb/ {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
expires off;
etag off;
}
```
## 反向代理负载均衡
- /etc/nginx/conf.d/upstream.conf
```nginx
http {
upstream tomcat {
#ip_hash;
server 192.168.1.201:8443 fail_timeout=32s;
server 192.168.1.202:8443 fail_timeout=32s;
server 192.168.1.203:8443 backup fail_timeout=32s;
keepalive 300;
}
```
- /etc/nginx/conf.d/80.conf
```nginx
server {
listen 80;
server_name _;
location ^~ /webapp/ {
proxy_pass http://tomcat;
## 增加/修改请求头
#proxy_set_header Host $host:$server_port;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Server $host;
## 设置请求体上限
#client_max_body_size 8m;
#client_body_buffer_size 8m;
## 设置连接超时、发送请求超时和读取响应超时
#proxy_connect_timeout 2s;
#proxy_send_timeout 16;
#proxy_read_timeout 16;
## 设置响应缓存大小
#proxy_buffer_size 64k;
#proxy_buffers 4 64k;
#proxy_busy_buffers_size 128k;
#proxy_max_temp_file_size 0;
## 禁用相应缓存
#proxy_cache off;
#proxy_buffering off;
## 跨域
#add_header 'Access-Control-Allow-Origin' *;
}
}
```
## 反向代理 websocket
```nginx
location /websocket/ {
proxy_pass http://127.0.0.1:8002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
```
## Basic HTTP 认证
- 生成密码文件(用户名是admin密码是123456)
```bash
echo "admin:$(openssl passwd -crypt 123456)" > /etc/nginx/nginx.auth
#或者
htpasswd -c -m /mnt/vdb1/svnrepos/accesspwd gxfp #根据提示输入密码
```
- 修改 nginx 配置http、server 和 location 都可以
```nginx
location / {
auth_basic "Kibana";
auth_basic_user_file /etc/nginx/nginx.auth;
}
```
## 自签 ssl 证书
```bash
mkdir /etc/nginx/ssl && cd /etc/nginx/ssl
openssl genrsa -out ssl.key 2048
openssl req -new -key ssl.key -days 3650 -out ssl.csr
openssl x509 -req -in ssl.csr -signkey ssl.key -out ssl.crt
```
## https 访问
```nginx
server {
ssl on;
listen 443 ssl;
server_name www.domain.com;
ssl_certificate /etc/nginx/ssl/ssl.crt;
ssl_certificate_key /etc/nginx/ssl/ssl.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
default_type text/plain;
return 200 "OK.\n";
}
```
## http 自动跳转 https有三种配置
- rewrite 服务端重定向
```nginx
server {
listen 80;
server_name www.domain.com;
rewrite ^(.*) https://$server_name$1 permanent;
}
```
- return 客户端重定向
```nginx
server {
listen 80;
server_name www.domain.com;
return 301 https://$server_name$request_uri;
}
```
- error_page 客户端重定向
```nginx
server {
ssl on;
listen 80;
listen 443 ssl;
server_name www.domain.com;
ssl_certificate /etc/nginx/ssl/ssl.crt;
ssl_certificate_key /etc/nginx/ssl/ssl.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
error_page 497 https://$server_name$request_uri;
}
```
## http 和 https 共存
```nginx
server {
listen 80;
listen 443 ssl;
server_name www.domain.com;
ssl_certificate /etc/nginx/ssl/ssl.crt;
ssl_certificate_key /etc/nginx/ssl/ssl.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
default_type text/plain;
return 200 "OK.\n";
}
```
## nginx 日志配置
- http 常规日志
```
log_format main '$remote_addr - [$time_local] "$request_method $uri" "$args" '
'"-" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
```
- http 登陆日志,打印 post 请求体
```
log_format login '$remote_addr - [$time_local] "$request_method $uri" "$args" '
'"$request_body" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
```
- https 常规日志,从 http_x_forwoarded_for 中获取请求源地址
```
log_format smain '$http_x_forwarded_for - [$time_local] "$request_method $uri" "$args" '
'"-" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "-"';
```
- https 登陆日志,从 http_x_forwoarded_for 中获取请求源地址,并打印 post 请求体
```
log_format slogin '$http_x_forwarded_for - [$time_local] "$request_method $uri" "$args" '
'"$request_body" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "-"';
```
## 常用全局配置
```nginx
events {
use epoll;
multi_accept on;
worker_connections 10240;
}
http {
access_log /var/log/nginx/access.log main;
gzip on;
sendfile on;
tcp_nopush on;
tcp_nodelay off;
server_tokens off;
keepalive_timeout 65;
types_hash_max_size 2048;
}
```