vault 创建过程 & 新增编码的方法

本文详细介绍了在特定配置文件中新增ID码的方法,并通过示例展示了如何在create_vault命令中进行设置。同时,文章深入探讨了ID码的具体实现、数据库存储方式以及与XML配置的交互过程,包括使用Eclipse插件编辑数据库表结构和解析XML文件的流程。此外,还阐述了vault管理、权限控制、服务接口和服务状态绑定等方面的内容。

新增IDA码的方法

/root/dsnet-accesser/conf/core-org-bindings.xml文件中,

在现有的三四种IDA码的后面,增加一种


      <bindns:implementation class="org.cleversafe.ida.CosetCode.CosetInformationDispersalCodec" referral="cosetcodec" minVersion="1.0" maxVersion="1.0"/>

 

然后在create_vault命令中的vault配置xml中进行设置

/root/dsnet-accesser/bin/dsnet-create-vault --name="iqn.2010-05.anycn" --descriptor="/root/dsnet-accesser/conf/anycn.xml"

如:anycn.xml中

<!-- Information Dispersal Algorithm -->
   <vault:ida kind="IDA" referral="cosetcodec" version="1">
      <eval:param name="num-slices">
         <eval:literal type="int" value="8"/>
      </eval:param>
      <eval:param name="threshold">
         <eval:literal type="int" value="6"/>
      </eval:param>
   </vault:ida>

 

 

 


 

 

./dsnet-create-vault

 

好像有二个接口:

1、具体实现是在org.cleversafe.layer.access.GridAccessDaemon 中有函数

private class VaultStatus implements VaultStatusMBean

 VaultStatus(文件名为GridAccessDaemon )中有:

public String createVault(String descriptor, String name)

 

调用的可能是:

 

LocalFileVaultManager implements VaultManager中的:

org.cleversafe.vault.managers.LocalFileVaultManager.createVault(String, String, UUID, CredentialsManager)

 

这一块又用到了hibernate,至于吗,要用这么多中间件。

 

  vault的信息是存在javaDB数据库中的。

库的位置是在/root/dsnet-accesser/output/accesser/directory/directory.db,这个目录就是数据库。

注: 该库只能一个用户同时访问,所以accesser要先关掉。

用eclipse的插件“Eclipse Data Tools Platform”可以编辑查看。

APP库中的VAULT表

结果如下:

VAULT_IDVAULT_IDENTIFIERVAULT_NAME
13107236a477ba-737c-475c-ad98-bb99370103c5iqn.2010-03.sjtu
294912d140b7a4-b64d-48ab-861c-3a6eaa8c93fbiqn.2010-05.anycn

 

 

SERVICE表:

SERVICE_IDSERVICE_NAMESERVICE_TYPEOBJ_VERSIONSERVICE_VAULT
163840iqn.2010-03.sjtuiscsi0131072

 

SERVICE_INTERFACE表:

SERVICE_INTERFACE_IDSERVICE_INTERFACE_HOSTSERVICE_INTERFACE_PORTSERVICE_INTERFACE_AUTOSTARTSERVICE_INTERFACE_TYPEOBJ_VERSION
10.0.0.032601iscsi5

 

SERVICE_TO_SERVICE_INTERFACE表:

 SERVICE_INTERFACE_ID                SERVICE_ID
 --------------------                                      ----------
                    1                                             163840

 

此时:/root/dsnet-accesser/bin/dsnet-list-targets
+------------------+------------------+--------------------------------------+
| iqn.2010-03.sjtu | iqn.2010-03.sjtu | 36a477ba-737c-475c-ad98-bb99370103c5 |
+------------------+------------------+--------------------------------------+

 

 

 

 

vault表与vaultstate绑定的(org.cleversafe.vault.managers.state.VaultState)

 


 

以上是数据库这一块写好了。

 


xml这一块

应该是用xmlbean, 这一块的代码写的很乱,框架用了很多,但是接口并没有写成活的。

org.cleversafe.vault.managers.LocalFileVaultManager.getVaultInstance(UUID, InputStream, Credentials, KeyPair)

中,

 

 XMLVaultDescriptor(din, ctx);
中是对xml进行解析。

 

一层层下去,org.cleversafe.vault.XMLVaultDescriptor.loadVaultFromXML(InputStream)中vd.getVault().getIda()就是读出来

IDA的。

anycn.xml

 

 

access control这一块

本函数中用到

org.cleversafe.vault.managers.LocalFileVaultManager.createVaultACL(UUID, File, Credentials, PublicKey)

 

 

 

 

 

下面来看storeslices:

 

上面的org.cleversafe.vault.managers.LocalFileVaultManager.createVault(String, String, UUID, CredentialsManager)中,

调用org.cleversafe.vault.managers.LocalFileVaultManager.executeOnStores(UUID, File, Credentials, KeyPair, StoreExecuter, boolean)

在store slices中安装vault。

 

 

 


 

另一方面我们来看一下vault这个东西。

org.cleversafe.layer.block.dsd.BlockDeviceMain中新实例化一个BlockDeviceVault

org.cleversafe.layer.block.BlockDeviceVault<<

extends BaseVaultpublic class BlockDeviceVault extends BaseVault

BaseVault中就有了decodec就是IDA的编码,但是

public abstract class BaseVault implements Vault

vault中没有这个码,但是有get这个码的方法。

 

用命令:find /root/dsnet-accesser/ |  xargs grep "BlockDevice"

可以查到,在blockdevice-org-bindings.xml中有用到“org.cleversafe.layer.block.BlockDeviceVault”这个类,NND。

./conf/blockdevice-org-bindings.xml:      <bindns:implementation class="org.cleversafe.layer.block.BlockDeviceVault" referral="block"/>

 

 

 

 

 

&lt;think&gt; 我们需要在已有信任库的基础上添加新的信任证书。有两种主要方式: 1. 使用keytool命令合并两个信任库(适用于文件形式) 2. 在代码中同时加载多个信任库(更灵活,无需合并文件) 考虑到您可能不想修改原有信任库文件,且希望动态管理,推荐代码方式。 ### 方案1:代码中合并多个信任库(推荐) ```java import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; import java.io.InputStream; import java.security.KeyStore; public class MultiTrustStoreConfig { // 假设已有第一个信任库(classpath下的old-truststore.jks) @Value(&quot;classpath:old-truststore.jks&quot;) private Resource oldTruststore; // 第二个信任库(新增的,可以是文件或动态生成的) private KeyStore newTrustStore; // 设置新信任库(假设已经通过某种方式创建好) public void setNewTrustStore(KeyStore newTrustStore) { this.newTrustStore = newTrustStore; } @Bean public RestTemplate restTemplate() throws Exception { // 加载第一个信任库 KeyStore trustStore1 = KeyStore.getInstance(&quot;JKS&quot;); try (InputStream is = oldTruststore.getInputStream()) { trustStore1.load(is, &quot;password1&quot;.toCharArray()); } // 如果第二个信任库是动态创建的(比如从PEM),则不需要加载文件 // 假设newTrustStore已经初始化 // 合并两个信任库 KeyStore mergedTrustStore = KeyStore.getInstance(&quot;JKS&quot;); mergedTrustStore.load(null, null); // 初始化空的 // 将第一个信任库的所有证书复制到合并库 for (String alias : Collections.list(trustStore1.aliases())) { Certificate cert = trustStore1.getCertificate(alias); mergedTrustStore.setCertificateEntry(&quot;old-&quot;+alias, cert); // 注意别名冲突 } // 将第二个信任库的所有证书复制到合并库 for (String alias : Collections.list(newTrustStore.aliases())) { Certificate cert = newTrustStore.getCertificate(alias); mergedTrustStore.setCertificateEntry(&quot;new-&quot;+alias, cert); } // 创建SSL上下文 SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(mergedTrustStore, null) .build(); CloseableHttpClient httpClient = HttpClients.custom() .setSSLContext(sslContext) .build(); return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient)); } } ``` ### 方案2:使用keytool合并两个JKS文件(适用于静态文件) ```bash # 假设有两个信任库:old.jks 和 new.jks # 1. 将new.jks中的证书导入到old.jks(注意别名冲突) # 列出new.jks中的证书别名 keytool -list -keystore new.jks -storepass password # 逐个导入(假设别名分别为cert1, cert2) keytool -importcert -alias cert1 -file cert1.cer -keystore old.jks -storepass oldpassword keytool -importcert -alias cert2 -file cert2.cer -keystore old.jks -storepass oldpassword # 但这样需要先导出为cer文件,更简单的方式是直接复制别名: # 使用keytool的-importkeystore命令合并 keytool -importkeystore \ -srckeystore new.jks \ -destkeystore old.jks \ -srcstorepass newpassword \ -deststorepass oldpassword # 此命令会将new.jks中的所有条目(包括证书和私钥)导入old.jks,但信任库通常只包含证书。 # 注意:如果别名重复,会覆盖原有条目!为了避免,可以先修改别名再导入。 # 修改别名(在导入前) keytool -changealias -keystore new.jks -alias old-alias -destalias new-alias ``` ### 动态添加证书到已有信任库(不修改文件) ```java // 在已有信任库基础上动态添加新证书(不合并文件,仅内存中合并) public class DynamicAddCertificate { private KeyStore existingTrustStore; // 原有信任库 public void addCertificate(Certificate certificate, String alias) throws Exception { // 将新证书添加到现有的KeyStore对象中(内存中) existingTrustStore.setCertificateEntry(alias, certificate); // 然后需要重新SSLContext(可能会影响已经立的连接) // 通常需要重新创建RestTemplate/HttpClient } } ``` ### 最佳实践议 1. **别名管理**:合并时注意别名冲突,议添加前缀区分 2. **密码安全**:从安全配置源获取密码 3. **性能优化**:避免频繁重SSLContext(可考虑定期更新机制) 4. **微服务架构**:在Spring Cloud中可自定义`RestTemplate` Bean实现全局信任 &sect;&sect;相关问题&sect;&sect; 1. 如何在运行时动态向已加载的信任库中添加新的自签证书而不重启应用? 2. 合并两个信任库时遇到别名冲突应如何处理? 3. 在Spring Boot中如何为不同的第三方服务配置不同的信任库? 4. 使用内存中的合并信任库相比使用文件信任库有什么性能影响? 5. 如何验证新加入信任库的证书确实生效并能成功立HTTPS连接? &lt;/think&gt; ### 在已有信任库基础上新增信任库的解决方案 #### 方案一:物理合并两个信任库文件(推荐用于静态配置) ```bash # 1. 将新证书导入临时JKS keytool -importcert -alias new-cert -file new-cert.pem -keystore new-truststore.jks -storepass changeit -noprompt # 2. 将新信任库内容合并到原信任库 keytool -importkeystore \ -srckeystore new-truststore.jks \ -destkeystore existing-truststore.jks \ -srcstorepass changeit \ -deststorepass original-password \ -srcalias new-cert -destalias new-cert-alias ``` #### 方案二:代码中动态组合多个信任库(推荐用于动态环境) ```java import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContexts; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; import java.io.InputStream; import java.security.KeyStore; @Configuration public class MultiTruststoreConfig { // 原信任库配置 @Value(&quot;classpath:existing-truststore.jks&quot;) private Resource existingTruststore; // 新信任库配置 @Value(&quot;classpath:new-truststore.jks&quot;) private Resource newTruststore; @Bean public RestTemplate restTemplate() throws Exception { // 1. 加载原有信任库 KeyStore existing = loadTrustStore(existingTruststore, &quot;original-password&quot;); // 2. 加载新信任库 KeyStore newStore = loadTrustStore(newTruststore, &quot;changeit&quot;); // 3. 创建组合信任库(内存中) KeyStore combined = KeyStore.getInstance(KeyStore.getDefaultType()); combined.load(null, null); // 4. 合并原有信任库证书 for (String alias : Collections.list(existing.aliases())) { combined.setCertificateEntry(&quot;existing-&quot; + alias, existing.getCertificate(alias)); } // 5. 合并新信任库证书 for (String alias : Collections.list(newStore.aliases())) { combined.setCertificateEntry(&quot;new-&quot; + alias, newStore.getCertificate(alias)); } // 6. 配置SSL上下文 SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(combined, null) .build(); // 7. 创建HTTP客户端 CloseableHttpClient httpClient = HttpClients.custom() .setSSLContext(sslContext) .build(); return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient)); } private KeyStore loadTrustStore(Resource resource, String password) throws Exception { KeyStore trustStore = KeyStore.getInstance(&quot;JKS&quot;); try (InputStream is = resource.getInputStream()) { trustStore.load(is, password.toCharArray()); } return trustStore; } } ``` #### 方案三:系统属性配置多个信任库(适用于简单场景) ```java // 启动时设置系统属性(application.properties或启动参数) System.setProperty(&quot;javax.net.ssl.trustStore&quot;, &quot;path/to/existing-truststore.jks&quot;); System.setProperty(&quot;javax.net.ssl.trustStorePassword&quot;, &quot;original-password&quot;); // 添加额外信任库路径 System.setProperty(&quot;javax.net.ssl.trustStore&quot;, System.getProperty(&quot;javax.net.ssl.trustStore&quot;) + File.pathSeparator + &quot;path/to/new-truststore.jks&quot;); ``` #### 方案四:自定义TrustManager组合多个信任库 ```java public class CompositeX509TrustManager implements X509TrustManager { private final List&lt;X509TrustManager&gt; trustManagers = new ArrayList&lt;&gt;(); public CompositeX509TrustManager() throws Exception { // 添加原有信任库 addTrustStore(&quot;classpath:existing-truststore.jks&quot;, &quot;original-password&quot;); // 添加新信任库 addTrustStore(&quot;classpath:new-truststore.jks&quot;, &quot;changeit&quot;); } private void addTrustStore(String path, String password) throws Exception { try (InputStream is = getClass().getResourceAsStream(path)) { KeyStore ks = KeyStore.getInstance(&quot;JKS&quot;); ks.load(is, password.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); for (TrustManager tm : tmf.getTrustManagers()) { if (tm instanceof X509TrustManager) { trustManagers.add((X509TrustManager) tm); } } } } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { trustManagers.forEach(tm -&gt; { try { tm.checkClientTrusted(chain, authType); } catch (CertificateException e) { // 可添加日志 } }); } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { for (X509TrustManager tm : trustManagers) { try { tm.checkServerTrusted(chain, authType); return; // 任一信任库验证通过即可 } catch (CertificateException ignored) { // 继续尝试下一个 } } throw new CertificateException(&quot;所有信任库均不信任该证书&quot;); } @Override public X509Certificate[] getAcceptedIssuers() { List&lt;X509Certificate&gt; certificates = new ArrayList&lt;&gt;(); for (X509TrustManager tm : trustManagers) { Collections.addAll(certificates, tm.getAcceptedIssuers()); } return certificates.toArray(new X509Certificate[0]); } } ``` ### 最佳实践议 1. **别名管理**:合并时使用前缀避免别名冲突(如`existing-`和`new-`) 2. **密码安全**: - 从安全配置源获取密码(如Vault、KMS) - 避免硬编码密码 3. **性能优化**: ```java // 缓存SSLContext避免重复创建 private static SSLContext cachedSslContext; @Scheduled(fixedDelay = 3600000) // 每小时刷新 public void refreshTrustStores() { cachedSslContext = createSslContext(); // 重SSLContext } ``` 4. **验证配置**: ```bash # 验证信任库内容 keytool -list -v -keystore combined-truststore.jks ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值