nginx的记录(5)

背景:同事问我一个问题,nginx怎么代理websocket。

前面几天比较忙,今天总算能抽点时间出来折腾一下。

配置 Nginx 反向代理 WebSocket: https://www.hi-linux.com/posts/42176.html

上面的文章其实比较细了,我来给它精简一下。

本地起一个socket并测试

// app.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8010 });
wss.on('connection', (ws) => {
  ws.on('message', (message) => {
    console.log(`Received from client: %s', ${message}`);
    ws.send(`Server received from client: ${message}`);
  });
});
coffeescript

测试socket,可以使用wscat这个npm包。

未分类

nginx代理

这里假设对/sockjs-node的path进行URL代理。

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

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

    location /sockjs-node {
        proxy_pass http://127.0.0.1:8010;
        proxy_read_timeout 300s;

        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;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

    }
}

正如网上说的,和普通的HTTP反向代理不同的点就是多加了:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

未分类

仅仅配置这个就OK了么?不!会报错的。。

未分类

解决方法是:加一个map,与server平级

http {
    ...
    gzip  on;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    server {
         ....
    }
}

OK,那我们来测试一下吧!

未分类

搞定了~~~

nginx配置文件-安全配置-静止ip访问服务器

1、listen 指令后面有一个参数default_server ,这个参数是在 0.8.21 版本以后才有的,而之前是default 指令。Nginx 的虚拟主机是通过HTTP请求中的Host值来找到对应的虚拟主机配置,如果找不到呢?那 Nginx 就会将请求送到指定了 default_server 的 节点来处理,如果没有指定为 default_server 的话,就跑到 localhost 的节点,如果没有 localhost 的节点,那只好 404 了。

2、server_name _; 这里指定的不是什么特别的名字,它只是一个无效的域名。从来不会匹配任何真实名字相匹配。

一、80端口访问时:

这里介绍修改配置文件nginx.conf两种方法:
1)在server段里插入如下正则:
listen       80;
server_name  www.yuyangblog.net;
if ($host != 'www.yuyangblog.net'){
   return 403;
}


2)添加一个server
新加的server(注意是新增,并不是在原有的server基础上修改)
server {
  listen 80 default;
  server_name _;
  return 403;
}

二、443端口访问时:

必须要提供 ssl证书,才能 正确执行 ip 屏蔽 操作。

server
{
    listen 443 ssl default_server;
    ssl_certificate      path_to_your_fullchain.cer;
    ssl_certificate_key  paht_to_your_key;
    return 301 https://demo.com;
    #other return way
    #return  400;  # ban ip access to https server ,return 444, 404 is also OK

}

Centos7 安装 Nginx

简介

Nginx(发音同engine x)是一个异步框架的Web服务器,也可以用作反向代理,负载平衡器和 HTTP缓存。该软件由Igor Sysoev创建,并于2004年首次公开发布。同名公司成立于2011年,以提供支持。

编译安装法

1.安装gcc gcc是用来编译下载下来的nginx源码

yum install gcc-c++

2.安装pcre和pcre-devel

PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。
nginx 的 http 模块使用 pcre 来解析正则表达式,pcre-devel 是使用 pcre 开发的一个二次开发库。

yum install -y pcre pcre-devel

3.安装zlib zlib提供了很多压缩和解方式,nginx需要zlib对http进行gzip。

yum install -y zlib zlib-devel

4.安装openssl openssl是一个安全套接字层密码库,nginx要支持https,需要使用openssl。

yum install -y openssl openssl-devel

5.下载nginx

wget http://nginx.org/download/nginx-1.9.9.tar.gz

6.解压

tar -zxvf nginx-1.9.9.tar.gz

7.cd到文件路径

8.编译

./configure --prefix=/usr --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/tem/nginx/client --http-proxy-temp-path=/var/tem/nginx/proxy --http-fastcgi-temp-path=/var/tem/nginx/fcgi --with-http_stub_status_module

9.安装

make && make install

10.启动

nginx -c /etc/nginx/nginx.conf

11.如果出现[emerg] getpwnam("nginx") failed错误 执行

useradd -s /sbin/nologin -M nginx
id nginx

12.如果出现[emerg] mkdir() "/var/temp/nginx/client" failed (2: No such file or directory)错误 执行

sudo mkdir -p /var/tem/nginx/client

13.如果您正在运行防火墙,请运行以下命令以允许HTTP和HTTPS通信:

sudo firewall-cmd --permanent --zone=public --add-service=http 
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload

yum安装法

1.添加Nginx存储库

要添加CentOS 7 EPEL仓库,请打开终端并使用以下命令:

sudo yum install epel-release

2.安装Nginx

现在Nginx存储库已经安装在您的服务器上,使用以下yum命令安装Nginx :

sudo yum install nginx

在对提示回答yes后,Nginx将在服务器上完成安装。

3.启动Nginx

Nginx不会自行启动。要运行Nginx,请输入:

sudo systemctl start nginx

如果您正在运行防火墙,请运行以下命令以允许HTTP和HTTPS通信:

sudo firewall-cmd --permanent --zone=public --add-service=http 
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload

如果想在系统启动时启用Nginx。请输入以下命令:

sudo systemctl enable nginx

nginx windows安装、使用和开机启动配置

1、nginx windows安装、使用

1.1 下载,解压 nginx

下载地址: http://nginx.org/en/download.html
我下载的是 nginx-1.15.4

D:develop_toolsnginx 目录下将 nginx-1.15.4.zip解压到完整路径 D:develop_toolsnginxnginx-1.15.4, 如图所示:

未分类

1.2、启动nginx

启动nginx有两种方式:

  • 双击启动
  • cmd命令启动

1.2.1 双击启动

直接双击nginx.exe,双击后一个黑色的弹窗一闪而过。

1.2.2 cmd命令启动

用 管理员权限 打开cmd,切换到nginx解压目录下,输入命令 start nginx.exe 或者 nginx.exe ,回车后会出现一个黑色的弹窗一闪而过。

C:UsersAdministrator>cd D:develop_toolsnginxnginx-1.15.4
C:UsersAdministrator>d:
D:develop_toolsnginxnginx-1.15.4>start nginx.exe

1.3 验证

访问 http://localhost/

未分类

注:截图中的1.54是我修改index.html添加的,默认是没有。

2、开机启动配置

2.1 下载 WinSW

下载地址: https://github.com/kohsuke/winsw/releases

我选择的是 winsw-v2.1.2 , 它有两个版本:

  • WinSW.NET2.exe

  • WinSW.NET4.exe (我下载的版本)

2.2 配置步骤

2.2.1 与1.1的操作相同。

2.2.2 将 WinSW.NET4.exe 复制到 D:develop_toolsnginxnginx-1.15.4 目录中,并将名字修改为 nginxservice.exe

2.2.3 新建一个空的 nginxservice.xml 文件(名字要与nginxservice.exe 名字保持一致) ,其内容:

<service>
    <id>nginx</id>
    <name>nginx</name>
    <description>nginx</description>
    <logpath>D:develop_toolsnginxnginx-1.15.4</logpath>
    <logmode>roll</logmode>
    <depend></depend>
    <executable>D:develop_toolsnginxnginx-1.15.4nginx.exe</executable>
    <stopexecutable>D:develop_toolsnginxnginx-1.15.4nginx.exe -s stop</stopexecutable>
</service>

这里有3处必须修改: <logpath><executable><stopexecutable>
这3处是 nginx.exe 的所在目录。

示例中为nginx所有目录是 D:develop_toolsnginxnginx-1.15.4 的配置。

2.2.4 用管理员权限打开cmd,进入D:develop_toolsnginxnginx-1.15.4目录下,执行nginxservice.exe install 命令。

D:develop_toolsnginxnginx-1.15.4>nginxservice.exe install
2018-11-29 10:50:30,231 INFO  - Installing the service with id 'nginx'

未分类

2.2.5 在计算机管理–>服务中,找到 nginx 服务,右键启动服务。

未分类

2.3 验证

3、nginx常用的基本命令

start nginx.exe       ## 启动服务
nginx.exe -s stop     ## 快速停止服务
nginx.exe -s quit     ## 优雅的 停止服务

nginx.exe -s reload   ## 重新加载 配置文件,这命令可以不用停止nginx
nginx.exe -s reopen   ## 重新打开日志文件

最简单的dockerfile使用教程 – 创建一个支持SSL的Nginx镜像

什么是dockerfile?简单的说就是一个文本格式的脚本文件,其内包含了一条条的指令(Instruction),每一条指令负责描述镜像的当前层(Layer)如何构建。

下面通过一个具体的例子来学习dockerfile的写法。

新建一个dbuild文件夹,创建一个自定义的Nginx首页,逻辑很简单,显示一个自定义的图片文件train.jpg.

未分类

我想基于标准的Nginx镜像做一些修改,让Nginx支持SSL。SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。

为此我首先需要创建一个针对SSL的配置文件。

未分类

cat << '__EOF' > ssl.conf
server {
listen       443 ssl;
server_name  localhost;

ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

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

使用如下命令创建nginx.key和nginx.crt文件:

openssl req -x509 -nodes -newkey rsa:4096 -keyout nginx.key -out nginx.crt -days 365 -subj "/CN=$(hostname)"

未分类

一切就绪之后,下面就应该创建dockerfile了:

未分类

FROM nginx:stable

# copy the custom website into the image
COPY train.jpg /usr/share/nginx/html/
COPY index.html /usr/share/nginx/html/

# copy the SSL configuration file into the image
COPY ssl.conf /etc/nginx/conf.d/ssl.conf

# download the SSL key and certificate into the image
COPY nginx.key /etc/nginx/ssl/nginx.key
COPY nginx.crt /etc/nginx/ssl/nginx.crt

# expose the https port
EXPOSE 443

所有dockerfile第一行指令必定是FROM XXXX。

FROM的作用是指定基准镜像。该dockerfile以FROM后面指定的镜像为基础,在其上进行定制。

在 Docker Store 上有很多高质量的官方镜像,主要分为以下三大类:

  1. 开箱即用的服务类的镜像,比如网络服务器nginx ,也有数据库服务器诸如redis 、 mongo 、mysql 等;
  2. 方便开发、构建、运行各种语言应用的镜像,如 node 、 openjdk 、 python 等。
  3. 相对前两大类更为基础的操作系统镜像,如ubuntu 、 debian 、 centos 等

当然您如果不愿意基于这些官方已有镜像开始镜像构建,而是想从头开始,这也是可以的。Docker存在一个特殊的镜像,名为 scratch 。它是一个虚拟的概念,

表示一个空白的镜像。

直接使用FROM scratch 会让镜像体积更加小巧。

接下来的一系列copy指令都很好理解。

dockerfile开发完毕之后,执行命令:

docker build -t jerry-nginx:1.0 .

意思是基于当前目录开始构建镜像,注意末尾的.必不可少,代表“当前目录”。

通过docker build执行输出的日志可以观察到里面每一行的指令被逐行执行:

未分类

最后一行日志提示标签为jerry-nginx:1.0的景象被成功构建。

用下面的命令基于刚刚制作好的镜像运行一个容器:

docker run -d -p 443:443 -p 1082:80 jerry-nginx:1.0

基于http协议访问没有问题:

http://localhost:1082

未分类

基于https访问也能正常工作:

https://localhost:443

未分类

Nginx配置文件-3

设置黑白名单:

语法:
allow
deny

作用位置:
http, server, location, limit_except

具体实现:
server {
    server_name www.a.com;
    listen 80;
    root /web/a.com;
    index index.html;
    server_tokens off;

    location /test {
        root /www/html;
        deny 172.20.23.23;
        allow 172.20.23.33;
        deny all;
    }

    location /test1 {
        alias /mydata/html;
    }

}

测试访问:
[root@www21:17:48~]#curl http://www.a.com/test/ 
<h1>test location page for nginx</h1>

更改配置:
allow 172.20.23.33; --->换成deny
测试:
[root@www21:21:16~]#curl http://www.a.com/test/ 
<html>
<head><title>403 Forbidden</title></head>

基于用户的认证:

关键语法:
auth_basic "提醒语句"
官网说明:
Syntax: auth_basic string | off;
Default:    
auth_basic off;
Context:http, server, location, limit_except

auth_basic_user_file
官网说明:
Syntax: auth_basic_user_file file;
Default:    —
Context:http, server, location, limit_except

具体使用:
server {
        location /test1 {
        alias /mydata/html;
        auth_basic "test nginx";
        auth_basic_user_file /etc/nginx/conf.d/.npasswd;
    }
}

设置用户密码:
[root@www21:28:47conf.d]#htpasswd -c -m /etc/nginx/conf.d/.npasswd tom
New password: 
Re-type new password: 
Adding password for user tom

测试:
[root@www21:32:56~]#curl -u tom:123456 http://www.a.com/test1/
<h1>test alias for nginx</h1>

查看状态信息:

stub_status  on|off

具体使用:
server {
    location /status {
        stub_status on;
        allow 172.20.23.33;
        deny all;
     }

}

具体信息解析:
Active connections:当前状态,活动状态的连接数 
accepts:统计总值,已经接受的客户端请求的总数 
handled:统计总值,已经处理完成的客户端请求的总数 
requests:统计总值,客户端发来的总的请求数 
Reading:当前状态,正在读取客户端请求报文首部的连接的连接数 
Writing:当前状态,正在向客户端发送响应报文过程中的连接数 
Waiting:当前状态,正在等待客户端发出请求的空闲连接数

设置访问日志格式:

设置格式:
log_format [log_name] '$1 $2 $3';
设置在http段中
引用日志格式:
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

具体使用:
自定义日志格式:
log_format test '$remote_addr:$remote_port $request_method $remote_user $status $http_user_agent $bytes_sent $gzip_ratio';  
使用自定义格式:
server {
    server {
    server_name www.a.com;
    listen 80;
    root /web/a.com;
    index index.html;
    server_tokens off;
    access_log /web/a.com/a.com.log test;
}

http核心模块的内置变量:
 $uri:当前请求的uri,不带参数
 $host:http请求报文中host首部,如果请求中没有host首部,则以处理此请求的虚拟主机名
  代替!
 $request_uri:请求的uri,带完整参数
 $hostname:nginx服务运行在的主机的主机名
 $remote_addr:客户端ip
 $remote_port:客户端端口
 $remote_user:使用用户认证时客户端用户输入的用户名
 $request_filename:用户请求中的RUI经过本地root或alias转换后映射的本地的文件或路径
 $request_method:请求方法
 $server_addr:服务器地址
 $server_name:服务器名称
 $server_port:服务器端口
 $server_protocol:服务器向客户端发送响应时的协议 如http/1.1
 $scheme:在请求中使用的scheme,如https http,哪个协议
 $http_HEADER:匹配请求报文中指定的HEADER  $http_host匹配请求报文中的host首部
 $sent_http_HEADER:匹配响应报文中指定的HEADER---要小写
  例子:$http_content_type匹配响应报文中的content-type首部
 $document_root:当前请求映射到的root配置项
日志格式变量: 
 $status:用来引用状态码
 $bytes_sent:发送的字节数
 $http_referer:从哪个页面跳转过来的
 $http_user_agent:浏览器的类型
 $gzip_ratio:压缩比例,配合压缩功能

设置日志缓存:

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];  

open_log_file_cache off;  
缓存各日志文件相关的元数据信息   
max:缓存的最大文件描述符数量  
min_uses:在inactive指定的时长内访问大于等于此值方可被当作活动项  
inactive:非活动时长  
valid:验证缓存中各缓存项是否为活动项的时间间隔 

压缩功能:

关键设置:
gzip on|off
官网说明:
Syntax: gzip on | off;
Default:    
gzip off;
Context:http, server, location, if in location
基本设置项:
gzip_buffers [n]:压缩时缓冲大小
gzip_comp_level[0--9]:压缩等级
gzip_distable [对哪种浏览器,文件不压缩]msie6
gzip_min_length [值]:内容大于这个值才会压缩
gzip_http_version:压缩后构建响应报文,使用那个版本 1.0/1.1
gzip_types:只对那些类型的网页文件做压缩默认包含有text/html
gzip_buffers number size; 支持实现压缩功能时缓冲区数量及每个缓存区的大小  
默认:32 4k 或 16 8k
gzip_vary on | off;如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding

具体使用:
server {
        location /test3/ {
        gzip on;
        gzip_comp_level 6;
        gzip_min_length 100;
        gzip_types text/xml text/css text/plain application/javascript;
    }
}

测试:
172.20.23.33:44018 GET - 200 curl/7.29.0  200 436946 "-" -->压缩前
172.20.23.33:44020 GET - 200 curl/7.29.0  200 3252 "134.86"-->压缩后

掌握nginx的location优先级

  • 前言

近几年nginx在企业上的应用很广泛,但很多朋友还是不知道nginx的location优先级,如果不能清晰的掌握nginx的location优先级,就会在配置nginx的时候引起错误的跳转,错误的跳转往往就是一次严重的线上事故。因此,掌握nginx的location优先级非常重要。

  • 先来一个最简单的nginx配置
worker_processes  1;
events {
worker_connections  1024;
}
http {
include       mime.types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;

server {
    listen 80;
    location / {
        return 400;
    }
}
}

location /是通配的,也就是所以请求都能匹配,但它的优先级我们暂时还不知道。请求结果如下:

未分类

  • 多个通配的优先级测试,加入location /test
            location / {
                    return 400;
            }
            location /test {
                    return 401;
            }

加入location /test,我们故意把位置放到location /以下,来验证优先级。请求结果如下,返回401,从结果可以看出来/test的优先级高于location /。不过用户的访问要以/test开头,不是以/test开头还是命中到location /:

未分类

  • location正则的优先级测试,我们加入~ ^/test,使用正则匹配以test开头的
            location / {
                    return 400;
            }
            location /test {
                    return 401;
            }
            location ~ ^/test {
                    return 402;
            }

加入location ~ ^/test,我们故意再把它放到最后,来验证优先级。请求结果如下,返回402,从结果可以看出来正则的优先级要大于location /和location /test,也就是正则location大于通配location

未分类

  • 多个正则的优先级测试,我们使用两个正则,主要是来验证下,是不是正则配置得越多,优先级就越高。如下的配置
           location ~ ^/test {
                    return 402;
            }

            location ~ ^/test/aaa {
                    return 403;
            }

加入^/test/aaa,我们一样把它放到最后,请求/test/aaa。结果返回402,也就是匹配到第一个正则后,底下的正则不会再去匹配。由于请求/test/aaa,命中^/test,所以底下的正则就无效了:

未分类

  • 我们加入精准匹配,也就是nginx的=,我们来测试下精准匹配的优先级
            location ~ ^/test/aaa {
                    return 403;
            }

            location = /test/aaa {
                    return 404;
            }

我们故意把= /tmp/aaa放到最后,这个只能匹配到/test/aaa的请求,得到的结果如下,返回404。这个说明了,精准匹配=的优先级是最高的,不管它放到哪里。

未分类

  • 问题1:为什么我的nginx设置了全局跳转,但怎么不生效?
            location / {
                    rewrite xxx xxxx;
            }

            location ~* ^/test {
                    return 402;
            }

如果是以上的跳转配置的话,大家根据优先级来,可以发现location /的优先级是最低的,所以全局跳转不生效。因为当用户访问到/test/xx的时候,命中到其它location了。所以全局跳转的话,保留一个location /即可。

  • 问题2:为什么我的nginx动静分离配置失败了?
            location ~ ^/test {
                    root xxxx;
            }

            location ~ .jsp$ {
                    proxy_pass xxxx;
            }

如果是以上配置的话,当用户访问到/test/xxx.jsp的时候,就命令到location ~ ^/test了。所以动静分离如果都使用正则的话,需要注意location的放置位置。

解决Nginx出现403 forbidden (13: Permission denied)报错的四种方法

我是在在本地用虚拟机中通过yum安装nginx的,安装一切正常,但是访问时报403,

于是查看nginx日志,路径为/var/log/nginx/error.log。打开日志发现报错Permission denied,详细报错如下:

2018/11/28 11:39:40 [error] 41772#41772: *130 "/home/hc/dists/autoAweme/dist/index.html" is forbidden (13: Permission denied), client: 192.168.3.139, server: 192.168.3.139, request: "GET / HTTP/1.1", host: "192.168.3.139"

一:由于启动用户和nginx工作用户不一致所致

1. 查看nginx的启动用户

命令:

ps aux | grep "nginx: worker process" | awk  '{print $1}'
[root@localhost hc]# ps aux | grep "nginx: worker process" | awk  '{print $1}'
nginx
root

发现是nginx,而不是用root启动的

2. 将nginx.conf的user改为和启动用户一致

将nginx.conf文件中的 user 对应的nginx 改为 root ,改完后重启

[root@localhost hc]# vim /etc/nginx/nginx.conf
[root@localhost hc]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@localhost hc]# nginx -s reload

二、缺少index.html或者index.php文件,就是配置文件中index index.html index.htm这行中的指定的文件

server {
listen 80;
server_name localhost;
index index.php index.html;
root / var/www;
}

如果在/ var/www下面没有index.php,index.html的时候,直接访问域名,找不到文件,会报403 forbidden。

三、权限问题,如果nginx没有web目录的操作权限,也会出现403错误

解决办法:修改web目录的读写权限,或者是把nginx的启动用户改成目录的所属用户,重启Nginx即可解决

chmod -R 755 / var/www

四、SELinux设置为开启状态(enabled)的原因

首先查看本机SELinux的开启状态,如果SELinux status参数为enabled即为开启状态

/usr/sbin/ sestatus -v

或者使用getenforce命令检查

如何关闭 SELinux 呢

1. 临时关闭(不用重启)

setenforce  0

2. 永久关闭(需要重启)

修改配置文件 /etc/selinux/config,将SELINUX=enforcing改为SELINUX=disabled

vi /etc/selinux/config


#SELINUX=enforcing

SELINUX=disabled

重启生效。

reboot

nginx 详解 – 详细配置说明

一、服务器基础配置

远程链接服务器

ssh 用户名@公网ip

默认的用户名是root,假如公网 ip 是 a.b.c.d, 那链接命名就是

ssh [email protected]

下载安装基础库

yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install wget httpd-tools vim

关闭 iptables

查看iptables规则

iptables -L
或
iptables -t nat -L

关闭 iptables 规则

iptables -F
或
iptables -t nat -F

关闭 SELinux

查看是否打开

getenforce

关闭

setenforce 0

二、Nginx 简介及安装

Nginx 是一个开源且高性能、高可靠的 HTTP 中间件、代理服务。

安装Nginx

打开官网 https://nginx.org/en/linux_packages.html#stable

To set up the yum repository for RHEL/CentOS, create the file named /etc/yum.repos.d/nginx.repo with the following contents:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1

Replace “OS” with “rhel” or “centos”, depending on the distribution used, and “OSRELEASE” with “6” or “7”, for 6.x or 7.x versions, respectively.

三、安装目录及配置讲解

3.1 安装目录讲解

查看nginx的所有安装目录

rpm -ql nginx

然后得到如下配置

[root@ ~]# rpm -ql nginx

nginx日志轮转,用于logrotate服务的日志切割
/etc/logrotate.d/nginx

nginx主配置文件
/etc/nginx/nginx.conf
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf

cgi配置相关,fastcgi配置
/etc/nginx/fastcgi_params
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params

编码转换映射转化文件
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/win-utf

设置http协议的 Content-Type 与扩展名对应关系
/etc/nginx/mime.types


用于配置出系统守护进程管理器管理方式
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service

nginx模块目录
/etc/nginx/modules
/usr/lib64/nginx/modules


/usr/lib64/nginx

/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade

nginx服务的启动管理的终端命令
/usr/sbin/nginx
/usr/sbin/nginx-debug

nginx的手册和帮助文件
/usr/share/doc/nginx-1.14.0
/usr/share/doc/nginx-1.14.0/COPYRIGHT
/usr/share/man/man8/nginx.8.gz


/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html

nginx 的缓存目录
/var/cache/nginx

nginx日志目录
/var/log/nginx

3.2 安装编译参数

命令 nginx -V 查看所有编译参数

3.3 Nginx 默认配置语法

未分类

nginx 的默认配置文件

文件路径 /etc/nginx/conf.d/default.conf

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

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

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #

    #location ~ .php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ .php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /.ht {
    #    deny  all;
    #}
}

可以去 /usr/share/nginx/html/index.html 修改默认的展示页面,也可以去 /usr/share/nginx/html/50x.html 修改错误页面。

修改后重启 nginx

systemctl reload nginx.service
或
systemctl restart nginx.service

检查 nginx 配置,结果出现 successful 表示成功

nginx -t -c /etc/nginx/nginx.conf

重新加载配置

nginx -s reload -c /etc/nginx/nginx.conf

四、常见 Nginx 中间架构

  1. 静态资源WEB服务
  2. 代理服务
  3. 负载均衡调度器 SLB
  4. 动态缓存

4.1 静态资源WEB服务

未分类

未分类

配置语法-文件读取

Syntax: sendfile on|off;
Default: sendfile off;
Context: http,server,location,if in location

引读:--with-file-aio 异步文件读取

配置语法- tcp_nopush

Syntax: tcp_nopush on|off;
Default: tcp_nopush off;
Context: http,server,location

配置语法- tcp_nodelay

Syntax: tcp_nodelay on|off;
Default: tcp_nodelay on;
Context: http,server,location

配置语法- 压缩

Syntax: gzip_comp_level level;
Default: gzip_comp_level 1;
Context: http,server,location
Syntax: gzip_http_version 1.0|1.1;
Default: gzip_http_version 1.1;
Context: http,server,location

扩展 Nginx 压缩模块

预读 gzip 功能
http_gzip_static_module

应用支持 gunzip 的压缩方式
http_gunzip_module

浏览器缓存设置

配置语法 – expires

添加 Cache-Control、Expires 头

Syntax:expires [modified] time;
        expires epoch | max | off
Default: expires off;
Context: http, server, location, if in location

跨域

*表示允许所有的网站跨域,为了安全起见可以设置仅需要的网址

location ~ .*.(htm|html)$ {
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
    root /opt/app/code
}

基于 http_refer 防盗链配置模块

Syntax: valid_referers none | blocked | server_names | string...;
Default: -
Context: server, location,

4.2 代理服务

正向代理与反向代理的区别在于代理的对象不一样

  • 正向代理代理的对象是客户端
  • 反向代理代理的对象是服务端

配置语法

Syntax: proxy_pass URL
Default: -
Context: location,if in location,limit_except

URL 一般是以下三种

http://localhost:8080/uri/
https://192.168.1.1:8000/uri/
http://unix:/tmp/backend.socket:/uri/;

4.3 负载均衡

HttpIndex模块

这个模块提供一个简单方法来实现在轮询和客户端IP之间的后端服务器负荷平衡。

配置范例:

resolver 10.0.0.1;

upstream dynamic {
    zone upstream_dynamic 64k;

    hash $request_uri;  #按照url的hash值来分配,同一个url分配到同一个服务器

    server backend1.example.com      weight=5;
    server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
    server 192.0.2.1                 max_fails=3;
    server backend3.example.com      resolve;
    server backend4.example.com      service=http resolve;

    server backup1.example.com:8080  backup;
    server backup2.example.com:8080  backup;
}

server {
    location / {
        proxy_pass http://dynamic;
        health_check;
    }
}

状态解释

未分类

调度算法

未分类

4.4 缓存

缓存类型分类:客户端缓存,代理缓存,服务端缓存

proxy_cache

Syntax: proxy_cache zone | off;
Default:    
proxy_cache off;
Context:    http, server, location

proxy_cache_path

Syntax: proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default:    —
Context:    http

实例

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=cache_zone:10m max_size=10g inactive=60m use_temp_path=off;

map $request_method $purge_method {
    PURGE   1;
    default 0;
}

server {
    ...
    location / {
        proxy_pass http://backend;
        proxy_cache cache_zone;
        proxy_cache_key $uri;
        proxy_cache_purge $purge_method;
        # 当分配的服务器出现50X 错误时分配另一台服务器
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504
    }
}

五、Nginx深度学习

5.1 动静分离

upstream java_api{
    server 127.0.0.1:8080;
}
server {
    ...
    #匹配到jsp结尾的请求去请求服务器
    location ~ .jsp$ {
        proxy_pass http://java_api;
        index index.html index.htm;
    }

    #匹配到图片资源返回本地的内容
    location ~ .(jpg|png|gif)$ {
        expires 1h;
        gzip on;
    }
}

5.2 Nginx 的 rewrite规则

作用:实现 url 重写以及重定向

使用场景:

  • URL 访问跳转,支持开发设计
    • 页面跳转、兼容性支持、展示效果等
  • SEO优化
  • 维护。后台维护、流量转发等
  • 安全

语法

Syntax: rewrite regex replacement [flag];
Default:    —
Context:    server, location, if

If the specified regular expression matches a request URI, URI is changed as specified in the replacement string. The rewrite directives are executed sequentially in order of their appearance in the configuration file. It is possible to terminate further processing of the directives using flags. If a replacement string starts with “http://”, “https://”, or “$scheme”, the processing stops and the redirect is returned to a client.
An optional flag parameter can be one of:

  • last

停止rewrite检测

stops processing the current set of ngx_http_rewrite_module directives and starts a search for a new location matching the changed URI;

  • break

停止rewrite检测

stops processing the current set of ngx_http_rewrite_module directives as with the break directive;

  • redirect

返回302临时重定向,地址栏会显示跳转后的地址

returns a temporary redirect with the 302 code; used if a replacement string does not start with “http://”, “https://”, or “$scheme”;

  • permanent

返回302永久重定向,地址栏会显示跳转后的地址

returns a permanent redirect with the 301 code.

The full redirect URL is formed according to the request scheme ($scheme) and theserver_name_in_redirect and port_in_redirect directives.

Example:

server {
    ...
    rewrite ^(/download/.*)/media/(.*)..*$ $1/mp3/$2.mp3 last;
    rewrite ^(/download/.*)/audio/(.*)..*$ $1/mp3/$2.ra  last;
    return  403;
    ...
}

But if these directives are put inside the “/download/” location, the last flag should be replaced bybreak, or otherwise nginx will make 10 cycles and return the 500 error:

location /download/ {
    rewrite ^(/download/.*)/media/(.*)..*$ $1/mp3/$2.mp3 break;
    rewrite ^(/download/.*)/audio/(.*)..*$ $1/mp3/$2.ra  break;
    return  403;
}

If a replacement string includes the new request arguments, the previous request arguments are appended after them. If this is undesired, putting a question mark at the end of a replacement string avoids having them appended, for example:

rewrite ^/users/(.*)$ /show?user=$1? last;

If a regular expression includes the “}” or “;” characters, the whole expressions should be enclosed in single or double quotes.

5.3 安全校验 secure_link

指定并允许检查请求的链接的真实性以及保护资源免遭未授权的访问

限制链接生效周期

Syntax: secure_link expression;
Default:    —
Context:    http, server, location

Syntax: secure_link_md5 expression;
Default:    —
Context:    http, server, location

Example:

location /s/ {
    secure_link $arg_md5,$arg_expires;
    secure_link_md5 "$secure_link_expires$uri$remote_addr secret";

    if ($secure_link = "") {
        return 403;
    }

    if ($secure_link = "0") {
        return 410;
    }

    ...
}

5.4 geoip_module 模块

基于 IP 地址匹配 MaxMind GeoIP 二进制文件,读取 IP 所在地域信息

安装: yum install nginx-module-geoip

使用场景

  • 区别国内外做HTTP 访问规则
  • 区别国内城市地域做 HTTP 访问规则

5.5 配置 HTTPS

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

HTTPS 服务优化

  • 激活 keepalive 长连接
  • 设置 ssl session 缓存
server{
    listen       443;
    server_name  116.62.103.228 jeson.t.imooc.io;
    keepalive_timeout  100;

    ssl on;
    ssl_session_cache  shared:SSL:10m;
    ssl_session_timeout  10m;

    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;

    index index.html index.htm;
    location / {
        root /opt/app/code;
    }
}

5.6 Nginx 与 Lua 开发

Lua 是一个简洁、轻量、可扩展的脚本语言

Nginx + Lua 优势:充分的结合 Nginx 的并发处理 epoll 优势和 Lua 的轻量实现简单的功能且高并发的场景。

安装

yum install lua

运行 lua 有两种方式:命令行和脚本

  • 命令行模式
在命令行输入 lua 开启命令行交互模式
  • 脚本模式

编写 test.lua 文件,执行 lua test.lua 运行

注释

-- 行注释
--[[
    块注释
--]]

六、Nginx 常见问题

多个 server_name 的优先级

如果多个文件配置有相同的 server_name ,根据文件名先读取到哪个文件就加载哪个文件的配置

location 匹配优先级

=  进行普通字符精确匹配,也就是完全匹配
^~ 表示普通字符匹配,使用前缀匹配
~ ~*  表示执行一个正则匹配()

前两种匹配到之后就不往下继续匹配了,最后一种会继续往下匹配,如果没有匹配到,就用它的匹配。也就是前两种优先级比第三种高。

try_files 的使用

按顺序检查文件是否存在

location / {
    try_files $uri $uri/ /index.php;
}

七、Nginx 性能优化

7.1 文件句柄

文件句柄:linuxUnix 一切皆文件,文件句柄就是一个索引

设置方式:系统全局性修改,用户局部性修改,进程局部性修改

修改方法:

系统全局修改和针对用户修改

vim /etc/security/limits.conf

加入以下代码

# 给root用户设置
root soft nofile 10000
root hard nofile 10000
# 给所有用户全局设置
*    soft nofile 10000
*    hard nofile 10000

soft 不是强制性的,超过设置的值会提醒但不强制执行;hard 会强制执行

针对进程修改

vim /etc/nginx/nginx.conf

添加以下代码

worker_rlimit_nofile 20000

7.2 CPU 亲和

查看当前服务器的 CPU 个数

cat /proc/cpuinfo | grep "physical id"|sort|uniq|wc -l

查看 CPU 核数

cat /proc/cpuinfo | grep "cpu cores"|uniq

worker_processes = CPU 个数 * CPU 核数

假如有 2 个 CPU,每个 CPU 有 8 核,那 worker_processes 应该是16

打开 nginx 配置文件 vim /etc/nginx/nginx.conf

worker_processes  16;
worker_cpu_affinity  auto;

然后刷新nginx配置 nginx -s reload -c /etc/nginx/nginx.conf

7.3 Nginx 的通用配置

user  nginx;
worker_processes  1;
worker_cpu_affinity auto;

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

worker_rlimit_nofile 10000;

events {
    use epoll;
    worker_connections  1024;
}

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

    charset utf-8;

    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;
    gzip_disable  "MSIE [1-6].";
    gzip_http_version 1.1;

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

八、基于 Nginx 架构的安全

8.1 常见的恶意行为及防范手段

常见恶意行为:爬虫行为和恶意抓取、资源盗用

常用防范手段:

基础防盗链功能:目的不让恶意用户轻易爬取网站数据

secure_link_module: 提高数据安全性,对数据增加加密验证和失效性,适合核心重要数据

access_module: 对后台、部分用户服务的数据提供 IP 防控

8.2 常见的攻击手段

后台密码撞库

通过猜测密码字段不断对后台系统登录性尝试,获取后台登录密码

防范手段:

  • 后台登录密码复杂度
  • access_module 对后台提供 IP 防控
  • 预警机制

文件上传漏洞

location ^~ /upload{
    root /opt/app/images;
    if($requst_filename ~*(.*).php){
        return 403;
    }
}

SQL 注入

利用未过滤/未审核用户输入的攻击方法,让应用运行本不应该运行的 SQL 代码

Nginx + Lua 防火墙实现:https://github.com/loveshell/ngx_lua_waf

以上就是 Nginx 学习笔记的全部内容。

Nginx性能优化功能- Gzip压缩(大幅度提高页面加载速度)

Nginx开启Gzip压缩功能, 可以使网站的css、js 、xml、html 文件在传输时进行压缩,提高访问速度, 进而优化Nginx性能! Web网站上的图片,视频等其它多媒体文件以及大文件,因为压缩效果不好,所以对于图片没有必要支压缩,如果想要优化,可以图片的生命周期设置长一点,让客户端来缓存。 开启Gzip功能后,Nginx服务器会根据配置的策略对发送的内容, 如css、js、xml、html等静态资源进行压缩, 使得这些内容大小减少,在用户接收到返回内容之前对其进行处理,以压缩后的数据展现给客户。这样不仅可以节约大量的出口带宽,提高传输效率,还能提升用户快的感知体验, 一举两得; 尽管会消耗一定的cpu资源,但是为了给用户更好的体验还是值得的。

经过Gzip压缩后页面大小可以变为原来的30%甚至更小,这样,用户浏览页面的时候速度会快得多。Gzip 的压缩页面需要浏览器和服务器双方都支持,实际上就是服务器端压缩,传到浏览器后浏览器解压并解析。浏览器那里不需要我们担心,因为目前的巨大多数浏览器 都支持解析Gzip过的页面。

Gzip压缩作用:将响应报⽂发送⾄客户端之前可以启⽤压缩功能,这能够有效地节约带宽,并提⾼响应⾄客户端的速度。Gzip压缩可以配置http,server和location模块下。Nginx开启Gzip压缩功能的配置如下:

#修改nginx配置文件 /usr/local/nginx/conf/nginx.conf
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf        #将以下配置放到nginx.conf的http{ ... }节点中

#修改配置为
gzip on;                    #开启gzip压缩功能
gzip_min_length 10k;         #设置允许压缩的页面最小字节数; 这里表示如果文件小于10个字节,就不用压缩,因为没有意义,本来就很小.
gzip_buffers 4 16k;         #设置压缩缓冲区大小,此处设置为4个16K内存作为压缩结果流缓存
gzip_http_version 1.1;      #压缩版本
gzip_comp_level 2;   #设置压缩比率,最小为1,处理速度快,传输速度慢;9为最大压缩比,处理速度慢,传输速度快; 这里表示压缩级别,可以是0到9中的任一个,级别越高,压缩就越小,节省了带宽资源,但同时也消耗CPU资源,所以一般折中为6
gzip types text/css text/xml application/javascript;      #制定压缩的类型,线上配置时尽可能配置多的压缩类型!
gzip_disable "MSIE [1-6].";       #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip vary on;    #选择支持vary header;改选项可以让前端的缓存服务器缓存经过gzip压缩的页面; 这个可以不写,表示在传送数据时,给客户端说明我使用了gzip压缩

线上使用的Gzip压缩配置

[root@external-lb02 ~]# cat /data/nginx/conf/nginx.conf
........
http {
.......
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
    gzip_disable "MSIE [1-6].";
    gzip_vary on;

}

如果不开启Gzip压缩功能(即注释掉Gzip的相关配置), 查看某个图片大小

[root@external-lb02 ~]#  ll  -h /data/web//www/test.bmp
-rw-r--r-- 1 root root 453K 3月  14 18:43 /data/web//www/test.bmp

如下可知, 文件没有被压缩,文件传输大小还是400多K

未分类

如果开启Nginx的Gzip压缩功能(即打开Gzip的相关配置), 然后再次访问test.bmp图片, 发现压缩后的该图片文件传输大小只有200多K !

未分类

通过上面测试对比, 发现Nginx开启Gzip压缩功能后, 定义的gzip type的文件在传输时的大小明显变小, 这样这会大大提高nginx访问性能.

直接用curl测试命令:

[root@fvtlb02 ~]# curl -I -H "Accept-Encoding: gzip, deflate" "http://fvtvfc-web.kevin.com/service-worker.js"
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Mon, 26 Nov 2018 02:19:16 GMT
Content-Type: application/javascript; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Sun, 25 Nov 2018 22:28:15 GMT
Vary: Accept-Encoding
ETag: W/"5bfb21ff-40be"
Content-Encoding: gzip

如上,response header头信息中出现"Conten_Encoding: gzip" , 就说明Nginx已开启了压缩 (在浏览器访问, 通过F12看请求的响应头部 也是一样)

Nginx的Gzip压缩功能虽然好用,但是下面两类文件资源不太建议启用此压缩功能。

1) 图片类型资源 (还有视频文件)

原因:图片如jpg、png文件本身就会有压缩,所以就算开启gzip后,压缩前和压缩后大小没有多大区别,所以开启了反而会白白的浪费资源。(可以试试将一张jpg图片压缩为zip,观察大小并没有多大的变化。虽然zip和gzip算法不一样,但是可以看出压缩图片的价值并不大)

2) 大文件资源

原因:会消耗大量的cpu资源,且不一定有明显的效果。