Featured image of post Nginx Cookbook

Nginx Cookbook

本文记录 Nginx 常见需求的配置实现,用作备忘录。没有什么技术含量。

AND / OR

Nginx 不支持常见的逻辑运算符 &&, || 等,这种需求只能通过添加一个变量来实现。

AND

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
set $flag "";
if (<condition1>) {
    set $flag "${flag}1";
}
if (<condition2>) {
    set $flag "${flag}1";
}
if ($flag = "11") {
    # condition1 && conditon2
}

OR

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
set $flag "";
if (<condition1>) {
    set $flag "1";
}
if (<condition2>) {
    set $flag "1";
}
if ($flag = "1") {
    # condition1 || conditon2
}

更复杂的判断类似,通过添加标记字符串后进行判断。

请求域名判断

一个 vhost 绑定多个域名,根据访问域名的不同执行不同的操作。典型需求是其他域名 301 跳转主域名。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
server
{
    listen 80;
    listen 443 ssl http2;
    server_name weargallery.app wg.chenhe.me wg.chenhe.cc;
    root /www/wwwroot/weargallery;

    if ($host != 'weargallery.app') {
      rewrite ^/(.*)$ https://weargallery.app/$1 permanent;
    }
}

SNI 动态选择证书

一个 vhost 绑定多个域名,且都开启 https。虽然 SAN 证书可以包含多个主机名,但如果域名本身就不同就没办法了。

利用 SNI,可以指示 Nginx 根据客户端请求的域名来使用对应的证书。

约定版

我们约定证书的名称为域名。

1
2
3
4
5
6
7
8
server
{
    listen 443 ssl http2;
    server_name weargallery.app wg.chenhe.me wg.chenhe.cc;

    ssl_certificate /www/cert/$ssl_server_name.cert;
    ssl_certificate_key /www/cert/$ssl_server_name.key;
}

$ssl_server_name 是 Nginx 内置变量,实际值就是客户端请求的域名。例如 ‘weargallery.app’, ‘wg.chenhe.cc’.

配置版

也可以手动指定每个域名对应哪个证书。

1
2
3
4
5
6
7
8
9
map $ssl_server_name $ssl_cert {
    default /www/cert/weargallery.app.cert; # 默认证书
    wg.chenhe.cc /www/cert/cc.cert;
  	wg.chenhe.me /www/cert/me.cert;
}
map $ssl_server_name $ssl_key {  } # 同理

ssl_certificate $ssl_cert;
ssl_certificate_key $ssl_key;

robots.txt

有时不方便以文件形式添加 robots.txt,例如一个反向代理服务。那么就可以用 Nginx 直接实现:

1
2
3
4
5
location = /robots.txt {
  default_type text/html;
  add_header Content-Type "text/plain; charset=UTF-8";
  return 200 "User-Agent: *\nDisallow: /";
}

常用内置变量

变量注释Example
http_*任意请求头字段$http_accept_language -> Accept-Language
scheme协议‘http’ / ‘https’
request_method请求方法GET
request_uri[只读] 原始请求 URI,不包括主机名,包括参数/admin/login?username=abc
is_args请求是否有查询参数有 - ‘?’;没有 - '’
args查询参数,不包括 ‘?’name=bob&age=33
arg_*任意查询参数的值,参数名自动转小写
uri不包括主机名与参数/admin/login
remote_addr客户端地址
remote_port客户端端口
禁止转载到私域(公众号,非自己托管的博客等),其他情况请注明原作者与可点击跳转的来源链接。