nginx

概览

官网 nginx.org

官方文档地址 http://nginx.org/en/docs/

Usage statistics of web servers https://w3techs.com/technologies/overview/web_server

nginx 版本分为 Mainline version and Stable version

查看nginx当前最新稳定版 http://nginx.org/en/download.html

nginx应用场景  

- 静态处理
- 反向代理
- 负载均衡
- 代理缓存
- 访问限制
- 访问认证
- 安全防护

Nginx作为Web服务器的主要应用场景:
    ❑ 使用Nginx运行HTML、JS、CSS、小图片等静态数据(此功能类似Lighttpd软件)
    ❑ 使用Nginx运行MP4、FLV等视频流媒体服务。
    ❑ Nginx结合FastCGI运行PHP等动态程序(常用fastcgi_pass方式)
    ❑ Nginx结合Tomcat/Resin等支持Java动态程序(常用proxy_pass方式)
    ❑ Nginx结合Uwsgi等支持Python动态程序(常用uwsgi_pass方式)

Nginx采用Epool网络模型, Apache采用Select模型。  
Select: 当用户发起一次请求,select模型就会进行一次遍历扫描,从而导致性能低下。  
Epool: 当用户发起请求,epool模型会直接进行处理,效率高效,并无连接限制。  

nginx分为2种版本:
    - Mainline version 开发版
    - Stable version 稳定版

安装

http://nginx.org/en/linux_packages.html#RHEL-CentOS

cat << 'EOF' > /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

查看能够安装的nginx版本 yum list nginx --showduplicates

yum install nginx-1.16.1

nginx -V

##################################################### 冗余信息 #################################################
yum list nginx --showduplicates
Available Packages
nginx.x86_64          1:1.8.0-1.el7.ngx                 nginx-stable
nginx.x86_64          1:1.8.1-1.el7.ngx                 nginx-stable
nginx.x86_64          1:1.10.0-1.el7.ngx                nginx-stable
nginx.x86_64          1:1.10.1-1.el7.ngx                nginx-stable
nginx.x86_64          1:1.10.2-1.el7.ngx                nginx-stable
nginx.x86_64          1:1.10.3-1.el7.ngx                nginx-stable
nginx.x86_64          1:1.12.0-1.el7.ngx                nginx-stable
nginx.x86_64          1:1.12.1-1.el7.ngx                nginx-stable
nginx.x86_64          1:1.12.2-1.el7_4.ngx              nginx-stable
nginx.x86_64          1:1.14.0-1.el7_4.ngx              nginx-stable
nginx.x86_64          1:1.14.1-1.el7_4.ngx              nginx-stable
nginx.x86_64          1:1.14.2-1.el7_4.ngx              nginx-stable
nginx.x86_64          1:1.16.0-1.el7.ngx                nginx-stable
nginx.x86_64          1:1.16.1-1.el7                    epel        
nginx.x86_64          1:1.16.1-1.el7.ngx                nginx-stable
nginx.x86_64          1:1.18.0-1.el7.ngx                nginx-stable

rpm -ql nginx

[root@node1 ~]# rpm -ql nginx
/etc/logrotate.d/nginx
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/modules
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service
/usr/sbin/nginx
/usr/sbin/nginx-debug
/var/cache/nginx
/var/log/nginx
....

牛刀小试

nginx安装完毕,我们最简单就是把它当作解析静态文件来用,如解析 html css js jpg 之类的文件,感觉就像是当个浏览器来用,不过为了更简单化,我们下面就直接让nginx监听某个端口,在web界面上给我们输出hello-world好了

# systemctl status nginx
# cat /usr/lib/systemd/system/nginx.service | grep nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
# /usr/sbin/nginx -h
# ls  /etc/nginx/conf.d/default.conf
# cat   /usr/share/nginx/html/index.html

# fgrep ".log" /etc/nginx/nginx.conf
error_log  /var/log/nginx/error.log warn;
    access_log  /var/log/nginx/access.log  main;


systemctl start nginx
netstat -lntup | grep 80

打开浏览器访问80端口 注意不能有其它程序占用80端口,否则起不来的。

也可以在本地使用curl直接访问 curl 127.0.0.1:80

我们可以修改下配置文件,监听其它的端口

sed -i "s#listen .*#listen 9999;#g"  /etc/nginx/conf.d/default.conf 
nginx -t
systemctl restart nginx
curl 127.0.0.1:9999

一般机器可以使用的端口范围 (1, 65535)

静态html文件示例

# mkdir /test
# vim /test/index.html
# cat /test/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx! - test</title>
<meta charset="utf-8" />
<style>
    body {
        width: 35em;
        margin: 0 auto;
    }
</style>
</head>
<body>
<h1>欢迎来到 nginx!</h1>
<p>这是nginx测试页面</p>
<p>本页面的源代码写在:/test/index.html</p>
<p>本页面的配置文件写在:/etc/nginx/conf.d/test.conf</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

相同端口根据域名区分服务

不同的端口区分不同的服务,这是业界标配,端口这个东西很大程度上就是用来区分不同的服务,理解起来也非常直观

想象一下这个场景,我们的直接需求是需要跑个服务,如某购物网站,此时我们需要买一台机器,比如就在阿里云上买,机器买到手的同时我们也得到了一个公网IP,类似于 117.51.149.5 这样,当我们的服务搭建好之后,我们就可以使用 ip:port 类似 117.51.149.5:80 来访问,一般机器上的端口都有几万个,完全足够我们使用了,开发阶段就可以这样用,不过相信你也知道,正常我们访问互联网上的知名服务,没有直接使用ip的,都是用域名访问,类似于 baidu.com jd.com qq.com 这样,ip看起来不够专业,并且比较难记

如果我们买了一个域名,比如 mytest.com,我们同时也就拥有了几乎无数的二级域名,如 x.mytest.com b.mytest.com 这都是我们可以随意创建的,无需再支付费用,我们可以在购买域名的网站上,比如阿里云域名后台配置解析服务,就是当我们输入自己买的域名,自动帮我们调转到指定的公网IP地址上面去,这一步操作是靠着阿里云的DNS服务器实现的,对于大部分人的使用习惯来说,让 docs.mytest.com 指向一个文档类的页面,download.mytest.com 指向一个下载类的页面,是非常自然的,后面没接端口默认使用的也就是80端口,此时我们当然可以买2台机器,一个域名指向一个机器,这样完全不会有端口冲突的问题了,但是这样比较奢侈了,因此 同一台机器 同一个端口 根据域名区分不同的服务,就成了我们常见的需求,而nginx可以非常方便的解决这类问题,如下:

mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.off

# cat /etc/nginx/conf.d/docs.as4k.com.conf 
server {
    listen 80;
    server_name  docs.as4k.com;
    location / {
        root   /tmp/docs.as4k.com;
        index  index.html index.htm;
    }
}

# cat /etc/nginx/conf.d/download.as4k.com.conf 
server {
    listen 80;
    server_name  download.as4k.com;
    location / {
        root   /tmp/download.as4k.com;
        index  index.html index.htm;
    }
}

mkdir -p /tmp/docs.as4k.com
mkdir -p /tmp/download.as4k.com
echo "docs.as4k.com" > /tmp/docs.as4k.com/index.html
echo "download.as4k.com" > /tmp/download.as4k.com/index.html
echo "127.0.0.1 docs.as4k.com download.as4k.com" >> /etc/hosts

nginx -t 
systemctl restart nginx
curl -s docs.as4k.com
curl -s download.as4k.com

多个域名指向同一个服务

# cat /etc/nginx/conf.d/as4k.com.conf
server {
    listen 8080;
    server_name  www.as4k.com as4k.top;
    location / {
        root   /tmp/as4k.com;
        index  index.html index.htm;
    }
}

mkdir -p /tmp/as4k.com
echo "as4k.com OR www.as4k.top" > /tmp/as4k.com/index.html
echo "127.0.0.1 as4k.com www.as4k.com" >> /etc/hosts

nginx -t 
systemctl restart nginx
curl -s as4k.com:8080
curl -s www.as4k.com:8080

http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name

nginx搭建文件下载服务

搭建完毕静态资源网站,在浏览器输入域名,nginx会根据相应的配置文件,自动访问代码目录里的,index.html,如果没有此文件,一般会提示403 Forbidden。利用nginx搭建文件下载服务,实际上就是,把里面的目录结构展示给 用户。

cat /etc/nginx/conf.d/download.conf
server {
    listen 8090;
    server_name didi.as4k.top;
    charset utf-8;

    location / {
        root /tmp;
        index xxx.xxx;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
    }
}
nginx -t
systemctl restart nginx

简单解释:
    index xxx.xxx; # 更改默认主页
    autoindex on;  # 开启目录索引功能
    autoindex_exact_size off; # 人类可读显示文件大小
    autoindex_localtime on;  # 显示本地时间
http://nginx.org/en/docs/http/ngx_http_autoindex_module.html

nginx 作为下载服务器使用性能非常高,应用于大流量生产环境毫无性能问题,带宽基本打满

nginx 访问认证

如果我们希望用户在浏览器输入某个地址,不是直接打开该页面,而是需要输入账号密码认证通过后才能打开这个页面,这样的需求可以直接利用nginx自带的访问认证功能实现

cat /etc/nginx/conf.d/auth.conf
server {
    listen 8091;
    server_name didi.as4k.top;
    charset utf-8;

    location / {
        root /tmp;
        index xxx.xxx;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        auth_basic "Need Auth";
        auth_basic_user_file /etc/nginx/auth_passwd;
    }
}
yum install httpd-tools
htpasswd -b -c /etc/nginx/auth_passwd as4k 123456
cat /etc/nginx/auth_passwd

解释:
    auth_basic "Need Auth";                      # 里面的字符串任意,不可省略
    auth_basic_user_file /etc/nginx/auth_passwd; # 存放密码文件,不能是明文。

1 打开对应页面,发现需要输入账号密码才能进去

2 输入账号密码,正常进去

不过这里如果我们直接使用wget下载会发现报错

[root@10-255-20-218 conf.d]# wget http://didi.as4k.top:8091/tmp.txt
--2020-04-06 11:38:19--  http://didi.as4k.top:8091/tmp.txt
Resolving didi.as4k.top (didi.as4k.top)... 117.51.149.5
Connecting to didi.as4k.top (didi.as4k.top)|117.51.149.5|:8091... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Authorization failed.

因为此时的地址是加密认证的,我们可以这样下载
wget http://as4k:123456@didi.as4k.top:8091/tmp.txt

抽象语法 wget http://username:password@didi.as4k.top:8091/tmp.txt

wireshark抓取密码认证包

在网页端基于账户密码的验证,账号和密码都是明文输入的,可以是wireshark等工具,抓取出来看到。

基于IP访问控制

这个功能这里只是简单列举,实际工作中,这种需求都是直接用安全组控制

[root@web02 nginx]# cat /etc/nginx/conf.d/test.conf
server {
    listen 80;
    server_name test1.as4k.top;
    charset utf-8;
    root /test;

    location / {
        index index.html;
        deny  222.222.1.1;
        allow 36.2.1.0/24;
        allow 10.0.0.7;
        deny  all;
    }

    location /ftp {
        index xxx.xxx;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
    }
}

解释:
    location / {
        index index.html;
        deny  222.222.1.1; # 拒绝
        allow 36.2.1.0/24; # 允许
        allow 10.0.0.7;    # 允许
        deny  all;         # 其它所有-拒绝
    }

nginx status - 自带状态信息

nginx有个模块可以显示当前的连接状态信息,如请求数,已连接数等

# cat /etc/nginx/conf.d/status.conf
server {
    listen 8081;
    server_name  localhost;
    location /basic_status  {
        stub_status;
        access_log  off;
    }
}
nginx -t 
systemctl restart nginx
curl -s 127.0.0.1:8081/basic_status

http://nginx.org/en/docs/http/ngx_http_stub_status_module.html

日志

nginx中的日志大致分为两类,访问日志和错误日志:
    /var/log/nginx/access.log
    /var/log/nginx/error.log

cat /etc/nginx/nginx.conf
    log_format  main  
        '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    ...

`log_format`定义了一个变量main,该变量就表示了一种日志格式,后面就是这个日志的详细  
格式定义,后面的`access_log`就定义了日志的位置和使用的格式main,默认的日志格式分为  
三行,每一行都是用单引号包围起来的,里面的双引号会原样输出,里面的变量($开头)会被解析。

在server区块和location区块都是可以定义自己的日志的,单独定义日志之后,就不会再全局  
日志中生成日志了。

nginx日志允许使用的变量

$remote_addr            # 记录客户端IP地址
$remote_user            # 记录客户端用户名
$time_local             # 记录通用的本地时间
$time_iso8601           # 记录ISO8601标准格式下的本地时间
$request                # 记录请求的方法以及请求的http协议
$status                 # 记录请求状态码(用于定位错误信息)
$body_bytes_sent        # 发送给客户端的资源字节数,不包括响应头的大小
$bytes_sent             # 发送给客户端的总字节数
$msec                   # 日志写入时间。单位为秒,精度是毫秒。
$http_referer           # 记录从哪个页面链接访问过来的
$http_user_agent        # 记录客户端浏览器相关信息
$http_x_forwarded_for   # 记录客户端IP地址
$request_length         # 请求的长度(包括请求行, 请求头和请求正文)。
$request_time           # 请求花费的时间,单位为秒,精度毫秒

官方变量索引:http://nginx.org/en/docs/varindex.html

location 区块匹配

匹配符 匹配规则 优先级
= 精确匹配 1 (最高)
^~ 以某个字符串开头 2
~ 区分大小写的正则匹配 3
~* 不区分大小写的正则匹配 4
!~ 区分大小写不匹配的正则 5
!~* 不区分大小写不匹配的正则 6
/ 通用匹配,任何请求都会匹配到 7

nginx 反向代理

有时候我们会遇到类似如下这些需求:

  • 安全组只开放了80端口,我们不能随便改,但是我们搭建的服务是监听在8080端口的,这个服务我们不太熟悉,或者根本就不是我们搭建的,我们不想重启它,不想动它,我们就需要访问机器的80端口自动跳转到访问机器的8080端口,面向前端完全透明,反正老板是不会care你是如何实现的,老板只关心这个服务好没好,我怎么用
  • 某台机器上的某个服务,监听在一个本地端口上,比如 127.0.0.1:8888 ,但是现在我们希望在公网上就能访问这个服务,直接能想到的方法就是能不能通过改配置之类的把这个服务的监听端口换成 0.0.0.0:8888,还是那个前提,我们不想动,或者说我们也不敢动这个服务,随便改配置重启,万一服务崩了,那就炸了,我们需要变通的,放回其它能访问的端口,跳转到这个本地端口
  • 我们有一台机器,假设是 192.168.1.1 ,这台机器是面向公网全面锁死,不开放任务端口,但是我们就是想访问这台机器上的80端口

可以看到上面遇到的这些问题总结起来就是 我们不能直接访问某台机器的某个端口 ,而我们利用nginx给出的解决方案就是代理,它的原理就是,我自己不能访问,但是我找一个能访问的中间机器(或者中间端口)去帮我访问,反问得到的内容中间代理返回给我们,对外界几乎完全透明,就像是能直接访问一样

代理服务器简单来说就是中转站的作用,比如我们科学上网使用的VPN就是一种代理,被称为正向代理,代理的是客户端。还有一种是反向代理,主要是部署在服务器前端出口上的,代理的是服务端,比如我们有1台WEB机器,1台代理机器,上面都安装上NGINX,如果我们配置了代理,用户访问网站时不是直接请求的WEB机器,而是通过代理机器,代理机器再请求WEB机器,WEB机器把内容返回给代理机器,代理机器再返回给用户。

cat /etc/nginx/conf.d/proxy.conf 
server {
    listen 9999;
    server_name didi.as4k.com;
    
    location / {
        proxy_pass http://127.0.0.1:8080;
        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_pass http://127.0.0.1:8080;
最好是同一类协议互相代理即http和http玩,https和https玩,如果想要http和https互相代理,会遇到相当多的坑
127.0.0.1 这个ip地址只要是一个有效的地址就可以,公网,内网,localhost,/etc/hosts解析的内容,都可以,最关键的是与要被代理的机器要能通信
剩下的都是些优化参数,无需赘述

7层 负载均衡

配置负载均衡可以增强网站集群架构的三大功能:消除单点故障,故障恢复,故障检测。消除单点故障是指后端WEB服务器集群任何一台死机都不影响网站整体对外提供服务。故障恢复是指任何一台WEB机器死机,其它机器可以直接顶上。后端WEB集群中所有机器都是做一样的事情,WEB集群之间互相并不知道对方的存在,比如后端任何一台WEB机器死机,其它机器并不能得知这一消息,而只有负载均衡机器准确知道后端所有机器当前的状态,如果负载机器检查到后端某一台机器已经死机,那么这台机器自动被移除调度行列,不会再被分配到任务,直到其能够正常工作为止,这就是故障检测能力。

Algorithms Description
Round Robin 默认值,表示按顺序轮询。
weight 加权轮询,weight值越大,分配到的访问几率越高
ip_hash 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器
url_hash 按照访问URL的hash结果来分配请求,是每个URL定向到同一个后端服务器
least_conn 最少链接数,那个机器链接数少就分发
[root@lb01 conf.d]# cat wecenter.conf 
upstream backend {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    server 172.16.1.9:80;
}

server {
    listen 80;
    #server_name wecenter.as4k.com;
    location / {
        proxy_pass http://backend;
        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;
    }
}

4层 负载均衡

[root@lb01 ~]# cat /etc/nginx/nginx.conf 

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

stream {
    #1. 定义虚拟资源池
    upstream ssh {
        server 172.16.1.7:22;
    }

    upstream mysql {
        server 172.16.1.51:3306;
    }

    #2. 调用虚拟资源池
    server {
        listen 5555;
        proxy_pass ssh;
    }

    server {
        listen 6666;
        proxy_pass mysql;
    }
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

#################################################### 4层负载参考案例2 ####################################################
[root@pg-node1 nginx]# cat /etc/nginx/nginx.conf 

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

stream {
    upstream backend {
      server 192.168.2.32:5432;
      #   server 192.168.2.36:5432;
    }

    server {
        listen 6666;
        proxy_pass backend;
    }
}



http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

根据不同浏览器转到不同页面

[root@lb01 ~]# vim /etc/nginx/conf.d/phone_proxy.conf
upstream iphone {
    server 172.16.1.7:80;
}

upstream android {
    server 172.16.1.8:80;
}

server {
    listen 80;
    server_name phone.as4k.com;
    location / {
        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;

        #不区分大小写,正则匹配
        if ($http_user_agent ~* "iphone") {
            proxy_pass http://iphone;
        }

        if ($http_user_agent ~* "android") {
            proxy_pass http://android;
        }

        return 200 "only support phone";
    }
}
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

根据用户代理信息,判断客户端设备类型,在location中使用正则匹配,定位到不同的页面。

rewrite

[root@lb01 ~]# cat /etc/nginx/conf.d/xtest.conf 
server {
    listen 80;
    server_name localhost;
    root /xtest;
    index index.html;
    rewrite /index.html /home.html;
}
[root@lb01 ~]# mkdir -p /xtest 
[root@lb01 ~]# cat /xtest/home.html 
hello-home-html
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

[root@lb01 ~]# hostname -I
10.0.0.5
[root@lb01 ~]# cat /etc/nginx/conf.d/xtest.conf 
server {
    listen 80;
    server_name 10.0.0.5;
    root /xtest;
    index index.html;
    return 302 http://as4k.top;
}

还可以安装Chrome HTTP Status插件,更为直观的看到效果:

[root@lb02 ~]# cat /etc/nginx/conf.d/xtest.conf 
server {
    listen 80;
    server_name 10.0.0.6;
    default_type text/plain;
    return 200 "hello-world";
}
[root@lb02 ~]# nginx -t
[root@lb02 ~]# systemctl restart nginx

[root@lb01 ~]# cat /etc/nginx/conf.d/xtest.conf 
server {
    listen 80;
    server_name 10.0.0.5;
    root /xtest;
    index index.html;
    rewrite /2018-09-mc-auto-raise.mp4 /2018/09/mc-auto-raise.mp4;
}
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

[root@lb01 ~]# cat /etc/nginx/conf.d/xtest.conf 
server {
    listen 80;
    server_name 10.0.0.5;
    root /xtest;
    index index.html;
    rewrite /2018-09-mc-auto-raise.mp4 /2018/09/mc-auto-raise.mp4 redirect;
}
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

[root@lb01 ~]# cat /etc/nginx/conf.d/xtest.conf 
server {
    listen 80;
    server_name 10.0.0.5;
    root /xtest;
    index index.html;
    rewrite /2018-09-mc-auto-raise.html /2018/09/mc-auto-raise.mp4 redirect;
}
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

[root@lb01 ~]# cat /etc/nginx/conf.d/xtest.conf 
server {
    listen 80;
    server_name 10.0.0.5;
    root /xtest;
    index index.html;
    #rewrite /page-5.html /home.html?page=5 redirect;
    rewrite  /page-([1-9]+).html /home.html?page=$1 redirect;
}
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

配置nginx支持https

[root@lb01 ~]# cat /etc/nginx/conf.d/https.conf 
server {
    listen 443;
    server_name 10.0.0.5;
    ssl on;
    ssl_certificate      /etc/nginx/ssl_key/server.crt;
    ssl_certificate_key  /etc/nginx/ssl_key/server.key;

    location / {
        root /xtest;
        index index.html;
    }
}

server {
    listen 80;
    server_name 10.0.0.5;
    rewrite  (.*) https://$server_name$request_uri redirect;
    #rewrite (.*) https://$server_name$1 redirect;
    #rewrite ^/(.*)$ https://your.domain.com/$1 permanent;
}
[root@lb01 ~]# mkdir -p /xtest
[root@lb01 ~]# echo "TEST-HTTPS..." > /xtest/index.html 
[root@lb01 ~]# nginx -t
[root@lb01 ~]# systemctl restart nginx

`$server_name`表示主机名,`$request_uri`表示请求的地址,合起来就是去掉协议的网址部分。

在谷歌浏览器中访问`10.0.0.5`,会提示不受信任的证书,单击高级,继续访问:

友好的错误页面

可以在nginx中定制错误页面,给用户更好的体验。

error_page  404              /404.html;

    #redirect server error pages to the static page /50x.html

如下错误状态码进行跳转/500.jpg
error_page 500 502 503 504  /500.jpg;

当有人访问500.jpg 则进行精准匹配
location = /500.jpg {
    root   /code/error;
}

/root目录下的页面无法访问

/root目录默认的权限如下:

dr-xr-x---.   8 root root  4096 Jul  3 13:57 root

目录的owner.group都是root,权限为550。也就是说,除了root账户对该目录有读取\执行的权限外,其他账户没有任何权限。而nginx运行时所使用的账户不可能是root,所以nginx对该目录没有任何权限,导致访问该目录下的页面总是Permission denied。

因此,只要给/root目录加上一个默认账户执行的权限就可以了,即将权限调整为551。调整之后重试,问题解决。

证书配置 https

本文档以CentOS 7、Nginx 1.15.6为例
https://help.aliyun.com/document_detail/98728.html?spm=5176.2020520163.0.0.132b56a7xf8IJ8

# 以下属性中以ssl开头的属性代表与证书配置有关,其他属性请根据自己的需要进行配置。
server {
    listen 443 ssl;              #SSL协议访问端口号为443。此处如未添加ssl,可能会造成Nginx无法启动。
    server_name localhost;       #将localhost修改为您证书绑定的域名,例如:www.example.com。
    root html;
    index index.html index.htm;
    
    ssl_certificate     cert/domain name.pem;   #将domain name.pem替换成您证书的文件名。
    ssl_certificate_key cert/domain name.key;   #将domain name.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;   

    location / {
        root html;   #站点目录。
        index index.html index.htm;   
    }
}

http 请求跳转到 https
server {
    listen 80;
    server_name localhost;                      # 将localhost修改为您证书绑定的域名,例如:www.example.com。
    rewrite ^(.*)$ https://$host$1 permanent;   # 将所有http请求通过rewrite重定向到https。
    location / {
        index index.html index.htm;
    }
}

支持反向代理的一份https配置参考
[root@nexus3 conf.d]# cat docker_images.conf 
upstream nexus_docker_get {
    server 127.0.0.1:8084;
}

upstream nexus_docker_put {
    server 127.0.0.1:8082;
}

server {
    listen               443 ssl;
    server_name          test.as4k.com;
   
    ssl_certificate      /nexus3/cert/test.com.crt;
    ssl_certificate_key  /nexus3/cert/test.com.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;
   
    client_max_body_size      0;
    chunked_transfer_encoding on;
   
    set $upstream "nexus_docker_put";
    if ( $request_method ~* 'GET') {
        set $upstream "nexus_docker_get";
    }

    if ($request_uri ~ '/search') {
        set $upstream "nexus_docker_put"; 
    }  

    index index.html index.htm index.php;
    location / {
        proxy_pass http://$upstream;
        proxy_set_header Host $host;
        proxy_connect_timeout 3600;
        proxy_send_timeout 3600;
        proxy_read_timeout 3600;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_buffering off;
        proxy_request_buffering off;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto http;
    }
}


配置K8S Dashboard证书参考
[root@dpk1 conf.d]# cat /etc/nginx/conf.d/k8s.as4k.com.conf 

server {
    listen 443    ssl;                       
    server_name   k8s.as4k.com;
    root          html;
    index         index.html index.htm;
    
    ssl_certificate                /etc/nginx/cert/as4k.com.crt;  
    ssl_certificate_key            /etc/nginx/cert/as4k.com.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;

    location / {
        proxy_pass                 https://127.0.0.1:30000;
        proxy_set_header Host      $host;
        proxy_connect_timeout      3600;
        proxy_send_timeout         3600;
        proxy_read_timeout         3600;
        proxy_set_header           X-Real-IP $remote_addr;
        proxy_buffering            off;
        proxy_request_buffering    off;
        proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header           X-Forwarded-Proto http;
    }
}

server {
    listen          80;
    server_name     k8s.as4k.com;
    rewrite ^(.*)$  https://$host$1 permanent;
}

别忘记在相应的域名管理平台把域名解析到对应的公网IP地址上去

xtest.as4k.top 证书记录

bogon:~ ndps$ cat /Users/ndps/Downloads/3797235_xtest.as4k.top_nginx/3797235_xtest.as4k.top.key
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAtMoQdbLDcgmRNYcCf8pfZ/Dp73oJCdAmIsCkdgxGSqqgRrxa
5JUsB+r5kYtV3qCJ+fl+LI7A5x7tIziNf8N3qxjp70iInMzoA5RvRdaHZJ+9JiFH
mbhcQJLFrTcNYWG9okIEKLPTCz8cIJDM9OuMGuTJMsqVQkBAEAHZwGqokoLByzej
SzKAv/bEYPC40/406/pYZh3CS1TydUo3VV8k+0PVKRR5aq3fjgh4av3608+b8yKS
k0vaqZfFE2Em1x4A6An8qMTOmb5EjZ9ybLIkzXUFJUplRNW4Mg6EzOdMkRgWt+60
A/o14576zac8krltSj9Ym71f0ZsTSvzz6hmJRQIDAQABAoIBADs7eOkXCLH0MH85
HLiBtYB4jizH7u4oJFZ+h2Ol4eHUxW5nh+Acf7CYa+wjmp62On6MH6q5mroeh9Ni
U/noMOz93KdpPFkjSWDi4RIgl3uAWpiDjtHudUsyy1FVGC0vuNHQj0xGnn6wzqZc
ysnz4pNtIf5iIUTziAm2kYFZcKGPaGmEBbsqffSP/sPh3Kp0CZ07xZHU/wSoWqHc
mZuTFL7Dy8nWF+PNAS1usW/gh06c7Ig/AbT9HrrugtYtyMFJ3XXxKfrYOP/bnz8o
FzAwKF3iABbgVyIHBOhk8Xwk69YffExjWCdnVGVKUaFVU6aYb4U/NnUsvdpZ4TC9
wDr3+oECgYEA5afEFJxIkaqShe2jVKml9oa5w69D0nua/MvTQDfrwvMWmGJ7lvDy
8yELoV3b+1+ds98pH+QDEYusQlufxvvGPeWf6tVlWXBniYuZsX8FNlUAt9G5WmOG
WV+lt6Y3Jzu6LLAymoVvyY1hFR9eOIUyEzcykkItVMrlUPr/PrPAuvcCgYEAyYdC
7CpVORwXtaETxnNlvTxdiwOaBaI81FkRiPLzYQ5etY4cG2UR2cwtsCc+VeDgs13a
C2+VnhmQvEV7kaf/Q5WBuY0lnI1uxuWz14e42PAgxfjCeRx3upWhVt3unrdIVFUw
Bw2d7kjnZn7kzrBLMIQvi1pJndOvU4uFU6FD8qMCgYBRX+7UtsPoCZ69ogS73RkX
j4mHUzUfAflbFgYWvTnm7CfXex370AjmKZFrbkyid7DzqWFzEWIc93bkVH77DP+j
sxfFKDQvSusFC9g70pxQMjJ87+1Tn+xdAs0/k7/7QOipKQ3lPt7rdhMuXt0N/fRO
ZsKenKBfaT10QlvrJdpm5QKBgAmqMfxvf0zQ2xY71l3zFNMBfR74mj9g63fnmZ6u
wBtMfCBK43Aw5a1DTIGhMC0gLsaLXrSjslI1uao9ztJKc0SDfAgxC7e5VLG3PGu+
t4+33GqCJpl2Uwugt28aD6KO+aoJt9buwT83Qdm5hjGfZMu72yfcuaEXENZ533gG
SOLvAoGARIB4hGOWlXwGILgZ8kv9gb0jjtdFqAlsUfRLMQ6iZGQscktJGboEEpfF
18ACLspxyXFHhQFtqZwINYTNx8tUm277lJ7/Jp3yhesf9fZxLeeS41J0ZVkmtBxI
ze+7IaDwJzvYhPQ+uArunSoeB08EV3H/wYFVaWW9sS7CkpWFZZY=
-----END RSA PRIVATE KEY-----






bogon:~ ndps$ cat /Users/ndps/Downloads/3797235_xtest.as4k.top_nginx/3797235_xtest.as4k.top.pem 
-----BEGIN CERTIFICATE-----
MIIFhTCCBG2gAwIBAgIQBjJIXC1E336tqWHS9/RraTANBgkqhkiG9w0BAQsFADBu
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
RFYgVExTIENBIC0gRzEwHhcNMjAwNDIwMDAwMDAwWhcNMjEwNDIwMTIwMDAwWjAZ
MRcwFQYDVQQDEw54dGVzdC5hczRrLnRvcDCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALTKEHWyw3IJkTWHAn/KX2fw6e96CQnQJiLApHYMRkqqoEa8WuSV
LAfq+ZGLVd6gifn5fiyOwOce7SM4jX/Dd6sY6e9IiJzM6AOUb0XWh2SfvSYhR5m4
XECSxa03DWFhvaJCBCiz0ws/HCCQzPTrjBrkyTLKlUJAQBAB2cBqqJKCwcs3o0sy
gL/2xGDwuNP+NOv6WGYdwktU8nVKN1VfJPtD1SkUeWqt344IeGr9+tPPm/MikpNL
2qmXxRNhJtceAOgJ/KjEzpm+RI2fcmyyJM11BSVKZUTVuDIOhMznTJEYFrfutAP6
NeOe+s2nPJK5bUo/WJu9X9GbE0r88+oZiUUCAwEAAaOCAnIwggJuMB8GA1UdIwQY
MBaAFFV0T7JyT/VgulDR1+ZRXJoBhxrXMB0GA1UdDgQWBBTu3hRsKYbzkwrtUf06
XrIWqCwyrTAZBgNVHREEEjAQgg54dGVzdC5hczRrLnRvcDAOBgNVHQ8BAf8EBAMC
BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEwGA1UdIARFMEMwNwYJ
YIZIAYb9bAECMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv
bS9DUFMwCAYGZ4EMAQIBMIGABggrBgEFBQcBAQR0MHIwJAYIKwYBBQUHMAGGGGh0
dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBKBggrBgEFBQcwAoY+aHR0cDovL2NhY2Vy
dHMuZGlnaWNlcnQuY29tL0VuY3J5cHRpb25FdmVyeXdoZXJlRFZUTFNDQS1HMS5j
cnQwCQYDVR0TBAIwADCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB3APZclC/RdzAi
FFQYCDCUVo7jTRMZM7/fDC8gC8xO8WTjAAABcZdaoi4AAAQDAEgwRgIhANGb6zSX
GYArav89ONLNNDfHgp7oJ8RRR5FE19ZYahBiAiEAwjJ0lkziXx3qBRNsFQyMGaiO
2RnXPd8DZpSm1NQlwZUAdQBc3EOS/uarRUSxXprUVuYQN/vV+kfcoXOUsl7m9scO
ygAAAXGXWqJdAAAEAwBGMEQCIFCiG38FtnN7/3Yty+6h58tyzly6R9y4aVCkN3LF
Lad6AiADInzu+U1wT1d5dYD/a+jIvOZIbzEfETh6YlFtmEDuejANBgkqhkiG9w0B
AQsFAAOCAQEAL2w8S/QWh1CxjkatZ3iR4qbSngTB2EIU8YffW10h+PYwKfWBsA2L
UQ57Nu1jpQ371T8q8ZW9w4R2d6A86Kysqk5or2/ZNrWsbaUr7+ilc8B8yx4DgQ75
29Ijr2RwJvVblmPtuJ7yicT/2gZKteeM/wnqeCVOHugW1wOL+qUZ6OuM6GnsxBD5
rypFV6ZBJWo8HXCOLuXnFBgrDPpDddN3Qd8X/o8d1plc4dTns/fCJol2X4GReQWC
u0XXNqZq/7DvTmk41ATgNCwfXxzhkTbJq/w+UdvLEm5yzST2sVxmsBj+Y2xRqpHY
Q7bRm1QRks2q5xBN8lTWFfwIRVno79T8Xw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIQAnmsRYvBskWr+YBTzSybsTANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xNzExMjcxMjQ2MTBaFw0yNzExMjcxMjQ2MTBaMG4xCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPeP6wkab41dyQh6mKc
oHqt3jRIxW5MDvf9QyiOR7VfFwK656es0UFiIb74N9pRntzF1UgYzDGu3ppZVMdo
lbxhm6dWS9OK/lFehKNT0OYI9aqk6F+U7cA6jxSC+iDBPXwdF4rs3KRyp3aQn6pj
pp1yr7IB6Y4zv72Ee/PlZ/6rK6InC6WpK0nPVOYR7n9iDuPe1E4IxUMBH/T33+3h
yuH3dvfgiWUOUkjdpMbyxX+XNle5uEIiyBsi4IvbcTCh8ruifCIi5mDXkZrnMT8n
wfYCV6v6kDdXkbgGRLKsR4pucbJtbKqIkUGxuZI2t7pfewKRc5nWecvDBZf3+p1M
pA8CAwEAAaOCAU8wggFLMB0GA1UdDgQWBBRVdE+yck/1YLpQ0dfmUVyaAYca1zAf
BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYw
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAK3Gp6/aGq7aBZsxf/oQ+TD/B
SwW3AU4ETK+GQf2kFzYZkby5SFrHdPomunx2HBzViUchGoofGgg7gHW0W3MlQAXW
M0r5LUvStcr82QDWYNPaUy4taCQmyaJ+VB+6wxHstSigOlSNF2a6vg4rgexixeiV
4YSB03Yqp2t3TeZHM9ESfkus74nQyW7pRGezj+TC44xCagCQQOzzNmzEAP2SnCrJ
sNE2DpRVMnL8J6xBRdjmOsC3N6cQuKuRXbzByVBjCqAA8t1L0I+9wXJerLPyErjy
rMKWaBFLmfK/AHNF4ZihwPGOc7w6UHczBZXH5RFzJNnww+WnKuTPI0HfnVH8lg==
-----END CERTIFICATE-----


更换证书内容需要重启下nginx

nexus 配置 nginx 离线YUM仓库

cat << 'EOF' > /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
#baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
baseurl=http://192.168.1.112:8081/repository/nginx/$releasever/$basearch/
gpgcheck=0
enabled=1
EOF

yum clean all
yum list nginx --showduplicates
yum install nginx-1.16.1

参考资料

Alphabetical index of directives
http://nginx.org/en/docs/dirindex.html

Alphabetical index of variables
http://nginx.org/en/docs/varindex.html