一、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
文件 证书需要在服务器上配置才能生效,这里附上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
浏览器访问。出现不安全连接,因为这里的证书使用的是自签发的证书,浏览器内部是无法识别的: 使用MacOS自带的浏览器访问出现:
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
五、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… 《安全》