问题背景
项目架构为前后端分离的微服务架构:
- 前端部署在 8000 端口
- API 网关部署在 9000 端口
- 后端服务包括:
- api-backend (9001端口)
- api-interface (9002端口)
初始状态:
- 前端已配置 HTTPS(端口 8000)
- 后端服务未配置 HTTPS
- 通过 Nginx 进行反向代理
遇到的问题
-
第一阶段:400 Bad Request
This combination of host and port requires TLS
原因:前端使用 HTTPS,但后端服务未正确配置 SSL 证书。由于前端首先请求是到达api-gateway 网关层。借助Spring Cloud Gateway 进行请求转发。虽然给API gateway分配了https,但是它转发的另外两个模块的端口没有分配HTTPS导致请求转发错误。
-
第二阶段:403 错误
Failed to resolve 'api-backend' after 4 queries
原因:网关路由配置使用服务名而非具体地址,导致服务发现失败。
项目配置文件
解决方案
1. SSL 证书配置
为所有服务配置 SSL:
- API Gateway (9000端口):
application.yml
配置
yaml
server:
port: 9000
address: 0.0.0.0
ssl:
enabled: true
key-store: /www/server/nginx/ssl/<服务器ip>/keystore.p12
key-store-password: 1234
key-store-type: PKCS12
http2:
enabled: true
spring:
cloud:
gateway:
routes:
- id: api-backend
uri: https://<服务器ip>:9001
predicates:
- Path=/api/backend/**
filters:
- StripPrefix=0
- AddRequestHeader=X-Forwarded-Proto,https
- id: api-interface
uri: https://<服务器ip>:9002
predicates:
- Path=/api/interface/**
filters:
- StripPrefix=0
- AddRequestHeader=X-Forwarded-Proto,https
ssl:
key-store: /www/server/nginx/ssl/<服务器ip>/keystore.p12
key-store-password: 1234
key-store-type: PKCS12
logging:
level:
org:
springframework:
cloud:
gateway: DEBUG
dubbo:
application:
name: api-gateway-dubbo
qosEnable: false
enable-file-cache: false
protocol:
name: dubbo
port: -1
# 注意这里ssl也需要配置
ssl:
enabled: true
application-prod.yml
yml
spring:
cloud:
nacos:
server-addr: 192.168.15.233:8848
secure: true # 添加这行,启用安全连接
config:
file-extension: yaml
bootstrap.yml
yml
spring:
cloud:
nacos:
server-addr: 192.168.15.233:8848
secure: true # 添加这行,启用安全连接
config:
file-extension: yaml
application:
name: api-interface
- API-backend (9001端口)
application.yml
配置
yml
server:
port: 9001
address: 0.0.0.0
ssl:
enabled: true
key-store: /www/server/nginx/ssl/<服务器ip>/keystore.p12
key-store-password: 1234
key-store-type: PKCS12
http2:
enabled: true
servlet:
context-path: /api/backend
session:
cookie:
max-age: 7d
secure: true
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
servlet:
multipart:
max-file-size: 10MB
max-request-size: 100MB
session:
store-type: redis
timeout: 7d
knife4j:
enable: true
basic:
enable: true
username: root
password: xxx
dubbo:
application:
name: api-backend-dubbo
qosEnable: false
enable-file-cache: false
protocol:
name: dubbo
port: -1
registry:
address: nacos://192.168.15.233:8848
ssl:
enabled: true # 注意这里true
application-prod.yml
yml
# 客户端SDK 配置
api:
client:
gateway-host: https://<服务器ip>:9000
bootstrap.yml
yml
spring:
application:
name: api-backend
profiles:
active: prod
cloud:
nacos:
server-addr: 192.168.15.233:8848
secure: true # 添加这行,启用安全连接
config:
file-extension: yaml
- API- interface
application.yml
yml
server:
port: 9002
address: 0.0.0.0
ssl:
enabled: true
key-store: /www/server/nginx/ssl/<服务器ip>/keystore.p12
key-store-password: 1234
key-store-type: PKCS12
http2:
enabled: true
servlet:
context-path: /api/interface
#-------------------------------------------------
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
dubbo:
ssl:
enabled: true
application-prod.yml
yml
spring:
cloud:
nacos:
server-addr: 192.168.15.233:8848
secure: true # 添加这行,启用安全连接
config:
file-extension: yaml
bootstrap.yml
yml
spring:
cloud:
nacos:
server-addr: 192.168.15.233:8848
secure: true # 添加这行,启用安全连接
config:
file-extension: yaml
application:
name: api-interface
2. Nginx 配置
更新 Nginx 配置以支持 HTTPS 代理:
nginx
location /api {
rewrite ^/api/(.*) /$1 break;
proxy_pass https://<服务器ip>:9000/api;
proxy_ssl_verify off;
proxy_ssl_server_name on;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
关键配置点说明
-
SSL 证书配置
- 所有服务统一使用相同的 SSL 证书
- 启用 HTTP2 以提升性能
- 确保证书文件权限正确
-
网关路由
- 使用具体的服务地址而不是服务名
- 添加必要的请求头
- 保持 SSL 配置一致性
-
服务间通信
- Dubbo 服务启用 SSL
- 确保所有通信链路使用 HTTPS
最佳实践建议
-
证书管理
- 使用统一的证书存储位置
- 确保证书文件权限正确
- 定期更新证书
-
配置管理
- 使用配置中心统一管理
- 环境隔离(开发/生产)
- 密码等敏感信息加密存储
-
安全增强
- 启用 HTTP2
- 配置安全的 SSL 协议和密码套件
- 启用 HSTS 策略