10-HTTPS在Nginx中的配置

331 阅读3分钟

01-从HTTP到HTTPS

02-HTTPS证书生成、验签 、证书链

03-OpenSSL-创建带SAN扩展的证书并进行CA自签

04-HTTPS证书格式及转换

05-HTTPS 秘钥库与证书(Java)

06-HTTPS单向认证及Java案例

07-HTTPS双向认证及Java案例

08-HTTPS在HTTPClient的应用

10-HTTPS在Nginx中的配置

11-HTTPS在SpringBoot中的配置

12-HTTPS在Tomcat配置

13-SSL-Mysql配置与应用

14-HTTPS在Redis中的配置

15-HTTPS基于Feign的远程调用

16-HTTPS在Eureka中的配置

一、Nginx安装

这里以MacOS的安装为例进行说明:Mac 安装Nginx详细教程 常用的命令:

 #启动
 nginx
 # 查看进程
 ps -A | grep nginx
 # 停止nginx
 kill -9  master进程号
 # 重新加载配置
 nginx -s reload
 ./nginx -s stop
 ./nginx 
 # nginx的配置路径
 open /usr/local/etc/nginx/
 # nginx的启动目录
 /usr/local/Cellar/nginx/1.21.6_1/bin

二、证书准备

可以参考第三章生成证书:02-HTTPS证书生成、验签 、证书链

三、Nginx配置

在Nginx的目录下创建文件夹cert,并且放入生成好的server.crt文件 image.png 证书需要在服务器上配置才能生效,这里附上nginx的参考配置文件。

 ​
 #user  nobody;
 worker_processes  1;
 events {
   worker_connections  1024;
 }
 ​
 ​
 http {
   include       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  logs/access.log  main;
 ​
   # 提高访问安全配置
   autoindex           on;
   port_in_redirect    off;
   proxy_hide_header   X-Powered-By;
 ​
   # 提高文件传输效率
   sendfile        on;
   tcp_nopush      on;
   gzip            on;
 ​
   # 规则2.2.9:    配置Nginx的网络超时时间
   send_timeout            10;
   keepalive_timeout       65;
   client_body_timeout     10s;
   client_header_timeout   10s;
 ​
   upstream register {
     server 192.168.43.2:1111;
     server 192.168.43.2:1113;
   }
 ​
   # HTTP server
   server {
     listen       80;
     server_name  localhost;
     # 用户访问http直接转发到https
     rewrite ^(.*)$  https://$host$1 permanent;
   }
 ​
 ​
   # HTTPS server
   #
   server {
     listen       443 ssl;
     server_name  localhost;
 ​
     # 如果header过大,它会使用large_client_header_buffers来读取
     client_header_buffer_size  4k;
     # 参数含义是申请4个8k的请求头缓冲区
     large_client_header_buffers  4  8k;
     # 缓冲客户端请求的最大字节
     client_body_buffer_size  16K;
     # 客户端请求的最大单文件字节数
     client_max_body_size 512M;
 ​
     # 正确设置HTTP安全响应头
     add_header X-XSS-Protection "1; mode=block";
     add_header X-Frame-Options DENY;
     add_header X-Content-Type-Options nosniff;
     add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
     add_header Cache-control "no-cache, no-store, must-revalidate";
     add_header Pragma no-cache;
     add_header Expires 0;
 ​
     proxy_ssl_server_name on;
 ​
     # https的签名证书和秘钥
     ssl_certificate      ssl/server.crt; #server公钥证书
     ssl_certificate_key  ssl/server.key; #server私钥
 ​
     #ssl_client_certificate /data/sslKey/client.crt;  #客户端公钥证书,SSL双向认证
     #ssl_verify_client on;  #开启客户端证书验证 
     
 ​
     # ssl缓存设置
     ssl_session_cache shared:SSL:10m;
     ssl_session_timeout 10m;
     # ssl安全TLS协议
     ssl_protocols TLSv1.2;
     # 使用安全的加密套件
     ssl_ciphers  ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256;
     ssl_prefer_server_ciphers  on;
 ​
     # 隐藏nginx版本号
     server_tokens off;
 ​
     location / {
       root   html;
       index  index.html index.htm;
       limit_except GET POST HEAD OPTIONS {  
         deny  all;  
       }
     }
 ​
     location /nginx_status {
       stub_status on;
       access_log   off;
     }
   }
 }

重新加载配置

 # nginx的启动目录
 /usr/local/Cellar/nginx/1.21.6_1/bin
 # 重新加载配置
 nginx -s reload
 ./nginx -s stop
 ./nginx 

浏览器访问。出现不安全连接,因为这里的证书使用的是自签发的证书,浏览器内部是无法识别的: image.png 使用MacOS自带的浏览器访问出现: image.png

mac os 信任自签名证书:

四、Nginx SSL双向认证

我们可以在 Nginx 服务器上配置双向认证的 HTTPS 服务了,具体配置方式如下:

 server {
         listen       443 ssl;
         server_name  www.yourdomain.com;
         ssl                  on;  
         ssl_certificate      ssl/server.crt;  #server公钥证书
         ssl_certificate_key  ssl/server.key;  #server私钥
         ssl_client_certificate ssl/root.crt;  #客户端公钥证书
         ssl_verify_client on;  #开启客户端证书验证  
  
  
         location / {
             root   html;
             index  index.html index.htm;
         }
     }

4.curl 调用

使用 curl 加上证书路径,可以直接测试 Nginx 的 HTTPS 双向认证是否配置成功。

 ​
 # --cert指定客户端公钥证书的路径
 # --key指定客户端私钥文件的路径
 # -k不校验证书的合法性,因为我们用的是自签名证书,所以需要加这个参数 (控制台不校验nginx的证书)
 # 可以使用 -v 来观察具体的 SSL 握手过程
 ​
 $ curl --cert ./client.crt --key ./client.key https://localhost -k -v
 ​

image.png image.png

五、Nginx与Tomcat

Nginx 作为前端反向代理或者负载均衡,Tomcat 不需要自己处理 https,https 由 Nginx 处理:

  • 用户首先和 Nginx 建立连接,完成 SSL 握手
  • 而后 Nginx 作为代理以 http 协议将请求转发给 Tomcat 处理
  • Nginx 再把 Tomcat 的输出通过 SSL 加密发回给用户

Tomcat 只是在处理 http 请求而已 (默认监听 8080 端口)。因此,这种情况下不需要配置 Tomcat 的 SSL,只需要配置 Nginx 的 SSL,Tomcat 和 Nginx 需要配置以下几项:

  • Nginx 中启用 https:
  • Tomcat 的 server.xml 的 Host 中配置 Valve:
 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
     <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>
 </Host>
 ​
 # X-Forwarded-Proto 是为了正确地识别实际用户发出的协议是 http 还是 https
 # X-Forwarded-For 是为了获得实际用户的 IP
 # 如果不配置它们,则在 redirect 的时候仍然会使用 http 而不是 https

注意: 当使用非 443 端口,如 9443 时,需要修改 2 个地方:

 Nginx: Host 中增加 $server_port
     listen 9443 ssl;
     proxy_set_header Host $host:$server_port;
 ​
 Tomcat: 必须配置 httpsServerPort,否则 request.getServerPort() 仍然返回 443
     <Valve className="org.apache.catalina.valves.RemoteIpValve" 
         remoteIpHeader="X-Forwarded-For" 
         protocolHeader="X-Forwarded-Proto" 
         protocolHeaderHttpsValue="https"
         httpsServerPort="9443"
     />

更多内容关注微信公众号 ”前后端技术精选“,或者语雀,里面有更多知识:www.yuque.com/riverzmm/uu… 《安全》