图片 7

Spring Boot+Nginx+Tomcat+SSL配置笔记

Spring Boot 2.1.11 发布了,更新内容如下:

转自:

Spring Boot 2.x 已经发布了很久,现在 Spring Cloud 也发布了 基于 Spring
Boot 2.x 的 Finchley 版本,现在一起为项目做一次整体框架升级。

Spring Boot+Nginx+Tomcat+SSL配置笔记

如果你的tomcat应用需要采用ssl来加强安全性,一种做法是把tomcat配置为支持ssl,另一种做法是用nginx反向代理tomcat,然后把nginx配置为https访问,并且nginx与tomcat之间配置为普通的http协议即可。下面说的是后一种方法,同时假定我们基于spring-boot来开发应用。

一、配置nginx:

server {

    listen 80;

    listen 443 ssl;

    server_name localhost;

    ssl_certificate server.crt;

    ssl_certificate_key server.key;

    location / {

        proxy_pass ;

        proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header X-Forwarded-Port $server_port;

    }

}

这里有三点需要说明:

1、nginx允许一个server同时支持http和https两种协议。这里我们分别定义了http:80和https:443两个协议和端口号。如果你不需要http:80则可删除那行。

2、nginx收到请求后将通过http协议转发给tomcat。由于nginx和tomcat在同一台机里因此nginx和tomcat之间无需使用https协议。

3、由于对tomcat而言收到的是普通的http请求,因此当tomcat里的应用发生转向请求时将转向为http而非https,为此我们需要告诉tomcat已被https代理,方法是增加X-Forwared-Proto和X-Forwarded-Port两个HTTP头信息。

二、接着再配置tomcat。基于spring-boot开发时只需在application.properties中进行配置:

server.tomcat.remote_ip_header=x-forwarded-for

server.tomcat.protocol_header=x-forwarded-proto

server.tomcat.port-header=X-Forwarded-Port

server.use-forward-headers=true

该配置将指示tomcat从HTTP头信息中去获取协议信息(而非从HttpServletRequest中获取),同时,如果你的应用还用到了spring-security则也无需再配置。

此外,由于spring-boot足够自动化,你也可以把上面四行变为两行:

server.tomcat.protocol_header=x-forwarded-proto

server.use-forward-headers=true

Spring Boot+Nginx+Tomcat+SSL配置笔记。下面这样写也可以:

server.tomcat.remote_ip_header=x-forwarded-for

server.use-forward-headers=true

 但不能只写一行:

server.use-forward-headers=true

具体请参见

server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
The presence of either of those properties will switch on the valve

 此外,虽然我们的tomcat被nginx反向代理了,但仍可访问到其8080端口。为此可在application.properties中增加一行:

server.address=127.0.0.1

这样一来其8080端口就只能被本机访问了,其它机器访问不到。

Spring Boot 的详细介绍:请点这里
Spring Boot 的下载地址:请点这里

本文永久更新链接地址:

Boot+Nginx+Tomcat+SSL配置笔记
如果你的tomcat应用需要采用ssl来加强安全性,一种做法是把tomcat配置为支持ssl,另一种做法是用nginx反向代理…

Bug 修复

Spring Boot中启动HTTPS

升级前 => 升级后

  • 配置 Netty 时将忽略
    server.ssl.key-alias #19197
  • 在一个项目中使用多个数据库时,Liquibase
    执行器端点无法提供正确的信息 #19171
  • 当 Rabbit 配置为没有协议的地址时,ssl.enabled
    将被忽略 #19109
  • 在 CloudFoundryVcapEnvironmentPostProcessor 中使用
    DeferredLog #19027
  • @SpyBean (MockitoPostProcessor)  尝试初始化 @StepScope Bean
    超出范围 #19020
  • 如果存在正确的权限,则 HealthWebEndpointMapper
    应公开详细信息 #18998
  • Spring Boot – Maven
    插件损坏 #18936
  • BasicJsonParser 无法正确处理 [ 和 {
    之间的空格 #18911
  • @ServletComponentScan
    不适用于组件索引 #18910

如果你使用Spring Boot,并且想在内嵌tomcat中添加HTTPS,需要如下步骤

Spring Boot 1.5.x => Spring Boot 2.0.2

更新说明:

要有一个证书,买的或者自己生成的

Spring Cloud Edgware SR4 => Spring Cloud Finchley.RELEASE

(文/开源中国)    

在Spring Boot中启动HTTPS

Eureka Server

Eureka Server 依赖更新

升级前:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId></dependency>

升级后:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>

将HTTP重定向到HTTPS(可选)

Eureka Client

因为配置中心需要作为服务注册到注册中心,所以需要升级 Eureka
Client,其他依赖没有变动。

Eureka Client 依赖更新

升级前:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId></dependency>

升级后:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

获取SSL证书

Spring Cloud

注册中心里面的客户端实例IP显示不正确

因为 Spring Cloud 获取服务客户端 IP 地址配置变更了。

升级前:

${spring.cloud.client.ipAddress}

升级后:

${spring.cloud.client.ip-address}

有两种方式

Spring Security

一般注册中心、配置中心都会使用安全加密,就会依赖
spring-boot-starter-security 组件,升级后有几下两个问题。

1、用户名和密码无法登录

因为 Spring Security 的参数进行了变更。

升级前:

security: user: name: password:

升级后:

spring: security: user: name: password:

2、注册中心没有注册实例

如图所示,没有注册实例,两个注册中心无法互相注册。

图片 1image

因为 Spring Security 默认开启了所有 CSRF 攻击防御,需要禁用 /eureka
的防御。

在 Application 入口类增加忽略配置:

@EnableWebSecuritystatic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().ignoringAntMatchers("/eureka/**"); super.configure; }}

3、配置中心无法加解密

升级后发现访问配置中心无法读取到配置,也无法加解密配置信息,访问配置中心链接直接跳转到了登录页面。

图片 2image

现在想变回之前的 basic auth
认证方式,找源码发现是自动配置跳到了登录页面,现在重写一下。

自动配置源码:org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)

protected void configure(HttpSecurity http) throws Exception { logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity)."); http .authorizeRequests() .anyRequest().authenticated .formLogin .httpBasic();}

重写之后:

@EnableWebSecuritystatic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().ignoringAntMatchers.and().authorizeRequests().anyRequest() .authenticated.httpBasic(); }}

其实就是把 formLogin() 干掉了,又回到之前的 basic auth
认证方式,如下图所示。

图片 3image

现在我们又可以使用以下命令加解密了。

如解密:curl -d secret -u
user:password

恢复 basic auth 之后,之前的服务需要加密连接配置中心的又正常运行了。

自己通过keytool生成

Maven

升级到 Spring Boot 2.x 之后发现 Spring Boot 的 Maven
启动插件不好用了,主要是 Profile 不能自由切换。

升级前:

spring-boot:run -Drun.profiles=profile1

升级后:

spring-boot:run -Dspring-boot.run.profiles=profile1

具体的请参考:

通过证书授权机构购买

总结

以上都是踩完所有的坑总结出来的解决方案,实际解决问题的过程远要复杂的多。版本变化有点大,本次已成功升级了
Spring Cloud 基础依赖,及注册中心(Eureka Server)、配置中心(Config
Server)。

其他像 Gateway 代替了 Zuul, 及其他组件再慢慢升级,Spring Cloud
的快速发展令升级变得非常蛋疼,本文记录了升级过程中踩过的所有的坑。。。

坑死了,已经保证编译、运行正常,其他还有什么坑不知道,刚升级完 Finchley
这个正式版本,Spring Cloud 刚刚又发布了 Finchley.SR1,感觉 Spring Cloud
变成了学不动系列了。。。

@ All 码农们:你们升级了吗?有遇到什么样的坑?欢迎留言!

更多干货推荐

1.史上最强 Java 中高级面试题整理

2.史上最强 Spring Boot & Cloud 教程整理

3.史上最强架构设计分布式技术干货整理

更多请扫描下方的二维码关注我们的微信公众号,干货每日推送!

图片 4Java技术栈

这里作为演示,采用keytool生成

输入下面的命令,根据提示输入信息

图片 5

会生成一个PKCS12格式的叫做keystore.p12的证书,之后启动Spring
Boot时会引用这个证书

Spring Boot 中开启HTTPS

默认情况下Spring Boot内嵌的Tomcat服务器会在8080端口启动HTTP服务,Spring
Boot允许在application.properties中配置HTTP或HTTPS,但是不可同时配置,如果两个都启动,至少有一个要以编程的方式配置,Spring
Boot官方文档建议在application.properties中配置HTTPS,因为HTTPS比HTTP更复杂一些,可以参考spring-boot-sample-tomcat-multi-connectors的实例

在application.properties中配置HTTPS

server.port:8443server.ssl.key-store:classpath:keystore.p12server.ssl.key-store-password:mypasswordserver.ssl.keyStoreType:PKCS12server.ssl.keyAlias:tomcat

图片 6

这就够了

将HTTP请求重定向到HTTPS(可选)

让我们的应用支持HTTP是个好想法,但是需要重定向到HTTPS,上面说了不能同时在application.properties中同时配置两个connector,所以要以编程的方式配置HTTP
connector,然后重定向到HTTPS connector

这需要在配置类中配置一个TomcatEmbeddedServletContainerFactory
bean,代码如下

图片 7

搞定!

相关学习资料移步:

资料传送门