docker安装nginx,nginx配置文件,server_name匹配原理

docker安装nginx,nginx配置文件,server_name匹配原理

  • 1、docker安装nginx
  • 2、nginx配置文件
    • 2.1、整体配置文件介绍
    • 2.2、server块配置文件介绍(重点)
      • 2.2.1、server配置本地访问
      • 2.2.2、server_name匹配原理
      • 2.2.3、nginx中proxy_set_header Host 实际使用
      • 2.2.4、nginx中proxy_set_header X-Real-IP实际使用
      • 2.2.5、nginx中proxy_set_header X-Forwarded-For实际使用
      • 2.2.6、一个server配置,直接拿来用
      • 2.2.7、一个server配置,https请求的

1、docker安装nginx

1.1、启动nginx容器配置文件映射到主机

#拉取镜像
docker pull nginx:1.25
#启动临时nginx容器,拿配置文件
docker run --rm -d --name=temp-nginx nginx:1.25

mkdir -p /root/nginx/conf
mkdir -p /var/log/nginx
docker cp temp-nginx:/etc/nginx/nginx.conf /root/nginx/conf/nginx.conf
docker cp temp-nginx:/etc/nginx/conf.d /root/nginx/conf/conf.d
docker cp temp-nginx:/usr/share/nginx/html/ /root/nginx
#删除临时容器
docker rm -f temp-nginx

1.2、启动容器

docker run --name nginx  --restart=always -p 80:80 \
-v /root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /root/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /root/nginx/html:/usr/share/nginx/html \
-v /root/nginx/log:/var/log/nginx \
-d nginx:1.25

访问地址:

http://192.168.52.128

2、nginx配置文件

2.1、整体配置文件介绍

#查看配置文件
cat /root/nginx/conf/nginx.conf

#Nginx用户及组
#用户 组。window下不指定
user  nginx;
##工作进程:数目。根据硬件调整,通常等于CPU数量或者2倍于CPU。
worker_processes  auto;
#错误日志:存放路径。
error_log  /var/log/nginx/error.log notice;
#pid(进程标识符):存放路径。
pid        /var/run/nginx.pid;

#每个工作进程的最大连接数量。根据硬件调整,和前面工作进程配合起来用。
events {
    worker_connections  1024;
}

#http块(http设置)
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;
	#server块,单独放到配置文件,默认加载/etc/nginx/conf.d/*.conf配置文件
    include /etc/nginx/conf.d/*.conf;
}

2.2、server块配置文件介绍(重点)

2.2.1、server配置本地访问

1、server块可以配置多个,每个server块,相当于一个虚拟主机。
cat /root/nginx/conf/conf.d/default.conf

#访问http://192.168.52.128:8080,实际访问的是本地的 /usr/share/nginx/html文件
server {
    listen       8080;
    listen  [::]:8080;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

2.2.2、server_name匹配原理

1、当Nginx接到请求后,会匹配其配置中的server模块。匹配方法就是靠请求携带的host和port正好对应其配置中的server_name 和listen。如果做过ip和域名绑定,ip和域名二者是对等的。
2、如果不配置server_name,Nginx将默认的server_name的值为_,这代表匹配任何主机名,也就是如果不配置server_name,请求过来肯定匹配到第一个server。
如果listen能匹配上,server_name 匹配不上,默认请求到第一个匹配到listen所在的server。
3、如果需要代理到的地址是http://172.31.185.28:8080,代理机器的IP是192.168.52.128, 配置如下两个server。
注意:我故意把第一个server块的代理转发地址写错的,验证server_name的访问规则。

验证1:本机windows访问http://192.168.52.128:8081,访问不通,因为此时访问的host的是192.168.52.128:8081,匹配不上sever,所以默认使用第一个匹配到listen的server,第一个server我又故意写错了代理转发地址,所以不通。

验证2:本机windows要在host文件配置192.168.52.128 www.vm.cn, 访问http://www.vm.cn:8081是通的,因为此时访问的host的是www.vm.cn:8081,host能匹配到第二个server, 所以访问正常。
server {
        listen 8081;
        server_name  proxy.kutian.edn1;
        location / {
            proxy_pass http://172.31.185.29:8080;
            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_set_header X-Forwarded-Proto $scheme;
        }
}

server {
        listen 8081;
        server_name  www.vm.cn;
        location / {
            proxy_pass http://172.31.185.28:8080;
            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_set_header X-Forwarded-Proto $scheme;
        }
}
4、 一个nginx配置文件中可以有多个server_name,listen相同的虚拟主机。匹配多个时,默认使用匹配到的第一个server。




浏览器F12查看host
docker安装nginx,nginx配置文件,server_name匹配原理_第1张图片

2.2.3、nginx中proxy_set_header Host 实际使用

1、Host实际就是,在请求服务所带的请求主机,如上图,就是请求http://www.vm.cn:8081/vm时,带的Host的值为www.vm.cn:8081。Host实际就是被请求服务的域名或者IP。

2、手动指定IP,在用nginx做反向代理时,nginx去请求反向代理的地址时,也可指定Host的值。 比如我们用反向代理去请求华为HCS的接口地址时,反向代理的Host就必须要手动指定HCS的网关IP了(即使中间经过nat转换,也是配HCS的网关IP,不配nat的转换IP)。实际Host配什么值,主要看被调用端在代码里对Host做了什么限制。平常用的大部分还是不用手动指定Host的IP的。

3、host,浏览器请求的ip,不显示端口,请求http://www.vm.cn:8081/vm时,Host是www.vm.cn

4、http_host,浏览器请求的ip和端口号,请求http://www.vm.cn:8081/vm时,Host是www.vm.cn:8081

5、proxy_host,被代理服务的ip和端口号,请求http://www.vm.cn:8081/vm时,Host是172.31.185.28:8080,因为proxy_pass是 http://172.31.185.28:8080

配置举例:

server {
        listen 8081;
        server_name  www.vm.cn;
        location / {
            proxy_pass http://172.31.185.28:8080;
            proxy_set_header Host $host;
            #手动指定IP
            #proxy_set_header Host 172.17.2.2;
            #proxy_set_header Host $http_host;
            #proxy_set_header Host $proxy_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
}

服务端验证配置Host是否生效:
下面是,http://172.31.185.28:8080服务的代码,我是用java起的服务验证Host配置是否生效的。

@GetMapping("")
public Boolean test(HttpServletRequest request) {
    //获取Header中的所有key
    Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
        String headerName = headerNames.nextElement();
        if (Objects.equals("host", headerName)) {
            String headerValue = request.getHeader(headerName);
            System.out.println("headerName: " + headerName);
            System.out.println("headerValue: " + headerValue);
            System.out.println();
        }
    }
    return true;
}

2.2.4、nginx中proxy_set_header X-Real-IP实际使用

1、经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量可以拿到用户访问的真实IP地址。

2、比如,windows访问http://www.vm.cn:8081,windows的ip是172.31.185.28,代理机器的ip是192.168.52.128,设置成$remote_addr后,服务端通过代码request.getRemoteAddr()获得的地址是172.31.185.28

proxy_set_header X-Real-IP $remote_addr;

2.2.5、nginx中proxy_set_header X-Forwarded-For实际使用

1、$remote_addr 只能获取到与服务器本身直连的上层请求ip,所以设置$remote_addr一般都是设置第一个代理上面;但是问题是,有时候是通过cdn访问过来的,那么后面web服务器获取到的,永远都是cdn 的ip 而非真是用户ip,那么这个时候就要用到X-Forwarded-For 了。

2、在默认情况下经过proxy转发的请求,在后端看来远程地址都是proxy端的ip 。也就是说在默认情况下我们使用request.getAttribute("X-Forwarded-For")获取不到用户的ip,如果我们想要通过这个变量获得用户的ip,我们需要自己在nginx添加配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

2.2.6、一个server配置,直接拿来用

server {
    listen       8081;
    server_name  www.vm.cn;
    client_header_timeout 5s;   #针对 ddos


    client_header_buffer_size 512k;
    large_client_header_buffers 4 512k;

    location / {
        proxy_pass                  http://172.31.185.28:8080;
        proxy_redirect              off;
        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_set_header            Upgrade $http_upgrade;
        proxy_set_header            Connection "upgrade";

        client_max_body_size        500m;    #允许客户端请求的最大单文件字节数
        client_body_buffer_size     128k;   #缓冲区代理缓冲用户端请求的最大字节数,
        proxy_connect_timeout       90;     #nginx跟后端服务器连接超时时间(代理连接超时)
        proxy_send_timeout          60s;  #后端服务器数据回传时间(代理发送超时)
        proxy_read_timeout          60s;  #连接成功后,后端服务器响应时间(代理接收超时)--
        proxy_buffer_size           4k;     #设置代理服务器(nginx)保存用户头信息的缓冲区大小
        proxy_buffers               4 32k;  #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
        proxy_busy_buffers_size     64k;    #高负荷下缓冲大小(proxy_buffers*2)
        proxy_temp_file_write_size  64k;    #设定缓存文件夹大小,大于这个值,将从upstream服务器传
    }

}

2.2.7、一个server配置,https请求的

密钥文件需要自己替换下

server {
    listen       8081;
		listen       443 ssl;
    server_name  iam-apigateway-proxy.cxy.sd.cegn.cn;
    ssl_certificate     /etc/nginx/ssl/default.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 SSLv3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_session_timeout  5m;
    server_name  www.vm.cn;
    client_header_timeout 5s;   #针对 ddos


    client_header_buffer_size 512k;
    large_client_header_buffers 4 512k;

    location / {
        proxy_pass                  http://172.31.185.28:8080;
        proxy_redirect              off;
        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_set_header            Upgrade $http_upgrade;
        proxy_set_header            Connection "upgrade";

        client_max_body_size        500m;    #允许客户端请求的最大单文件字节数
        client_body_buffer_size     128k;   #缓冲区代理缓冲用户端请求的最大字节数,
        proxy_connect_timeout       90;     #nginx跟后端服务器连接超时时间(代理连接超时)
        proxy_send_timeout          60s;  #后端服务器数据回传时间(代理发送超时)
        proxy_read_timeout          60s;  #连接成功后,后端服务器响应时间(代理接收超时)--
        proxy_buffer_size           4k;     #设置代理服务器(nginx)保存用户头信息的缓冲区大小
        proxy_buffers               4 32k;  #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
        proxy_busy_buffers_size     64k;    #高负荷下缓冲大小(proxy_buffers*2)
        proxy_temp_file_write_size  64k;    #设定缓存文件夹大小,大于这个值,将从upstream服务器传
    }

}

你可能感兴趣的:(docker,nginx,容器)