《重新定义Spring Cloud实战》——3.5.5 启用https
3.5.5 启用https
对于上面开启HTTP Basic认证来说,从安全角度讲,基于base64编码很容易被——抓包然后破解,如果暴露在公网会非常不安全,这里就讲述一下如何在Eureka Server及Client开启https,来达到这个目的。
1.证书生成
keytool -genkeypair -alias server -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore server.p12 -validity 3650
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
[Unknown]:
您的组织单位名称是什么?
[Unknown]:
您的组织名称是什么?
[Unknown]:
您所在的城市或区域名称是什么?
[Unknown]:
您所在的省/市/自治区名称是什么?
[Unknown]:
该单位的双字母国家/地区代码是什么?
[Unknown]:
CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown是否正确?
[否]: Y
这里使用的密码是Spring Cloud,然后会在当前目录下生成一个名为server.p12的文件。
下面生成Client端使用的证书:
keytool -genkeypair -alias client -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore client.p12 -validity 3650
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
[Unknown]:
您的组织单位名称是什么?
[Unknown]:
您的组织名称是什么?
[Unknown]:
您所在的城市或区域名称是什么?
[Unknown]:
您所在的省/市/自治区名称是什么?
[Unknown]:
该单位的双字母国家/地区代码是什么?
[Unknown]:
CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown是否正确?
[否]: Y
这里使用的密码是Client,然后会在当前目录下生成一个名为client.p12的文件。
下面分别导出两个p12的证书,如下:
keytool -export -alias server -file server.crt --keystore server.p12
输入密钥库口令:
存储在文件 <server.crt> 中的证书
keytool -export -alias client -file client.crt --keystore client.p12
输入密钥库口令:
存储在文件 <client.crt> 中的证书
接下来将server.crt文件导入client.p12中,使Client端信任Server的证书:
keytool -import -alias server -file server.crt -keystore client.p12
输入密钥库口令:
所有者:CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
发布者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
序列号: 5249cc11
有效期为Mon Jun 25 18:53:20 CST 2018 至Thu Jun 22 18:53:20 CST 2028
证书指纹:
MD5: 4D:27:25:0E:A2:6A:7A:0C:81:D2:89:35:12:61:3E:16
SHA1: A3:5E:8E:09:F8:B1:44:9C:B5:AC:AB:2E:F2:7A:58:95:7F:02:69:C4
SHA256: 93:3B:9F:CA:74:D3:88:19:69:7F:65:E0:4F:DF:E0:71:C6:3E:5F:BC:FF:7F:4F:0F:39:43:D7:22:A6:87:96:8C
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位RSA密钥
版本: 3
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: BE A8 E5 3D D6 8E 58 47 CB C4 17 2A 8D 4F 50 1D ...=..XG...*.OP.
0010: 83 B8 3E 24 ..>$
]
]
是否信任此证书? [否]: Y
证书已添加到密钥库中
这里需要输入的是client.p12的密钥。
然后将client.crt导入server.p12中,使得Server信任Client的证书:
keytool -import -alias client -file client.crt -keystore server.p12
输入密钥库口令:
所有者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
发布者: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
序列号: 5c68914d
有效期为Tue Jun 26 09:30:47 CST 2018 至Fri Jun 23 09:30:47 CST 2028
证书指纹:
MD5: 4C:0F:35:63:CE:47:A9:C5:90:7C:B2:7D:07:CE:67:DC
SHA1: E2:E0:DD:E3:3F:84:DF:21:F5:FB:CA:F5:A9:FB:3C:CD:08:AE:3E:C3
SHA256: 65:B4:49:C0:1D:C3:7B:0C:1B:4D:13:67:91:1F:5E:18:6F:F7:0E:AD:64:D4:D9:11:97:DB:55:BB:D4:E3:3F:D2
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位RSA密钥
版本: 3
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 1F 49 7D 24 2F E0 7B 2E F2 F7 19 A2 48 23 4D 73 .I.$/.......H#Ms
0010: 1D DC 99 0B ....
]
]
是否信任此证书? [否]: Y
证书已添加到密钥库中
这里需要输入的是server.p12的密钥。
2. Eureka Server配置
把生成的server.p12放到Maven工程的resources目录下,然后指定相关配置如代码清单3-33所示。
代码清单3-33 ch3-5\ch3-5-eureka-server\src\main\resources\application-https.yml
server:
port: 8761
ssl:
enabled: true
key-store: classpath:server.p12
key-store-password: springcloud
key-store-type: PKCS12
key-alias: server
eureka:
instance:
hostname: localhost
securePort: ${server.port}
securePortEnabled: true
nonSecurePortEnabled: false
homePageUrl: https://${eureka.instance.hostname}:${server.port}/
statusPageUrl: https://${eureka.instance.hostname}:${server.port}/
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: https://${eureka.instance.hostname}:${server.port}/eureka/
server:
waitTimeInMsWhenSyncEmpty: 0
enableSelfPreservation: false
这里主要是指定server.ssl配置,以及eureka.instance的securePortEnabled及eureka.instance.securePort配置。
使用https的profile启动如下:
mvn spring-boot:run –Dspring.profiles.active=https
之后访问https://localhost:8761/,可以看到https已经启用。
3. Eureka Client配置
把生成的client.p12放到Maven工程的resources目录下,然后指定相关配置如代码清单3-34所示。
代码清单3-34 ch3-5\ch3-5-eureka-client\src\main\resources\application-https.yml
server:
port: 8081
spring:
application:
name: client1
eureka:
client:
securePortEnabled: true
ssl:
key-store: client.p12
key-store-password: client
serviceUrl:
defaultZone: https://localhost:8761/eureka/
这里我们没有指定整个应用实例启用https,仅仅是开启访问Eureka Server的https配置。通过自定义eureka.client.ssl.key-store以及eureka.client.ssl.key-store-password两个属性,指定Eureka Client访问Eureka Server的sslContext配置,这里需要在代码里指定DiscoveryClient.DiscoveryClientOptionalArgs,配置如代码清单3-35所示。
代码清单3-35 ch3-5\ch3-5-eureka-client\src\main\java\cn\springcloud\book\config\EurekaHttpsClientConfig.java
@Configuration
public class EurekaHttpsClientConfig {
@Value("${eureka.client.ssl.key-store}")
String keyStoreFileName;
@Value("${eureka.client.ssl.key-store-password}")
String keyStorePassword;
@Bean
public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException {
EurekaJerseyClientImpl.EurekaJerseyClientBuilder builder = new EurekaJerseyClientImpl.EurekaJerseyClientBuilder();
builder.withClientName("eureka-https-client");
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(
this.getClass().getClassLoader().getResource(keyStoreFileName),keyStorePassword.toCharArray()
)
.build();
builder.withCustomSSL(sslContext);
builder.withMaxTotalConnections(10);
builder.withMaxConnectionsPerHost(10);
DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs();
args.setEurekaJerseyClient(builder.build());
return args;
}
}
然后使用如下命令启动:
mvn spring-boot:run –Dspring.profiles.active=https
查询Eureka Server可以看到已经成功注册上:
curl --insecure https://localhost:8761/eureka/apps
<applications>
<versions__delta>1</versions__delta>
<apps__hashcode>UP_1_</apps__hashcode>
<application>
<name>CLIENT1</name>
<instance>
<instanceId>10.2.238.208:client1:8081</instanceId>
<hostName>10.2.238.208</hostName>
<app>CLIENT1</app>
<ipAddr>10.2.238.208</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">8081</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1529977873082</registrationTimestamp>
<lastRenewalTimestamp>1529978503987</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1529977873082</serviceUpTimestamp>
</leaseInfo>
<metadata>
<management.port>8081</management.port>
</metadata>
<homePageUrl>http://10.2.238.208:8081/</homePageUrl>
<statusPageUrl>http://10.2.238.208:8081/actuator/info</statusPageUrl>
<healthCheckUrl>http://10.2.238.208:8081/actuator/health</healthCheckUrl>
<vipAddress>client1</vipAddress>
<secureVipAddress>client1</secureVipAddress>
<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1529977873082</lastUpdatedTimestamp>
<lastDirtyTimestamp>1529977872969</lastDirtyTimestamp>
<actionType>ADDED</actionType>
</instance>
</application>
</applications>
- 点赞
- 收藏
- 关注作者
评论(0)