Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将内部CA导入Jenkins_Java_Ssl_Jenkins_Jenkins Pipeline_Self Signed - Fatal编程技术网

Java 将内部CA导入Jenkins

Java 将内部CA导入Jenkins,java,ssl,jenkins,jenkins-pipeline,self-signed,Java,Ssl,Jenkins,Jenkins Pipeline,Self Signed,我试图使用Jenkins作业(管道)从json端点读取一些信息,然后根据这些信息做一些事情 它从中读取的端点是内部端点,应用程序可以通过https访问,证书由我们的内部CA自签名 下面是示例代码,由管道运行以解析json: newjsonslurper().parse(新URL('https://my.internal.url/info“))?.application?.git?.commit 为了使它更复杂一点,我还使用了管道中全局工具配置中的Java二进制文件 当我运行管道时,我得到以下错误

我试图使用Jenkins作业(管道)从json端点读取一些信息,然后根据这些信息做一些事情

它从中读取的端点是内部端点,应用程序可以通过https访问,证书由我们的内部CA自签名

下面是示例代码,由管道运行以解析json:

newjsonslurper().parse(新URL('https://my.internal.url/info“))?.application?.git?.commit

为了使它更复杂一点,我还使用了管道中全局工具配置中的Java二进制文件

当我运行管道时,我得到以下错误:

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
Caused: sun.security.validator.ValidatorException: PKIX path building failed
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
Caused: javax.net.ssl.SSLHandshakeException
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959)
    ...
Caused: groovy.json.JsonException: Unable to process url: https://my.internal.url/info
    at groovy.json.JsonSlurper.parseURL(JsonSlurper.java:416)
    at groovy.json.JsonSlurper.parse(JsonSlurper.java:379)
    ...
所以现在我试图让JVM知道这个CA,它运行这段代码,但我不知道怎么做

我尝试下载根CA的pem文件,将其添加到系统证书中,然后通过执行以下操作将其导入java的系统默认
cacerts
文件(
/etc/ssl/certs/java/cacerts
):

curl -Lso /etc/ssl/certs/rootca1.pem "<DOWNLOAD LINK>" \
    && chmod 777 /etc/ssl/certs/rootca1.pem \
    && mkdir -p /usr/share/ca-certificates/projectname \
    && cp /etc/ssl/certs/rootca1.pem /usr/share/ca-certificates/projectname/rootca1.crt \
    && echo "projectname/rootca1.crt" >> /etc/ca-certificates.conf \
    && update-ca-certificates -f
curl-Lso/etc/ssl/certs/rootca1.pem“”\
&&chmod 777/etc/ssl/certs/rootca1.pem\
&&mkdir-p/usr/share/ca证书/projectname\
&&cp/etc/ssl/certs/rootca1.pem/usr/share/ca certificates/projectname/rootca1.crt\
&&echo“projectname/rootca1.crt”>>/etc/ca-certificates.conf\
&&更新ca证书-f
之后,当我使用一个类来测试java中的ssl连接(like)并运行
JavaSSLPoke时https://my.internal.url/info 443
我可以成功连接。詹金斯管道仍然失败,并出现相同的错误

然后我想,可能管道使用了由全局工具配置复制到工作区的java二进制文件(即使在Jenkins文件中还没有这样做),因此我将CA添加到该工具的
cacerts
密钥库中,并将其复制到工作区中(
$WORKSPACE/tools/hudson.model.JDK/Java_8/jre/lib/security/cacerts

之后,我可以将该二进制文件与SSLPoke类一起使用,以成功连接到URL,但管道仍然失败

所以我现在没主意了…有没有人经历过类似的问题并设法解决了它们?没有转移到正式签署的证书(由于各种原因,内部URL不能选择,甚至我们不加密)


提前感谢!

所以我们设法解决了这个问题。问题是,我们没有让代理提供整个证书链。除浏览器外,例如openssl二进制文件(以及Java实现)无法动态加载丢失的中间证书


因此,我们创建了一个包含整个证书链(从叶到根证书)的证书,现在一切正常。

我没有设法解决这个问题,但我们有一个解决方法。我们将证书放入从属容器,并定期在所有节点上的所有Java安装中安装它:

def jdksJava8 = ['Java 8', 'Java 8 Oracle']
def jdksJava11 = ['Java 11']

def nodeNames = env.'NODE_NAME' ? [env.'NODE_NAME'] : getNodeNames().sort().findAll { it.startsWith('my-node') }

stage 'Install myRootCA', {

    currentBuild.displayName = "${env.'BUILD_NUMBER'}: ${env.'NODE_NAME' ?: 'all nodes'}"

    parallel nodeNames.collectEntries { nodeName ->
        [
            (nodeName): {
                node nodeName, {
                    jdksJava8.each { jdkName ->
                        withEnv(["JAVA_HOME=${tool jdkName}"]) {
                            sh '$JAVA_HOME/bin/java -version'
                            sh script: '$JAVA_HOME/bin/keytool -delete -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias myRootCA', returnStatus: true
                            sh script: '$JAVA_HOME/bin/keytool -import -trustcacerts -noprompt -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias myRootCA -file /usr/share/ca-certificates/myCompany/myRootCA.crt', returnStatus: true
                        }
                    }

                    jdksJava11.each { jdkName ->
                        withEnv(["JAVA_HOME=${tool jdkName}"]) {
                            sh script: '$JAVA_HOME/bin/keytool -delete -cacerts -storepass changeit -noprompt -alias myRootCA', returnStatus: true
                            sh script: '$JAVA_HOME/bin/keytool -importcert -cacerts -storepass changeit -noprompt -alias myRootCA -file /usr/share/ca-certificates/myCompany/myRootCA.crt', returnStatus: true
                        }
                    }
                }
            }
        ]
    }

}

@NonCPS
def getNodeNames() {
    jenkins.model.Jenkins.instance.nodes.collect { node -> node.name }
}


使用此脚本的作业现在每晚都在运行。如果我们必须重新启动节点,我们会在之后手动运行它以重新安装证书。

遗憾的是,问题没有得到解决。这只是问题的一部分。从Jenkins到从属容器的工具在容器重新启动时仍然没有根ca。因此,我仍然是l寻找解决方案…我也有同样的问题。你找到解决方案了吗?我们没有找到合适的解决方案。但我们现在有一个安静的解决方案。我把它作为一个答案添加到这篇文章中。希望这对你也有帮助!