Title

linux安装nginx及常用命令

(一)在线安装 nginx

  • 安装必要的依赖
yum install -y gcc-c++pcre pcre-develzlib zlib-developenssl openssl-devel
  • 下载Nginx

下载命令

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

如果提示:

-bash: wget: 未找到命令

下载wget命令:

yum -y install wget

(二)本地下载nginx的linux压缩包

上传到linux服务器

判断linux上是否有nginx

[root@VM-4-6-centos /]# whereis nginx
[root@VM-4-6-centos /]# 
[root@VM-4-6-centos /]# nginx
-bash: nginx: command not found

解压 nginx-1.18.0.tar.gz 压缩包

[root@VM-4-6-centos home]# tar -zxvf nginx-1.18.0.tar.gz

安装

# 第一步:进入解压的nginx目录
[root@VM-4-6-centos home]# cd nginx-1.18.0
[root@VM-4-6-centos nginx-1.18.0]# ls
auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  man  README  src
# 第二步:自动配置
[root@VM-4-6-centos nginx-1.18.0]# ./configure     
checking for OS
 + Linux 3.10.0-1160.11.1.el7.x86_64 x86_64
checking for C compiler ... found
 + using GNU C compiler
 + gcc version: 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
checking for gcc -pipe switch ... found
checking for -Wl,-E switch ... found
checking for gcc builtin atomic operations ... found
checking for C99 variadic macros ... found
# 第三步:执行make命令
[root@VM-4-6-centos nginx-1.18.0]# make
make -f objs/Makefile
make[1]: Entering directory `/home/nginx-1.18.0'
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        -o objs/src/core/nginx.o \
        src/core/nginx.c
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        -o objs/src/core/ngx_log.o \
        src/core/ngx_log.c
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        -o objs/src/core/ngx_palloc.o \
        src/core/ngx_palloc.c
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        -o objs/src/core/ngx_array.o \
        src/core/ngx_array.c
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
# 第四步:执行 make install 命令
[root@VM-4-6-centos nginx-1.18.0]# make install
make -f objs/Makefile install
make[1]: Entering directory `/home/nginx-1.18.0'
test -d '/usr/local/nginx' || mkdir -p '/usr/local/nginx'
test -d '/usr/local/nginx/sbin' \
        || mkdir -p '/usr/local/nginx/sbin'
test ! -f '/usr/local/nginx/sbin/nginx' \
        || mv '/usr/local/nginx/sbin/nginx' \
                '/usr/local/nginx/sbin/nginx.old'
cp objs/nginx '/usr/local/nginx/sbin/nginx'
test -d '/usr/local/nginx/conf' \
        || mkdir -p '/usr/local/nginx/conf'
# 第五步:验证是否安装
[root@VM-4-6-centos nginx-1.18.0]# whereis nginx
nginx: /usr/local/nginx
[root@VM-4-6-centos nginx-1.18.0]# cd /usr/local/nginx # 进入安装 nginx 目录
[root@VM-4-6-centos nginx]# ll
total 16
drwxr-xr-x 2 root root 4096 Aug  7 20:08 conf
drwxr-xr-x 2 root root 4096 Aug  7 20:08 html
drwxr-xr-x 2 root root 4096 Aug  7 20:08 logs
drwxr-xr-x 2 root root 4096 Aug  7 20:08 sbin  # 一般存放的执行文件
[root@VM-4-6-centos nginx]# cd sbin
[root@VM-4-6-centos sbin]# ls
nginx
[root@VM-4-6-centos sbin]# ./nginx   # 执行 nginx
[root@VM-4-6-centos sbin]# cd ..
[root@VM-4-6-centos nginx]# ls
client_body_temp  conf  fastcgi_temp  html  logs  proxy_temp  sbin  scgi_temp  uwsgi_temp
[root@VM-4-6-centos nginx]# cd conf  # 进入 nginx 配置文件目录
[root@VM-4-6-centos conf]# ll
total 68
-rw-r--r-- 1 root root 1077 Aug  7 20:08 fastcgi.conf
-rw-r--r-- 1 root root 1077 Aug  7 20:08 fastcgi.conf.default
-rw-r--r-- 1 root root 1007 Aug  7 20:08 fastcgi_params
-rw-r--r-- 1 root root 1007 Aug  7 20:08 fastcgi_params.default
-rw-r--r-- 1 root root 2837 Aug  7 20:08 koi-utf
-rw-r--r-- 1 root root 2223 Aug  7 20:08 koi-win
-rw-r--r-- 1 root root 5231 Aug  7 20:08 mime.types
-rw-r--r-- 1 root root 5231 Aug  7 20:08 mime.types.default
-rw-r--r-- 1 root root 2656 Aug  7 20:08 nginx.conf    # nginx 配置文件
-rw-r--r-- 1 root root 2656 Aug  7 20:08 nginx.conf.default
-rw-r--r-- 1 root root  636 Aug  7 20:08 scgi_params
-rw-r--r-- 1 root root  636 Aug  7 20:08 scgi_params.default
-rw-r--r-- 1 root root  664 Aug  7 20:08 uwsgi_params
-rw-r--r-- 1 root root  664 Aug  7 20:08 uwsgi_params.default
-rw-r--r-- 1 root root 3610 Aug  7 20:08 win-utf
[root@VM-4-6-centos conf]# cat nginx.conf   # 查看 nginx 配置文件

nginx.conf 配置文件


#指定nginx运行的用户及用户组,默认为nobody
#user  nobody;
#开启的线程数,一般跟逻辑CPU核数一致
worker_processes  1;

#定位全局错误日志文件,级别以notice显示,还有debug,info,warn,error,crit模式,debug输出最多,crir输出最少,根据实际环境而定
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#指定进程id的存储文件位置
#pid        logs/nginx.pid;


events {
    #定义每个进程的最大连接数,受系统进程的最大打开文件数量限制。
    worker_connections  1024;
}


http {
    #主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度,DNS主配置文件中的zonerfc1912,acl基本上都是用include语句。
    include       mime.types;
    #核心模块指令,智力默认设置为二进制流,也就是当文件类型未定义时使用这种方式
    default_type  application/octet-stream;

    #下面代码为日志格式的设定,main为日志格式的名称,可自行设置,后面引用
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    #引用日志main
    #access_log  logs/access.log  main;
    
    # client_max_body_size 用来修改允许客户端上传文件的大小。默认为1m,如果设置为0,表示上传文件大小不受限制。
    # 可以在以下模块设置: http, server, location
    client_max_body_size 10m;

    #开启高效文件传输模式
    sendfile        on;
    #开启防止网络阻塞
    #tcp_nopush     on;

    #设置客户端连接保存活动的超时时间
    #keepalive_timeout  0;
    keepalive_timeout  65;

    #开启gzip压缩
    gzip on; 
    #低于1kb的资源不压缩 
    gzip_min_length 1k;
    #压缩级别1-9,越大压缩率越高,同时消耗cpu资源也越多,建议设置在5左右。 
    gzip_comp_level 5; 
    #需要压缩哪些响应类型的资源,多个空格隔开。不建议压缩图片.
    gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css; 
    #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
    gzip_disable "MSIE [1-6]\."; 
    #是否添加“Vary: Accept-Encoding”响应头
    gzip_vary on;

   server{
        listen       8080;
        server_name  localhost;
        location /my {
            alias /usr/local/files/web;
        }
    }

    server {
        #监听端口为 80
        listen       80;     
        #设置主机域名
        server_name  localhost;
        #设置访问的语言编码
        #charset koi8-r;
        #设置虚拟主机访问日志的存放路径及日志的格式为main
        #access_log  logs/host.access.log  main;
        #设置虚拟主机的基本信息
        location / {
            #设置虚拟主机的网站根目录
            root   html;
            #设置虚拟主机默认访问的网页
            index  index.html index.htm;
        }
  
        location /test01/ {
            # 解决跨域
            add_header Access-Control-Allow-Methods '*';
            add_header Access-Control-Max-Age 3600;
            add_header Access-Control-Allow-Credentials true;
            add_header Access-Control-Allow-Origin '*';
            add_header Access-Control-Allow-Headers '*';
            if ($request_method = OPTIONS){
                return 200;
            }
            # 携带请求头
            proxy_set_header Host $host:$server_port;
            # 携带nginx代理后原请求ip 
            # proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://192.168.0.111:8085/;
        }


        location /test02/ {
            add_header Access-Control-Allow-Methods '*';
            add_header Access-Control-Max-Age 3600;
            add_header Access-Control-Allow-Credentials true;
            add_header Access-Control-Allow-Origin '*';
            add_header Access-Control-Allow-Headers '*';
            if ($request_method = OPTIONS){
                return 200;
            }
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            # 使用这种代理方式,需要在项目里面配置 server.servlet.context-path=/test02
            proxy_pass http://192.168.0.222:8085/test02/;
        }


        #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   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;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

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


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

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

}

nginx监听会使用一个端口,代理的服务会使用一个端口,所以当两个端口一样时候,端口会被占用,出现问题

查看linux监听的端口号

netstat -tuln

-t 表示显示TCP端口

-u 表示显示UDP端口

-l 表示显示正在监听的端口

-n 表示直接使用数字形式显示地址和端口号

WebSocket连接错误Error during WebSocket handshake Unexpected response code 404

问题:后台SpringBoot使用@ServerEndpoint创建了一个websocket服务端,本地测试的时候一切正常,部署到线上的时候链接报错:WebSocket connection to 'ws://xxxx' failed: Error during WebSocket handshake: Unexpected response code: 404

当项目使用域名+端口号的方式访问的时候ws连接正常,而通过nginx反向代理后ws连接就不正常了。

错误的nginx配置:

server{
    listen  80;
    charset utf-8;
    server_name ws.xxx.cn;
     proxy_set_header Host $host:$server_port;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header REMOTE-HOST $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size 100m;
     location /  {
        proxy_pass http://127.0.0.1:8087; 
     }
 }

原因

Websocket握手格式包:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com 

这请求类似http协议,里面多了陌生的内容是:

Upgrade: websocket
Connection: Upgrade

这个就是Websocket的相关的,他会告诉Apache、Nginx等服务器我发起的是websocket请求,不是http!下面的三个参数Sec-WebSocket-Key、Sec-WebSocket-Protocol、Sec-WebSocket-Version作用大概就是验证请求确实是websocket,同时指定协议版本。

websocket虽然只发送了一次请求但是有三次握手:

第一次握手:
客户端通过http的第一次握手去连接服务器,告知服务器升级协议并发送Sec-WebSocket-Key过去
第二次握手:
服务器在接收到客户端升级协议的请求之后会取出Sec-WebSocket-Key在后面连接一个GUID,再对连接后的字符串做SHA1,得到16进制表示的字符串,将每两位当作一个字节进行分隔,得到字节数组,对字节数组做Base64,即得到Sec-WebSocket-Accept的值。返回客户端
第三次握手:
客户端在收到Sec-WebSocket-Accept值并验证通过后成功建立连接,就可以互相传递数据了。直至连接关闭。

解决

nginx配置WebSocket代理

要将客户端和服务器之间的连接从HTTP / 1.1转换为WebSocket,将使用HTTP / 1.1中可用的协议切换机制。
但是,有一个微妙之处:由于“升级”是 逐跳的 标头,因此它不会从客户端传递到代理服务器。使用正向代理,客户端可以使用该CONNECT 方法来规避此问题。但是,这不适用于反向代理,因为客户端不知道任何代理服务器,并且需要对代理服务器进行特殊处理。

从版本1.3.13开始,nginx实施了特殊的操作模式,如果代理服务器返回了代码为101(交换协议)的响应,并且客户端通过以下方式请求协议切换,则允许在客户端与代理服务器之间建立隧道。请求中的“升级”标头。
如上所述,包括“ Upgrade”和“ Connection”的逐跳标头未从客户端传递到代理服务器,因此,为了使代理服务器了解客户端将协议切换到WebSocket的意图,这些标头必须明确传递:

location /chat/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

默认情况下,如果代理服务器在60秒内未传输任何数据,则连接将关闭。可以使用proxy_read_timeout指令来增加此超时时间 。或者,可以将代理服务器配置为定期发送WebSocket ping帧以重置超时并检查连接是否仍然有效。
如果不配置超时时间,隔一会就会断开 具体超时时间具体要根据业务来调整。最终的配置如下:

server{
    listen  80;
    charset utf-8;
    server_name ws.xxx.cn;
     proxy_set_header Host $host:$server_port;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header REMOTE-HOST $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size 100m;
     location /  {
        proxy_pass http://127.0.0.1:8087; 
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
         
        proxy_connect_timeout 4s; 
        proxy_read_timeout 7200s; 
        proxy_send_timeout 12s; 
     }
 }

nginx携带原请求IP两种方式区别

proxy_set_header X-Real-IP $remote_addr;

这句话的意思是说,当你使用了nginx反向服务器后,在web端使用request.getRemoteAddr()(本质上就是获取$remote_addr),取得的是nginx的地址,即$remote_addr变量中封装的是nginx的地址,当然是没法获得用户的真实ip的。但是,nginx是可以获得用户的真实ip的,也就是说nginx使用$remote_addr变量时获得的是用户的真实ip,如果我们想要在web端获得用户的真实ip,就必须在nginx里作一个赋值操作,即上面的配置

$remote_addr 只能获取到与服务器本身直连的上层请求ip,所以设置$remote_addr 一般都是设置第一个代理上面;但是问题是,有时候是通过cdn访问过来的,那么后面web服务器获取到的,永远都是cdn 的ip 而非真是用户ip,那么这个时候就要用到X-Forwarded-For 了,这个变量的意思,其实就像是链路反追踪,从客户的真实ip为起点,穿过多层级的proxy ,最终到达web 服务器,都会记录下来。

  • 所以在获取用户真实ip的时候,一般就可以设置成 下面的配置

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

x_forwarded_for变量,这是一个squid开发的,用于识别通过HTTP代理或负载平衡器原始IP一个连接到Web服务器的客户机地址的非rfc标准,如果有做x_forwarded_for设置的话,每次经过proxy转发都会有记录,格式就是client1,proxy1,proxy2以逗号隔开各个地址,由于它是非rfc标准,所以默认是没有的,需要强制添加。在默认情况下经过proxy转发的请求,在后端看来远程地址都是proxy端的ip 。也就是说在默认情况下我们使用request.getHeader(“X-Forwarded-For”)获取不到用户的ip,如果我们想要通过这个变量获得用户的ip,我们需要自己在nginx添加配置:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

意思是增加一个$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增加,而不是覆盖,当然由于默认的X-Forwarded-For值是空的,所以我们总感觉X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,实际上当你搭建两台nginx在不同的ip上,并且都使用了这段配置,那你会发现在web服务器端通过request.getHeader(“X-Forwarded-For”)获得的将会是客户端ip和第一台nginx的ip。

那么$proxy_add_x_forwarded_for又是什么?

$proxy_add_x_forwarded_for变量包含客户端请求头中的x_forwarded_for$remote_addr两部分,他们之间用逗号分开。举个例子,有一个web应用,在它之前通过了两个nginx转发,即用户访问该web通过两台nginx。

在第一台nginx中,使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

现在的$proxy_add_x_forwarded_for变量的X-Forwarded-For部分是空的,所以只有$remote_addr,而$remote_addr的值是用户的ip,于是赋值以后,X-Forwarded-For变量的值就是用户的真实的ip地址了。

到了第二台nginx,使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

现在的$proxy_add_x_forwarded_for变量,X-Forwarded-For部分包含的是用户的真实ip,$remote_addr部分的值是上一台nginx的ip地址,于是通过这个赋值以后现在的X-Forwarded-For的值就变成了“用户的真实ip,第一台nginx的ip”。

        // 获取 X-Forwarded-For 中用户真实ip
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        String[] xForwardedForSplit= xForwardedFor.split(",");
        log.info(xForwardedForSplit[0]);

解决springboot上传文件限制

  • nginx 修改上传文件限制
http {

	# client_max_body_size 用来修改允许客户端上传文件的大小。默认为1m,如果设置为0,表示上传文件大小不受限制。
    # 可以在以下模块设置: http, server, location
    client_max_body_size 10m;
	
	server{
			listen       8080;
			server_name  localhost;
			location /my {
				alias /usr/local/files/web;
			}
		}
}
  • 在springboot 中设置
  1. 添加yml配置
spring:
  servlet:
    multipart:
      max-file-size: 5120MB
      max-request-size: 5120MB
  1. 添加配置bean
  @Bean
  public MultipartConfigElement multipartConfigElement(){
    MultipartConfigFactory factory=new MultipartConfigFactory();
    factory.setMaxFileSize(DataSize.of(5, DataUnit.GIGABYTES));
    factory.setMaxRequestSize(DataSize.of(5, DataUnit.GIGABYTES));
    return factory.createMultipartConfig();
  }

代理数据库端口号

需要安装 stream 模块

nginx.conf 文件头部添加

load_module /usr/local/nginx/modules/ngx_stream_module.so;

添加配置

# 读取模块
load_module /usr/local/nginx/modules/ngx_stream_module.so;

events {
    worker_connections  1024;
}
# 代理数据库,在http配置外面
stream {
    # mysql
    upstream mysql {
           server 172.168.1.1:3306;
    }
    server {
       listen 8801;#数据库服务器监听端口
       proxy_connect_timeout 10s;
       proxy_timeout 300s;#设置客户端和代理服务之间的超时时间,如果5分钟内没操作将自动断开。
       proxy_pass mysql; # upstream 设置的名称
    }
    # pgsql
    upstream pgsql {
           server 172.168.1.2:5432;
    }
    server {
       listen 8802;#数据库服务器监听端口
       proxy_connect_timeout 10s;
       proxy_timeout 300s;#设置客户端和代理服务之间的超时时间,如果5分钟内没操作将自动断开。
       proxy_pass pgsql; # upstream 设置的名称
    }
}
# http 配置
http {

    server {
        listen       80;
        server_name  localhost;
    }
}

配置中nginx和alias的区别分析

root和alias都可以定义在location模块中,都是用来指定请求资源的真实路径,比如:

  • 使用 root
location /test/ {  
    root /data/one;
}

请求 http://location/test/index.html 这个地址时,那么在服务器里面对应的真正的资源

是 /data/one/test/index.html 文件 (就会请求不到资源)

真实的路径是root指定的值加上location指定的值

  • 使用 alias
location /test/ {  
    alias /data/one;
}

同样请求 http://location/test/index.html 时,在服务器查找的资源路径是: /data/one/index.html , 就可以访问资源

alias指定的路径是location的别名,不管location的值怎么写,资源的 真实路径都是 alias 指定的路径

现在就可以访问80端口号对nginx进行访问了

location 配置 /XXX 与 /XXX/ 区别

1.location和proxy_pass都带/,则真实地址不带location匹配目录

location /api/ {
    proxy_pass http://127.0.0.1:8080/;
}

访问地址:www.test.com/api/upload --> http://127.0.0.1:8080/upload

2.location不带/,proxy_pass带/,则真实地址会带/

location /api {
    proxy_pass http://127.0.0.1:8080/;
}

访问地址: www.test.com/api/upload --> http://127.0.0.1:8080//upload

3.location带/,proxy_pass不带/,则真实地址会带location匹配目录/api/

location /api/ {
    proxy_pass http://127.0.0.1:8080;
}

访问地址: www.test.com/api/upload --> http://127.0.0.1:8080/api/upload

4.location和proxy_pass都不带/,则真实地址会带location匹配目录/api/

location /api {
    proxy_pass http://127.0.0.1:8080;
}

访问地址: www.test.com/api/upload --> http://127.0.0.1:8080/api/upload

5.location和proxy_pass都带/,但 proxy_pass带地址

location /api/ {
    proxy_pass http://127.0.0.1:8080/server/;
}

访问地址: www.test.com/api/upload --> http://127.0.0.1:8080/server/upload

6.location不带/,proxy_pass带/,但 proxy_pass带地址,则真实地址会多个/

location /api {
    proxy_pass http://127.0.0.1:8080/server/;
}

访问地址: www.test.com/api/upload --> http://127.0.0.1:8080/server//upload

7.location带/,proxy_pass不带/,但 proxy_pass带地址,则真实地址会直接连起来

location /api/ {
    proxy_pass http://127.0.0.1:8080/server;
}

访问地址: www.test.com/api/upload --> http://127.0.0.1:8080/serverupload

8.location和proxy_pass都不带/,但 proxy_pass带地址,则真实地址匹配地址会替换location匹配目录

location /api {
    proxy_pass http://127.0.0.1:8080/server;
}

访问地址: www.test.com/api/upload --> http://127.0.0.1:8080/server/upload

总结
1.proxy_pass代理地址端口后有目录(包括 / ),转发后地址:代理地址+访问URL目录部分去除location匹配目录
2.proxy_pass代理地址端口后无任何,转发后地址:代理地址+访问URL目录部

nginx常用命令

cd /usr/local/nginx/sbin/
./nginx  # 启动
./nginx -s stop # 停止
./nginx -s quit # 安全退出
./nginx -s reload # 重新加载配置文件
ps aux|grep nginx # 查看nginx进程

简单配置反向代理和负载均衡

http {
    //http配置
    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    upstream mytest{  //名称任意
        //负载均衡配置
        server 127.0.0.1:8080 weight=1;  //权重
        server 127.0.0.1:8081 weight=1;
    }
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://mytest;   //反向代理
        }
        location /admin {
            //不同的服务器
        }
}

nginx 代理其他服务器静态资源

  • 代理其他服务器静态资源 nginx 配置
server {
        listen       80;
        server_name  localhost;

        location /student-web/ {
            proxy_pass http:192.168.12.11:8001;   //反向代理
        }
}

/student-web/ 与项目文件夹名字一致才会匹配上

  • 192.168.12.11 服务器 nginx 配置
server {
        listen       8001;
        server_name  192.168.12.11;

        location / {
            root /home/web/;   //反向代理
        }
}

将项目文件夹放在 /home/web 目录下,通过请求 http:代理的地址/student-web 就可以访问啦

nginx-目录遍历漏洞

描述:
一般在配置Nginx访问静态资源时,需要指定文件在服务器上的路径,一般是在location下配置alias设置文件目录。如果alias路径后配置了/而location路径后未配置/就会出现目录穿越的漏洞,访问者通过调整url的格式就可以查看到alias配置路径的目录的上层目录及文件情况,造成信息泄露。

解决方式:

在配置alias目录路径时,location后面的目录路径也要加上/,如:location /files/

server {
 
  listen 8081;
 
  server_name localhost;
  
	 # 会造成目录遍历漏洞
     location /cc1 {
        autoindex on;
        alias /test/;
        autoindex_exact_size off;
        autoindex_localtime on;
        charset utf-8;
        index index.html index.htm;
     }
	 
	 # 不会造成目录遍历漏洞
	 location /cc2/ {
        autoindex on;
        alias /test/;
        autoindex_exact_size off;
        autoindex_localtime on;
        charset utf-8;
        index index.html index.htm;
     }

     # 跳转404页面
    location /404.html {
        # 使用绝对地址 跳转页面
        root /usr/local/nginx/html/50x.html;
    }
 }

location匹配规则

1.location的三类匹配

精准匹配:location = / {...}
一般匹配:location / {...}
正则匹配:location ~ / {...}

2.location 常用的匹配规则

= :进行普通字符精确匹配,也就是完全匹配
^~ :表示普通字符匹配,使用前缀匹配,如果匹配成功,则不再匹配其它 正则匹配location
~ :区分大小写的匹配
~* :不区分大小写的匹配。
!~ :区分大小写的匹配取非
!~* :不区分大小写的匹配取非

3.location 优先级

首先精确匹配 =
其次前缀匹配 ^~
其次是按文件中顺序的正则匹配 *
然后匹配不带任何修饰符的一般前缀匹配
最后是交给 / 通用匹配

4.location 示例

(1)location = / {}
=为精确匹配 / ,主机名后面不能带任何字符串,比如访问 / 和 /data,则 / 匹配,/data 不匹配
再比如 location = /abc,则只匹配/abc ,/abc/或 /abcd不匹配。若 location /abc,则即匹配/abc 、/abcd/ 同时也匹配 /abc/。

(2)location / {}
因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 比如访问 / 和 /data, 则 / 匹配, /data 也匹配,
但后面前缀路径会和最长字符串优先匹配(最长匹配)

(3)location /documents/ {}
匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的前缀路径没有匹配到时,才会采用这一条

(4)location /documents/abc {}
匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的前缀路径没有匹配到时,才会采用这一条

(5)location ^~ /images/ {}
匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条

(6)location ~* .(gif|jpg|jpeg)$ {}
匹配所有以 gif、jpg或jpeg 结尾的请求
然而,所有请求 /images/ 下的图片会被 location ^~ /images/ 处理,因为 ^~ 的优先级更高,所以到达不了这一条正则

(7)location /images/abc {}
最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它 location,会发现 ^~ 和 ~ 存在

(8)location ~ /images/abc {}
匹配以/images/abc 开头的,优先级次之,只有去掉 location ^~ /images/ 才会采用这一条

(9)location /images/abc/1.html {}
匹配/images/abc/1.html 文件,如果和正则location ~ /images/abc/1.html 相比,正则优先级更高

5.优先级总结

(location = 完整路径) > (location ^~ 路径) > (location ,* 正则顺序) > (location 部分前缀路径) > (location /)

location 匹配
首先看 优先级:精确= > 前缀^~ > 正则,* > 一般 > 通用/

在没有精准匹配的情况下,先看前缀匹配的长度,然后根据最长的前缀匹配的优先级去确定是否再去看其它正则匹配location,
如果最长的前缀匹配带有 ^~ 则不再看其它正则匹配location,如果最长的前缀匹配是没有修饰符的一般匹配则会再看其它正则匹配location

前缀匹配看长度,最长的优先匹配
正则匹配看上下顺序,由上往下依次匹配,当有匹配成功时候,停止匹配,按当前匹配规则处理请求

只有在精准、前缀、正则、一般 都没有匹配到的时候才会看通用匹配

6.location的三个匹配规则定义

第一个必选规则
直接匹配网站根目录首页,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。
可以是一个静态首页,也可以直接转发给后端应用服务器
location = /index.html {
root html;
index index.html index.htm;
}

第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/;
}

location ~* .(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}

第三个规则就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器
非静态文件请求就默认是动态请求
location / {
proxy_pass http://tomcat_server;
}


参考链接:
https://www.jb51.net/article/244331.htm

posted @ 2021-08-07 20:46  快乐小洋人  阅读(485)  评论(0)    收藏  举报